From 416331ca661973916afa1054e91ffcb888c09018 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Mon, 25 Nov 2019 21:38:20 +0000 Subject: [PATCH] New upstream version 1.38.0+dfsg1 --- CONTRIBUTING.md | 9 +- Cargo.lock | 1428 ++-- README.md | 78 +- RELEASES.md | 131 +- config.toml.example | 11 +- git-commit-hash | 2 +- src/README.md | 7 +- src/bootstrap/README.md | 10 +- src/bootstrap/bin/main.rs | 3 +- src/bootstrap/bin/rustc.rs | 82 +- src/bootstrap/bin/rustdoc.rs | 3 +- src/bootstrap/bootstrap.py | 67 +- src/bootstrap/builder.rs | 14 +- src/bootstrap/builder/tests.rs | 5 +- src/bootstrap/cache.rs | 5 +- src/bootstrap/cc_detect.rs | 2 + src/bootstrap/channel.rs | 2 +- src/bootstrap/check.rs | 5 - src/bootstrap/compile.rs | 7 +- src/bootstrap/config.rs | 13 +- src/bootstrap/configure.py | 5 +- src/bootstrap/dist.rs | 25 +- src/bootstrap/doc.rs | 38 +- src/bootstrap/flags.rs | 26 +- src/bootstrap/lib.rs | 32 +- src/bootstrap/mk/Makefile.in | 4 - src/bootstrap/native.rs | 14 +- src/bootstrap/sanity.rs | 15 +- src/bootstrap/test.rs | 160 +- src/bootstrap/tool.rs | 97 +- src/bootstrap/util.rs | 76 +- src/build_helper/lib.rs | 14 +- src/ci/awscli-requirements.txt | 13 - src/ci/azure-pipelines/auto.yml | 22 +- src/ci/azure-pipelines/master.yml | 2 +- src/ci/azure-pipelines/pr.yml | 24 +- .../azure-pipelines/steps/install-clang.yml | 18 +- .../azure-pipelines/steps/install-sccache.yml | 4 +- .../steps/install-windows-build-deps.yml | 27 +- src/ci/azure-pipelines/steps/run.yml | 87 +- src/ci/azure-pipelines/try.yml | 6 +- src/ci/docker/README.md | 2 +- src/ci/docker/armhf-gnu/Dockerfile | 2 +- src/ci/docker/asmjs/Dockerfile | 2 +- src/ci/docker/dist-powerpc-linux/Dockerfile | 4 - src/ci/docker/dist-various-1/Dockerfile | 9 +- .../dist-various-1/install-mips-musl.sh | 2 +- .../dist-various-1/install-mipsel-musl.sh | 2 +- src/ci/docker/dist-various-2/Dockerfile | 32 +- .../dist-various-2/build-wasi-toolchain.sh | 2 +- .../docker/dist-x86_64-linux/build-openssl.sh | 2 +- .../build-netbsd-toolchain.sh | 2 +- src/ci/docker/run.sh | 56 +- src/ci/docker/scripts/android-sdk-manager.py | 8 +- src/ci/docker/scripts/freebsd-toolchain.sh | 2 +- src/ci/docker/scripts/sccache.sh | 2 +- src/ci/docker/test-various/Dockerfile | 3 +- src/ci/docker/x86_64-gnu-debug/Dockerfile | 3 +- .../x86_64-gnu-full-bootstrap/Dockerfile | 2 + src/ci/docker/x86_64-gnu-llvm-6.0/Dockerfile | 2 + src/ci/docker/x86_64-gnu-nopt/Dockerfile | 2 + src/ci/docker/x86_64-gnu-tools/Dockerfile | 4 +- .../x86_64-gnu-tools/checkregression.py | 12 +- src/ci/docker/x86_64-gnu-tools/checktools.sh | 22 +- src/ci/docker/x86_64-gnu-tools/repo.sh | 34 +- src/ci/docker/x86_64-gnu/Dockerfile | 2 + src/ci/init_repo.sh | 5 - src/ci/install-awscli.sh | 35 + src/ci/run.sh | 20 +- src/ci/shared.sh | 46 +- ...referring-to-an-item-in-the-module-tree.md | 5 +- ...g-paths-into-scope-with-the-use-keyword.md | 6 +- .../ch09-02-recoverable-errors-with-result.md | 2 +- src/doc/book/src/ch11-01-writing-tests.md | 13 +- src/doc/book/src/ch11-03-test-organization.md | 2 +- src/doc/book/src/ch19-06-macros.md | 2 +- src/doc/book/src/title-page.md | 17 +- src/doc/edition-guide/.travis.yml | 4 +- src/doc/edition-guide/README.md | 4 +- .../cargo-check-for-faster-checking.md | 4 +- ...-install-for-easy-installation-of-tools.md | 10 +- .../src/rust-2018/macros/at-most-once.md | 6 +- .../rust-2018/module-system/path-clarity.md | 52 +- .../the-anonymous-lifetime.md | 7 +- .../rustup-for-managing-rust-versions.md | 33 +- .../the-compiler/improved-error-messages.md | 27 +- .../embedded-book/src/concurrency/index.md | 60 + .../src/interoperability/c-with-rust.md | 4 +- .../embedded-book/src/intro/install/verify.md | 2 +- src/doc/embedded-book/src/start/exceptions.md | 1 + src/doc/nomicon/README.md | 47 +- src/doc/nomicon/src/README.md | 2 +- src/doc/nomicon/src/dropck.md | 2 +- src/doc/nomicon/src/lifetime-mismatch.md | 1 - src/doc/nomicon/src/transmutes.md | 2 +- src/doc/reference/.travis.yml | 2 +- src/doc/reference/book.toml | 4 +- src/doc/reference/src/abi.md | 16 +- src/doc/reference/src/attributes.md | 128 +- src/doc/reference/src/attributes/codegen.md | 24 +- src/doc/reference/src/attributes/derive.md | 14 +- .../reference/src/attributes/diagnostics.md | 52 +- src/doc/reference/src/attributes/limits.md | 16 +- src/doc/reference/src/attributes/testing.md | 10 +- .../src/behavior-considered-undefined.md | 17 +- .../reference/src/conditional-compilation.md | 24 +- src/doc/reference/src/const_eval.md | 72 +- .../reference/src/crates-and-source-files.md | 22 +- src/doc/reference/src/destructors.md | 31 +- .../reference/src/dynamically-sized-types.md | 14 +- src/doc/reference/src/expressions.md | 140 +- .../reference/src/expressions/array-expr.md | 26 +- .../reference/src/expressions/block-expr.md | 44 +- .../reference/src/expressions/call-expr.md | 10 +- .../reference/src/expressions/closure-expr.md | 26 +- .../src/expressions/enum-variant-expr.md | 10 +- .../reference/src/expressions/field-expr.md | 16 +- .../reference/src/expressions/grouped-expr.md | 8 +- src/doc/reference/src/expressions/if-expr.md | 12 +- .../reference/src/expressions/literal-expr.md | 20 +- .../reference/src/expressions/loop-expr.md | 18 +- .../reference/src/expressions/match-expr.md | 36 +- .../src/expressions/method-call-expr.md | 22 +- .../src/expressions/operator-expr.md | 24 +- .../reference/src/expressions/path-expr.md | 14 +- .../reference/src/expressions/range-expr.md | 12 +- .../reference/src/expressions/return-expr.md | 2 +- .../reference/src/expressions/struct-expr.md | 34 +- .../reference/src/expressions/tuple-expr.md | 16 +- src/doc/reference/src/glossary.md | 26 +- src/doc/reference/src/identifiers.md | 4 +- src/doc/reference/src/interior-mutability.md | 4 +- src/doc/reference/src/introduction.md | 10 +- src/doc/reference/src/items.md | 62 +- .../reference/src/items/associated-items.md | 50 +- src/doc/reference/src/items/constant-items.md | 16 +- src/doc/reference/src/items/enumerations.md | 26 +- src/doc/reference/src/items/extern-crates.md | 10 +- .../reference/src/items/external-blocks.md | 24 +- src/doc/reference/src/items/functions.md | 62 +- src/doc/reference/src/items/generics.md | 38 +- .../reference/src/items/implementations.md | 44 +- src/doc/reference/src/items/modules.md | 28 +- src/doc/reference/src/items/static-items.md | 14 +- src/doc/reference/src/items/structs.md | 18 +- src/doc/reference/src/items/traits.md | 58 +- src/doc/reference/src/items/type-aliases.md | 10 +- src/doc/reference/src/items/unions.md | 30 +- .../reference/src/items/use-declarations.md | 16 +- src/doc/reference/src/keywords.md | 22 +- src/doc/reference/src/lifetime-elision.md | 12 +- src/doc/reference/src/linkage.md | 8 +- src/doc/reference/src/macro-ambiguity.md | 2 +- src/doc/reference/src/macros-by-example.md | 38 +- src/doc/reference/src/macros.md | 26 +- src/doc/reference/src/notation.md | 8 +- src/doc/reference/src/paths.md | 32 +- src/doc/reference/src/patterns.md | 54 +- src/doc/reference/src/procedural-macros.md | 32 +- src/doc/reference/src/runtime.md | 8 +- .../reference/src/special-types-and-traits.md | 48 +- src/doc/reference/src/statements.md | 36 +- src/doc/reference/src/subtyping.md | 4 +- src/doc/reference/src/tokens.md | 86 +- src/doc/reference/src/trait-bounds.md | 20 +- src/doc/reference/src/type-coercions.md | 2 +- src/doc/reference/src/type-layout.md | 10 +- src/doc/reference/src/types.md | 112 +- src/doc/reference/src/types/array.md | 8 +- src/doc/reference/src/types/closure.md | 20 +- src/doc/reference/src/types/enum.md | 6 +- src/doc/reference/src/types/function-item.md | 18 +- .../reference/src/types/function-pointer.md | 20 +- src/doc/reference/src/types/impl-trait.md | 4 +- src/doc/reference/src/types/pointer.md | 12 +- src/doc/reference/src/types/slice.md | 4 +- src/doc/reference/src/types/struct.md | 8 +- src/doc/reference/src/types/textual.md | 2 +- src/doc/reference/src/types/trait-object.md | 14 +- src/doc/reference/src/types/tuple.md | 2 +- src/doc/reference/src/types/union.md | 11 +- src/doc/reference/src/unsafety.md | 10 +- src/doc/reference/src/variables.md | 4 +- .../reference/src/visibility-and-privacy.md | 2 +- src/doc/reference/{src => }/theme/header.hbs | 0 .../reference/{src => }/theme/reference.css | 17 +- src/doc/rust-by-example/README.md | 1 + src/doc/rust-by-example/src/SUMMARY.md | 1 + .../src/attribute/cfg/custom.md | 2 +- .../rust-by-example/src/attribute/crate.md | 2 +- src/doc/rust-by-example/src/cargo/test.md | 12 +- src/doc/rust-by-example/src/crates/lib.md | 2 +- src/doc/rust-by-example/src/crates/link.md | 2 +- .../rust-by-example/src/error/iter_result.md | 4 +- .../src/error/option_unwrap.md | 2 +- src/doc/rust-by-example/src/error/panic.md | 2 +- .../src/flow_control/if_let.md | 4 +- .../src/flow_control/match/binding.md | 4 +- .../src/flow_control/match/destructuring.md | 2 +- src/doc/rust-by-example/src/generics/impl.md | 22 +- src/doc/rust-by-example/src/hello/print.md | 2 +- src/doc/rust-by-example/src/macros/dry.md | 2 +- src/doc/rust-by-example/src/meta/doc.md | 2 +- src/doc/rust-by-example/src/mod/split.md | 4 +- src/doc/rust-by-example/src/mod/use.md | 2 +- src/doc/rust-by-example/src/mod/visibility.md | 10 +- .../rust-by-example/src/scope/borrow/alias.md | 6 +- .../src/scope/borrow/freeze.md | 6 +- src/doc/rust-by-example/src/scope/raii.md | 2 +- .../src/std/hash/alt_key_types.md | 4 +- .../rust-by-example/src/std/hash/hashset.md | 4 +- src/doc/rust-by-example/src/std/panic.md | 2 +- src/doc/rust-by-example/src/std/rc.md | 54 + src/doc/rust-by-example/src/std/str.md | 22 +- src/doc/rust-by-example/src/std/vec.md | 18 +- src/doc/rust-by-example/src/std_misc/arg.md | 2 +- .../src/std_misc/arg/matching.md | 2 +- .../src/std_misc/file/create.md | 2 +- .../rust-by-example/src/std_misc/file/open.md | 2 +- .../src/std_misc/file/read_lines.md | 10 +- src/doc/rust-by-example/src/std_misc/fs.md | 4 +- .../src/testing/dev_dependencies.md | 2 +- .../src/testing/doc_testing.md | 2 +- .../src/testing/integration_testing.md | 2 +- .../src/testing/unit_testing.md | 18 +- src/doc/rustc-guide/.travis.yml | 4 +- src/doc/rustc-guide/README.md | 2 +- src/doc/rustc-guide/book.toml | 2 +- .../rustc-guide/ci/build-ignore-timeouts.sh | 24 + src/doc/rustc-guide/ci/install.sh | 4 +- src/doc/rustc-guide/src/SUMMARY.md | 7 +- src/doc/rustc-guide/src/about-this-guide.md | 2 +- src/doc/rustc-guide/src/appendix/glossary.md | 2 +- src/doc/rustc-guide/src/appendix/humorust.md | 12 + .../moves_and_initialization/move_paths.md | 9 +- .../src/borrow_check/region_inference.md | 3 +- .../constraint_propagation.md | 24 +- .../region_inference/lifetime_parameters.md | 8 +- .../region_inference/member_constraints.md | 17 +- .../placeholders_and_universes.md | 6 +- src/doc/rustc-guide/src/closure.md | 4 +- .../rustc-guide/src/codegen/updating-llvm.md | 2 +- src/doc/rustc-guide/src/compiler-team.md | 6 +- src/doc/rustc-guide/src/compiletest.md | 4 +- .../src/debugging-support-in-rustc.md | 2 +- .../rustc-guide/src/how-to-build-and-run.md | 10 +- src/doc/rustc-guide/src/kinds.md | 4 +- src/doc/rustc-guide/src/macro-expansion.md | 4 +- src/doc/rustc-guide/src/mir/index.md | 2 +- src/doc/rustc-guide/src/miri.md | 2 +- .../query-evaluation-model-in-detail.md | 2 +- .../rustc-guide/src/stabilization_guide.md | 6 +- src/doc/rustc-guide/src/tests/adding.md | 23 +- src/doc/rustc-guide/src/tests/running.md | 21 +- src/doc/rustc-guide/src/the-parser.md | 13 + .../src/traits/goals-and-clauses.md | 2 +- .../rustc-guide/src/traits/implied-bounds.md | 2 +- src/doc/rustc-guide/src/traits/index.md | 4 +- src/doc/rustc-guide/src/ty.md | 2 +- src/doc/rustc/src/codegen-options/index.md | 8 +- src/doc/rustc/src/command-line-arguments.md | 51 +- src/doc/rustc/src/linker-plugin-lto.md | 1 + src/doc/rustc/src/lints/index.md | 2 +- src/doc/rustc/src/lints/levels.md | 6 +- .../src/lints/listing/allowed-by-default.md | 2 +- .../src/lints/listing/deny-by-default.md | 12 +- .../src/lints/listing/warn-by-default.md | 22 +- src/doc/rustdoc/src/unstable-features.md | 35 +- .../const-in-array-repeat-expressions.md | 11 + .../src/language-features/on-unimplemented.md | 3 +- .../src/language-features/param-attrs.md | 27 + .../src/language-features/plugin.md | 10 +- .../src/language-features/slice-patterns.md | 6 +- .../asm.md | 0 .../concat-idents.md | 0 .../library-features/debug-map-key-value.md | 9 + .../global-asm.md | 0 .../unstable-book/src/library-features/n16.md | 5 - .../trace-macros.md | 0 src/etc/cpu-usage-over-time-plot.sh | 2 +- src/etc/gdb_load_rust_pretty_printers.py | 1 + src/etc/rust-lldb | 33 +- src/liballoc/Cargo.toml | 4 +- src/liballoc/alloc.rs | 39 +- src/liballoc/alloc/tests.rs | 30 + src/liballoc/benches/slice.rs | 8 +- src/liballoc/borrow.rs | 12 +- src/liballoc/boxed.rs | 57 +- src/liballoc/collections/binary_heap.rs | 5 + src/liballoc/collections/btree/map.rs | 54 +- src/liballoc/collections/btree/node.rs | 8 +- src/liballoc/collections/btree/set.rs | 7 + src/liballoc/collections/linked_list.rs | 293 +- src/liballoc/collections/linked_list/tests.rs | 264 + src/liballoc/collections/vec_deque.rs | 475 +- src/liballoc/collections/vec_deque/tests.rs | 379 + src/liballoc/lib.rs | 43 +- src/liballoc/prelude/v1.rs | 1 - src/liballoc/raw_vec.rs | 191 +- src/liballoc/raw_vec/tests.rs | 73 + src/liballoc/rc.rs | 771 +- src/liballoc/rc/tests.rs | 439 + src/liballoc/slice.rs | 191 +- src/liballoc/str.rs | 27 +- src/liballoc/string.rs | 9 +- src/liballoc/sync.rs | 767 +- src/liballoc/sync/tests.rs | 492 ++ src/liballoc/tests.rs | 13 + src/liballoc/tests/arc.rs | 121 + src/liballoc/tests/btree/map.rs | 3 + src/liballoc/tests/btree/set.rs | 28 +- src/liballoc/tests/heap.rs | 32 +- src/liballoc/tests/lib.rs | 4 +- src/liballoc/tests/linked_list.rs | 2 - src/liballoc/tests/rc.rs | 117 + src/liballoc/tests/str.rs | 20 +- src/liballoc/tests/vec.rs | 110 +- src/liballoc/tests/vec_deque.rs | 1 - src/liballoc/vec.rs | 167 +- src/libarena/Cargo.toml | 1 - src/libarena/lib.rs | 10 +- src/libcore/Cargo.toml | 2 +- src/libcore/alloc.rs | 11 +- src/libcore/any.rs | 27 + src/libcore/array.rs | 444 +- src/libcore/ascii.rs | 1 + src/libcore/benches/slice.rs | 26 + src/libcore/cell.rs | 37 +- src/libcore/char/methods.rs | 33 +- src/libcore/clone.rs | 8 + src/libcore/cmp.rs | 34 +- src/libcore/convert.rs | 30 +- src/libcore/default.rs | 8 + src/libcore/ffi.rs | 19 +- src/libcore/fmt/builders.rs | 160 +- src/libcore/fmt/float.rs | 7 +- src/libcore/fmt/mod.rs | 17 +- src/libcore/fmt/num.rs | 4 +- src/libcore/future/future.rs | 9 +- src/libcore/hash/mod.rs | 15 + src/libcore/hint.rs | 2 +- src/libcore/intrinsics.rs | 104 +- src/libcore/iter/adapters/flatten.rs | 61 +- src/libcore/iter/adapters/mod.rs | 180 + src/libcore/iter/mod.rs | 2 +- src/libcore/iter/traits/accum.rs | 144 +- src/libcore/iter/traits/collect.rs | 5 +- src/libcore/iter/traits/iterator.rs | 110 +- src/libcore/lib.rs | 17 +- src/libcore/macros.rs | 705 +- src/libcore/marker.rs | 16 +- src/libcore/mem/manually_drop.rs | 2 + src/libcore/mem/maybe_uninit.rs | 37 +- src/libcore/mem/mod.rs | 48 +- src/libcore/num/f32.rs | 121 +- src/libcore/num/f64.rs | 121 +- src/libcore/num/mod.rs | 50 +- src/libcore/ops/function.rs | 4 + src/libcore/ops/index.rs | 4 +- src/libcore/ops/try.rs | 4 +- src/libcore/option.rs | 236 +- src/libcore/pin.rs | 159 +- src/libcore/prelude/v1.rs | 51 + src/libcore/ptr/mod.rs | 330 +- src/libcore/ptr/non_null.rs | 2 +- src/libcore/ptr/unique.rs | 6 +- src/libcore/result.rs | 167 +- src/libcore/slice/mod.rs | 127 +- src/libcore/slice/rotate.rs | 221 +- src/libcore/slice/sort.rs | 4 +- src/libcore/str/lossy.rs | 4 +- src/libcore/str/mod.rs | 184 +- src/libcore/task/wake.rs | 4 +- src/libcore/tests/ascii.rs | 2 +- src/libcore/tests/fmt/builders.rs | 93 +- src/libcore/tests/fmt/mod.rs | 2 - src/libcore/tests/iter.rs | 245 +- src/libcore/tests/lib.rs | 5 +- src/libcore/tests/num/dec2flt/mod.rs | 1 + src/libcore/tests/num/flt2dec/estimator.rs | 7 +- src/libcore/tests/num/flt2dec/mod.rs | 16 +- src/libcore/tests/num/flt2dec/random.rs | 31 +- .../tests/num/flt2dec/strategy/dragon.rs | 1 + .../tests/num/flt2dec/strategy/grisu.rs | 1 + src/libcore/tests/option.rs | 30 +- src/libcore/tests/pattern.rs | 2 +- src/libcore/tests/ptr.rs | 8 +- src/libcore/tests/result.rs | 185 +- src/libcore/tests/slice.rs | 109 +- src/libcore/tests/time.rs | 2 +- src/libcore/time.rs | 36 +- src/libcore/unicode/printable.py | 6 +- src/libcore/unicode/printable.rs | 156 +- src/libcore/unicode/tables.rs | 1377 ++-- src/libcore/unicode/unicode.py | 1098 ++- src/libfmt_macros/Cargo.toml | 2 +- src/libfmt_macros/lib.rs | 77 +- src/libfmt_macros/tests.rs | 333 +- src/libgraphviz/Cargo.toml | 1 - src/libgraphviz/lib.rs | 2 - src/libpanic_abort/lib.rs | 4 +- src/libpanic_unwind/dwarf/mod.rs | 21 +- src/libpanic_unwind/dwarf/tests.rs | 19 + src/libpanic_unwind/gcc.rs | 3 + src/libpanic_unwind/lib.rs | 2 - src/libproc_macro/bridge/buffer.rs | 2 +- src/libproc_macro/bridge/scoped_cell.rs | 3 +- src/libproc_macro/lib.rs | 3 +- src/libprofiler_builtins/build.rs | 1 + src/libprofiler_builtins/lib.rs | 1 - src/librustc/Cargo.toml | 36 +- src/librustc/cfg/construct.rs | 59 +- src/librustc/cfg/mod.rs | 2 +- src/librustc/dep_graph/dep_tracking_map.rs | 2 +- src/librustc/dep_graph/graph.rs | 88 +- src/librustc/error_codes.rs | 14 +- src/librustc/hir/check_attr.rs | 16 +- src/librustc/hir/def.rs | 32 +- src/librustc/hir/def_id.rs | 27 +- src/librustc/hir/intravisit.rs | 28 +- src/librustc/hir/lowering.rs | 3253 +------- src/librustc/hir/lowering/expr.rs | 1497 ++++ src/librustc/hir/lowering/item.rs | 1410 ++++ src/librustc/hir/map/collector.rs | 9 + src/librustc/hir/map/def_collector.rs | 91 +- src/librustc/hir/map/definitions.rs | 44 +- src/librustc/hir/map/hir_id_validator.rs | 7 +- src/librustc/hir/map/mod.rs | 83 +- src/librustc/hir/mod.rs | 99 +- src/librustc/hir/print.rs | 1904 +++-- src/librustc/hir/ptr.rs | 141 + src/librustc/hir/upvars.rs | 2 +- src/librustc/ich/hcx.rs | 10 +- src/librustc/ich/impls_syntax.rs | 23 +- src/librustc/infer/canonical/canonicalizer.rs | 2 +- src/librustc/infer/canonical/mod.rs | 2 +- src/librustc/infer/combine.rs | 4 + src/librustc/infer/equate.rs | 2 + src/librustc/infer/error_reporting/mod.rs | 42 +- .../infer/error_reporting/need_type_info.rs | 6 +- .../nice_region_error/find_anon_type.rs | 17 +- src/librustc/infer/glb.rs | 2 + .../infer/lexical_region_resolve/README.md | 2 +- .../infer/lexical_region_resolve/mod.rs | 21 +- src/librustc/infer/lub.rs | 2 + src/librustc/infer/mod.rs | 27 +- src/librustc/infer/nll_relate/mod.rs | 8 +- src/librustc/infer/opaque_types/mod.rs | 200 +- src/librustc/infer/outlives/env.rs | 2 +- src/librustc/infer/outlives/obligations.rs | 2 +- .../infer/region_constraints/leak_check.rs | 4 +- src/librustc/infer/region_constraints/mod.rs | 2 +- src/librustc/infer/sub.rs | 3 + src/librustc/infer/type_variable.rs | 2 +- src/librustc/lib.rs | 45 +- src/librustc/lint/builtin.rs | 33 +- src/librustc/lint/context.rs | 22 +- src/librustc/lint/internal.rs | 82 +- src/librustc/lint/mod.rs | 58 +- src/librustc/middle/allocator.rs | 16 - src/librustc/middle/borrowck.rs | 5 - src/librustc/middle/cstore.rs | 6 +- src/librustc/middle/dead.rs | 28 +- src/librustc/middle/dependency_format.rs | 8 +- src/librustc/middle/entry.rs | 14 +- src/librustc/middle/expr_use_visitor.rs | 11 +- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/lang_items.rs | 33 +- src/librustc/middle/lib_features.rs | 8 +- src/librustc/middle/liveness.rs | 88 +- src/librustc/middle/mem_categorization.rs | 90 +- src/librustc/middle/reachable.rs | 28 +- src/librustc/middle/region.rs | 11 +- src/librustc/middle/resolve_lifetime.rs | 197 +- src/librustc/middle/stability.rs | 238 +- src/librustc/mir/cache.rs | 18 +- src/librustc/mir/interpret/allocation.rs | 14 +- src/librustc/mir/interpret/error.rs | 516 +- src/librustc/mir/interpret/mod.rs | 98 +- src/librustc/mir/interpret/pointer.rs | 14 +- src/librustc/mir/interpret/value.rs | 69 +- src/librustc/mir/mod.rs | 918 +-- src/librustc/mir/mono.rs | 2 +- src/librustc/mir/tcx.rs | 24 +- src/librustc/mir/visit.rs | 51 +- src/librustc/query/mod.rs | 15 +- src/librustc/session/config.rs | 199 +- src/librustc/session/mod.rs | 57 +- src/librustc/tests.rs | 13 + src/librustc/traits/coherence.rs | 10 +- src/librustc/traits/error_reporting.rs | 21 +- src/librustc/traits/object_safety.rs | 2 +- src/librustc/traits/project.rs | 6 +- src/librustc/traits/query/normalize.rs | 2 +- .../traits/query/normalize_erasing_regions.rs | 2 +- src/librustc/traits/select.rs | 12 +- src/librustc/traits/specialize/mod.rs | 10 +- .../traits/specialize/specialization_graph.rs | 4 +- src/librustc/traits/structural_impls.rs | 6 +- src/librustc/traits/util.rs | 2 +- src/librustc/ty/_match.rs | 6 +- src/librustc/ty/codec.rs | 6 +- src/librustc/ty/context.rs | 286 +- src/librustc/ty/error.rs | 2 +- src/librustc/ty/flags.rs | 2 + .../ty/inhabitedness/def_id_forest.rs | 2 +- src/librustc/ty/inhabitedness/mod.rs | 3 +- src/librustc/ty/layout.rs | 263 +- src/librustc/ty/mod.rs | 109 +- src/librustc/ty/print/obsolete.rs | 3 +- src/librustc/ty/print/pretty.rs | 60 +- src/librustc/ty/query/config.rs | 6 +- src/librustc/ty/query/job.rs | 49 +- src/librustc/ty/query/mod.rs | 4 +- src/librustc/ty/query/on_disk_cache.rs | 107 +- src/librustc/ty/query/plumbing.rs | 50 +- src/librustc/ty/relate.rs | 18 +- src/librustc/ty/structural_impls.rs | 4 +- src/librustc/ty/sty.rs | 114 +- src/librustc/ty/subst.rs | 4 +- src/librustc/ty/trait_def.rs | 2 +- src/librustc/ty/util.rs | 125 +- src/librustc/ty/walk.rs | 4 +- src/librustc/ty/wf.rs | 2 +- src/librustc/util/common.rs | 30 +- src/librustc/util/common/tests.rs | 14 + src/librustc_allocator/Cargo.toml | 20 - src/librustc_allocator/expand.rs | 301 - src/librustc_allocator/lib.rs | 45 - src/librustc_apfloat/Cargo.toml | 1 - src/librustc_apfloat/lib.rs | 4 - src/librustc_asan/lib.rs | 2 - .../Cargo.toml | 7 +- .../borrowck/README.md | 4 +- .../borrowck/check_loans.rs | 372 +- .../borrowck/gather_loans/gather_moves.rs | 92 +- .../borrowck/gather_loans/lifetime.rs | 23 +- .../borrowck/gather_loans/mod.rs | 142 +- .../borrowck/gather_loans/restrictions.rs | 21 +- src/librustc_ast_borrowck/borrowck/mod.rs | 621 ++ .../borrowck/move_data.rs | 33 +- .../dataflow.rs | 30 +- .../graphviz.rs | 0 .../lib.rs | 3 - .../borrowck/gather_loans/move_error.rs | 186 - src/librustc_borrowck/borrowck/mod.rs | 1573 ---- src/librustc_borrowck/error_codes.rs | 1 - src/librustc_codegen_llvm/Cargo.toml | 2 +- src/librustc_codegen_llvm/abi.rs | 64 +- src/librustc_codegen_llvm/allocator.rs | 3 +- src/librustc_codegen_llvm/asm.rs | 4 +- src/librustc_codegen_llvm/attributes.rs | 24 + src/librustc_codegen_llvm/back/archive.rs | 23 +- src/librustc_codegen_llvm/back/lto.rs | 7 +- src/librustc_codegen_llvm/back/write.rs | 94 +- src/librustc_codegen_llvm/base.rs | 4 +- src/librustc_codegen_llvm/builder.rs | 22 +- src/librustc_codegen_llvm/common.rs | 31 +- src/librustc_codegen_llvm/consts.rs | 4 +- src/librustc_codegen_llvm/context.rs | 30 +- .../debuginfo/metadata.rs | 48 +- src/librustc_codegen_llvm/declare.rs | 2 +- src/librustc_codegen_llvm/error_codes.rs | 2 - src/librustc_codegen_llvm/intrinsic.rs | 35 +- src/librustc_codegen_llvm/lib.rs | 12 +- src/librustc_codegen_llvm/llvm/ffi.rs | 19 +- src/librustc_codegen_llvm/llvm/mod.rs | 3 - src/librustc_codegen_llvm/llvm_util.rs | 2 +- src/librustc_codegen_llvm/metadata.rs | 13 +- src/librustc_codegen_llvm/type_.rs | 2 - src/librustc_codegen_ssa/Cargo.toml | 5 +- src/librustc_codegen_ssa/back/command.rs | 6 +- src/librustc_codegen_ssa/back/link.rs | 22 +- src/librustc_codegen_ssa/back/linker.rs | 69 +- src/librustc_codegen_ssa/back/mod.rs | 1 - .../back/symbol_export.rs | 36 +- src/librustc_codegen_ssa/back/wasm.rs | 191 - src/librustc_codegen_ssa/back/write.rs | 15 +- src/librustc_codegen_ssa/base.rs | 20 +- src/librustc_codegen_ssa/debuginfo/mod.rs | 2 +- .../debuginfo/type_names.rs | 16 +- src/librustc_codegen_ssa/error_codes.rs | 2 - src/librustc_codegen_ssa/lib.rs | 8 +- src/librustc_codegen_ssa/mir/analyze.rs | 151 +- src/librustc_codegen_ssa/mir/block.rs | 61 +- src/librustc_codegen_ssa/mir/constant.rs | 2 +- src/librustc_codegen_ssa/mir/operand.rs | 24 +- src/librustc_codegen_ssa/mir/place.rs | 169 +- src/librustc_codegen_ssa/mir/rvalue.rs | 28 +- src/librustc_codegen_ssa/mir/statement.rs | 11 +- src/librustc_codegen_ssa/traits/backend.rs | 4 +- src/librustc_codegen_ssa/traits/builder.rs | 2 +- src/librustc_codegen_ssa/traits/consts.rs | 2 +- src/librustc_codegen_ssa/traits/type_.rs | 5 +- src/librustc_codegen_utils/Cargo.toml | 1 - src/librustc_codegen_utils/codegen_backend.rs | 2 - src/librustc_codegen_utils/lib.rs | 5 - src/librustc_codegen_utils/link.rs | 2 +- src/librustc_codegen_utils/symbol_names/v0.rs | 2 +- .../symbol_names_test.rs | 4 +- src/librustc_cratesio_shim/Cargo.toml | 26 - src/librustc_cratesio_shim/src/lib.rs | 11 - src/librustc_data_structures/Cargo.toml | 6 +- src/librustc_data_structures/base_n.rs | 24 +- src/librustc_data_structures/base_n/tests.rs | 22 + .../binary_search_util/mod.rs | 2 +- .../binary_search_util/{test.rs => tests.rs} | 0 src/librustc_data_structures/bit_set.rs | 374 +- src/librustc_data_structures/bit_set/tests.rs | 369 + src/librustc_data_structures/fingerprint.rs | 13 +- src/librustc_data_structures/flock.rs | 12 +- .../graph/dominators/mod.rs | 7 +- .../graph/dominators/{test.rs => tests.rs} | 8 +- .../graph/implementation/mod.rs | 6 +- .../graph/iterate/mod.rs | 2 +- .../graph/iterate/{test.rs => tests.rs} | 2 +- src/librustc_data_structures/graph/mod.rs | 16 +- .../graph/reference.rs | 8 +- src/librustc_data_structures/graph/scc/mod.rs | 3 +- .../graph/scc/{test.rs => tests.rs} | 4 +- .../graph/{test.rs => tests.rs} | 8 +- .../graph/vec_graph/mod.rs | 2 +- .../graph/vec_graph/{test.rs => tests.rs} | 0 src/librustc_data_structures/indexed_vec.rs | 63 +- src/librustc_data_structures/interner.rs | 58 - src/librustc_data_structures/lib.rs | 13 +- src/librustc_data_structures/macros.rs | 4 +- .../obligation_forest/mod.rs | 2 +- .../obligation_forest/{test.rs => tests.rs} | 4 +- .../owning_ref/mod.rs | 23 +- .../owning_ref/tests.rs | 20 +- src/librustc_data_structures/sharded.rs | 128 + src/librustc_data_structures/sip128.rs | 233 +- src/librustc_data_structures/sip128/tests.rs | 226 + src/librustc_data_structures/small_c_str.rs | 47 +- .../small_c_str/tests.rs | 45 + .../snapshot_map/mod.rs | 2 +- .../snapshot_map/{test.rs => tests.rs} | 0 src/librustc_data_structures/svh.rs | 2 +- src/librustc_data_structures/sync.rs | 55 +- src/librustc_data_structures/tiny_list.rs | 139 +- .../tiny_list/tests.rs | 133 + .../transitive_relation.rs | 358 +- .../transitive_relation/tests.rs | 357 + src/librustc_driver/Cargo.toml | 18 +- src/librustc_driver/lib.rs | 87 +- src/librustc_driver/pretty.rs | 206 +- src/librustc_errors/Cargo.toml | 7 +- .../annotate_snippet_emitter_writer.rs | 8 +- src/librustc_errors/diagnostic_builder.rs | 9 +- src/librustc_errors/emitter.rs | 66 +- src/librustc_errors/lib.rs | 94 +- src/librustc_fs_util/Cargo.toml | 1 - src/librustc_fs_util/lib.rs | 2 - src/librustc_incremental/Cargo.toml | 4 +- src/librustc_incremental/assert_dep_graph.rs | 6 +- .../assert_module_sources.rs | 2 +- src/librustc_incremental/lib.rs | 7 - .../persist/dirty_clean.rs | 12 +- src/librustc_incremental/persist/fs.rs | 73 +- src/librustc_incremental/persist/fs/tests.rs | 65 + src/librustc_incremental/persist/load.rs | 4 +- src/librustc_incremental/persist/save.rs | 2 +- src/librustc_interface/Cargo.toml | 8 +- src/librustc_interface/interface.rs | 1 - src/librustc_interface/lib.rs | 6 - src/librustc_interface/passes.rs | 143 +- src/librustc_interface/proc_macro_decls.rs | 6 +- src/librustc_interface/queries.rs | 30 +- src/librustc_interface/util.rs | 8 +- src/librustc_lexer/Cargo.toml | 15 + src/librustc_lexer/src/cursor.rs | 57 + src/librustc_lexer/src/lib.rs | 710 ++ src/librustc_lexer/src/unescape.rs | 325 + src/librustc_lexer/src/unescape/tests.rs | 276 + src/librustc_lint/Cargo.toml | 1 - src/librustc_lint/builtin.rs | 222 +- src/librustc_lint/error_codes.rs | 2 +- src/librustc_lint/lib.rs | 33 +- src/librustc_lint/non_ascii_idents.rs | 22 + src/librustc_lint/nonstandard_style.rs | 4 +- src/librustc_lint/types.rs | 10 +- src/librustc_lint/unused.rs | 122 +- src/librustc_llvm/build.rs | 17 +- src/librustc_llvm/lib.rs | 7 +- src/librustc_lsan/lib.rs | 2 - src/librustc_macros/src/lib.rs | 2 +- src/librustc_macros/src/query.rs | 13 + src/librustc_metadata/Cargo.toml | 5 +- src/librustc_metadata/creader.rs | 38 +- src/librustc_metadata/cstore_impl.rs | 6 +- src/librustc_metadata/decoder.rs | 21 +- src/librustc_metadata/encoder.rs | 67 +- src/librustc_metadata/error_codes.rs | 9 +- src/librustc_metadata/foreign_modules.rs | 6 +- src/librustc_metadata/lib.rs | 11 +- src/librustc_metadata/link_args.rs | 2 +- src/librustc_metadata/native_libs.rs | 12 +- src/librustc_metadata/schema.rs | 13 +- src/librustc_mir/Cargo.toml | 6 +- src/librustc_mir/borrow_check/borrow_set.rs | 7 +- .../borrow_check/conflict_errors.rs | 286 +- .../borrow_check/error_reporting.rs | 354 +- src/librustc_mir/borrow_check/flows.rs | 17 +- src/librustc_mir/borrow_check/mod.rs | 464 +- src/librustc_mir/borrow_check/move_errors.rs | 222 +- .../borrow_check/mutability_errors.rs | 391 +- .../borrow_check/nll/constraint_generation.rs | 138 +- .../borrow_check/nll/constraints/graph.rs | 6 +- .../borrow_check/nll/explain_borrow/mod.rs | 69 +- src/librustc_mir/borrow_check/nll/facts.rs | 54 +- .../borrow_check/nll/invalidation.rs | 11 +- src/librustc_mir/borrow_check/nll/mod.rs | 6 +- .../nll/region_infer/error_reporting/mod.rs | 10 +- .../borrow_check/nll/region_infer/mod.rs | 18 +- .../borrow_check/nll/region_infer/values.rs | 2 +- .../nll/type_check/input_output.rs | 5 +- .../nll/type_check/liveness/mod.rs | 15 +- .../nll/type_check/liveness/polonius.rs | 94 + .../nll/type_check/liveness/trace.rs | 145 +- .../borrow_check/nll/type_check/mod.rs | 191 +- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/borrow_check/path_utils.rs | 8 +- src/librustc_mir/borrow_check/place_ext.rs | 2 +- .../borrow_check/places_conflict.rs | 35 +- src/librustc_mir/borrow_check/prefixes.rs | 85 +- src/librustc_mir/borrow_check/used_muts.rs | 9 +- src/librustc_mir/build/expr/as_place.rs | 23 +- src/librustc_mir/build/expr/as_rvalue.rs | 61 +- src/librustc_mir/build/expr/as_temp.rs | 65 +- src/librustc_mir/build/expr/category.rs | 2 +- src/librustc_mir/build/expr/into.rs | 106 +- src/librustc_mir/build/matches/mod.rs | 59 +- src/librustc_mir/build/matches/simplify.rs | 3 +- src/librustc_mir/build/matches/test.rs | 17 +- src/librustc_mir/build/mod.rs | 82 +- src/librustc_mir/build/scope.rs | 26 +- src/librustc_mir/const_eval.rs | 104 +- .../dataflow/drop_flag_effects.rs | 6 +- .../dataflow/impls/borrowed_locals.rs | 2 +- src/librustc_mir/dataflow/impls/borrows.rs | 10 +- src/librustc_mir/dataflow/impls/mod.rs | 6 +- .../dataflow/impls/storage_liveness.rs | 12 +- src/librustc_mir/dataflow/mod.rs | 17 +- .../dataflow/move_paths/builder.rs | 52 +- src/librustc_mir/dataflow/move_paths/mod.rs | 9 +- src/librustc_mir/error_codes.rs | 20 +- src/librustc_mir/hair/cx/expr.rs | 17 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/hair/cx/to_ref.rs | 2 +- src/librustc_mir/hair/mod.rs | 1 - src/librustc_mir/hair/pattern/_match.rs | 107 +- src/librustc_mir/hair/pattern/check_match.rs | 69 +- src/librustc_mir/hair/pattern/mod.rs | 247 +- src/librustc_mir/interpret/cast.rs | 167 +- src/librustc_mir/interpret/eval_context.rs | 143 +- src/librustc_mir/interpret/intern.rs | 19 +- src/librustc_mir/interpret/intrinsics.rs | 37 +- src/librustc_mir/interpret/machine.rs | 74 +- src/librustc_mir/interpret/memory.rs | 278 +- src/librustc_mir/interpret/mod.rs | 4 +- src/librustc_mir/interpret/operand.rs | 101 +- src/librustc_mir/interpret/operator.rs | 73 +- src/librustc_mir/interpret/place.rs | 109 +- src/librustc_mir/interpret/snapshot.rs | 13 +- src/librustc_mir/interpret/step.rs | 21 +- src/librustc_mir/interpret/terminator.rs | 118 +- src/librustc_mir/interpret/traits.rs | 18 +- src/librustc_mir/interpret/validity.rs | 138 +- src/librustc_mir/interpret/visitor.rs | 28 +- src/librustc_mir/lib.rs | 16 +- src/librustc_mir/monomorphize/collector.rs | 51 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 10 +- src/librustc_mir/shim.rs | 10 +- src/librustc_mir/transform/add_retag.rs | 53 +- src/librustc_mir/transform/check_unsafety.rs | 45 +- src/librustc_mir/transform/const_prop.rs | 133 +- src/librustc_mir/transform/copy_prop.rs | 44 +- src/librustc_mir/transform/dump_mir.rs | 4 +- src/librustc_mir/transform/elaborate_drops.rs | 12 +- src/librustc_mir/transform/generator.rs | 56 +- src/librustc_mir/transform/inline.rs | 44 +- src/librustc_mir/transform/instcombine.rs | 21 +- src/librustc_mir/transform/lower_128bit.rs | 230 - src/librustc_mir/transform/mod.rs | 26 +- src/librustc_mir/transform/promote_consts.rs | 55 +- src/librustc_mir/transform/qualify_consts.rs | 355 +- .../transform/remove_noop_landing_pads.rs | 5 +- src/librustc_mir/transform/rustc_peek.rs | 14 +- src/librustc_mir/transform/simplify.rs | 2 +- .../transform/simplify_branches.rs | 12 +- .../transform/uniform_array_move_out.rs | 114 +- src/librustc_mir/util/alignment.rs | 13 +- src/librustc_mir/util/borrowck_errors.rs | 502 +- src/librustc_mir/util/def_use.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 17 +- src/librustc_mir/util/graphviz.rs | 4 +- src/librustc_mir/util/liveness.rs | 8 +- src/librustc_mir/util/mod.rs | 17 - src/librustc_mir/util/pretty.rs | 2 +- src/librustc_msan/lib.rs | 2 - src/librustc_passes/Cargo.toml | 3 - src/librustc_passes/ast_validation.rs | 16 +- src/librustc_passes/error_codes.rs | 4 +- src/librustc_passes/hir_stats.rs | 7 +- src/librustc_passes/layout_test.rs | 6 +- src/librustc_passes/lib.rs | 4 - src/librustc_passes/loops.rs | 34 +- src/librustc_passes/rvalue_promotion.rs | 25 +- src/librustc_plugin/Cargo.toml | 2 +- src/librustc_plugin/build.rs | 6 +- src/librustc_plugin/error_codes.rs | 4 +- src/librustc_plugin/lib.rs | 3 +- src/librustc_plugin/registry.rs | 12 +- src/librustc_privacy/Cargo.toml | 1 - src/librustc_privacy/error_codes.rs | 2 - src/librustc_privacy/lib.rs | 288 +- src/librustc_resolve/Cargo.toml | 2 +- src/librustc_resolve/build_reduced_graph.rs | 797 +- src/librustc_resolve/check_unused.rs | 201 +- src/librustc_resolve/diagnostics.rs | 1035 ++- src/librustc_resolve/error_codes.rs | 4 +- src/librustc_resolve/late.rs | 1994 +++++ src/librustc_resolve/late/diagnostics.rs | 769 ++ src/librustc_resolve/lib.rs | 4260 ++-------- src/librustc_resolve/macros.rs | 988 +-- src/librustc_resolve/resolve_imports.rs | 287 +- src/librustc_save_analysis/Cargo.toml | 1 - src/librustc_save_analysis/dump_visitor.rs | 79 +- .../{json_dumper.rs => dumper.rs} | 61 +- src/librustc_save_analysis/lib.rs | 120 +- src/librustc_save_analysis/sig.rs | 22 +- src/librustc_save_analysis/span_utils.rs | 2 +- src/librustc_target/Cargo.toml | 4 +- src/librustc_target/abi/call/hexagon.rs | 2 - src/librustc_target/abi/mod.rs | 105 +- src/librustc_target/lib.rs | 16 - .../spec/aarch64_unknown_redox.rs | 20 + .../spec/aarch64_wrs_vxworks.rs | 24 + src/librustc_target/spec/abi.rs | 29 +- src/librustc_target/spec/abi/tests.rs | 27 + src/librustc_target/spec/apple_ios_base.rs | 14 + .../spec/arm_linux_androideabi.rs | 2 +- .../spec/arm_unknown_linux_gnueabi.rs | 2 +- .../spec/arm_unknown_linux_gnueabihf.rs | 4 +- .../spec/arm_unknown_linux_musleabi.rs | 2 +- .../spec/arm_unknown_linux_musleabihf.rs | 4 +- src/librustc_target/spec/arm_wrs_vxworks.rs | 31 + .../spec/arm_wrs_vxworks_sf.rs | 25 + .../spec/armebv7r_none_eabi.rs | 2 +- .../spec/armebv7r_none_eabihf.rs | 4 +- .../spec/armv4t_unknown_linux_gnueabi.rs | 2 +- .../spec/armv5te_unknown_linux_gnueabi.rs | 2 +- .../spec/armv5te_unknown_linux_musleabi.rs | 2 +- .../spec/armv6_unknown_freebsd.rs | 4 +- .../spec/armv6_unknown_netbsd_eabihf.rs | 4 +- src/librustc_target/spec/armv7_apple_ios.rs | 2 +- .../spec/armv7_linux_androideabi.rs | 4 +- .../spec/armv7_unknown_cloudabi_eabihf.rs | 2 +- .../spec/armv7_unknown_freebsd.rs | 4 +- .../spec/armv7_unknown_linux_gnueabi.rs | 29 + .../spec/armv7_unknown_linux_gnueabihf.rs | 4 +- .../spec/armv7_unknown_linux_musleabi.rs | 34 + .../spec/armv7_unknown_linux_musleabihf.rs | 4 +- .../spec/armv7_unknown_netbsd_eabihf.rs | 4 +- src/librustc_target/spec/armv7_wrs_vxworks.rs | 31 + src/librustc_target/spec/armv7r_none_eabi.rs | 2 +- .../spec/armv7r_none_eabihf.rs | 4 +- src/librustc_target/spec/armv7s_apple_ios.rs | 2 +- .../spec/hexagon_unknown_linux_musl.rs | 36 + src/librustc_target/spec/i586_wrs_vxworks.rs | 8 + .../spec/i686_uwp_windows_gnu.rs | 27 + src/librustc_target/spec/i686_wrs_vxworks.rs | 23 + .../spec/i686_wrs_vxworks_gnu.rs | 23 + src/librustc_target/spec/mod.rs | 38 +- .../spec/powerpc64_wrs_vxworks.rs | 25 + .../spec/powerpc64_wrs_vxworks_gnusf.rs | 26 + .../spec/powerpc_wrs_vxworks.rs | 26 + .../spec/powerpc_wrs_vxworks_gnusf.rs | 26 + .../spec/powerpc_wrs_vxworks_gnuspesf.rs | 27 + .../spec/powerpc_wrs_vxworks_spe.rs | 27 + src/librustc_target/spec/redox_base.rs | 15 +- .../spec/riscv32i_unknown_none_elf.rs | 32 + .../spec/riscv64gc_unknown_none_elf.rs | 1 + .../spec/riscv64imac_unknown_none_elf.rs | 1 + .../spec/thumbv6m_none_eabi.rs | 2 +- .../spec/thumbv7a_pc_windows_msvc.rs | 2 +- .../spec/thumbv7em_none_eabi.rs | 2 +- .../spec/thumbv7em_none_eabihf.rs | 10 +- .../spec/thumbv7m_none_eabi.rs | 2 +- .../spec/thumbv7neon_linux_androideabi.rs | 2 +- .../thumbv7neon_unknown_linux_gnueabihf.rs | 2 +- .../spec/thumbv8m_base_none_eabi.rs | 2 +- .../spec/thumbv8m_main_none_eabi.rs | 2 +- .../spec/thumbv8m_main_none_eabihf.rs | 4 +- src/librustc_target/spec/vxworks_base.rs | 41 + src/librustc_target/spec/wasm32_base.rs | 8 + src/librustc_target/spec/windows_msvc_base.rs | 4 + src/librustc_target/spec/windows_uwp_base.rs | 64 + .../spec/x86_64_fortanix_unknown_sgx.rs | 2 +- .../spec/x86_64_unknown_linux_gnux32.rs | 3 +- .../spec/x86_64_unknown_redox.rs | 2 +- .../spec/x86_64_uwp_windows_gnu.rs | 22 + .../spec/x86_64_wrs_vxworks.rs | 23 + src/librustc_traits/Cargo.toml | 1 - .../program_clauses/primitive.rs | 16 +- .../chalk_context/resolvent_ops.rs | 5 + src/librustc_traits/dropck_outlives.rs | 8 +- src/librustc_traits/lib.rs | 4 - src/librustc_traits/lowering/environment.rs | 2 +- src/librustc_traits/lowering/mod.rs | 24 +- src/librustc_tsan/lib.rs | 2 - src/librustc_typeck/Cargo.toml | 2 +- src/librustc_typeck/astconv.rs | 122 +- src/librustc_typeck/check/_match.rs | 66 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/coercion.rs | 8 +- src/librustc_typeck/check/demand.rs | 82 +- src/librustc_typeck/check/dropck.rs | 6 +- src/librustc_typeck/check/expr.rs | 82 +- .../check/generator_interior.rs | 6 +- src/librustc_typeck/check/intrinsic.rs | 8 +- src/librustc_typeck/check/method/mod.rs | 4 +- src/librustc_typeck/check/method/probe.rs | 12 +- src/librustc_typeck/check/method/suggest.rs | 193 +- src/librustc_typeck/check/mod.rs | 334 +- src/librustc_typeck/check/regionck.rs | 15 +- src/librustc_typeck/check/upvar.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 125 +- src/librustc_typeck/check/writeback.rs | 216 +- src/librustc_typeck/check_unused.rs | 8 +- src/librustc_typeck/coherence/builtin.rs | 10 +- .../coherence/inherent_impls.rs | 45 +- .../coherence/inherent_impls_overlap.rs | 4 +- src/librustc_typeck/coherence/mod.rs | 10 +- src/librustc_typeck/coherence/orphan.rs | 4 +- src/librustc_typeck/coherence/unsafety.rs | 4 +- src/librustc_typeck/collect.rs | 413 +- src/librustc_typeck/error_codes.rs | 56 +- src/librustc_typeck/impl_wf_check.rs | 18 +- src/librustc_typeck/lib.rs | 31 +- src/librustc_typeck/namespace.rs | 6 +- .../outlives/implicit_infer.rs | 2 +- src/librustc_typeck/outlives/mod.rs | 12 +- src/librustc_typeck/outlives/test.rs | 4 +- src/librustc_typeck/outlives/utils.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustc_typeck/variance/mod.rs | 4 +- src/librustc_typeck/variance/solve.rs | 4 +- src/librustc_typeck/variance/terms.rs | 2 +- src/librustc_typeck/variance/test.rs | 4 +- src/librustdoc/Cargo.toml | 5 +- src/librustdoc/clean/blanket_impl.rs | 7 +- src/librustdoc/clean/cfg.rs | 420 +- src/librustdoc/clean/cfg/tests.rs | 412 + src/librustdoc/clean/inline.rs | 81 +- src/librustdoc/clean/mod.rs | 226 +- src/librustdoc/clean/simplify.rs | 2 +- src/librustdoc/config.rs | 57 +- src/librustdoc/core.rs | 81 +- src/librustdoc/doctree.rs | 94 +- src/librustdoc/externalfiles.rs | 48 +- src/librustdoc/fold.rs | 8 +- src/librustdoc/html/format.rs | 3 +- src/librustdoc/html/highlight.rs | 70 +- src/librustdoc/html/item_type.rs | 9 +- src/librustdoc/html/markdown.rs | 286 +- src/librustdoc/html/markdown/tests.rs | 32 +- src/librustdoc/html/render.rs | 165 +- src/librustdoc/html/render/tests.rs | 29 + src/librustdoc/html/static/rustdoc.css | 5 + src/librustdoc/html/static/storage.js | 4 +- src/librustdoc/html/toc.rs | 2 +- src/librustdoc/lib.rs | 28 +- src/librustdoc/markdown.rs | 14 +- .../passes/check_code_block_syntax.rs | 37 +- src/librustdoc/passes/collapse_docs.rs | 8 +- .../passes/collect_intra_doc_links.rs | 51 +- src/librustdoc/passes/collect_trait_impls.rs | 12 +- src/librustdoc/passes/mod.rs | 86 +- src/librustdoc/passes/unindent_comments.rs | 79 +- .../passes/unindent_comments/tests.rs | 72 + src/librustdoc/test.rs | 2 +- src/librustdoc/theme.rs | 109 +- src/librustdoc/theme/tests.rs | 102 + src/librustdoc/visit_ast.rs | 141 +- src/libserialize/Cargo.toml | 1 - src/libserialize/collection_impls.rs | 10 +- src/libserialize/json.rs | 18 +- src/libserialize/leb128.rs | 44 - src/libserialize/lib.rs | 3 +- src/libserialize/serialize.rs | 6 +- src/libserialize/tests/json.rs | 1 - src/libserialize/tests/leb128.rs | 46 + src/libserialize/tests/opaque.rs | 1 - src/libstd/Cargo.toml | 11 +- src/libstd/build.rs | 6 +- src/libstd/collections/hash/map.rs | 4 +- src/libstd/collections/hash/set.rs | 4 +- src/libstd/env.rs | 17 + src/libstd/error.rs | 10 +- src/libstd/f32.rs | 6 +- src/libstd/f64.rs | 6 +- src/libstd/ffi/c_str.rs | 21 +- src/libstd/ffi/os_str.rs | 13 +- src/libstd/fs.rs | 6 +- src/libstd/io/mod.rs | 212 +- src/libstd/io/util.rs | 18 +- src/libstd/keyword_docs.rs | 71 +- src/libstd/lib.rs | 81 +- src/libstd/macros.rs | 533 +- src/libstd/net/udp.rs | 4 +- src/libstd/os/linux/fs.rs | 7 +- src/libstd/os/linux/raw.rs | 56 + src/libstd/os/mod.rs | 4 +- src/libstd/os/raw/mod.rs | 58 +- src/libstd/os/redox/fs.rs | 383 + src/libstd/os/redox/mod.rs | 6 + src/libstd/os/redox/raw.rs | 67 + src/libstd/os/vxworks/fs.rs | 84 + src/libstd/os/vxworks/mod.rs | 6 + src/libstd/os/vxworks/raw.rs | 7 + src/libstd/panicking.rs | 2 +- src/libstd/path.rs | 16 +- src/libstd/prelude/mod.rs | 3 - src/libstd/prelude/v1.rs | 64 +- src/libstd/primitive_docs.rs | 29 +- src/libstd/process.rs | 27 - src/libstd/sync/condvar.rs | 36 +- src/libstd/sync/mod.rs | 1 + src/libstd/sync/mpsc/sync.rs | 18 +- src/libstd/sys/cloudabi/abi/cloudabi.rs | 4 +- src/libstd/sys/cloudabi/condvar.rs | 29 +- src/libstd/sys/cloudabi/io.rs | 14 + src/libstd/sys/cloudabi/mod.rs | 11 +- src/libstd/sys/cloudabi/mutex.rs | 26 +- src/libstd/sys/cloudabi/time.rs | 12 +- src/libstd/sys/mod.rs | 10 +- src/libstd/sys/redox/condvar.rs | 111 - src/libstd/sys/redox/ext/fs.rs | 339 - src/libstd/sys/redox/ext/mod.rs | 45 - src/libstd/sys/redox/ext/net.rs | 759 -- src/libstd/sys/redox/ext/thread.rs | 39 - src/libstd/sys/redox/fast_thread_local.rs | 4 - src/libstd/sys/redox/fd.rs | 88 - src/libstd/sys/redox/fs.rs | 447 - src/libstd/sys/redox/io.rs | 32 - src/libstd/sys/redox/memchr.rs | 4 - src/libstd/sys/redox/mod.rs | 96 - src/libstd/sys/redox/mutex.rs | 169 - src/libstd/sys/redox/net/dns/answer.rs | 12 - src/libstd/sys/redox/net/dns/mod.rs | 205 - src/libstd/sys/redox/net/dns/query.rs | 8 - src/libstd/sys/redox/net/mod.rs | 140 - src/libstd/sys/redox/net/netc.rs | 47 - src/libstd/sys/redox/net/tcp.rs | 251 - src/libstd/sys/redox/net/udp.rs | 237 - src/libstd/sys/redox/path.rs | 29 - src/libstd/sys/redox/pipe.rs | 101 - src/libstd/sys/redox/process.rs | 609 -- src/libstd/sys/redox/rand.rs | 3 - src/libstd/sys/redox/rwlock.rs | 51 - src/libstd/sys/redox/syscall/arch/arm.rs | 73 - src/libstd/sys/redox/syscall/arch/x86.rs | 73 - src/libstd/sys/redox/syscall/arch/x86_64.rs | 74 - src/libstd/sys/redox/syscall/call.rs | 348 - src/libstd/sys/redox/syscall/data.rs | 191 - src/libstd/sys/redox/syscall/error.rs | 315 - src/libstd/sys/redox/syscall/flag.rs | 148 - src/libstd/sys/redox/syscall/mod.rs | 33 - src/libstd/sys/redox/syscall/number.rs | 73 - src/libstd/sys/redox/thread.rs | 84 - src/libstd/sys/redox/thread_local.rs | 61 - src/libstd/sys/redox/time.rs | 207 - src/libstd/sys/sgx/abi/usercalls/alloc.rs | 12 +- src/libstd/sys/sgx/io.rs | 14 + src/libstd/sys/sgx/mod.rs | 2 +- src/libstd/sys/unix/alloc.rs | 12 +- src/libstd/sys/unix/args.rs | 3 +- src/libstd/sys/unix/condvar.rs | 6 +- src/libstd/sys/unix/env.rs | 11 + src/libstd/sys/unix/ext/net.rs | 4 +- src/libstd/sys/unix/fast_thread_local.rs | 2 +- src/libstd/sys/unix/fd.rs | 8 +- src/libstd/sys/unix/fs.rs | 27 +- src/libstd/sys/unix/io.rs | 25 + src/libstd/sys/unix/mod.rs | 1 + src/libstd/sys/unix/os.rs | 30 +- src/libstd/sys/unix/pipe.rs | 3 +- src/libstd/sys/unix/process/process_common.rs | 10 +- src/libstd/sys/unix/process/process_unix.rs | 21 +- src/libstd/sys/unix/rand.rs | 15 +- src/libstd/sys/unix/thread.rs | 18 +- src/libstd/sys/unix/time.rs | 25 +- src/libstd/sys/vxworks/alloc.rs | 53 + src/libstd/sys/{redox => vxworks}/args.rs | 49 +- src/libstd/sys/vxworks/backtrace/mod.rs | 110 + .../sys/vxworks/backtrace/printing/dladdr.rs | 35 + .../sys/vxworks/backtrace/printing/mod.rs | 33 + .../vxworks/backtrace/tracing/backtrace_fn.rs | 39 + .../sys/vxworks/backtrace/tracing/gcc_s.rs | 99 + .../sys/vxworks/backtrace/tracing/mod.rs | 8 + src/libstd/sys/{redox => vxworks}/cmath.rs | 0 src/libstd/sys/vxworks/condvar.rs | 96 + src/libstd/sys/{redox => vxworks}/env.rs | 4 +- src/libstd/sys/{redox => vxworks}/ext/ffi.rs | 6 +- src/libstd/sys/vxworks/ext/fs.rs | 801 ++ src/libstd/sys/{redox => vxworks}/ext/io.rs | 80 +- src/libstd/sys/vxworks/ext/mod.rs | 20 + src/libstd/sys/vxworks/ext/net.rs | 1825 +++++ .../sys/{redox => vxworks}/ext/process.rs | 32 +- src/libstd/sys/vxworks/ext/raw.rs | 5 + src/libstd/sys/vxworks/fast_thread_local.rs | 36 + src/libstd/sys/vxworks/fd.rs | 188 + src/libstd/sys/vxworks/fs.rs | 575 ++ src/libstd/sys/vxworks/io.rs | 86 + src/libstd/sys/vxworks/memchr.rs | 24 + src/libstd/sys/vxworks/mod.rs | 125 + src/libstd/sys/vxworks/mutex.rs | 127 + src/libstd/sys/vxworks/net.rs | 357 + src/libstd/sys/{redox => vxworks}/os.rs | 191 +- src/libstd/sys/vxworks/path.rs | 19 + src/libstd/sys/vxworks/pipe.rs | 95 + src/libstd/sys/vxworks/process/mod.rs | 7 + .../sys/vxworks/process/process_common.rs | 405 + .../sys/vxworks/process/process_vxworks.rs | 156 + src/libstd/sys/vxworks/process/rtp.rs | 298 + src/libstd/sys/vxworks/rand.rs | 31 + src/libstd/sys/vxworks/rwlock.rs | 113 + src/libstd/sys/vxworks/stack_overflow.rs | 41 + src/libstd/sys/{redox => vxworks}/stdio.rs | 19 +- src/libstd/sys/vxworks/thread.rs | 143 + src/libstd/sys/vxworks/thread_local.rs | 34 + src/libstd/sys/vxworks/time.rs | 224 + src/libstd/sys/vxworks/weak.rs | 60 + src/libstd/sys/wasi/io.rs | 25 + src/libstd/sys/wasi/mod.rs | 2 + src/libstd/sys/wasm/fast_thread_local.rs | 9 + src/libstd/sys/wasm/io.rs | 14 + src/libstd/sys/wasm/mod.rs | 5 +- src/libstd/sys/wasm/thread.rs | 76 +- src/libstd/sys/wasm/thread_local.rs | 32 +- src/libstd/sys/wasm/thread_local_atomics.rs | 61 - src/libstd/sys/windows/c.rs | 221 +- src/libstd/sys/windows/compat.rs | 2 + src/libstd/sys/windows/ext/fs.rs | 30 + src/libstd/sys/windows/fs.rs | 88 +- src/libstd/sys/windows/io.rs | 25 + src/libstd/sys/windows/mod.rs | 15 +- src/libstd/sys/windows/net.rs | 51 +- src/libstd/sys/windows/os.rs | 23 +- src/libstd/sys/windows/path.rs | 2 +- src/libstd/sys/windows/pipe.rs | 11 +- src/libstd/sys/windows/process.rs | 7 +- src/libstd/sys/windows/rand.rs | 18 + .../stack_overflow_uwp.rs} | 10 +- src/libstd/sys/windows/stdio_uwp.rs | 85 + src/libstd/sys_common/alloc.rs | 3 +- src/libstd/sys_common/io.rs | 2 +- src/libstd/sys_common/mod.rs | 1 - src/libstd/sys_common/os_str_bytes.rs | 6 + src/libstd/thread/local.rs | 5 + src/libstd/thread/mod.rs | 2 +- src/libstd/time.rs | 10 +- src/libsyntax/Cargo.toml | 5 +- src/libsyntax/ast.rs | 168 +- src/libsyntax/ast/tests.rs | 8 + src/libsyntax/attr/builtin.rs | 147 +- src/libsyntax/attr/mod.rs | 73 +- src/libsyntax/diagnostics/macros.rs | 8 +- src/libsyntax/diagnostics/plugin.rs | 4 +- src/libsyntax/early_buffered_lints.rs | 1 + src/libsyntax/error_codes.rs | 4 +- src/libsyntax/ext/allocator.rs | 75 + src/libsyntax/ext/base.rs | 181 +- src/libsyntax/ext/build.rs | 549 +- src/libsyntax/ext/derive.rs | 75 - src/libsyntax/ext/expand.rs | 561 +- src/libsyntax/ext/placeholders.rs | 7 +- src/libsyntax/ext/proc_macro.rs | 217 + .../ext}/proc_macro_server.rs | 40 +- src/libsyntax/ext/tt/macro_check.rs | 626 ++ src/libsyntax/ext/tt/macro_parser.rs | 16 +- src/libsyntax/ext/tt/macro_rules.rs | 228 +- src/libsyntax/ext/tt/quoted.rs | 48 +- src/libsyntax/ext/tt/transcribe.rs | 38 +- src/libsyntax/feature_gate.rs | 391 +- src/libsyntax/json.rs | 10 +- src/libsyntax/lib.rs | 35 +- src/libsyntax/mut_visit.rs | 107 +- src/libsyntax/mut_visit/tests.rs | 71 + src/libsyntax/parse/attr.rs | 67 +- src/libsyntax/parse/diagnostics.rs | 293 +- src/libsyntax/parse/lexer/comments.rs | 347 +- src/libsyntax/parse/lexer/comments/tests.rs | 47 + src/libsyntax/parse/lexer/mod.rs | 1837 +---- src/libsyntax/parse/lexer/tests.rs | 255 + src/libsyntax/parse/lexer/tokentrees.rs | 27 +- src/libsyntax/parse/lexer/unicode_chars.rs | 171 +- src/libsyntax/parse/literal.rs | 8 +- src/libsyntax/parse/mod.rs | 309 +- src/libsyntax/parse/parser.rs | 7195 ++--------------- src/libsyntax/parse/parser/expr.rs | 1748 ++++ src/libsyntax/parse/parser/generics.rs | 276 + src/libsyntax/parse/parser/item.rs | 1915 +++++ src/libsyntax/parse/parser/module.rs | 332 + src/libsyntax/parse/parser/pat.rs | 634 ++ src/libsyntax/parse/parser/path.rs | 474 ++ src/libsyntax/parse/parser/stmt.rs | 458 ++ src/libsyntax/parse/parser/ty.rs | 461 ++ src/libsyntax/parse/tests.rs | 339 + src/libsyntax/parse/token.rs | 47 +- src/libsyntax/parse/unescape.rs | 602 -- .../parse/unescape_error_reporting.rs | 5 +- src/libsyntax/print/helpers.rs | 34 + src/libsyntax/print/pp.rs | 212 +- src/libsyntax/print/pprust.rs | 2944 +++---- src/libsyntax/print/pprust/tests.rs | 69 + src/libsyntax/ptr.rs | 6 +- src/libsyntax/source_map.rs | 246 +- src/libsyntax/source_map/tests.rs | 213 + src/libsyntax/{test_snippet.rs => tests.rs} | 98 +- src/libsyntax/tokenstream.rs | 135 +- src/libsyntax/tokenstream/tests.rs | 108 + src/libsyntax/util/lev_distance.rs | 60 +- src/libsyntax/util/lev_distance/tests.rs | 58 + src/libsyntax/util/parser.rs | 2 +- src/libsyntax/util/parser_testing.rs | 160 - src/libsyntax/visit.rs | 41 +- src/libsyntax_ext/Cargo.toml | 10 +- src/libsyntax_ext/asm.rs | 9 - src/libsyntax_ext/assert.rs | 6 +- src/libsyntax_ext/cfg.rs | 3 +- src/libsyntax_ext/concat.rs | 3 +- src/libsyntax_ext/concat_idents.rs | 13 +- src/libsyntax_ext/deriving/clone.rs | 11 +- src/libsyntax_ext/deriving/cmp/eq.rs | 7 +- src/libsyntax_ext/deriving/cmp/ord.rs | 3 +- src/libsyntax_ext/deriving/cmp/partial_eq.rs | 7 +- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 5 +- src/libsyntax_ext/deriving/custom.rs | 119 - src/libsyntax_ext/deriving/debug.rs | 1 - src/libsyntax_ext/deriving/decodable.rs | 21 +- src/libsyntax_ext/deriving/default.rs | 3 +- src/libsyntax_ext/deriving/encodable.rs | 21 +- src/libsyntax_ext/deriving/generic/mod.rs | 62 +- src/libsyntax_ext/deriving/generic/ty.rs | 17 +- src/libsyntax_ext/deriving/hash.rs | 1 - src/libsyntax_ext/deriving/mod.rs | 84 +- src/libsyntax_ext/env.rs | 3 +- src/libsyntax_ext/error_codes.rs | 4 +- src/libsyntax_ext/format.rs | 248 +- src/libsyntax_ext/global_allocator.rs | 190 + src/libsyntax_ext/global_asm.rs | 12 - src/libsyntax_ext/lib.rs | 143 +- src/libsyntax_ext/log_syntax.rs | 12 +- src/libsyntax_ext/plugin_macro_defs.rs | 58 + ...c_macro_decls.rs => proc_macro_harness.rs} | 39 +- src/libsyntax_ext/proc_macro_impl.rs | 68 - .../ext => libsyntax_ext}/source_util.rs | 59 +- .../standard_library_imports.rs} | 69 +- src/libsyntax_ext/test.rs | 68 +- src/libsyntax_ext/test_case.rs | 60 - .../test.rs => libsyntax_ext/test_harness.rs} | 118 +- src/libsyntax_ext/trace_macros.rs | 11 +- src/libsyntax_pos/Cargo.toml | 4 +- src/libsyntax_pos/analyze_source_file.rs | 155 +- .../analyze_source_file/tests.rs | 151 + src/libsyntax_pos/hygiene.rs | 554 +- src/libsyntax_pos/lib.rs | 95 +- src/libsyntax_pos/symbol.rs | 84 +- src/libsyntax_pos/symbol/tests.rs | 32 + src/libsyntax_pos/tests.rs | 18 + src/libterm/lib.rs | 2 - src/libterm/terminfo/parm.rs | 144 +- src/libterm/terminfo/parm/tests.rs | 137 + src/libterm/terminfo/parser/compiled.rs | 16 +- src/libterm/terminfo/parser/compiled/tests.rs | 8 + src/libterm/terminfo/searcher.rs | 21 +- src/libterm/terminfo/searcher/tests.rs | 19 + src/libterm/win.rs | 37 +- src/libtest/lib.rs | 105 +- src/libtest/stats.rs | 34 +- src/libtest/stats/tests.rs | 27 +- src/libtest/tests.rs | 70 +- src/libunwind/build.rs | 14 +- src/libunwind/lib.rs | 7 +- src/libunwind/libunwind.rs | 18 + src/rustllvm/PassWrapper.cpp | 32 +- src/rustllvm/RustWrapper.cpp | 22 + src/rustllvm/rustllvm.h | 4 - src/stage0.txt | 12 +- src/{stdsimd => stdarch}/.appveyor.yml | 0 src/{stdsimd => stdarch}/CONTRIBUTING.md | 26 +- src/{stdsimd => stdarch}/Cargo.toml | 2 +- src/{stdsimd => stdarch}/LICENSE-APACHE | 0 src/{stdsimd => stdarch}/LICENSE-MIT | 0 src/{stdsimd => stdarch}/QUESTIONS.md | 4 +- src/{stdsimd => stdarch}/README.md | 8 +- src/stdarch/azure-pipelines.yml | 221 + .../ci/android-install-ndk.sh | 0 .../ci/android-install-sdk.sh | 0 .../ci/android-sysimage.sh | 0 src/stdarch/ci/azure-install-rust.yml | 76 + .../docker/aarch64-linux-android/Dockerfile | 0 .../aarch64-unknown-linux-gnu/Dockerfile | 0 .../docker/arm-linux-androideabi/Dockerfile | 0 .../arm-unknown-linux-gnueabihf/Dockerfile | 0 .../armv7-unknown-linux-gnueabihf/Dockerfile | 0 .../docker/i586-unknown-linux-gnu/Dockerfile | 0 .../docker/i686-unknown-linux-gnu/Dockerfile | 0 .../docker/mips-unknown-linux-gnu/Dockerfile | 0 .../mips64-unknown-linux-gnuabi64/Dockerfile | 0 .../Dockerfile | 0 .../mipsel-unknown-linux-musl/Dockerfile | 0 .../ci/docker/nvptx64-nvidia-cuda/Dockerfile | 0 .../powerpc-unknown-linux-gnu/Dockerfile | 0 .../powerpc64-unknown-linux-gnu/Dockerfile | 2 +- .../powerpc64le-unknown-linux-gnu/Dockerfile | 3 +- .../docker/s390x-unknown-linux-gnu/Dockerfile | 0 .../docker/wasm32-unknown-unknown/Dockerfile | 24 + .../wasm32-unknown-unknown/wasm-entrypoint.sh | 15 + .../ci/docker/x86_64-linux-android/Dockerfile | 0 .../Dockerfile | 6 +- .../x86_64-unknown-linux-gnu/Dockerfile | 0 src/{stdsimd => stdarch}/ci/dox.sh | 7 - src/{stdsimd => stdarch}/ci/gba.json | 0 src/{stdsimd => stdarch}/ci/run-docker.sh | 26 +- src/{stdsimd => stdarch}/ci/run.sh | 45 +- .../ci/runtest-android.rs | 0 src/stdarch/ci/style.sh | 22 + .../crates/assert-instr-macro/Cargo.toml | 0 .../crates/assert-instr-macro/build.rs | 0 .../crates/assert-instr-macro/src/lib.rs | 36 +- .../crates/core_arch/Cargo.toml | 18 +- .../crates/core_arch/LICENSE-APACHE | 0 .../crates/core_arch/LICENSE-MIT | 0 .../crates/core_arch/README.md | 22 +- .../crates/core_arch/build.rs | 0 .../crates/core_arch/src/aarch64/crc.rs | 4 +- .../crates/core_arch/src/aarch64/crypto.rs | 4 +- .../crates/core_arch/src/aarch64/mod.rs | 2 +- .../crates/core_arch/src/aarch64/neon.rs | 4 +- .../crates/core_arch/src/aarch64/v8.rs | 2 +- .../core_arch/src/acle/barrier/common.rs | 0 .../crates/core_arch/src/acle/barrier/cp15.rs | 0 .../crates/core_arch/src/acle/barrier/mod.rs | 0 .../core_arch/src/acle/barrier/not_mclass.rs | 0 .../crates/core_arch/src/acle/barrier/v8.rs | 0 .../crates/core_arch/src/acle/dsp.rs | 4 +- .../crates/core_arch/src/acle/ex.rs | 0 .../crates/core_arch/src/acle/hints.rs | 0 .../crates/core_arch/src/acle/mod.rs | 0 .../core_arch/src/acle/registers/aarch32.rs | 2 +- .../core_arch/src/acle/registers/mod.rs | 0 .../core_arch/src/acle/registers/v6m.rs | 0 .../core_arch/src/acle/registers/v7m.rs | 0 .../crates/core_arch/src/acle/sat.rs | 0 .../crates/core_arch/src/acle/simd32.rs | 4 +- .../crates/core_arch/src/arm/armclang.rs | 2 +- .../crates/core_arch/src/arm/mod.rs | 2 +- .../crates/core_arch/src/arm/neon.rs | 286 +- .../core_arch/src/arm/table_lookup_tests.rs | 2 +- .../crates/core_arch/src/arm/v6.rs | 2 +- .../crates/core_arch/src/arm/v7.rs | 8 +- .../crates/core_arch/src/core_arch_docs.md | 1 + .../crates/core_arch/src/lib.rs | 13 +- .../crates/core_arch/src/macros.rs | 84 + .../crates/core_arch/src/mips/mod.rs | 2 +- .../crates/core_arch/src/mips/msa.rs | 4 +- .../crates/core_arch/src/mips/msa/macros.rs | 0 .../crates/core_arch/src/mod.rs | 6 +- .../crates/core_arch/src/nvptx/mod.rs | 0 .../crates/core_arch/src/powerpc/altivec.rs | 1298 ++- .../crates/core_arch/src/powerpc/mod.rs | 2 +- .../crates/core_arch/src/powerpc/vsx.rs | 4 +- .../crates/core_arch/src/powerpc64/mod.rs | 0 .../crates/core_arch/src/simd.rs | 17 +- .../crates/core_arch/src/simd_llvm.rs | 0 .../crates/core_arch/src/v64.rs | 0 .../crates/core_arch/src/wasm32/atomic.rs | 2 +- .../crates/core_arch/src/wasm32/memory.rs | 2 +- .../crates/core_arch/src/wasm32/mod.rs | 3 +- .../crates/core_arch/src/wasm32/simd128.rs | 1395 ++-- .../crates/core_arch/src/x86/abm.rs | 4 +- .../crates/core_arch/src/x86/adx.rs | 4 +- .../crates/core_arch/src/x86/aes.rs | 4 +- .../crates/core_arch/src/x86/avx.rs | 12 +- .../crates/core_arch/src/x86/avx2.rs | 6 +- .../crates/core_arch/src/x86/avx512f.rs | 4 +- .../crates/core_arch/src/x86/avx512ifma.rs | 4 +- .../crates/core_arch/src/x86/bmi1.rs | 4 +- .../crates/core_arch/src/x86/bmi2.rs | 4 +- .../crates/core_arch/src/x86/bswap.rs | 2 +- .../crates/core_arch/src/x86/bt.rs | 2 +- .../crates/core_arch/src/x86/cpuid.rs | 4 +- .../crates/core_arch/src/x86/eflags.rs | 0 src/stdarch/crates/core_arch/src/x86/f16c.rs | 134 + .../crates/core_arch/src/x86/fma.rs | 4 +- .../crates/core_arch/src/x86/fxsr.rs | 4 +- .../crates/core_arch/src/x86/macros.rs | 0 .../crates/core_arch/src/x86/mmx.rs | 4 +- .../crates/core_arch/src/x86/mod.rs | 16 +- .../crates/core_arch/src/x86/pclmulqdq.rs | 4 +- .../crates/core_arch/src/x86/rdrand.rs | 2 +- .../crates/core_arch/src/x86/rdtsc.rs | 4 +- src/stdarch/crates/core_arch/src/x86/rtm.rs | 166 + .../crates/core_arch/src/x86/sha.rs | 4 +- .../crates/core_arch/src/x86/sse.rs | 8 +- .../crates/core_arch/src/x86/sse2.rs | 14 +- .../crates/core_arch/src/x86/sse3.rs | 4 +- .../crates/core_arch/src/x86/sse41.rs | 4 +- .../crates/core_arch/src/x86/sse42.rs | 4 +- .../crates/core_arch/src/x86/sse4a.rs | 4 +- .../crates/core_arch/src/x86/ssse3.rs | 4 +- .../crates/core_arch/src/x86/tbm.rs | 4 +- .../crates/core_arch/src/x86/test.rs | 0 .../crates/core_arch/src/x86/xsave.rs | 12 +- .../crates/core_arch/src/x86_64/abm.rs | 4 +- .../crates/core_arch/src/x86_64/adx.rs | 4 +- .../crates/core_arch/src/x86_64/avx.rs | 2 +- .../crates/core_arch/src/x86_64/avx2.rs | 2 +- .../crates/core_arch/src/x86_64/bmi.rs | 4 +- .../crates/core_arch/src/x86_64/bmi2.rs | 4 +- .../crates/core_arch/src/x86_64/bswap.rs | 2 +- .../crates/core_arch/src/x86_64/bt.rs | 2 +- .../crates/core_arch/src/x86_64/cmpxchg16b.rs | 2 +- .../crates/core_arch/src/x86_64/fxsr.rs | 4 +- .../crates/core_arch/src/x86_64/mod.rs | 0 .../crates/core_arch/src/x86_64/rdrand.rs | 2 +- .../crates/core_arch/src/x86_64/sse.rs | 4 +- .../crates/core_arch/src/x86_64/sse2.rs | 4 +- .../crates/core_arch/src/x86_64/sse41.rs | 4 +- .../crates/core_arch/src/x86_64/sse42.rs | 4 +- .../crates/core_arch/src/x86_64/xsave.rs | 8 +- .../crates/core_arch/tests/cpu-detection.rs | 2 +- .../crates/simd-test-macro/Cargo.toml | 0 .../crates/simd-test-macro/src/lib.rs | 2 +- .../crates/std_detect/Cargo.toml | 12 +- .../crates/std_detect/LICENSE-APACHE | 0 .../crates/std_detect/LICENSE-MIT | 0 .../crates/std_detect/README.md | 6 +- .../std_detect/src/detect/arch/aarch64.rs | 0 .../crates/std_detect/src/detect/arch/arm.rs | 0 .../crates/std_detect/src/detect/arch/mips.rs | 0 .../std_detect/src/detect/arch/mips64.rs | 0 .../std_detect/src/detect/arch/powerpc.rs | 0 .../std_detect/src/detect/arch/powerpc64.rs | 0 .../crates/std_detect/src/detect/arch/x86.rs | 15 + .../crates/std_detect/src/detect/bit.rs | 0 .../crates/std_detect/src/detect/cache.rs | 0 .../std_detect/src/detect/error_macros.rs | 0 .../crates/std_detect/src/detect/mod.rs | 0 .../std_detect/src/detect/os/aarch64.rs | 0 .../src/detect/os/freebsd/aarch64.rs | 0 .../std_detect/src/detect/os/freebsd/arm.rs | 27 + .../src/detect/os/freebsd/auxvec.rs | 86 + .../std_detect/src/detect/os/freebsd/mod.rs | 8 + .../src/detect/os/freebsd/powerpc.rs | 27 + .../std_detect/src/detect/os/linux/aarch64.rs | 0 .../std_detect/src/detect/os/linux/arm.rs | 0 .../std_detect/src/detect/os/linux/auxvec.rs | 0 .../std_detect/src/detect/os/linux/cpuinfo.rs | 0 .../std_detect/src/detect/os/linux/mips.rs | 0 .../std_detect/src/detect/os/linux/mod.rs | 0 .../std_detect/src/detect/os/linux/powerpc.rs | 2 +- .../crates/std_detect/src/detect/os/other.rs | 0 .../crates/std_detect/src/detect/os/x86.rs | 23 +- .../src/detect/test_data/linux-rpi3.auxv | Bin .../detect/test_data/linux-x64-i7-6850k.auxv | Bin .../macos-virtualbox-linux-x86-4850HQ.auxv | Bin .../crates/std_detect/src/lib.rs | 1 - .../crates/std_detect/src/mod.rs | 0 .../crates/std_detect/tests/cpu-detection.rs | 2 +- .../std_detect/tests/macro_trailing_commas.rs | 1 - .../crates/stdarch-test}/Cargo.toml | 6 +- .../crates/stdarch-test/src/disassembly.rs | 192 + .../crates/stdarch-test}/src/lib.rs | 145 +- .../crates/stdarch-test}/src/wasm.rs | 64 +- .../crates/stdarch-verify}/Cargo.toml | 4 +- .../stdarch-verify}/arm-intrinsics.html | 0 .../crates/stdarch-verify}/build.rs | 0 .../crates/stdarch-verify}/mips-msa.h | 0 .../crates/stdarch-verify}/src/lib.rs | 27 +- .../crates/stdarch-verify}/tests/arm.rs | 4 +- .../crates/stdarch-verify}/tests/mips.rs | 9 +- .../crates/stdarch-verify}/tests/x86-intel.rs | 139 +- .../crates/stdarch-verify}/x86-intel.xml | 0 src/{stdsimd => stdarch}/examples/Cargo.toml | 6 +- src/{stdsimd => stdarch}/examples/hex.rs | 4 +- src/{stdsimd => stdarch}/examples/wasm.rs | 0 src/stdarch/vendor.yml | 2 + src/stdsimd/.travis.yml | 133 - .../docker/wasm32-unknown-unknown/Dockerfile | 27 - src/stdsimd/crates/core_arch/foo.wasm | Bin 252 -> 0 bytes .../crates/stdsimd-test/src/disassembly.rs | 217 - src/stdsimd/vendor.yml | 2 - src/test/COMPILER_TESTS.md | 2 +- src/test/codegen/issue-45222.rs | 1 + src/test/codegen/issue-45466.rs | 1 + src/test/codegen/mainsubprogram.rs | 2 +- src/test/codegen/mainsubprogramstart.rs | 2 +- src/test/codegen/pgo-instrumentation.rs | 8 +- .../codegen/repr-transparent-aggregates-1.rs | 18 +- src/test/codegen/swap-small-types.rs | 1 + .../compile-fail/{ => consts}/const-err3.rs | 0 .../{ => consts}/const-fn-error.rs | 1 + src/test/compile-fail/consts/issue-55878.rs | 7 + src/test/compile-fail/issue-52443.rs | 9 +- src/test/debuginfo/generator-objects.rs | 16 +- src/test/debuginfo/issue-57822.rs | 55 + .../struct_point.rs | 2 +- .../change_add_field/struct_point.rs | 2 +- src/test/incremental/change_crate_dep_kind.rs | 2 +- .../change_private_fn/struct_point.rs | 2 +- .../change_private_fn_cc/struct_point.rs | 2 +- .../struct_point.rs | 2 +- .../struct_point.rs | 2 +- .../struct_point.rs | 2 +- .../struct_point.rs | 2 +- .../incremental/hashes/call_expressions.rs | 2 +- .../incremental/hashes/closure_expressions.rs | 2 +- src/test/incremental/hashes/consts.rs | 2 +- .../incremental/hashes/enum_constructors.rs | 2 +- src/test/incremental/hashes/enum_defs.rs | 2 +- .../incremental/hashes/exported_vs_not.rs | 2 +- src/test/incremental/hashes/extern_mods.rs | 2 +- src/test/incremental/hashes/for_loops.rs | 2 +- .../incremental/hashes/function_interfaces.rs | 2 +- src/test/incremental/hashes/if_expressions.rs | 2 +- .../hashes/indexing_expressions.rs | 2 +- src/test/incremental/hashes/inherent_impls.rs | 2 +- src/test/incremental/hashes/inline_asm.rs | 2 +- .../incremental/hashes/let_expressions.rs | 2 +- .../incremental/hashes/loop_expressions.rs | 2 +- .../incremental/hashes/match_expressions.rs | 2 +- src/test/incremental/hashes/panic_exprs.rs | 2 +- src/test/incremental/hashes/statics.rs | 2 +- .../incremental/hashes/struct_constructors.rs | 2 +- src/test/incremental/hashes/struct_defs.rs | 2 +- src/test/incremental/hashes/trait_defs.rs | 2 +- src/test/incremental/hashes/trait_impls.rs | 2 +- src/test/incremental/hashes/type_defs.rs | 2 +- .../hashes/unary_and_binary_exprs.rs | 2 +- .../incremental/hashes/while_let_loops.rs | 6 +- src/test/incremental/hashes/while_loops.rs | 4 +- src/test/incremental/ich_nested_items.rs | 2 +- .../incremental/incremental_proc_macro.rs | 2 +- src/test/incremental/issue-42602.rs | 2 +- .../incremental/issue-49595/issue-49595.rs | 2 +- ...ssue-59523-on-implemented-is-not-unused.rs | 2 +- ...layout-scalar-valid-range-is-not-unused.rs | 2 +- src/test/incremental/krate-inherent.rs | 2 +- src/test/incremental/macro_export.rs | 2 +- .../incremental/remove_source_file/main.rs | 2 +- src/test/incremental/string_constant.rs | 2 +- .../thinlto/cgu_invalidated_via_import.rs | 2 +- ...independent_cgus_dont_affect_each_other.rs | 2 +- src/test/incremental/unchecked_dirty_clean.rs | 8 +- src/test/incremental/warnings-reemitted.rs | 2 +- src/test/mir-opt/const_prop/reify_fn_ptr.rs | 2 +- src/test/mir-opt/issue-62289.rs | 91 + src/test/mir-opt/loop_test.rs | 1 + src/test/mir-opt/lower_128bit_debug_test.rs | 226 - src/test/mir-opt/lower_128bit_test.rs | 149 - src/test/mir-opt/uniform_array_move_out.rs | 2 +- src/test/mir-opt/while-storage.rs | 45 +- src/test/pretty/attr-literals.rs | 2 +- src/test/pretty/attr-tokens-raw-ident.rs | 7 + src/test/pretty/block-comment-wchar.pp | 5 +- src/test/pretty/cast-lt.pp | 2 +- src/test/pretty/delimited-token-groups.rs | 49 + src/test/pretty/do1.rs | 2 +- src/test/pretty/dollar-crate.pp | 8 +- src/test/pretty/issue-30731.rs | 2 +- src/test/pretty/issue-4264.pp | 4 +- src/test/pretty/macro.rs | 7 + src/test/pretty/match-block-expr.rs | 2 +- src/test/pretty/stmt_expr_attributes.rs | 12 +- .../hotplug_codegen_backend/the_backend.rs | 1 + src/test/run-make-fulldeps/issue-19371/foo.rs | 1 + .../output-type-permutations/Makefile | 6 +- .../pretty-expanded-hygiene/Makefile | 21 - .../pretty-expanded-hygiene/input.pp.rs | 9 - .../pretty-expanded/input.rs | 14 +- .../reproducible-build-2/Makefile | 16 + .../reproducible-build-2/linker.rs | 44 + .../reproducible-build-aux.rs | 28 + .../reproducible-build.rs | 116 + .../sanitizer-memory/uninit.rs | 1 + .../run-make-fulldeps/save-analysis/foo.rs | 5 +- src/test/run-make-fulldeps/simd-ffi/simd.rs | 6 +- .../thumb-none-qemu/example/Cargo.toml | 2 +- .../thumb-none-qemu/example/src/main.rs | 16 +- .../run-pass-fulldeps/issue-15778-pass.rs | 13 - src/test/run-pass/attr-on-generic-formals.rs | 52 - src/test/run-pass/auxiliary/arc_wake.rs | 64 - .../run-pass/auxiliary/weak-lang-items.rs | 22 - .../auxiliary/coherence_copy_like_lib.rs | 10 - .../coherence/auxiliary/coherence_lib.rs | 15 - .../run-pass/consts/auxiliary/const_fn_lib.rs | 5 - src/test/run-pass/format-hygiene.rs | 6 - .../run-pass/generator/niche-in-generator.rs | 17 + src/test/run-pass/hygiene/ty_params.rs | 14 - src/test/run-pass/if-ret.stderr | 8 - .../auxiliary/macro_crate_nonterminal.rs | 12 - .../macros/auxiliary/unstable-macros.rs | 6 - .../macros/macro-use-all-and-none.stderr | 8 - .../inner_modrs_mod/innest.rs | 1 - .../crate-path-absolute.rs | 42 - .../crate-path-absolute.stderr | 8 - .../crate-path-visibility-ambiguity.rs | 15 - .../crate-path-visibility-ambiguity.stderr | 8 - .../auxiliary/xcrate.rs | 7 - .../rfc-2126-extern-absolute-paths/basic.rs | 25 - .../rfc-2126-extern-absolute-paths/test.rs | 10 - .../whitelisted.rs | 14 - .../traits/auxiliary/trait_safety_lib.rs | 9 - src/test/run-pass/tydesc-name.rs | 16 - src/test/rustdoc-ui/cfg-test.rs | 14 +- src/test/rustdoc-ui/cfg-test.stdout | 7 +- src/test/rustdoc-ui/coverage/basic.rs | 2 +- src/test/rustdoc-ui/coverage/empty.rs | 2 +- src/test/rustdoc-ui/coverage/enums.rs | 2 +- src/test/rustdoc-ui/coverage/exotic.rs | 2 +- src/test/rustdoc-ui/coverage/private.rs | 2 +- .../rustdoc-ui/coverage/statics-consts.rs | 2 +- src/test/rustdoc-ui/coverage/traits.rs | 9 +- src/test/rustdoc-ui/deprecated-attrs.rs | 2 +- .../rustdoc-ui/intra-links-warning-crlf.rs | 2 +- .../intra-links-warning-crlf.stderr | 2 +- src/test/rustdoc-ui/intra-links-warning.rs | 2 +- .../rustdoc-ui/intra-links-warning.stderr | 2 +- src/test/rustdoc-ui/invalid-syntax.rs | 2 +- src/test/rustdoc-ui/invalid-syntax.stderr | 168 +- src/test/rustdoc-ui/issue-58473-2.rs | 2 +- src/test/rustdoc-ui/issue-58473.rs | 2 +- src/test/rustdoc-ui/lint-group.stderr | 6 +- src/test/rustdoc-ui/unused.rs | 2 +- .../auxiliary/through-proc-macro-aux.rs | 20 + src/test/rustdoc/cfg-doctest.rs | 8 + src/test/rustdoc/deref-mut-methods.rs | 29 + src/test/rustdoc/inline_cross/add-docs.rs | 9 + .../inline_cross/auxiliary/add-docs.rs | 4 + src/test/rustdoc/intra-link-builtin-macros.rs | 3 + src/test/rustdoc/issue-52873.rs | 1 + src/test/rustdoc/keyword.rs | 1 + src/test/rustdoc/proc-macro.rs | 2 +- src/test/rustdoc/through-proc-macro.rs | 12 + .../ast_stmt_expr_attr.rs | 2 + .../ui-fulldeps/auxiliary/attr-plugin-test.rs | 14 +- .../auxiliary/issue-13560-1.rs | 0 .../auxiliary/issue-13560-2.rs | 0 .../auxiliary/issue-13560-3.rs | 0 .../auxiliary/issue-16822.rs | 0 .../auxiliary/issue-18502.rs | 0 .../auxiliary/issue-24106.rs | 0 .../auxiliary/issue-40001-plugin.rs | 1 + .../auxiliary/linkage-visibility.rs | 0 .../auxiliary/lint-for-crate-rpass.rs} | 1 + .../ui-fulldeps/auxiliary/lint-for-crate.rs | 1 + .../auxiliary/lint-group-plugin-test.rs | 1 + .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 1 + .../ui-fulldeps/auxiliary/lint-tool-test.rs | 13 +- .../auxiliary/llvm-pass-plugin.rs | 1 + .../auxiliary/lto-syntax-extension-lib.rs | 0 .../auxiliary/lto-syntax-extension-plugin.rs | 1 + .../auxiliary/macro-crate-test.rs | 1 + .../auxiliary/outlive-expansion-phase.rs | 1 + .../auxiliary/plugin-args.rs | 5 +- .../ui-fulldeps/auxiliary/rlib-crate-test.rs | 1 + .../auxiliary/roman-numerals.rs | 2 +- .../syntax-extension-with-dll-deps-1.rs | 0 .../compiler-calls.rs | 1 + .../create-dir-all-bare.rs | 2 + src/test/ui-fulldeps/deprecated-derive.rs | 12 - src/test/ui-fulldeps/deprecated-derive.stderr | 6 - .../derive-no-std-not-supported.rs | 2 + .../deriving-encodable-decodable-box.rs | 9 +- ...riving-encodable-decodable-cell-refcell.rs | 9 +- .../deriving-global.rs | 5 +- .../deriving-hygiene.rs | 5 +- .../dropck_tarena_sound_drop.rs | 2 + .../empty-struct-braces-derive.rs | 1 + .../extern-mod-syntax.rs | 2 + src/test/ui-fulldeps/gated-plugin.stderr | 2 +- .../hash-stable-is-unstable.stderr | 10 +- .../internal-lints/default_hash_types.rs | 2 +- .../internal-lints/default_hash_types.stderr | 4 +- .../lint_pass_impl_without_macro.rs | 53 + .../lint_pass_impl_without_macro.stderr | 26 + .../internal-lints/pass_ty_by_ref.rs | 2 +- .../internal-lints/pass_ty_by_ref.stderr | 4 +- .../internal-lints/qualified_ty_ty_ctxt.rs | 2 +- .../qualified_ty_ty_ctxt.stderr | 4 +- .../internal-lints/ty_tykind_usage.rs | 2 +- .../internal-lints/ty_tykind_usage.stderr | 4 +- .../issue-11881.rs | 11 +- .../issue-13560.rs | 1 + .../issue-14021.rs | 2 + .../issue-15149.rs | 2 + src/test/ui-fulldeps/issue-15778-pass.rs | 15 + .../issue-15924.rs | 2 + .../issue-16822.rs | 1 + .../issue-18502.rs | 1 + .../issue-24106.rs | 1 + .../issue-24972.rs | 2 + .../issue-2804.rs | 2 + .../issue-40001.rs | 1 + .../issue-4016.rs | 2 + .../issue-4036.rs | 1 + .../linkage-visibility.rs | 1 + src/test/ui-fulldeps/lint-group-plugin.stderr | 4 +- .../lint-plugin-cmdline-allow.stderr | 2 +- .../lint-plugin-cmdline-load.stderr | 2 +- src/test/ui-fulldeps/lint-plugin.stderr | 2 +- .../lint-tool-cmdline-allow.stderr | 4 +- src/test/ui-fulldeps/lint-tool-test.stderr | 8 +- .../llvm-pass-plugin.rs | 1 + .../lto-syntax-extension.rs | 1 + .../macro-crate-multi-decorator.rs | 2 + .../mod_dir_path_canonicalized.rs | 1 + .../mod_dir_simple/compiletest-ignore-dir | 0 .../mod_dir_simple/test.rs | 2 + .../myriad-closures.rs | 1 + .../newtype_index.rs | 8 +- .../outlive-expansion-phase.rs | 1 + .../plugin-args-1.rs | 1 + .../plugin-args-2.rs | 1 + .../plugin-args-3.rs | 1 + .../ui-fulldeps/plugin-as-extern-crate.rs | 1 - .../ui-fulldeps/plugin-as-extern-crate.stderr | 2 +- .../plugin-attr-register-deny.stderr | 2 +- src/test/ui-fulldeps/plugin-reexport.rs | 10 + src/test/ui-fulldeps/plugin-reexport.stderr | 15 + .../pprust-expr-roundtrip.rs | 1 + .../regions-mock-tcx.rs | 2 + .../rename-directory.rs | 2 + .../roman-numerals-macro.rs | 1 + .../rustc_encodable_hygiene.rs | 2 + .../stdio-from.rs | 1 + .../switch-stdout.rs | 2 + .../undef_mask.rs | 1 + .../abi-sysv64-arg-passing.rs | 1 + .../abi-sysv64-register-usage.rs | 1 + .../issues/issue-62350-sysv-neg-reg-counts.rs | 0 src/test/{run-pass => ui}/abort-on-c-abi.rs | 2 + .../{run-pass => ui}/alias-uninit-value.rs | 2 + .../align-with-extern-c-fn.rs | 2 + .../alignment-gep-tup-like-1.rs | 2 + .../alloca-from-derived-tydesc.rs | 2 + .../{run-pass => ui}/allocator-alloc-one.rs | 2 + src/test/ui/allocator-submodule.rs | 28 - src/test/ui/allocator-submodule.stderr | 8 - src/test/ui/allocator/allocator-args.rs | 13 + src/test/ui/allocator/allocator-args.stderr | 8 + .../allocator/auxiliary/custom-as-global.rs | 0 .../allocator/auxiliary/custom.rs | 0 .../allocator/auxiliary/helper.rs | 0 src/test/ui/allocator/custom-in-block.rs | 22 + src/test/ui/allocator/custom-in-submodule.rs | 26 + src/test/{run-pass => ui}/allocator/custom.rs | 0 src/test/ui/allocator/two-allocators.rs | 2 +- src/test/ui/allocator/two-allocators.stderr | 8 +- src/test/ui/allocator/two-allocators2.rs | 2 +- src/test/ui/allocator/two-allocators2.stderr | 2 +- src/test/ui/allocator/two-allocators3.rs | 2 +- src/test/ui/allocator/two-allocators3.stderr | 2 +- .../{run-pass => ui}/allocator/xcrate-use.rs | 0 .../{run-pass => ui}/allocator/xcrate-use2.rs | 0 .../ui/annotate-snippet/missing-type.stderr | 10 +- src/test/{run-pass => ui}/anon-extern-mod.rs | 1 + src/test/ui/anon-params-deprecated.fixed | 2 +- src/test/ui/anon-params-deprecated.rs | 2 +- src/test/{run-pass => ui}/argument-passing.rs | 2 + .../array-slice-vec/arr_cycle.rs | 0 .../array-slice-vec/array_const_index-1.rs | 0 .../array-slice-vec/box-of-array-of-drop-1.rs | 0 .../array-slice-vec/box-of-array-of-drop-2.rs | 0 .../array-slice-vec/cast-in-array-size.rs | 0 .../check-static-mut-slices.rs | 0 .../array-slice-vec/check-static-slice.rs | 0 .../array-slice-vec/copy-out-of-array-1.rs | 0 .../array-slice-vec/destructure-array-1.rs | 0 .../array-slice-vec/empty-mutable-vec.rs | 0 .../array-slice-vec/estr-slice.rs | 0 .../array-slice-vec/evec-slice.rs | 0 .../array-slice-vec/fixed_length_copy.rs | 0 .../array-slice-vec/huge-largest-array.rs | 0 .../array-slice-vec/ivec-pass-by-value.rs | 0 ...ility-inherits-through-fixed-length-vec.rs | 0 .../array-slice-vec/mutable-alias-vec.rs | 0 .../array-slice-vec/nested-vec-1.rs | 0 .../array-slice-vec/nested-vec-2.rs | 0 .../array-slice-vec/nested-vec-3.rs | 0 .../new-style-fixed-length-vec.rs | 0 .../array-slice-vec/rcvr-borrowed-to-slice.rs | 0 .../array-slice-vec/repeated-vector-syntax.rs | 0 .../array-slice-vec/show-boxed-slice.rs | 0 .../array-slice-vec/slice-2.rs | 0 .../slice-of-zero-size-elements.rs | 0 .../array-slice-vec/slice-panic-1.rs | 0 .../array-slice-vec/slice-panic-2.rs | 0 .../{run-pass => ui}/array-slice-vec/slice.rs | 0 .../array-slice-vec/slice_binary_search.rs | 0 .../array-slice-vec/subslice-patterns-pass.rs | 128 + .../array-slice-vec/variance-vec-covariant.rs | 0 .../array-slice-vec/vec-concat.rs | 0 .../array-slice-vec/vec-dst.rs | 0 .../array-slice-vec/vec-fixed-length.rs | 0 .../array-slice-vec/vec-growth.rs | 0 .../array-slice-vec/vec-late-init.rs | 0 .../array-slice-vec/vec-macro-no-std.rs | 0 .../array-slice-vec/vec-macro-repeat.rs | 0 .../array-slice-vec/vec-macro-rvalue-scope.rs | 0 .../vec-macro-with-brackets.rs | 0 .../vec-macro-with-trailing-comma.rs | 0 .../array-slice-vec/vec-matching-autoslice.rs | 0 .../array-slice-vec/vec-matching-fixed.rs | 0 .../array-slice-vec/vec-matching-fold.rs | 4 +- .../vec-matching-legal-tail-element-borrow.rs | 2 +- .../array-slice-vec/vec-matching.rs | 27 +- .../array-slice-vec/vec-push.rs | 0 .../array-slice-vec/vec-repeat-with-cast.rs | 0 .../array-slice-vec/vec-slice-drop.rs | 0 .../array-slice-vec/vec-slice.rs | 0 .../array-slice-vec/vec-tail-matching.rs | 4 +- .../array-slice-vec/vec-to_str.rs | 0 .../{run-pass => ui}/array-slice-vec/vec.rs | 0 .../array-slice-vec/vec_cycle.rs | 0 .../array-slice-vec/vec_cycle_wrapped.rs | 0 .../array-slice-vec/vector-no-ann-2.rs | 0 src/test/ui/array_const_index-0.stderr | 2 +- src/test/ui/array_const_index-1.stderr | 2 +- src/test/{run-pass => ui}/artificial-block.rs | 2 + src/test/{run-pass => ui}/as-precedence.rs | 2 + src/test/{run-pass => ui}/asm-concat-src.rs | 1 + src/test/{run-pass => ui}/asm-in-moved.rs | 2 + .../{run-pass => ui}/asm-in-out-operand.rs | 2 + .../{run-pass => ui}/asm-indirect-memory.rs | 2 + src/test/{run-pass => ui}/asm-out-assign.rs | 2 + .../assert-eq-trailing-comma.rs | 2 + src/test/{run-pass => ui}/assert-escape.rs | 2 + .../assert-ne-trailing-comma.rs | 2 + src/test/{run-pass => ui}/assign-assign.rs | 1 + src/test/{run-pass => ui}/assoc-oddities-3.rs | 2 + .../associated-const-ambiguity-report.stderr | 2 + .../associated-const-trait-bound.rs | 2 +- .../associated-const-const-eval.rs | 0 ...associated-const-cross-crate-const-eval.rs | 0 .../associated-const-cross-crate-defaults.rs | 0 .../associated-const-cross-crate.rs | 0 .../associated-const-in-global-const.rs | 0 .../associated-const-inherent-impl.rs | 0 .../associated-const-marks-live-code.rs | 0 .../associated-const-match-patterns.rs | 0 .../associated-const-outer-ty-refs.rs | 0 .../associated-const-overwrite-default.rs | 0 .../associated-const-public-impl.rs | 0 .../associated-const-range-match-patterns.rs | 0 .../associated-const-resolution-order.rs | 0 .../associated-const-self-type.rs | 0 .../associated-const-type-parameters.rs | 0 .../associated-const-ufcs-infer-trait.rs | 0 .../associated-const-use-default.rs | 0 ...associated-const-use-impl-of-same-trait.rs | 0 .../associated-consts/associated-const.rs | 0 .../auxiliary/associated-const-cc-lib.rs | 0 .../auxiliary/empty-struct.rs | 0 .../associated-item-long-paths.rs | 2 + src/test/ui/associated-path-shl.rs | 1 - src/test/ui/associated-path-shl.stderr | 16 +- .../ambiguous-associated-type.rs | 12 + .../bounds-on-assoc-in-trait.rs | 2 +- .../ui/associated-type-bounds/duplicate.rs | 14 +- .../associated-type-bounds/duplicate.stderr | 86 +- ...tential-type.rs => dyn-impl-trait-type.rs} | 1 - .../associated-type-bounds/dyn-lcsit.stderr | 2 + .../entails-sized-object-safety.rs | 2 +- .../ui/associated-type-bounds/issue-61752.rs | 24 + .../ui/associated-type-bounds/lcsit.stderr | 2 + ...tial-type.rs => trait-alias-impl-trait.rs} | 10 +- .../ui/associated-type-bounds/trait-params.rs | 2 +- .../ui/associated-type-bounds/type-alias.rs | 2 +- .../associated-type-bounds/type-alias.stderr | 2 +- .../associated-types-basic.rs | 0 .../associated-types-binding-in-trait.rs | 0 ...ssociated-types-binding-in-where-clause.rs | 0 .../associated-types-bound.rs | 0 .../associated-types/associated-types-cc.rs | 0 .../associated-types-conditional-dispatch.rs | 0 .../associated-types-constant-type.rs | 0 ...ciated-types-doubleendediterator-object.rs | 0 ...ted-types-duplicate-binding-in-env-hrtb.rs | 0 ...sociated-types-duplicate-binding-in-env.rs | 0 .../associated-types-enum-field-named.rs | 0 .../associated-types-enum-field-numbered.rs | 0 .../associated-types-eq-obj.rs | 0 .../associated-types-from-supertrait.rs | 2 + .../associated-types-impl-redirect.rs | 0 .../associated-types-in-bound-type-arg.rs | 0 .../associated-types-in-default-method.rs | 0 .../associated-types-in-fn.rs | 0 .../associated-types-in-impl-generics.rs | 0 .../associated-types-in-inherent-method.rs | 0 .../associated-types-issue-20220.rs | 0 .../associated-types-issue-20371.rs | 0 .../associated-types-issue-21212.rs | 0 .../associated-types-iterator-binding.rs | 0 .../associated-types-method.rs | 0 .../associated-types-nested-projections.rs | 0 ...iated-types-normalize-in-bounds-binding.rs | 0 ...sociated-types-normalize-in-bounds-ufcs.rs | 0 .../associated-types-normalize-in-bounds.rs | 0 ...ociated-types-normalize-unifield-struct.rs | 0 ...ject-from-type-param-via-bound-in-where.rs | 0 ...d-types-projection-bound-in-supertraits.rs | 0 ...ypes-projection-from-known-type-in-impl.rs | 0 ...ociated-types-projection-in-object-type.rs | 0 ...sociated-types-projection-in-supertrait.rs | 0 ...ciated-types-projection-in-where-clause.rs | 0 ...ted-types-projection-to-unrelated-trait.rs | 0 ...ed-path-with-trait-with-type-parameters.rs | 0 .../associated-types-ref-from-struct.rs | 0 .../associated-types-ref-in-struct-literal.rs | 0 ...ciated-types-region-erasure-issue-20582.rs | 0 .../associated-types-resolve-lifetime.rs | 0 .../associated-types-return.rs | 0 .../associated-types-simple.rs | 0 .../associated-types-stream.rs | 0 .../associated-types-struct-field-named.rs | 0 .../associated-types-struct-field-numbered.rs | 0 .../associated-types-sugar-path.rs | 0 ...iated-types-where-clause-impl-ambiguity.rs | 0 .../auxiliary/associated-types-cc-lib.rs | 0 .../ui/associated-types/cache/chrono-scan.rs | 2 + src/test/ui/async-await/async-await.rs | 25 +- ...ync-block-control-flow-static-semantics.rs | 67 + ...block-control-flow-static-semantics.stderr | 79 + .../async-await/async-closure-matches-expr.rs | 12 + src/test/ui/async-await/async-closure.rs | 97 + src/test/ui/async-await/async-error-span.rs | 17 + .../ui/async-await/async-error-span.stderr | 15 + .../ui/async-await/async-fn-path-elision.rs | 2 +- .../async-await/async-fn-send-uses-nonsend.rs | 2 +- .../async-await/async-fn-size-moved-locals.rs | 21 + .../async-await/async-fn-size.rs | 21 +- src/test/ui/async-await/async-matches-expr.rs | 5 +- .../async-unsafe-fn-call-in-safe.rs | 21 + .../async-unsafe-fn-call-in-safe.stderr | 35 + src/test/ui/async-await/async-with-closure.rs | 6 +- ...> 2015-edition-error-various-positions.rs} | 5 +- ...15-edition-error-various-positions.stderr} | 31 +- ...018-edition-error-in-non-macro-position.rs | 2 +- .../await-keyword/2018-edition-error.rs | 6 +- .../await-keyword/2018-edition-error.stderr | 18 +- .../incorrect-syntax-suggestions.rs | 25 + .../incorrect-syntax-suggestions.stderr | 48 +- .../await-keyword/post_expansion_error.stderr | 4 +- src/test/ui/async-await/await-macro.rs | 201 - src/test/ui/async-await/await-unsize.rs | 16 + .../ui/async-await/bound-normalization.rs | 16 + ...nditional-and-guaranteed-initialization.rs | 18 + ...-for-async-fn-parameters-by-ref-binding.rs | 2 +- .../drop-order-for-async-fn-parameters.rs | 2 +- .../drop-order-for-locals-when-cancelled.rs | 176 + .../drop-order/drop-order-when-cancelled.rs | 307 + .../ui/async-await/feature-async-closure.rs | 8 + .../async-await/feature-async-closure.stderr | 12 + .../async-await}/futures-api.rs | 2 + .../ui/async-await/generics-and-bounds.rs | 2 +- .../async-await/issue-60709.rs | 6 +- src/test/ui/async-await/issue-61793.rs | 2 +- src/test/ui/async-await/issue-62658.rs | 29 + src/test/ui/async-await/issues/issue-53249.rs | 8 +- src/test/ui/async-await/issues/issue-54974.rs | 4 +- src/test/ui/async-await/issues/issue-55324.rs | 6 +- src/test/ui/async-await/issues/issue-58885.rs | 4 +- src/test/ui/async-await/issues/issue-59001.rs | 4 +- src/test/ui/async-await/issues/issue-59972.rs | 19 +- src/test/ui/async-await/issues/issue-60518.rs | 2 +- .../issues/issue-60655-latebound-regions.rs | 11 +- src/test/ui/async-await/issues/issue-60674.rs | 2 +- src/test/ui/async-await/issues/issue-61986.rs | 2 +- .../{issue-62009.rs => issue-62009-1.rs} | 2 - ...ssue-62009.stderr => issue-62009-1.stderr} | 23 +- .../ui/async-await/issues/issue-62009-2.rs | 10 + .../async-await/issues/issue-62009-2.stderr | 10 + .../move-part-await-return-rest-struct.rs | 20 + .../move-part-await-return-rest-tuple.rs | 14 + .../ui/async-await/multiple-lifetimes/hrtb.rs | 2 +- .../async-await/multiple-lifetimes/named.rs | 2 +- .../no-args-non-move-async-closure.rs | 2 +- .../no-move-across-await-struct.rs | 19 + .../no-move-across-await-struct.stderr | 13 + .../async-await/no-move-across-await-tuple.rs | 15 + .../no-move-across-await-tuple.stderr | 14 + .../no-non-guaranteed-initialization.rs | 16 + .../no-non-guaranteed-initialization.stderr | 9 + .../partial-initialization-across-await.rs | 44 + ...partial-initialization-across-await.stderr | 21 + .../recursive-async-impl-trait-type.rs | 4 +- .../recursive-async-impl-trait-type.stderr | 8 +- .../suggest-missing-await-closure.fixed | 23 + .../suggest-missing-await-closure.rs | 23 + .../suggest-missing-await-closure.stderr | 15 + .../async-await/suggest-missing-await.fixed | 11 - .../ui/async-await/suggest-missing-await.rs | 11 - .../async-await/suggest-missing-await.stderr | 14 +- .../{run-pass => ui}/atomic-access-bool.rs | 2 + src/test/{run-pass => ui}/atomic-alignment.rs | 2 + .../atomic-compare_exchange.rs | 2 + src/test/{run-pass => ui}/atomic-print.rs | 2 + src/test/{run-pass => ui}/attr-main-2.rs | 2 + src/test/{run-pass => ui}/attr-main.rs | 1 + src/test/{run-pass => ui}/attr-shebang.rs | 2 + src/test/{run-pass => ui}/attr-start.rs | 1 + src/test/{run-pass => ui}/attr.rs | 1 + .../ui/attributes/attr-before-view-item.rs | 2 +- .../ui/attributes/attr-before-view-item2.rs | 2 +- src/test/ui/attributes/attr-mix-new.rs | 2 +- .../attrs-with-no-formal-in-generics-1.rs | 6 +- .../attrs-with-no-formal-in-generics-1.stderr | 6 +- .../attrs-with-no-formal-in-generics-2.rs | 2 +- .../attrs-with-no-formal-in-generics-2.stderr | 6 +- src/test/ui/attributes/class-attributes-1.rs | 2 +- src/test/ui/attributes/class-attributes-2.rs | 2 +- src/test/ui/attributes/item-attributes.rs | 2 +- src/test/ui/attributes/method-attributes.rs | 2 +- src/test/ui/attributes/obsolete-attr.rs | 6 +- src/test/ui/attributes/obsolete-attr.stderr | 13 +- src/test/ui/attributes/unknown-attr.rs | 9 +- src/test/ui/attributes/unknown-attr.stderr | 20 +- src/test/ui/attributes/variant-attributes.rs | 2 +- ...ugmented-assignments-feature-gate-cross.rs | 1 + .../augmented-assignments-feature-gate.rs | 2 + .../augmented-assignments-rpass.rs} | 2 + src/test/{run-pass => ui}/auto-instantiate.rs | 2 + .../{run-pass => ui}/auto-is-contextual.rs | 2 + src/test/{run-pass => ui}/autobind.rs | 2 + .../auto-ref-bounded-ty-param.rs | 0 .../autoref-autoderef/auto-ref-sliceable.rs | 0 .../autoref-autoderef/auto-ref.rs | 0 .../autoderef-and-borrow-method-receiver.rs | 0 .../autoderef-method-on-trait.rs | 0 .../autoderef-method-priority.rs | 0 .../autoderef-method-twice-but-not-thrice.rs | 0 .../autoderef-method-twice.rs | 0 .../autoref-autoderef/autoderef-method.rs | 0 .../autoref-autoderef/autoderef-privacy.rs | 0 .../autoref-intermediate-types-issue-3585.rs | 0 .../anon-extern-mod-cross-crate-1.rs | 0 .../auxiliary/augmented_assignments.rs | 0 .../blind-item-mixed-crate-use-item-foo.rs | 0 .../blind-item-mixed-crate-use-item-foo2.rs | 0 .../check_static_recursion_foreign_helper.rs | 0 .../{run-pass => ui}/auxiliary/cond_plugin.rs | 0 .../crate-method-reexport-grrrrrrr2.rs | 0 .../auxiliary/debuginfo-lto-aux.rs | 0 .../auxiliary/edition-kw-macro-2015.rs | 0 .../auxiliary/edition-kw-macro-2018.rs | 0 .../{run-pass => ui}/auxiliary/foreign_lib.rs | 0 .../{run-pass => ui}/auxiliary/hello_macro.rs | 0 .../auxiliary/impl_privacy_xc_1.rs | 0 .../auxiliary/impl_privacy_xc_2.rs | 0 .../{run-pass => ui}/auxiliary/inline_dtor.rs | 0 .../auxiliary/inner_static.rs | 0 .../auxiliary/kinds_in_metadata.rs | 0 .../link-cfg-works-transitive-dylib.rs | 0 .../link-cfg-works-transitive-rlib.rs | 0 .../{run-pass => ui}/auxiliary/linkage1.rs | 0 .../auxiliary/llvm_pr32379.rs | 0 .../auxiliary/msvc-data-only-lib.rs | 0 .../{run-pass => ui}/auxiliary/nested_item.rs | 0 .../auxiliary/proc_macro_def.rs | 0 .../auxiliary/reachable-unnameable-items.rs | 0 .../auxiliary/reexport-should-still-link.rs | 0 .../auxiliary/rmeta-rlib-rpass.rs} | 0 .../{run-pass => ui}/auxiliary/rmeta-rmeta.rs | 0 .../{run-pass => ui}/auxiliary/svh-a-base.rs | 0 src/test/{run-pass => ui}/auxiliary/svh-b.rs | 0 .../auxiliary/trait_superkinds_in_metadata.rs | 0 .../auxiliary/typeid-intrinsic-aux1.rs | 0 .../auxiliary/typeid-intrinsic-aux2.rs | 0 .../using-target-feature-unstable.rs | 0 .../backtrace-debuginfo-aux.rs | 1 + .../{run-pass => ui}/backtrace-debuginfo.rs | 18 +- src/test/{run-pass => ui}/backtrace.rs | 2 + src/test/ui/bad/bad-extern-link-attrs.stderr | 4 +- src/test/ui/bad/bad-lint-cap2.stderr | 2 +- src/test/ui/bad/bad-lint-cap3.stderr | 2 +- .../bare-fn-implements-fn-mut.rs | 2 + .../{run-pass => ui}/bare-static-string.rs | 2 + src/test/ui/bastion-of-the-turbofish.rs | 2 +- .../{run-pass => ui}/bench/issue-32062.rs | 0 src/test/{run-pass => ui}/big-literals.rs | 1 + .../binary-minus-without-space.rs | 1 + src/test/{run-pass => ui}/bind-by-move.rs | 2 + .../bind-by-move-no-guards.stderr | 2 +- .../bind-field-short-with-modifiers.rs | 0 .../binding/borrowed-ptr-pattern-2.rs | 0 .../binding/borrowed-ptr-pattern-3.rs | 0 .../borrowed-ptr-pattern-infallible.rs | 0 .../binding/borrowed-ptr-pattern-option.rs | 0 .../binding/borrowed-ptr-pattern.rs | 0 .../binding/empty-types-in-patterns.rs | 0 .../binding/exhaustive-bool-match-sanity.rs | 0 .../binding/expr-match-generic-unique1.rs | 0 .../binding/expr-match-generic-unique2.rs | 0 .../binding/expr-match-generic.rs | 0 .../binding/expr-match-panic-all.rs | 0 .../binding/expr-match-panic.rs | 0 .../binding/expr-match-unique.rs | 0 .../{run-pass => ui}/binding/expr-match.rs | 0 .../binding/fat-arrow-match.rs | 0 .../fn-arg-incomplete-pattern-drop-order.rs | 1 + .../binding/fn-pattern-expected-type-2.rs | 0 .../binding/fn-pattern-expected-type.rs | 0 .../binding/func-arg-incomplete-pattern.rs | 0 .../binding/func-arg-ref-pattern.rs | 0 .../binding/func-arg-wild-pattern.rs | 0 src/test/{run-pass => ui}/binding/if-let.rs | 0 .../binding/inconsistent-lifetime-mismatch.rs | 0 .../inferred-suffix-in-pattern-range.rs | 0 .../binding/irrefutable-slice-patterns.rs | 2 +- .../binding/let-assignability.rs | 0 .../binding/let-destruct-ref.rs | 0 .../binding/let-var-hygiene.rs | 0 .../binding/match-arm-statics.rs | 0 .../binding/match-beginning-vert.rs | 0 .../binding/match-borrowed_str.rs | 0 .../{run-pass => ui}/binding/match-bot-2.rs | 0 .../{run-pass => ui}/binding/match-bot.rs | 0 .../binding/match-byte-array-patterns.rs | 0 .../binding/match-enum-struct-0.rs | 0 .../binding/match-enum-struct-1.rs | 0 .../binding/match-implicit-copy-unique.rs | 0 .../binding/match-in-macro.rs | 0 .../{run-pass => ui}/binding/match-join.rs | 0 .../binding/match-larger-const.rs | 0 .../binding/match-naked-record-expr.rs | 0 .../binding/match-naked-record.rs | 0 .../{run-pass => ui}/binding/match-path.rs | 0 .../binding/match-pattern-bindings.rs | 0 .../binding/match-pattern-lit.rs | 0 .../binding/match-pattern-no-type-params.rs | 0 .../binding/match-pattern-simple.rs | 0 .../{run-pass => ui}/binding/match-phi.rs | 0 .../binding/match-pipe-binding.rs | 0 .../binding/match-range-infer.rs | 0 .../binding/match-range-static.rs | 0 .../{run-pass => ui}/binding/match-range.rs | 0 .../binding/match-reassign.rs | 0 .../match-ref-binding-in-guard-3256.rs | 0 .../binding/match-ref-binding-mut-option.rs | 0 .../binding/match-ref-binding-mut.rs | 0 .../binding/match-ref-binding.rs | 0 .../binding/match-ref-unsized.rs | 0 .../{run-pass => ui}/binding/match-str.rs | 0 .../binding/match-struct-0.rs | 0 .../{run-pass => ui}/binding/match-tag.rs | 0 .../binding/match-unique-bind.rs | 0 .../{run-pass => ui}/binding/match-unsized.rs | 0 .../match-value-binding-in-guard-3291.rs | 0 .../binding/match-var-hygiene.rs | 0 .../binding/match-vec-alternatives.rs | 0 .../binding/match-vec-rvalue.rs | 0 .../binding/match-with-ret-arm.rs | 0 .../{run-pass => ui}/binding/multi-let.rs | 0 .../binding/mut-in-ident-patterns.rs | 0 .../binding/nested-exhaustive-match.rs | 0 .../{run-pass => ui}/binding/nested-matchs.rs | 0 .../binding/nested-pattern.rs | 0 .../{run-pass => ui}/binding/nil-pattern.rs | 0 .../binding/nullary-or-pattern.rs | 0 .../binding/optional_comma_in_match_arm.rs | 0 .../{run-pass => ui}/binding/or-pattern.rs | 0 .../binding/order-drop-with-match.rs | 0 .../{run-pass => ui}/binding/pat-ranges.rs | 0 .../{run-pass => ui}/binding/pat-tuple-1.rs | 0 .../{run-pass => ui}/binding/pat-tuple-2.rs | 0 .../{run-pass => ui}/binding/pat-tuple-3.rs | 0 .../{run-pass => ui}/binding/pat-tuple-4.rs | 0 .../{run-pass => ui}/binding/pat-tuple-5.rs | 0 .../{run-pass => ui}/binding/pat-tuple-6.rs | 0 .../{run-pass => ui}/binding/pat-tuple-7.rs | 0 .../binding/pattern-bound-var-in-for-each.rs | 0 .../binding/pattern-in-closure.rs | 0 .../range-inclusive-pattern-precedence.rs | 0 .../binding/simple-generic-match.rs | 0 .../binding/use-uninit-match.rs | 0 .../binding/use-uninit-match2.rs | 0 .../binding/zero_sized_subslice_match.rs | 2 +- .../{run-pass => ui}/binops-issue-22743.rs | 2 + src/test/{run-pass => ui}/binops.rs | 2 + src/test/{run-pass => ui}/bitwise.rs | 2 + .../blind-item-local-shadow.rs | 2 + .../blind-item-mixed-crate-use-item.rs | 1 + .../blind-item-mixed-use-item.rs | 1 + .../{run-pass => ui}/block-arg-call-as.rs | 2 + src/test/{run-pass => ui}/block-arg.rs | 1 + .../{run-pass => ui}/block-explicit-types.rs | 2 + .../{run-pass => ui}/block-expr-precedence.rs | 2 + src/test/{run-pass => ui}/block-fn-coerce.rs | 2 + src/test/{run-pass => ui}/block-iter-1.rs | 2 + src/test/{run-pass => ui}/block-iter-2.rs | 2 + .../block-must-not-have-result-while.rs | 2 +- .../block-must-not-have-result-while.stderr | 8 + .../consider-removing-last-semi.stderr | 4 +- src/test/ui/block-result/issue-11714.stderr | 2 +- src/test/ui/block-result/issue-13428.stderr | 4 +- src/test/{run-pass => ui}/bool-not.rs | 2 + src/test/{run-pass => ui}/bool.rs | 1 + .../borrow-by-val-method-receiver.rs | 2 + src/test/ui/borrowck/assign-never-type.rs | 14 + .../borrowck/borrowck-assign-to-subfield.rs | 0 .../borrowck-assignment-to-static-mut.rs | 0 .../borrowck/borrowck-binding-mutbl.rs | 0 .../borrowck-borrow-from-expr-block.rs | 0 .../borrowck-borrow-of-mut-base-ptr-safe.rs | 0 .../borrowck-borrow-overloaded-auto-deref.rs | 13 +- ...rrowck-borrow-overloaded-auto-deref.stderr | 84 +- .../borrowck-borrow-overloaded-deref.rs | 13 +- .../borrowck-borrow-overloaded-deref.stderr | 42 +- .../borrowck/borrowck-closures-two-imm.rs | 0 .../borrowck-describe-lvalue.nll.stderr | 16 +- .../ui/borrowck/borrowck-describe-lvalue.rs | 8 +- .../borrowck/borrowck-describe-lvalue.stderr | 16 +- ...k-escaping-closure-error-2.polonius.stderr | 16 + .../borrowck-field-sensitivity-rpass.rs} | 0 .../borrowck/borrowck-fixed-length-vecs.rs | 0 .../borrowck/borrowck-freeze-frozen-mut.rs | 0 .../borrowck/borrowck-lend-args.rs | 0 .../borrowck-macro-interaction-issue-6304.rs | 0 .../borrowck-migrate-to-nll.edition.stderr | 18 +- .../ui/borrowck/borrowck-migrate-to-nll.rs | 27 +- .../borrowck-migrate-to-nll.zflag.stderr | 18 +- .../borrowck/borrowck-move-by-capture-ok.rs | 0 .../borrowck/borrowck-move-out-from-array.rs | 2 +- .../borrowck-move-out-from-array.stderr | 4 +- .../borrowck/borrowck-move-out-of-vec-tail.rs | 2 +- ...orrowck-multiple-borrows-interior-boxes.rs | 0 .../borrowck/borrowck-mut-uniq.rs | 0 .../borrowck/borrowck-mut-vec-as-imm-slice.rs | 0 .../borrowck-mutate-in-guard.nll.stderr | 41 - .../ui/borrowck/borrowck-mutate-in-guard.rs | 8 +- .../borrowck/borrowck-mutate-in-guard.stderr | 22 +- .../borrowck-overloaded-index-ref-index.rs | 2 +- ...borrowck-overloaded-index-ref-index.stderr | 4 +- .../borrowck/borrowck-pat-enum.rs | 0 .../borrowck-pat-reassign-no-binding.rs | 0 .../borrowck/borrowck-rvalues-mutable.rs | 0 .../borrowck-scope-of-deref-issue-4666.rs | 0 ...rowck-slice-pattern-element-loan-rpass.rs} | 2 +- .../borrowck-slice-pattern-element-loan.rs | 12 +- ...borrowck-slice-pattern-element-loan.stderr | 16 +- .../borrowck/borrowck-static-item-in-fn.rs | 0 .../borrowck/borrowck-trait-lifetime.rs | 0 .../borrowck/borrowck-uniq-via-ref.rs | 0 .../borrowck/borrowck-univariant-enum.rs | 0 .../borrowck-unsafe-static-mutable-borrows.rs | 0 .../borrowck/borrowck-unused-mut-locals.rs | 0 .../borrowck-use-mut-borrow-rpass.rs} | 0 .../borrowck-vec-pattern-element-loan.rs | 6 +- .../borrowck-vec-pattern-loan-from-mut.rs | 2 +- .../borrowck-vec-pattern-move-tail.rs | 2 +- .../borrowck-vec-pattern-move-tail.stderr | 4 +- .../borrowck/borrowck-vec-pattern-nesting.rs | 2 +- .../borrowck-vec-pattern-nesting.stderr | 4 +- .../borrowck-vec-pattern-tail-element-loan.rs | 2 +- .../disallow-possibly-uninitialized.rs | 22 + .../disallow-possibly-uninitialized.stderr | 27 + .../borrowck/index-mut-help-with-impl.stderr | 2 - src/test/ui/borrowck/index-mut-help.stderr | 8 +- .../borrowck/issue-27282-mutation-in-guard.rs | 13 + .../issue-27282-mutation-in-guard.stderr | 15 + .../ui/borrowck/issue-31287-drop-in-guard.rs | 8 + .../borrowck/issue-31287-drop-in-guard.stderr | 14 + .../ui/borrowck/issue-45983.migrate.stderr | 2 +- src/test/ui/borrowck/issue-45983.nll.stderr | 4 +- src/test/ui/borrowck/issue-45983.rs | 1 + ...-ascribe-wildcard-to-structured-pattern.rs | 2 +- .../borrowck/issue-62007-assign-box.rs | 0 .../borrowck/issue-62007-assign-field.rs | 0 .../borrowck/issue-62107-match-arm-scopes.rs | 12 + .../issue-62107-match-arm-scopes.stderr | 9 + src/test/ui/borrowck/mut-borrow-in-loop.rs | 2 +- .../ui/borrowck/mut-borrow-in-loop.stderr | 8 + ...ref-mut-in-let-issue-46557.polonius.stderr | 59 + .../borrowck/two-phase-baseline.rs | 0 .../borrowck/two-phase-bin-ops.rs | 0 ...se-control-flow-split-before-activation.rs | 0 ...-sharing-interference-2.migrate2015.stderr | 8 +- ...-sharing-interference-2.migrate2018.stderr | 8 +- ...tion-sharing-interference-2.nll2015.stderr | 6 +- ...tion-sharing-interference-2.nll2018.stderr | 6 +- ...hase-reservation-sharing-interference-2.rs | 1 + ...phase-surprise-no-conflict.polonius.stderr | 148 + src/test/{run-pass => ui}/box-new.rs | 1 + .../{run-pass => ui}/bug-7183-generics.rs | 2 + src/test/{run-pass => ui}/bug-7295.rs | 1 + .../{run-pass => ui}/builtin-clone-unwind.rs | 2 + src/test/{run-pass => ui}/builtin-clone.rs | 1 + ...ltin-superkinds-capabilities-transitive.rs | 1 + .../builtin-superkinds-capabilities-xc.rs | 1 + .../builtin-superkinds-capabilities.rs | 1 + .../builtin-superkinds-in-metadata.rs | 2 + .../builtin-superkinds-phantom-typaram.rs | 2 + .../builtin-superkinds-simple.rs | 1 + .../builtin-superkinds-typaram.rs | 1 + src/test/{run-pass => ui}/byte-literals.rs | 1 + src/test/{run-pass => ui}/c-stack-as-value.rs | 1 + .../c-stack-returning-int64.rs | 1 + .../ui/c-variadic/variadic-ffi-4.nll.stderr | 34 +- src/test/ui/c-variadic/variadic-ffi-4.rs | 4 +- src/test/ui/c-variadic/variadic-ffi-4.stderr | 122 +- .../{run-pass => ui}/cabi-int-widening.rs | 1 + src/test/{run-pass => ui}/can-copy-pod.rs | 1 + .../cancel-clean-via-immediate-rvalue-ref.rs | 1 + .../{run-pass => ui}/cast-does-fallback.rs | 2 + .../{run-pass => ui}/cast-region-to-uint.rs | 2 + .../cast-rfc0401-vtable-kinds.rs | 1 + src/test/{run-pass => ui}/cast-rfc0401.rs | 2 + src/test/{run-pass => ui}/cast-to-infer-ty.rs | 1 + src/test/{run-pass => ui}/cast.rs | 2 + src/test/ui/cast/cast-ptr-to-int-const.stderr | 4 +- .../{run-pass => ui}/catch-unwind-bang.rs | 1 + .../{run-pass => ui}/cell-does-not-clone.rs | 2 + .../cfg/auxiliary/cfg_inner_static.rs | 0 .../crate-attributes-using-cfg_attr.rs | 0 src/test/{run-pass => ui}/cfg/cfg-attr-cfg.rs | 0 .../{run-pass => ui}/cfg/cfg-attr-crate.rs | 0 src/test/{run-pass => ui}/cfg/cfg-family.rs | 0 .../{run-pass => ui}/cfg/cfg-in-crate-1.rs | 0 .../{run-pass => ui}/cfg/cfg-macros-foo.rs | 0 .../{run-pass => ui}/cfg/cfg-macros-notfoo.rs | 0 .../{run-pass => ui}/cfg/cfg-match-arm.rs | 0 .../{run-pass => ui}/cfg/cfg-target-family.rs | 0 .../{run-pass => ui}/cfg/cfg-target-vendor.rs | 0 src/test/{run-pass => ui}/cfg/cfg_attr.rs | 0 .../{run-pass => ui}/cfg/cfg_inner_static.rs | 0 .../{run-pass => ui}/cfg/cfg_stmt_expr.rs | 0 .../{run-pass => ui}/cfg/cfgs-on-items.rs | 0 .../cfg/conditional-compile-arch.rs | 0 .../cfg/conditional-compile.rs | 0 .../cfg/crate-attributes-using-cfg_attr.rs | 0 .../chalkify/builtin-copy-clone.rs | 1 + .../chalkify/inherent_impl.rs | 1 + .../{run-pass => ui}/chalkify/projection.rs | 1 + .../{run-pass => ui}/chalkify/super_trait.rs | 1 + .../chalkify/trait_implied_bound.rs | 1 + .../chalkify/type_implied_bound.rs | 1 + src/test/{run-pass => ui}/char.rs | 2 + src/test/{run-pass => ui}/char_unicode.rs | 2 + .../check-static-recursion-foreign.rs | 2 + .../check_const-feature-gated.rs | 2 + src/test/ui/check_match/issue-43253.rs | 2 +- .../{run-pass => ui}/child-outlives-parent.rs | 1 + .../cleanup-arm-conditional.rs | 2 + .../cleanup-rvalue-during-if-and-while.rs | 1 + .../cleanup-rvalue-for-scope.rs | 2 + .../{run-pass => ui}/cleanup-rvalue-scopes.rs | 2 + ...nup-rvalue-temp-during-incomplete-alloc.rs | 2 + .../{run-pass => ui}/cleanup-shortcircuit.rs | 1 + .../{run-pass => ui}/clone-with-exterior.rs | 2 + .../close-over-big-then-small-data.rs | 2 + .../expect-fn-supply-fn-multiple.rs | 2 +- ...t-infer-var-supply-ty-with-bound-region.rs | 2 +- ...ct-infer-var-supply-ty-with-free-region.rs | 2 +- .../ui/closure-expected-type/issue-24421.rs | 2 +- src/test/ui/closure_promotion.rs | 2 +- src/test/{run-pass => ui}/cmp-default.rs | 2 + .../{run-pass => ui}/codegen-object-shim.rs | 2 + .../ui/codemap_tests/bad-format-args.stderr | 4 +- src/test/ui/codemap_tests/unicode_3.rs | 2 +- src/test/ui/codemap_tests/unicode_3.stderr | 2 +- .../coerce/coerce-expect-unsized.rs | 0 .../coerce/coerce-overloaded-autoderef.rs | 0 .../coerce/coerce-reborrow-imm-ptr-arg.rs | 0 .../coerce/coerce-reborrow-imm-ptr-rcvr.rs | 0 .../coerce/coerce-reborrow-imm-vec-arg.rs | 0 .../coerce/coerce-reborrow-imm-vec-rcvr.rs | 0 .../coerce/coerce-reborrow-mut-ptr-arg.rs | 0 .../coerce/coerce-reborrow-mut-ptr-rcvr.rs | 0 .../coerce/coerce-reborrow-mut-vec-arg.rs | 0 .../coerce/coerce-reborrow-mut-vec-rcvr.rs | 0 .../coerce/coerce-unify-return.rs | 0 .../{run-pass => ui}/coerce/coerce-unify.rs | 0 .../coerce/coerce-unsize-subtype.rs | 0 .../coercion/coerce-issue-49593-box-never.rs | 2 +- ...coercion-missing-tail-expected-type.stderr | 4 +- .../re_rebalance_coherence_lib-rpass.rs} | 9 + .../coherence/coherence-bigint-int.rs | 0 .../coherence/coherence-bigint-vecint.rs | 0 .../coherence/coherence-blanket.rs | 0 .../coherence-covered-type-parameter.rs | 0 .../coherence/coherence-impl-in-fn.rs | 0 .../coherence-iterator-vec-any-elem.rs | 0 .../coherence/coherence-iterator-vec.rs | 0 .../coherence-multidispatch-tuple.rs | 0 .../coherence-negative-impls-safe-rpass.rs} | 0 .../coherence/coherence-rfc447-constrained.rs | 0 src/test/ui/coherence/coherence-subtyping.rs | 2 +- .../coherence/coherence-where-clause.rs | 0 .../coherence/coherence_copy_like.rs | 0 ...erence_copy_like_err_fundamental_struct.rs | 2 +- ...herence-default-generic-associated-type.rs | 27 + .../re-rebalance-coherence-rpass.rs} | 0 .../{run-pass => ui}/collections-const-new.rs | 2 + src/test/{run-pass => ui}/command-exec.rs | 2 + src/test/{run-pass => ui}/command-pre-exec.rs | 2 + src/test/ui/command-uid-gid.rs | 32 + src/test/{run-pass => ui}/complex.rs | 2 + .../concat.rs => ui/concat-rpass.rs} | 2 + .../cfg-attr-crate-2.stderr | 2 +- .../cfg-attr-empty-is-unused.stderr | 2 +- .../cfg-attr-multi-false.rs | 2 +- .../cfg-attr-multi-invalid-1.stderr | 2 +- .../cfg-attr-multi-invalid-2.stderr | 2 +- .../cfg-attr-multi-true.rs | 2 +- .../cfg-attr-multi-true.stderr | 2 +- ...-attr-unknown-attribute-macro-expansion.rs | 3 +- ...r-unknown-attribute-macro-expansion.stderr | 6 +- .../cfg-generic-params.stderr | 20 +- .../apit-with-const-param.stderr | 2 + .../alloc-traits-impls-length-32.rs | 40 + .../alloc-traits-no-impls-length-33.rs | 43 + .../alloc-traits-no-impls-length-33.stderr | 48 + .../alloc-types-no-impls-length-33.rs | 26 + .../alloc-types-no-impls-length-33.stderr | 75 + .../core-traits-impls-length-32.rs | 66 + .../core-traits-no-impls-length-33.rs | 29 + .../core-traits-no-impls-length-33.stderr | 54 + .../array-wrapper-struct-ctor.stderr | 2 + .../ui/const-generics/broken-mir-1.stderr | 2 + src/test/ui/const-generics/broken-mir-2.rs | 3 +- .../ui/const-generics/broken-mir-2.stderr | 8 +- .../cannot-infer-const-args.stderr | 2 + .../cannot-infer-type-for-const-param.rs | 2 +- .../cannot-infer-type-for-const-param.stderr | 2 + .../concrete-const-as-fn-arg.stderr | 2 + .../concrete-const-impl-method.stderr | 2 + .../condition-in-trait-const-arg.stderr | 2 + .../ui/const-generics/const-arg-in-fn.stderr | 2 + .../const-expression-parameter.stderr | 2 + .../const-fn-with-const-param.stderr | 14 +- .../const-generic-array-wrapper.stderr | 2 + .../const-param-before-other-params.rs | 1 - .../const-param-before-other-params.stderr | 10 +- .../const-param-from-outer-fn.stderr | 14 +- .../const-param-in-trait-ungated.stderr | 2 +- .../const-param-in-trait.stderr | 2 + ...-type-depends-on-type-param-ungated.stderr | 2 +- ...st-param-type-depends-on-type-param.stderr | 12 +- .../const-parameter-uppercase-lint.stderr | 2 + src/test/ui/const-generics/const-types.stderr | 2 + .../derive-debug-array-wrapper.rs | 2 +- .../derive-debug-array-wrapper.stderr | 8 +- .../fn-taking-const-generic-array.stderr | 2 + .../impl-const-generic-struct.stderr | 2 + .../incorrect-number-of-const-args.stderr | 2 + src/test/ui/const-generics/issue-60263.stderr | 2 +- .../issue-60818-struct-constructors.rs | 2 +- .../issue-60818-struct-constructors.stderr | 2 + .../ui/const-generics/issue-61336-1.stderr | 2 + src/test/ui/const-generics/issue-61336-2.rs | 3 +- .../ui/const-generics/issue-61336-2.stderr | 18 +- src/test/ui/const-generics/issue-61336.rs | 3 +- src/test/ui/const-generics/issue-61336.stderr | 18 +- src/test/ui/const-generics/issue-61422.rs | 1 + src/test/ui/const-generics/issue-61422.stderr | 2 + .../mut-ref-const-param-array.stderr | 2 + .../struct-with-invalid-const-param.stderr | 12 +- ...transparent-maybeunit-array-wrapper.stderr | 2 + .../uninferred-consts-during-codegen-1.stderr | 2 + .../uninferred-consts-during-codegen-2.stderr | 2 + .../const-generics/unused-const-param.stderr | 2 + .../ui/consts/array-literal-index-oob.stderr | 2 +- .../{run-pass => ui}/consts/assoc-const.rs | 0 .../anon-extern-mod-cross-crate-1.rs | 0 .../consts/auxiliary/cci_borrow_lib.rs | 0 .../consts/auxiliary/cci_const.rs | 0 .../consts/auxiliary/cci_const_block.rs | 0 .../{run-pass => ui}/consts/bswap-const.rs | 0 .../consts/chained-constants-stackoverflow.rs | 0 .../consts/const-adt-align-mismatch.rs | 0 .../consts/const-autoderef.rs | 0 .../{run-pass => ui}/consts/const-big-enum.rs | 0 .../{run-pass => ui}/consts/const-binops.rs | 0 .../consts/const-bitshift-rhs-inference.rs | 0 .../consts/const-block-cross-crate-fn.rs | 0 .../consts/const-block-item-macro-codegen.rs | 0 .../consts/const-block-item.rs | 0 .../const-block-non-item-statement-3.rs | 0 .../const-block-non-item-statement-rpass.rs} | 0 .../consts/const-block-non-item-statement.rs | 2 +- .../{run-pass => ui}/consts/const-block.rs | 0 .../{run-pass => ui}/consts/const-bound.rs | 0 .../consts/const-byte-str-cast.rs | 0 .../consts/const-cast-ptr-int.rs | 0 .../{run-pass => ui}/consts/const-cast.rs | 0 .../{run-pass => ui}/consts/const-const.rs | 0 .../{run-pass => ui}/consts/const-contents.rs | 0 .../consts/const-cross-crate-const.rs | 0 .../consts/const-cross-crate-extern.rs | 0 src/test/ui/consts/const-deref-ptr.stderr | 2 +- .../{run-pass => ui}/consts/const-deref.rs | 0 .../consts/const-endianess.rs | 0 .../consts/const-enum-byref-self.rs | 0 .../consts/const-enum-byref.rs | 0 .../consts/const-enum-cast.rs | 0 .../{run-pass => ui}/consts/const-enum-ptr.rs | 0 .../consts/const-enum-struct.rs | 0 .../consts/const-enum-struct2.rs | 0 .../consts/const-enum-structlike.rs | 0 .../consts/const-enum-tuple.rs | 0 .../consts/const-enum-tuple2.rs | 0 .../consts/const-enum-tuplestruct.rs | 0 .../consts/const-enum-tuplestruct2.rs | 0 .../consts/const-enum-vec-index.rs | 0 .../consts/const-enum-vec-ptr.rs | 0 .../consts/const-enum-vector.rs | 0 .../consts/const-err-rpass.rs} | 0 ...nst-pointer-values-in-various-types.stderr | 2 +- src/test/ui/consts/const-eval/const_let.rs | 15 +- .../ui/consts/const-eval/const_let.stderr | 27 +- .../ui/consts/const-eval/const_panic.stderr | 2 +- .../const-eval/const_panic_libcore.stderr | 2 +- .../const_panic_libcore_main.stderr | 2 +- .../ui/consts/const-eval/const_prop_errors.rs | 2 +- .../ui/consts/const-eval/const_raw_ptr_ops.rs | 4 +- .../const-eval/const_raw_ptr_ops.stderr | 16 +- .../ui/consts/const-eval/const_signed_pat.rs | 2 +- src/test/ui/consts/const-eval/double_check.rs | 2 +- .../ui/consts/const-eval/double_promotion.rs | 2 +- .../consts/const-eval/duration_conversion.rs | 2 +- .../consts/const-eval/extern_fat_pointer.rs | 2 +- .../feature-gate-const_fn_union.stderr | 2 +- .../feature-gate-const_panic.stderr | 6 +- .../const-eval/ice-generic-assoc-const.rs | 2 +- src/test/ui/consts/const-eval/ice-packed.rs | 2 +- .../index_out_of_bounds_propagated.stderr | 2 +- .../ui/consts/const-eval/infinite_loop.rs | 4 +- .../ui/consts/const-eval/infinite_loop.stderr | 12 +- src/test/ui/consts/const-eval/issue-47971.rs | 2 +- .../ui/consts/const-eval/issue-49296.stderr | 2 +- src/test/ui/consts/const-eval/issue-50706.rs | 2 +- .../ui/consts/const-eval/issue-50814-2.stderr | 2 +- .../ui/consts/const-eval/issue-50814.stderr | 2 +- src/test/ui/consts/const-eval/issue-51300.rs | 2 +- src/test/ui/consts/const-eval/issue-52442.rs | 5 +- .../ui/consts/const-eval/issue-52442.stderr | 21 +- src/test/ui/consts/const-eval/issue-52475.rs | 4 +- .../ui/consts/const-eval/issue-52475.stderr | 12 +- src/test/ui/consts/const-eval/issue-53157.rs | 2 +- src/test/ui/consts/const-eval/issue-53401.rs | 2 +- src/test/ui/consts/const-eval/issue-55541.rs | 2 +- src/test/ui/consts/const-eval/issue-62272.rs | 9 + .../consts/const-eval/match-test-ptr-null.rs | 4 +- .../const-eval/match-test-ptr-null.stderr | 8 +- .../no_lint_for_statically_known_error.rs | 2 +- .../promote_mutable_zst_mir_borrowck.rs | 2 +- .../ui/consts/const-eval/pub_const_err.rs | 2 +- .../ui/consts/const-eval/pub_const_err_bin.rs | 2 +- .../ui/consts/const-eval/simple_with_undef.rs | 2 +- src/test/ui/consts/const-eval/ub-enum.rs | 32 +- src/test/ui/consts/const-eval/ub-enum.stderr | 56 +- src/test/ui/consts/const-eval/ub-nonnull.rs | 10 + .../ui/consts/const-eval/ub-nonnull.stderr | 27 +- src/test/ui/consts/const-eval/ub-ref.stderr | 2 +- .../consts/const-eval/union-ub-fat-ptr.stderr | 4 +- .../const-eval/unused-broken-const.stderr | 2 +- src/test/ui/consts/const-eval/valid-const.rs | 2 +- .../ui/consts/const-eval/zst_operand_eval.rs | 2 +- .../ui/consts/const-expr-addr-operator.rs | 2 +- .../consts/const-expr-in-fixed-length-vec.rs | 0 .../consts/const-expr-in-vec-repeat.rs | 0 .../consts/const-extern-function.rs | 0 .../consts/const-fields-and-indexing.rs | 0 .../consts/const-fn-const-eval.rs | 0 .../ui/consts/const-fn-destructuring-arg.rs | 2 +- .../consts/const-fn-feature-flags.rs | 0 .../consts/const-fn-method.rs | 0 .../consts/const-fn-nested.rs | 0 .../consts/const-fn-stability-calls.rs | 0 src/test/ui/consts/const-fn-type-name-any.rs | 29 + .../consts/const-fn-type-name.rs | 2 +- .../{run-pass => ui}/consts/const-fn-val.rs | 0 src/test/{run-pass => ui}/consts/const-fn.rs | 0 .../consts/const-index-feature-gate.rs | 0 .../consts/const-int-conversion-rpass.rs} | 2 + .../consts/const-int-overflowing-rpass.rs} | 2 + .../consts/const-int-rotate-rpass.rs} | 2 + .../consts/const-int-saturating-arith.rs | 1 + .../consts/const-int-sign-rpass.rs} | 2 + src/test/ui/consts/const-int-unchecked.stderr | 82 +- .../consts/const-int-wrapping-rpass.rs} | 2 + .../consts/const-labeled-break.rs | 6 +- .../const-len-underflow-separate-spans.stderr | 2 +- .../ui/consts/const-match-check.eval1.stderr | 4 +- .../ui/consts/const-match-check.eval2.stderr | 4 +- .../consts/const-match-check.matchck.stderr | 16 +- .../consts/const-meth-pattern.rs | 0 .../consts/const-needs_drop.rs | 2 + .../{run-pass => ui}/consts/const-negation.rs | 0 .../{run-pass => ui}/consts/const-negative.rs | 0 src/test/ui/consts/const-nonzero.rs | 2 +- .../consts/const-nullary-enum.rs | 0 .../consts/const-nullary-univariant-enum.rs | 0 .../const-pattern-not-const-evaluable.rs | 2 +- .../consts/const-pattern-variant.rs | 0 src/test/ui/consts/const-prop-ice.stderr | 2 +- src/test/ui/consts/const-prop-ice2.stderr | 2 +- .../consts/const-ptr-nonnull-rpass.rs} | 0 .../consts/const-ptr-unique-rpass.rs} | 0 .../consts/const-rec-and-tup.rs | 0 .../consts/const-region-ptrs-noncopy.rs | 0 .../consts/const-region-ptrs.rs | 0 .../consts/const-repeated-values.rs | 0 .../consts/const-size_of-align_of.rs | 0 src/test/ui/consts/const-slice-oob.stderr | 2 +- .../{run-pass => ui}/consts/const-str-ptr.rs | 0 .../consts/const-struct-offsets.rs | 0 .../{run-pass => ui}/consts/const-struct.rs | 0 .../consts/const-trait-to-trait.rs | 0 .../consts/const-tuple-struct.rs | 0 .../consts/const-typeid-of-rpass.rs} | 0 .../consts/const-unit-struct.rs | 0 .../consts/const-unsafe-fn.rs | 0 .../ui/consts/const-validation-fail-55455.rs | 2 +- .../consts/const-vec-of-fns.rs | 0 .../consts/const-vec-syntax.rs | 0 .../consts/const-vecs-and-slices.rs | 0 src/test/{run-pass => ui}/consts/const.rs | 0 .../consts/const_fn_return_nested_fn_ptr.rs | 2 +- src/test/ui/consts/const_let_assign.rs | 2 +- src/test/ui/consts/const_let_assign2.rs | 2 +- src/test/ui/consts/const_let_eq_float.rs | 2 +- src/test/ui/consts/const_let_irrefutable.rs | 2 +- .../ui/consts/const_let_refutable.nll.stderr | 31 - src/test/ui/consts/const_let_refutable.rs | 8 +- src/test/ui/consts/const_let_refutable.stderr | 16 +- .../consts/consts-in-patterns.rs | 0 .../ui/consts/dangling-alloc-id-ice.stderr | 2 +- src/test/ui/consts/dangling_raw_ptr.stderr | 2 +- .../consts/deref_in_pattern.rs | 0 src/test/ui/consts/drop_none.rs | 2 +- src/test/{run-pass => ui}/consts/ice-48279.rs | 0 src/test/ui/consts/int_ptr_for_zst_slices.rs | 2 +- src/test/ui/consts/invalid_promotion.rs | 2 +- .../{run-pass => ui}/consts/issue-37550.rs | 0 src/test/ui/consts/issue-51559.rs | 7 + src/test/ui/consts/issue-51559.stderr | 12 + src/test/ui/consts/issue-62045.rs | 2 +- .../consts/issue-broken-mir.rs | 0 .../consts/locals-in-const-fn.rs | 0 .../consts/match-const-fn-structs.rs | 0 .../min_const_fn/allow_const_fn_ptr.stderr | 2 +- .../allow_const_fn_ptr_feature_gate.rs | 2 +- .../allow_const_fn_ptr_feature_gate.stderr | 8 +- .../min_const_fn/bad_const_fn_body_ice.stderr | 2 +- .../ui/consts/min_const_fn/cast_errors.stderr | 10 +- .../min_const_fn/cmp_fn_pointers.stderr | 2 +- .../ui/consts/min_const_fn/loop_ice.stderr | 2 +- .../min_const_fn/min_const_fn.nll.stderr | 100 +- .../ui/consts/min_const_fn/min_const_fn.rs | 3 +- .../consts/min_const_fn/min_const_fn.stderr | 100 +- .../min_const_fn/min_const_fn_dyn.nll.stderr | 4 +- .../min_const_fn/min_const_fn_dyn.stderr | 4 +- .../min_const_fn/min_const_fn_fn_ptr.stderr | 4 +- .../min_const_fn/min_const_fn_libstd.rs | 2 +- .../min_const_fn_libstd_stability.stderr | 8 +- .../min_const_fn/min_const_fn_unsafe.stderr | 8 +- ...in_const_unsafe_fn_libstd_stability.stderr | 8 +- ...n_const_unsafe_fn_libstd_stability2.stderr | 6 +- .../consts/min_const_fn/mutable_borrow.stderr | 4 +- .../{run-pass => ui}/consts/mozjs-error.rs | 0 .../consts/non-scalar-cast.rs | 0 src/test/ui/consts/projection_qualif.stderr | 2 +- .../consts/promote_const_let.polonius.stderr | 29 + .../promote_evaluation_unused_result.rs | 2 +- src/test/ui/consts/promote_fn_calls.rs | 2 +- src/test/ui/consts/promote_fn_calls_std.rs | 2 +- .../ui/consts/promoted-validation-55454.rs | 2 +- src/test/ui/consts/promoted_regression.rs | 2 +- src/test/{run-pass => ui}/consts/promotion.rs | 0 .../{run-pass => ui}/consts/references.rs | 0 .../{run-pass => ui}/consts/repeat_match.rs | 0 .../consts/return-in-const-fn.rs | 0 .../const-fns.rs | 26 + .../const-fns.stderr | 13 + .../migrate-fail.rs | 26 + .../migrate-fail.stderr | 23 + .../migrate-pass.rs | 128 + .../nll-fail.rs | 25 + .../nll-fail.stderr | 23 + .../nll-pass.rs | 127 + .../run-pass.rs | 12 + .../trait-error.rs | 10 + .../trait-error.stderr | 13 + src/test/ui/consts/self_normalization.rs | 16 + src/test/ui/consts/self_normalization2.rs | 21 + .../consts/signed_enum_discr.rs | 0 .../ui/consts/single_variant_match_ice.stderr | 2 +- src/test/ui/consts/static-cycle-error.rs | 2 +- .../consts/static_mut_containing_mut_ref.rs | 2 +- src/test/ui/consts/std/slice.rs | 2 +- .../consts/transmute-const.rs | 0 .../consts/tuple-struct-constructors.rs | 0 src/test/ui/consts/underscore_const_names.rs | 2 +- .../consts/uninhabited-const-issue-61744.rs | 4 +- .../uninhabited-const-issue-61744.stderr | 59 +- src/test/ui/consts/union_constant.rs | 2 +- src/test/{run-pass => ui}/core-run-destroy.rs | 3 + .../{run-pass => ui}/crate-leading-sep.rs | 1 + .../crate-method-reexport-grrrrrrr.rs | 1 + .../{run-pass => ui}/crate-name-attr-used.rs | 1 + src/test/ui/crate-name-mismatch.rs | 2 +- src/test/ui/crate-name-mismatch.stderr | 2 +- .../anon-extern-mod-cross-crate-2.rs | 0 .../anon-extern-mod-cross-crate-1.rs | 0 .../auxiliary/anon_trait_static_method_lib.rs | 0 .../cross-crate/auxiliary/cci_borrow_lib.rs | 0 .../auxiliary/cci_capture_clause.rs | 0 .../cross-crate/auxiliary/cci_const.rs | 0 .../cross-crate/auxiliary/cci_impl_lib.rs | 0 .../cross-crate/auxiliary/cci_iter_lib.rs | 0 .../cross-crate/auxiliary/cci_nested_lib.rs | 0 .../auxiliary/cci_no_inline_lib.rs | 0 .../auxiliary/moves_based_on_type_lib.rs | 0 .../auxiliary/newtype_struct_xc.rs | 0 .../cross-crate/auxiliary/pub_static_array.rs | 0 .../auxiliary/reexported_static_methods.rs | 0 .../auxiliary/xcrate-trait-lifetime-param.rs | 0 .../auxiliary/xcrate_address_insignificant.rs | 0 .../xcrate_associated_type_defaults.rs | 0 .../xcrate_generic_fn_nested_return.rs | 0 .../auxiliary/xcrate_static_addresses.rs | 0 .../auxiliary/xcrate_unit_struct.rs | 0 .../cross-crate/cci_borrow.rs | 0 .../cross-crate/cci_capture_clause.rs | 0 .../cross-crate/cci_impl_exe.rs | 0 .../cross-crate/cci_iter_exe.rs | 0 .../cross-crate/cci_nested_exe.rs | 0 .../cross-crate/cci_no_inline_exe.rs | 0 .../cross-crate/cross-crate-const-pat.rs | 0 .../cross-crate-newtype-struct-pat.rs | 0 .../moves-based-on-type-cross-crate.rs | 0 .../reexported-static-methods-cross-crate.rs | 0 .../cross-crate/static-array-across-crate.rs | 0 .../xcrate-address-insignificant.rs | 0 .../xcrate-associated-type-defaults.rs | 0 .../cross-crate/xcrate-static-addresses.rs | 0 .../xcrate-trait-lifetime-param.rs | 0 .../cross-crate/xcrate-unit-struct.rs | 0 .../xcrate_generic_fn_nested_return.rs | 0 src/test/ui/cross/cross-fn-cache-hole.stderr | 2 +- .../{run-pass => ui}/crt-static-off-works.rs | 2 + .../{run-pass => ui}/crt-static-on-works.rs | 2 + src/test/ui/custom_attribute.rs | 6 +- src/test/ui/custom_attribute.stderr | 16 +- .../{run-pass => ui}/cycle-generic-bound.rs | 1 + .../dead-code-alias-in-pat.rs | 2 + .../dead-code-leading-underscore.rs | 1 + src/test/ui/dead-code-tuple-struct-field.rs | 2 +- src/test/{run-pass => ui}/debuginfo-lto.rs | 1 + src/test/{run-pass => ui}/deep.rs | 1 + .../default-alloc-error-hook.rs | 1 + .../default-associated-types.rs | 2 + .../default-method-parsing.rs | 1 + .../{run-pass => ui}/default-method-simple.rs | 2 + .../defaults-well-formedness.rs | 2 + .../auxiliary/field-method-macro.rs | 23 + .../auxiliary/nested-fn-macro.rs | 11 + .../auxiliary/private-use-macro.rs | 11 + .../ui/definition-reachable/field-method.rs | 11 + src/test/ui/definition-reachable/nested-fn.rs | 11 + .../definition-reachable/private-non-types.rs | 21 + .../ui/definition-reachable/private-types.rs | 19 + .../ui/definition-reachable/private-use.rs | 10 + .../deprecation-in-force-unstable.rs | 1 + .../ui/deprecation/atomic_initializers.fixed | 2 +- .../ui/deprecation/atomic_initializers.rs | 2 +- .../ui/deprecation/atomic_initializers.stderr | 2 +- .../deprecated-macro_escape-inner.stderr | 2 +- .../deprecation/deprecation-in-future.stderr | 2 +- .../ui/deprecation/derive_on_deprecated.rs | 2 +- .../derive_on_deprecated_forbidden.rs | 2 +- src/test/{run-pass => ui}/deref-lval.rs | 2 + src/test/{run-pass => ui}/deref-mut-on-ref.rs | 1 + src/test/{run-pass => ui}/deref-on-ref.rs | 1 + src/test/{run-pass => ui}/deref-rc.rs | 2 + src/test/{run-pass => ui}/deref.rs | 1 + src/test/ui/derive-uninhabited-enum-38885.rs | 2 +- src/test/ui/derived-errors/issue-31997.rs | 1 + src/test/ui/derived-errors/issue-31997.stderr | 2 +- .../derives/auxiliary/derive-marker-tricky.rs | 15 + src/test/ui/derives/derive-marker-tricky.rs | 16 + .../deriving-meta-empty-trait-list.stderr | 2 +- .../deriving-meta-unknown-trait.stderr | 2 +- .../ui/derives/deriving-with-repr-packed.rs | 8 +- .../derives/deriving-with-repr-packed.stderr | 8 +- .../deriving/auxiliary/derive-no-std.rs | 0 .../deriving/derive-no-std.rs | 0 .../deriving/derive-partialord-correctness.rs | 0 .../deriving/deriving-associated-types.rs | 0 .../deriving/deriving-bounds.rs | 0 .../deriving/deriving-clone-array.rs | 0 .../deriving/deriving-clone-enum.rs | 0 .../deriving/deriving-clone-generic-enum.rs | 0 .../deriving/deriving-clone-generic-struct.rs | 0 .../deriving-clone-generic-tuple-struct.rs | 0 .../deriving/deriving-clone-struct.rs | 0 .../deriving/deriving-clone-tuple-struct.rs | 0 .../deriving/deriving-cmp-generic-enum.rs | 0 .../deriving-cmp-generic-struct-enum.rs | 0 .../deriving/deriving-cmp-generic-struct.rs | 0 .../deriving-cmp-generic-tuple-struct.rs | 0 .../deriving/deriving-cmp-shortcircuit.rs | 0 .../deriving/deriving-copyclone.rs | 0 .../deriving/deriving-default-box.rs | 0 .../deriving/deriving-enum-single-variant.rs | 0 .../deriving/deriving-eq-ord-boxed-slice.rs | 0 .../deriving/deriving-hash.rs | 0 .../deriving/deriving-in-fn.rs | 0 .../deriving/deriving-in-macro.rs | 0 .../deriving/deriving-meta-multiple.rs | 0 .../deriving/deriving-meta.rs | 0 ...deriving-self-lifetime-totalord-totaleq.rs | 0 .../deriving/deriving-show-2.rs | 0 .../deriving/deriving-show.rs | 0 .../deriving/deriving-via-extension-c-enum.rs | 0 .../deriving/deriving-via-extension-enum.rs | 0 .../deriving-via-extension-hash-enum.rs | 0 .../deriving-via-extension-hash-struct.rs | 0 .../deriving-via-extension-struct-empty.rs | 0 ...-via-extension-struct-like-enum-variant.rs | 0 .../deriving-via-extension-struct-tuple.rs | 0 .../deriving/deriving-via-extension-struct.rs | 0 .../deriving-via-extension-type-params.rs | 0 .../deriving/deriving-with-repr-packed.rs | 0 src/test/ui/did_you_mean/issue-31424.stderr | 2 +- ...nicode-confusable-in-float-literal-expt.rs | 2 + ...de-confusable-in-float-literal-expt.stderr | 17 +- .../{run-pass => ui}/dispatch_from_dyn_zst.rs | 2 + .../diverging-fallback-control-flow.rs | 2 + .../diverging-fallback-method-chain.rs | 2 + .../diverging-fallback-option.rs | 2 + src/test/{run-pass => ui}/double-ref.rs | 2 + .../auxiliary/dropck_eyepatch_extern_crate.rs | 0 .../drop/drop-on-empty-block-exit.rs | 0 src/test/{run-pass => ui}/drop/drop-on-ret.rs | 0 .../drop/drop-struct-as-object.rs | 0 .../{run-pass => ui}/drop/drop-trait-enum.rs | 0 .../drop/drop-trait-generic.rs | 0 src/test/{run-pass => ui}/drop/drop-trait.rs | 0 .../drop/drop-uninhabited-enum.rs | 0 .../drop/drop-with-type-ascription-1.rs | 0 .../drop/drop-with-type-ascription-2.rs | 0 .../drop/dropck-eyepatch-extern-crate.rs | 0 .../drop/dropck-eyepatch-reorder.rs | 0 .../{run-pass => ui}/drop/dropck-eyepatch.rs | 0 .../drop/dropck_legal_cycles.rs | 0 src/test/ui/drop/dynamic-drop-async.rs | 328 + .../{run-pass => ui}/drop/dynamic-drop.rs | 6 +- .../drop/no-drop-flag-size.rs | 0 .../{run-pass => ui}/drop/nondrop-cycle.rs | 0 ...dropck_trait_cycle_checked.polonius.stderr | 74 + src/test/{run-pass => ui}/dupe-first-attr.rc | 0 src/test/ui/duplicate/dupe-symbols-7.stderr | 2 +- .../duplicated-external-mods.rs | 1 + ...dyn-2015-idents-in-decl-macros-unlinted.rs | 2 +- .../dyn-2015-idents-in-macros-unlinted.rs | 2 +- .../dyn-2015-no-warnings-without-lints.rs | 2 +- .../issue-56327-dyn-trait-in-macro-is-okay.rs | 2 +- .../dst-coerce-custom.rs | 0 .../dynamically-sized-types/dst-coerce-rc.rs | 0 .../dynamically-sized-types/dst-coercions.rs | 0 .../dynamically-sized-types/dst-deref-mut.rs | 0 .../dynamically-sized-types/dst-deref.rs | 0 .../dst-field-align.rs | 0 .../dynamically-sized-types/dst-index.rs | 0 .../dst-irrefutable-bind.rs | 0 .../dynamically-sized-types/dst-raw.rs | 0 .../dst-struct-sole.rs | 0 .../dynamically-sized-types/dst-struct.rs | 0 .../dst-trait-tuple.rs | 0 .../dynamically-sized-types/dst-trait.rs | 0 .../dynamically-sized-types/dst-tuple-sole.rs | 0 .../dynamically-sized-types/dst-tuple.rs | 0 .../{run-pass => ui}/early-ret-binop-add.rs | 2 + .../{run-pass => ui}/early-vtbl-resolution.rs | 2 + .../edition-keywords-2015-2015.rs | 2 + .../edition-keywords-2015-2018.rs | 2 + .../edition-keywords-2018-2015.rs | 2 + .../edition-keywords-2018-2018.rs | 2 + .../editions/edition-extern-crate-allowed.rs | 2 +- .../edition-extern-crate-allowed.stderr | 2 +- src/test/ui/editions/edition-feature-ok.rs | 2 +- .../ui/editions/edition-feature-redundant.rs | 2 +- .../edition-imports-virtual-2015-ambiguity.rs | 2 +- .../edition-keywords-2015-2015-expansion.rs | 2 +- ...dition-keywords-2015-2018-expansion.stderr | 4 +- .../edition-keywords-2018-2015-expansion.rs | 2 +- .../edition-keywords-2018-2015-parsing.stderr | 6 +- ...dition-keywords-2018-2018-expansion.stderr | 4 +- .../edition-keywords-2018-2018-parsing.stderr | 6 +- .../edition-raw-pointer-method-2015.stderr | 2 +- src/test/{run-pass => ui}/else-if.rs | 2 + ...mit-artifact-notifications.polonius.stderr | 1 + src/test/ui/emit-artifact-notifications.rs | 4 +- .../empty-allocation-non-null.rs | 2 + .../empty-allocation-rvalue-non-null.rs | 2 + .../empty-type-parameter-list.rs | 1 + src/test/ui/empty/empty-linkname.stderr | 2 +- .../ui/empty/empty-never-array.nll.stderr | 23 - src/test/ui/empty/empty-never-array.rs | 4 +- src/test/ui/empty/empty-never-array.stderr | 8 +- src/test/{run-pass => ui}/empty_global_asm.rs | 2 + src/test/ui/enable-unstable-lib-feature.rs | 1 - .../ui/enable-unstable-lib-feature.stderr | 2 +- ...re-gate-arbitrary_enum_discriminant.stderr | 6 +- .../env-args-reverse-iterator.rs | 1 + src/test/{run-pass => ui}/env-funky-keys.rs | 1 + src/test/{run-pass => ui}/env-home-dir.rs | 2 + src/test/{run-pass => ui}/env-null-vars.rs | 2 + src/test/{run-pass => ui}/env-vars.rs | 1 + .../{run-pass => ui}/epoch-gate-feature.rs | 2 + src/test/{run-pass => ui}/eq-multidispatch.rs | 2 + src/test/ui/error-codes/E0008.stderr | 2 +- src/test/ui/error-codes/E0034.stderr | 2 + src/test/ui/error-codes/E0121.stderr | 10 +- src/test/ui/error-codes/E0137.stderr | 6 +- src/test/ui/error-codes/E0254.rs | 2 +- src/test/ui/error-codes/E0259.rs | 1 - src/test/ui/error-codes/E0259.stderr | 2 +- src/test/ui/error-codes/E0260.rs | 2 - src/test/ui/error-codes/E0260.stderr | 2 +- src/test/ui/error-codes/E0301.stderr | 2 +- src/test/ui/error-codes/E0395.stderr | 2 +- src/test/ui/error-codes/E0396-fixed.stderr | 2 +- src/test/ui/error-codes/E0396.stderr | 2 +- src/test/ui/error-codes/E0432.stderr | 2 +- src/test/ui/error-codes/E0454.stderr | 2 +- src/test/ui/error-codes/E0458.stderr | 2 +- src/test/ui/error-codes/E0459.stderr | 2 +- src/test/ui/error-codes/E0528.rs | 2 +- src/test/ui/error-codes/E0528.stderr | 4 +- src/test/ui/error-codes/E0658.stderr | 2 +- src/test/ui/error-codes/E0661.rs | 2 + src/test/ui/error-codes/E0661.stderr | 2 +- src/test/ui/error-codes/E0662.rs | 2 + src/test/ui/error-codes/E0662.stderr | 2 +- src/test/ui/error-codes/E0663.rs | 2 + src/test/ui/error-codes/E0663.stderr | 2 +- src/test/ui/error-codes/E0664.rs | 2 + src/test/ui/error-codes/E0664.stderr | 2 +- src/test/ui/error-codes/E0705.rs | 2 +- src/test/ui/error-codes/E0730.stderr | 2 + .../e0119/auxiliary/issue-23563-a.rs | 2 +- src/test/{run-pass => ui}/estr-uniq.rs | 2 + ...xclusive_range_pattern_syntax_collision.rs | 4 +- ...sive_range_pattern_syntax_collision.stderr | 20 +- ...clusive_range_pattern_syntax_collision2.rs | 5 +- ...ive_range_pattern_syntax_collision2.stderr | 27 +- ...clusive_range_pattern_syntax_collision3.rs | 5 +- ...ive_range_pattern_syntax_collision3.stderr | 31 +- src/test/{run-pass => ui}/exec-env.rs | 1 + .../ui/exhaustive_integer_patterns.stderr | 28 +- .../auxiliary/cross_crate_ice.rs | 11 - .../declared_but_never_defined.rs | 6 - .../declared_but_not_defined_in_scope.rs | 12 - .../existential-types-with-cycle-error.rs | 12 - .../existential-types-with-cycle-error.stderr | 30 - .../existential-types-with-cycle-error2.rs | 16 - ...existential-types-with-cycle-error2.stderr | 30 - .../generic_duplicate_lifetime_param.rs | 9 - .../generic_duplicate_param_use10.rs | 12 - .../generic_lifetime_param.rs | 11 - .../no_inferrable_concrete_type.rs | 13 - .../no_inferrable_concrete_type.stderr | 27 - .../unused_generic_param.stderr | 14 - src/test/ui/explain.rs | 2 +- .../{run-pass => ui}/explicit-i-suffix.rs | 2 + src/test/ui/explore-issue-38412.stderr | 14 +- .../export-glob-imports-target.rs | 2 + src/test/{run-pass => ui}/export-multi.rs | 1 + .../export-non-interference2.rs | 2 + .../export-non-interference3.rs | 2 + src/test/{run-pass => ui}/expr-block-fn.rs | 2 + .../expr-block-generic-unique1.rs | 2 + .../expr-block-generic-unique2.rs | 2 + .../{run-pass => ui}/expr-block-generic.rs | 2 + src/test/{run-pass => ui}/expr-block-slot.rs | 1 + .../{run-pass => ui}/expr-block-unique.rs | 2 + src/test/{run-pass => ui}/expr-block.rs | 2 + src/test/{run-pass => ui}/expr-copy.rs | 2 + src/test/{run-pass => ui}/expr-empty-ret.rs | 2 + src/test/{run-pass => ui}/expr-fn.rs | 2 + src/test/{run-pass => ui}/expr-if-generic.rs | 2 + .../{run-pass => ui}/expr-if-panic-all.rs | 1 + src/test/{run-pass => ui}/expr-if-panic.rs | 2 + src/test/{run-pass => ui}/expr-if-unique.rs | 2 + src/test/{run-pass => ui}/expr-if.rs | 1 + src/test/{run-pass => ui}/expr-scope.rs | 1 + .../ext-expand-inner-exprs.rs | 2 + src/test/{run-pass => ui}/extend-for-unit.rs | 2 + src/test/{run-pass => ui}/exterior.rs | 2 + src/test/ui/extern-prelude-fail.stderr | 6 +- src/test/ui/extern-prelude.rs | 2 +- .../auxiliary/extern-crosscrate-source.rs | 0 .../extern/auxiliary/extern-take-value.rs | 0 .../auxiliary/extern_calling_convention.rs | 0 .../auxiliary/extern_mod_ordering_lib.rs | 0 .../extern/auxiliary/fat_drop.rs | 0 src/test/{run-pass => ui}/extern/extern-1.rs | 0 .../extern/extern-call-deep.rs | 0 .../extern/extern-call-deep2.rs | 0 .../extern/extern-call-direct.rs | 0 .../extern/extern-call-indirect.rs | 0 .../extern/extern-call-scrub.rs | 0 .../extern/extern-calling-convention-test.rs | 0 .../extern/extern-compare-with-return-type.rs | 0 src/test/ui/extern/extern-crate-visibility.rs | 4 +- .../ui/extern/extern-crate-visibility.stderr | 4 +- .../extern/extern-crosscrate.rs | 0 src/test/ui/extern/extern-ffi-fn-with-body.rs | 11 + .../ui/extern/extern-ffi-fn-with-body.stderr | 18 + .../extern/extern-foreign-crate.rs | 0 .../{run-pass => ui}/extern/extern-methods.rs | 0 .../{run-pass => ui}/extern/extern-mod-abi.rs | 0 .../extern/extern-mod-ordering-exe.rs | 0 .../extern/extern-pass-TwoU16s.rs | 0 .../extern/extern-pass-TwoU32s.rs | 0 .../extern/extern-pass-TwoU64s.rs | 0 .../extern/extern-pass-TwoU8s.rs | 0 .../extern/extern-pass-char.rs | 0 .../extern/extern-pass-double.rs | 0 .../extern/extern-pass-empty.rs | 0 .../extern/extern-pass-u32.rs | 0 .../extern/extern-pass-u64.rs | 0 .../extern/extern-prelude-core.rs | 0 .../extern/extern-prelude-core.stderr | 2 +- .../extern/extern-prelude-no-speculative.rs | 0 .../extern/extern-prelude-std.rs | 0 .../extern/extern-prelude-std.stderr | 2 +- .../{run-pass => ui}/extern/extern-pub.rs | 0 .../extern/extern-return-TwoU16s.rs | 0 .../extern/extern-return-TwoU32s.rs | 0 .../extern/extern-return-TwoU64s.rs | 0 .../extern/extern-return-TwoU8s.rs | 0 .../{run-pass => ui}/extern/extern-rust.rs | 0 .../extern/extern-take-value.rs | 0 .../extern/extern-thiscall.rs | 0 .../extern/extern-types-inherent-impl.rs | 0 .../extern/extern-types-manual-sync-send.rs | 0 .../extern/extern-types-pointer-cast.rs | 0 .../extern/extern-types-size_of_val.rs | 0 .../extern/extern-types-thin-pointer.rs | 0 .../extern/extern-types-trait-impl.rs | 0 .../extern/extern-vectorcall.rs | 0 .../extern/extern_fat_drop.rs | 0 src/test/ui/extern/external-doc-error.rs | 1 - src/test/ui/extern/external-doc-error.stderr | 12 +- .../extoption_env-not-defined.rs | 2 + src/test/{run-pass => ui}/fact.rs | 2 + src/test/{run-pass => ui}/fat-lto.rs | 1 + .../fat-ptr-cast-rpass.rs} | 2 + src/test/{run-pass => ui}/fds-are-cloexec.rs | 1 + .../ui/feature-gate-optimize_attribute.rs | 10 +- .../ui/feature-gate-optimize_attribute.stderr | 20 +- src/test/ui/feature-gate/await-macro.rs | 12 - src/test/ui/feature-gate/await-macro.stderr | 12 - .../feature-gate-c_variadic.stderr | 2 +- .../feature-gate/feature-gate-cfg_doctest.rs | 4 + .../feature-gate-cfg_doctest.stderr | 12 + .../feature-gate-static-nobundle-2.stderr | 2 +- .../issue-43106-gating-of-bench.rs | 13 +- .../issue-43106-gating-of-bench.stderr | 9 +- .../issue-43106-gating-of-builtin-attrs.rs | 1 + ...issue-43106-gating-of-builtin-attrs.stderr | 468 +- .../issue-43106-gating-of-inline.stderr | 2 +- .../issue-43106-gating-of-macro_escape.rs | 2 +- .../issue-43106-gating-of-macro_escape.stderr | 2 +- .../issue-43106-gating-of-test.rs | 12 +- .../issue-43106-gating-of-test.stderr | 9 +- .../issue-49983-see-issue-0.stderr | 4 +- src/test/ui/feature-gate/rustc-private.rs | 5 + src/test/ui/feature-gate/rustc-private.stderr | 12 + .../feature-gated-feature-in-macro-arg.stderr | 2 +- src/test/ui/feature-gates/bench.rs | 5 + src/test/ui/feature-gates/bench.stderr | 12 + .../feature-gate-abi-msp430-interrupt.stderr | 2 +- .../ui/feature-gates/feature-gate-abi.stderr | 126 +- .../feature-gate-abi_unadjusted.stderr | 2 +- .../feature-gate-alloc-error-handler.rs | 2 +- .../feature-gate-alloc-error-handler.stderr | 4 +- .../feature-gate-allocator_internals.stderr | 2 +- ...-allow-internal-unsafe-nested-macro.stderr | 2 +- ...llow-internal-unstable-nested-macro.stderr | 2 +- ...gate-allow-internal-unstable-struct.stderr | 2 +- ...eature-gate-allow-internal-unstable.stderr | 2 +- .../feature-gate-allow_fail.stderr | 2 +- .../feature-gate-arbitrary-self-types.stderr | 12 +- ...te-arbitrary_self_types-raw-pointer.stderr | 12 +- src/test/ui/feature-gates/feature-gate-asm.rs | 2 + .../ui/feature-gates/feature-gate-asm.stderr | 8 +- .../ui/feature-gates/feature-gate-asm2.rs | 2 +- .../ui/feature-gates/feature-gate-asm2.stderr | 6 +- .../feature-gate-assoc-type-defaults.stderr | 2 +- ...feature-gate-associated_type_bounds.stderr | 32 +- ...ature-gate-async-await-2015-edition.stderr | 2 +- .../feature-gates/feature-gate-async-await.rs | 1 - .../feature-gate-async-await.stderr | 19 +- .../feature-gate-box-expr.stderr | 2 +- .../feature-gate-box_patterns.stderr | 2 +- .../feature-gate-box_syntax.stderr | 2 +- .../feature-gate-cfg-target-has-atomic.rs | 6 +- .../feature-gate-cfg-target-has-atomic.stderr | 36 +- ...eature-gate-cfg-target-thread-local.stderr | 2 +- .../feature-gate-compiler-builtins.stderr | 2 +- .../feature-gate-concat_idents.stderr | 12 +- .../feature-gate-concat_idents2.rs | 2 - .../feature-gate-concat_idents2.stderr | 10 +- .../feature-gate-concat_idents3.rs | 2 - .../feature-gate-concat_idents3.stderr | 16 +- .../feature-gate-const-indexing.rs | 2 +- .../feature-gate-const_fn.stderr | 4 +- .../feature-gate-const_generics.stderr | 4 +- ...-gate-const_in_array_repeat_expressions.rs | 11 + ...e-const_in_array_repeat_expressions.stderr | 13 + .../feature-gate-const_transmute.stderr | 2 +- ...ture-gate-crate_visibility_modifier.stderr | 2 +- .../feature-gate-custom_attribute.rs | 35 +- .../feature-gate-custom_attribute.stderr | 92 +- .../feature-gate-custom_attribute2.rs | 34 +- .../feature-gate-custom_attribute2.stderr | 68 +- .../feature-gate-custom_test_frameworks.rs | 3 + ...feature-gate-custom_test_frameworks.stderr | 13 +- .../feature-gate-decl_macro.stderr | 2 +- ...ate-default_type_parameter_fallback.stderr | 2 +- .../feature-gates/feature-gate-doc_alias.rs | 2 +- .../feature-gate-doc_alias.stderr | 4 +- .../feature-gate-doc_cfg-cfg-rustdoc.stderr | 2 +- .../ui/feature-gates/feature-gate-doc_cfg.rs | 2 +- .../feature-gates/feature-gate-doc_cfg.stderr | 4 +- .../feature-gates/feature-gate-doc_keyword.rs | 2 +- .../feature-gate-doc_keyword.stderr | 4 +- .../feature-gates/feature-gate-doc_masked.rs | 2 +- .../feature-gate-doc_masked.stderr | 4 +- .../feature-gate-doc_spotlight.rs | 2 +- .../feature-gate-doc_spotlight.stderr | 4 +- .../feature-gate-dropck-ugeh-2.rs | 12 - .../feature-gate-dropck-ugeh-2.stderr | 14 - .../feature-gates/feature-gate-dropck-ugeh.rs | 29 - .../feature-gate-dropck-ugeh.stderr | 20 - ...eature-gate-exclusive-range-pattern.stderr | 2 +- .../feature-gate-existential-type.rs | 17 - .../feature-gate-existential-type.stderr | 21 - .../feature-gate-extern_absolute_paths.stderr | 6 +- .../feature-gate-extern_types.stderr | 2 +- .../feature-gate-external_doc.rs | 2 +- .../feature-gate-external_doc.stderr | 4 +- .../feature-gate-ffi_returns_twice.stderr | 2 +- .../feature-gate-format_args_nl.stderr | 6 +- .../feature-gate-fundamental.stderr | 2 +- .../feature-gate-generators.stderr | 2 +- ...ature-gate-generic_associated_types.stderr | 14 +- .../feature-gate-global_asm.stderr | 6 +- ...feature-gate-impl_trait_in_bindings.stderr | 4 +- .../feature-gate-intrinsics.stderr | 4 +- .../feature-gate-is_sorted.stderr | 8 +- .../feature-gate-label_break_value.stderr | 2 +- .../feature-gate-lang-items.stderr | 2 +- .../feature-gate-link_args.stderr | 6 +- .../feature-gate-link_cfg.stderr | 2 +- .../feature-gate-link_llvm_intrinsics.stderr | 2 +- .../feature-gates/feature-gate-linkage.stderr | 2 +- .../feature-gate-lint-reasons.stderr | 2 +- .../feature-gate-log_syntax.stderr | 6 +- .../feature-gates/feature-gate-log_syntax2.rs | 2 - .../feature-gate-log_syntax2.stderr | 8 +- .../feature-gate-macros_in_extern.stderr | 6 +- .../ui/feature-gates/feature-gate-main.rs | 2 +- .../ui/feature-gates/feature-gate-main.stderr | 4 +- .../feature-gate-marker_trait_attr.stderr | 2 +- .../feature-gates/feature-gate-may-dangle.rs | 2 +- .../feature-gate-may-dangle.stderr | 4 +- .../feature-gate-min_const_fn.stderr | 4 +- .../feature-gate-naked_functions.stderr | 4 +- .../feature-gate-needs-allocator.stderr | 2 +- .../feature-gate-never_type.stderr | 10 +- src/test/ui/feature-gates/feature-gate-nll.rs | 1 + .../ui/feature-gates/feature-gate-nll.stderr | 4 +- .../feature-gate-no-debug.stderr | 2 +- .../feature-gates/feature-gate-no_core.stderr | 2 +- .../feature-gate-non_ascii_idents.stderr | 26 +- .../feature-gate-non_exhaustive.stderr | 2 +- ...ate-omit-gdb-pretty-printer-section.stderr | 2 +- .../feature-gate-on-unimplemented.stderr | 2 +- .../feature-gate-optin-builtin-traits.stderr | 4 +- .../feature-gates/feature-gate-plugin.stderr | 2 +- .../feature-gate-plugin_registrar.stderr | 2 +- .../feature-gate-prelude_import.stderr | 2 +- .../feature-gate-profiler-runtime.stderr | 2 +- .../feature-gate-repr-simd.stderr | 4 +- .../feature-gates/feature-gate-repr128.stderr | 2 +- .../feature-gate-rustc-attrs-1.stderr | 6 +- .../feature-gates/feature-gate-rustc-attrs.rs | 21 +- .../feature-gate-rustc-attrs.stderr | 57 +- .../feature-gate-rustc_const_unstable.stderr | 2 +- .../feature-gate-sanitizer-runtime.stderr | 2 +- .../feature-gate-simd-ffi.stderr | 4 +- .../ui/feature-gates/feature-gate-simd.stderr | 2 +- .../feature-gate-slice-patterns.rs | 12 +- .../feature-gate-slice-patterns.stderr | 48 +- .../ui/feature-gates/feature-gate-start.rs | 2 +- .../feature-gates/feature-gate-start.stderr | 4 +- .../feature-gate-static-nobundle.stderr | 2 +- .../feature-gate-stmt_expr_attributes.stderr | 2 +- .../feature-gate-thread_local.stderr | 2 +- .../feature-gate-trace_macros.stderr | 6 +- .../feature-gate-trait-alias.stderr | 2 +- .../feature-gate-transparent_enums.stderr | 2 +- .../feature-gate-transparent_unions.stderr | 2 +- .../feature-gate-trivial_bounds.stderr | 22 +- .../feature-gate-try_blocks.stderr | 2 +- .../feature-gate-try_reserve.stderr | 2 +- .../feature-gate-type_alias_impl_trait.rs | 15 + .../feature-gate-type_alias_impl_trait.stderr | 21 + .../feature-gate-type_ascription.stderr | 2 +- ...-gate-unboxed-closures-manual-impls.stderr | 14 +- ...-gate-unboxed-closures-method-calls.stderr | 6 +- ...re-gate-unboxed-closures-ufcs-calls.stderr | 6 +- .../feature-gate-unboxed-closures.stderr | 4 +- ...feature-gate-unsized_tuple_coercion.stderr | 2 +- .../feature-gate-untagged_unions.stderr | 6 +- .../feature-gate-unwind-attributes.rs | 2 +- .../feature-gate-unwind-attributes.stderr | 4 +- .../filter-block-view-items.rs | 1 + src/test/{run-pass => ui}/fixup-deref-mut.rs | 2 + src/test/ui/fn_must_use.rs | 2 +- .../for-loop-while/auto-loop.rs | 0 .../for-loop-while/break-value.rs | 0 .../{run-pass => ui}/for-loop-while/break.rs | 0 .../for-loop-while/for-destruct.rs | 0 .../for-loop-while/for-loop-goofiness.rs | 0 .../for-loop-while/for-loop-has-unit-body.rs | 1 + .../for-loop-while/for-loop-into-iterator.rs | 0 .../for-loop-lifetime-of-unbound-values.rs | 0 .../for-loop-while/for-loop-macro.rs | 0 .../for-loop-mut-ref-element.rs | 0 .../for-loop-while/for-loop-no-std.rs | 0 .../for-loop-while/for-loop-panic.rs | 0 ...unconstrained-element-type-i32-fallback.rs | 0 .../foreach-external-iterators-break.rs | 0 ...xternal-iterators-hashmap-break-restart.rs | 0 .../foreach-external-iterators-hashmap.rs | 0 .../foreach-external-iterators-loop.rs | 0 .../foreach-external-iterators-nested.rs | 0 .../foreach-external-iterators.rs | 0 .../for-loop-while/foreach-nested.rs | 0 .../for-loop-while/foreach-put-structured.rs | 0 .../foreach-simple-outer-slot.rs | 0 .../for-loop-while/label_break_value.rs | 0 .../for-loop-while/labeled-break.rs | 0 .../for-loop-while/linear-for-loop.rs | 0 .../liveness-assign-imm-local-after-loop.rs | 0 .../for-loop-while/liveness-loop-break.rs | 0 .../for-loop-while/liveness-move-in-loop.rs | 0 .../for-loop-while/loop-break-cont-1.rs | 0 .../for-loop-while/loop-break-cont.rs | 0 .../for-loop-while/loop-break-value.rs | 0 .../for-loop-while/loop-diverges.rs | 0 .../for-loop-while/loop-label-shadowing.rs | 0 .../loop-labeled-break-value.rs | 0 .../loop-no-reinit-needed-post-bot.rs | 0 .../for-loop-while/loop-scope.rs | 0 .../for-loop-while/while-cont.rs | 0 .../for-loop-while/while-flow-graph.rs | 0 .../for-loop-while/while-label.rs | 0 .../for-loop-while/while-let.rs | 0 .../while-loop-constraints-2.rs | 0 .../for-loop-while/while-prelude-drop.rs | 0 .../for-loop-while/while-with-break.rs | 0 .../{run-pass => ui}/for-loop-while/while.rs | 0 ...oop-refutable-pattern-error-message.stderr | 4 +- .../foreign/auxiliary/fn-abi.rs | 0 .../foreign/auxiliary/foreign_lib.rs | 0 .../foreign/foreign-call-no-runtime.rs | 0 .../{run-pass => ui}/foreign/foreign-dupe.rs | 0 .../foreign/foreign-fn-linkname.rs | 0 .../foreign/foreign-fn-with-byval.rs | 0 .../foreign/foreign-int-types.rs | 0 .../foreign-mod-src/compiletest-ignore-dir | 0 .../foreign/foreign-mod-src/inner.rs | 0 .../foreign/foreign-mod-unused-const.rs | 0 .../foreign/foreign-no-abi.rs | 0 .../foreign-src/compiletest-ignore-dir | 0 .../foreign/foreign-src/foreign.rs | 0 .../foreign/foreign-truncated-arguments.rs | 0 src/test/{run-pass => ui}/foreign/foreign2.rs | 0 src/test/{run-pass => ui}/format-nan.rs | 2 + src/test/{run-pass => ui}/format-no-std.rs | 1 + src/test/{run-pass => ui}/format-ref-cell.rs | 2 + .../{run-pass => ui}/fsu-moves-and-copies.rs | 2 + .../{run-pass => ui}/fun-call-variants.rs | 2 + .../{run-pass => ui}/fun-indirect-call.rs | 2 + .../functions-closures/auxiliary/fn-abi.rs | 0 .../call-closure-from-overloaded-op.rs | 0 .../capture-clauses-boxed-closures.rs | 0 .../capture-clauses-unboxed-closures.rs | 0 .../functions-closures/clone-closure.rs | 0 .../closure-bounds-can-capture-chan.rs | 0 .../closure-expected-type/README.md | 0 .../expect-infer-supply-two-infers.rs | 0 .../closure-expected-type/issue-38714.rs | 0 .../supply-just-return-type.rs | 0 .../closure-expected-type/supply-nothing.rs | 0 .../functions-closures/closure-immediate.rs | 0 .../functions-closures/closure-inference.rs | 0 .../functions-closures/closure-inference2.rs | 0 .../functions-closures/closure-reform.rs | 0 .../closure-returning-closure.rs | 0 .../closure-to-fn-coercion.rs | 0 .../closure_to_fn_coercion-expected-types.rs | 0 .../functions-closures/copy-closure.rs | 0 .../functions-closures/fn-abi.rs | 0 .../functions-closures/fn-bare-assign.rs | 0 .../fn-bare-coerce-to-block.rs | 0 .../functions-closures/fn-bare-item.rs | 0 .../functions-closures/fn-bare-size.rs | 0 .../functions-closures/fn-bare-spawn.rs | 0 .../functions-closures/fn-coerce-field.rs | 0 .../functions-closures/fn-item-type-cast.rs | 0 .../functions-closures/fn-item-type-coerce.rs | 0 .../fn-item-type-zero-sized.rs | 0 .../functions-closures/fn-lval.rs | 0 .../functions-closures/fn-type-infer.rs | 0 .../implied-bounds-closure-arg-outlives.rs | 0 .../nullable-pointer-opt-closures.rs | 0 .../parallel-codegen-closures.rs | 0 .../functions-closures/return-from-closure.rs | 0 .../ui/future-incompatible-lint-group.stderr | 2 +- .../generator/addassign-yield.rs | 1 + .../generator/auxiliary/xcrate-reachable.rs | 0 .../generator/auxiliary/xcrate.rs | 0 .../generator/borrow-in-tail-expr.rs | 0 .../generator/conditional-drop.rs | 0 .../generator/control-flow.rs | 0 .../generator/drop-and-replace.rs | 1 + .../{run-pass => ui}/generator/drop-env.rs | 0 .../{run-pass => ui}/generator/issue-44197.rs | 0 .../{run-pass => ui}/generator/issue-52398.rs | 0 src/test/ui/generator/issue-53548-1.rs | 2 +- src/test/ui/generator/issue-53548.rs | 2 +- .../{run-pass => ui}/generator/issue-57084.rs | 0 .../{run-pass => ui}/generator/issue-58888.rs | 0 .../ui/generator/issue-62506-two_awaits.rs | 18 + .../generator/iterator-count.rs | 0 .../generator/live-upvar-across-yield.rs | 0 .../generator/match-bindings.rs | 0 .../generator/nested_generators.rs | 0 .../generator/non-static-is-unpin.rs | 0 .../generator/overlap-locals.rs | 2 + .../{run-pass => ui}/generator/panic-drops.rs | 0 .../{run-pass => ui}/generator/panic-safe.rs | 0 .../partial-initialization-across-yield.rs | 46 + ...partial-initialization-across-yield.stderr | 21 + .../generator/pin-box-generator.rs | 0 .../generator/reborrow-mut-upvar.rs | 0 ...escapes-but-not-over-yield.polonius.stderr | 20 + .../generator/resume-after-return.rs | 0 .../generator/size-moved-locals.rs | 14 + src/test/{run-pass => ui}/generator/smoke.rs | 0 .../generator/static-generators.rs | 0 .../too-live-local-in-immovable-gen.rs | 0 .../generator/xcrate-reachable.rs | 0 src/test/{run-pass => ui}/generator/xcrate.rs | 0 .../generator/yield-in-args-rev.rs | 0 .../generator/yield-in-box.rs | 0 .../generator/yield-in-initializer.rs | 0 .../generator/yield-subtype.rs | 0 src/test/ui/generic/generic-param-attrs.rs | 46 +- .../auxiliary/default_type_params_xc.rs | 0 .../generics/generic-alias-unique.rs | 0 ...generic-default-type-params-cross-crate.rs | 0 .../generics/generic-default-type-params.rs | 0 .../generics/generic-derived-type.rs | 0 .../generics/generic-exterior-unique.rs | 0 .../generics/generic-extern-mangle.rs | 0 .../generics/generic-fn-infer.rs | 0 .../generics/generic-fn-twice.rs | 0 .../generics/generic-fn-unique.rs | 0 .../{run-pass => ui}/generics/generic-fn.rs | 0 .../generics/generic-ivec-leak.rs | 0 .../generics/generic-newtype-struct.rs | 0 .../generics/generic-object.rs | 0 .../generics/generic-recursive-tag.rs | 0 .../generics/generic-static-methods.rs | 0 .../generics/generic-tag-corruption.rs | 0 .../generics/generic-tag-local.rs | 0 .../generics/generic-tag-match.rs | 0 .../generics/generic-tag-values.rs | 0 .../{run-pass => ui}/generics/generic-tag.rs | 0 .../generics/generic-temporary.rs | 0 .../{run-pass => ui}/generics/generic-tup.rs | 0 .../generics/generic-type-synonym.rs | 0 .../{run-pass => ui}/generics/generic-type.rs | 0 .../generics/generic-unique.rs | 0 src/test/{run-pass => ui}/global-scope.rs | 2 + .../{run-pass => ui}/guards-not-exhaustive.rs | 2 + src/test/{run-pass => ui}/guards.rs | 2 + src/test/{run-pass => ui}/hashmap-memory.rs | 2 + src/test/{run-pass => ui}/hello.rs | 2 + src/test/ui/hello_world/main.rs | 2 +- .../hrtb-binder-levels-in-object-types.rs | 0 .../hrtb-debruijn-object-types-in-closures.rs | 0 .../hrtb-fn-like-trait-object.rs | 0 .../hrtb-fn-like-trait.rs | 0 .../hrtb-opt-in-copy.rs | 0 .../higher-rank-trait-bounds/hrtb-parse.rs | 0 .../hrtb-precedence-of-plus-where-clause.rs | 0 .../hrtb-precedence-of-plus.rs | 0 .../hrtb-resolve-lifetime.rs | 0 .../hrtb-trait-object-paren-notation.rs | 0 .../hrtb-trait-object-passed-to-closure.rs | 0 .../hrtb-type-outlives.rs | 0 .../hrtb-unboxed-closure-trait.rs | 0 .../hrtb/hrtb-perfect-forwarding.nll.stderr | 2 +- src/test/ui/hrtb/issue-30786.migrate.stderr | 11 + src/test/ui/hrtb/issue-30786.nll.stderr | 14 + src/test/ui/hrtb/issue-30786.rs | 116 + src/test/ui/hrtb/issue-62203-hrtb-ice.rs | 50 + src/test/ui/hrtb/issue-62203-hrtb-ice.stderr | 22 + src/test/{run-pass => ui}/html-literals.rs | 2 + src/test/ui/huge-array-simple-32.rs | 11 + src/test/ui/huge-array-simple-32.stderr | 8 + src/test/ui/huge-array-simple-64.rs | 11 + src/test/ui/huge-array-simple-64.stderr | 8 + src/test/ui/huge-array-simple.rs | 20 - src/test/ui/huge-array-simple.stderr | 4 - src/test/ui/huge-array.rs | 3 +- src/test/ui/huge-array.stderr | 4 + src/test/ui/huge-enum.rs | 9 +- src/test/ui/huge-enum.stderr | 4 + src/test/ui/huge-struct.rs | 2 + src/test/ui/huge-struct.stderr | 4 + .../hygiene/auxiliary/legacy_interaction.rs | 1 - .../hygiene/auxiliary/my_crate.rs | 1 - .../ui/hygiene/auxiliary/stdlib-prelude.rs | 3 + .../ui/hygiene/auxiliary/transparent-basic.rs | 2 +- .../hygiene/auxiliary/unhygienic_example.rs | 1 - .../hygiene/auxiliary/xcrate.rs | 1 - src/test/ui/hygiene/dollar-crate-modern.rs | 2 +- .../ui/hygiene/dollar-crate-modern.stderr | 2 +- src/test/ui/hygiene/duplicate_lifetimes.rs | 19 + .../ui/hygiene/duplicate_lifetimes.stderr | 27 + src/test/ui/hygiene/eager-from-opaque-2.rs | 22 + src/test/ui/hygiene/eager-from-opaque.rs | 20 + src/test/ui/hygiene/expansion-info-reset.rs | 3 - .../ui/hygiene/expansion-info-reset.stderr | 2 +- .../extern-prelude-from-opaque-fail.rs | 28 + .../extern-prelude-from-opaque-fail.stderr | 37 + src/test/ui/hygiene/format-args.rs | 12 + src/test/ui/hygiene/generate-mod.rs | 2 +- src/test/ui/hygiene/generic_params.rs | 104 + src/test/ui/hygiene/generic_params.stderr | 8 + .../hygiene/hygiene-dodging-1.rs | 0 src/test/{run-pass => ui}/hygiene/hygiene.rs | 0 .../hygiene/hygienic-labels-in-let.rs | 0 .../hygiene/hygienic-labels-in-let.stderr | 0 .../hygiene/hygienic-labels.rs | 0 .../hygiene/hygienic-labels.stderr | 0 .../{run-pass => ui}/hygiene/issue-44128.rs | 2 +- .../{run-pass => ui}/hygiene/issue-47311.rs | 2 +- .../{run-pass => ui}/hygiene/issue-47312.rs | 2 +- .../hygiene/issue-61574-const-parameters.rs | 32 + .../issue-61574-const-parameters.stderr | 8 + src/test/{run-pass => ui}/hygiene/items.rs | 2 +- .../hygiene/legacy_interaction.rs | 4 +- src/test/{run-pass => ui}/hygiene/lexical.rs | 2 +- src/test/ui/hygiene/local_inner_macros.rs | 2 +- .../hygiene/no_implicit_prelude-2018.stderr | 2 - .../ui/hygiene/no_implicit_prelude.stderr | 1 - src/test/ui/hygiene/privacy-early.rs | 17 + src/test/ui/hygiene/privacy-early.stderr | 21 + .../ui/hygiene/rustc-macro-transparency.rs | 31 + .../hygiene/rustc-macro-transparency.stderr | 22 + .../hygiene/specialization.rs | 0 .../stdlib-prelude-from-opaque-early.rs | 21 + .../stdlib-prelude-from-opaque-late.rs | 16 + .../hygiene/trait_items-2.rs} | 2 +- src/test/ui/hygiene/transparent-basic.rs | 6 +- .../input.rs => ui/hygiene/unpretty-debug.rs} | 6 + src/test/ui/hygiene/unpretty-debug.stdout | 15 + .../hygiene/wrap_unhygienic_example.rs | 2 +- src/test/{run-pass => ui}/hygiene/xcrate.rs | 0 src/test/{run-pass => ui}/if-bot.rs | 2 + src/test/{run-pass => ui}/if-check.rs | 2 + src/test/{run-pass => ui}/if-ret.rs | 2 + src/test/ui/if/if-let.rs | 2 +- src/test/ui/if/if-let.stderr | 2 +- src/test/ui/if/if-no-match-bindings.rs | 6 + src/test/ui/if/if-no-match-bindings.stderr | 38 +- src/test/ui/if/ifmt-bad-arg.rs | 13 +- src/test/ui/if/ifmt-bad-arg.stderr | 94 +- src/test/ui/if/ifmt-unknown-trait.stderr | 11 + src/test/{run-pass => ui}/ifmt.rs | 2 + .../{run-pass => ui}/ignore-all-the-things.rs | 2 + src/test/{run-pass => ui}/impl-for-never.rs | 1 + .../inherent-impl.rs | 2 +- .../impl-inherent-non-conflict.rs | 1 + .../impl-not-adjacent-to-type.rs | 2 + .../{run-pass => ui}/impl-privacy-xc-1.rs | 1 + .../{run-pass => ui}/impl-privacy-xc-2.rs | 1 + .../impl-trait-in-bindings.rs | 2 + .../impl-trait-in-bindings.stderr | 4 +- ...sociated-impl-trait-type-generic-trait.rs} | 8 +- ... => associated-impl-trait-type-trivial.rs} | 6 +- ...-type.rs => associated-impl-trait-type.rs} | 6 +- .../impl-trait/auto-trait-leak-rpass.rs} | 0 .../impl-trait/auxiliary/xcrate.rs | 0 src/test/ui/impl-trait/bindings-opaque.stderr | 2 + src/test/ui/impl-trait/bindings.stderr | 14 +- .../ui/impl-trait/bound-normalization-fail.rs | 52 + .../bound-normalization-fail.stderr | 31 + .../ui/impl-trait/bound-normalization-pass.rs | 109 + .../bound-normalization-pass.stderr | 8 + .../impl-trait/bounds_regression.rs | 0 .../can-return-unconstrained-closure.rs | 2 +- .../ui/impl-trait/deprecated_annotation.rs | 2 +- .../impl-trait/equality-rpass.rs} | 0 .../impl-trait/example-calendar.rs | 0 .../{run-pass => ui}/impl-trait/example-st.rs | 0 .../impl-trait/existential_type_in_fn_body.rs | 12 - src/test/ui/impl-trait/issue-55872-1.rs | 22 + src/test/ui/impl-trait/issue-55872-1.stderr | 33 + src/test/ui/impl-trait/issue-55872-2.rs | 20 + src/test/ui/impl-trait/issue-55872-2.stderr | 21 + src/test/ui/impl-trait/issue-55872.rs | 19 + src/test/ui/impl-trait/issue-55872.stderr | 12 + .../infinite-impl-trait-issue-38064.stderr | 4 +- src/test/ui/impl-trait/issues/issue-42479.rs | 2 +- src/test/ui/impl-trait/issues/issue-49376.rs | 2 +- src/test/ui/impl-trait/issues/issue-52128.rs | 2 +- src/test/ui/impl-trait/issues/issue-53457.rs | 4 +- .../issue-55608-captures-empty-region.rs | 2 +- .../issues/issue-57464-unexpected-regions.rs | 2 +- .../{run-pass => ui}/impl-trait/lifetimes.rs | 0 src/test/ui/impl-trait/multiple-lifetimes.rs | 2 +- .../multiple-lifetimes/error-handling.rs | 4 +- .../multiple-lifetimes/error-handling.stderr | 2 +- .../ordinary-bounds-pick-original-elided.rs | 2 +- ...ds-pick-original-type-alias-impl-trait.rs} | 6 +- .../ordinary-bounds-pick-original.rs | 2 +- .../ordinary-bounds-pick-other.rs | 2 +- .../{run-pass => ui}/impl-trait/nesting.rs | 0 .../recursive-impl-trait-type.stderr | 28 +- ... => return-position-impl-trait-minimal.rs} | 2 +- .../type-alias-impl-trait-in-fn-body.rs | 12 + .../impl-trait/universal_hrtb_anon.rs | 0 .../impl-trait/universal_hrtb_named.rs | 0 .../universal_in_adt_in_parameters.rs | 0 .../universal_in_impl_trait_in_parameters.rs | 0 .../universal_in_trait_defn_parameters.rs | 0 .../impl-trait/universal_multiple_bounds.rs | 0 .../ui/impl-trait/universal_wrong_bounds.rs | 7 +- .../impl-trait/universal_wrong_bounds.stderr | 14 +- src/test/ui/impl-trait/where-allowed.rs | 6 +- src/test/ui/impl-trait/where-allowed.stderr | 79 +- .../{run-pass => ui}/impl-trait/xcrate.rs | 0 .../impl-trait/xcrate_simple.rs | 0 src/test/ui/import3.stderr | 2 +- .../extern-crate-self-macro-item.rs | 2 +- .../extern-crate-self-pass.rs | 2 +- ...-prelude-extern-crate-absolute-expanded.rs | 2 +- .../extern-prelude-extern-crate-cfg.rs | 2 +- .../extern-prelude-extern-crate-pass.rs | 2 +- ...e-extern-crate-restricted-shadowing.stderr | 2 +- .../extern-prelude-extern-crate-shadowing.rs | 2 +- src/test/ui/imports/gensymed.rs | 2 +- .../ui/imports/glob-conflict-cross-crate.rs | 2 +- .../imports/glob-conflict-cross-crate.stderr | 2 +- src/test/ui/imports/glob-shadowing.stderr | 4 +- .../auxiliary/crate_with_invalid_spans.rs | 0 .../crate_with_invalid_spans_macros.rs | 0 .../import-crate-with-invalid-spans/main.rs | 0 .../{run-pass => ui}/imports/import-from.rs | 0 .../imports/import-glob-0-rpass.rs} | 0 .../{run-pass => ui}/imports/import-glob-1.rs | 0 .../imports/import-glob-crate.rs | 0 .../imports/import-in-block.rs | 0 .../imports/import-prefix-macro.rs | 0 .../{run-pass => ui}/imports/import-rename.rs | 0 .../imports/import-trailing-comma.rs | 0 src/test/{run-pass => ui}/imports/import.rs | 0 src/test/{run-pass => ui}/imports/import2.rs | 0 src/test/{run-pass => ui}/imports/import3.rs | 0 src/test/{run-pass => ui}/imports/import4.rs | 0 src/test/{run-pass => ui}/imports/import5.rs | 0 src/test/{run-pass => ui}/imports/import6.rs | 0 src/test/{run-pass => ui}/imports/import7.rs | 0 src/test/{run-pass => ui}/imports/import8.rs | 0 src/test/{run-pass => ui}/imports/imports.rs | 0 src/test/ui/imports/issue-53140.rs | 2 +- src/test/ui/imports/issue-53269.stderr | 2 +- src/test/ui/imports/issue-53512.rs | 3 +- src/test/ui/imports/issue-53512.stderr | 8 +- src/test/ui/imports/issue-55457.stderr | 2 +- src/test/ui/imports/issue-55811.rs | 2 +- src/test/ui/imports/issue-56125.stderr | 12 +- src/test/ui/imports/issue-56263.rs | 2 +- src/test/ui/imports/issue-57539.stderr | 4 +- .../local-modularized-tricky-fail-1.stderr | 2 +- .../local-modularized-tricky-fail-2.stderr | 6 +- .../local-modularized-tricky-fail-3.stderr | 2 +- .../imports/local-modularized-tricky-pass.rs | 2 +- src/test/ui/imports/local-modularized.rs | 2 +- .../ui/imports/unresolved-imports-used.stderr | 2 +- src/test/ui/imports/unused-macro-use.stderr | 2 +- src/test/ui/imports/unused.stderr | 2 +- .../{run-pass => ui}/in-band-lifetimes.rs | 12 +- src/test/{run-pass => ui}/inc-range-pat.rs | 1 + .../{run-pass => ui}/infer-fn-tail-expr.rs | 2 + .../inference-variable-behind-raw-pointer.rs | 2 +- ...ference-variable-behind-raw-pointer.stderr | 2 +- .../ui/inference/inference_unstable.stderr | 4 +- .../inference_unstable_featured.stderr | 2 + .../inference_unstable_forced.stderr | 2 +- src/test/{run-pass => ui}/inherit-env.rs | 1 + src/test/{run-pass => ui}/init-large-type.rs | 2 + .../{run-pass => ui}/init-res-into-things.rs | 2 + src/test/ui/init-unsafe.rs | 1 + src/test/ui/init-unsafe.stderr | 2 +- src/test/{run-pass => ui}/inlined-main.rs | 2 + .../{run-pass => ui}/inner-attrs-on-impl.rs | 2 + src/test/{run-pass => ui}/inner-module.rs | 2 + src/test/{run-pass => ui}/inner-static.rs | 1 + src/test/{run-pass => ui}/instantiable.rs | 2 + .../internal/internal-unstable-noallow.stderr | 8 +- .../internal-unstable-thread-local.stderr | 2 +- src/test/ui/internal/internal-unstable.stderr | 10 +- .../intrinsics/auxiliary/cci_intrinsic.rs | 0 .../intrinsics/intrinsic-alignment.rs | 0 .../intrinsics/intrinsic-assume.rs | 0 .../intrinsics/intrinsic-atomics-cc.rs | 0 .../intrinsics/intrinsic-atomics.rs | 0 .../intrinsics/intrinsic-move-val-cleanups.rs | 0 .../intrinsics/intrinsic-move-val.rs | 0 .../intrinsics/intrinsic-uninit.rs | 0 .../intrinsics/intrinsic-unreachable.rs | 0 .../intrinsics/intrinsics-integer.rs | 0 .../intrinsics/intrinsics-math.rs | 0 .../intrinsics/unchecked_math_unstable.stderr | 6 +- src/test/ui/invalid/invalid-crate-type.stderr | 2 +- .../ui/invalid/invalid-plugin-attr.stderr | 2 +- .../invalid_const_promotion.rs | 2 + .../invoke-external-foreign.rs | 1 + src/test/{run-pass => ui}/irrefutable-unit.rs | 1 + src/test/ui/issue-53912.rs | 2 +- src/test/{run-pass => ui}/issue-59020.rs | 0 .../issues/auxiliary/cgu_test.rs | 0 .../issues/auxiliary/cgu_test_a.rs | 0 .../issues/auxiliary/cgu_test_b.rs | 0 .../{run-pass => ui}/issues/auxiliary/i8.rs | 0 .../{run-pass => ui}/issues/auxiliary/iss.rs | 0 .../issues/auxiliary/issue-10028.rs | 0 .../issues/auxiliary/issue-10031-aux.rs | 0 .../issues/auxiliary/issue-11224.rs | 0 .../issues/auxiliary/issue-11225-1.rs | 0 .../issues/auxiliary/issue-11225-2.rs | 0 .../issues/auxiliary/issue-11225-3.rs | 0 .../issues/auxiliary/issue-11508.rs | 0 .../issues/auxiliary/issue-11529.rs | 0 .../issues/auxiliary/issue-12133-dylib.rs | 0 .../issues/auxiliary/issue-12133-dylib2.rs | 0 .../issues/auxiliary/issue-12133-rlib.rs | 0 .../issues/auxiliary/issue-12612-1.rs | 0 .../issues/auxiliary/issue-12612-2.rs | 0 .../issues/auxiliary/issue-12660-aux.rs | 0 .../issues/auxiliary/issue-13507.rs | 0 .../issues/auxiliary/issue-13620-1.rs | 0 .../issues/auxiliary/issue-13620-2.rs | 0 .../issues/auxiliary/issue-13872-1.rs | 0 .../issues/auxiliary/issue-13872-2.rs | 0 .../issues/auxiliary/issue-13872-3.rs | 0 .../issues/auxiliary/issue-14344-1.rs | 0 .../issues/auxiliary/issue-14344-2.rs | 0 .../issues/auxiliary/issue-14421.rs | 0 .../issues/auxiliary/issue-14422.rs | 0 .../issues/auxiliary/issue-15562.rs | 0 .../issues/auxiliary/issue-16643.rs | 0 .../issues/auxiliary/issue-17662.rs | 0 .../issues/auxiliary/issue-17718-aux.rs | 0 .../issues/auxiliary/issue-18501.rs | 0 .../issues/auxiliary/issue-18514.rs | 0 .../issues/auxiliary/issue-18711.rs | 0 .../issues/auxiliary/issue-18913-1.rs | 0 .../issues/auxiliary/issue-18913-2.rs | 0 .../issues/auxiliary/issue-19293.rs | 0 .../issues/auxiliary/issue-19340-1.rs | 0 .../issues/auxiliary/issue-20389.rs | 0 .../issues/auxiliary/issue-2170-lib.rs | 0 .../issues/auxiliary/issue-2316-a.rs | 0 .../issues/auxiliary/issue-2316-b.rs | 0 .../issues/auxiliary/issue-2380.rs | 0 .../issues/auxiliary/issue-2414-a.rs | 0 .../issues/auxiliary/issue-2414-b.rs | 0 .../issues/auxiliary/issue-2472-b.rs | 0 .../issues/auxiliary/issue-25185-1.rs | 0 .../issues/auxiliary/issue-25185-2.rs | 0 .../issues/auxiliary/issue-2526.rs | 0 .../issues/auxiliary/issue-25467.rs | 0 .../issues/auxiliary/issue-2631-a.rs | 0 .../issues/auxiliary/issue-2723-a.rs | 0 src/test/ui/issues/auxiliary/issue-29265.rs | 9 + .../issues/auxiliary/issue-29485.rs | 0 .../issues/auxiliary/issue-3012-1.rs | 0 .../issues/auxiliary/issue-3136-a.rc | 0 .../issues/auxiliary/issue-3136-a.rs | 0 .../issues/auxiliary/issue-31702-1.rs | 0 .../issues/auxiliary/issue-31702-2.rs | 0 .../issues/auxiliary/issue-34796-aux.rs | 0 .../issues/auxiliary/issue-36954.rs | 0 .../issues/auxiliary/issue-38190.rs | 0 .../issues/auxiliary/issue-38226-aux.rs | 0 .../issues/auxiliary/issue-38715-modern.rs | 0 .../issues/auxiliary/issue-38715.rs | 0 .../issues/auxiliary/issue-3979-traits.rs | 0 .../issues/auxiliary/issue-39823.rs | 0 .../issues/auxiliary/issue-40469.rs | 0 .../issues/auxiliary/issue-41053.rs | 0 .../issues/auxiliary/issue-41394.rs | 0 .../issues/auxiliary/issue-42007-s.rs | 0 .../issues/auxiliary/issue-4208-cc.rs | 0 .../issues/auxiliary/issue-4545.rs | 0 .../issues/auxiliary/issue-48984-aux.rs | 0 src/test/ui/issues/auxiliary/issue-49544.rs | 7 + .../issues/auxiliary/issue-5518.rs | 0 .../issues/auxiliary/issue-5521.rs | 0 .../issues/auxiliary/issue-7178.rs | 0 .../issues/auxiliary/issue-7899.rs | 0 .../issues/auxiliary/issue-8044.rs | 0 .../issues/auxiliary/issue-8259.rs | 0 .../issues/auxiliary/issue-8401.rs | 0 .../issues/auxiliary/issue-9123.rs | 0 .../issues/auxiliary/issue-9155.rs | 0 .../issues/auxiliary/issue-9188.rs | 0 .../issues/auxiliary/issue-9906.rs | 0 .../issues/auxiliary/issue-9968.rs | 0 .../issues/auxiliary/xcrate-issue-61711-b.rs | 5 + .../{run-pass => ui}/issues/issue-10025.rs | 0 .../{run-pass => ui}/issues/issue-10028.rs | 0 .../{run-pass => ui}/issues/issue-10031.rs | 0 .../{run-pass => ui}/issues/issue-10228.rs | 0 .../{run-pass => ui}/issues/issue-10392.rs | 0 src/test/ui/issues/issue-10396.rs | 2 +- .../{run-pass => ui}/issues/issue-10436.rs | 0 src/test/ui/issues/issue-10456.rs | 2 +- src/test/ui/issues/issue-10536.rs | 8 +- src/test/ui/issues/issue-10536.stderr | 38 +- .../{run-pass => ui}/issues/issue-10626.rs | 0 .../{run-pass => ui}/issues/issue-10638.rs | 0 .../{run-pass => ui}/issues/issue-10682.rs | 0 .../{run-pass => ui}/issues/issue-10683.rs | 0 .../{run-pass => ui}/issues/issue-10718.rs | 0 .../{run-pass => ui}/issues/issue-10734.rs | 0 src/test/ui/issues/issue-10763.rs | 2 +- .../issues/issue-10764-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-10767.rs | 0 .../{run-pass => ui}/issues/issue-10802.rs | 0 .../{run-pass => ui}/issues/issue-10806.rs | 0 src/test/ui/issues/issue-10853.rs | 2 +- src/test/ui/issues/issue-10902.rs | 2 +- .../{run-pass => ui}/issues/issue-11047.rs | 0 .../{run-pass => ui}/issues/issue-11085.rs | 0 .../{run-pass => ui}/issues/issue-1112.rs | 0 .../{run-pass => ui}/issues/issue-11205.rs | 0 .../{run-pass => ui}/issues/issue-11224.rs | 0 .../{run-pass => ui}/issues/issue-11225-1.rs | 0 .../{run-pass => ui}/issues/issue-11225-2.rs | 0 .../{run-pass => ui}/issues/issue-11225-3.rs | 0 .../{run-pass => ui}/issues/issue-11267.rs | 0 .../{run-pass => ui}/issues/issue-11382.rs | 0 src/test/ui/issues/issue-11384.rs | 2 +- .../{run-pass => ui}/issues/issue-11508.rs | 0 .../{run-pass => ui}/issues/issue-11529.rs | 0 .../{run-pass => ui}/issues/issue-11552.rs | 0 .../{run-pass => ui}/issues/issue-11577.rs | 0 src/test/ui/issues/issue-11592.rs | 2 +- src/test/ui/issues/issue-11612.rs | 2 +- .../{run-pass => ui}/issues/issue-11677.rs | 0 .../{run-pass => ui}/issues/issue-11709.rs | 0 .../{run-pass => ui}/issues/issue-11820.rs | 0 src/test/ui/issues/issue-11869.rs | 2 +- .../{run-pass => ui}/issues/issue-11940.rs | 0 .../{run-pass => ui}/issues/issue-11958.rs | 0 .../{run-pass => ui}/issues/issue-12033.rs | 0 .../{run-pass => ui}/issues/issue-12133-1.rs | 0 .../{run-pass => ui}/issues/issue-12133-2.rs | 0 .../{run-pass => ui}/issues/issue-12133-3.rs | 0 .../{run-pass => ui}/issues/issue-12285.rs | 0 src/test/ui/issues/issue-12369.rs | 4 +- src/test/ui/issues/issue-12369.stderr | 4 +- src/test/ui/issues/issue-1251.rs | 2 +- .../{run-pass => ui}/issues/issue-1257.rs | 0 .../{run-pass => ui}/issues/issue-12582.rs | 0 .../{run-pass => ui}/issues/issue-12612.rs | 0 .../{run-pass => ui}/issues/issue-12660.rs | 0 .../{run-pass => ui}/issues/issue-12677.rs | 0 .../{run-pass => ui}/issues/issue-12699.rs | 0 src/test/ui/issues/issue-12729.rs | 2 +- .../{run-pass => ui}/issues/issue-12744.rs | 0 .../{run-pass => ui}/issues/issue-12860.rs | 0 .../{run-pass => ui}/issues/issue-12909.rs | 0 src/test/ui/issues/issue-12997-1.rs | 2 + src/test/ui/issues/issue-12997-1.stderr | 4 +- src/test/ui/issues/issue-12997-2.rs | 2 + src/test/ui/issues/issue-12997-2.stderr | 2 +- .../{run-pass => ui}/issues/issue-13027.rs | 0 src/test/ui/issues/issue-13105.rs | 2 +- src/test/ui/issues/issue-13167.rs | 2 +- .../{run-pass => ui}/issues/issue-13204.rs | 0 src/test/ui/issues/issue-13214.rs | 2 +- .../issues/issue-13259-windows-tcb-trash.rs | 0 .../{run-pass => ui}/issues/issue-13264.rs | 0 .../{run-pass => ui}/issues/issue-13304.rs | 0 .../{run-pass => ui}/issues/issue-13323.rs | 0 src/test/ui/issues/issue-13405.rs | 2 +- .../{run-pass => ui}/issues/issue-13434.rs | 0 .../{run-pass => ui}/issues/issue-13507-2.rs | 0 .../{run-pass => ui}/issues/issue-13620.rs | 0 .../{run-pass => ui}/issues/issue-13655.rs | 0 .../{run-pass => ui}/issues/issue-13665.rs | 0 src/test/ui/issues/issue-13703.rs | 2 +- .../{run-pass => ui}/issues/issue-13763.rs | 0 src/test/ui/issues/issue-13775.rs | 2 +- .../{run-pass => ui}/issues/issue-13808.rs | 0 src/test/ui/issues/issue-13837.rs | 2 +- .../{run-pass => ui}/issues/issue-13867.rs | 0 .../{run-pass => ui}/issues/issue-13872.rs | 0 .../{run-pass => ui}/issues/issue-13902.rs | 0 src/test/ui/issues/issue-14082.rs | 2 +- .../{run-pass => ui}/issues/issue-14229.rs | 0 src/test/ui/issues/issue-14254.rs | 2 +- .../{run-pass => ui}/issues/issue-14308.rs | 0 src/test/ui/issues/issue-14330.rs | 2 +- .../{run-pass => ui}/issues/issue-14344.rs | 0 .../{run-pass => ui}/issues/issue-14382.rs | 0 .../{run-pass => ui}/issues/issue-14393.rs | 0 .../{run-pass => ui}/issues/issue-14399.rs | 0 .../{run-pass => ui}/issues/issue-14421.rs | 0 .../{run-pass => ui}/issues/issue-14422.rs | 0 .../{run-pass => ui}/issues/issue-14456.rs | 0 .../{run-pass => ui}/issues/issue-1451.rs | 0 .../{run-pass => ui}/issues/issue-14589.rs | 0 .../{run-pass => ui}/issues/issue-1460.rs | 0 .../{run-pass => ui}/issues/issue-14821.rs | 0 src/test/ui/issues/issue-14837.rs | 2 +- .../{run-pass => ui}/issues/issue-14865.rs | 0 .../{run-pass => ui}/issues/issue-14875.rs | 0 src/test/ui/issues/issue-14901.rs | 2 +- .../{run-pass => ui}/issues/issue-14919.rs | 0 src/test/ui/issues/issue-14933.rs | 2 +- src/test/ui/issues/issue-14936.rs | 2 +- .../{run-pass => ui}/issues/issue-14940.rs | 0 .../{run-pass => ui}/issues/issue-14958.rs | 0 src/test/ui/issues/issue-14959.rs | 2 +- .../{run-pass => ui}/issues/issue-15043.rs | 0 .../{run-pass => ui}/issues/issue-15063.rs | 0 .../{run-pass => ui}/issues/issue-15080.rs | 4 +- .../{run-pass => ui}/issues/issue-15104.rs | 2 +- src/test/ui/issues/issue-15108.rs | 2 +- .../issues/issue-15129-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-15155.rs | 0 .../{run-pass => ui}/issues/issue-15189.rs | 0 .../{run-pass => ui}/issues/issue-15221.rs | 0 src/test/ui/issues/issue-15261.rs | 2 +- src/test/ui/issues/issue-15381.nll.stderr | 16 - src/test/ui/issues/issue-15381.rs | 4 +- src/test/ui/issues/issue-15381.stderr | 8 +- .../{run-pass => ui}/issues/issue-15444.rs | 0 .../{run-pass => ui}/issues/issue-15487.rs | 0 .../issues/issue-15523-big.rs | 0 .../{run-pass => ui}/issues/issue-15523.rs | 0 .../{run-pass => ui}/issues/issue-15562.rs | 0 .../{run-pass => ui}/issues/issue-15571.rs | 0 .../{run-pass => ui}/issues/issue-15673.rs | 0 .../{run-pass => ui}/issues/issue-15689-1.rs | 0 src/test/ui/issues/issue-15689-2.rs | 2 +- .../{run-pass => ui}/issues/issue-15730.rs | 0 .../{run-pass => ui}/issues/issue-15734.rs | 0 src/test/ui/issues/issue-15735.rs | 2 +- .../{run-pass => ui}/issues/issue-15763.rs | 0 .../{run-pass => ui}/issues/issue-15774.rs | 0 .../{run-pass => ui}/issues/issue-15793.rs | 0 .../{run-pass => ui}/issues/issue-15858.rs | 0 .../issue-15881-model-lexer-dotdotdot.rs | 0 src/test/ui/issues/issue-15919-32.rs | 12 + src/test/ui/issues/issue-15919-32.stderr | 8 + src/test/ui/issues/issue-15919-64.rs | 12 + src/test/ui/issues/issue-15919-64.stderr | 8 + src/test/ui/issues/issue-15919.rs | 16 - src/test/ui/issues/issue-15919.stderr | 4 - .../{run-pass => ui}/issues/issue-16151.rs | 0 src/test/ui/issues/issue-16250.stderr | 2 +- .../{run-pass => ui}/issues/issue-16256.rs | 0 .../{run-pass => ui}/issues/issue-16272.rs | 0 .../{run-pass => ui}/issues/issue-16278.rs | 0 .../{run-pass => ui}/issues/issue-16441.rs | 0 .../{run-pass => ui}/issues/issue-16452.rs | 0 .../{run-pass => ui}/issues/issue-16492.rs | 0 .../{run-pass => ui}/issues/issue-16530.rs | 0 .../{run-pass => ui}/issues/issue-16560.rs | 0 src/test/ui/issues/issue-16596.rs | 2 +- .../issues/issue-16597-empty.rs | 0 .../{run-pass => ui}/issues/issue-16597.rs | 0 .../{run-pass => ui}/issues/issue-1660.rs | 0 .../{run-pass => ui}/issues/issue-16602-1.rs | 0 .../{run-pass => ui}/issues/issue-16602-2.rs | 0 .../{run-pass => ui}/issues/issue-16602-3.rs | 0 .../{run-pass => ui}/issues/issue-16643.rs | 0 .../{run-pass => ui}/issues/issue-16648.rs | 0 src/test/ui/issues/issue-16668.rs | 2 +- .../{run-pass => ui}/issues/issue-16671.rs | 0 .../{run-pass => ui}/issues/issue-16739.rs | 0 .../{run-pass => ui}/issues/issue-16745.rs | 0 .../{run-pass => ui}/issues/issue-16774.rs | 0 .../{run-pass => ui}/issues/issue-16783.rs | 0 .../{run-pass => ui}/issues/issue-16819.rs | 0 .../issues/issue-16922-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-1696.rs | 0 src/test/ui/issues/issue-1697.rs | 2 +- src/test/ui/issues/issue-1697.stderr | 2 +- .../{run-pass => ui}/issues/issue-1701.rs | 0 .../{run-pass => ui}/issues/issue-17068.rs | 0 .../{run-pass => ui}/issues/issue-17074.rs | 0 src/test/ui/issues/issue-17121.rs | 2 +- .../{run-pass => ui}/issues/issue-17170.rs | 0 .../{run-pass => ui}/issues/issue-17216.rs | 0 .../{run-pass => ui}/issues/issue-17233.rs | 0 src/test/ui/issues/issue-17263.rs | 2 +- .../{run-pass => ui}/issues/issue-17302.rs | 0 .../{run-pass => ui}/issues/issue-17322.rs | 0 src/test/ui/issues/issue-17336.rs | 2 +- .../{run-pass => ui}/issues/issue-17351.rs | 0 .../{run-pass => ui}/issues/issue-17361.rs | 0 src/test/ui/issues/issue-17450.rs | 2 +- src/test/ui/issues/issue-17458.stderr | 2 +- .../{run-pass => ui}/issues/issue-17503.rs | 0 .../{run-pass => ui}/issues/issue-17662.rs | 0 .../issues/issue-17718-borrow-interior.rs | 0 .../issues/issue-17718-const-destructors.rs | 2 +- .../ui/issues/issue-17718-const-naming.stderr | 4 +- .../issues/issue-17718-parse-const.rs | 0 .../issue-17718-static-unsafe-interior.rs | 0 .../{run-pass => ui}/issues/issue-17718.rs | 0 src/test/ui/issues/issue-17732.rs | 2 +- .../{run-pass => ui}/issues/issue-17734.rs | 0 src/test/ui/issues/issue-17746.rs | 2 +- .../{run-pass => ui}/issues/issue-17756.rs | 0 .../{run-pass => ui}/issues/issue-17771.rs | 0 .../{run-pass => ui}/issues/issue-17816.rs | 0 .../{run-pass => ui}/issues/issue-17877.rs | 4 +- .../{run-pass => ui}/issues/issue-17897.rs | 0 src/test/ui/issues/issue-17904.rs | 2 +- .../{run-pass => ui}/issues/issue-18060.rs | 0 .../{run-pass => ui}/issues/issue-18075.rs | 0 src/test/ui/issues/issue-18083.rs | 2 +- src/test/ui/issues/issue-18088.rs | 2 +- .../{run-pass => ui}/issues/issue-18110.rs | 0 .../{run-pass => ui}/issues/issue-18173.rs | 0 src/test/ui/issues/issue-18188.rs | 2 +- src/test/ui/issues/issue-1821.rs | 2 +- .../{run-pass => ui}/issues/issue-18232.rs | 0 src/test/ui/issues/issue-18294.stderr | 2 +- .../{run-pass => ui}/issues/issue-18352.rs | 0 .../{run-pass => ui}/issues/issue-18353.rs | 0 .../{run-pass => ui}/issues/issue-18412.rs | 0 .../{run-pass => ui}/issues/issue-18425.rs | 0 src/test/ui/issues/issue-18446-2.rs | 2 +- .../{run-pass => ui}/issues/issue-18464.rs | 0 .../{run-pass => ui}/issues/issue-18501.rs | 0 .../{run-pass => ui}/issues/issue-18514.rs | 0 .../{run-pass => ui}/issues/issue-18539.rs | 0 .../{run-pass => ui}/issues/issue-18652.rs | 0 .../{run-pass => ui}/issues/issue-18655.rs | 0 src/test/ui/issues/issue-1866.rs | 2 +- .../{run-pass => ui}/issues/issue-18661.rs | 0 .../{run-pass => ui}/issues/issue-18685.rs | 0 .../{run-pass => ui}/issues/issue-18711.rs | 0 src/test/ui/issues/issue-18738.rs | 2 +- .../{run-pass => ui}/issues/issue-18767.rs | 0 .../issues/issue-18804/auxiliary/lib.rs | 0 .../issues/issue-18804/main.rs | 0 src/test/ui/issues/issue-18809.rs | 2 +- .../{run-pass => ui}/issues/issue-18845.rs | 0 .../{run-pass => ui}/issues/issue-18859.rs | 0 src/test/ui/issues/issue-18906.rs | 2 +- .../{run-pass => ui}/issues/issue-18913.rs | 0 .../{run-pass => ui}/issues/issue-18937-1.rs | 0 .../{run-pass => ui}/issues/issue-18952.rs | 0 src/test/ui/issues/issue-18988.rs | 2 +- .../{run-pass => ui}/issues/issue-19001.rs | 0 src/test/ui/issues/issue-19037.rs | 2 +- src/test/ui/issues/issue-19081.rs | 2 +- src/test/ui/issues/issue-19097.rs | 2 +- src/test/ui/issues/issue-19098.rs | 2 +- src/test/ui/issues/issue-19102.rs | 2 +- .../{run-pass => ui}/issues/issue-19127.rs | 0 src/test/ui/issues/issue-19129-1.rs | 2 +- src/test/ui/issues/issue-19129-2.rs | 2 +- .../{run-pass => ui}/issues/issue-19135.rs | 0 .../{run-pass => ui}/issues/issue-19244.rs | 0 .../{run-pass => ui}/issues/issue-19293.rs | 0 .../{run-pass => ui}/issues/issue-19340-1.rs | 0 .../{run-pass => ui}/issues/issue-19340-2.rs | 0 .../{run-pass => ui}/issues/issue-19358.rs | 0 .../{run-pass => ui}/issues/issue-19367.rs | 0 src/test/ui/issues/issue-19398.rs | 2 +- src/test/ui/issues/issue-19404.rs | 2 +- src/test/ui/issues/issue-19479.rs | 2 +- .../{run-pass => ui}/issues/issue-19499.rs | 0 src/test/ui/issues/issue-19631.rs | 2 +- src/test/ui/issues/issue-19632.rs | 2 +- .../{run-pass => ui}/issues/issue-1974.rs | 0 .../issues/issue-19811-escape-unicode.rs | 0 src/test/ui/issues/issue-19850.rs | 2 +- src/test/ui/issues/issue-19982.rs | 2 +- src/test/ui/issues/issue-20009.rs | 2 +- .../issues/issue-20055-box-trait.rs | 0 .../issues/issue-20055-box-unsized-array.rs | 0 src/test/ui/issues/issue-20091.rs | 2 +- .../{run-pass => ui}/issues/issue-20174.rs | 0 src/test/ui/issues/issue-20186.rs | 2 +- .../issues/issue-20313-rpass.rs} | 0 src/test/ui/issues/issue-20313.stderr | 2 +- .../{run-pass => ui}/issues/issue-20343.rs | 0 .../{run-pass => ui}/issues/issue-20389.rs | 0 src/test/ui/issues/issue-20396.rs | 2 +- src/test/ui/issues/issue-20414.rs | 2 +- .../{run-pass => ui}/issues/issue-20427.rs | 0 src/test/ui/issues/issue-20454.rs | 2 +- .../{run-pass => ui}/issues/issue-20544.rs | 0 .../{run-pass => ui}/issues/issue-20575.rs | 0 .../{run-pass => ui}/issues/issue-20616.rs | 0 src/test/ui/issues/issue-2063-resource.rs | 2 +- .../{run-pass => ui}/issues/issue-2063.rs | 0 src/test/ui/issues/issue-20644.rs | 2 +- .../{run-pass => ui}/issues/issue-20676.rs | 0 .../{run-pass => ui}/issues/issue-2074.rs | 0 src/test/ui/issues/issue-20763-1.rs | 2 +- src/test/ui/issues/issue-20763-2.rs | 2 +- src/test/ui/issues/issue-20797.rs | 2 +- .../{run-pass => ui}/issues/issue-20803.rs | 0 .../{run-pass => ui}/issues/issue-20823.rs | 0 src/test/ui/issues/issue-20825-2.rs | 2 +- .../{run-pass => ui}/issues/issue-20847.rs | 0 .../{run-pass => ui}/issues/issue-20953.rs | 0 .../{run-pass => ui}/issues/issue-21033.rs | 0 .../{run-pass => ui}/issues/issue-21058.rs | 5 +- src/test/ui/issues/issue-21140.rs | 2 +- src/test/ui/issues/issue-21174-2.rs | 2 +- src/test/ui/issues/issue-21245.rs | 2 +- .../{run-pass => ui}/issues/issue-21291.rs | 0 .../{run-pass => ui}/issues/issue-21306.rs | 0 .../{run-pass => ui}/issues/issue-21361.rs | 0 src/test/ui/issues/issue-21363.rs | 2 +- .../{run-pass => ui}/issues/issue-21384.rs | 0 .../{run-pass => ui}/issues/issue-21400.rs | 0 src/test/ui/issues/issue-21402.rs | 2 +- .../{run-pass => ui}/issues/issue-21475.rs | 0 .../{run-pass => ui}/issues/issue-21486.rs | 0 src/test/ui/issues/issue-21520.rs | 2 +- src/test/ui/issues/issue-21562.rs | 2 +- src/test/ui/issues/issue-21596.stderr | 1 + src/test/ui/issues/issue-21622.rs | 2 +- src/test/ui/issues/issue-21634.rs | 2 +- .../{run-pass => ui}/issues/issue-21655.rs | 0 .../{run-pass => ui}/issues/issue-2170-exe.rs | 0 .../{run-pass => ui}/issues/issue-21721.rs | 0 src/test/ui/issues/issue-21726.rs | 2 +- src/test/ui/issues/issue-21891.rs | 2 +- .../{run-pass => ui}/issues/issue-2190-1.rs | 0 .../{run-pass => ui}/issues/issue-21909.rs | 0 .../{run-pass => ui}/issues/issue-21922.rs | 0 .../{run-pass => ui}/issues/issue-22008.rs | 0 .../{run-pass => ui}/issues/issue-22036.rs | 0 src/test/ui/issues/issue-22066.rs | 2 +- .../{run-pass => ui}/issues/issue-2214.rs | 5 +- .../{run-pass => ui}/issues/issue-2216.rs | 0 .../{run-pass => ui}/issues/issue-22258.rs | 0 .../{run-pass => ui}/issues/issue-22346.rs | 0 src/test/ui/issues/issue-22356.rs | 2 +- src/test/ui/issues/issue-22375.rs | 2 +- .../{run-pass => ui}/issues/issue-22403.rs | 0 .../{run-pass => ui}/issues/issue-22426.rs | 0 .../{run-pass => ui}/issues/issue-22463.rs | 0 src/test/ui/issues/issue-22471.rs | 2 +- .../issues/issue-22536-copy-mustnt-zero.rs | 0 .../{run-pass => ui}/issues/issue-22546.rs | 0 .../{run-pass => ui}/issues/issue-22577.rs | 0 .../{run-pass => ui}/issues/issue-22629.rs | 0 src/test/ui/issues/issue-22644.stderr | 13 +- src/test/ui/issues/issue-22777.rs | 2 +- src/test/ui/issues/issue-22781.rs | 2 +- src/test/ui/issues/issue-22814.rs | 2 +- .../{run-pass => ui}/issues/issue-22828.rs | 0 .../{run-pass => ui}/issues/issue-2284.rs | 0 .../{run-pass => ui}/issues/issue-22864-1.rs | 0 .../{run-pass => ui}/issues/issue-22864-2.rs | 0 .../{run-pass => ui}/issues/issue-2288.rs | 0 src/test/ui/issues/issue-22894.rs | 2 +- .../{run-pass => ui}/issues/issue-22992-2.rs | 0 .../{run-pass => ui}/issues/issue-22992.rs | 0 src/test/ui/issues/issue-23024.stderr | 2 +- .../{run-pass => ui}/issues/issue-23036.rs | 0 src/test/ui/issues/issue-2311-2.rs | 2 +- src/test/ui/issues/issue-2311.rs | 2 +- src/test/ui/issues/issue-2312.rs | 2 +- .../{run-pass => ui}/issues/issue-2316-c.rs | 0 .../{run-pass => ui}/issues/issue-23208.rs | 0 .../{run-pass => ui}/issues/issue-23261.rs | 0 .../{run-pass => ui}/issues/issue-23304-1.rs | 0 .../{run-pass => ui}/issues/issue-23304-2.rs | 0 .../{run-pass => ui}/issues/issue-23311.rs | 0 .../{run-pass => ui}/issues/issue-23336.rs | 0 .../issue-23338-ensure-param-drop-order.rs | 0 ...ssue-23338-params-outlive-temps-of-body.rs | 0 src/test/ui/issues/issue-23406.rs | 2 +- .../{run-pass => ui}/issues/issue-23433.rs | 0 src/test/ui/issues/issue-23442.rs | 2 +- src/test/ui/issues/issue-23477.rs | 2 +- .../{run-pass => ui}/issues/issue-23485.rs | 0 .../{run-pass => ui}/issues/issue-23491.rs | 0 src/test/ui/issues/issue-23550.rs | 2 +- .../issues/issue-23611-enum-swap-in-drop.rs | 0 .../{run-pass => ui}/issues/issue-23649-1.rs | 0 .../{run-pass => ui}/issues/issue-23649-2.rs | 0 src/test/ui/issues/issue-23649-3.rs | 2 +- .../{run-pass => ui}/issues/issue-23699.rs | 0 .../{run-pass => ui}/issues/issue-23781.rs | 0 .../{run-pass => ui}/issues/issue-2380-b.rs | 0 .../{run-pass => ui}/issues/issue-23808.rs | 0 .../{run-pass => ui}/issues/issue-23825.rs | 0 .../{run-pass => ui}/issues/issue-2383.rs | 0 .../{run-pass => ui}/issues/issue-23833.rs | 0 .../{run-pass => ui}/issues/issue-23891.rs | 0 .../{run-pass => ui}/issues/issue-23898.rs | 0 .../{run-pass => ui}/issues/issue-23958.rs | 0 .../issues/issue-23968-const-not-overflow.rs | 0 .../{run-pass => ui}/issues/issue-23992.rs | 0 .../{run-pass => ui}/issues/issue-24010.rs | 2 + src/test/ui/issues/issue-24085.rs | 2 +- .../{run-pass => ui}/issues/issue-24086.rs | 0 .../{run-pass => ui}/issues/issue-2414-c.rs | 0 src/test/ui/issues/issue-24161.rs | 2 +- src/test/ui/issues/issue-24227.rs | 2 +- .../{run-pass => ui}/issues/issue-2428.rs | 0 .../{run-pass => ui}/issues/issue-24308.rs | 0 .../{run-pass => ui}/issues/issue-24313.rs | 0 src/test/ui/issues/issue-24338.rs | 2 +- .../{run-pass => ui}/issues/issue-24353.rs | 0 src/test/ui/issues/issue-24389.rs | 2 +- src/test/ui/issues/issue-24434.rs | 2 +- .../{run-pass => ui}/issues/issue-2445-b.rs | 0 .../{run-pass => ui}/issues/issue-2445.rs | 0 .../{run-pass => ui}/issues/issue-24533.rs | 0 ...535-allow-mutable-borrow-in-match-guard.rs | 0 .../{run-pass => ui}/issues/issue-24589.rs | 0 .../{run-pass => ui}/issues/issue-2463.rs | 0 .../auxiliary/issue-24687-lib.rs | 0 .../auxiliary/issue-24687-mbcs-in-comments.rs | 0 .../issue-24687-embed-debuginfo/main.rs | 0 .../{run-pass => ui}/issues/issue-2472.rs | 0 .../{run-pass => ui}/issues/issue-24779.rs | 0 .../issues/issue-24805-dropck-itemless.rs | 8 +- src/test/ui/issues/issue-2487-a.rs | 2 +- .../issues/issue-24945-repeat-dash-opts.rs | 0 .../{run-pass => ui}/issues/issue-24947.rs | 0 .../{run-pass => ui}/issues/issue-24954.rs | 0 src/test/ui/issues/issue-2502.rs | 2 +- .../{run-pass => ui}/issues/issue-25089.rs | 0 .../{run-pass => ui}/issues/issue-25145.rs | 0 src/test/ui/issues/issue-25180.rs | 2 +- .../{run-pass => ui}/issues/issue-25185.rs | 0 .../{run-pass => ui}/issues/issue-2526-a.rs | 0 .../{run-pass => ui}/issues/issue-25279.rs | 0 .../{run-pass => ui}/issues/issue-25339.rs | 0 .../{run-pass => ui}/issues/issue-25343.rs | 0 src/test/ui/issues/issue-25394.rs | 2 +- .../{run-pass => ui}/issues/issue-25467.rs | 0 .../{run-pass => ui}/issues/issue-25497.rs | 0 .../{run-pass => ui}/issues/issue-2550.rs | 0 .../{run-pass => ui}/issues/issue-25515.rs | 0 .../issues/issue-25549-multiple-drop.rs | 0 src/test/ui/issues/issue-25579.rs | 2 +- .../{run-pass => ui}/issues/issue-25679.rs | 0 .../{run-pass => ui}/issues/issue-25693.rs | 0 .../{run-pass => ui}/issues/issue-25700-1.rs | 0 .../{run-pass => ui}/issues/issue-25700-2.rs | 0 .../issues/issue-25746-bool-transmute.rs | 0 .../{run-pass => ui}/issues/issue-25757.rs | 0 .../{run-pass => ui}/issues/issue-25810.rs | 0 src/test/ui/issues/issue-25826.stderr | 2 +- .../{run-pass => ui}/issues/issue-25916.rs | 0 src/test/ui/issues/issue-26095.rs | 2 +- src/test/ui/issues/issue-2611-3.rs | 2 +- .../{run-pass => ui}/issues/issue-26127.rs | 0 src/test/ui/issues/issue-26158.rs | 6 - src/test/ui/issues/issue-26158.stderr | 9 - src/test/ui/issues/issue-26205.rs | 2 +- .../{run-pass => ui}/issues/issue-26251.rs | 0 .../{run-pass => ui}/issues/issue-2631-b.rs | 0 .../{run-pass => ui}/issues/issue-26322.rs | 0 .../{run-pass => ui}/issues/issue-2633-2.rs | 0 .../{run-pass => ui}/issues/issue-2633.rs | 0 .../{run-pass => ui}/issues/issue-2642.rs | 0 .../{run-pass => ui}/issues/issue-26468.rs | 0 .../{run-pass => ui}/issues/issue-26484.rs | 0 .../{run-pass => ui}/issues/issue-26641.rs | 0 src/test/ui/issues/issue-26646.rs | 2 +- .../{run-pass => ui}/issues/issue-26655.rs | 0 .../{run-pass => ui}/issues/issue-26709.rs | 0 .../{run-pass => ui}/issues/issue-26802.rs | 0 .../{run-pass => ui}/issues/issue-26805.rs | 0 .../issues/issue-26873-multifile.rs | 0 .../issues/issue-26873-multifile/A/B.rs | 0 .../issues/issue-26873-multifile/A/C.rs | 0 .../issues/issue-26873-multifile/A/mod.rs | 0 .../compiletest-ignore-dir | 0 .../issues/issue-26873-multifile/mod.rs | 0 .../issues/issue-26873-onefile.rs | 0 .../issues/issue-26905-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-26996.rs | 0 src/test/ui/issues/issue-26997.rs | 2 +- .../{run-pass => ui}/issues/issue-27021.rs | 0 src/test/ui/issues/issue-27042.rs | 1 + src/test/ui/issues/issue-27042.stderr | 24 +- .../issue-27054-primitive-binary-ops.rs | 0 .../issues/issue-27060-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-2708.rs | 0 src/test/ui/issues/issue-27105.rs | 2 +- .../{run-pass => ui}/issues/issue-2718.rs | 0 .../{run-pass => ui}/issues/issue-2723-b.rs | 0 .../{run-pass => ui}/issues/issue-27240.rs | 0 .../{run-pass => ui}/issues/issue-27268.rs | 0 src/test/ui/issues/issue-27281.rs | 2 +- .../issue-27282-reborrow-ref-mut-in-guard.rs | 2 - ...sue-27282-reborrow-ref-mut-in-guard.stderr | 2 +- .../{run-pass => ui}/issues/issue-27320.rs | 0 .../{run-pass => ui}/issues/issue-2734.rs | 0 .../{run-pass => ui}/issues/issue-2735-2.rs | 0 .../{run-pass => ui}/issues/issue-2735-3.rs | 0 .../{run-pass => ui}/issues/issue-2735.rs | 0 .../issues/issue-27401-dropflag-reinit.rs | 0 src/test/ui/issues/issue-2748-a.rs | 2 +- .../{run-pass => ui}/issues/issue-2748-b.rs | 0 src/test/ui/issues/issue-27583.rs | 2 +- .../{run-pass => ui}/issues/issue-27639.rs | 0 .../{run-pass => ui}/issues/issue-27859.rs | 0 src/test/ui/issues/issue-27889.rs | 2 +- .../{run-pass => ui}/issues/issue-27890.rs | 0 .../{run-pass => ui}/issues/issue-27901.rs | 0 .../{run-pass => ui}/issues/issue-27949.rs | 0 .../{run-pass => ui}/issues/issue-27997.rs | 0 src/test/ui/issues/issue-2804-2.rs | 2 +- src/test/ui/issues/issue-28075.stderr | 2 +- src/test/ui/issues/issue-28134.rs | 2 +- src/test/ui/issues/issue-28134.stderr | 8 +- .../{run-pass => ui}/issues/issue-28181.rs | 0 src/test/ui/issues/issue-28279.rs | 2 +- src/test/ui/issues/issue-28388-3.stderr | 2 +- .../issues/issue-28498-must-work-ex1.rs | 0 .../issues/issue-28498-must-work-ex2.rs | 0 .../issues/issue-28498-ugeh-ex1.rs | 8 +- .../issue-28498-ugeh-with-lifetime-param.rs | 9 +- .../issue-28498-ugeh-with-passed-to-fn.rs | 11 +- .../issue-28498-ugeh-with-trait-bound.rs | 13 +- .../{run-pass => ui}/issues/issue-28550.rs | 0 src/test/ui/issues/issue-28561.rs | 2 +- src/test/ui/issues/issue-28600.rs | 2 +- .../{run-pass => ui}/issues/issue-28676.rs | 0 .../{run-pass => ui}/issues/issue-28777.rs | 0 src/test/ui/issues/issue-28822.rs | 2 +- .../{run-pass => ui}/issues/issue-28828.rs | 0 .../{run-pass => ui}/issues/issue-28839.rs | 0 src/test/ui/issues/issue-28871.rs | 2 +- src/test/ui/issues/issue-28936.rs | 2 +- .../{run-pass => ui}/issues/issue-2895.rs | 0 .../{run-pass => ui}/issues/issue-28950.rs | 0 .../{run-pass => ui}/issues/issue-28983.rs | 0 src/test/ui/issues/issue-28999.rs | 2 +- src/test/ui/issues/issue-29030.rs | 2 +- src/test/ui/issues/issue-29037.rs | 2 +- src/test/ui/issues/issue-2904.rs | 2 +- src/test/ui/issues/issue-29048.rs | 2 +- .../{run-pass => ui}/issues/issue-29053.rs | 0 .../{run-pass => ui}/issues/issue-29071-2.rs | 0 src/test/ui/issues/issue-29071.rs | 2 +- .../{run-pass => ui}/issues/issue-29092.rs | 0 .../issues/issue-29147-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-29166.rs | 0 .../{run-pass => ui}/issues/issue-29227.rs | 0 src/test/ui/issues/issue-29265.rs | 10 + src/test/ui/issues/issue-29276.rs | 2 +- .../{run-pass => ui}/issues/issue-2935.rs | 0 .../{run-pass => ui}/issues/issue-2936.rs | 0 .../{run-pass => ui}/issues/issue-29466.rs | 0 .../{run-pass => ui}/issues/issue-29485.rs | 0 .../{run-pass => ui}/issues/issue-29488.rs | 0 src/test/ui/issues/issue-29516.rs | 2 +- .../{run-pass => ui}/issues/issue-29522.rs | 0 src/test/ui/issues/issue-29540.rs | 2 +- .../{run-pass => ui}/issues/issue-29663.rs | 0 .../{run-pass => ui}/issues/issue-29668.rs | 0 src/test/ui/issues/issue-29710.rs | 2 +- src/test/ui/issues/issue-29740.rs | 2 +- src/test/ui/issues/issue-29743.rs | 2 +- .../{run-pass => ui}/issues/issue-29746.rs | 0 .../{run-pass => ui}/issues/issue-29844.rs | 0 .../{run-pass => ui}/issues/issue-2989.rs | 0 .../{run-pass => ui}/issues/issue-29914-2.rs | 0 .../{run-pass => ui}/issues/issue-29914-3.rs | 0 .../{run-pass => ui}/issues/issue-29914.rs | 0 .../{run-pass => ui}/issues/issue-29927-1.rs | 0 .../{run-pass => ui}/issues/issue-29927.rs | 0 .../{run-pass => ui}/issues/issue-29948.rs | 0 .../issues/issue-30018-nopanic.rs | 0 .../issues/issue-30018-panic.rs | 0 src/test/ui/issues/issue-30079.stderr | 2 +- .../{run-pass => ui}/issues/issue-30081.rs | 0 .../{run-pass => ui}/issues/issue-3012-2.rs | 0 .../issues/issue-30240-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-3026.rs | 0 .../{run-pass => ui}/issues/issue-3037.rs | 0 .../{run-pass => ui}/issues/issue-30371.rs | 0 .../{run-pass => ui}/issues/issue-30490.rs | 0 .../{run-pass => ui}/issues/issue-3052.rs | 0 .../{run-pass => ui}/issues/issue-30530.rs | 0 .../{run-pass => ui}/issues/issue-30615.rs | 0 src/test/ui/issues/issue-30730.stderr | 2 +- .../{run-pass => ui}/issues/issue-30756.rs | 0 .../{run-pass => ui}/issues/issue-30891.rs | 0 .../{run-pass => ui}/issues/issue-3091.rs | 0 .../{run-pass => ui}/issues/issue-3109.rs | 0 .../{run-pass => ui}/issues/issue-3121.rs | 0 src/test/ui/issues/issue-31260.rs | 2 +- .../issues/issue-31267-additional.rs | 0 .../{run-pass => ui}/issues/issue-31267.rs | 0 .../{run-pass => ui}/issues/issue-31299.rs | 0 .../{run-pass => ui}/issues/issue-3136-b.rs | 0 src/test/ui/issues/issue-3149.rs | 2 +- src/test/ui/issues/issue-31597.rs | 2 +- .../{run-pass => ui}/issues/issue-31702.rs | 0 .../{run-pass => ui}/issues/issue-31776.rs | 0 .../{run-pass => ui}/issues/issue-32008.rs | 0 .../{run-pass => ui}/issues/issue-3211.rs | 0 .../{run-pass => ui}/issues/issue-3220.rs | 0 .../{run-pass => ui}/issues/issue-32292.rs | 0 src/test/ui/issues/issue-32323.stderr | 2 +- src/test/ui/issues/issue-32324.rs | 2 +- .../{run-pass => ui}/issues/issue-32389.rs | 0 .../{run-pass => ui}/issues/issue-32518.rs | 0 src/test/ui/issues/issue-32655.rs | 7 +- src/test/ui/issues/issue-32655.stderr | 15 +- src/test/ui/issues/issue-32782.stderr | 2 +- .../{run-pass => ui}/issues/issue-32805.rs | 0 src/test/ui/issues/issue-32829.stderr | 2 +- .../{run-pass => ui}/issues/issue-3290.rs | 0 .../{run-pass => ui}/issues/issue-32947.rs | 0 src/test/ui/issues/issue-32995-2.stderr | 2 +- src/test/ui/issues/issue-32995.stderr | 2 +- .../{run-pass => ui}/issues/issue-33096.rs | 0 .../issues/issue-33140-traitobject-crate.rs | 2 +- .../{run-pass => ui}/issues/issue-33185.rs | 0 .../{run-pass => ui}/issues/issue-33187.rs | 0 .../{run-pass => ui}/issues/issue-33202.rs | 0 src/test/ui/issues/issue-33264.rs | 2 +- src/test/ui/issues/issue-33287.rs | 2 +- src/test/{run-pass => ui}/issues/issue-333.rs | 0 .../{run-pass => ui}/issues/issue-33387.rs | 0 .../{run-pass => ui}/issues/issue-33461.rs | 0 src/test/ui/issues/issue-33464.stderr | 6 +- .../{run-pass => ui}/issues/issue-33498.rs | 0 .../{run-pass => ui}/issues/issue-33537.rs | 0 .../{run-pass => ui}/issues/issue-33687.rs | 0 .../{run-pass => ui}/issues/issue-33770.rs | 0 .../{run-pass => ui}/issues/issue-3389.rs | 0 src/test/ui/issues/issue-33903.rs | 2 +- .../{run-pass => ui}/issues/issue-33992.rs | 0 .../{run-pass => ui}/issues/issue-34053.rs | 0 .../{run-pass => ui}/issues/issue-34074.rs | 0 src/test/ui/issues/issue-34194.rs | 2 +- src/test/ui/issues/issue-3424.rs | 2 +- src/test/ui/issues/issue-34255-1.stderr | 13 +- .../{run-pass => ui}/issues/issue-3429.rs | 0 src/test/ui/issues/issue-34334.rs | 1 + src/test/ui/issues/issue-34334.stderr | 10 +- .../{run-pass => ui}/issues/issue-34427.rs | 0 .../{run-pass => ui}/issues/issue-3447.rs | 0 .../{run-pass => ui}/issues/issue-34503.rs | 0 .../{run-pass => ui}/issues/issue-34569.rs | 0 .../{run-pass => ui}/issues/issue-34571.rs | 0 src/test/ui/issues/issue-34751.rs | 2 +- src/test/ui/issues/issue-34780.rs | 2 +- .../{run-pass => ui}/issues/issue-34784.rs | 0 .../{run-pass => ui}/issues/issue-34796.rs | 0 .../{run-pass => ui}/issues/issue-34798.rs | 0 .../{run-pass => ui}/issues/issue-34932.rs | 0 .../{run-pass => ui}/issues/issue-3500.rs | 0 src/test/ui/issues/issue-35241.stderr | 5 +- src/test/ui/issues/issue-35376.rs | 2 +- .../{run-pass => ui}/issues/issue-35423.rs | 0 src/test/ui/issues/issue-35546.rs | 2 +- .../{run-pass => ui}/issues/issue-3556.rs | 0 .../{run-pass => ui}/issues/issue-3559.rs | 0 .../{run-pass => ui}/issues/issue-35600.rs | 0 src/test/ui/issues/issue-3563-2.rs | 2 +- .../{run-pass => ui}/issues/issue-3563-3.rs | 0 .../{run-pass => ui}/issues/issue-3574.rs | 0 .../{run-pass => ui}/issues/issue-35815.rs | 0 .../{run-pass => ui}/issues/issue-36023.rs | 0 .../issue-36036-associated-type-layout.rs | 0 .../{run-pass => ui}/issues/issue-36053.rs | 0 src/test/ui/issues/issue-36075.rs | 2 +- src/test/ui/issues/issue-3609.rs | 2 +- .../issue-36139-normalize-closure-sig.rs | 0 .../{run-pass => ui}/issues/issue-36260.rs | 0 .../issues/issue-36278-prefix-nesting.rs | 0 .../{run-pass => ui}/issues/issue-36381.rs | 0 .../{run-pass => ui}/issues/issue-36401.rs | 0 .../{run-pass => ui}/issues/issue-36474.rs | 0 .../{run-pass => ui}/issues/issue-3656.rs | 6 +- .../issue-36744-bitcast-args-if-needed.rs | 0 .../ui/issues/issue-36744-without-calls.rs | 2 +- .../{run-pass => ui}/issues/issue-36768.rs | 0 .../issues/issue-36786-resolve-call.rs | 0 .../{run-pass => ui}/issues/issue-36792.rs | 0 .../{run-pass => ui}/issues/issue-36816.rs | 0 .../{run-pass => ui}/issues/issue-3683.rs | 0 .../{run-pass => ui}/issues/issue-36856.rs | 0 src/test/ui/issues/issue-36881.rs | 1 - src/test/ui/issues/issue-36881.stderr | 4 +- .../{run-pass => ui}/issues/issue-36936.rs | 0 .../{run-pass => ui}/issues/issue-36954.rs | 0 src/test/ui/issues/issue-3702-2.stderr | 2 + .../{run-pass => ui}/issues/issue-3702.rs | 0 .../{run-pass => ui}/issues/issue-37109.rs | 0 .../{run-pass => ui}/issues/issue-37175.rs | 0 .../{run-pass => ui}/issues/issue-37222.rs | 0 .../issues/issue-37291/auxiliary/lib.rs | 0 .../issues/issue-37291/main.rs | 0 src/test/ui/issues/issue-37323.rs | 2 +- .../{run-pass => ui}/issues/issue-3743.rs | 0 src/test/ui/issues/issue-37433.rs | 10 + src/test/ui/issues/issue-37433.stderr | 8 + src/test/ui/issues/issue-37515.stderr | 2 +- .../{run-pass => ui}/issues/issue-3753.rs | 0 src/test/ui/issues/issue-37534.rs | 2 +- src/test/ui/issues/issue-37534.stderr | 8 +- src/test/ui/issues/issue-37550.stderr | 2 +- src/test/ui/issues/issue-37598.rs | 5 +- src/test/ui/issues/issue-37655.rs | 2 +- .../{run-pass => ui}/issues/issue-37686.rs | 0 src/test/ui/issues/issue-37725.rs | 2 +- src/test/ui/issues/issue-37733.rs | 2 +- src/test/ui/issues/issue-37887.stderr | 4 +- .../{run-pass => ui}/issues/issue-3794.rs | 0 .../{run-pass => ui}/issues/issue-37991.rs | 0 .../{run-pass => ui}/issues/issue-38002.rs | 0 .../{run-pass => ui}/issues/issue-38033.rs | 0 .../{run-pass => ui}/issues/issue-38074.rs | 0 .../{run-pass => ui}/issues/issue-38091.rs | 0 .../{run-pass => ui}/issues/issue-38190.rs | 0 .../{run-pass => ui}/issues/issue-38226.rs | 0 .../{run-pass => ui}/issues/issue-38437.rs | 0 .../{run-pass => ui}/issues/issue-3847.rs | 0 .../{run-pass => ui}/issues/issue-38556.rs | 0 .../issues/issue-38715-rpass.rs} | 0 src/test/ui/issues/issue-38715.stderr | 2 +- src/test/ui/issues/issue-38727.rs | 2 +- src/test/ui/issues/issue-3874.rs | 2 +- .../{run-pass => ui}/issues/issue-38763.rs | 0 .../{run-pass => ui}/issues/issue-3878.rs | 0 src/test/ui/issues/issue-38875/issue-38875.rs | 2 +- src/test/ui/issues/issue-3888-2.rs | 2 +- .../{run-pass => ui}/issues/issue-38942.rs | 0 .../{run-pass => ui}/issues/issue-3895.rs | 0 .../{run-pass => ui}/issues/issue-38987.rs | 0 .../{run-pass => ui}/issues/issue-3904.rs | 0 src/test/ui/issues/issue-39089.rs | 2 +- .../{run-pass => ui}/issues/issue-39292.rs | 0 .../{run-pass => ui}/issues/issue-3935.rs | 0 .../{run-pass => ui}/issues/issue-39367.rs | 0 src/test/ui/issues/issue-39404.stderr | 2 +- src/test/ui/issues/issue-39467.rs | 2 +- .../{run-pass => ui}/issues/issue-39548.rs | 0 src/test/ui/issues/issue-39559.stderr | 8 +- src/test/ui/issues/issue-39616.stderr | 2 +- .../{run-pass => ui}/issues/issue-39709.rs | 0 .../{run-pass => ui}/issues/issue-39720.rs | 0 .../issues/issue-39720.stderr | 0 src/test/ui/issues/issue-3979-2.rs | 2 +- .../issues/issue-3979-generics.rs | 0 .../issues/issue-3979-xcrate.rs | 0 .../{run-pass => ui}/issues/issue-3979.rs | 0 .../{run-pass => ui}/issues/issue-39808.rs | 0 .../{run-pass => ui}/issues/issue-39823.rs | 0 .../{run-pass => ui}/issues/issue-39827.rs | 0 src/test/ui/issues/issue-39848.stderr | 2 +- src/test/ui/issues/issue-3991.rs | 2 +- src/test/ui/issues/issue-39984.rs | 2 +- .../{run-pass => ui}/issues/issue-40003.rs | 0 .../{run-pass => ui}/issues/issue-40085.rs | 0 src/test/ui/issues/issue-40136.rs | 2 +- .../{run-pass => ui}/issues/issue-40235.rs | 0 src/test/ui/issues/issue-4025.rs | 2 +- .../{run-pass => ui}/issues/issue-40408.rs | 0 .../{run-pass => ui}/issues/issue-40469.rs | 0 src/test/ui/issues/issue-40510-2.rs | 2 +- src/test/ui/issues/issue-40510-4.rs | 2 +- .../{run-pass => ui}/issues/issue-40770.rs | 0 .../{run-pass => ui}/issues/issue-40847.rs | 0 .../{run-pass => ui}/issues/issue-40883.rs | 0 .../{run-pass => ui}/issues/issue-40951.rs | 0 src/test/ui/issues/issue-40962.rs | 2 +- .../{run-pass => ui}/issues/issue-41053.rs | 0 .../{run-pass => ui}/issues/issue-4107.rs | 0 .../{run-pass => ui}/issues/issue-41213.rs | 0 src/test/ui/issues/issue-41272.rs | 2 +- src/test/ui/issues/issue-41298.rs | 2 +- .../issues/issue-41394-rpass.rs} | 0 .../{run-pass => ui}/issues/issue-41479.rs | 0 .../{run-pass => ui}/issues/issue-41498.rs | 0 .../{run-pass => ui}/issues/issue-41604.rs | 0 src/test/ui/issues/issue-41628.rs | 2 +- .../{run-pass => ui}/issues/issue-41677.rs | 0 .../{run-pass => ui}/issues/issue-41696.rs | 0 src/test/ui/issues/issue-41726.rs | 2 +- src/test/ui/issues/issue-41726.stderr | 2 +- .../{run-pass => ui}/issues/issue-41744.rs | 0 .../{run-pass => ui}/issues/issue-41803.rs | 0 .../issues/issue-41849-variance-req.rs | 0 .../{run-pass => ui}/issues/issue-41888.rs | 0 ...sue-41936-variance-coerce-unsized-cycle.rs | 2 +- src/test/ui/issues/issue-41998.rs | 2 +- .../{run-pass => ui}/issues/issue-42007.rs | 0 .../{run-pass => ui}/issues/issue-4208.rs | 0 .../{run-pass => ui}/issues/issue-42148.rs | 0 .../{run-pass => ui}/issues/issue-42210.rs | 0 .../{run-pass => ui}/issues/issue-4228.rs | 0 .../{run-pass => ui}/issues/issue-42453.rs | 0 .../{run-pass => ui}/issues/issue-42463.rs | 0 src/test/ui/issues/issue-42467.rs | 2 +- .../{run-pass => ui}/issues/issue-4252.rs | 0 .../{run-pass => ui}/issues/issue-42552.rs | 0 .../{run-pass => ui}/issues/issue-42679.rs | 0 .../{run-pass => ui}/issues/issue-42747.rs | 0 src/test/ui/issues/issue-42956.rs | 2 +- src/test/ui/issues/issue-43057.rs | 2 +- src/test/ui/issues/issue-43105.stderr | 2 +- .../{run-pass => ui}/issues/issue-43132.rs | 0 src/test/ui/issues/issue-43162.stderr | 2 +- .../{run-pass => ui}/issues/issue-43205.rs | 0 .../{run-pass => ui}/issues/issue-43291.rs | 0 .../{run-pass => ui}/issues/issue-4333.rs | 0 src/test/ui/issues/issue-43357.rs | 2 +- src/test/ui/issues/issue-43398.rs | 15 + src/test/ui/issues/issue-43483.rs | 2 +- src/test/ui/issues/issue-43623.rs | 19 + src/test/ui/issues/issue-43623.stderr | 42 + .../{run-pass => ui}/issues/issue-43692.rs | 0 .../{run-pass => ui}/issues/issue-43853.rs | 0 .../{run-pass => ui}/issues/issue-4387.rs | 0 .../{run-pass => ui}/issues/issue-43910.rs | 0 .../{run-pass => ui}/issues/issue-43923.rs | 0 src/test/ui/issues/issue-44005.rs | 2 +- .../{run-pass => ui}/issues/issue-4401.rs | 0 src/test/ui/issues/issue-44023.stderr | 2 +- src/test/ui/issues/issue-44056.rs | 2 +- src/test/ui/issues/issue-44247.rs | 2 +- .../{run-pass => ui}/issues/issue-44333.rs | 0 src/test/ui/issues/issue-44373-2.rs | 2 +- src/test/ui/issues/issue-44402.rs | 2 +- src/test/ui/issues/issue-44405.rs | 22 + src/test/ui/issues/issue-44405.stderr | 11 + src/test/ui/issues/issue-44406.stderr | 5 +- .../{run-pass => ui}/issues/issue-4446.rs | 0 .../{run-pass => ui}/issues/issue-4448.rs | 0 src/test/ui/issues/issue-4464.rs | 2 +- src/test/ui/issues/issue-44730.rs | 2 +- src/test/ui/issues/issue-44851.rs | 2 +- .../{run-pass => ui}/issues/issue-45124.rs | 0 .../{run-pass => ui}/issues/issue-45152.rs | 0 src/test/ui/issues/issue-45296.stderr | 4 +- .../{run-pass => ui}/issues/issue-4541.rs | 0 .../{run-pass => ui}/issues/issue-4542.rs | 0 src/test/ui/issues/issue-45425.rs | 2 +- .../{run-pass => ui}/issues/issue-4545.rs | 0 .../{run-pass => ui}/issues/issue-45510.rs | 0 src/test/ui/issues/issue-45562.fixed | 2 +- src/test/ui/issues/issue-45562.rs | 2 +- src/test/ui/issues/issue-45562.stderr | 4 +- ...96-scribble-on-boxed-borrow.migrate.stderr | 8 +- ...-45696-scribble-on-boxed-borrow.nll.stderr | 6 +- .../issue-45696-scribble-on-boxed-borrow.rs | 1 + .../{run-pass => ui}/issues/issue-45731.rs | 0 .../{run-pass => ui}/issues/issue-46069.rs | 0 .../{run-pass => ui}/issues/issue-46095.rs | 0 .../{run-pass => ui}/issues/issue-46519.rs | 0 .../{run-pass => ui}/issues/issue-46553.rs | 0 .../{run-pass => ui}/issues/issue-46845.rs | 0 .../{run-pass => ui}/issues/issue-46855.rs | 0 .../issues/issue-46920-byte-array-patterns.rs | 0 src/test/ui/issues/issue-46959.rs | 2 +- src/test/ui/issues/issue-46964.rs | 2 +- src/test/ui/issues/issue-47094.rs | 2 +- .../{run-pass => ui}/issues/issue-47139-1.rs | 0 .../{run-pass => ui}/issues/issue-47139-2.rs | 0 src/test/ui/issues/issue-47309.rs | 2 +- .../{run-pass => ui}/issues/issue-4734.rs | 0 .../{run-pass => ui}/issues/issue-4735.rs | 0 .../{run-pass => ui}/issues/issue-47364.rs | 0 .../{run-pass => ui}/issues/issue-4759-1.rs | 0 .../{run-pass => ui}/issues/issue-4759.rs | 0 .../{run-pass => ui}/issues/issue-47638.rs | 0 src/test/ui/issues/issue-47673.rs | 2 +- src/test/ui/issues/issue-47703-1.rs | 2 +- src/test/ui/issues/issue-47703-tuple.rs | 2 +- src/test/ui/issues/issue-47703.rs | 2 +- src/test/ui/issues/issue-47722.rs | 2 +- src/test/ui/issues/issue-47789.rs | 2 +- .../{run-pass => ui}/issues/issue-48006.rs | 2 + src/test/ui/issues/issue-48131.rs | 1 + src/test/ui/issues/issue-48131.stderr | 4 +- .../{run-pass => ui}/issues/issue-48159.rs | 0 src/test/ui/issues/issue-4830.rs | 2 +- .../issues/issue-48508-aux.rs | 0 .../{run-pass => ui}/issues/issue-48508.rs | 0 src/test/ui/issues/issue-48551.rs | 2 +- .../{run-pass => ui}/issues/issue-4865-1.rs | 0 .../{run-pass => ui}/issues/issue-4865-2.rs | 0 .../{run-pass => ui}/issues/issue-4865-3.rs | 0 .../{run-pass => ui}/issues/issue-4875.rs | 0 .../{run-pass => ui}/issues/issue-48962.rs | 0 .../{run-pass => ui}/issues/issue-48984.rs | 0 src/test/ui/issues/issue-49074.rs | 2 +- src/test/ui/issues/issue-49074.stderr | 6 +- .../{run-pass => ui}/issues/issue-49298.rs | 0 src/test/ui/issues/issue-49544.rs | 9 + src/test/ui/issues/issue-49556.rs | 2 +- src/test/ui/issues/issue-49579.rs | 2 +- ...orthand-field-patterns-in-pattern-macro.rs | 0 .../{run-pass => ui}/issues/issue-49632.rs | 0 .../{run-pass => ui}/issues/issue-49685.rs | 0 .../{run-pass => ui}/issues/issue-49854.rs | 0 src/test/ui/issues/issue-49919.rs | 7 + src/test/ui/issues/issue-49919.stderr | 9 + src/test/ui/issues/issue-49934.rs | 2 +- .../{run-pass => ui}/issues/issue-49955-2.rs | 0 .../{run-pass => ui}/issues/issue-49955.rs | 0 .../{run-pass => ui}/issues/issue-49973.rs | 0 ...e-5008-borrowed-traitobject-method-call.rs | 0 src/test/ui/issues/issue-50187.rs | 2 +- .../option-as_deref.rs | 6 + .../option-as_deref.stderr | 12 + .../option-as_deref_mut.rs | 6 + .../option-as_deref_mut.stderr | 12 + .../option-deref.rs | 6 - .../option-deref.stderr | 12 - .../result-as_deref.rs | 6 + .../result-as_deref.stderr | 12 + .../result-as_deref_err.rs | 6 + .../result-as_deref_err.stderr | 12 + .../result-as_deref_mut.rs | 6 + .../result-as_deref_mut.stderr | 12 + .../result-as_deref_mut_err.rs | 6 + .../result-as_deref_mut_err.stderr | 12 + .../result-as_deref_mut_ok.rs | 6 + .../result-as_deref_mut_ok.stderr | 12 + .../result-as_deref_ok.rs | 6 + .../result-as_deref_ok.stderr | 12 + .../result-deref-err.rs | 6 - .../result-deref-err.stderr | 12 - .../result-deref-ok.rs | 6 - .../result-deref-ok.stderr | 12 - .../result-deref.rs | 6 - .../result-deref.stderr | 12 - src/test/ui/issues/issue-50411.rs | 2 +- .../{run-pass => ui}/issues/issue-50415.rs | 0 .../{run-pass => ui}/issues/issue-50442.rs | 0 src/test/ui/issues/issue-50471.rs | 2 +- src/test/ui/issues/issue-50518.rs | 2 +- .../{run-pass => ui}/issues/issue-5060.rs | 0 .../{run-pass => ui}/issues/issue-50689.rs | 0 .../{run-pass => ui}/issues/issue-50731.rs | 0 src/test/ui/issues/issue-50761.rs | 2 +- .../{run-pass => ui}/issues/issue-50811.rs | 0 .../auxiliary/lib.rs | 0 .../issue-50865-private-impl-trait/main.rs | 0 src/test/ui/issues/issue-50993.rs | 2 +- .../{run-pass => ui}/issues/issue-51185.rs | 0 .../{run-pass => ui}/issues/issue-51345.rs | 0 .../{run-pass => ui}/issues/issue-51582.rs | 0 src/test/ui/issues/issue-51655.rs | 2 +- .../{run-pass => ui}/issues/issue-51907.rs | 0 .../{run-pass => ui}/issues/issue-5192.rs | 0 src/test/ui/issues/issue-51947.rs | 2 +- .../issue-52023-array-size-pointer-cast.rs | 2 +- ...issue-52023-array-size-pointer-cast.stderr | 8 +- .../issue-52140/auxiliary/some_crate.rs | 0 .../issues/issue-52140/main.rs | 0 .../issue-52141/auxiliary/some_crate.rs | 0 .../issues/issue-52141/main.rs | 0 .../{run-pass => ui}/issues/issue-52169.rs | 0 .../{run-pass => ui}/issues/issue-5239-2.rs | 0 .../{run-pass => ui}/issues/issue-5243.rs | 0 src/test/ui/issues/issue-52489.stderr | 2 +- .../{run-pass => ui}/issues/issue-52557.rs | 0 .../issues/issue-52705/auxiliary/png2.rs | 0 .../issues/issue-52705/main.rs | 0 .../{run-pass => ui}/issues/issue-5280.rs | 0 src/test/ui/issues/issue-52992.rs | 2 +- .../{run-pass => ui}/issues/issue-5315.rs | 0 .../issue-5321-immediates-with-bare-self.rs | 0 .../{run-pass => ui}/issues/issue-53333.rs | 0 src/test/ui/issues/issue-53419.rs | 2 +- src/test/ui/issues/issue-5353.rs | 2 +- src/test/ui/issues/issue-53568.rs | 2 +- .../issues/issue-53675-a-test-called-panic.rs | 2 +- .../{run-pass => ui}/issues/issue-53728.rs | 2 + .../issue-53787-inline-assembler-macro.rs | 2 + .../issue-53787-inline-assembler-macro.stderr | 2 +- .../{run-pass => ui}/issues/issue-53843.rs | 2 + src/test/ui/issues/issue-54062.rs | 13 + src/test/ui/issues/issue-54062.stderr | 16 + src/test/ui/issues/issue-54348.stderr | 2 +- src/test/ui/issues/issue-54387.rs | 2 +- ...issue-54462-mutable-noalias-correctness.rs | 1 + .../{run-pass => ui}/issues/issue-54467.rs | 2 + .../issues/issue-54477-reduced-2.rs | 1 + src/test/ui/issues/issue-54521-1.rs | 2 +- .../{run-pass => ui}/issues/issue-54696.rs | 0 src/test/ui/issues/issue-54943-1.rs | 2 +- src/test/ui/issues/issue-54943-2.rs | 2 +- src/test/ui/issues/issue-54943-3.rs | 2 +- src/test/ui/issues/issue-5500-1.rs | 2 +- .../{run-pass => ui}/issues/issue-5518.rs | 0 .../{run-pass => ui}/issues/issue-5521.rs | 0 .../{run-pass => ui}/issues/issue-5530.rs | 0 .../{run-pass => ui}/issues/issue-55376.rs | 1 + .../{run-pass => ui}/issues/issue-55380.rs | 0 .../{run-pass => ui}/issues/issue-5550.rs | 0 src/test/ui/issues/issue-55511.rs | 4 +- src/test/ui/issues/issue-55511.stderr | 14 + .../{run-pass => ui}/issues/issue-5554.rs | 0 src/test/ui/issues/issue-5572.rs | 2 +- src/test/ui/issues/issue-56128.rs | 2 +- src/test/ui/issues/issue-56202.rs | 2 +- .../{run-pass => ui}/issues/issue-56237.rs | 2 + src/test/ui/issues/issue-56411-aux.rs | 2 +- .../{run-pass => ui}/issues/issue-5666.rs | 0 src/test/ui/issues/issue-56762.rs | 2 + src/test/ui/issues/issue-56762.stderr | 15 +- src/test/ui/issues/issue-56806.stderr | 2 +- src/test/ui/issues/issue-56870.rs | 38 + .../{run-pass => ui}/issues/issue-5688.rs | 0 .../{run-pass => ui}/issues/issue-5708.rs | 0 src/test/ui/issues/issue-57156.rs | 2 +- src/test/ui/issues/issue-57162.rs | 2 +- .../{run-pass => ui}/issues/issue-5718.rs | 0 .../{run-pass => ui}/issues/issue-5741.rs | 0 src/test/ui/issues/issue-57410-1.rs | 2 +- src/test/ui/issues/issue-57410.rs | 2 +- src/test/ui/issues/issue-5754.rs | 2 +- .../{run-pass => ui}/issues/issue-5791.rs | 0 .../{run-pass => ui}/issues/issue-58212.rs | 3 + .../issue-58375-monomorphize-default-impls.rs | 24 + .../issue-58435-ice-with-assoc-const.rs | 1 + .../{run-pass => ui}/issues/issue-58463.rs | 0 src/test/ui/issues/issue-5884.rs | 2 +- src/test/ui/issues/issue-58856-2.rs | 2 +- src/test/ui/issues/issue-58856-2.stderr | 4 +- src/test/ui/issues/issue-5900.rs | 2 +- .../{run-pass => ui}/issues/issue-5917.rs | 0 src/test/ui/issues/issue-5950.rs | 2 +- src/test/ui/issues/issue-59508-1.stderr | 12 +- .../{run-pass => ui}/issues/issue-5988.rs | 0 .../{run-pass => ui}/issues/issue-5997.rs | 0 src/test/ui/issues/issue-60622.stderr | 2 +- src/test/ui/issues/issue-60662.rs | 6 +- src/test/ui/issues/issue-60662.stdout | 6 +- .../{run-pass => ui}/issues/issue-6117.rs | 0 .../{run-pass => ui}/issues/issue-6128.rs | 0 .../{run-pass => ui}/issues/issue-6130.rs | 0 .../{run-pass => ui}/issues/issue-6153.rs | 0 .../{run-pass => ui}/issues/issue-6157.rs | 0 src/test/ui/issues/issue-61696.rs | 66 + .../issue-61711-once-caused-rustc-inf-loop.rs | 11 + .../{run-pass => ui}/issues/issue-61894.rs | 6 +- src/test/ui/issues/issue-62375.rs | 9 + src/test/ui/issues/issue-62375.stderr | 13 + src/test/ui/issues/issue-62554.rs | 5 + src/test/ui/issues/issue-62554.stderr | 30 + .../{run-pass => ui}/issues/issue-6318.rs | 0 .../{run-pass => ui}/issues/issue-6334.rs | 0 src/test/ui/issues/issue-63364.rs | 10 + src/test/ui/issues/issue-63364.stderr | 10 + src/test/ui/issues/issue-6341.rs | 2 +- .../{run-pass => ui}/issues/issue-6344-let.rs | 0 .../issues/issue-6344-match.rs | 0 .../{run-pass => ui}/issues/issue-6449.rs | 0 src/test/ui/issues/issue-6458-4.stderr | 2 +- src/test/ui/issues/issue-6470.rs | 2 +- src/test/ui/issues/issue-6557.rs | 2 +- .../{run-pass => ui}/issues/issue-6892.rs | 0 src/test/ui/issues/issue-6898.rs | 2 +- .../{run-pass => ui}/issues/issue-6919.rs | 0 src/test/ui/issues/issue-6991.rs | 2 +- .../{run-pass => ui}/issues/issue-7012.rs | 0 .../{run-pass => ui}/issues/issue-7178.rs | 0 .../{run-pass => ui}/issues/issue-7222.rs | 0 src/test/ui/issues/issue-7268.rs | 2 +- .../{run-pass => ui}/issues/issue-7344.rs | 0 .../issues/issue-7519-match-unit-in-arg.rs | 0 .../{run-pass => ui}/issues/issue-7563.rs | 0 .../{run-pass => ui}/issues/issue-7575.rs | 0 src/test/ui/issues/issue-7607-2.rs | 2 +- .../{run-pass => ui}/issues/issue-7660.rs | 0 .../{run-pass => ui}/issues/issue-7663.rs | 0 ...7673-cast-generically-implemented-trait.rs | 2 +- .../{run-pass => ui}/issues/issue-7784.rs | 2 +- .../{run-pass => ui}/issues/issue-7899.rs | 0 .../{run-pass => ui}/issues/issue-7911.rs | 0 .../{run-pass => ui}/issues/issue-8044.rs | 0 ...fault-method-self-inherit-builtin-trait.rs | 2 +- .../{run-pass => ui}/issues/issue-8248.rs | 0 .../{run-pass => ui}/issues/issue-8249.rs | 0 .../{run-pass => ui}/issues/issue-8259.rs | 0 .../{run-pass => ui}/issues/issue-8351-1.rs | 0 .../{run-pass => ui}/issues/issue-8351-2.rs | 0 .../{run-pass => ui}/issues/issue-8391.rs | 0 src/test/ui/issues/issue-8398.rs | 2 +- .../{run-pass => ui}/issues/issue-8401.rs | 0 .../{run-pass => ui}/issues/issue-8460.rs | 0 .../{run-pass => ui}/issues/issue-8498.rs | 0 .../{run-pass => ui}/issues/issue-8506.rs | 0 src/test/ui/issues/issue-8521.rs | 2 +- src/test/ui/issues/issue-8578.rs | 2 +- src/test/{run-pass => ui}/issues/issue-868.rs | 0 .../{run-pass => ui}/issues/issue-8709.rs | 0 src/test/ui/issues/issue-8727.stderr | 2 +- .../{run-pass => ui}/issues/issue-8783.rs | 0 .../{run-pass => ui}/issues/issue-8827.rs | 0 .../{run-pass => ui}/issues/issue-8851.rs | 0 .../{run-pass => ui}/issues/issue-8860.rs | 0 .../{run-pass => ui}/issues/issue-8898.rs | 0 .../{run-pass => ui}/issues/issue-9047.rs | 0 src/test/ui/issues/issue-9110.rs | 2 +- .../{run-pass => ui}/issues/issue-9123.rs | 0 .../{run-pass => ui}/issues/issue-9129.rs | 0 .../{run-pass => ui}/issues/issue-9155.rs | 0 .../{run-pass => ui}/issues/issue-9188.rs | 0 src/test/ui/issues/issue-9243.rs | 2 +- src/test/ui/issues/issue-9249.rs | 2 +- .../{run-pass => ui}/issues/issue-9259.rs | 0 .../{run-pass => ui}/issues/issue-9382.rs | 0 .../issue-9394-inherited-trait-calls.rs | 0 .../{run-pass => ui}/issues/issue-9396.rs | 0 .../{run-pass => ui}/issues/issue-9446.rs | 0 src/test/ui/issues/issue-9719.rs | 2 +- .../{run-pass => ui}/issues/issue-9737.rs | 0 src/test/{run-pass => ui}/issues/issue-979.rs | 0 .../{run-pass => ui}/issues/issue-9837.rs | 0 .../{run-pass => ui}/issues/issue-9906.rs | 0 .../{run-pass => ui}/issues/issue-9918.rs | 0 .../{run-pass => ui}/issues/issue-9942.rs | 0 .../{run-pass => ui}/issues/issue-9951.rs | 0 .../{run-pass => ui}/issues/issue-9968.rs | 0 src/test/{run-pass => ui}/istr.rs | 2 + .../{run-pass => ui}/item-name-overload.rs | 2 + .../into-iterator-type-inference-shift.rs | 0 .../iterators/iter-cloned-type-inference.rs | 0 .../{run-pass => ui}/iterators/iter-range.rs | 0 .../iterators/iter-step-overflow-debug.rs | 0 .../iterators/iter-step-overflow-ndebug.rs | 0 .../iterators/iter-sum-overflow-debug.rs | 0 .../iterators/iter-sum-overflow-ndebug.rs | 0 .../iter-sum-overflow-overflow-checks.rs | 0 .../{run-pass => ui}/iterators/iter-zip.rs | 0 src/test/ui/json-and-color.rs | 4 + src/test/ui/json-and-color.stderr | 2 + src/test/ui/json-and-error-format.rs | 4 + src/test/ui/json-and-error-format.stderr | 2 + src/test/ui/json-invalid.rs | 4 + src/test/ui/json-invalid.stderr | 2 + src/test/ui/json-multiple.nll.stderr | 1 + src/test/ui/json-multiple.rs | 5 + src/test/ui/json-multiple.stderr | 1 + src/test/ui/json-options.nll.stderr | 1 + src/test/ui/json-options.rs | 5 + src/test/ui/json-options.stderr | 1 + src/test/ui/json-short.rs | 2 + src/test/ui/json-short.stderr | 19 + .../keyword-changes-2012-07-31.rs | 2 + .../kindck-implicit-close-over-mut-var.rs | 2 + .../{run-pass => ui}/kinds-in-metadata.rs | 1 + .../label_break_value_illegal_uses.stderr | 4 +- .../lambda-infer-unresolved.rs | 2 + .../{run-pass => ui}/lambda-var-hygiene.rs | 1 + src/test/{run-pass => ui}/large-records.rs | 2 + .../{run-pass => ui}/last-use-in-block.rs | 2 + .../last-use-in-cap-clause.rs | 2 + .../{run-pass => ui}/last-use-is-capture.rs | 2 + ...ue-60431-unsized-tail-behind-projection.rs | 35 + src/test/{run-pass => ui}/lazy-and-or.rs | 2 + src/test/{run-pass => ui}/lazy-init.rs | 2 + .../{run-pass => ui}/leak-unique-as-tydesc.rs | 1 + .../lex-bare-cr-nondoc-comment.rs | 1 + ...line-endings-string-literal-doc-comment.rs | 1 + src/test/{run-pass => ui}/lexical-scoping.rs | 1 + src/test/{run-pass => ui}/lib-defaults.rs | 1 + .../ui/lifetime_starts_expressions.stderr | 13 +- src/test/{run-pass => ui}/link-cfg-works.rs | 1 + src/test/{run-pass => ui}/link-section.rs | 2 + src/test/ui/linkage-attr/linkage4.stderr | 2 +- src/test/{run-pass => ui}/linkage1.rs | 1 + src/test/{run-pass => ui}/lint-cap.rs | 1 + .../lint-dead-code-associated-type.rs | 2 + .../lint-dead-code-variant.rs | 2 + .../lint-expr-stmt-attrs-for-early-lints.rs | 2 + .../lint-unknown-lints-at-crate-level.rs | 1 + .../ui/lint/command-line-lint-group-allow.rs | 2 +- .../ui/lint/command-line-lint-group-warn.rs | 2 +- .../ui/lint/deny-overflowing-literals.stderr | 2 +- .../lint/inclusive-range-pattern-syntax.fixed | 2 +- .../ui/lint/inclusive-range-pattern-syntax.rs | 2 +- ...47390-unused-variable-in-struct-pattern.rs | 2 +- ...0-unused-variable-in-struct-pattern.stderr | 6 +- ...775-nested-macro-unnecessary-parens-arg.rs | 2 +- ...issue-54099-camel-case-underscore-types.rs | 2 +- .../lint/issue-54180-unused-ref-field.stderr | 2 +- .../ui/lint/issue-54538-unused-parens-lint.rs | 2 +- src/test/ui/lint/lint-change-warnings.stderr | 6 +- .../lint/lint-group-nonstandard-style.stderr | 10 +- src/test/ui/lint/lint-impl-fn.stderr | 16 +- .../lint-incoherent-auto-trait-objects.stderr | 2 +- ...t-lowercase-static-const-pattern-rename.rs | 2 +- src/test/ui/lint/lint-misplaced-attr.stderr | 2 +- .../ui/lint/lint-non-camel-case-variant.rs | 2 +- ...on-camel-case-with-trailing-underscores.rs | 2 +- ...-non-snake-case-no-lowercase-equivalent.rs | 2 +- .../ui/lint/lint-nonstandard-style-unicode.rs | 2 +- src/test/ui/lint/lint-output-format-2.rs | 2 +- src/test/ui/lint/lint-output-format-2.stderr | 2 +- src/test/ui/lint/lint-output-format.stderr | 6 +- src/test/ui/lint/lint-qualification.rs | 1 + src/test/ui/lint/lint-qualification.stderr | 2 +- src/test/ui/lint/lint-removed-cmdline.stderr | 2 +- src/test/ui/lint/lint-removed.stderr | 2 +- src/test/ui/lint/lint-renamed-allow.stderr | 2 +- src/test/ui/lint/lint-renamed-cmdline.stderr | 2 +- src/test/ui/lint/lint-renamed.stderr | 4 +- src/test/ui/lint/lint-stability-2.stderr | 64 +- src/test/ui/lint/lint-stability-deprecated.rs | 3 +- .../ui/lint/lint-stability-deprecated.stderr | 210 +- src/test/ui/lint/lint-stability-fields.stderr | 86 +- src/test/ui/lint/lint-stability.stderr | 82 +- src/test/ui/lint/lint-unexported-no-mangle.rs | 4 +- .../ui/lint/lint-unexported-no-mangle.stderr | 8 +- .../ui/lint/lint-unknown-feature-default.rs | 2 +- src/test/ui/lint/lint-unknown-feature.rs | 2 +- src/test/ui/lint/lint-unnecessary-parens.rs | 1 + .../ui/lint/lint-unnecessary-parens.stderr | 22 +- src/test/ui/lint/lint-unused-mut-variables.rs | 64 +- .../ui/lint/lint-unused-mut-variables.stderr | 112 +- src/test/ui/lint/lint-unused-variables.rs | 64 + src/test/ui/lint/lint-unused-variables.stderr | 56 + .../ui/lint/lint-uppercase-variables.stderr | 2 +- src/test/ui/lint/lints-in-foreign-macros.rs | 2 +- src/test/ui/lint/must-use-ops.rs | 2 +- src/test/ui/lint/not_found.rs | 2 +- src/test/ui/lint/not_found.stderr | 2 +- src/test/ui/lint/reasons-erroneous.rs | 2 +- src/test/ui/lint/reasons-erroneous.stderr | 2 +- src/test/ui/lint/reasons.rs | 2 +- src/test/ui/lint/reasons.stderr | 2 +- .../lint-non-ascii-idents.rs | 11 + .../lint-non-ascii-idents.stderr | 32 + src/test/ui/lint/suggestions.rs | 6 +- src/test/ui/lint/suggestions.stderr | 30 +- src/test/ui/lint/type-overflow.rs | 2 +- src/test/ui/lint/uninitialized-zeroed.rs | 66 + src/test/ui/lint/uninitialized-zeroed.stderr | 289 + src/test/ui/lint/unreachable_pub-pub_crate.rs | 2 +- src/test/ui/lint/unreachable_pub.rs | 2 +- .../lint/unused_import_warning_issue_45268.rs | 2 +- src/test/ui/lint/unused_labels.rs | 2 +- .../lint/unused_parens_json_suggestion.fixed | 27 + .../ui/lint/unused_parens_json_suggestion.rs | 4 +- .../lint/unused_parens_json_suggestion.stderr | 28 +- ...unused_parens_remove_json_suggestion.fixed | 62 + .../unused_parens_remove_json_suggestion.rs | 62 + ...nused_parens_remove_json_suggestion.stderr | 666 ++ src/test/ui/lint/use-redundant.rs | 2 +- src/test/ui/lint/use_suggestion_json.rs | 2 +- src/test/ui/lint/use_suggestion_json.stderr | 52 +- src/test/{run-pass => ui}/list.rs | 2 + .../liveness-assign-imm-local-after-ret.rs | 2 + .../ui/liveness/liveness-forgot-ret.stderr | 2 +- .../ui/liveness/liveness-missing-ret2.stderr | 2 +- .../ui/liveness/liveness-move-in-while.rs | 3 + .../ui/liveness/liveness-move-in-while.stderr | 20 + .../liveness-return-last-stmt-semi.stderr | 8 +- src/test/ui/liveness/liveness-unused.stderr | 2 +- src/test/{run-pass => ui}/llvm-pr32379.rs | 1 + src/test/{run-pass => ui}/log-err-phi.rs | 2 + .../log-knows-the-names-of-variants-in-std.rs | 2 + .../log-knows-the-names-of-variants.rs | 2 + src/test/{run-pass => ui}/log-poly.rs | 2 + .../logging-only-prints-once.rs | 1 + .../logging_before_rt_started.rs | 1 + src/test/{run-pass => ui}/long-while.rs | 1 + src/test/ui/loops/loop-break-unsize.rs | 8 + src/test/ui/loops/loop-break-value.rs | 2 +- src/test/ui/loops/loop-break-value.stderr | 23 +- .../ui/loops/loop-labeled-break-value.stderr | 27 +- .../ui/loops/loop-properly-diverging-2.stderr | 9 +- .../loops/loops-reject-duplicate-labels-2.rs | 2 +- .../ui/loops/loops-reject-duplicate-labels.rs | 2 +- ...loops-reject-labels-shadowing-lifetimes.rs | 2 +- .../loops-reject-lifetime-shadowing-label.rs | 2 +- .../lto-many-codegen-units.rs | 1 + .../lto-still-runs-thread-dtors.rs | 1 + .../lub-glb-with-unbound-infer-var.rs | 1 + src/test/{run-pass => ui}/macro-quote-cond.rs | 2 + src/test/{run-pass => ui}/macro-quote-test.rs | 1 + src/test/ui/macro_backtrace/main.stderr | 40 +- .../macros/assert-eq-macro-success.rs | 0 .../macros/assert-eq-macro-unsized.rs | 0 .../macros/assert-ne-macro-success.rs | 0 .../macros/assert-ne-macro-unsized.rs | 0 .../ui/macros/auxiliary/deprecated-macros.rs | 3 + .../auxiliary/dollar-crate-nested-encoding.rs | 10 + .../macros/auxiliary/macro-comma-support.rs | 0 .../auxiliary/macro-include-items-expr.rs | 0 .../auxiliary/macro-include-items-item.rs | 0 .../macros/auxiliary/macro_crate_def_only.rs | 0 .../auxiliary/macro_export_inner_module.rs | 0 .../macros/auxiliary/macro_with_super_1.rs | 0 .../macros/auxiliary/proc_macro_sequence.rs | 36 + .../macros/auxiliary/two_macros-rpass.rs} | 0 .../ui/macros/auxiliary/unstable-macros.rs | 10 + .../macros/auxiliary/use-macro-self.rs | 0 .../ui/macros/builtin-prelude-no-accidents.rs | 8 + .../builtin-prelude-no-accidents.stderr | 21 + src/test/ui/macros/builtin-std-paths-fail.rs | 21 + .../ui/macros/builtin-std-paths-fail.stderr | 75 + src/test/ui/macros/builtin-std-paths.rs | 32 + .../macros/colorful-write-macros.rs | 0 .../macros/conditional-debug-macro-on.rs | 0 .../macros/derive-in-eager-expansion-hang.rs | 14 + .../derive-in-eager-expansion-hang.stderr | 20 + src/test/{run-pass => ui}/macros/die-macro.rs | 0 .../ui/macros/dollar-crate-nested-encoding.rs | 8 + src/test/ui/macros/format-parse-errors.rs | 10 +- src/test/ui/macros/format-parse-errors.stderr | 26 +- .../{run-pass => ui}/macros/issue-25274.rs | 2 + .../ui/macros/issue-61053-different-kleene.rs | 30 + .../issue-61053-different-kleene.stderr | 45 + .../ui/macros/issue-61053-duplicate-binder.rs | 14 + .../issue-61053-duplicate-binder.stderr | 16 + .../macros/issue-61053-missing-repetition.rs | 28 + .../issue-61053-missing-repetition.stderr | 33 + src/test/ui/macros/issue-61053-unbound.rs | 28 + src/test/ui/macros/issue-61053-unbound.stderr | 26 + src/test/ui/macros/issue-63102.rs | 8 + ...log_syntax-trace_macros-macro-locations.rs | 0 ...syntax-trace_macros-macro-locations.stdout | 0 src/test/{run-pass => ui}/macros/macro-2.rs | 0 .../macros/macro-as-fn-body.rs | 0 .../macro-at-most-once-rep-2015-rpass.rs} | 0 .../macro-at-most-once-rep-2018-rpass.rs} | 0 .../macros/macro-attribute-expansion.rs | 0 .../macros/macro-attributes.rs | 0 .../macros/macro-block-nonterminal.rs | 0 .../macros/macro-comma-behavior-rpass.rs} | 0 .../macros/macro-comma-support-rpass.rs} | 1 + .../macros/macro-crate-def-only.rs | 0 .../macros/macro-crate-nonterminal-renamed.rs | 0 .../macros/macro-crate-nonterminal.rs | 0 .../macros/macro-crate-use.rs | 0 .../macros/macro-deep_expansion.rs | 0 .../macros/macro-delimiter-significance.rs | 0 src/test/ui/macros/macro-deprecation.rs | 13 + src/test/ui/macros/macro-deprecation.stderr | 14 + .../macros/macro-doc-comments.rs | 0 .../macros/macro-doc-escapes.rs | 0 .../macros/macro-doc-raw-str-hashes.rs | 0 src/test/ui/macros/macro-error.stderr | 2 +- .../ui/macros/macro-expanded-include/test.rs | 2 +- .../macros/macro-export-inner-module.rs | 0 .../macros/macro-first-set.rs | 2 +- .../macros/macro-follow-rpass.rs} | 0 src/test/ui/macros/macro-follow.stderr | 44 +- .../macros/macro-followed-by-seq.rs | 0 .../macros/macro-include-items.rs | 0 .../macros/macro-interpolation.rs | 0 ...vocation-in-count-expr-fixed-array-type.rs | 0 .../macros/macro-lifetime-used-with-bound.rs | 0 .../macros/macro-lifetime-used-with-labels.rs | 0 .../macro-lifetime-used-with-labels.stderr | 0 .../macros/macro-lifetime-used-with-static.rs | 0 .../{run-pass => ui}/macros/macro-lifetime.rs | 0 .../{run-pass => ui}/macros/macro-literal.rs | 0 .../macros/macro-meta-items.rs | 0 .../macros/macro-method-issue-4621.rs | 0 .../macros/macro-multiple-items.rs | 0 src/test/ui/macros/macro-name-typo.stderr | 2 +- .../macros/macro-named-default.rs | 0 .../macro-nested_definition_issue-31946.rs | 0 .../macros/macro-nested_expr.rs | 0 .../macros/macro-nested_stmt_macros.rs | 0 .../{run-pass => ui}/macros/macro-nt-list.rs | 0 .../macros/macro-of-higher-order.rs | 0 .../macros/macro-pat-follow.rs | 0 .../macros/macro-pat-neg-lit.rs | 0 src/test/{run-pass => ui}/macros/macro-pat.rs | 0 .../macros/macro-path-prelude-fail-3.stderr | 2 +- .../ui/macros/macro-path-prelude-fail-4.rs | 2 +- .../macros/macro-path-prelude-fail-4.stderr | 4 +- src/test/ui/macros/macro-path-prelude-pass.rs | 2 +- .../ui/macros/macro-path-prelude-pass.stderr | 2 +- .../macro-path-prelude-shadowing.stderr | 2 +- .../{run-pass => ui}/macros/macro-path.rs | 0 .../macros/macro-pub-matcher.rs | 0 src/test/ui/macros/macro-reexport-removed.rs | 2 +- .../ui/macros/macro-reexport-removed.stderr | 8 +- .../macros/macro-seq-followed-by-seq.rs | 0 src/test/ui/macros/macro-shadowing-relaxed.rs | 2 +- .../macros/macro-stability-rpass.rs} | 2 +- src/test/ui/macros/macro-stability.rs | 20 +- src/test/ui/macros/macro-stability.stderr | 40 +- src/test/ui/macros/macro-stmt-matchers.rs | 2 +- .../{run-pass => ui}/macros/macro-stmt.rs | 0 .../macros/macro-stmt_macro_in_expr_macro.rs | 0 .../macros/macro-tt-followed-by-seq.rs | 0 src/test/ui/macros/macro-tt-matchers.rs | 2 +- .../macros/macro-use-all-and-none.rs | 6 +- .../ui/macros/macro-use-all-and-none.stderr | 12 + .../{run-pass => ui}/macros/macro-use-all.rs | 0 src/test/ui/macros/macro-use-bad-args-1.rs | 1 - .../ui/macros/macro-use-bad-args-1.stderr | 2 +- src/test/ui/macros/macro-use-bad-args-2.rs | 1 - .../ui/macros/macro-use-bad-args-2.stderr | 2 +- .../{run-pass => ui}/macros/macro-use-both.rs | 0 .../{run-pass => ui}/macros/macro-use-one.rs | 0 src/test/ui/macros/macro-use-scope.rs | 2 +- .../ui/macros/macro-use-wrong-name.stderr | 2 +- .../macros/macro-with-attrs1.rs | 0 .../macros/macro-with-attrs2.rs | 0 .../macro-with-braces-in-expr-position.rs | 0 src/test/ui/macros/macro_undefined.stderr | 2 +- .../macros/macro_with_super_2.rs | 0 .../macros/macros-in-extern-rpass.rs} | 0 src/test/ui/macros/macros-in-extern.stderr | 6 +- .../ui/macros/meta-item-absolute-path.stderr | 4 +- src/test/ui/macros/meta-variable-misuse.rs | 34 + src/test/ui/macros/missing-comma.stderr | 2 +- src/test/ui/macros/must-use-in-macro-55516.rs | 2 +- .../macros/parse-complex-macro-invoc-op.rs | 0 .../macros/paths-in-macro-invocations.rs | 4 +- .../macros/pub-item-inside-macro.rs | 0 .../macros/pub-method-inside-macro.rs | 0 .../ui/macros/restricted-shadowing-modern.rs | 24 +- src/test/ui/macros/same-sequence-span.rs | 23 + src/test/ui/macros/same-sequence-span.stderr | 34 + .../macros/semi-after-macro-ty.rs | 0 .../macros/stmt_expr_attr_macro_parse.rs | 0 .../macros/syntax-extension-cfg.rs | 0 .../includeme.fragment | 0 .../macros/syntax-extension-source-utils.rs | 4 +- src/test/ui/macros/trace-macro.rs | 2 +- src/test/ui/macros/trace-macro.stderr | 2 +- src/test/ui/macros/trace_faulty_macros.stderr | 12 +- src/test/{run-pass => ui}/macros/try-macro.rs | 1 + .../{run-pass => ui}/macros/two-macro-use.rs | 0 .../macros/type-macros-hlist.rs | 0 .../macros/type-macros-simple.rs | 0 .../typeck-macro-interaction-issue-8852.rs | 0 src/test/ui/macros/unknown-builtin.rs | 14 + src/test/ui/macros/unknown-builtin.stderr | 14 + .../{run-pass => ui}/macros/use-macro-self.rs | 0 .../ui/malformed/malformed-regressions.rs | 2 +- .../ui/malformed/malformed-regressions.stderr | 2 +- src/test/ui/match/issue-50900.rs | 19 + src/test/ui/match/issue-50900.stderr | 14 + .../ui/match/match-arm-resolving-to-never.rs | 19 + .../match/match-arm-resolving-to-never.stderr | 22 + src/test/ui/match/match-non-exhaustive.stderr | 4 +- .../ui/match/match-range-fail-dominate.stderr | 2 +- src/test/ui/match/match-ref-mut-stability.rs | 2 +- src/test/ui/match/match-vec-mismatch.rs | 4 +- src/test/ui/match/match-vec-mismatch.stderr | 4 +- src/test/ui/match/match-vec-unreachable.rs | 2 +- src/test/{run-pass => ui}/max-min-classes.rs | 2 + src/test/ui/maybe-bounds-where-cpass.rs | 2 +- .../methods/auxiliary/method_self_arg1.rs | 0 .../methods/auxiliary/method_self_arg2.rs | 0 ...method-ambig-two-traits-cross-crate.stderr | 2 + .../method-ambig-two-traits-from-impls.rs | 16 + .../method-ambig-two-traits-from-impls.stderr | 22 + .../method-ambig-two-traits-from-impls2.rs | 16 + ...method-ambig-two-traits-from-impls2.stderr | 22 + ...mbig-two-traits-with-default-method.stderr | 2 + ...thod-argument-inference-associated-type.rs | 0 .../method-call-lifetime-args-subst-index.rs | 2 +- ...e-trait-object-with-separate-params.stderr | 2 + .../method-early-bound-lifetimes-on-self.rs | 0 ...thod-mut-self-modifies-mut-slice-lvalue.rs | 0 .../method-normalize-bounds-issue-20604.rs | 0 .../method-probe-no-guessing-dyn-trait.rs | 1 + .../methods/method-projection.rs | 0 .../methods/method-recursive-blanket-impl.rs | 0 .../methods/method-self-arg-aux1.rs | 0 .../methods/method-self-arg-aux2.rs | 0 .../methods/method-self-arg-trait.rs | 0 .../methods/method-self-arg.rs | 0 .../methods/method-trait-object-with-hrtb.rs | 2 +- .../method-two-trait-defer-resolution-1.rs | 0 .../method-two-trait-defer-resolution-2.rs | 0 ...o-traits-distinguished-via-where-clause.rs | 0 .../methods/method-where-clause.rs | 0 .../{run-pass => ui}/mid-path-type-params.rs | 2 + .../minmax-stability-issue-23687.rs | 2 + .../mir/auxiliary/mir_external_refs.rs | 0 .../mir/mir-inlining/ice-issue-45493.rs | 0 .../mir/mir-inlining/ice-issue-45885.rs | 0 .../no-trait-method-issue-40473.rs | 0 .../mir/mir-typeck-normalize-fn-sig.rs | 0 .../mir/mir_adt_construction.rs | 0 .../mir/mir_ascription_coercion.rs | 0 .../mir/mir_augmented_assignments.rs | 0 .../{run-pass => ui}/mir/mir_autoderef.rs | 0 src/test/{run-pass => ui}/mir/mir_boxing.rs | 0 .../mir/mir_build_match_comparisons.rs | 0 .../mir/mir_call_with_associated_type.rs | 0 .../mir/mir_calls_to_shims.rs | 0 .../{run-pass => ui}/mir/mir_cast_fn_ret.rs | 0 .../{run-pass => ui}/mir/mir_codegen_array.rs | 0 .../mir/mir_codegen_array_2.rs | 0 .../mir/mir_codegen_call_converging.rs | 0 .../{run-pass => ui}/mir/mir_codegen_calls.rs | 0 .../mir/mir_codegen_calls_variadic.rs | 0 .../mir/mir_codegen_critical_edge.rs | 0 .../mir/mir_codegen_spike1.rs | 0 .../mir/mir_codegen_switch.rs | 0 .../mir/mir_codegen_switchint.rs | 0 .../mir/mir_coercion_casts.rs | 0 .../{run-pass => ui}/mir/mir_coercions.rs | 0 .../{run-pass => ui}/mir/mir_constval_adts.rs | 0 .../{run-pass => ui}/mir/mir_drop_order.rs | 0 .../mir/mir_early_return_scope.rs | 0 src/test/{run-pass => ui}/mir/mir_fat_ptr.rs | 0 .../{run-pass => ui}/mir/mir_fat_ptr_drop.rs | 0 .../mir/mir_heavy_promoted.rs | 0 .../mir/mir_match_arm_guard.rs | 0 .../{run-pass => ui}/mir/mir_match_test.rs | 0 .../{run-pass => ui}/mir/mir_misc_casts.rs | 0 .../{run-pass => ui}/mir/mir_overflow_off.rs | 0 .../{run-pass => ui}/mir/mir_raw_fat_ptr.rs | 0 .../{run-pass => ui}/mir/mir_refs_correct.rs | 0 .../{run-pass => ui}/mir/mir_small_agg_arg.rs | 0 .../mir/mir_static_subtype.rs | 1 + .../mir/mir_struct_with_assoc_ty.rs | 0 .../mir/mir_temp_promotions.rs | 0 .../{run-pass => ui}/mir/mir_void_return.rs | 0 .../{run-pass => ui}/mir/mir_void_return_2.rs | 0 .../ui/mismatched_types/issue-38371.stderr | 6 +- src/test/ui/missing/missing-allocator.stderr | 2 +- src/test/ui/missing/missing-return.stderr | 2 +- .../ui/missing/missing-semicolon-warning.rs | 2 +- src/test/ui/missing_debug_impls.stderr | 4 +- .../modules/auxiliary/two_macros_2.rs | 0 .../{run-pass => ui}/modules/mod-inside-fn.rs | 0 .../modules/mod-view-items.rs | 0 .../modules/mod_dir_implicit.rs | 0 .../compiletest-ignore-dir | 0 .../modules/mod_dir_implicit_aux/mod.rs | 0 .../{run-pass => ui}/modules/mod_dir_path.rs | 0 .../{run-pass => ui}/modules/mod_dir_path2.rs | 0 .../{run-pass => ui}/modules/mod_dir_path3.rs | 0 .../modules/mod_dir_path_multi.rs | 0 .../modules/mod_dir_recursive.rs | 0 .../modules/mod_dir_simple.rs | 0 .../mod_dir_simple/compiletest-ignore-dir | 0 .../mod_dir_simple/load_another_mod.rs | 0 .../modules/mod_dir_simple/test.rs | 0 src/test/{run-pass => ui}/modules/mod_file.rs | 0 .../{run-pass => ui}/modules/mod_file_aux.rs | 0 .../modules/mod_file_with_path_attr.rs | 0 .../compiletest-ignore-dir | 0 .../float-template/inst_f32.rs | 2 + .../float-template/inst_f64.rs | 2 + .../float-template/inst_float.rs | 2 + src/test/{run-pass => ui}/monad.rs | 2 + .../monomorphize-abi-alignment.rs | 2 + ...nomorphized-callees-with-ty-params-3314.rs | 1 + .../{run-pass => ui}/moves/move-1-unique.rs | 0 .../{run-pass => ui}/moves/move-2-unique.rs | 0 src/test/{run-pass => ui}/moves/move-2.rs | 0 .../{run-pass => ui}/moves/move-3-unique.rs | 0 .../{run-pass => ui}/moves/move-4-unique.rs | 0 src/test/{run-pass => ui}/moves/move-4.rs | 0 .../moves/move-arg-2-unique.rs | 0 src/test/{run-pass => ui}/moves/move-arg-2.rs | 0 src/test/{run-pass => ui}/moves/move-arg.rs | 0 .../{run-pass => ui}/moves/move-nullary-fn.rs | 0 .../moves/move-out-of-field.rs | 0 .../{run-pass => ui}/moves/move-scalar.rs | 0 .../moves-based-on-type-capture-clause.rs | 0 src/test/{run-pass => ui}/mpsc_stress.rs | 1 + src/test/{run-pass => ui}/msvc-data-only.rs | 1 + src/test/{run-pass => ui}/multi-panic.rs | 1 + src/test/{run-pass => ui}/multibyte.rs | 1 + ...ispatch-conditional-impl-not-considered.rs | 1 + src/test/{run-pass => ui}/multidispatch1.rs | 2 + src/test/{run-pass => ui}/multidispatch2.rs | 2 + .../{run-pass => ui}/multiline-comment.rs | 1 + src/test/ui/multiple-main-2.rs | 2 +- src/test/ui/multiple-main-2.stderr | 6 +- src/test/ui/multiple-main-3.rs | 2 +- src/test/ui/multiple-main-3.stderr | 6 +- src/test/{run-pass => ui}/multiple-reprs.rs | 2 + .../mut-function-arguments.rs | 2 + src/test/{run-pass => ui}/mut-vstore-expr.rs | 1 + .../mutual-recursion-group.rs | 2 + .../native-print-no-runtime.rs | 2 + src/test/{run-pass => ui}/negative.rs | 2 + .../{run-pass => ui}/nested-block-comment.rs | 1 + src/test/{run-pass => ui}/nested-class.rs | 2 + .../nested-function-names-issue-8587.rs | 1 + src/test/{run-pass => ui}/nested_item_main.rs | 1 + src/test/ui/never-assign-dead-code.rs | 2 +- src/test/ui/never-assign-dead-code.stderr | 4 +- src/test/{run-pass => ui}/never-result.rs | 2 + .../{run-pass => ui}/never-type-rvalues.rs | 2 + src/test/{run-pass => ui}/never_coercions.rs | 1 + src/test/ui/never_transmute_never.rs | 2 +- src/test/{run-pass => ui}/new-box-syntax.rs | 1 + src/test/{run-pass => ui}/new-box.rs | 2 + src/test/{run-pass => ui}/new-impl-syntax.rs | 2 + .../{run-pass => ui}/new-import-syntax.rs | 2 + .../{run-pass => ui}/new-style-constants.rs | 2 + .../{run-pass => ui}/new-unicode-escapes.rs | 2 + .../{run-pass => ui}/new-unsafe-pointers.rs | 1 + .../{run-pass => ui}/newlambdas-ret-infer.rs | 2 + .../{run-pass => ui}/newlambdas-ret-infer2.rs | 2 + src/test/{run-pass => ui}/newlambdas.rs | 1 + .../{run-pass => ui}/newtype-polymorphic.rs | 2 + .../{run-pass => ui}/newtype-temporary.rs | 2 + src/test/{run-pass => ui}/newtype.rs | 2 + .../{run-pass => ui}/nil-decl-in-foreign.rs | 2 + .../issue-58127-mutliple-requirements.rs | 2 +- .../propagate-despite-same-free-region.rs | 2 +- src/test/ui/nll/constant.rs | 2 +- src/test/ui/nll/drop-may-dangle.rs | 2 +- src/test/ui/nll/empty-type-predicate.rs | 2 +- src/test/ui/nll/extra-unused-mut.rs | 2 +- .../ui/nll/generator-distinct-lifetime.rs | 2 +- src/test/ui/nll/get_default.polonius.stderr | 15 + src/test/ui/nll/issue-16223.rs | 2 +- src/test/ui/nll/issue-21114-ebfull.rs | 2 +- src/test/ui/nll/issue-21114-kixunil.rs | 2 +- .../ui/nll/issue-22323-temp-destruction.rs | 2 +- src/test/ui/nll/issue-30104.rs | 2 +- ...ue-32382-index-assoc-type-with-lifetime.rs | 2 +- ...ssue-42574-diagnostic-in-nested-closure.rs | 13 + ...-42574-diagnostic-in-nested-closure.stderr | 26 + src/test/ui/nll/issue-43058.rs | 2 +- src/test/ui/nll/issue-46589.rs | 6 + src/test/ui/nll/issue-46589.stderr | 2 +- src/test/ui/nll/issue-47022.rs | 2 +- .../nll/issue-47153-generic-const.rs | 0 src/test/{run-pass => ui}/nll/issue-47589.rs | 0 .../nll/issue-48623-closure.rs | 0 .../nll/issue-48623-generator.rs | 0 src/test/{run-pass => ui}/nll/issue-50343.rs | 0 .../nll/issue-50461-used-mut-from-moves.rs | 0 src/test/ui/nll/issue-50716-1.rs | 2 +- src/test/ui/nll/issue-51191.stderr | 2 +- src/test/ui/nll/issue-51351.rs | 2 +- src/test/ui/nll/issue-52078.rs | 2 +- src/test/ui/nll/issue-53119.rs | 2 +- .../nll/issue-53123-raw-pointer-cast.rs | 0 src/test/ui/nll/issue-53570.rs | 2 +- src/test/ui/nll/issue-55344.rs | 2 +- src/test/ui/nll/issue-55651.rs | 2 +- src/test/ui/nll/issue-57280-1.rs | 2 +- src/test/ui/nll/issue-57280.rs | 2 +- src/test/ui/nll/issue-61311-normalize.rs | 2 +- src/test/ui/nll/issue-61320-normalize.rs | 2 +- .../loan_ends_mid_block_pair.polonius.stderr | 15 + src/test/ui/nll/match-cfg-fake-edges.rs | 16 +- src/test/ui/nll/match-cfg-fake-edges.stderr | 16 +- src/test/ui/nll/match-cfg-fake-edges2.rs | 20 + src/test/ui/nll/match-cfg-fake-edges2.stderr | 15 + .../ui/nll/match-guards-partially-borrow.rs | 2 - .../nll/match-guards-partially-borrow.stderr | 18 +- .../maybe-initialized-drop-uninitialized.rs | 2 +- .../nll/mutating_references.rs | 0 .../ui/nll/polonius/assignment-kills-loans.rs | 88 + .../polonius/assignment-to-differing-field.rs | 50 + .../assignment-to-differing-field.stderr | 51 + src/test/ui/nll/polonius/call-kills-loans.rs | 24 + src/test/ui/nll/polonius/issue-46589.rs | 32 + .../nll/{ => polonius}/polonius-smoke-test.rs | 0 .../{ => polonius}/polonius-smoke-test.stderr | 0 .../nll/polonius/storagedead-kills-loans.rs | 29 + .../nll/process_or_insert_default.rs | 0 src/test/ui/nll/projection-return.rs | 2 +- src/test/{run-pass => ui}/nll/rc-loop.rs | 0 .../ui/nll/relate_tys/hr-fn-aau-eq-abu.rs | 2 +- .../ui/nll/relate_tys/hr-fn-aba-as-aaa.rs | 2 +- src/test/ui/nll/relate_tys/issue-48071.rs | 2 +- ...return-ref-mut-issue-46557.polonius.stderr | 15 + src/test/ui/nll/ty-outlives/issue-53789-1.rs | 2 +- src/test/ui/nll/ty-outlives/issue-53789-2.rs | 2 +- src/test/ui/nll/ty-outlives/issue-55756.rs | 2 +- .../ui/nll/ty-outlives/projection-body.rs | 2 +- .../ty-outlives/projection-implied-bounds.rs | 7 +- .../projection-implied-bounds.stderr | 2 +- ...n-one-region-trait-bound-static-closure.rs | 2 +- .../projection-where-clause-env.rs | 2 +- .../projection-where-clause-trait.rs | 2 +- .../ty-outlives/ty-param-implied-bounds.rs | 6 +- .../ui/nll/user-annotations/downcast-infer.rs | 2 +- .../issue-54570-bootstrapping.rs | 2 +- src/test/{run-pass => ui}/no-core-1.rs | 2 + src/test/{run-pass => ui}/no-core-2.rs | 2 + src/test/ui/no-implicit-prelude-nested.rs | 6 +- src/test/ui/no-implicit-prelude-nested.stderr | 22 +- src/test/ui/no-implicit-prelude.rs | 2 +- src/test/ui/no-implicit-prelude.stderr | 10 +- src/test/{run-pass => ui}/no-landing-pads.rs | 1 + src/test/ui/no-link.rs | 2 +- src/test/ui/no-link.stderr | 2 +- src/test/{run-pass => ui}/no-std-1.rs | 2 + src/test/{run-pass => ui}/no-std-2.rs | 2 + src/test/{run-pass => ui}/no-std-3.rs | 2 + src/test/ui/no-std-inject.rs | 1 - src/test/ui/no-std-inject.stderr | 2 +- src/test/{run-pass => ui}/no-stdio.rs | 1 + .../no-warn-on-field-replace-issue-34101.rs | 2 +- .../{run-pass => ui}/non-built-in-quote.rs | 1 + .../ui/non-exhaustive/non-exhaustive-match.rs | 18 +- .../non-exhaustive-match.stderr | 4 +- .../non-exhaustive-pattern-witness.rs | 2 +- src/test/{run-pass => ui}/non-legacy-modes.rs | 2 + .../non_modrs_mods/foors_mod.rs | 1 + .../foors_mod/compiletest-ignore-dir | 0 .../foors_mod}/inline/somename.rs | 2 + .../foors_mod/inner_foors_mod.rs | 2 + .../foors_mod}/inner_foors_mod/innest.rs | 2 + .../foors_mod}/inner_modrs_mod/innest.rs | 2 + .../foors_mod}/inner_modrs_mod/mod.rs | 2 + .../modrs_mod/compiletest-ignore-dir | 0 .../modrs_mod}/inline/somename.rs | 2 + .../modrs_mod/inner_foors_mod.rs | 2 + .../modrs_mod}/inner_foors_mod/innest.rs | 2 + .../modrs_mod}/inner_modrs_mod/innest.rs | 2 + .../modrs_mod}/inner_modrs_mod/mod.rs | 2 + .../non_modrs_mods/modrs_mod/mod.rs | 2 + .../non_modrs_mods/non_modrs_mods.rs | 0 .../some_crazy_attr_mod_dir/arbitrary_name.rs | 2 + .../compiletest-ignore-dir | 0 .../inner_modrs_mod/innest.rs | 3 + .../inner_modrs_mod/mod.rs | 2 + .../non_modrs_mods_and_inline_mods.rs | 2 +- src/test/{run-pass => ui}/nul-characters.rs | 2 + .../nullable-pointer-ffi-compat.rs | 1 + .../nullable-pointer-iotareduction.rs | 2 + .../{run-pass => ui}/nullable-pointer-size.rs | 2 + .../numbers-arithmetic/arith-0.rs | 0 .../numbers-arithmetic/arith-1.rs | 0 .../numbers-arithmetic/arith-2.rs | 0 .../numbers-arithmetic/arith-unsigned.rs | 0 .../numbers-arithmetic/div-mod.rs | 0 .../float-int-invalid-const-cast.rs | 0 .../float-literal-inference.rs | 0 .../numbers-arithmetic/float-nan.rs | 0 .../numbers-arithmetic/float-signature.rs | 0 .../numbers-arithmetic/float.rs | 0 .../numbers-arithmetic/float2.rs | 0 .../numbers-arithmetic/float_math.rs | 0 .../numbers-arithmetic/floatlits.rs | 0 .../numbers-arithmetic/i128-ffi.rs | 0 .../numbers-arithmetic/i128.rs | 0 .../numbers-arithmetic/i32-sub.rs | 0 .../numbers-arithmetic/i8-incr.rs | 0 .../numbers-arithmetic/int-abs-overflow.rs | 0 .../numbers-arithmetic/int.rs | 0 .../integer-literal-radix.rs | 0 .../integer-literal-suffix-inference-2.rs | 0 .../integer-literal-suffix-inference-3.rs | 0 .../integer-literal-suffix-inference.rs | 0 .../next-power-of-two-overflow-debug.rs | 0 .../next-power-of-two-overflow-ndebug.rs | 0 .../numbers-arithmetic/num-wrapping.rs | 0 .../numeric-method-autoexport.rs | 0 .../promoted_overflow_opt.rs | 0 .../saturating-float-casts.rs | 0 .../numbers-arithmetic/shift-near-oflo.rs | 0 .../numbers-arithmetic/shift-various-types.rs | 0 .../numbers-arithmetic/shift.rs | 0 .../signed-shift-const-eval.rs | 0 .../numbers-arithmetic/u128-as-f32.rs | 0 .../numbers-arithmetic/u128.rs | 0 .../numbers-arithmetic/u32-decr.rs | 0 .../numbers-arithmetic/u8-incr-decr.rs | 0 .../numbers-arithmetic/u8-incr.rs | 0 .../numbers-arithmetic/uint.rs | 0 ...ject-lifetime-default-default-to-static.rs | 1 + .../object-lifetime-default-from-rptr-box.rs | 1 + .../object-lifetime-default-from-rptr-mut.rs | 1 + .../object-lifetime-default-from-rptr.rs | 1 + .../object-lifetime-default.stderr | 48 +- .../object-method-numbering.rs | 1 + .../object-safety-by-value-self.rs | 2 +- .../object-safety/object-safety-phantom-fn.rs | 2 +- .../objects-coerce-freeze-borrored.rs | 1 + ...owned-object-borrowed-method-headerless.rs | 1 + .../objects-owned-object-owned-method.rs | 1 + src/test/ui/obsolete-in-place/bad.rs | 1 - src/test/ui/obsolete-in-place/bad.stderr | 17 +- .../{run-pass => ui}/once-move-out-on-heap.rs | 1 + src/test/{run-pass => ui}/one-tuple.rs | 1 + .../op-assign-builtins-by-ref.rs | 2 + src/test/{run-pass => ui}/opeq.rs | 2 + .../operator-associativity.rs | 1 + .../operator-multidispatch.rs | 1 + .../{run-pass => ui}/operator-overloading.rs | 2 + .../{run-pass => ui}/optimization-fuel-0.rs | 2 + .../optimization-fuel-0.stderr | 0 .../{run-pass => ui}/optimization-fuel-1.rs | 2 + .../optimization-fuel-1.stderr | 0 src/test/{run-pass => ui}/option-ext.rs | 2 + src/test/{run-pass => ui}/option-unwrap.rs | 2 + src/test/{run-pass => ui}/out-of-stack.rs | 2 + .../{run-pass => ui}/out-pointer-aliasing.rs | 2 + .../{run-pass => ui}/output-slot-variants.rs | 2 + .../over-constrained-vregs.rs | 2 + ...lap-doesnt-conflict-with-specialization.rs | 2 + ...p-permitted-for-annotated-marker-traits.rs | 1 + .../auxiliary/overloaded_autoderef_xc.rs | 0 .../overloaded/overloaded-autoderef-count.rs | 0 .../overloaded-autoderef-indexing.rs | 0 .../overloaded/overloaded-autoderef-order.rs | 0 .../overloaded/overloaded-autoderef-vtable.rs | 0 .../overloaded/overloaded-autoderef-xcrate.rs | 0 .../overloaded/overloaded-autoderef.rs | 0 .../overloaded-calls-object-one-arg.rs | 0 .../overloaded-calls-object-two-args.rs | 0 .../overloaded-calls-object-zero-args.rs | 0 .../overloaded-calls-param-vtables.rs | 0 .../overloaded/overloaded-calls-simple.rs | 0 .../overloaded/overloaded-calls-zero-args.rs | 0 .../overloaded/overloaded-deref-count.rs | 0 .../overloaded/overloaded-deref.rs | 0 .../overloaded/overloaded-index-assoc-list.rs | 0 .../overloaded/overloaded-index-autoderef.rs | 0 .../overloaded/overloaded-index-in-field.rs | 0 .../overloaded/overloaded-index.rs | 0 .../overloaded_deref_with_ref_pattern.rs | 0 ...oaded_deref_with_ref_pattern_issue15609.rs | 0 .../{run-pass => ui}/owned-implies-static.rs | 1 + .../packed/auxiliary/packed.rs | 0 .../packed/packed-struct-borrow-element.rs | 0 .../packed/packed-struct-drop-aligned.rs | 0 .../packed/packed-struct-generic-layout.rs | 0 .../packed/packed-struct-generic-size.rs | 0 .../packed/packed-struct-layout.rs | 0 .../packed/packed-struct-match.rs | 0 .../packed/packed-struct-optimized-enum.rs | 0 .../packed/packed-struct-size-xc.rs | 0 .../packed/packed-struct-size.rs | 0 .../packed/packed-struct-vec.rs | 0 .../packed/packed-tuple-struct-layout.rs | 0 .../packed/packed-tuple-struct-size.rs | 0 .../packed-with-inference-vars-issue-61402.rs | 22 + .../abort-link-to-unwinding-crates.rs | 0 .../{run-pass => ui}/panic-runtime/abort.rs | 0 .../auxiliary/exit-success-if-unwind.rs | 0 .../panic-runtime/link-to-abort.rs | 0 .../panic-runtime/link-to-unwind.rs | 0 .../panic-runtime/lto-abort.rs | 0 .../panic-runtime/lto-unwind.rs | 0 src/test/ui/panic-runtime/needs-gate.stderr | 4 +- .../panic-uninitialized-zeroed.rs | 2 + src/test/ui/panic_implementation-closures.rs | 2 +- .../panics/panic-handler-chain.rs | 0 .../panics/panic-handler-flail-wildly.rs | 0 .../panics/panic-handler-set-twice.rs | 0 .../panics/panic-in-dtor-drops-fields.rs | 0 .../panics/panic-recover-propagate.rs | 0 .../{run-pass => ui}/panics/panic-safe.rs | 0 src/test/{run-pass => ui}/paren-free.rs | 2 + .../{run-pass => ui}/parse-assoc-type-lt.rs | 1 + src/test/{run-pass => ui}/parse-panic.rs | 2 + .../parser-unicode-whitespace.rs | 1 + src/test/ui/parser/attr.stderr | 4 +- src/test/ui/parser/bounds-obj-parens.rs | 2 +- src/test/ui/parser/default.stderr | 4 +- src/test/ui/parser/fn-arg-doc-comment.stderr | 4 +- src/test/ui/parser/impl-qpath.rs | 2 +- .../inner-attr-after-doc-comment.stderr | 11 +- src/test/ui/parser/inner-attr.stderr | 7 +- src/test/ui/parser/issue-17383.stderr | 2 +- src/test/ui/parser/issue-19096.rs | 9 +- src/test/ui/parser/issue-19096.stderr | 13 +- src/test/ui/parser/issue-20711-2.rs | 4 +- src/test/ui/parser/issue-20711-2.stderr | 6 +- src/test/ui/parser/issue-20711.rs | 4 +- src/test/ui/parser/issue-20711.stderr | 6 +- src/test/ui/parser/issue-33262.stderr | 2 +- src/test/ui/parser/issue-41155.stderr | 4 +- src/test/ui/parser/issue-62881.stderr | 2 +- src/test/ui/parser/issue-62895.stderr | 4 +- src/test/ui/parser/issue-62913.rs | 3 + src/test/ui/parser/issue-62913.stderr | 16 + src/test/ui/parser/issue-62973.rs | 8 + src/test/ui/parser/issue-62973.stderr | 61 + .../issue-63115-range-pat-interpolated.rs | 16 + src/test/ui/parser/issue-63135.rs | 3 + src/test/ui/parser/issue-63135.stderr | 44 + .../ui/parser/lex-bad-numeric-literals.stderr | 4 +- src/test/ui/parser/lex-bad-token.rs | 2 + src/test/ui/parser/lex-stray-backslash.rs | 2 + .../ui/parser/macro-bad-delimiter-ident.rs | 2 +- .../parser/macro-bad-delimiter-ident.stderr | 6 +- .../macro/trait-object-macro-matcher.stderr | 2 +- src/test/ui/parser/match-vec-invalid.rs | 10 +- src/test/ui/parser/match-vec-invalid.stderr | 47 +- src/test/ui/parser/pat-lt-bracket-6.rs | 6 + src/test/ui/parser/pat-lt-bracket-6.stderr | 24 +- src/test/ui/parser/pat-lt-bracket-7.rs | 7 +- src/test/ui/parser/pat-lt-bracket-7.stderr | 16 +- src/test/ui/parser/pat-tuple-2.rs | 3 +- src/test/ui/parser/pat-tuple-2.stderr | 8 - src/test/ui/parser/pat-tuple-3.rs | 2 +- src/test/ui/parser/pat-tuple-3.stderr | 6 +- src/test/ui/parser/pat-tuple-4.rs | 8 +- src/test/ui/parser/pat-tuple-4.stderr | 30 +- src/test/ui/parser/pat-tuple-5.rs | 7 +- src/test/ui/parser/pat-tuple-5.stderr | 32 +- src/test/ui/parser/raw-byte-string-eof.stderr | 4 +- .../ui/parser/raw-byte-string-literals.stderr | 4 +- src/test/ui/parser/raw-str-delim.stderr | 2 +- .../ui/parser/raw/raw-literal-keywords.rs | 15 +- .../ui/parser/raw/raw-literal-keywords.stderr | 22 +- src/test/ui/parser/recover-enum2.stderr | 2 +- .../recover-for-loop-parens-around-head.rs | 15 + ...recover-for-loop-parens-around-head.stderr | 27 + .../ui/parser/recover-from-bad-variant.stderr | 13 +- src/test/ui/parser/recover-from-homoglyph.rs | 4 + .../ui/parser/recover-from-homoglyph.stderr | 22 + src/test/ui/parser/recover-range-pats.rs | 151 + src/test/ui/parser/recover-range-pats.stderr | 619 ++ src/test/ui/parser/recover-tuple-pat.rs | 4 +- src/test/ui/parser/recover-tuple-pat.stderr | 20 +- .../parser/removed-syntax-mut-vec-ty.stderr | 2 +- .../ui/parser/removed-syntax-record.stderr | 2 +- .../ui/parser/removed-syntax-static-fn.rs | 4 +- .../ui/parser/removed-syntax-static-fn.stderr | 6 +- ...several-carriage-returns-in-doc-comment.rs | 10 + ...ral-carriage-returns-in-doc-comment.stderr | 20 + .../tag-variant-disr-non-nullary.stderr | 2 +- src/test/ui/parser/trailing-plus-in-bounds.rs | 2 +- .../trait-object-lifetime-parens.stderr | 2 +- .../parser/trait-object-trait-parens.stderr | 2 +- .../ui/parser/trait-plusequal-splitting.rs | 2 +- .../ui/parser/underscore-suffix-for-string.rs | 2 +- src/test/ui/parser/unicode-quote-chars.rs | 3 + src/test/ui/parser/unicode-quote-chars.stderr | 18 +- src/test/ui/path-lookahead.stderr | 4 +- src/test/{run-pass => ui}/path.rs | 1 + .../{run-pass => ui}/paths-containing-nul.rs | 2 + .../pattern/rest-pat-semantic-disallowed.rs | 82 + .../rest-pat-semantic-disallowed.stderr | 188 + src/test/ui/pattern/rest-pat-syntactic.rs | 70 + .../ui/precise_pointer_size_matching.stderr | 8 +- src/test/ui/print-fuel/print-fuel.rs | 2 +- .../print-stdout-eprint-stderr.rs | 1 + src/test/ui/print_type_sizes/anonymous.rs | 2 +- src/test/ui/print_type_sizes/generics.rs | 2 +- .../ui/print_type_sizes/multiple_types.rs | 2 +- src/test/ui/print_type_sizes/niche-filling.rs | 2 +- src/test/ui/print_type_sizes/no_duplicates.rs | 2 +- src/test/ui/print_type_sizes/packed.rs | 2 +- src/test/ui/print_type_sizes/padding.rs | 2 +- src/test/ui/print_type_sizes/repr-align.rs | 2 +- src/test/ui/print_type_sizes/repr_int_c.rs | 2 +- src/test/ui/print_type_sizes/uninhabited.rs | 2 +- src/test/ui/print_type_sizes/variants.rs | 2 +- .../privacy/auxiliary/priv-impl-prim-ty.rs | 0 .../privacy/auxiliary/privacy_reexport.rs | 0 .../privacy/auxiliary/pub_use_mods_xcrate.rs | 0 .../privacy/auxiliary/pub_use_xcrate1.rs | 0 .../privacy/auxiliary/pub_use_xcrate2.rs | 0 src/test/ui/privacy/issue-57264-1.rs | 2 +- src/test/ui/privacy/issue-57264-2.rs | 2 +- .../ui/privacy/legacy-ctor-visibility.stderr | 2 +- .../privacy/priv-impl-prim-ty.rs | 0 .../{run-pass => ui}/privacy/privacy-ns.rs | 0 .../privacy/privacy-reexport.rs | 0 .../privacy/privacy1-rpass.rs} | 0 src/test/ui/privacy/privacy5.stderr | 96 + .../privacy/private-class-field.rs | 0 .../ui/privacy/private-in-public-assoc-ty.rs | 5 +- .../privacy/private-in-public-assoc-ty.stderr | 16 +- .../ui/privacy/private-in-public-expr-pat.rs | 2 +- .../private-in-public-non-principal.stderr | 2 +- ...rivate-in-public-type-alias-impl-trait.rs} | 8 +- .../ui/privacy/private-in-public-warn.stderr | 2 +- .../privacy/private-method-rpass.rs} | 0 .../privacy/pub-extern-privacy.rs | 0 .../privacy/pub-use-xcrate.rs | 0 .../privacy/pub_use_mods_xcrate_exe.rs | 0 .../restricted/lookup-ignores-private.rs | 2 +- src/test/ui/privacy/restricted/test.rs | 2 +- src/test/ui/privacy/restricted/test.stderr | 4 +- .../{run-pass => ui}/proc-macro/add-impl.rs | 1 + .../proc-macro/append-impl.rs | 1 + .../{run-pass => ui}/proc-macro/attr-args.rs | 1 + .../{run-pass => ui}/proc-macro/attr-cfg.rs | 1 + .../proc-macro/attr-on-trait.rs | 1 + .../proc-macro/attr-stmt-expr-rpass.rs} | 5 +- src/test/ui/proc-macro/attr-stmt-expr.rs | 4 +- src/test/ui/proc-macro/attr-stmt-expr.stderr | 4 +- .../attribute-spans-preserved.stdout | 2 +- src/test/ui/proc-macro/attribute.rs | 3 +- src/test/ui/proc-macro/attribute.stderr | 24 +- src/test/ui/proc-macro/attributes-included.rs | 2 +- .../ui/proc-macro/attributes-included.stderr | 2 +- .../proc-macro/auxiliary/add-impl.rs | 0 .../proc-macro/auxiliary/append-impl.rs | 0 .../proc-macro/auxiliary/attr-args.rs | 0 .../proc-macro/auxiliary/attr-cfg.rs | 0 .../proc-macro/auxiliary/attr-on-trait.rs | 0 .../auxiliary/attr-stmt-expr-rpass.rs} | 4 +- .../ui/proc-macro/auxiliary/attr-stmt-expr.rs | 4 +- .../proc-macro/auxiliary/bang-macro.rs | 0 .../proc-macro/auxiliary/call-site.rs | 0 .../auxiliary/count_compound_ops.rs | 0 .../auxiliary/custom-attr-only-one-derive.rs | 0 .../proc-macro/auxiliary/derive-a.rs | 0 .../proc-macro/auxiliary/derive-atob.rs | 0 .../proc-macro/auxiliary/derive-attr-cfg.rs | 0 .../proc-macro/auxiliary/derive-b-rpass.rs} | 2 +- .../proc-macro/auxiliary/derive-ctod.rs | 0 .../proc-macro/auxiliary/derive-nothing.rs | 0 .../auxiliary/derive-same-struct.rs | 0 .../proc-macro/auxiliary/derive-two-attrs.rs | 0 .../proc-macro/auxiliary/derive-union.rs | 0 .../auxiliary/dollar-crate-external.rs | 6 + .../proc-macro/auxiliary/double.rs | 0 .../proc-macro/auxiliary/empty-crate.rs | 0 .../auxiliary/expand-with-a-macro.rs | 0 .../auxiliary/external-crate-var.rs | 0 .../auxiliary/gen-lifetime-token.rs | 0 .../proc-macro/auxiliary/hygiene_example.rs | 0 .../auxiliary/hygiene_example_codegen.rs | 0 .../proc-macro/auxiliary/issue-39889.rs | 0 .../proc-macro/auxiliary/issue-42708.rs | 0 .../proc-macro/auxiliary/issue-50061.rs | 0 .../proc-macro/auxiliary/lifetimes-rpass.rs} | 0 .../proc-macro/auxiliary/modify-ast.rs | 0 .../proc-macro/auxiliary/negative-token.rs | 0 .../proc-macro/auxiliary/not-joint.rs | 0 .../proc-macro/auxiliary/span-api-tests.rs | 0 .../proc-macro/auxiliary/span-test-macros.rs | 0 .../auxiliary/test-macros-rpass.rs} | 0 .../{run-pass => ui}/proc-macro/bang-macro.rs | 1 + .../{run-pass => ui}/proc-macro/call-site.rs | 2 + .../proc-macro/count_compound_ops.rs | 1 + .../{run-pass => ui}/proc-macro/crate-var.rs | 1 + .../proc-macro/custom-attr-only-one-derive.rs | 1 + .../proc-macro/derive-attr-cfg.rs | 2 + .../{run-pass => ui}/proc-macro/derive-b.rs | 5 +- .../ui/proc-macro/derive-helper-shadowed.rs | 2 +- .../ui/proc-macro/derive-helper-shadowing.rs | 2 +- .../proc-macro/derive-helper-shadowing.stderr | 8 +- src/test/ui/proc-macro/derive-in-mod.rs | 2 +- .../proc-macro/derive-same-struct.rs | 2 + .../proc-macro/derive-same-struct.stdout | 0 src/test/ui/proc-macro/derive-still-gated.rs | 2 +- .../ui/proc-macro/derive-still-gated.stderr | 6 +- .../proc-macro/derive-test.rs | 1 + .../proc-macro/derive-two-attrs.rs | 2 + .../proc-macro/derive-union.rs | 2 + .../ui/proc-macro/dollar-crate-issue-57089.rs | 2 +- .../dollar-crate-issue-57089.stdout | 4 +- .../ui/proc-macro/dollar-crate-issue-62325.rs | 27 + .../dollar-crate-issue-62325.stdout | 112 + src/test/ui/proc-macro/dollar-crate.stdout | 60 +- .../ui/proc-macro/edition-imports-2018.rs | 2 +- .../proc-macro/empty-crate.rs | 2 + .../ui/proc-macro/expand-to-unstable-2.rs | 5 +- .../ui/proc-macro/expand-to-unstable-2.stderr | 4 +- .../ui/proc-macro/expand-to-unstable.stderr | 2 +- .../proc-macro/expand-with-a-macro.rs | 1 + .../extern-prelude-extern-crate-proc-macro.rs | 2 +- .../proc-macro/gen-lifetime-token.rs | 1 + src/test/ui/proc-macro/generate-mod.stderr | 2 +- .../helper-attr-blocked-by-import.rs | 2 +- .../proc-macro/hygiene_example.rs | 2 + .../proc-macro/issue-39889.rs | 2 + src/test/ui/proc-macro/issue-41211.rs | 4 +- src/test/ui/proc-macro/issue-41211.stderr | 14 +- .../proc-macro/issue-42708.rs | 1 + .../proc-macro/issue-50061.rs | 2 + src/test/ui/proc-macro/issue-53481.rs | 2 +- .../proc-macro/lifetimes-rpass.rs} | 6 +- src/test/ui/proc-macro/lifetimes.stderr | 2 +- .../{run-pass => ui}/proc-macro/load-two.rs | 2 + .../proc-macro/macro-namespace-reserved-2.rs | 18 +- .../macro-namespace-reserved-2.stderr | 98 +- src/test/ui/proc-macro/macro-use-attr.rs | 2 +- src/test/ui/proc-macro/macro-use-bang.rs | 2 +- .../proc-macro/macros-in-extern-rpass.rs} | 5 +- .../ui/proc-macro/macros-in-extern.stderr | 6 +- .../{run-pass => ui}/proc-macro/modify-ast.rs | 1 + src/test/ui/proc-macro/more-gates.stderr | 10 +- .../proc-macro/negative-token.rs | 1 + src/test/ui/proc-macro/no-missing-docs.rs | 2 +- .../{run-pass => ui}/proc-macro/not-joint.rs | 1 + .../ui/proc-macro/proc-macro-attributes.rs | 2 +- .../proc-macro/proc-macro-attributes.stderr | 10 +- .../ui/proc-macro/proc-macro-gates.stderr | 34 +- .../ui/proc-macro/proc-macro-gates2.stderr | 8 +- .../ui/proc-macro/reserved-macro-names.rs | 6 +- .../ui/proc-macro/reserved-macro-names.stderr | 6 +- src/test/ui/proc-macro/resolve-error.rs | 4 +- src/test/ui/proc-macro/resolve-error.stderr | 35 +- src/test/{run-pass => ui}/proc-macro/smoke.rs | 2 + .../proc-macro/span-api-tests.rs | 1 + .../proc-macro/struct-field-macro.rs | 2 + src/test/{run-pass => ui}/proc_macro.rs | 1 + .../{run-pass => ui}/process/process-envs.rs | 1 + .../{run-pass => ui}/process/process-exit.rs | 0 .../process/process-remove-from-env.rs | 1 + .../process/process-sigpipe.rs | 1 + .../process/process-spawn-nonexistent.rs | 0 .../process-spawn-with-unicode-params.rs | 0 .../process/process-status-inherits-stdin.rs | 0 .../project-cache-issue-31849.rs | 1 + .../project-cache-issue-37154.rs | 2 + .../project-defer-unification.rs | 2 + .../ptr-coercion-rpass.rs} | 2 + .../pub/pub-reexport-priv-extern-crate.stderr | 2 +- src/test/{run-pass => ui}/pure-sum.rs | 2 + src/test/{run-pass => ui}/purity-infer.rs | 2 + src/test/{run-pass => ui}/range-type-infer.rs | 2 + src/test/{run-pass => ui}/range.rs | 2 + src/test/ui/range/range_traits-4.rs | 2 +- src/test/ui/range/range_traits-5.rs | 2 +- src/test/ui/range/range_traits-7.rs | 2 +- src/test/{run-pass => ui}/range_inclusive.rs | 1 + .../{run-pass => ui}/range_inclusive_gate.rs | 2 + .../{run-pass => ui}/ranges-precedence.rs | 1 + src/test/{run-pass => ui}/raw-fat-ptr.rs | 1 + src/test/{run-pass => ui}/raw-str.rs | Bin 835 -> 847 bytes .../rcvr-borrowed-to-region.rs | 2 + .../reachable-unnameable-items.rs | 1 + .../reachable-unnameable-type-alias.rs | 2 + src/test/ui/reachable/expr_andand.rs | 2 +- src/test/ui/reachable/expr_oror.rs | 2 +- src/test/ui/reachable/expr_while.rs | 5 +- src/test/ui/reachable/expr_while.stderr | 37 +- src/test/{run-pass => ui}/readalias.rs | 2 + src/test/{run-pass => ui}/realloc-16687.rs | 1 + src/test/ui/recursion/recursive-reexports.rs | 2 +- .../ui/recursion/recursive-reexports.stderr | 2 +- ...rsive-types-are-not-uninhabited.nll.stderr | 16 - .../recursive-types-are-not-uninhabited.rs | 4 +- ...recursive-types-are-not-uninhabited.stderr | 8 +- .../reexport-should-still-link.rs | 1 + src/test/{run-pass => ui}/reexport-star.rs | 1 + .../reexport-test-harness-main.rs | 1 + .../refer-to-other-statics-by-value.rs | 2 + src/test/ui/refutable-pattern-errors.rs | 2 +- src/test/ui/refutable-pattern-errors.stderr | 4 +- ...6537-closure-uses-region-from-container.rs | 2 +- ...gion-bound-extra-bound-in-inherent-impl.rs | 2 +- ...gion-bound-on-closure-outlives-call.stderr | 2 +- ...ion-bound-same-bounds-in-trait-and-impl.rs | 2 +- .../ui/regions/region-object-lifetime-1.rs | 2 +- .../ui/regions/region-object-lifetime-3.rs | 2 +- .../regions-addr-of-interior-of-unique-box.rs | 0 .../regions/regions-addr-of-ret.rs | 0 .../regions-assoc-type-region-bound.rs | 0 .../regions-assoc-type-static-bound.rs | 0 .../regions/regions-borrow-at.rs | 0 .../regions/regions-borrow-evec-fixed.rs | 0 .../regions/regions-borrow-evec-uniq.rs | 0 .../regions/regions-borrow-uniq.rs | 0 .../{run-pass => ui}/regions/regions-bot.rs | 0 .../regions-bound-lists-feature-gate-2.rs | 0 .../regions-bound-lists-feature-gate.rs | 0 ...-close-over-type-parameter-successfully.rs | 0 .../regions/regions-copy-closure.rs | 0 .../regions/regions-creating-enums2.rs | 0 .../regions/regions-creating-enums5.rs | 0 .../regions/regions-debruijn-of-object.rs | 0 .../regions/regions-dependent-addr-of.rs | 0 .../regions/regions-dependent-autofn.rs | 0 .../regions/regions-dependent-autoslice.rs | 0 .../regions/regions-dependent-let-ref.rs | 0 ...egions-early-bound-lifetime-in-assoc-fn.rs | 0 .../regions-early-bound-trait-param.rs | 0 ...egions-early-bound-used-in-bound-method.rs | 0 .../regions-early-bound-used-in-bound.rs | 0 .../regions-early-bound-used-in-type-param.rs | 0 .../regions/regions-escape-into-other-fn.rs | 0 .../regions/regions-expl-self.rs | 0 .../regions/regions-fn-subtyping-2.rs | 0 .../regions/regions-fn-subtyping.rs | 0 ...on-outlives-static-outlives-free-region.rs | 0 ...regions-implied-bounds-projection-gap-2.rs | 2 +- ...regions-implied-bounds-projection-gap-3.rs | 2 +- ...regions-implied-bounds-projection-gap-4.rs | 2 +- .../regions-infer-borrow-scope-addr-of.rs | 0 .../regions-infer-borrow-scope-view.rs | 0 ...gions-infer-borrow-scope-within-loop-ok.rs | 0 .../regions/regions-infer-borrow-scope.rs | 0 .../regions/regions-infer-call-2.rs | 0 .../regions/regions-infer-call.rs | 0 ...regions-infer-contravariance-due-to-ret.rs | 0 .../regions-infer-reborrow-ref-mut-recurse.rs | 0 ...regions-infer-region-in-fn-but-not-type.rs | 0 .../regions/regions-infer-static-from-proc.rs | 0 .../regions/regions-issue-21422.rs | 0 .../regions/regions-issue-22246.rs | 0 .../regions-lifetime-nonfree-late-bound.rs | 0 ...-lifetime-static-items-enclosing-scopes.rs | 0 .../regions/regions-link-fn-args.rs | 0 .../regions/regions-lub-ref-ref-rc.rs | 0 .../regions/regions-mock-codegen.rs | 0 .../regions-no-bound-in-argument-cleanup.rs | 0 .../regions-no-variance-from-fn-generics.rs | 0 .../regions/regions-nullary-variant.rs | 0 ...s-outlives-nominal-type-enum-region-rev.rs | 2 +- ...gions-outlives-nominal-type-enum-region.rs | 2 +- ...ons-outlives-nominal-type-enum-type-rev.rs | 2 +- ...regions-outlives-nominal-type-enum-type.rs | 2 +- ...outlives-nominal-type-struct-region-rev.rs | 2 +- ...ons-outlives-nominal-type-struct-region.rs | 2 +- ...s-outlives-nominal-type-struct-type-rev.rs | 2 +- ...gions-outlives-nominal-type-struct-type.rs | 2 +- .../regions-outlives-projection-hrtype.rs | 2 +- .../regions-outlives-projection-trait-def.rs | 2 +- .../ui/regions/regions-outlives-scalar.rs | 2 +- .../regions/regions-params.rs | 0 .../regions-reassign-let-bound-pointer.rs | 0 .../regions-reassign-match-bound-pointer.rs | 0 .../regions/regions-refcell.rs | 0 ...ions-on-closures-to-inference-variables.rs | 0 .../regions-return-interior-of-option.rs | 0 .../regions/regions-scope-chain-example.rs | 0 .../regions/regions-self-impls.rs | 0 .../regions/regions-self-in-enums.rs | 0 .../regions/regions-simple.rs | 0 .../regions/regions-static-bound-rpass.rs} | 0 .../regions/regions-static-closure.rs | 0 .../regions/regions-trait-object-1.rs | 0 ...ariance-contravariant-use-contravariant.rs | 0 ...egions-variance-covariant-use-covariant.rs | 0 src/test/ui/removing-extern-crate.fixed | 2 +- src/test/ui/removing-extern-crate.rs | 2 +- src/test/ui/removing-extern-crate.stderr | 2 +- .../{run-pass => ui}/repeat-expr-in-static.rs | 2 + src/test/ui/repeat-to-run-dtor-twice.rs | 2 +- src/test/{run-pass => ui}/repr_c_int_align.rs | 1 + .../ui/reserved/reserved-attr-on-macro.rs | 4 +- .../ui/reserved/reserved-attr-on-macro.stderr | 14 +- .../{run-pass => ui}/resolve-issue-2428.rs | 2 + .../resolve-pseudo-shadowing.rs | 1 + .../ui/resolve/enums-are-namespaced-xc.stderr | 6 +- src/test/ui/resolve/issue-57523.rs | 2 +- src/test/ui/resolve/levenshtein.stderr | 2 +- src/test/ui/resolve/privacy-enum-ctor.stderr | 24 +- .../ui/resolve/privacy-struct-ctor.stderr | 12 + src/test/ui/resolve/resolve-bad-visibility.rs | 4 +- .../ui/resolve/resolve-bad-visibility.stderr | 21 +- ...e-conflict-extern-crate-vs-extern-crate.rs | 1 - ...nflict-extern-crate-vs-extern-crate.stderr | 4 - .../ui/resolve/resolve-inconsistent-names.rs | 31 +- .../resolve/resolve-inconsistent-names.stderr | 87 +- src/test/ui/resolve/token-error-correct-3.rs | 1 - .../ui/resolve/token-error-correct-3.stderr | 19 +- .../ui/resolve/visibility-indeterminate.rs | 5 + .../resolve/visibility-indeterminate.stderr | 19 + src/test/ui/resolve_self_super_hint.rs | 2 - src/test/ui/resolve_self_super_hint.stderr | 8 +- .../resource-assign-is-not-copy.rs | 2 + .../{run-pass => ui}/resource-destruct.rs | 2 + .../result-opt-conversions.rs | 2 + src/test/{run-pass => ui}/ret-bang.rs | 2 + src/test/{run-pass => ui}/ret-none.rs | 2 + src/test/{run-pass => ui}/return-nil.rs | 1 + .../bind-by-move-no-guards.rs | 3 +- .../feature-gate.gate_and_2015.stderr | 2 +- .../feature-gate.gate_and_2018.stderr | 2 +- .../feature-gate.no_gate.stderr | 4 +- .../feature-gate.rs | 9 +- .../rfc-basic-examples.rs | 20 +- .../rfc-reject-double-move-across-arms.rs | 1 - .../rfc-reject-double-move-across-arms.stderr | 2 +- .../rfc-reject-double-move-in-first-arm.rs | 1 - ...rfc-reject-double-move-in-first-arm.stderr | 2 +- .../ui/rfc-2005-default-binding-mode/slice.rs | 2 +- .../ui/rfc-2008-non-exhaustive/struct.stderr | 2 + .../uninhabited/patterns.rs | 2 +- .../ui/rfc-2008-non-exhaustive/variant.stderr | 6 + .../variants_fictive_visibility.rs | 2 +- .../ui/rfc-2093-infer-outlives/issue-54467.rs | 2 +- .../not-whitelisted.rs | 2 +- .../not-whitelisted.stderr | 8 +- .../single-segment.rs | 2 +- .../single-segment.stderr | 2 +- .../ui/rfc-2166-underscore-imports/basic.rs | 2 +- .../rfc-2166-underscore-imports/duplicate.rs | 2 +- .../rfc-2166-underscore-imports/intercrate.rs | 2 +- .../ui/rfc-2306/convert-id-const-with-gate.rs | 2 +- .../ast-pretty-check.rs | 2 +- .../ast-pretty-check.stdout | 2 +- .../disallowed-positions.stderr | 26 +- .../feature-gate.stderr | 64 +- .../auxiliary/param-attrs.rs | 34 + .../param-attrs-allowed.rs | 179 +- .../param-attrs-builtin-attrs.rs | 16 +- .../param-attrs-builtin-attrs.stderr | 32 +- .../rfc-2565-param-attrs/param-attrs-cfg.rs | 40 +- .../param-attrs-cfg.stderr | 46 +- .../param-attrs-feature-gate.rs | 4 +- .../param-attrs-feature-gate.stderr | 14 +- .../param-attrs-pretty.rs | 56 + ...-hide-behind-direct-unsafe-ptr-embedded.rs | 24 + ...low-hide-behind-direct-unsafe-ptr-param.rs | 24 + ...ide-behind-indirect-unsafe-ptr-embedded.rs | 24 + ...w-hide-behind-indirect-unsafe-ptr-param.rs | 24 + .../allow-use-behind-cousin-variant.rs | 59 + ...cant-hide-behind-direct-struct-embedded.rs | 26 + ...-hide-behind-direct-struct-embedded.stderr | 8 + .../cant-hide-behind-direct-struct-param.rs | 26 + ...ant-hide-behind-direct-struct-param.stderr | 8 + ...nt-hide-behind-doubly-indirect-embedded.rs | 29 + ...ide-behind-doubly-indirect-embedded.stderr | 14 + .../cant-hide-behind-doubly-indirect-param.rs | 29 + ...t-hide-behind-doubly-indirect-param.stderr | 14 + ...nt-hide-behind-indirect-struct-embedded.rs | 29 + ...ide-behind-indirect-struct-embedded.stderr | 14 + .../cant-hide-behind-indirect-struct-param.rs | 29 + ...t-hide-behind-indirect-struct-param.stderr | 14 + .../ui/rfc1445/feature-gate.no_gate.stderr | 2 +- .../fn-ptr-is-structurally-matchable.rs | 135 + ...-61118-match-slice-forbidden-without-eq.rs | 19 + ...18-match-slice-forbidden-without-eq.stderr | 8 + ...2307-match-ref-ref-forbidden-without-eq.rs | 43 + ...-match-ref-ref-forbidden-without-eq.stderr | 23 + .../ui/rfc1445/issue-63479-match-fnptr.rs | 36 + ...ty-array-allowed-without-eq-issue-62336.rs | 17 + .../rfc1445/match-forbidden-without-eq.stderr | 2 +- ...tch-nonempty-array-forbidden-without-eq.rs | 19 + ...nonempty-array-forbidden-without-eq.stderr | 8 + .../collections.stderr | 2 + .../construct_with_other_type.stderr | 2 + .../empty_generics.stderr | 2 + .../gat-dont-ice-on-absent-feature.stderr | 2 +- .../gat-incomplete-warning.stderr | 2 + .../generic-associated-types-where.stderr | 2 + ...ssociated_type_undeclared_lifetimes.stderr | 2 + .../iterable.stderr | 2 + .../parameter_number_and_kind.stderr | 2 + .../parse/in-trait-impl.rs | 2 +- .../parse/in-trait.rs | 2 +- .../pointer_family.stderr | 2 + .../shadowing.rs | 2 +- .../shadowing.stderr | 2 + .../streaming_iterator.stderr | 2 + src/test/ui/rfc1717/missing-link-attr.stderr | 2 +- src/test/{run-pass => ui}/rfcs/rfc-1014-2.rs | 0 src/test/{run-pass => ui}/rfcs/rfc-1014.rs | 0 .../rfcs/rfc-1789-as-cell/from-mut.rs | 0 .../termination-trait-for-box-dyn-error.rs | 0 .../termination-trait-for-empty.rs | 0 .../termination-trait-for-exitcode.rs | 0 .../termination-trait-for-impl-termination.rs | 0 ...rmination-trait-for-result-box-error_ok.rs | 0 .../termination-trait-for-result.rs | 0 .../termination-trait-for-str.rs | 0 .../rfcs/rfc-2005-default-binding-mode/box.rs | 0 .../rfc-2005-default-binding-mode/constref.rs | 0 .../rfc-2005-default-binding-mode/enum.rs | 0 .../rfcs/rfc-2005-default-binding-mode/for.rs | 0 .../rfc-2005-default-binding-mode/general.rs | 0 .../rfcs/rfc-2005-default-binding-mode/lit.rs | 0 .../rfc-2005-default-binding-mode/range.rs | 0 .../ref-region.rs | 0 .../reset-mode.rs | 0 .../rfc-2005-default-binding-mode/slice.rs | 2 +- .../rfc-2005-default-binding-mode/struct.rs | 0 .../tuple-struct.rs | 0 .../rfc-2005-default-binding-mode/tuple.rs | 0 .../rfcs/rfc-2151-raw-identifiers/attr.rs | 0 .../rfcs/rfc-2151-raw-identifiers/basic.rs | 0 .../rfcs/rfc-2151-raw-identifiers/items.rs | 0 .../rfcs/rfc-2151-raw-identifiers/macros.rs | 2 +- .../rfcs/rfc-2175-or-if-while-let/basic.rs | 0 .../rfcs/rfc-2302-self-struct-ctor.rs | 0 ...-unreserve-pure-offsetof-sizeof-alignof.rs | 0 .../rfc1445/eq-allows-match-on-ty-in-macro.rs | 0 .../rfcs/rfc1445/eq-allows-match.rs | 0 src/test/{run-pass => ui}/rfcs/rfc1623.rs | 0 .../rfcs/rfc1717/auxiliary/clibrary.rs | 0 .../rfcs/rfc1717/library-override.rs | 0 .../rfcs/rfc1857-drop-order.rs | 0 src/test/ui/rmeta-lib-pass.rs | 2 +- src/test/ui/rmeta-pass.rs | 2 +- src/test/ui/rmeta-priv-warn.rs | 2 +- .../{run-pass/rmeta.rs => ui/rmeta-rpass.rs} | 3 +- .../running-with-no-runtime.rs | 1 + .../ui/rust-2018/async-ident-allowed.stderr | 2 +- .../ui/rust-2018/edition-lint-paths-2018.rs | 2 +- .../edition-lint-uninferable-outlives.rs | 2 +- .../extern-crate-idiomatic-in-2018.stderr | 2 +- ...54400-unused-extern-crate-attr-span.stderr | 2 +- .../ui/rust-2018/macro-use-warned-against.rs | 2 +- .../rust-2018/macro-use-warned-against.stderr | 2 +- .../ui/rust-2018/proc-macro-crate-in-paths.rs | 2 +- .../ui/rust-2018/remove-extern-crate.fixed | 2 +- src/test/ui/rust-2018/remove-extern-crate.rs | 2 +- .../ui/rust-2018/remove-extern-crate.stderr | 2 +- .../suggestions-not-always-applicable.fixed | 2 +- .../suggestions-not-always-applicable.rs | 2 +- .../suggestions-not-always-applicable.stderr | 2 +- src/test/ui/rust-2018/try-ident.fixed | 2 +- src/test/ui/rust-2018/try-ident.rs | 2 +- src/test/ui/rust-2018/try-ident.stderr | 2 +- src/test/ui/rust-2018/try-macro.fixed | 3 +- src/test/ui/rust-2018/try-macro.rs | 3 +- src/test/ui/rust-2018/try-macro.stderr | 4 +- .../ambiguity-macros-nested.stderr | 4 +- .../uniform-paths/ambiguity-macros.stderr | 4 +- .../uniform-paths/ambiguity-nested.stderr | 4 +- .../rust-2018/uniform-paths/ambiguity.stderr | 4 +- .../rust-2018/uniform-paths/fn-local-enum.rs | 2 +- .../uniform-paths/from-decl-macro.rs | 2 +- .../rust-2018/uniform-paths/issue-56596-2.rs | 2 +- .../uniform-paths/issue-56596.stderr | 4 +- .../rust-2018/uniform-paths/prelude-fail.rs | 7 +- .../uniform-paths/prelude-fail.stderr | 10 +- .../ui/rust-2018/uniform-paths/prelude.rs | 6 +- src/test/ui/rust-unstable-column-gated.rs | 2 +- src/test/ui/rust-unstable-column-gated.stderr | 7 +- src/test/{run-pass => ui}/rustc-rust-log.rs | 1 + .../rvalue-static-promotion.rs | 2 + src/test/ui/safe-extern-statics.stderr | 2 +- .../emit-notifications.polonius.stderr | 2 + .../ui/save-analysis/emit-notifications.rs | 4 +- .../segfault-no-out-of-stack.rs | 2 + src/test/ui/self/explicit-self-closures.rs | 2 +- src/test/ui/self/self-in-typedefs.rs | 2 +- src/test/ui/self/self-type-param.rs | 2 +- .../semistatement-in-lambda.rs | 2 + .../sepcomp/auxiliary/sepcomp-extern-lib.rs | 0 .../sepcomp/auxiliary/sepcomp_cci_lib.rs | 0 .../sepcomp/auxiliary/sepcomp_lib.rs | 0 .../{run-pass => ui}/sepcomp/sepcomp-cci.rs | 0 .../sepcomp/sepcomp-extern.rs | 0 .../sepcomp/sepcomp-fns-backwards.rs | 0 .../{run-pass => ui}/sepcomp/sepcomp-fns.rs | 0 .../sepcomp/sepcomp-lib-lto.rs | 0 .../{run-pass => ui}/sepcomp/sepcomp-lib.rs | 0 .../sepcomp/sepcomp-statics.rs | 0 .../sepcomp/sepcomp-unwind.rs | 0 src/test/{run-pass => ui}/seq-compare.rs | 2 + src/test/{run-pass => ui}/shadow.rs | 2 + .../shadowed-use-visibility.rs | 2 + src/test/{run-pass => ui}/shebang.rs | 4 +- .../signal-alternate-stack-cleanup.rs | 1 + .../{run-pass => ui}/signal-exit-status.rs | 1 + .../sigpipe-should-be-ignored.rs | 2 + .../simd-intrinsic-generic-reduction.rs | 22 +- .../simd-intrinsic-generic-reduction.stderr | 46 +- .../{run-pass => ui}/simd/simd-generics.rs | 0 .../simd/simd-intrinsic-float-math.rs | 0 .../simd/simd-intrinsic-float-minmax.rs | 0 ...intrinsic-generic-arithmetic-saturating.rs | 0 .../simd/simd-intrinsic-generic-arithmetic.rs | 0 .../simd/simd-intrinsic-generic-bitmask.rs | 0 .../simd/simd-intrinsic-generic-cast.rs | 0 .../simd/simd-intrinsic-generic-comparison.rs | 0 .../simd/simd-intrinsic-generic-elements.rs | 0 .../simd/simd-intrinsic-generic-gather.rs | 0 .../simd/simd-intrinsic-generic-reduction.rs | 10 +- .../simd/simd-intrinsic-generic-select.rs | 4 + .../{run-pass => ui}/simd/simd-size-align.rs | 0 .../simd/simd-target-feature-mixup.rs | 0 src/test/{run-pass => ui}/simd/simd-type.rs | 0 src/test/{run-pass => ui}/simple-infer.rs | 2 + .../{run-pass => ui}/simple_global_asm.rs | 2 + .../one-use-in-fn-argument.rs | 10 + .../one-use-in-fn-argument.stderr | 34 +- .../one-use-in-fn-return.rs | 2 +- .../single-use-lifetime/one-use-in-struct.rs | 2 +- .../two-uses-in-fn-argument-and-return.rs | 2 +- .../two-uses-in-fn-arguments.rs | 2 +- .../two-uses-in-inherent-impl-header.rs | 2 +- .../two-uses-in-trait-impl.rs | 2 +- src/test/{run-pass => ui}/size-and-align.rs | 2 + .../sized-borrowed-pointer.rs | 2 + .../{run-pass => ui}/sized-owned-pointer.rs | 2 + src/test/{run-pass => ui}/sleep.rs | 1 + .../{run-pass => ui}/slowparse-bstring.rs | 1 + src/test/{run-pass => ui}/slowparse-string.rs | 1 + .../ui/span/gated-features-attr-spans.stderr | 2 +- src/test/ui/span/issue-24690.rs | 2 +- src/test/ui/span/issue-24690.stderr | 4 +- src/test/ui/span/issue-27522.stderr | 2 +- src/test/ui/span/issue-36530.rs | 7 +- src/test/ui/span/issue-36530.stderr | 24 +- .../ui/span/issue-43927-non-ADT-derive.rs | 3 + .../ui/span/issue-43927-non-ADT-derive.stderr | 26 +- src/test/ui/span/issue-7575.stderr | 8 +- .../span/issue28498-reject-lifetime-param.rs | 5 +- .../issue28498-reject-lifetime-param.stderr | 2 +- .../ui/span/issue28498-reject-passed-to-fn.rs | 3 +- .../issue28498-reject-passed-to-fn.stderr | 2 +- .../ui/span/issue28498-reject-trait-bound.rs | 9 +- .../span/issue28498-reject-trait-bound.stderr | 2 +- src/test/ui/span/macro-span-replacement.rs | 2 +- .../ui/span/macro-span-replacement.stderr | 2 +- src/test/ui/span/multispan-import-lint.rs | 2 +- src/test/ui/span/multispan-import-lint.stderr | 2 +- .../unused-warning-point-at-signature.stderr | 2 +- src/test/ui/span/visibility-ty-params.stderr | 14 +- .../specialization/README-rpass.md} | 0 .../specialization/assoc-ty-graph-cycle.rs | 0 .../auxiliary/cross_crates_defaults.rs | 0 .../specialization/auxiliary/go_trait.rs | 0 .../auxiliary/specialization_cross_crate.rs | 0 .../specialization/cross-crate-defaults.rs | 0 .../defaultimpl/allowed-cross-crate.rs | 0 .../defaultimpl/auxiliary/go_trait.rs | 0 .../defaultimpl/out-of-order.rs | 0 .../defaultimpl/overlap-projection.rs | 0 .../specialization/defaultimpl/projection.rs | 0 ...specialization-feature-gate-default.stderr | 2 +- ...ation-trait-item-not-implemented-rpass.rs} | 0 src/test/ui/specialization/issue-36804.rs | 31 + .../specialization/issue-50452.rs | 0 .../specialization-allowed-cross-crate.rs | 0 .../specialization-assoc-fns.rs | 0 .../specialization/specialization-basics.rs | 0 .../specialization-cross-crate-no-gate.rs | 0 .../specialization-cross-crate.rs | 0 .../specialization-default-methods.rs | 0 ...specialization-feature-gate-default.stderr | 2 +- .../specialization-on-projection.rs | 0 .../specialization-out-of-order.rs | 0 .../specialization-overlap-projection.rs | 0 .../specialization-projection-alias.rs | 0 .../specialization-projection.rs | 0 .../specialization-super-traits.rs | 0 ...on-translate-projections-with-lifetimes.rs | 0 ...ation-translate-projections-with-params.rs | 0 .../specialization-translate-projections.rs | 0 src/test/{run-pass => ui}/sse2.rs | 1 + .../stability-attribute-issue.stderr | 4 +- src/test/{run-pass => ui}/stable-addr-of.rs | 1 + src/test/{run-pass => ui}/stack-probes-lto.rs | 1 + src/test/{run-pass => ui}/stack-probes.rs | 2 + src/test/ui/static/static-extern-type.rs | 2 +- src/test/ui/static_sized_requirement.rs | 2 +- .../auxiliary/static-function-pointer-aux.rs | 0 .../statics/auxiliary/static-methods-crate.rs | 0 .../auxiliary/static_fn_inline_xc_aux.rs | 0 .../auxiliary/static_fn_trait_xc_aux.rs | 0 .../statics/auxiliary/static_mut_xc.rs | 0 .../statics/static-fn-inline-xc.rs | 0 .../statics/static-fn-trait-xc.rs | 0 .../statics/static-function-pointer-xc.rs | 0 .../statics/static-function-pointer.rs | 0 .../{run-pass => ui}/statics/static-impl.rs | 0 ...tic-method-in-trait-with-tps-intracrate.rs | 0 .../statics/static-method-xcrate.rs | 0 .../statics/static-methods-in-traits.rs | 0 .../statics/static-methods-in-traits2.rs | 0 .../statics/static-mut-foreign.rs | 0 .../{run-pass => ui}/statics/static-mut-xc.rs | 0 .../statics/static-recursive.rs | 0 .../{run-pass => ui}/stdio-is-blocking.rs | 1 + src/test/ui/stmt_expr_attrs_no_feature.stderr | 18 +- src/test/{run-pass => ui}/str-concat.rs | 2 + src/test/{run-pass => ui}/str-multiline.rs | 2 + src/test/{run-pass => ui}/string-box-error.rs | 1 + src/test/{run-pass => ui}/string-escapes.rs | 2 + .../{run-pass => ui}/struct-ctor-mangling.rs | 2 + .../structs-enums/align-enum.rs | 0 .../structs-enums/align-struct.rs | 0 .../structs-enums/auxiliary/cci_class.rs | 0 .../structs-enums/auxiliary/cci_class_2.rs | 0 .../structs-enums/auxiliary/cci_class_3.rs | 0 .../structs-enums/auxiliary/cci_class_4.rs | 0 .../structs-enums/auxiliary/cci_class_6.rs | 0 .../structs-enums/auxiliary/cci_class_cast.rs | 0 .../auxiliary/cci_class_trait.rs | 0 .../structs-enums/auxiliary/empty-struct.rs | 0 .../auxiliary/namespaced_enum_emulate_flat.rs | 0 .../auxiliary/namespaced_enums.rs | 0 .../auxiliary/newtype_struct_xc.rs | 0 .../struct_destructuring_cross_crate.rs | 0 .../auxiliary/struct_variant_xc_aux.rs | 0 .../auxiliary/xcrate_struct_aliases.rs | 0 .../structs-enums/borrow-tuple-fields.rs | 0 .../class-cast-to-trait-cross-crate-2.rs | 0 .../class-cast-to-trait-multiple-types.rs | 0 .../structs-enums/class-cast-to-trait.rs | 0 .../structs-enums/class-dtor.rs | 0 .../structs-enums/class-exports.rs | 0 .../class-impl-very-parameterized-trait.rs | 0 .../class-implement-trait-cross-crate.rs | 0 .../structs-enums/class-implement-traits.rs | 0 .../structs-enums/class-method-cross-crate.rs | 0 .../class-methods-cross-crate.rs | 0 .../structs-enums/class-methods.rs | 0 .../class-poly-methods-cross-crate.rs | 0 .../structs-enums/class-poly-methods.rs | 0 .../structs-enums/class-separate-impl.rs | 0 .../structs-enums/class-str-field.rs | 0 .../structs-enums/class-typarams.rs | 0 .../structs-enums/classes-cross-crate.rs | 0 .../structs-enums/classes-self-referential.rs | 0 .../classes-simple-cross-crate.rs | 0 .../structs-enums/classes-simple-method.rs | 0 .../structs-enums/classes-simple.rs | 0 .../{run-pass => ui}/structs-enums/classes.rs | 0 .../codegen-tag-static-padding.rs | 0 .../structs-enums/compare-generic-enums.rs | 0 .../structs-enums/discrim-explicit-23030.rs | 0 .../structs-enums/empty-struct-braces.rs | 0 .../structs-enums/empty-tag.rs | 0 .../structs-enums/enum-alignment.rs | 0 .../structs-enums/enum-clike-ffi-as-int.rs | 0 .../structs-enums/enum-discr.rs | 0 .../structs-enums/enum-discrim-autosizing.rs | 0 .../enum-discrim-manual-sizing.rs | 0 .../enum-discrim-range-overflow.rs | 0 .../structs-enums/enum-discrim-width-stuff.rs | 0 .../structs-enums/enum-disr-val-pretty.rs | 0 .../structs-enums/enum-export-inheritance.rs | 0 .../structs-enums/enum-layout-optimization.rs | 0 .../enum-non-c-like-repr-c-and-int.rs | 1 + .../structs-enums/enum-non-c-like-repr-c.rs | 1 + .../structs-enums/enum-non-c-like-repr-int.rs | 1 + .../structs-enums/enum-null-pointer-opt.rs | 0 .../enum-nullable-const-null-with-fields.rs | 0 .../enum-nullable-simplifycfg-misopt.rs | 0 .../structs-enums/enum-univariant-repr.rs | 0 .../structs-enums/enum-variants.rs | 0 .../structs-enums/enum-vec-initializer.rs | 0 .../structs-enums/export-abstract-tag.rs | 0 .../structs-enums/export-tag-variant.rs | 0 .../structs-enums/expr-if-struct.rs | 0 .../structs-enums/expr-match-struct.rs | 0 .../structs-enums/field-destruction-order.rs | 0 .../structs-enums/foreign-struct.rs | 0 .../structs-enums/functional-struct-upd.rs | 0 .../structs-enums/ivec-tag.rs | 0 .../module-qualified-struct-destructure.rs | 0 .../namespaced-enum-emulate-flat-xc.rs | 0 .../namespaced-enum-emulate-flat.rs | 0 .../namespaced-enum-glob-import-xcrate.rs | 0 .../namespaced-enum-glob-import.rs | 0 .../structs-enums/namespaced-enums-xcrate.rs | 0 .../structs-enums/namespaced-enums.rs | 0 .../structs-enums/nested-enum-same-names.rs | 0 .../structs-enums/newtype-struct-drop-run.rs | 0 .../structs-enums/newtype-struct-with-dtor.rs | 0 .../structs-enums/newtype-struct-xc-2.rs | 0 .../structs-enums/newtype-struct-xc.rs | 0 .../structs-enums/nonzero-enum.rs | 0 .../structs-enums/numeric-fields.rs | 0 ...object-lifetime-default-from-ref-struct.rs | 0 ...bject-lifetime-default-from-rptr-struct.rs | 0 .../structs-enums/rec-align-u32.rs | 0 .../structs-enums/rec-align-u64.rs | 0 .../structs-enums/rec-auto.rs | 0 .../structs-enums/rec-extend.rs | 0 .../{run-pass => ui}/structs-enums/rec-tup.rs | 0 .../{run-pass => ui}/structs-enums/rec.rs | 0 .../structs-enums/record-pat.rs | 0 .../structs-enums/resource-in-struct.rs | 0 .../structs-enums/simple-generic-tag.rs | 0 .../structs-enums/simple-match-generic-tag.rs | 0 .../structs-enums/small-enum-range-edge.rs | 0 .../structs-enums/small-enums-with-fields.rs | 0 .../structs-enums/struct-aliases-xcrate.rs | 0 .../structs-enums/struct-aliases.rs | 0 .../struct-destructuring-cross-crate.rs | 0 .../structs-enums/struct-field-shorthand.rs | 0 .../struct-like-variant-construct.rs | 0 .../struct-like-variant-match.rs | 0 .../struct-lit-functional-no-fields.rs | 0 .../structs-enums/struct-literal-dtor.rs | 0 .../structs-enums/struct-new-as-field-name.rs | 0 .../structs-enums/struct-order-of-eval-1.rs | 0 .../structs-enums/struct-order-of-eval-2.rs | 0 .../structs-enums/struct-order-of-eval-3.rs | 0 .../structs-enums/struct-order-of-eval-4.rs | 0 .../structs-enums/struct-partial-move-1.rs | 0 .../structs-enums/struct-partial-move-2.rs | 0 .../struct-path-associated-type.rs | 0 .../structs-enums/struct-path-self.rs | 0 .../structs-enums/struct-pattern-matching.rs | 0 .../structs-enums/struct-return.rs | 0 .../struct-variant-field-visibility.rs | 0 .../structs-enums/struct_variant_xc.rs | 0 .../structs-enums/struct_variant_xc_match.rs | 0 .../structs-enums/tag-align-dyn-u64.rs | 0 .../structs-enums/tag-align-dyn-variants.rs | 0 .../structs-enums/tag-align-shape.rs | 0 .../structs-enums/tag-align-u64.rs | 0 .../structs-enums/tag-disr-val-shape.rs | 0 .../structs-enums/tag-exports.rs | 0 .../structs-enums/tag-in-block.rs | 0 .../tag-variant-disr-type-mismatch.rs | 0 .../structs-enums/tag-variant-disr-val.rs | 0 .../{run-pass => ui}/structs-enums/tag.rs | 0 .../structs-enums/tuple-struct-construct.rs | 0 .../tuple-struct-constructor-pointer.rs | 0 .../tuple-struct-destructuring.rs | 0 .../structs-enums/tuple-struct-matching.rs | 0 .../structs-enums/tuple-struct-trivial.rs | 0 .../structs-enums/uninstantiable-struct.rs | 0 .../unit-like-struct-drop-run.rs | 0 .../structs-enums/unit-like-struct.rs | 0 .../structs-enums/variant-structs-trivial.rs | 0 .../{run-pass => ui}/structured-compare.rs | 2 + src/test/ui/substs-ppaux.normal.stderr | 32 +- src/test/ui/substs-ppaux.verbose.stderr | 32 +- .../assoc-type-in-method-return.rs | 7 + .../assoc-type-in-method-return.stderr | 9 + src/test/ui/suggestions/attribute-typos.rs | 20 +- .../ui/suggestions/attribute-typos.stderr | 28 +- .../ui/suggestions/auxiliary/issue-61963-1.rs | 40 + .../ui/suggestions/auxiliary/issue-61963.rs | 41 + ...fn-or-tuple-struct-with-underscore-args.rs | 19 + ...r-tuple-struct-with-underscore-args.stderr | 38 + .../fn-or-tuple-struct-without-args.rs | 45 + .../fn-or-tuple-struct-without-args.stderr | 220 + src/test/ui/suggestions/issue-21673.rs | 13 + src/test/ui/suggestions/issue-21673.stderr | 27 + src/test/ui/suggestions/issue-57672.rs | 2 +- src/test/ui/suggestions/issue-61226.rs | 5 + src/test/ui/suggestions/issue-61226.stderr | 9 + src/test/ui/suggestions/issue-61963.rs | 24 + src/test/ui/suggestions/issue-61963.stderr | 14 + src/test/ui/suggestions/issue-62843.rs | 5 + src/test/ui/suggestions/issue-62843.stderr | 13 + .../ui/suggestions/suggest-variants.stderr | 4 +- .../type-ascription-instead-of-method.stderr | 7 +- .../type-ascription-instead-of-path.rs | 2 +- .../type-ascription-instead-of-path.stderr | 2 +- .../type-ascription-instead-of-variant.stderr | 7 +- .../ui/suggestions/vec-macro-in-pattern.fixed | 8 + .../ui/suggestions/vec-macro-in-pattern.rs | 8 + .../suggestions/vec-macro-in-pattern.stderr | 15 + .../super-fast-paren-parsing.rs | 2 + src/test/{run-pass => ui}/super.rs | 2 + src/test/{run-pass => ui}/supported-cast.rs | 2 + src/test/{run-pass => ui}/svh-add-nothing.rs | 1 + src/test/{run-pass => ui}/swap-1.rs | 2 + src/test/{run-pass => ui}/swap-2.rs | 2 + src/test/{run-pass => ui}/swap-overlapping.rs | 2 + .../syntax-trait-polarity-feature-gate.stderr | 2 +- .../{run-pass => ui}/tail-call-arg-leak.rs | 1 + src/test/{run-pass => ui}/tail-cps.rs | 2 + src/test/{run-pass => ui}/tail-direct.rs | 2 + src/test/ui/target-feature-gate.stderr | 2 +- src/test/ui/target-feature-wrong.rs | 4 +- src/test/ui/target-feature-wrong.stderr | 4 +- src/test/{run-pass => ui}/tcp-stress.rs | 1 + .../terminate-in-initializer.rs | 1 + ...est-allow-dead-extern-static-no-warning.rs | 1 + .../{run-pass => ui}/test-allow-fail-attr.rs | 1 + .../ui/test-attr-non-associated-functions.rs | 2 +- .../test-attr-non-associated-functions.stderr | 2 +- ...e-verification-for-explicit-return-type.rs | 2 + .../test-main-not-dead-attr.rs | 1 + .../{run-pass => ui}/test-main-not-dead.rs | 1 + src/test/ui/test-on-macro.rs | 2 +- src/test/ui/test-on-macro.stderr | 2 +- .../test-runner-hides-buried-main.rs | 1 + .../test-runner-hides-main.rs | 1 + .../test-runner-hides-start.rs | 1 + .../test-shadowing/test-cant-be-shadowed.rs | 2 +- .../test-should-fail-good-message.rs | 1 + src/test/ui/test-should-panic-attr.rs | 2 +- src/test/{run-pass => ui}/test-vs-cfg-test.rs | 1 + .../thin-lto-global-allocator.rs | 1 + .../{run-pass => ui}/thinlto/all-crates.rs | 0 .../thinlto/auxiliary/dylib.rs | 0 .../thinlto/auxiliary/msvc-imp-present.rs | 0 .../thinlto/auxiliary/thin-lto-inlines-aux.rs | 0 .../{run-pass => ui}/thinlto/dylib-works.rs | 0 .../thinlto/msvc-imp-present.rs | 0 .../thinlto/thin-lto-inlines.rs | 0 .../thinlto/thin-lto-inlines2.rs | 0 .../{run-pass => ui}/thinlto/weak-works.rs | 0 .../thread-local-not-in-prelude.rs | 2 + .../auxiliary/thread-local-extern-static.rs | 0 .../{run-pass => ui}/threads-sendsync/comm.rs | 0 .../send-is-not-static-par-for.rs | 0 .../threads-sendsync/send-resource.rs | 0 .../threads-sendsync/send-type-inference.rs | 0 .../threads-sendsync/send_str_hashmap.rs | 0 .../threads-sendsync/send_str_treemap.rs | 0 .../threads-sendsync/sendable-class.rs | 0 .../threads-sendsync/sendfn-is-a-block.rs | 0 .../sendfn-spawn-with-fn-arg.rs | 0 .../threads-sendsync/spawn-fn.rs | 0 .../threads-sendsync/spawn-types.rs | 0 .../threads-sendsync/spawn.rs | 0 .../threads-sendsync/spawn2.rs | 0 .../threads-sendsync/spawning-with-debug.rs | 0 .../std-sync-right-kind-impls.rs | 0 .../threads-sendsync/sync-send-atomics.rs | 0 .../threads-sendsync/sync-send-in-std.rs | 0 .../sync-send-iterators-in-libcollections.rs | 0 .../sync-send-iterators-in-libcore.rs | 0 .../threads-sendsync/task-comm-0.rs | 0 .../threads-sendsync/task-comm-1.rs | 0 .../threads-sendsync/task-comm-10.rs | 0 .../threads-sendsync/task-comm-11.rs | 0 .../threads-sendsync/task-comm-12.rs | 0 .../threads-sendsync/task-comm-13.rs | 0 .../threads-sendsync/task-comm-14.rs | 0 .../threads-sendsync/task-comm-15.rs | 0 .../threads-sendsync/task-comm-16.rs | 0 .../threads-sendsync/task-comm-17.rs | 0 .../threads-sendsync/task-comm-3.rs | 0 .../threads-sendsync/task-comm-4.rs | 0 .../threads-sendsync/task-comm-5.rs | 0 .../threads-sendsync/task-comm-6.rs | 0 .../threads-sendsync/task-comm-7.rs | 0 .../threads-sendsync/task-comm-9.rs | 0 .../threads-sendsync/task-comm-chan-nil.rs | 0 .../threads-sendsync/task-life-0.rs | 0 .../task-spawn-move-and-copy.rs | 0 .../threads-sendsync/task-stderr.rs | 0 .../thread-local-extern-static.rs | 0 .../threads-sendsync/thread-local-syntax.rs | 0 .../threads-sendsync/threads.rs | 0 .../tls-dtors-are-run-in-a-static-binary.rs | 0 .../threads-sendsync/tls-init-on-init.rs | 0 .../threads-sendsync/tls-try-with.rs | 0 .../tool-attributes-misplaced-1.rs | 2 +- .../tool-attributes-misplaced-1.stderr | 18 +- .../tool-attributes-misplaced-2.rs | 4 +- .../tool-attributes-misplaced-2.stderr | 8 +- src/test/{run-pass => ui}/tool_attributes.rs | 1 + .../tool_lints.rs => ui/tool_lints-rpass.rs} | 2 + .../tool_lints_2018_preview.rs | 2 + src/test/ui/trace_macros-gate.stderr | 24 +- src/test/{run-pass => ui}/trailing-comma.rs | 3 +- .../traits/anon-trait-static-method.rs | 0 .../traits/anon_trait_static_method_exe.rs | 0 .../traits/assignability-trait.rs | 0 .../astconv-cycle-between-trait-and-type.rs | 0 .../traits/augmented-assignments-trait.rs | 0 .../{run-pass => ui}/traits/auto-traits.rs | 0 .../auxiliary/anon_trait_static_method_lib.rs | 0 .../traits/auxiliary/go_trait.rs | 0 .../traits/auxiliary/trait_alias.rs | 0 .../auxiliary/trait_default_method_xc_aux.rs | 0 .../trait_default_method_xc_aux_2.rs | 0 .../trait_inheritance_auto_xc_2_aux.rs | 0 .../trait_inheritance_auto_xc_aux.rs | 0 .../trait_inheritance_overloading_xc.rs | 0 .../traits/auxiliary/trait_xc_call_aux.rs | 0 .../traits/auxiliary/traitimpl.rs | 0 src/test/ui/traits/conservative_impl_trait.rs | 2 +- .../traits/cycle-trait-type-trait.rs | 0 .../default-method-supertrait-vtable.rs | 0 src/test/{run-pass => ui}/traits/dyn-trait.rs | 0 .../traits/fmt-pointer-trait.rs | 0 .../traits/impl-implicit-trait.rs | 0 .../traits/impl-inherent-prefer-over-trait.rs | 0 .../infer-from-object-trait-issue-26952.rs | 0 .../traits/inherent-trait-method-order.rs | 0 .../traits/kindck-owned-trait-contains-1.rs | 0 .../traits/multiple-trait-bounds.rs | 0 .../traits/object-one-type-two-traits.rs | 0 ...overlap-permitted-for-marker-traits-neg.rs | 0 .../overlap-permitted-for-marker-traits.rs | 0 .../traits/parameterized-trait-with-bounds.rs | 0 .../traits/principal-less-trait-objects.rs | 1 + .../traits/supertrait-default-generics.rs | 0 .../traits/syntax-trait-polarity.rs | 0 .../ui/traits/trait-alias-ambiguous.stderr | 2 + .../traits/trait-alias-import-cross-crate.rs | 0 .../traits/trait-alias-import.rs | 2 + .../trait-alias/trait-alias-maybe-bound.rs | 2 +- .../traits/trait-bounds-basic.rs | 0 ...trait-bounds-impl-comparison-duplicates.rs | 0 .../traits/trait-bounds-in-arc.rs | 2 +- .../trait-bounds-not-on-bare-trait.stderr | 2 +- ...rait-bounds-on-structs-and-enums-rpass.rs} | 0 .../traits/trait-bounds-recursion.rs | 0 .../{run-pass => ui}/traits/trait-bounds.rs | 0 .../traits/trait-cache-issue-18209.rs | 0 .../traits/trait-coercion-generic.rs | 0 .../{run-pass => ui}/traits/trait-coercion.rs | 0 .../traits/trait-composition-trivial.rs | 0 .../traits/trait-copy-guessing.rs | 0 .../trait-default-method-bound-subst.rs | 0 .../trait-default-method-bound-subst2.rs | 0 .../trait-default-method-bound-subst3.rs | 0 .../trait-default-method-bound-subst4.rs | 0 .../traits/trait-default-method-bound.rs | 0 .../traits/trait-default-method-xc-2.rs | 0 .../traits/trait-default-method-xc.rs | 0 ...se-ambiguity-where-clause-builtin-bound.rs | 0 .../{run-pass => ui}/traits/trait-generic.rs | 0 .../{run-pass => ui}/traits/trait-impl-2.rs | 0 .../{run-pass => ui}/traits/trait-impl.rs | 0 .../traits/trait-inheritance-auto-xc-2.rs | 0 .../traits/trait-inheritance-auto-xc.rs | 0 .../traits/trait-inheritance-auto.rs | 0 .../trait-inheritance-call-bound-inherited.rs | 0 ...trait-inheritance-call-bound-inherited2.rs | 0 ...ritance-cast-without-call-to-supertrait.rs | 0 .../traits/trait-inheritance-cast.rs | 0 .../trait-inheritance-cross-trait-call-xc.rs | 0 .../trait-inheritance-cross-trait-call.rs | 0 .../traits/trait-inheritance-diamond.rs | 0 .../trait-inheritance-multiple-inheritors.rs | 0 .../trait-inheritance-multiple-params.rs | 0 .../traits/trait-inheritance-num.rs | 0 .../traits/trait-inheritance-num0.rs | 0 .../traits/trait-inheritance-num1.rs | 0 .../traits/trait-inheritance-num2.rs | 0 .../traits/trait-inheritance-num3.rs | 0 .../traits/trait-inheritance-num5.rs | 0 .../trait-inheritance-overloading-simple.rs | 0 .../trait-inheritance-overloading-xc-exe.rs | 0 .../traits/trait-inheritance-overloading.rs | 0 .../trait-inheritance-self-in-supertype.rs | 0 .../traits/trait-inheritance-self.rs | 0 .../traits/trait-inheritance-simple.rs | 0 .../traits/trait-inheritance-static.rs | 0 .../traits/trait-inheritance-static2.rs | 0 .../traits/trait-inheritance-subst.rs | 0 .../traits/trait-inheritance-subst2.rs | 0 .../traits/trait-inheritance-visibility.rs | 0 .../traits/trait-inheritance2.rs | 0 .../traits/trait-item-inside-macro.rs | 0 .../traits/trait-object-auto-dedup.rs | 0 .../traits/trait-object-exclusion.rs | 0 .../traits/trait-object-generics.rs | 0 .../traits/trait-object-lifetime-first.rs | 0 .../trait-object-with-lifetime-bound.rs | 0 ...ect-with-self-in-projection-output-good.rs | 2 +- ...n-projection-output-repeated-supertrait.rs | 2 +- src/test/ui/traits/trait-privacy.rs | 2 +- .../traits/trait-region-pointer-simple.rs | 0 .../traits/trait-safety-ok-cc.rs | 0 .../traits/trait-safety-ok.rs | 0 .../traits/trait-static-method-overwriting.rs | 0 .../{run-pass => ui}/traits/trait-to-str.rs | 0 .../traits/trait-where-clause-vs-impl.rs | 0 .../traits/trait-with-bounds-default.rs | 0 src/test/ui/traits/trait-with-dst.rs | 2 +- .../traits/traits-assoc-type-in-supertrait.rs | 0 .../traits/traits-conditional-dispatch.rs | 0 .../traits/traits-conditional-model-fn.rs | 0 .../traits/traits-default-method-macro.rs | 0 .../traits/traits-default-method-mut.rs | 0 .../traits/traits-default-method-self.rs | 0 .../traits/traits-default-method-trivial.rs | 0 .../traits/traits-elaborate-type-region.rs | 0 .../traits-impl-object-overlap-issue-23853.rs | 0 .../traits/traits-issue-22019.rs | 0 .../traits/traits-issue-22110.rs | 0 .../traits/traits-issue-22655.rs | 0 .../ui/traits/traits-issue-23003-overflow.rs | 2 +- .../traits/traits-issue-23003.rs | 0 .../traits/traits-issue-26339.rs | 0 ...aits-multidispatch-infer-convert-target.rs | 0 .../traits/traits-negative-impls-rpass.rs} | 0 .../traits/traits-repeated-supertrait.rs | 0 .../traits/ufcs-trait-object.rs | 0 .../traits/use-trait-before-def.rs | 0 .../transmute-non-immediate-to-immediate.rs | 1 + .../transmute-specialization.rs | 2 + .../ui/transmute/transmute-imut-to-mut.stderr | 2 +- .../trivial-bounds-inconsistent-copy.stderr | 2 +- ...vial-bounds-inconsistent-projection.stderr | 2 +- .../trivial-bounds-inconsistent-sized.stderr | 2 +- ...ial-bounds-inconsistent-well-formed.stderr | 2 +- .../trivial-bounds-inconsistent.stderr | 4 +- src/test/{run-pass => ui}/trivial-message.rs | 2 + .../trivial_casts-rpass.rs} | 1 + src/test/{run-pass => ui}/try-block.rs | 2 + .../try-from-int-error-partial-eq.rs | 2 + .../try-is-identifier-edition2015.rs | 2 + .../{run-pass => ui}/try-operator-custom.rs | 2 + .../{run-pass => ui}/try-operator-hygiene.rs | 2 + src/test/{run-pass => ui}/try-operator.rs | 2 + src/test/ui/try-poll.rs | 2 +- src/test/{run-pass => ui}/try-wait.rs | 2 + src/test/{run-pass => ui}/try_from.rs | 1 + src/test/{run-pass => ui}/tup.rs | 2 + .../{run-pass => ui}/tuple-index-fat-types.rs | 2 + src/test/{run-pass => ui}/tuple-index.rs | 2 + src/test/ui/tydesc-name.rs | 14 + ...ity-lint-ambiguous_associated_items.stderr | 4 +- .../type-alias-enum-variants/issue-57866.rs | 2 +- .../issue-61801-path-pattern-can-infer.rs | 2 +- ...63151-dead-code-lint-fields-in-patterns.rs | 26 + .../self-in-enum-definition.rs | 8 + .../self-in-enum-definition.stderr | 28 + .../associated-type-alias-impl-trait.rs} | 6 +- .../auxiliary/cross_crate_ice.rs | 11 + .../auxiliary/cross_crate_ice2.rs | 6 +- .../bound_reduction.rs | 6 +- .../bound_reduction2.rs | 4 +- .../bound_reduction2.stderr | 6 +- .../cross_crate_ice.rs | 2 +- .../cross_crate_ice2.rs | 2 +- .../declared_but_never_defined.rs | 6 + .../declared_but_never_defined.stderr | 4 +- .../declared_but_not_defined_in_scope.rs | 12 + .../declared_but_not_defined_in_scope.stderr | 4 +- .../different_defining_uses.rs | 4 +- .../different_defining_uses.stderr | 2 +- .../different_defining_uses_never_type.rs | 4 +- .../different_defining_uses_never_type.stderr | 4 +- .../different_defining_uses_never_type2.rs | 6 +- .../generic_different_defining_uses.rs | 4 +- .../generic_different_defining_uses.stderr | 2 +- .../generic_duplicate_lifetime_param.rs | 9 + .../generic_duplicate_lifetime_param.stderr | 8 +- .../generic_duplicate_param_use.rs | 6 +- .../generic_duplicate_param_use.stderr | 6 +- .../generic_duplicate_param_use10.rs | 12 + .../generic_duplicate_param_use2.rs | 6 +- .../generic_duplicate_param_use2.stderr | 2 +- .../generic_duplicate_param_use3.rs | 6 +- .../generic_duplicate_param_use3.stderr | 2 +- .../generic_duplicate_param_use4.rs | 6 +- .../generic_duplicate_param_use4.stderr | 2 +- .../generic_duplicate_param_use5.rs | 4 +- .../generic_duplicate_param_use5.stderr | 2 +- .../generic_duplicate_param_use6.rs | 4 +- .../generic_duplicate_param_use6.stderr | 2 +- .../generic_duplicate_param_use7.rs | 6 +- .../generic_duplicate_param_use8.rs | 4 +- .../generic_duplicate_param_use8.stderr | 2 +- .../generic_duplicate_param_use9.rs | 4 +- .../generic_duplicate_param_use9.stderr | 2 +- .../generic_lifetime_param.rs | 11 + .../generic_nondefining_use.rs | 6 +- .../generic_nondefining_use.stderr | 12 +- .../generic_not_used.rs | 4 +- .../generic_not_used.stderr | 8 +- ..._type_does_not_live_long_enough.nll.stderr | 6 +- .../generic_type_does_not_live_long_enough.rs | 4 +- ...eric_type_does_not_live_long_enough.stderr | 14 +- .../generic_underconstrained.rs | 4 +- .../generic_underconstrained.stderr | 10 +- .../generic_underconstrained2.rs | 6 +- .../generic_underconstrained2.stderr | 20 +- .../issue-52843-closure-constrain.rs | 13 + .../issue-52843-closure-constrain.stderr | 20 + .../ui/type-alias-impl-trait/issue-53096.rs | 9 + .../ui/type-alias-impl-trait/issue-53598.rs | 28 + .../type-alias-impl-trait/issue-53598.stderr | 12 + .../issue-53678-generator-and-const-fn.rs | 19 + .../ui/type-alias-impl-trait/issue-57700.rs | 22 + .../type-alias-impl-trait/issue-57700.stderr | 12 + .../ui/type-alias-impl-trait/issue-58887.rs | 23 + .../type-alias-impl-trait/issue-58887.stderr | 30 + .../ui/type-alias-impl-trait/issue-58951.rs | 13 + .../issue-60371.rs | 2 +- .../issue-60371.stderr | 18 +- .../ui/type-alias-impl-trait/issue-60407.rs | 15 + .../ui/type-alias-impl-trait/issue-60564.rs | 26 + .../type-alias-impl-trait/issue-60564.stderr | 25 + .../nested_type_alias_impl_trait.rs} | 8 +- .../never_reveal_concrete_type.rs | 4 +- .../never_reveal_concrete_type.stderr | 0 .../no_inferrable_concrete_type.rs | 13 + .../no_inferrable_concrete_type.stderr | 8 + .../no_revealing_outside_defining_module.rs | 4 +- ...o_revealing_outside_defining_module.stderr | 0 .../not_a_defining_use.rs | 6 +- .../not_a_defining_use.stderr | 4 +- .../not_well_formed.rs | 4 +- .../not_well_formed.stderr | 6 +- .../private_unused.rs | 2 +- .../type-alias-impl-trait-const.rs | 20 + .../type-alias-impl-trait-const.stderr | 8 + .../type-alias-impl-trait-fns.rs | 27 + .../type-alias-impl-trait-tuple.rs | 33 + .../type-alias-impl-trait-with-cycle-error.rs | 12 + ...e-alias-impl-trait-with-cycle-error.stderr | 8 + ...type-alias-impl-trait-with-cycle-error2.rs | 16 + ...-alias-impl-trait-with-cycle-error2.stderr | 8 + .../type-alias-impl-trait-with-no-traits.rs} | 4 +- ...pe-alias-impl-trait-with-no-traits.stderr} | 8 +- .../type-alias-impl-trait.rs} | 18 +- .../unused_generic_param.rs | 6 +- .../unused_generic_param.stderr | 14 + src/test/{run-pass => ui}/type-ascription.rs | 2 + .../{run-pass => ui}/type-id-higher-rank-2.rs | 1 + .../{run-pass => ui}/type-id-higher-rank.rs | 1 + .../{run-pass => ui}/type-in-nested-module.rs | 2 + .../type-infer-generalize-ty-var.rs | 2 + src/test/{run-pass => ui}/type-namespace.rs | 2 + .../type-param-constraints.rs | 2 + src/test/{run-pass => ui}/type-param.rs | 2 + .../type-params-in-for-each.rs | 2 + src/test/{run-pass => ui}/type-ptr.rs | 2 + src/test/{run-pass => ui}/type-sizes.rs | 2 + .../{run-pass => ui}/type-use-i1-versus-i8.rs | 1 + src/test/ui/type/ascription/issue-34255-1.rs | 15 + .../ui/type/ascription/issue-34255-1.stderr | 30 + src/test/ui/type/ascription/issue-47666.rs | 5 + .../ui/type/ascription/issue-47666.stderr | 17 + src/test/ui/type/ascription/issue-54516.rs | 6 + .../ui/type/ascription/issue-54516.stderr | 13 + src/test/ui/type/ascription/issue-60933.rs | 4 + .../ui/type/ascription/issue-60933.stderr | 13 + src/test/ui/type/type-alias-bounds.rs | 2 +- src/test/ui/type/type-alias-bounds.stderr | 2 +- ...e-ascription-instead-of-initializer.stderr | 2 +- ...ascription-instead-of-statement-end.stderr | 18 +- .../typeck-closure-to-unsafe-fn-ptr.rs | 2 + .../typeck-fn-to-unsafe-fn-ptr.rs | 1 + ...10-must-typeck-match-pats-before-guards.rs | 2 +- .../typeck_type_placeholder_item.stderr | 50 +- .../typeck_type_placeholder_item_help.rs | 29 + .../typeck_type_placeholder_item_help.stderr | 48 + .../typeck_type_placeholder_1.rs | 2 + .../typeclasses-eq-example-static.rs | 2 + .../typeclasses-eq-example.rs | 2 + src/test/{run-pass => ui}/typeid-intrinsic.rs | 20 +- .../{run-pass => ui}/typestate-cfg-nesting.rs | 2 + .../{run-pass => ui}/typestate-multi-decl.rs | 2 + .../ufcs-polymorphic-paths.rs | 2 + src/test/{run-pass => ui}/ufcs-type-params.rs | 1 + .../ui/ufcs/ufcs-explicit-self-bad.stderr | 6 +- .../unary-minus-suffix-inference.rs | 2 + .../auxiliary/unboxed-closures-cross-crate.rs | 0 .../unboxed-closure-feature-gate.stderr | 2 +- ...nboxed-closure-sugar-not-used-on-fn.stderr | 4 +- .../unboxed-closures-all-traits.rs | 0 .../unboxed-closures-blanket-fn-mut.rs | 0 .../unboxed-closures-blanket-fn.rs | 0 .../unboxed-closures-boxed.rs | 0 .../unboxed-closures-by-ref.rs | 0 .../unboxed-closures-call-fn-autoderef.rs | 0 .../unboxed-closures-call-sugar-autoderef.rs | 0 ...ed-closures-call-sugar-object-autoderef.rs | 0 .../unboxed-closures-call-sugar-object.rs | 0 .../unboxed-closures-counter-not-moved.rs | 0 .../unboxed-closures-cross-crate.rs | 0 .../unboxed-closures-direct-sugary-call.rs | 0 .../unboxed-closures/unboxed-closures-drop.rs | 0 .../unboxed-closures-extern-fn-hr.rs | 0 .../unboxed-closures-extern-fn.rs | 0 ...ures-failed-recursive-fn-1.polonius.stderr | 60 + ...unboxed-closures-fn-as-fnmut-and-fnonce.rs | 0 .../unboxed-closures-fnmut-as-fnonce.rs | 0 .../unboxed-closures-generic.rs | 0 ...res-infer-arg-types-from-expected-bound.rs | 0 ...fer-arg-types-from-expected-object-type.rs | 0 ...-types-w-bound-regs-from-expected-bound.rs | 0 ...oxed-closures-infer-explicit-call-early.rs | 0 ...oxed-closures-infer-fnmut-calling-fnmut.rs | 0 .../unboxed-closures-infer-fnmut-move.rs | 0 .../unboxed-closures-infer-fnmut.rs | 0 .../unboxed-closures-infer-fnonce-move.rs | 0 .../unboxed-closures-infer-fnonce.rs | 0 .../unboxed-closures-infer-kind.rs | 0 .../unboxed-closures-infer-recursive-fn.rs | 0 .../unboxed-closures-infer-upvar.rs | 0 .../unboxed-closures-manual-impl.rs | 0 .../unboxed-closures-monomorphization.rs | 0 ...osures-move-from-projection-issue-30046.rs | 0 .../unboxed-closures-move-mutable.rs | 0 ...ures-move-some-upvars-in-by-ref-closure.rs | 0 .../unboxed-closures-prelude.rs | 0 .../unboxed-closures-simple.rs | 0 .../unboxed-closures-single-word-env.rs | 0 .../unboxed-closures-static-call-fn-once.rs | 0 .../unboxed-closures-sugar-object.rs | 0 .../unboxed-closures-unique-type-id.rs | 0 .../unboxed-closures-zero-args.rs | 0 .../{run-pass => ui}/underscore-lifetimes.rs | 2 + .../underscore-method-after-integer.rs | 2 + .../uniform-paths/auxiliary/issue-53691.rs | 0 .../uniform-paths/basic-nested.rs | 0 .../{run-pass => ui}/uniform-paths/basic.rs | 0 .../uniform-paths/issue-53691.rs | 1 + .../uniform-paths/macros-nested.rs | 0 .../{run-pass => ui}/uniform-paths/macros.rs | 0 .../uniform-paths/same-crate.rs | 0 src/test/{run-pass => ui}/unify-return-ty.rs | 1 + .../exhaustive-wo-nevertype-issue-51221.rs | 9 + .../privately-uninhabited-dead-code.rs | 2 +- .../uninhabited-matches-feature-gated.rs | 2 + .../uninhabited-matches-feature-gated.stderr | 14 +- .../{run-pass => ui}/uninit-empty-types.rs | 2 + .../{run-pass => ui}/union/auxiliary/union.rs | 0 .../{run-pass => ui}/union/union-align.rs | 0 .../{run-pass => ui}/union/union-backcomp.rs | 0 .../{run-pass => ui}/union/union-basic.rs | 0 .../{run-pass => ui}/union/union-c-interop.rs | 0 .../union/union-const-codegen.rs | 0 .../union/union-const-eval-field.rs | 0 src/test/ui/union/union-const-eval.rs | 2 +- .../union/union-derive-rpass.rs} | 0 .../union/union-drop-assign.rs | 0 src/test/{run-pass => ui}/union/union-drop.rs | 0 .../union/union-generic-rpass.rs} | 0 .../union/union-inherent-method.rs | 0 .../{run-pass => ui}/union/union-macro.rs | 0 .../{run-pass => ui}/union/union-nodrop.rs | 0 .../{run-pass => ui}/union/union-nonzero.rs | 0 .../{run-pass => ui}/union/union-overwrite.rs | 0 .../{run-pass => ui}/union/union-packed.rs | 0 .../union/union-pat-refutability.rs | 0 .../union/union-trait-impl.rs | 0 .../{run-pass => ui}/union/union-transmute.rs | 0 .../union-with-drop-fields-lint-rpass.rs} | 0 .../unique/unique-assign-copy.rs | 0 .../unique/unique-assign-drop.rs | 0 .../unique/unique-assign-generic.rs | 0 .../{run-pass => ui}/unique/unique-assign.rs | 0 .../unique/unique-autoderef-field.rs | 0 .../unique/unique-autoderef-index.rs | 0 .../{run-pass => ui}/unique/unique-cmp.rs | 0 .../unique/unique-containing-tag.rs | 0 .../{run-pass => ui}/unique/unique-create.rs | 0 .../unique/unique-decl-init-copy.rs | 0 .../unique/unique-decl-init.rs | 0 .../unique/unique-decl-move.rs | 0 .../{run-pass => ui}/unique/unique-decl.rs | 0 .../{run-pass => ui}/unique/unique-deref.rs | 0 .../unique/unique-destructure.rs | 0 .../unique/unique-drop-complex.rs | 0 .../unique/unique-ffi-symbols.rs | 0 .../unique/unique-fn-arg-move.rs | 0 .../unique/unique-fn-arg-mut.rs | 0 .../{run-pass => ui}/unique/unique-fn-arg.rs | 0 .../{run-pass => ui}/unique/unique-fn-ret.rs | 0 .../unique/unique-generic-assign.rs | 0 .../{run-pass => ui}/unique/unique-in-tag.rs | 0 .../unique/unique-in-vec-copy.rs | 0 .../{run-pass => ui}/unique/unique-in-vec.rs | 0 .../{run-pass => ui}/unique/unique-init.rs | 0 .../{run-pass => ui}/unique/unique-kinds.rs | 0 .../{run-pass => ui}/unique/unique-log.rs | 0 .../unique/unique-match-discrim.rs | 0 .../unique/unique-move-drop.rs | 0 .../unique/unique-move-temp.rs | 0 .../{run-pass => ui}/unique/unique-move.rs | 0 .../{run-pass => ui}/unique/unique-mutable.rs | 0 .../unique/unique-object-move.rs | 0 .../{run-pass => ui}/unique/unique-pat-2.rs | 0 .../{run-pass => ui}/unique/unique-pat-3.rs | 0 .../{run-pass => ui}/unique/unique-pat.rs | 0 .../{run-pass => ui}/unique/unique-rec.rs | 0 .../{run-pass => ui}/unique/unique-send-2.rs | 0 .../{run-pass => ui}/unique/unique-send.rs | 0 .../{run-pass => ui}/unique/unique-swap.rs | 0 src/test/{run-pass => ui}/unit.rs | 2 + .../{run-pass => ui}/unnamed_argument_mode.rs | 1 + .../{run-pass => ui}/unreachable-code-1.rs | 2 + src/test/{run-pass => ui}/unreachable-code.rs | 2 + .../ui/unreachable/unreachable-try-pattern.rs | 2 +- src/test/ui/unresolved/unresolved-import.rs | 2 +- .../ui/unresolved/unresolved-import.stderr | 2 +- src/test/ui/unrestricted-attribute-tokens.rs | 2 +- src/test/{run-pass => ui}/unsafe-coercion.rs | 1 + .../unsafe-fn-called-from-unsafe-blk.rs | 2 + .../unsafe-fn-called-from-unsafe-fn.rs | 2 + .../unsafe-pointer-assignability.rs | 2 + src/test/ui/unsafe/ranged_ints2_const.stderr | 4 +- .../unsized-locals/autoderef.rs | 2 + .../unsized-locals/box-fnonce.rs | 2 + .../by-value-trait-object-safety-rpass.rs} | 2 + ...y-value-trait-object-safety-withdefault.rs | 2 + .../reference-unsized-locals.rs | 0 .../unsized-locals/simple-unsized-locals.rs | 0 .../unsized-locals/unsized-exprs-rpass.rs} | 0 src/test/ui/unsized-locals/unsized-index.rs | 2 +- .../unsized-locals/unsized-parameters.rs | 0 .../{run-pass => ui}/unsized-tuple-impls.rs | 2 + src/test/{run-pass => ui}/unsized.rs | 2 + src/test/{run-pass => ui}/unsized2.rs | 2 + .../unsized3.rs => ui/unsized3-rpass.rs} | 1 + .../{run-pass => ui}/unused-move-capture.rs | 1 + src/test/{run-pass => ui}/unused-move.rs | 1 + src/test/{run-pass => ui}/unwind-resource.rs | 2 + src/test/{run-pass => ui}/unwind-unique.rs | 1 + .../{run-pass => ui}/use-crate-name-alias.rs | 1 + .../{run-pass => ui}/use-import-export.rs | 1 + src/test/{run-pass => ui}/use-keyword-2.rs | 2 + src/test/{run-pass => ui}/use-mod.rs | 2 + .../{run-pass => ui}/use-nested-groups.rs | 2 + src/test/{run-pass => ui}/use.rs | 2 + src/test/ui/use/use-mod/use-mod-4.stderr | 2 +- src/test/{run-pass => ui}/use_inline_dtor.rs | 1 + src/test/ui/user-defined-macro-rules.rs | 10 +- src/test/ui/user-defined-macro-rules.stderr | 8 - .../using-target-feature-unstable.rs | 1 + src/test/{run-pass => ui}/utf8-bom.rs | 1 + src/test/{run-pass => ui}/utf8.rs | 2 + src/test/{run-pass => ui}/utf8_chars.rs | 2 + .../utf8_idents-rpass.rs} | 1 + src/test/ui/utf8_idents.stderr | 10 +- src/test/{run-pass => ui}/variadic-ffi.rs | 1 + ...ariance-intersection-of-ref-and-opt-ref.rs | 1 + .../variance-iterators-in-libcore.rs | 2 + .../variance-use-contravariant-struct-2.rs | 2 +- .../variance-use-covariant-struct-2.rs | 2 +- src/test/{run-pass => ui}/volatile-fat-ptr.rs | 2 + .../wait-forked-but-failed-child.rs | 2 + .../{run-pass => ui}/warn-ctypes-inhibit.rs | 2 + src/test/ui/wasm-import-module.stderr | 6 +- src/test/{run-pass => ui}/weak-lang-item.rs | 1 + .../weak-new-uninhabited-issue-48493.rs | 2 + src/test/{run-pass => ui}/weird-exit-code.rs | 1 + src/test/{run-pass => ui}/weird-exprs.rs | 2 + .../wf-bound-region-in-object-type.rs | 2 + .../auxiliary/where_clauses_xc.rs | 0 .../where-clause-bounds-inconsistency.rs | 0 .../where-clause-early-bound-lifetimes.rs | 0 .../where-clause-method-substituion-rpass.rs} | 0 .../where-clause-region-outlives.rs | 0 .../where-clauses-cross-crate.rs | 0 .../where-clauses/where-clauses-lifetimes.rs | 0 .../where-clauses/where-clauses-method.rs | 0 .../where-clauses-unboxed-closures.rs | 0 .../where-clauses/where-clauses.rs | 0 src/test/ui/while-let.stderr | 2 +- src/test/{run-pass => ui}/wrapping-int-api.rs | 1 + src/test/{run-pass => ui}/write-fmt-errors.rs | 2 + src/test/{run-pass => ui}/writealias.rs | 2 + .../wrong-hashset-issue-42918.rs | 1 + src/test/{run-pass => ui}/x86stdcall.rs | 2 + src/test/{run-pass => ui}/x86stdcall2.rs | 2 + src/test/{run-pass => ui}/yield.rs | 2 + src/test/{run-pass => ui}/yield1.rs | 2 + src/test/{run-pass => ui}/yield2.rs | 2 + src/test/{run-pass => ui}/z-crate-attr.rs | 1 + .../zero-sized/zero-size-type-destructors.rs | 0 .../zero-sized/zero-sized-binary-heap-push.rs | 0 .../zero-sized/zero-sized-btreemap-insert.rs | 0 .../zero-sized/zero-sized-linkedlist-push.rs | 0 .../zero-sized/zero-sized-tuple-struct.rs | 0 .../zero-sized/zero-sized-vec-deque-push.rs | 0 .../zero-sized/zero-sized-vec-push.rs | 0 src/tools/build-manifest/src/main.rs | 6 +- src/tools/cargotest/main.rs | 4 +- src/tools/compiletest/src/common.rs | 8 +- src/tools/compiletest/src/header.rs | 35 +- src/tools/compiletest/src/header/tests.rs | 27 + src/tools/compiletest/src/main.rs | 59 +- src/tools/compiletest/src/runtest.rs | 96 +- src/tools/compiletest/src/runtest/tests.rs | 61 + src/tools/compiletest/src/tests.rs | 51 + src/tools/compiletest/src/util.rs | 35 +- src/tools/compiletest/src/util/tests.rs | 32 + src/tools/error_index_generator/main.rs | 15 +- src/tools/linkchecker/main.rs | 2 - src/tools/publish_toolstate.py | 8 + src/tools/rust-installer/.travis.yml | 1 + src/tools/rust-installer/Cargo.toml | 4 +- src/tools/rust-installer/src/combiner.rs | 104 +- src/tools/rust-installer/src/generator.rs | 60 +- src/tools/rust-installer/src/lib.rs | 33 +- src/tools/rust-installer/src/main.rs | 43 +- .../rust-installer/src/remove_dir_all.rs | 378 +- src/tools/rust-installer/src/scripter.rs | 37 +- src/tools/rust-installer/src/tarballer.rs | 103 +- src/tools/rust-installer/src/util.rs | 93 +- src/tools/rustbook/Cargo.toml | 11 +- src/tools/rustbook/src/main.rs | 82 +- .../rustc-std-workspace-alloc/Cargo.toml | 1 + src/tools/rustc-std-workspace-core/lib.rs | 1 - src/tools/rustc-workspace-hack/Cargo.toml | 1 + src/tools/rustdoc-themes/main.rs | 2 - src/tools/rustdoc/main.rs | 2 - src/tools/tidy/src/deps.rs | 7 +- src/tools/tidy/src/edition.rs | 45 + src/tools/tidy/src/features.rs | 15 +- src/tools/tidy/src/features/tests.rs | 9 + src/tools/tidy/src/features/version.rs | 45 +- src/tools/tidy/src/features/version/tests.rs | 38 + src/tools/tidy/src/lib.rs | 23 +- src/tools/tidy/src/libcoretest.rs | 27 - src/tools/tidy/src/main.rs | 5 +- src/tools/tidy/src/style.rs | 16 +- src/tools/tidy/src/unit_tests.rs | 65 + src/tools/unstable-book-gen/src/main.rs | 5 - vendor/ammonia/.cargo-checksum.json | 2 +- vendor/ammonia/CHANGELOG.md | 4 + vendor/ammonia/Cargo.toml | 5 +- vendor/ammonia/examples/ammonia-cat.rs | 1 + vendor/ammonia/src/lib.rs | 2 +- vendor/annotate-snippets/.cargo-checksum.json | 2 +- vendor/annotate-snippets/CHANGELOG.md | 15 + vendor/annotate-snippets/Cargo.toml | 18 +- vendor/annotate-snippets/README.md | 17 +- .../examples/expected_type.rs | 4 +- vendor/annotate-snippets/examples/footer.rs | 4 +- vendor/annotate-snippets/examples/format.rs | 4 +- .../annotate-snippets/examples/multislice.rs | 4 +- .../src/display_list/structs.rs | 8 +- vendor/annotate-snippets/src/formatter/mod.rs | 46 +- .../annotate-snippets/src/formatter/style.rs | 4 +- vendor/annotate-snippets/src/lib.rs | 2 + .../src/stylesheets/color.rs | 4 +- .../src/stylesheets/no_color.rs | 4 +- vendor/annotate-snippets/tests/diff/mod.rs | 7 +- .../tests/dl_from_snippet.rs | 2 - vendor/annotate-snippets/tests/fixtures.rs | 9 +- vendor/annotate-snippets/tests/formatter.rs | 88 +- vendor/annotate-snippets/tests/snippet/mod.rs | 7 +- vendor/autocfg/.cargo-checksum.json | 1 - vendor/autocfg/README.md | 75 - vendor/autocfg/examples/integers.rs | 9 - vendor/autocfg/examples/paths.rs | 22 - vendor/autocfg/examples/traits.rs | 26 - vendor/autocfg/examples/versions.rs | 9 - vendor/autocfg/src/error.rs | 69 - vendor/autocfg/src/lib.rs | 305 - vendor/autocfg/src/tests.rs | 65 - vendor/autocfg/src/version.rs | 60 - vendor/backtrace-sys/.cargo-checksum.json | 2 +- vendor/backtrace-sys/Cargo.toml | 4 +- vendor/backtrace-sys/build.rs | 34 +- vendor/backtrace-sys/src/lib.rs | 66 +- vendor/backtrace/.cargo-checksum.json | 2 +- vendor/backtrace/Cargo.toml | 42 +- vendor/backtrace/azure-pipelines.yml | 3 + vendor/backtrace/build.rs | 13 - vendor/backtrace/ci/android-sdk.sh | 74 + vendor/backtrace/ci/azure-install-rust.yml | 14 +- vendor/backtrace/ci/azure-test-all.yml | 12 +- .../docker/arm-linux-androideabi/Dockerfile | 23 +- vendor/backtrace/ci/run-docker.sh | 2 +- vendor/backtrace/ci/runtest-android.rs | 50 + vendor/backtrace/src/backtrace/dbghelp.rs | 8 +- vendor/backtrace/src/backtrace/libunwind.rs | 7 +- vendor/backtrace/src/backtrace/mod.rs | 8 +- vendor/backtrace/src/backtrace/noop.rs | 2 +- .../backtrace/src/backtrace/unix_backtrace.rs | 3 +- vendor/backtrace/src/capture.rs | 62 +- vendor/backtrace/src/dbghelp.rs | 82 +- vendor/backtrace/src/lib.rs | 54 +- .../src/symbolize/coresymbolication.rs | 19 +- vendor/backtrace/src/symbolize/dbghelp.rs | 44 +- vendor/backtrace/src/symbolize/dladdr.rs | 45 +- .../backtrace/src/symbolize/dladdr_resolve.rs | 13 +- vendor/backtrace/src/symbolize/gimli.rs | 551 +- .../backtrace/src/symbolize/libbacktrace.rs | 39 +- vendor/backtrace/src/symbolize/mod.rs | 98 +- vendor/backtrace/src/symbolize/noop.rs | 17 +- vendor/backtrace/src/types.rs | 7 +- vendor/backtrace/src/windows.rs | 2 +- vendor/backtrace/tests/accuracy/auxiliary.rs | 11 +- vendor/backtrace/tests/accuracy/main.rs | 8 +- vendor/backtrace/tests/long_fn_name.rs | 4 +- vendor/backtrace/tests/smoke.rs | 3 +- vendor/bitflags/.cargo-checksum.json | 2 +- vendor/bitflags/CHANGELOG.md | 242 +- vendor/bitflags/CODE_OF_CONDUCT.md | 144 +- vendor/bitflags/Cargo.toml | 5 +- vendor/bitflags/LICENSE-APACHE | 402 +- vendor/bitflags/LICENSE-MIT | 50 +- vendor/bitflags/README.md | 68 +- vendor/bitflags/build.rs | 44 + vendor/bitflags/src/example_generated.rs | 28 +- vendor/bitflags/src/lib.rs | 2582 +++--- vendor/c2-chacha/.cargo-checksum.json | 1 + vendor/c2-chacha/Cargo.toml | 49 + vendor/c2-chacha/LICENSE-APACHE | 201 + vendor/c2-chacha/LICENSE-MIT | 25 + vendor/c2-chacha/README.md | 24 + vendor/c2-chacha/benches/chacha20.rs | 20 + vendor/c2-chacha/benches/machine.rs | 39 + vendor/c2-chacha/src/guts.rs | 299 + vendor/c2-chacha/src/lib.rs | 49 + vendor/c2-chacha/src/rustcrypto_impl.rs | 548 ++ vendor/compiler_builtins/.cargo-checksum.json | 2 +- vendor/compiler_builtins/Cargo.lock | 23 + vendor/compiler_builtins/Cargo.toml | 2 +- .../compiler_builtins/examples/intrinsics.rs | 4 +- vendor/compiler_builtins/src/arm.rs | 9 +- vendor/compiler_builtins/src/int/addsub.rs | 37 +- vendor/compiler_builtins/src/int/mul.rs | 17 +- vendor/compiler_builtins/src/int/sdiv.rs | 11 - vendor/compiler_builtins/src/int/shift.rs | 40 +- vendor/compiler_builtins/src/int/udiv.rs | 11 - vendor/compiler_builtins/src/macros.rs | 14 - vendor/crossbeam-deque/.cargo-checksum.json | 1 + vendor/crossbeam-deque/CHANGELOG.md | 71 + vendor/crossbeam-deque/Cargo.toml | 31 + .../LICENSE-APACHE | 0 .../{autocfg => crossbeam-deque}/LICENSE-MIT | 2 - vendor/crossbeam-deque/README.md | 51 + vendor/crossbeam-deque/src/lib.rs | 879 ++ vendor/crossbeam-deque/tests/fifo.rs | 371 + vendor/crossbeam-deque/tests/lifo.rs | 371 + vendor/crossbeam-epoch/.cargo-checksum.json | 1 + vendor/crossbeam-epoch/CHANGELOG.md | 81 + vendor/crossbeam-epoch/Cargo.lock | 262 + vendor/crossbeam-epoch/Cargo.toml | 54 + .../LICENSE-APACHE | 0 vendor/crossbeam-epoch/LICENSE-MIT | 27 + vendor/crossbeam-epoch/README.md | 53 + vendor/crossbeam-epoch/benches/defer.rs | 71 + vendor/crossbeam-epoch/benches/flush.rs | 53 + vendor/crossbeam-epoch/benches/pin.rs | 32 + vendor/crossbeam-epoch/examples/sanitize.rs | 69 + .../crossbeam-epoch/examples/treiber_stack.rs | 110 + vendor/crossbeam-epoch/src/atomic.rs | 1201 +++ vendor/crossbeam-epoch/src/collector.rs | 434 + vendor/crossbeam-epoch/src/default.rs | 75 + vendor/crossbeam-epoch/src/deferred.rs | 134 + vendor/crossbeam-epoch/src/epoch.rs | 114 + vendor/crossbeam-epoch/src/guard.rs | 527 ++ vendor/crossbeam-epoch/src/internal.rs | 552 ++ vendor/crossbeam-epoch/src/lib.rs | 111 + vendor/crossbeam-epoch/src/sync/list.rs | 478 ++ vendor/crossbeam-epoch/src/sync/mod.rs | 4 + vendor/crossbeam-epoch/src/sync/queue.rs | 441 + vendor/crossbeam-queue/.cargo-checksum.json | 1 + vendor/crossbeam-queue/CHANGELOG.md | 11 + .../Cargo.toml | 22 +- .../{idna => crossbeam-queue}/LICENSE-APACHE | 0 .../LICENSE-MIT | 2 - vendor/crossbeam-queue/LICENSE-THIRD-PARTY | 31 + vendor/crossbeam-queue/README.md | 66 + vendor/crossbeam-queue/src/array_queue.rs | 425 + vendor/crossbeam-queue/src/err.rs | 46 + vendor/crossbeam-queue/src/lib.rs | 22 + vendor/crossbeam-queue/src/seg_queue.rs | 481 ++ vendor/crossbeam-queue/tests/array_queue.rs | 249 + vendor/crossbeam-queue/tests/seg_queue.rs | 164 + vendor/crossbeam-utils/.cargo-checksum.json | 1 + vendor/crossbeam-utils/CHANGELOG.md | 89 + vendor/crossbeam-utils/Cargo.toml | 37 + .../LICENSE-APACHE | 0 vendor/crossbeam-utils/LICENSE-MIT | 23 + vendor/crossbeam-utils/README.md | 72 + vendor/crossbeam-utils/benches/atomic_cell.rs | 159 + .../crossbeam-utils/src/atomic/atomic_cell.rs | 924 +++ vendor/crossbeam-utils/src/atomic/consume.rs | 82 + vendor/crossbeam-utils/src/atomic/mod.rs | 7 + vendor/crossbeam-utils/src/backoff.rs | 294 + vendor/crossbeam-utils/src/cache_padded.rs | 116 + vendor/crossbeam-utils/src/lib.rs | 67 + vendor/crossbeam-utils/src/sync/mod.rs | 17 + vendor/crossbeam-utils/src/sync/parker.rs | 311 + .../crossbeam-utils/src/sync/sharded_lock.rs | 600 ++ vendor/crossbeam-utils/src/sync/wait_group.rs | 139 + vendor/crossbeam-utils/src/thread.rs | 529 ++ vendor/crossbeam-utils/tests/atomic_cell.rs | 208 + vendor/crossbeam-utils/tests/cache_padded.rs | 112 + vendor/crossbeam-utils/tests/parker.rs | 42 + vendor/crossbeam-utils/tests/sharded_lock.rs | 245 + vendor/crossbeam-utils/tests/thread.rs | 175 + vendor/crossbeam-utils/tests/wait_group.rs | 66 + vendor/fuchsia-cprng/.cargo-checksum.json | 1 - vendor/fuchsia-cprng/AUTHORS | 10 - vendor/fuchsia-cprng/LICENSE | 27 - vendor/fuchsia-cprng/PATENTS | 22 - vendor/fuchsia-cprng/src/lib.rs | 57 - vendor/getrandom/.cargo-checksum.json | 1 + vendor/getrandom/CHANGELOG.md | 97 + vendor/getrandom/Cargo.toml | 46 + vendor/getrandom/LICENSE-APACHE | 201 + vendor/{rand-0.4.6 => getrandom}/LICENSE-MIT | 1 + vendor/getrandom/README.md | 67 + vendor/getrandom/benches/mod.rs | 23 + vendor/getrandom/src/cloudabi.rs | 25 + vendor/getrandom/src/dummy.rs | 14 + vendor/getrandom/src/error.rs | 166 + vendor/getrandom/src/error_impls.rs | 35 + vendor/getrandom/src/freebsd.rs | 45 + vendor/getrandom/src/fuchsia.rs | 20 + vendor/getrandom/src/ios.rs | 31 + vendor/getrandom/src/lib.rs | 256 + vendor/getrandom/src/linux_android.rs | 44 + vendor/getrandom/src/macos.rs | 34 + vendor/getrandom/src/openbsd.rs | 23 + vendor/getrandom/src/rdrand.rs | 90 + vendor/getrandom/src/solaris_illumos.rs | 44 + vendor/getrandom/src/use_file.rs | 58 + vendor/getrandom/src/util.rs | 96 + vendor/getrandom/src/util_libc.rs | 118 + vendor/getrandom/src/wasi.rs | 22 + vendor/getrandom/src/wasm32_bindgen.rs | 129 + vendor/getrandom/src/wasm32_stdweb.rs | 114 + vendor/getrandom/src/windows.rs | 26 + vendor/getrandom/tests/mod.rs | 61 + vendor/handlebars/.cargo-checksum.json | 2 +- vendor/handlebars/CHANGELOG.md | 40 +- vendor/handlebars/Cargo.lock | 548 ++ vendor/handlebars/Cargo.toml | 17 +- vendor/handlebars/README.md | 19 +- vendor/handlebars/benches/bench.rs | 3 +- vendor/handlebars/examples/decorator.rs | 8 +- vendor/handlebars/examples/error.rs | 2 +- vendor/handlebars/examples/partials.rs | 2 +- vendor/handlebars/examples/quick.rs | 2 +- vendor/handlebars/examples/render-cli.rs | 3 +- vendor/handlebars/examples/render.rs | 6 +- vendor/handlebars/examples/render_file.rs | 6 +- vendor/handlebars/rustfmt.toml | 1 - vendor/handlebars/src/context.rs | 331 +- vendor/handlebars/src/directives/inline.rs | 23 +- vendor/handlebars/src/directives/mod.rs | 34 +- vendor/handlebars/src/error.rs | 18 +- vendor/handlebars/src/grammar.pest | 9 +- vendor/handlebars/src/grammar.rs | 25 +- .../handlebars/src/helpers/helper_boolean.rs | 14 +- vendor/handlebars/src/helpers/helper_each.rs | 223 +- vendor/handlebars/src/helpers/helper_if.rs | 64 +- vendor/handlebars/src/helpers/helper_log.rs | 33 +- .../handlebars/src/helpers/helper_lookup.rs | 50 +- vendor/handlebars/src/helpers/helper_raw.rs | 24 +- vendor/handlebars/src/helpers/helper_with.rs | 161 +- vendor/handlebars/src/helpers/mod.rs | 72 +- vendor/handlebars/src/lib.rs | 18 +- vendor/handlebars/src/macros.rs | 27 +- vendor/handlebars/src/partial.rs | 175 +- vendor/handlebars/src/registry.rs | 187 +- vendor/handlebars/src/render.rs | 435 +- vendor/handlebars/src/support.rs | 2 +- vendor/handlebars/src/template.rs | 197 +- vendor/handlebars/src/value.rs | 85 +- vendor/handlebars/tests/block_context.rs | 76 + vendor/hashbrown-0.4.0/.cargo-checksum.json | 1 + vendor/hashbrown-0.4.0/CHANGELOG.md | 128 + vendor/hashbrown-0.4.0/Cargo.toml | 65 + .../LICENSE-APACHE | 0 vendor/hashbrown-0.4.0/LICENSE-MIT | 25 + vendor/hashbrown-0.4.0/README.md | 87 + vendor/hashbrown-0.4.0/benches/bench.rs | 150 + vendor/hashbrown-0.4.0/clippy.toml | 1 + .../src/external_trait_impls/mod.rs | 4 + .../src/external_trait_impls/rayon/helpers.rs | 26 + .../src/external_trait_impls/rayon/map.rs | 676 ++ .../src/external_trait_impls/rayon/mod.rs | 5 + .../src/external_trait_impls/rayon/raw.rs | 193 + .../src/external_trait_impls/rayon/set.rs | 646 ++ .../src/external_trait_impls/serde.rs | 200 + vendor/hashbrown-0.4.0/src/fx.rs | 119 + vendor/hashbrown-0.4.0/src/lib.rs | 93 + vendor/hashbrown-0.4.0/src/macros.rs | 54 + vendor/hashbrown-0.4.0/src/map.rs | 3566 ++++++++ vendor/hashbrown-0.4.0/src/raw/bitmask.rs | 108 + vendor/hashbrown-0.4.0/src/raw/generic.rs | 157 + vendor/hashbrown-0.4.0/src/raw/mod.rs | 1374 ++++ vendor/hashbrown-0.4.0/src/raw/sse2.rs | 140 + vendor/hashbrown-0.4.0/src/rustc_entry.rs | 573 ++ vendor/hashbrown-0.4.0/src/scopeguard.rs | 49 + vendor/hashbrown-0.4.0/src/set.rs | 1829 +++++ vendor/hashbrown-0.4.0/tests/hasher.rs | 65 + vendor/hashbrown-0.4.0/tests/rayon.rs | 533 ++ vendor/hashbrown-0.4.0/tests/serde.rs | 59 + vendor/hashbrown-0.4.0/tests/set.rs | 31 + vendor/hashbrown/.cargo-checksum.json | 2 +- vendor/hashbrown/CHANGELOG.md | 9 + vendor/hashbrown/Cargo.toml | 2 +- vendor/hashbrown/README.md | 9 +- vendor/hashbrown/benches/bench.rs | 286 +- vendor/hashbrown/src/lib.rs | 7 +- vendor/hashbrown/src/map.rs | 4 +- vendor/hashbrown/src/raw/mod.rs | 17 +- .../{idna => idna-0.1.5}/.cargo-checksum.json | 0 vendor/{idna => idna-0.1.5}/Cargo.toml | 0 vendor/{url => idna-0.1.5}/LICENSE-APACHE | 0 vendor/{idna => idna-0.1.5}/LICENSE-MIT | 0 .../src/IdnaMappingTable.txt | 0 vendor/{idna => idna-0.1.5}/src/lib.rs | 0 .../src/make_uts46_mapping_table.py | 0 vendor/{idna => idna-0.1.5}/src/punycode.rs | 0 vendor/{idna => idna-0.1.5}/src/uts46.rs | 0 .../src/uts46_mapping_table.rs | 0 .../{idna => idna-0.1.5}/tests/IdnaTest.txt | 0 vendor/{idna => idna-0.1.5}/tests/punycode.rs | 0 .../tests/punycode_tests.json | 0 vendor/{idna => idna-0.1.5}/tests/tests.rs | 0 vendor/{idna => idna-0.1.5}/tests/unit.rs | 0 vendor/{idna => idna-0.1.5}/tests/uts46.rs | 0 vendor/jobserver/.cargo-checksum.json | 2 +- vendor/jobserver/Cargo.toml | 10 +- vendor/jobserver/src/lib.rs | 308 +- vendor/libc/.cargo-checksum.json | 2 +- vendor/libc/Cargo.toml | 7 +- vendor/libc/README.md | 6 +- vendor/libc/build.rs | 46 +- vendor/libc/src/cloudabi/mod.rs | 9 - vendor/libc/src/fixed_width_ints.rs | 44 + vendor/libc/src/fuchsia/aarch64.rs | 270 - vendor/libc/src/fuchsia/mod.rs | 277 +- vendor/libc/src/fuchsia/x86_64.rs | 339 - vendor/libc/src/hermit/mod.rs | 9 - vendor/libc/src/lib.rs | 29 +- vendor/libc/src/macros.rs | 38 + vendor/libc/src/redox/align.rs | 6 - vendor/libc/src/redox/mod.rs | 416 - vendor/libc/src/redox/net.rs | 117 - vendor/libc/src/redox/no_align.rs | 6 - vendor/libc/src/sgx.rs | 9 - vendor/libc/src/switch.rs | 9 - vendor/libc/src/unix/bsd/apple/b32.rs | 4 +- vendor/libc/src/unix/bsd/apple/b64.rs | 4 +- vendor/libc/src/unix/bsd/apple/mod.rs | 613 +- .../unix/bsd/freebsdlike/dragonfly/errno.rs | 12 + .../src/unix/bsd/freebsdlike/dragonfly/mod.rs | 193 +- .../unix/bsd/freebsdlike/freebsd/aarch64.rs | 4 +- .../src/unix/bsd/freebsdlike/freebsd/arm.rs | 4 +- .../bsd/freebsdlike/freebsd/freebsd11/mod.rs | 214 + .../freebsdlike/freebsd/freebsd11/x86_64.rs | 30 + .../bsd/freebsdlike/freebsd/freebsd12/mod.rs | 207 + .../freebsdlike/freebsd/freebsd12/x86_64.rs | 32 + .../src/unix/bsd/freebsdlike/freebsd/mod.rs | 429 +- .../unix/bsd/freebsdlike/freebsd/powerpc64.rs | 4 +- .../src/unix/bsd/freebsdlike/freebsd/x86.rs | 4 +- .../unix/bsd/freebsdlike/freebsd/x86_64.rs | 26 - vendor/libc/src/unix/bsd/freebsdlike/mod.rs | 45 +- vendor/libc/src/unix/bsd/mod.rs | 30 +- vendor/libc/src/unix/bsd/netbsdlike/mod.rs | 13 +- .../src/unix/bsd/netbsdlike/netbsd/mod.rs | 204 +- .../{openbsdlike => }/openbsd/aarch64.rs | 0 .../{openbsdlike => openbsd}/mod.rs | 616 +- .../{openbsdlike => }/openbsd/x86.rs | 0 .../{openbsdlike => }/openbsd/x86_64.rs | 0 .../bsd/netbsdlike/openbsdlike/bitrig/mod.rs | 129 - .../bsd/netbsdlike/openbsdlike/bitrig/x86.rs | 2 - .../netbsdlike/openbsdlike/bitrig/x86_64.rs | 10 - .../bsd/netbsdlike/openbsdlike/openbsd/mod.rs | 497 -- vendor/libc/src/unix/haiku/mod.rs | 81 +- vendor/libc/src/unix/hermit/mod.rs | 7 + .../{notbsd => linux_like}/android/b32/arm.rs | 0 .../{notbsd => linux_like}/android/b32/mod.rs | 63 +- .../{notbsd => linux_like}/android/b32/x86.rs | 0 .../android/b64/aarch64.rs | 14 +- .../{notbsd => linux_like}/android/b64/mod.rs | 39 +- .../android/b64/x86_64.rs | 24 +- .../{notbsd => linux_like}/android/mod.rs | 275 +- .../emscripten/align.rs | 0 .../{notbsd => linux_like}/emscripten/mod.rs | 157 +- .../emscripten/no_align.rs | 0 .../{notbsd => linux_like}/linux/align.rs | 6 +- .../mips => linux_like/linux/gnu}/align.rs | 0 .../other => linux_like/linux/gnu}/b32/arm.rs | 276 +- .../linux/gnu/b32/mips.rs} | 590 +- .../other => linux_like/linux/gnu}/b32/mod.rs | 191 +- .../linux/gnu}/b32/powerpc.rs | 280 +- .../other => linux_like/linux/gnu}/b32/x86.rs | 274 +- .../linux/gnu}/b64/aarch64.rs | 134 +- .../linux/gnu/b64}/mips64.rs | 563 +- .../other => linux_like/linux/gnu}/b64/mod.rs | 19 +- .../linux/gnu}/b64/powerpc64.rs | 137 +- .../linux/gnu/b64/s390x.rs} | 548 +- .../linux/gnu}/b64/sparc64.rs | 127 +- .../linux/gnu/b64/x86_64/mod.rs} | 145 +- .../linux/gnu/b64/x86_64}/not_x32.rs | 1 + .../linux/gnu/b64/x86_64}/x32.rs | 1 + .../other => linux_like/linux/gnu}/mod.rs | 342 +- .../mips => linux_like/linux/gnu}/no_align.rs | 0 .../unix/{notbsd => linux_like}/linux/mod.rs | 519 +- .../linux/musl/b32/arm.rs | 26 +- .../linux/musl/b32/mips.rs | 27 +- .../linux/musl/b32/mod.rs | 0 .../linux/musl/b32/powerpc.rs | 24 +- .../linux/musl/b32/x86.rs | 26 +- .../linux/musl/b64/aarch64.rs | 14 +- .../linux/musl/b64/mod.rs | 19 +- .../linux/musl/b64/powerpc64.rs | 7 +- .../linux/musl/b64/x86_64.rs | 12 +- .../{notbsd => linux_like}/linux/musl/mod.rs | 74 +- .../{notbsd => linux_like}/linux/no_align.rs | 0 .../src/unix/{notbsd => linux_like}/mod.rs | 119 +- vendor/libc/src/unix/mod.rs | 105 +- vendor/libc/src/unix/newlib/mod.rs | 78 +- vendor/libc/src/unix/notbsd/linux/mips/mod.rs | 960 --- .../libc/src/unix/notbsd/linux/other/align.rs | 13 - .../src/unix/notbsd/linux/other/no_align.rs | 10 - .../libc/src/unix/notbsd/linux/s390x/align.rs | 10 - .../src/unix/notbsd/linux/s390x/no_align.rs | 7 - vendor/libc/src/unix/redox/mod.rs | 597 ++ vendor/libc/src/unix/solarish/mod.rs | 140 +- vendor/libc/src/unix/uclibc/arm/mod.rs | 412 +- .../libc/src/unix/uclibc/mips/mips32/mod.rs | 8 - vendor/libc/src/unix/uclibc/mips/mod.rs | 19 +- vendor/libc/src/unix/uclibc/mod.rs | 228 +- vendor/libc/src/wasi.rs | 29 +- vendor/libc/src/windows/mod.rs | 9 - vendor/lzma-sys/.cargo-checksum.json | 2 +- vendor/lzma-sys/Cargo.toml | 11 +- vendor/lzma-sys/build.rs | 264 +- vendor/lzma-sys/config.h | 40 + vendor/lzma-sys/src/lib.rs | 227 +- vendor/mdbook/.cargo-checksum.json | 2 +- vendor/mdbook/CHANGELOG.md | 24 +- vendor/mdbook/Cargo.toml | 6 +- vendor/mdbook/README.md | 6 +- vendor/mdbook/appveyor.yml | 3 + vendor/mdbook/src/book/mod.rs | 12 +- vendor/mdbook/src/config.rs | 30 +- vendor/mdbook/src/preprocess/links.rs | 118 +- .../renderer/html_handlebars/hbs_renderer.rs | 11 +- .../html_handlebars/helpers/navigation.rs | 10 +- .../renderer/html_handlebars/helpers/theme.rs | 7 +- .../renderer/html_handlebars/helpers/toc.rs | 7 +- vendor/mdbook/src/utils/fs.rs | 15 +- vendor/mdbook/src/utils/mod.rs | 76 +- vendor/mdbook/src/utils/string.rs | 121 +- vendor/mdbook/tests/dummy_book/mod.rs | 7 +- vendor/mdbook/tests/dummy_book/src/SUMMARY.md | 1 + .../tests/dummy_book/src/first/unicode.md | 21 + .../tests/dummy_book/src/second/nested.md | 8 + vendor/mdbook/tests/rendered_output.rs | 15 +- vendor/mdbook/tests/searchindex_fixture.json | 1268 ++- vendor/memoffset-0.2.1/.cargo-checksum.json | 1 + .../{autocfg => memoffset-0.2.1}/Cargo.toml | 18 +- vendor/memoffset-0.2.1/LICENSE | 19 + vendor/memoffset-0.2.1/README.md | 47 + vendor/memoffset-0.2.1/src/lib.rs | 70 + vendor/memoffset-0.2.1/src/offset_of.rs | 119 + vendor/memoffset-0.2.1/src/span_of.rs | 274 + vendor/memoffset/.cargo-checksum.json | 2 +- vendor/memoffset/Cargo.toml | 8 +- vendor/memoffset/README.md | 9 +- vendor/memoffset/build.rs | 12 + vendor/memoffset/src/lib.rs | 8 +- vendor/memoffset/src/offset_of.rs | 130 +- vendor/memoffset/src/span_of.rs | 240 +- vendor/minifier/.cargo-checksum.json | 2 +- vendor/minifier/Cargo.lock | 106 + vendor/minifier/Cargo.toml | 2 +- vendor/minifier/src/js/js.rs | 126 +- vendor/minifier/src/js/token.rs | 314 +- vendor/minifier/src/js/utils.rs | 115 +- vendor/minifier/src/json/read/byte_to_char.rs | 2 +- vendor/minifier/tests/files/main.js | 2542 ++++++ vendor/minifier/tests/files/minified_main.js | 1 + vendor/minifier/tests/js_minify.rs | 57 + .../.cargo-checksum.json | 0 .../Cargo.toml | 0 vendor/percent-encoding-1.0.1/LICENSE-APACHE | 201 + .../LICENSE-MIT | 0 .../lib.rs | 0 vendor/phf/.cargo-checksum.json | 2 +- vendor/phf/Cargo.toml | 10 +- vendor/phf/src/lib.rs | 49 +- vendor/phf_codegen/.cargo-checksum.json | 2 +- vendor/phf_codegen/Cargo.toml | 7 +- vendor/phf_codegen/src/lib.rs | 2 +- vendor/phf_generator/.cargo-checksum.json | 2 +- vendor/phf_generator/Cargo.toml | 7 +- vendor/phf_generator/src/lib.rs | 11 +- vendor/phf_shared/.cargo-checksum.json | 2 +- vendor/phf_shared/Cargo.toml | 3 +- vendor/phf_shared/src/lib.rs | 2 +- vendor/polonius-engine/.cargo-checksum.json | 2 +- vendor/polonius-engine/Cargo.toml | 2 +- vendor/polonius-engine/src/facts.rs | 30 +- .../src/output/datafrog_opt.rs | 42 +- vendor/polonius-engine/src/output/hybrid.rs | 6 +- vendor/polonius-engine/src/output/liveness.rs | 193 + .../src/output/location_insensitive.rs | 34 +- vendor/polonius-engine/src/output/mod.rs | 12 +- vendor/polonius-engine/src/output/naive.rs | 56 +- vendor/ppv-lite86/.cargo-checksum.json | 1 + vendor/ppv-lite86/Cargo.toml | 31 + vendor/ppv-lite86/LICENSE-APACHE | 201 + vendor/ppv-lite86/LICENSE-MIT | 25 + vendor/ppv-lite86/src/generic.rs | 786 ++ vendor/ppv-lite86/src/lib.rs | 22 + vendor/ppv-lite86/src/soft.rs | 420 + vendor/ppv-lite86/src/types.rs | 279 + vendor/ppv-lite86/src/x86_64/mod.rs | 433 + vendor/ppv-lite86/src/x86_64/sse2.rs | 1633 ++++ vendor/pulldown-cmark/.cargo-checksum.json | 2 +- vendor/pulldown-cmark/Cargo.toml | 6 +- vendor/pulldown-cmark/README.md | 4 +- .../pulldown-cmark/benches/html_rendering.rs | 2 +- vendor/pulldown-cmark/benches/lib.rs | 2 +- vendor/pulldown-cmark/build.rs | 125 +- .../pulldown-cmark/examples/event-filter.rs | 4 +- .../examples/string-to-string.rs | 8 +- vendor/pulldown-cmark/specs/regression.txt | 67 + vendor/pulldown-cmark/src/entities.rs | 4258 +++++----- vendor/pulldown-cmark/src/escape.rs | 134 +- vendor/pulldown-cmark/src/html.rs | 26 +- vendor/pulldown-cmark/src/lib.rs | 20 +- vendor/pulldown-cmark/src/linklabel.rs | 17 +- vendor/pulldown-cmark/src/main.rs | 73 +- vendor/pulldown-cmark/src/parse.rs | 653 +- vendor/pulldown-cmark/src/puncttable.rs | 561 +- vendor/pulldown-cmark/src/scanners.rs | 555 +- vendor/pulldown-cmark/src/simd.rs | 72 +- vendor/pulldown-cmark/src/strings.rs | 19 +- vendor/pulldown-cmark/src/tree.rs | 13 +- vendor/pulldown-cmark/tests/errors.rs | 6 +- vendor/pulldown-cmark/tests/html.rs | 2 +- vendor/pulldown-cmark/tests/lib.rs | 242 +- .../pulldown-cmark/tests/suite/footnotes.rs | 2 +- .../tests/suite/gfm_strikethrough.rs | 2 +- .../pulldown-cmark/tests/suite/gfm_table.rs | 4 +- .../tests/suite/gfm_tasklist.rs | 2 +- vendor/pulldown-cmark/tests/suite/mod.rs | 8 +- .../pulldown-cmark/tests/suite/regression.rs | 86 +- vendor/pulldown-cmark/tests/suite/spec.rs | 11 +- vendor/pulldown-cmark/tests/suite/table.rs | 5 +- .../third_party/GitHub/gfm_table.txt | 7 +- vendor/pulldown-cmark/tools/mk_entities.py | 9 +- vendor/pulldown-cmark/tools/mk_puncttable.py | 12 +- vendor/rand-0.4.6/.cargo-checksum.json | 1 - vendor/rand-0.4.6/CHANGELOG.md | 277 - vendor/rand-0.4.6/Cargo.toml | 45 - vendor/rand-0.4.6/README.md | 139 - vendor/rand-0.4.6/appveyor.yml | 38 - vendor/rand-0.4.6/benches/bench.rs | 34 - .../benches/distributions/exponential.rs | 18 - .../rand-0.4.6/benches/distributions/gamma.rs | 31 - .../rand-0.4.6/benches/distributions/mod.rs | 3 - .../benches/distributions/normal.rs | 18 - vendor/rand-0.4.6/benches/generators.rs | 133 - vendor/rand-0.4.6/benches/misc.rs | 62 - .../src/distributions/exponential.rs | 124 - vendor/rand-0.4.6/src/distributions/mod.rs | 409 - vendor/rand-0.4.6/src/distributions/range.rs | 241 - vendor/rand-0.4.6/src/jitter.rs | 754 -- vendor/rand-0.4.6/src/lib.rs | 1220 --- vendor/rand-0.4.6/src/os.rs | 656 -- vendor/rand-0.4.6/src/prng/chacha.rs | 321 - vendor/rand-0.4.6/src/prng/isaac.rs | 328 - vendor/rand-0.4.6/src/prng/isaac64.rs | 340 - vendor/rand-0.4.6/src/prng/mod.rs | 51 - vendor/rand-0.4.6/src/prng/xorshift.rs | 101 - vendor/rand-0.4.6/src/rand_impls.rs | 299 - vendor/rand-0.4.6/src/read.rs | 123 - vendor/rand-0.4.6/src/reseeding.rs | 229 - vendor/rand-0.4.6/src/seq.rs | 337 - vendor/rand-0.4.6/utils/ziggurat_tables.py | 127 - vendor/rand-0.6.1/.cargo-checksum.json | 1 + vendor/rand-0.6.1/CHANGELOG.md | 484 ++ vendor/rand-0.6.1/COPYRIGHT | 12 + vendor/rand-0.6.1/Cargo.toml | 94 + vendor/rand-0.6.1/LICENSE-APACHE | 201 + vendor/rand-0.6.1/LICENSE-MIT | 26 + vendor/rand-0.6.1/README.md | 115 + .../benches/distributions.rs | 0 vendor/rand-0.6.1/benches/generators.rs | 200 + vendor/rand-0.6.1/benches/misc.rs | 160 + vendor/rand-0.6.1/benches/seq.rs | 174 + vendor/{rand => rand-0.6.1}/build.rs | 0 vendor/rand-0.6.1/examples/monte-carlo.rs | 51 + vendor/rand-0.6.1/examples/monty-hall.rs | 116 + vendor/{rand => rand-0.6.1}/src/deprecated.rs | 0 .../rand-0.6.1/src/distributions/bernoulli.rs | 165 + .../rand-0.6.1/src/distributions/binomial.rs | 177 + vendor/rand-0.6.1/src/distributions/cauchy.rs | 115 + .../rand-0.6.1/src/distributions/dirichlet.rs | 137 + .../src/distributions/exponential.rs | 124 + vendor/rand-0.6.1/src/distributions/float.rs | 259 + .../src/distributions/gamma.rs | 209 +- .../rand-0.6.1/src/distributions/integer.rs | 161 + vendor/rand-0.6.1/src/distributions/mod.rs | 621 ++ .../src/distributions/normal.rs | 120 +- vendor/rand-0.6.1/src/distributions/other.rs | 219 + vendor/rand-0.6.1/src/distributions/pareto.rs | 74 + .../rand-0.6.1/src/distributions/poisson.rs | 157 + .../src/distributions/triangular.rs | 86 + .../rand-0.6.1/src/distributions/uniform.rs | 1297 +++ .../src/distributions/unit_circle.rs | 102 + .../src/distributions/unit_sphere.rs | 100 + vendor/rand-0.6.1/src/distributions/utils.rs | 504 ++ .../rand-0.6.1/src/distributions/weibull.rs | 71 + .../src/distributions/weighted.rs | 0 .../src/distributions/ziggurat_tables.rs | 9 +- vendor/rand-0.6.1/src/lib.rs | 944 +++ vendor/rand-0.6.1/src/prelude.rs | 27 + vendor/{rand => rand-0.6.1}/src/prng/mod.rs | 0 vendor/rand-0.6.1/src/rngs/adapter/mod.rs | 15 + vendor/rand-0.6.1/src/rngs/adapter/read.rs | 137 + .../rand-0.6.1/src/rngs/adapter/reseeding.rs | 370 + vendor/rand-0.6.1/src/rngs/entropy.rs | 297 + .../{rand => rand-0.6.1}/src/rngs/jitter.rs | 0 vendor/rand-0.6.1/src/rngs/mock.rs | 59 + vendor/rand-0.6.1/src/rngs/mod.rs | 217 + vendor/rand-0.6.1/src/rngs/os.rs | 1275 +++ vendor/rand-0.6.1/src/rngs/small.rs | 105 + vendor/rand-0.6.1/src/rngs/std.rs | 81 + vendor/rand-0.6.1/src/rngs/thread.rs | 135 + vendor/rand-0.6.1/src/seq/index.rs | 378 + vendor/rand-0.6.1/src/seq/mod.rs | 836 ++ .../{rand => rand-0.6.1}/tests/uniformity.rs | 0 vendor/rand/.cargo-checksum.json | 2 +- vendor/rand/CHANGELOG.md | 80 + vendor/rand/Cargo.toml | 77 +- vendor/rand/README.md | 77 +- vendor/rand/benches/generators.rs | 166 +- vendor/rand/benches/misc.rs | 60 +- vendor/rand/benches/seq.rs | 9 +- vendor/rand/examples/monte-carlo.rs | 39 +- vendor/rand/examples/monty-hall.rs | 10 +- vendor/rand/rustfmt.toml | 30 + vendor/rand/src/distributions/bernoulli.rs | 57 +- vendor/rand/src/distributions/binomial.rs | 275 +- vendor/rand/src/distributions/cauchy.rs | 41 +- vendor/rand/src/distributions/dirichlet.rs | 26 +- vendor/rand/src/distributions/exponential.rs | 34 +- vendor/rand/src/distributions/float.rs | 28 +- vendor/rand/src/distributions/gamma.rs | 90 +- vendor/rand/src/distributions/integer.rs | 41 +- vendor/rand/src/distributions/mod.rs | 520 +- vendor/rand/src/distributions/normal.rs | 49 +- vendor/rand/src/distributions/other.rs | 14 +- vendor/rand/src/distributions/pareto.rs | 19 +- vendor/rand/src/distributions/poisson.rs | 26 +- vendor/rand/src/distributions/triangular.rs | 21 +- vendor/rand/src/distributions/uniform.rs | 217 +- vendor/rand/src/distributions/unit_circle.rs | 50 +- vendor/rand/src/distributions/unit_sphere.rs | 51 +- vendor/rand/src/distributions/utils.rs | 13 +- vendor/rand/src/distributions/weibull.rs | 19 +- .../distributions/weighted/alias_method.rs | 499 ++ vendor/rand/src/distributions/weighted/mod.rs | 248 + vendor/rand/src/lib.rs | 533 +- vendor/rand/src/prelude.rs | 17 +- vendor/rand/src/rngs/adapter/mod.rs | 4 +- vendor/rand/src/rngs/adapter/read.rs | 51 +- vendor/rand/src/rngs/adapter/reseeding.rs | 86 +- vendor/rand/src/rngs/entropy.rs | 248 +- vendor/rand/src/rngs/mock.rs | 4 + vendor/rand/src/rngs/mod.rs | 289 +- vendor/rand/src/rngs/os.rs | 1270 +-- vendor/rand/src/rngs/small.rs | 60 +- vendor/rand/src/rngs/std.rs | 59 +- vendor/rand/src/rngs/thread.rs | 103 +- vendor/rand/src/seq/index.rs | 73 +- vendor/rand/src/seq/mod.rs | 512 +- vendor/rand_chacha-0.1.0/.cargo-checksum.json | 1 + vendor/rand_chacha-0.1.0/CHANGELOG.md | 8 + vendor/rand_chacha-0.1.0/COPYRIGHT | 12 + vendor/rand_chacha-0.1.0/Cargo.toml | 35 + vendor/rand_chacha-0.1.0/LICENSE-APACHE | 201 + vendor/rand_chacha-0.1.0/LICENSE-MIT | 26 + vendor/rand_chacha-0.1.0/README.md | 44 + .../build.rs | 0 vendor/rand_chacha-0.1.0/src/chacha.rs | 449 + vendor/rand_chacha-0.1.0/src/lib.rs | 25 + vendor/rand_chacha/.cargo-checksum.json | 2 +- vendor/rand_chacha/CHANGELOG.md | 10 + vendor/rand_chacha/Cargo.toml | 25 +- vendor/rand_chacha/README.md | 23 +- vendor/rand_chacha/src/chacha.rs | 567 +- vendor/rand_chacha/src/lib.rs | 13 +- vendor/rand_core/.cargo-checksum.json | 1 + vendor/rand_core/CHANGELOG.md | 41 + vendor/rand_core/COPYRIGHT | 12 + vendor/rand_core/Cargo.toml | 45 + vendor/rand_core/LICENSE-APACHE | 201 + vendor/rand_core/LICENSE-MIT | 26 + vendor/rand_core/README.md | 82 + vendor/rand_core/src/block.rs | 433 + vendor/rand_core/src/error.rs | 134 + vendor/rand_core/src/impls.rs | 165 + vendor/rand_core/src/le.rs | 68 + vendor/rand_core/src/lib.rs | 493 ++ vendor/rand_hc-0.1.0/.cargo-checksum.json | 1 + vendor/rand_hc-0.1.0/CHANGELOG.md | 8 + vendor/rand_hc-0.1.0/COPYRIGHT | 12 + vendor/{rdrand => rand_hc-0.1.0}/Cargo.toml | 28 +- vendor/rand_hc-0.1.0/LICENSE-APACHE | 201 + vendor/rand_hc-0.1.0/LICENSE-MIT | 25 + vendor/rand_hc-0.1.0/README.md | 44 + vendor/rand_hc-0.1.0/src/hc128.rs | 462 ++ vendor/rand_hc-0.1.0/src/lib.rs | 25 + vendor/rand_hc/.cargo-checksum.json | 2 +- vendor/rand_hc/CHANGELOG.md | 8 + vendor/rand_hc/Cargo.toml | 10 +- vendor/rand_hc/README.md | 15 +- vendor/rand_hc/src/hc128.rs | 12 +- vendor/rand_hc/src/lib.rs | 4 +- .../rand_xorshift-0.1.0/.cargo-checksum.json | 1 + vendor/rand_xorshift-0.1.0/CHANGELOG.md | 8 + vendor/rand_xorshift-0.1.0/COPYRIGHT | 12 + vendor/rand_xorshift-0.1.0/Cargo.toml | 45 + vendor/rand_xorshift-0.1.0/LICENSE-APACHE | 201 + vendor/rand_xorshift-0.1.0/LICENSE-MIT | 26 + vendor/rand_xorshift-0.1.0/README.md | 44 + vendor/rand_xorshift-0.1.0/src/lib.rs | 32 + .../src/xorshift.rs | 0 vendor/rand_xorshift/.cargo-checksum.json | 2 +- vendor/rand_xorshift/CHANGELOG.md | 13 +- vendor/rand_xorshift/Cargo.toml | 23 +- vendor/rand_xorshift/README.md | 19 +- vendor/rand_xorshift/src/lib.rs | 113 +- vendor/rand_xorshift/tests/mod.rs | 89 + vendor/rayon-core/.cargo-checksum.json | 2 +- vendor/rayon-core/Cargo.toml | 29 +- vendor/rayon-core/README.md | 2 +- vendor/rayon-core/src/compile_fail/mod.rs | 1 - .../src/compile_fail/scope_join_bad.rs | 2 +- vendor/rayon-core/src/internal/task.rs | 3 +- vendor/rayon-core/src/internal/worker.rs | 30 +- vendor/rayon-core/src/job.rs | 105 +- vendor/rayon-core/src/join/mod.rs | 54 +- vendor/rayon-core/src/join/test.rs | 22 +- vendor/rayon-core/src/latch.rs | 37 +- vendor/rayon-core/src/lib.rs | 356 +- vendor/rayon-core/src/log.rs | 125 +- vendor/rayon-core/src/private.rs | 26 + vendor/rayon-core/src/registry.rs | 492 +- vendor/rayon-core/src/scope/internal.rs | 10 +- vendor/rayon-core/src/scope/mod.rs | 342 +- vendor/rayon-core/src/scope/test.rs | 215 +- vendor/rayon-core/src/sleep/mod.rs | 50 +- vendor/rayon-core/src/spawn/mod.rs | 96 +- vendor/rayon-core/src/spawn/test.rs | 113 +- vendor/rayon-core/src/test.rs | 58 +- vendor/rayon-core/src/thread_pool/internal.rs | 11 +- vendor/rayon-core/src/thread_pool/mod.rs | 127 +- vendor/rayon-core/src/thread_pool/test.rs | 125 +- vendor/rayon-core/src/unwind.rs | 28 +- vendor/rayon-core/src/util.rs | 2 +- vendor/rayon-core/tests/scoped_threadpool.rs | 102 + .../rayon-core/tests/stack_overflow_crash.rs | 39 +- vendor/rayon/.cargo-checksum.json | 2 +- vendor/rayon/Cargo.toml | 22 +- vendor/rayon/FAQ.md | 4 +- vendor/rayon/README.md | 18 +- vendor/rayon/RELEASES.md | 159 +- vendor/rayon/appveyor.yml | 72 - vendor/rayon/bors.toml | 7 - vendor/rayon/ci/highlander.sh | 12 - vendor/rayon/examples/cpu_monitor.rs | 15 +- vendor/rayon/scripts/analyze.sh | 30 - vendor/rayon/src/collections/binary_heap.rs | 18 +- vendor/rayon/src/collections/btree_map.rs | 20 +- vendor/rayon/src/collections/btree_set.rs | 16 +- vendor/rayon/src/collections/hash_map.rs | 22 +- vendor/rayon/src/collections/hash_set.rs | 18 +- vendor/rayon/src/collections/linked_list.rs | 20 +- vendor/rayon/src/collections/vec_deque.rs | 24 +- .../cannot_collect_filtermap_data.rs | 4 +- .../compile_fail}/cannot_zip_filtered_data.rs | 6 +- .../compile_fail}/cell_par_iter.rs | 4 +- vendor/rayon/src/compile_fail/mod.rs | 7 + vendor/rayon/src/compile_fail/must_use.rs | 62 + .../src/compile_fail/no_send_par_iter.rs | 64 + .../compile_fail}/rc_par_iter.rs | 6 +- vendor/rayon/src/iter/chain.rs | 141 +- vendor/rayon/src/iter/chunks.rs | 140 +- vendor/rayon/src/iter/cloned.rs | 98 +- vendor/rayon/src/iter/collect/consumer.rs | 39 +- vendor/rayon/src/iter/collect/mod.rs | 51 +- vendor/rayon/src/iter/collect/test.rs | 75 +- vendor/rayon/src/iter/empty.rs | 18 +- vendor/rayon/src/iter/enumerate.rs | 59 +- vendor/rayon/src/iter/extend.rs | 165 +- vendor/rayon/src/iter/filter.rs | 66 +- vendor/rayon/src/iter/filter_map.rs | 64 +- vendor/rayon/src/iter/find.rs | 45 +- vendor/rayon/src/iter/find_first_last/mod.rs | 74 +- vendor/rayon/src/iter/find_first_last/test.rs | 61 +- vendor/rayon/src/iter/flat_map.rs | 68 +- vendor/rayon/src/iter/flatten.rs | 23 +- vendor/rayon/src/iter/fold.rs | 161 +- vendor/rayon/src/iter/for_each.rs | 29 +- vendor/rayon/src/iter/from_par_iter.rs | 97 +- vendor/rayon/src/iter/inspect.rs | 129 +- vendor/rayon/src/iter/interleave.rs | 166 +- vendor/rayon/src/iter/interleave_shortest.rs | 58 +- vendor/rayon/src/iter/intersperse.rs | 153 +- vendor/rayon/src/iter/len.rs | 129 +- vendor/rayon/src/iter/map.rs | 134 +- vendor/rayon/src/iter/map_with.rs | 412 +- vendor/rayon/src/iter/mod.rs | 998 ++- vendor/rayon/src/iter/noop.rs | 13 +- vendor/rayon/src/iter/once.rs | 11 +- vendor/rayon/src/iter/panic_fuse.rs | 338 + vendor/rayon/src/iter/par_bridge.rs | 200 + vendor/rayon/src/iter/plumbing/README.md | 4 +- vendor/rayon/src/iter/plumbing/mod.rs | 123 +- vendor/rayon/src/iter/product.rs | 49 +- vendor/rayon/src/iter/reduce.rs | 36 +- vendor/rayon/src/iter/repeat.rs | 75 +- vendor/rayon/src/iter/rev.rs | 59 +- vendor/rayon/src/iter/skip.rs | 41 +- vendor/rayon/src/iter/splitter.rs | 40 +- vendor/rayon/src/iter/sum.rs | 43 +- vendor/rayon/src/iter/take.rs | 39 +- vendor/rayon/src/iter/test.rs | 1034 ++- vendor/rayon/src/iter/try_fold.rs | 292 + vendor/rayon/src/iter/try_reduce.rs | 126 + vendor/rayon/src/iter/try_reduce_with.rs | 134 + vendor/rayon/src/iter/unzip.rs | 290 +- vendor/rayon/src/iter/update.rs | 165 +- vendor/rayon/src/iter/while_some.rs | 72 +- vendor/rayon/src/iter/zip.rs | 89 +- vendor/rayon/src/iter/zip_eq.rs | 40 +- vendor/rayon/src/lib.rs | 34 +- vendor/rayon/src/math.rs | 7 +- vendor/rayon/src/option.rs | 48 +- vendor/rayon/src/par_either.rs | 32 +- vendor/rayon/src/prelude.rs | 3 +- vendor/rayon/src/private.rs | 1 - vendor/rayon/src/range.rs | 171 +- vendor/rayon/src/range_inclusive.rs | 203 + vendor/rayon/src/result.rs | 65 +- vendor/rayon/src/slice/mergesort.rs | 96 +- vendor/rayon/src/slice/mod.rs | 238 +- vendor/rayon/src/slice/quicksort.rs | 53 +- vendor/rayon/src/slice/test.rs | 38 +- vendor/rayon/src/split_producer.rs | 45 +- vendor/rayon/src/str.rs | 535 +- vendor/rayon/src/test.rs | 48 - vendor/rayon/src/vec.rs | 27 +- vendor/rayon/tests/clones.rs | 21 +- .../tests/compile-fail-unstable/README.md | 3 - vendor/rayon/tests/compile-fail/README.md | 11 - vendor/rayon/tests/compile-fail/must_use.rs | 37 - .../tests/compile-fail/no_send_par_iter.rs | 27 - .../tests/compile-fail/quicksort_race1.rs | 26 - .../tests/compile-fail/quicksort_race2.rs | 26 - .../tests/compile-fail/quicksort_race3.rs | 26 - vendor/rayon/tests/compile-fail/rc_return.rs | 8 - vendor/rayon/tests/compile-fail/rc_upvar.rs | 9 - .../tests/compile-fail/scope_join_bad.rs | 22 - vendor/rayon/tests/debug.rs | 21 +- vendor/rayon/tests/intersperse.rs | 17 +- vendor/rayon/tests/iter_panic.rs | 47 + vendor/rayon/tests/named-threads.rs | 26 + vendor/rayon/tests/octillion.rs | 123 + vendor/rayon/tests/producer_split_at.rs | 112 +- .../rayon/tests/run-fail-unstable/README.md | 3 - vendor/rayon/tests/run-fail/README.md | 14 - vendor/rayon/tests/run-fail/iter_panic.rs | 10 - vendor/rayon/tests/run-fail/simple_panic.rs | 9 - .../rayon/tests/run-pass-unstable/README.md | 3 - vendor/rayon/tests/run-pass/README.md | 7 - .../rayon/tests/run-pass/double_init_fail.rs | 11 - .../rayon/tests/run-pass/init_zero_threads.rs | 7 - vendor/rayon/tests/run-pass/named-threads.rs | 19 - vendor/rayon/tests/run-pass/scope_join.rs | 45 - .../tests/run-pass/stack_overflow_crash.rs | 58 - vendor/rayon/tests/sort-panic-safe.rs | 43 +- vendor/rayon/tests/str.rs | 120 + vendor/rdrand/.cargo-checksum.json | 1 - vendor/rdrand/LICENSE | 12 - vendor/rdrand/README.mkd | 8 - vendor/rdrand/appveyor.yml | 27 - vendor/rdrand/benches/rdrand.rs | 49 - vendor/rdrand/benches/rdseed.rs | 49 - vendor/rdrand/benches/std.rs | 31 - vendor/rdrand/src/changelog.rs | 25 - vendor/rdrand/src/lib.rs | 472 -- vendor/remove_dir_all/.cargo-checksum.json | 2 +- vendor/remove_dir_all/Cargo.toml | 8 +- vendor/remove_dir_all/src/fs.rs | 86 +- vendor/remove_dir_all/src/lib.rs | 8 +- vendor/rustfix/.cargo-checksum.json | 2 +- vendor/rustfix/Cargo.toml | 9 +- vendor/rustfix/Changelog.md | 79 + vendor/rustfix/src/diagnostics.rs | 14 +- vendor/rustfix/src/lib.rs | 47 +- vendor/ryu/.cargo-checksum.json | 2 +- vendor/ryu/Cargo.toml | 8 +- vendor/ryu/README.md | 73 +- vendor/ryu/benches/bench.rs | 58 + .../upstream_benchmark.rs} | 4 +- vendor/ryu/src/buffer/mod.rs | 101 +- vendor/ryu/src/common.rs | 61 +- vendor/ryu/src/d2s.rs | 279 +- vendor/ryu/src/d2s_intrinsics.rs | 32 +- vendor/ryu/src/d2s_small_table.rs | 8 +- vendor/ryu/src/f2s.rs | 202 +- vendor/ryu/src/lib.rs | 91 +- vendor/ryu/src/pretty/mod.rs | 34 +- vendor/ryu/tests/d2s_test.rs | 259 +- vendor/ryu/tests/exhaustive.rs | 4 +- vendor/ryu/tests/f2s_test.rs | 158 +- vendor/ryu/tests/macros/mod.rs | 12 +- vendor/scopeguard-0.3.3/.cargo-checksum.json | 1 + vendor/scopeguard-0.3.3/Cargo.toml | 28 + vendor/scopeguard-0.3.3/LICENSE-APACHE | 201 + vendor/scopeguard-0.3.3/LICENSE-MIT | 25 + vendor/scopeguard-0.3.3/README.rst | 81 + vendor/scopeguard-0.3.3/examples/readme.rs | 27 + vendor/scopeguard-0.3.3/src/lib.rs | 409 + vendor/scopeguard/.cargo-checksum.json | 2 +- vendor/scopeguard/Cargo.toml | 8 +- vendor/scopeguard/README.rst | 23 +- vendor/scopeguard/examples/readme.rs | 2 +- vendor/scopeguard/src/lib.rs | 253 +- vendor/serde_json/.cargo-checksum.json | 2 +- vendor/serde_json/Cargo.toml | 27 +- vendor/serde_json/LICENSE-MIT | 2 - vendor/serde_json/README.md | 158 +- vendor/serde_json/src/de.rs | 415 +- vendor/serde_json/src/error.rs | 89 +- vendor/serde_json/src/iter.rs | 8 - vendor/serde_json/src/lib.rs | 159 +- vendor/serde_json/src/macros.rs | 39 +- vendor/serde_json/src/map.rs | 88 +- vendor/serde_json/src/number.rs | 71 +- vendor/serde_json/src/raw.rs | 50 +- vendor/serde_json/src/read.rs | 100 +- vendor/serde_json/src/ser.rs | 84 +- vendor/serde_json/src/value/de.rs | 8 - vendor/serde_json/src/value/from.rs | 93 +- vendor/serde_json/src/value/index.rs | 29 +- vendor/serde_json/src/value/mod.rs | 355 +- vendor/serde_json/src/value/partial_eq.rs | 8 - vendor/serde_json/src/value/ser.rs | 22 +- .../{url => url-1.7.2}/.cargo-checksum.json | 0 vendor/{url => url-1.7.2}/Cargo.toml | 0 vendor/url-1.7.2/LICENSE-APACHE | 201 + vendor/{url => url-1.7.2}/LICENSE-MIT | 0 vendor/{url => url-1.7.2}/README.md | 0 vendor/{url => url-1.7.2}/UPGRADING.md | 0 vendor/{url => url-1.7.2}/appveyor.yml | 0 .../{url => url-1.7.2}/benches/parse_url.rs | 0 vendor/{url => url-1.7.2}/docs/404.html | 0 vendor/{url => url-1.7.2}/docs/index.html | 0 vendor/{url => url-1.7.2}/src/encoding.rs | 0 .../{url => url-1.7.2}/src/form_urlencoded.rs | 0 vendor/{url => url-1.7.2}/src/host.rs | 0 vendor/{url => url-1.7.2}/src/lib.rs | 0 vendor/{url => url-1.7.2}/src/origin.rs | 0 vendor/{url => url-1.7.2}/src/parser.rs | 0 .../{url => url-1.7.2}/src/path_segments.rs | 0 vendor/{url => url-1.7.2}/src/quirks.rs | 0 vendor/{url => url-1.7.2}/src/slicing.rs | 0 vendor/{url => url-1.7.2}/tests/data.rs | 0 .../tests/setters_tests.json | 0 vendor/{url => url-1.7.2}/tests/unit.rs | 0 .../{url => url-1.7.2}/tests/urltestdata.json | 0 version | 2 +- 8070 files changed, 167068 insertions(+), 92812 deletions(-) delete mode 100644 src/ci/awscli-requirements.txt create mode 100755 src/ci/install-awscli.sh rename src/doc/reference/{src => }/theme/header.hbs (100%) rename src/doc/reference/{src => }/theme/reference.css (91%) create mode 100644 src/doc/rust-by-example/src/std/rc.md create mode 100644 src/doc/rustc-guide/ci/build-ignore-timeouts.sh create mode 100644 src/doc/rustc-guide/src/appendix/humorust.md create mode 100644 src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md create mode 100644 src/doc/unstable-book/src/language-features/param-attrs.md rename src/doc/unstable-book/src/{language-features => library-features}/asm.md (100%) rename src/doc/unstable-book/src/{language-features => library-features}/concat-idents.md (100%) create mode 100644 src/doc/unstable-book/src/library-features/debug-map-key-value.md rename src/doc/unstable-book/src/{language-features => library-features}/global-asm.md (100%) delete mode 100644 src/doc/unstable-book/src/library-features/n16.md rename src/doc/unstable-book/src/{language-features => library-features}/trace-macros.md (100%) create mode 100644 src/liballoc/alloc/tests.rs create mode 100644 src/liballoc/collections/linked_list/tests.rs create mode 100644 src/liballoc/collections/vec_deque/tests.rs create mode 100644 src/liballoc/raw_vec/tests.rs create mode 100644 src/liballoc/rc/tests.rs create mode 100644 src/liballoc/sync/tests.rs create mode 100644 src/libpanic_unwind/dwarf/tests.rs create mode 100644 src/librustc/hir/lowering/expr.rs create mode 100644 src/librustc/hir/lowering/item.rs create mode 100644 src/librustc/hir/ptr.rs delete mode 100644 src/librustc/middle/allocator.rs create mode 100644 src/librustc/tests.rs create mode 100644 src/librustc/util/common/tests.rs delete mode 100644 src/librustc_allocator/Cargo.toml delete mode 100644 src/librustc_allocator/expand.rs delete mode 100644 src/librustc_allocator/lib.rs rename src/{librustc_borrowck => librustc_ast_borrowck}/Cargo.toml (83%) rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/README.md (99%) rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/check_loans.rs (60%) rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/gather_loans/gather_moves.rs (54%) rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/gather_loans/lifetime.rs (80%) rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/gather_loans/mod.rs (73%) rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/gather_loans/restrictions.rs (91%) create mode 100644 src/librustc_ast_borrowck/borrowck/mod.rs rename src/{librustc_borrowck => librustc_ast_borrowck}/borrowck/move_data.rs (96%) rename src/{librustc_borrowck => librustc_ast_borrowck}/dataflow.rs (97%) rename src/{librustc_borrowck => librustc_ast_borrowck}/graphviz.rs (100%) rename src/{librustc_borrowck => librustc_ast_borrowck}/lib.rs (83%) delete mode 100644 src/librustc_borrowck/borrowck/gather_loans/move_error.rs delete mode 100644 src/librustc_borrowck/borrowck/mod.rs delete mode 100644 src/librustc_borrowck/error_codes.rs delete mode 100644 src/librustc_codegen_ssa/back/wasm.rs delete mode 100644 src/librustc_cratesio_shim/Cargo.toml delete mode 100644 src/librustc_cratesio_shim/src/lib.rs create mode 100644 src/librustc_data_structures/base_n/tests.rs rename src/librustc_data_structures/binary_search_util/{test.rs => tests.rs} (100%) create mode 100644 src/librustc_data_structures/bit_set/tests.rs rename src/librustc_data_structures/graph/dominators/{test.rs => tests.rs} (85%) rename src/librustc_data_structures/graph/iterate/{test.rs => tests.rs} (85%) rename src/librustc_data_structures/graph/scc/{test.rs => tests.rs} (98%) rename src/librustc_data_structures/graph/{test.rs => tests.rs} (87%) rename src/librustc_data_structures/graph/vec_graph/{test.rs => tests.rs} (100%) delete mode 100644 src/librustc_data_structures/interner.rs rename src/librustc_data_structures/obligation_forest/{test.rs => tests.rs} (99%) create mode 100644 src/librustc_data_structures/sharded.rs create mode 100644 src/librustc_data_structures/sip128/tests.rs create mode 100644 src/librustc_data_structures/small_c_str/tests.rs rename src/librustc_data_structures/snapshot_map/{test.rs => tests.rs} (100%) create mode 100644 src/librustc_data_structures/tiny_list/tests.rs create mode 100644 src/librustc_data_structures/transitive_relation/tests.rs create mode 100644 src/librustc_incremental/persist/fs/tests.rs create mode 100644 src/librustc_lexer/Cargo.toml create mode 100644 src/librustc_lexer/src/cursor.rs create mode 100644 src/librustc_lexer/src/lib.rs create mode 100644 src/librustc_lexer/src/unescape.rs create mode 100644 src/librustc_lexer/src/unescape/tests.rs create mode 100644 src/librustc_lint/non_ascii_idents.rs create mode 100644 src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs delete mode 100644 src/librustc_mir/transform/lower_128bit.rs create mode 100644 src/librustc_resolve/late.rs create mode 100644 src/librustc_resolve/late/diagnostics.rs rename src/librustc_save_analysis/{json_dumper.rs => dumper.rs} (65%) create mode 100644 src/librustc_target/spec/aarch64_unknown_redox.rs create mode 100644 src/librustc_target/spec/aarch64_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/abi/tests.rs create mode 100644 src/librustc_target/spec/arm_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/arm_wrs_vxworks_sf.rs create mode 100644 src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs create mode 100644 src/librustc_target/spec/armv7_unknown_linux_musleabi.rs create mode 100644 src/librustc_target/spec/armv7_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/hexagon_unknown_linux_musl.rs create mode 100644 src/librustc_target/spec/i586_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/i686_uwp_windows_gnu.rs create mode 100644 src/librustc_target/spec/i686_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/i686_wrs_vxworks_gnu.rs create mode 100644 src/librustc_target/spec/powerpc64_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/powerpc64_wrs_vxworks_gnusf.rs create mode 100644 src/librustc_target/spec/powerpc_wrs_vxworks.rs create mode 100644 src/librustc_target/spec/powerpc_wrs_vxworks_gnusf.rs create mode 100644 src/librustc_target/spec/powerpc_wrs_vxworks_gnuspesf.rs create mode 100644 src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs create mode 100644 src/librustc_target/spec/riscv32i_unknown_none_elf.rs create mode 100644 src/librustc_target/spec/vxworks_base.rs create mode 100644 src/librustc_target/spec/windows_uwp_base.rs create mode 100644 src/librustc_target/spec/x86_64_uwp_windows_gnu.rs create mode 100644 src/librustc_target/spec/x86_64_wrs_vxworks.rs create mode 100644 src/librustdoc/clean/cfg/tests.rs create mode 100644 src/librustdoc/html/render/tests.rs create mode 100644 src/librustdoc/passes/unindent_comments/tests.rs create mode 100644 src/librustdoc/theme/tests.rs create mode 100644 src/libserialize/tests/leb128.rs create mode 100644 src/libstd/os/redox/fs.rs create mode 100644 src/libstd/os/redox/mod.rs create mode 100644 src/libstd/os/redox/raw.rs create mode 100644 src/libstd/os/vxworks/fs.rs create mode 100644 src/libstd/os/vxworks/mod.rs create mode 100644 src/libstd/os/vxworks/raw.rs delete mode 100644 src/libstd/sys/redox/condvar.rs delete mode 100644 src/libstd/sys/redox/ext/fs.rs delete mode 100644 src/libstd/sys/redox/ext/mod.rs delete mode 100644 src/libstd/sys/redox/ext/net.rs delete mode 100644 src/libstd/sys/redox/ext/thread.rs delete mode 100644 src/libstd/sys/redox/fast_thread_local.rs delete mode 100644 src/libstd/sys/redox/fd.rs delete mode 100644 src/libstd/sys/redox/fs.rs delete mode 100644 src/libstd/sys/redox/io.rs delete mode 100644 src/libstd/sys/redox/memchr.rs delete mode 100644 src/libstd/sys/redox/mod.rs delete mode 100644 src/libstd/sys/redox/mutex.rs delete mode 100644 src/libstd/sys/redox/net/dns/answer.rs delete mode 100644 src/libstd/sys/redox/net/dns/mod.rs delete mode 100644 src/libstd/sys/redox/net/dns/query.rs delete mode 100644 src/libstd/sys/redox/net/mod.rs delete mode 100644 src/libstd/sys/redox/net/netc.rs delete mode 100644 src/libstd/sys/redox/net/tcp.rs delete mode 100644 src/libstd/sys/redox/net/udp.rs delete mode 100644 src/libstd/sys/redox/path.rs delete mode 100644 src/libstd/sys/redox/pipe.rs delete mode 100644 src/libstd/sys/redox/process.rs delete mode 100644 src/libstd/sys/redox/rand.rs delete mode 100644 src/libstd/sys/redox/rwlock.rs delete mode 100644 src/libstd/sys/redox/syscall/arch/arm.rs delete mode 100644 src/libstd/sys/redox/syscall/arch/x86.rs delete mode 100644 src/libstd/sys/redox/syscall/arch/x86_64.rs delete mode 100644 src/libstd/sys/redox/syscall/call.rs delete mode 100644 src/libstd/sys/redox/syscall/data.rs delete mode 100644 src/libstd/sys/redox/syscall/error.rs delete mode 100644 src/libstd/sys/redox/syscall/flag.rs delete mode 100644 src/libstd/sys/redox/syscall/mod.rs delete mode 100644 src/libstd/sys/redox/syscall/number.rs delete mode 100644 src/libstd/sys/redox/thread.rs delete mode 100644 src/libstd/sys/redox/thread_local.rs delete mode 100644 src/libstd/sys/redox/time.rs create mode 100644 src/libstd/sys/vxworks/alloc.rs rename src/libstd/sys/{redox => vxworks}/args.rs (58%) create mode 100644 src/libstd/sys/vxworks/backtrace/mod.rs create mode 100644 src/libstd/sys/vxworks/backtrace/printing/dladdr.rs create mode 100644 src/libstd/sys/vxworks/backtrace/printing/mod.rs create mode 100644 src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs create mode 100644 src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs create mode 100644 src/libstd/sys/vxworks/backtrace/tracing/mod.rs rename src/libstd/sys/{redox => vxworks}/cmath.rs (100%) create mode 100644 src/libstd/sys/vxworks/condvar.rs rename src/libstd/sys/{redox => vxworks}/env.rs (73%) rename src/libstd/sys/{redox => vxworks}/ext/ffi.rs (83%) create mode 100644 src/libstd/sys/vxworks/ext/fs.rs rename src/libstd/sys/{redox => vxworks}/ext/io.rs (59%) create mode 100644 src/libstd/sys/vxworks/ext/mod.rs create mode 100644 src/libstd/sys/vxworks/ext/net.rs rename src/libstd/sys/{redox => vxworks}/ext/process.rs (83%) create mode 100644 src/libstd/sys/vxworks/ext/raw.rs create mode 100644 src/libstd/sys/vxworks/fast_thread_local.rs create mode 100644 src/libstd/sys/vxworks/fd.rs create mode 100644 src/libstd/sys/vxworks/fs.rs create mode 100644 src/libstd/sys/vxworks/io.rs create mode 100644 src/libstd/sys/vxworks/memchr.rs create mode 100644 src/libstd/sys/vxworks/mod.rs create mode 100644 src/libstd/sys/vxworks/mutex.rs create mode 100644 src/libstd/sys/vxworks/net.rs rename src/libstd/sys/{redox => vxworks}/os.rs (52%) create mode 100644 src/libstd/sys/vxworks/path.rs create mode 100644 src/libstd/sys/vxworks/pipe.rs create mode 100644 src/libstd/sys/vxworks/process/mod.rs create mode 100644 src/libstd/sys/vxworks/process/process_common.rs create mode 100644 src/libstd/sys/vxworks/process/process_vxworks.rs create mode 100644 src/libstd/sys/vxworks/process/rtp.rs create mode 100644 src/libstd/sys/vxworks/rand.rs create mode 100644 src/libstd/sys/vxworks/rwlock.rs create mode 100644 src/libstd/sys/vxworks/stack_overflow.rs rename src/libstd/sys/{redox => vxworks}/stdio.rs (73%) create mode 100644 src/libstd/sys/vxworks/thread.rs create mode 100644 src/libstd/sys/vxworks/thread_local.rs create mode 100644 src/libstd/sys/vxworks/time.rs create mode 100644 src/libstd/sys/vxworks/weak.rs create mode 100644 src/libstd/sys/wasm/fast_thread_local.rs delete mode 100644 src/libstd/sys/wasm/thread_local_atomics.rs rename src/libstd/sys/{redox/stack_overflow.rs => windows/stack_overflow_uwp.rs} (52%) create mode 100644 src/libstd/sys/windows/stdio_uwp.rs create mode 100644 src/libsyntax/ast/tests.rs create mode 100644 src/libsyntax/ext/allocator.rs delete mode 100644 src/libsyntax/ext/derive.rs create mode 100644 src/libsyntax/ext/proc_macro.rs rename src/{libsyntax_ext => libsyntax/ext}/proc_macro_server.rs (97%) create mode 100644 src/libsyntax/ext/tt/macro_check.rs create mode 100644 src/libsyntax/mut_visit/tests.rs create mode 100644 src/libsyntax/parse/lexer/comments/tests.rs create mode 100644 src/libsyntax/parse/lexer/tests.rs create mode 100644 src/libsyntax/parse/parser/expr.rs create mode 100644 src/libsyntax/parse/parser/generics.rs create mode 100644 src/libsyntax/parse/parser/item.rs create mode 100644 src/libsyntax/parse/parser/module.rs create mode 100644 src/libsyntax/parse/parser/pat.rs create mode 100644 src/libsyntax/parse/parser/path.rs create mode 100644 src/libsyntax/parse/parser/stmt.rs create mode 100644 src/libsyntax/parse/parser/ty.rs create mode 100644 src/libsyntax/parse/tests.rs delete mode 100644 src/libsyntax/parse/unescape.rs create mode 100644 src/libsyntax/print/helpers.rs create mode 100644 src/libsyntax/print/pprust/tests.rs create mode 100644 src/libsyntax/source_map/tests.rs rename src/libsyntax/{test_snippet.rs => tests.rs} (87%) create mode 100644 src/libsyntax/tokenstream/tests.rs create mode 100644 src/libsyntax/util/lev_distance/tests.rs delete mode 100644 src/libsyntax/util/parser_testing.rs delete mode 100644 src/libsyntax_ext/deriving/custom.rs create mode 100644 src/libsyntax_ext/global_allocator.rs create mode 100644 src/libsyntax_ext/plugin_macro_defs.rs rename src/libsyntax_ext/{proc_macro_decls.rs => proc_macro_harness.rs} (92%) delete mode 100644 src/libsyntax_ext/proc_macro_impl.rs rename src/{libsyntax/ext => libsyntax_ext}/source_util.rs (76%) rename src/{libsyntax/std_inject.rs => libsyntax_ext/standard_library_imports.rs} (57%) delete mode 100644 src/libsyntax_ext/test_case.rs rename src/{libsyntax/test.rs => libsyntax_ext/test_harness.rs} (80%) create mode 100644 src/libsyntax_pos/analyze_source_file/tests.rs create mode 100644 src/libsyntax_pos/symbol/tests.rs create mode 100644 src/libsyntax_pos/tests.rs create mode 100644 src/libterm/terminfo/parm/tests.rs create mode 100644 src/libterm/terminfo/parser/compiled/tests.rs create mode 100644 src/libterm/terminfo/searcher/tests.rs rename src/{stdsimd => stdarch}/.appveyor.yml (100%) rename src/{stdsimd => stdarch}/CONTRIBUTING.md (77%) rename src/{stdsimd => stdarch}/Cargo.toml (90%) rename src/{stdsimd => stdarch}/LICENSE-APACHE (100%) rename src/{stdsimd => stdarch}/LICENSE-MIT (100%) rename src/{stdsimd => stdarch}/QUESTIONS.md (95%) rename src/{stdsimd => stdarch}/README.md (85%) create mode 100644 src/stdarch/azure-pipelines.yml rename src/{stdsimd => stdarch}/ci/android-install-ndk.sh (100%) rename src/{stdsimd => stdarch}/ci/android-install-sdk.sh (100%) rename src/{stdsimd => stdarch}/ci/android-sysimage.sh (100%) create mode 100644 src/stdarch/ci/azure-install-rust.yml rename src/{stdsimd => stdarch}/ci/docker/aarch64-linux-android/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/aarch64-unknown-linux-gnu/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/arm-linux-androideabi/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/i586-unknown-linux-gnu/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/i686-unknown-linux-gnu/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/mips-unknown-linux-gnu/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/mipsel-unknown-linux-musl/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/nvptx64-nvidia-cuda/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/powerpc-unknown-linux-gnu/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile (91%) rename src/{stdsimd => stdarch}/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile (77%) rename src/{stdsimd => stdarch}/ci/docker/s390x-unknown-linux-gnu/Dockerfile (100%) create mode 100644 src/stdarch/ci/docker/wasm32-unknown-unknown/Dockerfile create mode 100755 src/stdarch/ci/docker/wasm32-unknown-unknown/wasm-entrypoint.sh rename src/{stdsimd => stdarch}/ci/docker/x86_64-linux-android/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/docker/x86_64-unknown-linux-gnu-emulated/Dockerfile (67%) rename src/{stdsimd => stdarch}/ci/docker/x86_64-unknown-linux-gnu/Dockerfile (100%) rename src/{stdsimd => stdarch}/ci/dox.sh (83%) rename src/{stdsimd => stdarch}/ci/gba.json (100%) rename src/{stdsimd => stdarch}/ci/run-docker.sh (63%) rename src/{stdsimd => stdarch}/ci/run.sh (69%) rename src/{stdsimd => stdarch}/ci/runtest-android.rs (100%) create mode 100644 src/stdarch/ci/style.sh rename src/{stdsimd => stdarch}/crates/assert-instr-macro/Cargo.toml (100%) rename src/{stdsimd => stdarch}/crates/assert-instr-macro/build.rs (100%) rename src/{stdsimd => stdarch}/crates/assert-instr-macro/src/lib.rs (88%) rename src/{stdsimd => stdarch}/crates/core_arch/Cargo.toml (58%) rename src/{stdsimd => stdarch}/crates/core_arch/LICENSE-APACHE (100%) rename src/{stdsimd => stdarch}/crates/core_arch/LICENSE-MIT (100%) rename src/{stdsimd => stdarch}/crates/core_arch/README.md (75%) rename src/{stdsimd => stdarch}/crates/core_arch/build.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/aarch64/crc.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/aarch64/crypto.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/aarch64/mod.rs (95%) rename src/{stdsimd => stdarch}/crates/core_arch/src/aarch64/neon.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/aarch64/v8.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/barrier/common.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/barrier/cp15.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/barrier/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/barrier/not_mclass.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/barrier/v8.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/dsp.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/ex.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/hints.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/registers/aarch32.rs (79%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/registers/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/registers/v6m.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/registers/v7m.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/sat.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/acle/simd32.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/arm/armclang.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/arm/mod.rs (97%) rename src/{stdsimd => stdarch}/crates/core_arch/src/arm/neon.rs (83%) rename src/{stdsimd => stdarch}/crates/core_arch/src/arm/table_lookup_tests.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/arm/v6.rs (96%) rename src/{stdsimd => stdarch}/crates/core_arch/src/arm/v7.rs (90%) rename src/{stdsimd => stdarch}/crates/core_arch/src/core_arch_docs.md (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/lib.rs (89%) rename src/{stdsimd => stdarch}/crates/core_arch/src/macros.rs (78%) rename src/{stdsimd => stdarch}/crates/core_arch/src/mips/mod.rs (86%) rename src/{stdsimd => stdarch}/crates/core_arch/src/mips/msa.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/mips/msa/macros.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/mod.rs (97%) rename src/{stdsimd => stdarch}/crates/core_arch/src/nvptx/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/powerpc/altivec.rs (50%) rename src/{stdsimd => stdarch}/crates/core_arch/src/powerpc/mod.rs (91%) rename src/{stdsimd => stdarch}/crates/core_arch/src/powerpc/vsx.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/powerpc64/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/simd.rs (93%) rename src/{stdsimd => stdarch}/crates/core_arch/src/simd_llvm.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/v64.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/wasm32/atomic.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/wasm32/memory.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/wasm32/mod.rs (85%) rename src/{stdsimd => stdarch}/crates/core_arch/src/wasm32/simd128.rs (63%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/abm.rs (96%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/adx.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/aes.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/avx.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/avx2.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/avx512f.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/avx512ifma.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/bmi1.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/bmi2.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/bswap.rs (95%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/bt.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/cpuid.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/eflags.rs (100%) create mode 100644 src/stdarch/crates/core_arch/src/x86/f16c.rs rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/fma.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/fxsr.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/macros.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/mmx.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/mod.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/pclmulqdq.rs (97%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/rdrand.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/rdtsc.rs (97%) create mode 100644 src/stdarch/crates/core_arch/src/x86/rtm.rs rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sha.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sse.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sse2.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sse3.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sse41.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sse42.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/sse4a.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/ssse3.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/tbm.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/test.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86/xsave.rs (96%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/abm.rs (96%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/adx.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/avx.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/avx2.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/bmi.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/bmi2.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/bswap.rs (96%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/bt.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/cmpxchg16b.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/fxsr.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/rdrand.rs (97%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/sse.rs (98%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/sse2.rs (99%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/sse41.rs (96%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/sse42.rs (93%) rename src/{stdsimd => stdarch}/crates/core_arch/src/x86_64/xsave.rs (97%) rename src/{stdsimd => stdarch}/crates/core_arch/tests/cpu-detection.rs (97%) rename src/{stdsimd => stdarch}/crates/simd-test-macro/Cargo.toml (100%) rename src/{stdsimd => stdarch}/crates/simd-test-macro/src/lib.rs (98%) rename src/{stdsimd => stdarch}/crates/std_detect/Cargo.toml (65%) rename src/{stdsimd => stdarch}/crates/std_detect/LICENSE-APACHE (100%) rename src/{stdsimd => stdarch}/crates/std_detect/LICENSE-MIT (100%) rename src/{stdsimd => stdarch}/crates/std_detect/README.md (94%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/aarch64.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/arm.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/mips.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/mips64.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/powerpc.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/powerpc64.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/arch/x86.rs (96%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/bit.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/cache.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/error_macros.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/aarch64.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/freebsd/aarch64.rs (100%) create mode 100644 src/stdarch/crates/std_detect/src/detect/os/freebsd/arm.rs create mode 100644 src/stdarch/crates/std_detect/src/detect/os/freebsd/auxvec.rs rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/freebsd/mod.rs (60%) create mode 100644 src/stdarch/crates/std_detect/src/detect/os/freebsd/powerpc.rs rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/aarch64.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/arm.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/auxvec.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/cpuinfo.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/mips.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/linux/powerpc.rs (94%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/other.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/os/x86.rs (94%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/test_data/linux-rpi3.auxv (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/test_data/linux-x64-i7-6850k.auxv (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/detect/test_data/macos-virtualbox-linux-x86-4850HQ.auxv (100%) rename src/{stdsimd => stdarch}/crates/std_detect/src/lib.rs (97%) rename src/{stdsimd => stdarch}/crates/std_detect/src/mod.rs (100%) rename src/{stdsimd => stdarch}/crates/std_detect/tests/cpu-detection.rs (98%) rename src/{stdsimd => stdarch}/crates/std_detect/tests/macro_trailing_commas.rs (96%) rename src/{stdsimd/crates/stdsimd-test => stdarch/crates/stdarch-test}/Cargo.toml (85%) create mode 100644 src/stdarch/crates/stdarch-test/src/disassembly.rs rename src/{stdsimd/crates/stdsimd-test => stdarch/crates/stdarch-test}/src/lib.rs (56%) rename src/{stdsimd/crates/stdsimd-test => stdarch/crates/stdarch-test}/src/wasm.rs (59%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/Cargo.toml (87%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/arm-intrinsics.html (100%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/build.rs (100%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/mips-msa.h (100%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/src/lib.rs (94%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/tests/arm.rs (99%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/tests/mips.rs (98%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/tests/x86-intel.rs (72%) rename src/{stdsimd/crates/stdsimd-verify => stdarch/crates/stdarch-verify}/x86-intel.xml (100%) rename src/{stdsimd => stdarch}/examples/Cargo.toml (85%) rename src/{stdsimd => stdarch}/examples/hex.rs (98%) rename src/{stdsimd => stdarch}/examples/wasm.rs (100%) create mode 100644 src/stdarch/vendor.yml delete mode 100644 src/stdsimd/.travis.yml delete mode 100644 src/stdsimd/ci/docker/wasm32-unknown-unknown/Dockerfile delete mode 100755 src/stdsimd/crates/core_arch/foo.wasm delete mode 100644 src/stdsimd/crates/stdsimd-test/src/disassembly.rs delete mode 100644 src/stdsimd/vendor.yml rename src/test/compile-fail/{ => consts}/const-err3.rs (100%) rename src/test/compile-fail/{ => consts}/const-fn-error.rs (92%) create mode 100644 src/test/compile-fail/consts/issue-55878.rs create mode 100644 src/test/debuginfo/issue-57822.rs create mode 100644 src/test/mir-opt/issue-62289.rs delete mode 100644 src/test/mir-opt/lower_128bit_debug_test.rs delete mode 100644 src/test/mir-opt/lower_128bit_test.rs create mode 100644 src/test/pretty/attr-tokens-raw-ident.rs create mode 100644 src/test/pretty/delimited-token-groups.rs create mode 100644 src/test/pretty/macro.rs delete mode 100644 src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile delete mode 100644 src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs create mode 100644 src/test/run-make-fulldeps/reproducible-build-2/Makefile create mode 100644 src/test/run-make-fulldeps/reproducible-build-2/linker.rs create mode 100644 src/test/run-make-fulldeps/reproducible-build-2/reproducible-build-aux.rs create mode 100644 src/test/run-make-fulldeps/reproducible-build-2/reproducible-build.rs delete mode 100644 src/test/run-pass-fulldeps/issue-15778-pass.rs delete mode 100644 src/test/run-pass/attr-on-generic-formals.rs delete mode 100644 src/test/run-pass/auxiliary/arc_wake.rs delete mode 100644 src/test/run-pass/auxiliary/weak-lang-items.rs delete mode 100644 src/test/run-pass/coherence/auxiliary/coherence_copy_like_lib.rs delete mode 100644 src/test/run-pass/coherence/auxiliary/coherence_lib.rs delete mode 100644 src/test/run-pass/consts/auxiliary/const_fn_lib.rs delete mode 100644 src/test/run-pass/format-hygiene.rs create mode 100644 src/test/run-pass/generator/niche-in-generator.rs delete mode 100644 src/test/run-pass/hygiene/ty_params.rs delete mode 100644 src/test/run-pass/if-ret.stderr delete mode 100644 src/test/run-pass/macros/auxiliary/macro_crate_nonterminal.rs delete mode 100644 src/test/run-pass/macros/auxiliary/unstable-macros.rs delete mode 100644 src/test/run-pass/macros/macro-use-all-and-none.stderr delete mode 100644 src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-absolute.stderr delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-crate-paths/crate-path-visibility-ambiguity.stderr delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/test.rs delete mode 100644 src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs delete mode 100644 src/test/run-pass/traits/auxiliary/trait_safety_lib.rs delete mode 100644 src/test/run-pass/tydesc-name.rs create mode 100644 src/test/rustdoc/auxiliary/through-proc-macro-aux.rs create mode 100644 src/test/rustdoc/cfg-doctest.rs create mode 100644 src/test/rustdoc/deref-mut-methods.rs create mode 100644 src/test/rustdoc/inline_cross/add-docs.rs create mode 100644 src/test/rustdoc/inline_cross/auxiliary/add-docs.rs create mode 100644 src/test/rustdoc/intra-link-builtin-macros.rs create mode 100644 src/test/rustdoc/through-proc-macro.rs rename src/test/{run-pass-fulldeps => ui-fulldeps}/ast_stmt_expr_attr.rs (99%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-13560-1.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-13560-2.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-13560-3.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-16822.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-18502.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-24106.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/issue-40001-plugin.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/linkage-visibility.rs (100%) rename src/test/{run-pass-fulldeps/auxiliary/lint-for-crate.rs => ui-fulldeps/auxiliary/lint-for-crate-rpass.rs} (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/llvm-pass-plugin.rs (94%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/lto-syntax-extension-lib.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/lto-syntax-extension-plugin.rs (88%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/macro-crate-test.rs (97%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/outlive-expansion-phase.rs (94%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/plugin-args.rs (89%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/roman-numerals.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/auxiliary/syntax-extension-with-dll-deps-1.rs (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/compiler-calls.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/create-dir-all-bare.rs (94%) delete mode 100644 src/test/ui-fulldeps/deprecated-derive.rs delete mode 100644 src/test/ui-fulldeps/deprecated-derive.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/derive-no-std-not-supported.rs (95%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/deriving-encodable-decodable-box.rs (72%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/deriving-encodable-decodable-cell-refcell.rs (84%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/deriving-global.rs (93%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/deriving-hygiene.rs (84%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/dropck_tarena_sound_drop.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/empty-struct-braces-derive.rs (99%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/extern-mod-syntax.rs (92%) create mode 100644 src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs create mode 100644 src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-11881.rs (84%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-13560.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-14021.rs (97%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-15149.rs (99%) create mode 100644 src/test/ui-fulldeps/issue-15778-pass.rs rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-15924.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-16822.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-18502.rs (88%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-24106.rs (89%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-24972.rs (97%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-2804.rs (99%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-40001.rs (92%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-4016.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/issue-4036.rs (97%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/linkage-visibility.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/llvm-pass-plugin.rs (90%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/lto-syntax-extension.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/macro-crate-multi-decorator.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/mod_dir_path_canonicalized.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/mod_dir_simple/compiletest-ignore-dir (100%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/mod_dir_simple/test.rs (69%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/myriad-closures.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/newtype_index.rs (79%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/outlive-expansion-phase.rs (91%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/plugin-args-1.rs (92%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/plugin-args-2.rs (92%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/plugin-args-3.rs (94%) create mode 100644 src/test/ui-fulldeps/plugin-reexport.rs create mode 100644 src/test/ui-fulldeps/plugin-reexport.stderr rename src/test/{run-pass-fulldeps => ui-fulldeps}/pprust-expr-roundtrip.rs (99%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/regions-mock-tcx.rs (99%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/rename-directory.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/roman-numerals-macro.rs (96%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/rustc_encodable_hygiene.rs (95%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/stdio-from.rs (99%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/switch-stdout.rs (98%) rename src/test/{run-pass-fulldeps => ui-fulldeps}/undef_mask.rs (98%) rename src/test/{run-pass => ui}/abi-sysv64-arg-passing.rs (99%) rename src/test/{run-pass => ui}/abi-sysv64-register-usage.rs (99%) rename src/test/{run-pass => ui}/abi/issues/issue-62350-sysv-neg-reg-counts.rs (100%) rename src/test/{run-pass => ui}/abort-on-c-abi.rs (98%) rename src/test/{run-pass => ui}/alias-uninit-value.rs (96%) rename src/test/{run-pass => ui}/align-with-extern-c-fn.rs (93%) rename src/test/{run-pass => ui}/alignment-gep-tup-like-1.rs (97%) rename src/test/{run-pass => ui}/alloca-from-derived-tydesc.rs (95%) rename src/test/{run-pass => ui}/allocator-alloc-one.rs (96%) delete mode 100644 src/test/ui/allocator-submodule.rs delete mode 100644 src/test/ui/allocator-submodule.stderr create mode 100644 src/test/ui/allocator/allocator-args.rs create mode 100644 src/test/ui/allocator/allocator-args.stderr rename src/test/{run-pass => ui}/allocator/auxiliary/custom-as-global.rs (100%) rename src/test/{run-pass => ui}/allocator/auxiliary/custom.rs (100%) rename src/test/{run-pass => ui}/allocator/auxiliary/helper.rs (100%) create mode 100644 src/test/ui/allocator/custom-in-block.rs create mode 100644 src/test/ui/allocator/custom-in-submodule.rs rename src/test/{run-pass => ui}/allocator/custom.rs (100%) rename src/test/{run-pass => ui}/allocator/xcrate-use.rs (100%) rename src/test/{run-pass => ui}/allocator/xcrate-use2.rs (100%) rename src/test/{run-pass => ui}/anon-extern-mod.rs (96%) rename src/test/{run-pass => ui}/argument-passing.rs (97%) rename src/test/{run-pass => ui}/array-slice-vec/arr_cycle.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/array_const_index-1.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/box-of-array-of-drop-1.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/box-of-array-of-drop-2.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/cast-in-array-size.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/check-static-mut-slices.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/check-static-slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/copy-out-of-array-1.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/destructure-array-1.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/empty-mutable-vec.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/estr-slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/evec-slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/fixed_length_copy.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/huge-largest-array.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/ivec-pass-by-value.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/mutable-alias-vec.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/nested-vec-1.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/nested-vec-2.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/nested-vec-3.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/new-style-fixed-length-vec.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/rcvr-borrowed-to-slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/repeated-vector-syntax.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/show-boxed-slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/slice-2.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/slice-of-zero-size-elements.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/slice-panic-1.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/slice-panic-2.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/slice_binary_search.rs (100%) create mode 100644 src/test/ui/array-slice-vec/subslice-patterns-pass.rs rename src/test/{run-pass => ui}/array-slice-vec/variance-vec-covariant.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-concat.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-dst.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-fixed-length.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-growth.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-late-init.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-macro-no-std.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-macro-repeat.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-macro-rvalue-scope.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-macro-with-brackets.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-macro-with-trailing-comma.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-matching-autoslice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-matching-fixed.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-matching-fold.rs (92%) rename src/test/{run-pass => ui}/array-slice-vec/vec-matching-legal-tail-element-borrow.rs (86%) rename src/test/{run-pass => ui}/array-slice-vec/vec-matching.rs (82%) rename src/test/{run-pass => ui}/array-slice-vec/vec-push.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-repeat-with-cast.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-slice-drop.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-slice.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec-tail-matching.rs (88%) rename src/test/{run-pass => ui}/array-slice-vec/vec-to_str.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec_cycle.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vec_cycle_wrapped.rs (100%) rename src/test/{run-pass => ui}/array-slice-vec/vector-no-ann-2.rs (100%) rename src/test/{run-pass => ui}/artificial-block.rs (84%) rename src/test/{run-pass => ui}/as-precedence.rs (93%) rename src/test/{run-pass => ui}/asm-concat-src.rs (91%) rename src/test/{run-pass => ui}/asm-in-moved.rs (98%) rename src/test/{run-pass => ui}/asm-in-out-operand.rs (99%) rename src/test/{run-pass => ui}/asm-indirect-memory.rs (98%) rename src/test/{run-pass => ui}/asm-out-assign.rs (97%) rename src/test/{run-pass => ui}/assert-eq-trailing-comma.rs (74%) rename src/test/{run-pass => ui}/assert-escape.rs (82%) rename src/test/{run-pass => ui}/assert-ne-trailing-comma.rs (74%) rename src/test/{run-pass => ui}/assign-assign.rs (98%) rename src/test/{run-pass => ui}/assoc-oddities-3.rs (95%) rename src/test/{run-pass => ui}/associated-consts/associated-const-const-eval.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-cross-crate-const-eval.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-cross-crate-defaults.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-cross-crate.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-in-global-const.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-inherent-impl.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-marks-live-code.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-match-patterns.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-outer-ty-refs.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-overwrite-default.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-public-impl.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-range-match-patterns.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-resolution-order.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-self-type.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-type-parameters.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-ufcs-infer-trait.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-use-default.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const-use-impl-of-same-trait.rs (100%) rename src/test/{run-pass => ui}/associated-consts/associated-const.rs (100%) rename src/test/{run-pass => ui}/associated-consts/auxiliary/associated-const-cc-lib.rs (100%) rename src/test/{run-pass => ui}/associated-consts/auxiliary/empty-struct.rs (100%) rename src/test/{run-pass => ui}/associated-item-long-paths.rs (98%) create mode 100644 src/test/ui/associated-type-bounds/ambiguous-associated-type.rs rename src/test/ui/associated-type-bounds/{dyn-existential-type.rs => dyn-impl-trait-type.rs} (98%) create mode 100644 src/test/ui/associated-type-bounds/issue-61752.rs rename src/test/ui/associated-type-bounds/{existential-type.rs => trait-alias-impl-trait.rs} (84%) rename src/test/{run-pass => ui}/associated-types/associated-types-basic.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-binding-in-trait.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-binding-in-where-clause.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-bound.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-cc.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-conditional-dispatch.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-constant-type.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-doubleendediterator-object.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-duplicate-binding-in-env.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-enum-field-named.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-enum-field-numbered.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-eq-obj.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-from-supertrait.rs (87%) rename src/test/{run-pass => ui}/associated-types/associated-types-impl-redirect.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-in-bound-type-arg.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-in-default-method.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-in-fn.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-in-impl-generics.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-in-inherent-method.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-issue-20220.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-issue-20371.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-issue-21212.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-iterator-binding.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-method.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-nested-projections.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-normalize-in-bounds-binding.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-normalize-in-bounds-ufcs.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-normalize-in-bounds.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-normalize-unifield-struct.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-projection-bound-in-supertraits.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-projection-from-known-type-in-impl.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-projection-in-object-type.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-projection-in-supertrait.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-projection-in-where-clause.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-projection-to-unrelated-trait.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-ref-from-struct.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-ref-in-struct-literal.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-region-erasure-issue-20582.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-resolve-lifetime.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-return.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-simple.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-stream.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-struct-field-named.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-struct-field-numbered.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-sugar-path.rs (100%) rename src/test/{run-pass => ui}/associated-types/associated-types-where-clause-impl-ambiguity.rs (100%) rename src/test/{run-pass => ui}/associated-types/auxiliary/associated-types-cc-lib.rs (100%) create mode 100644 src/test/ui/async-await/async-block-control-flow-static-semantics.rs create mode 100644 src/test/ui/async-await/async-block-control-flow-static-semantics.stderr create mode 100644 src/test/ui/async-await/async-closure-matches-expr.rs create mode 100644 src/test/ui/async-await/async-closure.rs create mode 100644 src/test/ui/async-await/async-error-span.rs create mode 100644 src/test/ui/async-await/async-error-span.stderr rename src/test/{run-pass => ui}/async-await/async-fn-size-moved-locals.rs (82%) rename src/test/{run-pass => ui}/async-await/async-fn-size.rs (81%) create mode 100644 src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs create mode 100644 src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr rename src/test/ui/async-await/await-keyword/{2015-edition-error-in-non-macro-position.rs => 2015-edition-error-various-positions.rs} (89%) rename src/test/ui/async-await/await-keyword/{2015-edition-error-in-non-macro-position.stderr => 2015-edition-error-various-positions.stderr} (78%) delete mode 100644 src/test/ui/async-await/await-macro.rs create mode 100644 src/test/ui/async-await/await-unsize.rs create mode 100644 src/test/ui/async-await/bound-normalization.rs create mode 100644 src/test/ui/async-await/conditional-and-guaranteed-initialization.rs create mode 100644 src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs create mode 100644 src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs create mode 100644 src/test/ui/async-await/feature-async-closure.rs create mode 100644 src/test/ui/async-await/feature-async-closure.stderr rename src/test/{run-pass => ui/async-await}/futures-api.rs (98%) rename src/test/{run-pass => ui}/async-await/issue-60709.rs (90%) create mode 100644 src/test/ui/async-await/issue-62658.rs rename src/test/ui/async-await/issues/{issue-62009.rs => issue-62009-1.rs} (80%) rename src/test/ui/async-await/issues/{issue-62009.stderr => issue-62009-1.stderr} (62%) create mode 100644 src/test/ui/async-await/issues/issue-62009-2.rs create mode 100644 src/test/ui/async-await/issues/issue-62009-2.stderr create mode 100644 src/test/ui/async-await/move-part-await-return-rest-struct.rs create mode 100644 src/test/ui/async-await/move-part-await-return-rest-tuple.rs create mode 100644 src/test/ui/async-await/no-move-across-await-struct.rs create mode 100644 src/test/ui/async-await/no-move-across-await-struct.stderr create mode 100644 src/test/ui/async-await/no-move-across-await-tuple.rs create mode 100644 src/test/ui/async-await/no-move-across-await-tuple.stderr create mode 100644 src/test/ui/async-await/no-non-guaranteed-initialization.rs create mode 100644 src/test/ui/async-await/no-non-guaranteed-initialization.stderr create mode 100644 src/test/ui/async-await/partial-initialization-across-await.rs create mode 100644 src/test/ui/async-await/partial-initialization-across-await.stderr create mode 100644 src/test/ui/async-await/suggest-missing-await-closure.fixed create mode 100644 src/test/ui/async-await/suggest-missing-await-closure.rs create mode 100644 src/test/ui/async-await/suggest-missing-await-closure.stderr rename src/test/{run-pass => ui}/atomic-access-bool.rs (98%) rename src/test/{run-pass => ui}/atomic-alignment.rs (99%) rename src/test/{run-pass => ui}/atomic-compare_exchange.rs (99%) rename src/test/{run-pass => ui}/atomic-print.rs (98%) rename src/test/{run-pass => ui}/attr-main-2.rs (84%) rename src/test/{run-pass => ui}/attr-main.rs (85%) rename src/test/{run-pass => ui}/attr-shebang.rs (86%) rename src/test/{run-pass => ui}/attr-start.rs (91%) rename src/test/{run-pass => ui}/attr.rs (85%) rename src/test/{run-pass => ui}/augmented-assignments-feature-gate-cross.rs (92%) rename src/test/{run-pass => ui}/augmented-assignments-feature-gate.rs (92%) rename src/test/{run-pass/augmented-assignments.rs => ui/augmented-assignments-rpass.rs} (99%) rename src/test/{run-pass => ui}/auto-instantiate.rs (95%) rename src/test/{run-pass => ui}/auto-is-contextual.rs (93%) rename src/test/{run-pass => ui}/autobind.rs (96%) rename src/test/{run-pass => ui}/autoref-autoderef/auto-ref-bounded-ty-param.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/auto-ref-sliceable.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/auto-ref.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-and-borrow-method-receiver.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-method-on-trait.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-method-priority.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-method-twice.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-method.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoderef-privacy.rs (100%) rename src/test/{run-pass => ui}/autoref-autoderef/autoref-intermediate-types-issue-3585.rs (100%) rename src/test/{run-pass => ui}/auxiliary/anon-extern-mod-cross-crate-1.rs (100%) rename src/test/{run-pass => ui}/auxiliary/augmented_assignments.rs (100%) rename src/test/{run-pass => ui}/auxiliary/blind-item-mixed-crate-use-item-foo.rs (100%) rename src/test/{run-pass => ui}/auxiliary/blind-item-mixed-crate-use-item-foo2.rs (100%) rename src/test/{run-pass => ui}/auxiliary/check_static_recursion_foreign_helper.rs (100%) rename src/test/{run-pass => ui}/auxiliary/cond_plugin.rs (100%) rename src/test/{run-pass => ui}/auxiliary/crate-method-reexport-grrrrrrr2.rs (100%) rename src/test/{run-pass => ui}/auxiliary/debuginfo-lto-aux.rs (100%) rename src/test/{run-pass => ui}/auxiliary/edition-kw-macro-2015.rs (100%) rename src/test/{run-pass => ui}/auxiliary/edition-kw-macro-2018.rs (100%) rename src/test/{run-pass => ui}/auxiliary/foreign_lib.rs (100%) rename src/test/{run-pass => ui}/auxiliary/hello_macro.rs (100%) rename src/test/{run-pass => ui}/auxiliary/impl_privacy_xc_1.rs (100%) rename src/test/{run-pass => ui}/auxiliary/impl_privacy_xc_2.rs (100%) rename src/test/{run-pass => ui}/auxiliary/inline_dtor.rs (100%) rename src/test/{run-pass => ui}/auxiliary/inner_static.rs (100%) rename src/test/{run-pass => ui}/auxiliary/kinds_in_metadata.rs (100%) rename src/test/{run-pass => ui}/auxiliary/link-cfg-works-transitive-dylib.rs (100%) rename src/test/{run-pass => ui}/auxiliary/link-cfg-works-transitive-rlib.rs (100%) rename src/test/{run-pass => ui}/auxiliary/linkage1.rs (100%) rename src/test/{run-pass => ui}/auxiliary/llvm_pr32379.rs (100%) rename src/test/{run-pass => ui}/auxiliary/msvc-data-only-lib.rs (100%) rename src/test/{run-pass => ui}/auxiliary/nested_item.rs (100%) rename src/test/{run-pass => ui}/auxiliary/proc_macro_def.rs (100%) rename src/test/{run-pass => ui}/auxiliary/reachable-unnameable-items.rs (100%) rename src/test/{run-pass => ui}/auxiliary/reexport-should-still-link.rs (100%) rename src/test/{run-pass/auxiliary/rmeta-rlib.rs => ui/auxiliary/rmeta-rlib-rpass.rs} (100%) rename src/test/{run-pass => ui}/auxiliary/rmeta-rmeta.rs (100%) rename src/test/{run-pass => ui}/auxiliary/svh-a-base.rs (100%) rename src/test/{run-pass => ui}/auxiliary/svh-b.rs (100%) rename src/test/{run-pass => ui}/auxiliary/trait_superkinds_in_metadata.rs (100%) rename src/test/{run-pass => ui}/auxiliary/typeid-intrinsic-aux1.rs (100%) rename src/test/{run-pass => ui}/auxiliary/typeid-intrinsic-aux2.rs (100%) rename src/test/{run-pass => ui}/auxiliary/using-target-feature-unstable.rs (100%) rename src/test/{run-pass => ui}/backtrace-debuginfo-aux.rs (97%) rename src/test/{run-pass => ui}/backtrace-debuginfo.rs (85%) rename src/test/{run-pass => ui}/backtrace.rs (98%) rename src/test/{run-pass => ui}/bare-fn-implements-fn-mut.rs (96%) rename src/test/{run-pass => ui}/bare-static-string.rs (85%) rename src/test/{run-pass => ui}/bench/issue-32062.rs (100%) rename src/test/{run-pass => ui}/big-literals.rs (97%) rename src/test/{run-pass => ui}/binary-minus-without-space.rs (91%) rename src/test/{run-pass => ui}/bind-by-move.rs (93%) rename src/test/{run-pass => ui}/binding/bind-field-short-with-modifiers.rs (100%) rename src/test/{run-pass => ui}/binding/borrowed-ptr-pattern-2.rs (100%) rename src/test/{run-pass => ui}/binding/borrowed-ptr-pattern-3.rs (100%) rename src/test/{run-pass => ui}/binding/borrowed-ptr-pattern-infallible.rs (100%) rename src/test/{run-pass => ui}/binding/borrowed-ptr-pattern-option.rs (100%) rename src/test/{run-pass => ui}/binding/borrowed-ptr-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/empty-types-in-patterns.rs (100%) rename src/test/{run-pass => ui}/binding/exhaustive-bool-match-sanity.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match-generic-unique1.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match-generic-unique2.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match-generic.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match-panic-all.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match-panic.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match-unique.rs (100%) rename src/test/{run-pass => ui}/binding/expr-match.rs (100%) rename src/test/{run-pass => ui}/binding/fat-arrow-match.rs (100%) rename src/test/{run-pass => ui}/binding/fn-arg-incomplete-pattern-drop-order.rs (99%) rename src/test/{run-pass => ui}/binding/fn-pattern-expected-type-2.rs (100%) rename src/test/{run-pass => ui}/binding/fn-pattern-expected-type.rs (100%) rename src/test/{run-pass => ui}/binding/func-arg-incomplete-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/func-arg-ref-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/func-arg-wild-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/if-let.rs (100%) rename src/test/{run-pass => ui}/binding/inconsistent-lifetime-mismatch.rs (100%) rename src/test/{run-pass => ui}/binding/inferred-suffix-in-pattern-range.rs (100%) rename src/test/{run-pass => ui}/binding/irrefutable-slice-patterns.rs (86%) rename src/test/{run-pass => ui}/binding/let-assignability.rs (100%) rename src/test/{run-pass => ui}/binding/let-destruct-ref.rs (100%) rename src/test/{run-pass => ui}/binding/let-var-hygiene.rs (100%) rename src/test/{run-pass => ui}/binding/match-arm-statics.rs (100%) rename src/test/{run-pass => ui}/binding/match-beginning-vert.rs (100%) rename src/test/{run-pass => ui}/binding/match-borrowed_str.rs (100%) rename src/test/{run-pass => ui}/binding/match-bot-2.rs (100%) rename src/test/{run-pass => ui}/binding/match-bot.rs (100%) rename src/test/{run-pass => ui}/binding/match-byte-array-patterns.rs (100%) rename src/test/{run-pass => ui}/binding/match-enum-struct-0.rs (100%) rename src/test/{run-pass => ui}/binding/match-enum-struct-1.rs (100%) rename src/test/{run-pass => ui}/binding/match-implicit-copy-unique.rs (100%) rename src/test/{run-pass => ui}/binding/match-in-macro.rs (100%) rename src/test/{run-pass => ui}/binding/match-join.rs (100%) rename src/test/{run-pass => ui}/binding/match-larger-const.rs (100%) rename src/test/{run-pass => ui}/binding/match-naked-record-expr.rs (100%) rename src/test/{run-pass => ui}/binding/match-naked-record.rs (100%) rename src/test/{run-pass => ui}/binding/match-path.rs (100%) rename src/test/{run-pass => ui}/binding/match-pattern-bindings.rs (100%) rename src/test/{run-pass => ui}/binding/match-pattern-lit.rs (100%) rename src/test/{run-pass => ui}/binding/match-pattern-no-type-params.rs (100%) rename src/test/{run-pass => ui}/binding/match-pattern-simple.rs (100%) rename src/test/{run-pass => ui}/binding/match-phi.rs (100%) rename src/test/{run-pass => ui}/binding/match-pipe-binding.rs (100%) rename src/test/{run-pass => ui}/binding/match-range-infer.rs (100%) rename src/test/{run-pass => ui}/binding/match-range-static.rs (100%) rename src/test/{run-pass => ui}/binding/match-range.rs (100%) rename src/test/{run-pass => ui}/binding/match-reassign.rs (100%) rename src/test/{run-pass => ui}/binding/match-ref-binding-in-guard-3256.rs (100%) rename src/test/{run-pass => ui}/binding/match-ref-binding-mut-option.rs (100%) rename src/test/{run-pass => ui}/binding/match-ref-binding-mut.rs (100%) rename src/test/{run-pass => ui}/binding/match-ref-binding.rs (100%) rename src/test/{run-pass => ui}/binding/match-ref-unsized.rs (100%) rename src/test/{run-pass => ui}/binding/match-str.rs (100%) rename src/test/{run-pass => ui}/binding/match-struct-0.rs (100%) rename src/test/{run-pass => ui}/binding/match-tag.rs (100%) rename src/test/{run-pass => ui}/binding/match-unique-bind.rs (100%) rename src/test/{run-pass => ui}/binding/match-unsized.rs (100%) rename src/test/{run-pass => ui}/binding/match-value-binding-in-guard-3291.rs (100%) rename src/test/{run-pass => ui}/binding/match-var-hygiene.rs (100%) rename src/test/{run-pass => ui}/binding/match-vec-alternatives.rs (100%) rename src/test/{run-pass => ui}/binding/match-vec-rvalue.rs (100%) rename src/test/{run-pass => ui}/binding/match-with-ret-arm.rs (100%) rename src/test/{run-pass => ui}/binding/multi-let.rs (100%) rename src/test/{run-pass => ui}/binding/mut-in-ident-patterns.rs (100%) rename src/test/{run-pass => ui}/binding/nested-exhaustive-match.rs (100%) rename src/test/{run-pass => ui}/binding/nested-matchs.rs (100%) rename src/test/{run-pass => ui}/binding/nested-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/nil-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/nullary-or-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/optional_comma_in_match_arm.rs (100%) rename src/test/{run-pass => ui}/binding/or-pattern.rs (100%) rename src/test/{run-pass => ui}/binding/order-drop-with-match.rs (100%) rename src/test/{run-pass => ui}/binding/pat-ranges.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-1.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-2.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-3.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-4.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-5.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-6.rs (100%) rename src/test/{run-pass => ui}/binding/pat-tuple-7.rs (100%) rename src/test/{run-pass => ui}/binding/pattern-bound-var-in-for-each.rs (100%) rename src/test/{run-pass => ui}/binding/pattern-in-closure.rs (100%) rename src/test/{run-pass => ui}/binding/range-inclusive-pattern-precedence.rs (100%) rename src/test/{run-pass => ui}/binding/simple-generic-match.rs (100%) rename src/test/{run-pass => ui}/binding/use-uninit-match.rs (100%) rename src/test/{run-pass => ui}/binding/use-uninit-match2.rs (100%) rename src/test/{run-pass => ui}/binding/zero_sized_subslice_match.rs (73%) rename src/test/{run-pass => ui}/binops-issue-22743.rs (96%) rename src/test/{run-pass => ui}/binops.rs (99%) rename src/test/{run-pass => ui}/bitwise.rs (98%) rename src/test/{run-pass => ui}/blind-item-local-shadow.rs (93%) rename src/test/{run-pass => ui}/blind-item-mixed-crate-use-item.rs (97%) rename src/test/{run-pass => ui}/blind-item-mixed-use-item.rs (95%) rename src/test/{run-pass => ui}/block-arg-call-as.rs (92%) rename src/test/{run-pass => ui}/block-arg.rs (95%) rename src/test/{run-pass => ui}/block-explicit-types.rs (93%) rename src/test/{run-pass => ui}/block-expr-precedence.rs (99%) rename src/test/{run-pass => ui}/block-fn-coerce.rs (93%) rename src/test/{run-pass => ui}/block-iter-1.rs (95%) rename src/test/{run-pass => ui}/block-iter-2.rs (96%) rename src/test/{run-pass => ui}/bool-not.rs (91%) rename src/test/{run-pass => ui}/bool.rs (99%) rename src/test/{run-pass => ui}/borrow-by-val-method-receiver.rs (92%) create mode 100644 src/test/ui/borrowck/assign-never-type.rs rename src/test/{run-pass => ui}/borrowck/borrowck-assign-to-subfield.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-assignment-to-static-mut.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-binding-mutbl.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-borrow-from-expr-block.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-closures-two-imm.rs (100%) create mode 100644 src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr rename src/test/{run-pass/borrowck/borrowck-field-sensitivity.rs => ui/borrowck/borrowck-field-sensitivity-rpass.rs} (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-fixed-length-vecs.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-freeze-frozen-mut.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-lend-args.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-macro-interaction-issue-6304.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-move-by-capture-ok.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-multiple-borrows-interior-boxes.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-mut-uniq.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-mut-vec-as-imm-slice.rs (100%) delete mode 100644 src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr rename src/test/{run-pass => ui}/borrowck/borrowck-pat-enum.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-pat-reassign-no-binding.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-rvalues-mutable.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-scope-of-deref-issue-4666.rs (100%) rename src/test/{run-pass/borrowck/borrowck-slice-pattern-element-loan.rs => ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs} (89%) rename src/test/{run-pass => ui}/borrowck/borrowck-static-item-in-fn.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-trait-lifetime.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-uniq-via-ref.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-univariant-enum.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-unsafe-static-mutable-borrows.rs (100%) rename src/test/{run-pass => ui}/borrowck/borrowck-unused-mut-locals.rs (100%) rename src/test/{run-pass/borrowck/borrowck-use-mut-borrow.rs => ui/borrowck/borrowck-use-mut-borrow-rpass.rs} (100%) create mode 100644 src/test/ui/borrowck/disallow-possibly-uninitialized.rs create mode 100644 src/test/ui/borrowck/disallow-possibly-uninitialized.stderr create mode 100644 src/test/ui/borrowck/issue-27282-mutation-in-guard.rs create mode 100644 src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr create mode 100644 src/test/ui/borrowck/issue-31287-drop-in-guard.rs create mode 100644 src/test/ui/borrowck/issue-31287-drop-in-guard.stderr rename src/test/{run-pass => ui}/borrowck/issue-62007-assign-box.rs (100%) rename src/test/{run-pass => ui}/borrowck/issue-62007-assign-field.rs (100%) create mode 100644 src/test/ui/borrowck/issue-62107-match-arm-scopes.rs create mode 100644 src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr create mode 100644 src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr rename src/test/{run-pass => ui}/borrowck/two-phase-baseline.rs (100%) rename src/test/{run-pass => ui}/borrowck/two-phase-bin-ops.rs (100%) rename src/test/{run-pass => ui}/borrowck/two-phase-control-flow-split-before-activation.rs (100%) create mode 100644 src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr rename src/test/{run-pass => ui}/box-new.rs (85%) rename src/test/{run-pass => ui}/bug-7183-generics.rs (98%) rename src/test/{run-pass => ui}/bug-7295.rs (93%) rename src/test/{run-pass => ui}/builtin-clone-unwind.rs (98%) rename src/test/{run-pass => ui}/builtin-clone.rs (98%) rename src/test/{run-pass => ui}/builtin-superkinds-capabilities-transitive.rs (98%) rename src/test/{run-pass => ui}/builtin-superkinds-capabilities-xc.rs (98%) rename src/test/{run-pass => ui}/builtin-superkinds-capabilities.rs (97%) rename src/test/{run-pass => ui}/builtin-superkinds-in-metadata.rs (97%) rename src/test/{run-pass => ui}/builtin-superkinds-phantom-typaram.rs (96%) rename src/test/{run-pass => ui}/builtin-superkinds-simple.rs (93%) rename src/test/{run-pass => ui}/builtin-superkinds-typaram.rs (94%) rename src/test/{run-pass => ui}/byte-literals.rs (99%) rename src/test/{run-pass => ui}/c-stack-as-value.rs (96%) rename src/test/{run-pass => ui}/c-stack-returning-int64.rs (98%) rename src/test/{run-pass => ui}/cabi-int-widening.rs (95%) rename src/test/{run-pass => ui}/can-copy-pod.rs (96%) rename src/test/{run-pass => ui}/cancel-clean-via-immediate-rvalue-ref.rs (92%) rename src/test/{run-pass => ui}/cast-does-fallback.rs (95%) rename src/test/{run-pass => ui}/cast-region-to-uint.rs (88%) rename src/test/{run-pass => ui}/cast-rfc0401-vtable-kinds.rs (99%) rename src/test/{run-pass => ui}/cast-rfc0401.rs (99%) rename src/test/{run-pass => ui}/cast-to-infer-ty.rs (93%) rename src/test/{run-pass => ui}/cast.rs (97%) rename src/test/{run-pass => ui}/catch-unwind-bang.rs (93%) rename src/test/{run-pass => ui}/cell-does-not-clone.rs (97%) rename src/test/{run-pass => ui}/cfg/auxiliary/cfg_inner_static.rs (100%) rename src/test/{run-pass => ui}/cfg/auxiliary/crate-attributes-using-cfg_attr.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-attr-cfg.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-attr-crate.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-family.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-in-crate-1.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-macros-foo.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-macros-notfoo.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-match-arm.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-target-family.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg-target-vendor.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg_attr.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg_inner_static.rs (100%) rename src/test/{run-pass => ui}/cfg/cfg_stmt_expr.rs (100%) rename src/test/{run-pass => ui}/cfg/cfgs-on-items.rs (100%) rename src/test/{run-pass => ui}/cfg/conditional-compile-arch.rs (100%) rename src/test/{run-pass => ui}/cfg/conditional-compile.rs (100%) rename src/test/{run-pass => ui}/cfg/crate-attributes-using-cfg_attr.rs (100%) rename src/test/{run-pass => ui}/chalkify/builtin-copy-clone.rs (98%) rename src/test/{run-pass => ui}/chalkify/inherent_impl.rs (98%) rename src/test/{run-pass => ui}/chalkify/projection.rs (96%) rename src/test/{run-pass => ui}/chalkify/super_trait.rs (95%) rename src/test/{run-pass => ui}/chalkify/trait_implied_bound.rs (95%) rename src/test/{run-pass => ui}/chalkify/type_implied_bound.rs (97%) rename src/test/{run-pass => ui}/char.rs (94%) rename src/test/{run-pass => ui}/char_unicode.rs (95%) rename src/test/{run-pass => ui}/check-static-recursion-foreign.rs (97%) rename src/test/{run-pass => ui}/check_const-feature-gated.rs (84%) rename src/test/{run-pass => ui}/child-outlives-parent.rs (95%) rename src/test/{run-pass => ui}/cleanup-arm-conditional.rs (98%) rename src/test/{run-pass => ui}/cleanup-rvalue-during-if-and-while.rs (98%) rename src/test/{run-pass => ui}/cleanup-rvalue-for-scope.rs (98%) rename src/test/{run-pass => ui}/cleanup-rvalue-scopes.rs (99%) rename src/test/{run-pass => ui}/cleanup-rvalue-temp-during-incomplete-alloc.rs (98%) rename src/test/{run-pass => ui}/cleanup-shortcircuit.rs (98%) rename src/test/{run-pass => ui}/clone-with-exterior.rs (96%) rename src/test/{run-pass => ui}/close-over-big-then-small-data.rs (98%) rename src/test/{run-pass => ui}/cmp-default.rs (99%) rename src/test/{run-pass => ui}/codegen-object-shim.rs (90%) rename src/test/{run-pass => ui}/coerce/coerce-expect-unsized.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-overloaded-autoderef.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-imm-ptr-arg.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-imm-ptr-rcvr.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-imm-vec-arg.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-imm-vec-rcvr.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-mut-ptr-arg.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-mut-ptr-rcvr.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-mut-vec-arg.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-reborrow-mut-vec-rcvr.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-unify-return.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-unify.rs (100%) rename src/test/{run-pass => ui}/coerce/coerce-unsize-subtype.rs (100%) rename src/test/{run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs => ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs} (77%) rename src/test/{run-pass => ui}/coherence/coherence-bigint-int.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-bigint-vecint.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-blanket.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-covered-type-parameter.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-impl-in-fn.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-iterator-vec-any-elem.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-iterator-vec.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-multidispatch-tuple.rs (100%) rename src/test/{run-pass/coherence/coherence-negative-impls-safe.rs => ui/coherence/coherence-negative-impls-safe-rpass.rs} (100%) rename src/test/{run-pass => ui}/coherence/coherence-rfc447-constrained.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence-where-clause.rs (100%) rename src/test/{run-pass => ui}/coherence/coherence_copy_like.rs (100%) create mode 100644 src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs rename src/test/{run-pass/coherence/re-rebalance-coherence.rs => ui/coherence/re-rebalance-coherence-rpass.rs} (100%) rename src/test/{run-pass => ui}/collections-const-new.rs (95%) rename src/test/{run-pass => ui}/command-exec.rs (99%) rename src/test/{run-pass => ui}/command-pre-exec.rs (99%) create mode 100644 src/test/ui/command-uid-gid.rs rename src/test/{run-pass => ui}/complex.rs (98%) rename src/test/{run-pass/concat.rs => ui/concat-rpass.rs} (97%) create mode 100644 src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs create mode 100644 src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs create mode 100644 src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr create mode 100644 src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs create mode 100644 src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr create mode 100644 src/test/ui/const-generics/array-impls/core-traits-impls-length-32.rs create mode 100644 src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs create mode 100644 src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr rename src/test/{run-pass => ui}/consts/assoc-const.rs (100%) rename src/test/{run-pass => ui}/consts/auxiliary/anon-extern-mod-cross-crate-1.rs (100%) rename src/test/{run-pass => ui}/consts/auxiliary/cci_borrow_lib.rs (100%) rename src/test/{run-pass => ui}/consts/auxiliary/cci_const.rs (100%) rename src/test/{run-pass => ui}/consts/auxiliary/cci_const_block.rs (100%) rename src/test/{run-pass => ui}/consts/bswap-const.rs (100%) rename src/test/{run-pass => ui}/consts/chained-constants-stackoverflow.rs (100%) rename src/test/{run-pass => ui}/consts/const-adt-align-mismatch.rs (100%) rename src/test/{run-pass => ui}/consts/const-autoderef.rs (100%) rename src/test/{run-pass => ui}/consts/const-big-enum.rs (100%) rename src/test/{run-pass => ui}/consts/const-binops.rs (100%) rename src/test/{run-pass => ui}/consts/const-bitshift-rhs-inference.rs (100%) rename src/test/{run-pass => ui}/consts/const-block-cross-crate-fn.rs (100%) rename src/test/{run-pass => ui}/consts/const-block-item-macro-codegen.rs (100%) rename src/test/{run-pass => ui}/consts/const-block-item.rs (100%) rename src/test/{run-pass => ui}/consts/const-block-non-item-statement-3.rs (100%) rename src/test/{run-pass/consts/const-block-non-item-statement.rs => ui/consts/const-block-non-item-statement-rpass.rs} (100%) rename src/test/{run-pass => ui}/consts/const-block.rs (100%) rename src/test/{run-pass => ui}/consts/const-bound.rs (100%) rename src/test/{run-pass => ui}/consts/const-byte-str-cast.rs (100%) rename src/test/{run-pass => ui}/consts/const-cast-ptr-int.rs (100%) rename src/test/{run-pass => ui}/consts/const-cast.rs (100%) rename src/test/{run-pass => ui}/consts/const-const.rs (100%) rename src/test/{run-pass => ui}/consts/const-contents.rs (100%) rename src/test/{run-pass => ui}/consts/const-cross-crate-const.rs (100%) rename src/test/{run-pass => ui}/consts/const-cross-crate-extern.rs (100%) rename src/test/{run-pass => ui}/consts/const-deref.rs (100%) rename src/test/{run-pass => ui}/consts/const-endianess.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-byref-self.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-byref.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-cast.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-ptr.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-struct.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-struct2.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-structlike.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-tuple.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-tuple2.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-tuplestruct.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-tuplestruct2.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-vec-index.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-vec-ptr.rs (100%) rename src/test/{run-pass => ui}/consts/const-enum-vector.rs (100%) rename src/test/{run-pass/consts/const-err.rs => ui/consts/const-err-rpass.rs} (100%) create mode 100644 src/test/ui/consts/const-eval/issue-62272.rs rename src/test/{run-pass => ui}/consts/const-expr-in-fixed-length-vec.rs (100%) rename src/test/{run-pass => ui}/consts/const-expr-in-vec-repeat.rs (100%) rename src/test/{run-pass => ui}/consts/const-extern-function.rs (100%) rename src/test/{run-pass => ui}/consts/const-fields-and-indexing.rs (100%) rename src/test/{run-pass => ui}/consts/const-fn-const-eval.rs (100%) rename src/test/{run-pass => ui}/consts/const-fn-feature-flags.rs (100%) rename src/test/{run-pass => ui}/consts/const-fn-method.rs (100%) rename src/test/{run-pass => ui}/consts/const-fn-nested.rs (100%) rename src/test/{run-pass => ui}/consts/const-fn-stability-calls.rs (100%) create mode 100644 src/test/ui/consts/const-fn-type-name-any.rs rename src/test/{run-pass => ui}/consts/const-fn-type-name.rs (93%) rename src/test/{run-pass => ui}/consts/const-fn-val.rs (100%) rename src/test/{run-pass => ui}/consts/const-fn.rs (100%) rename src/test/{run-pass => ui}/consts/const-index-feature-gate.rs (100%) rename src/test/{run-pass/consts/const-int-conversion.rs => ui/consts/const-int-conversion-rpass.rs} (98%) rename src/test/{run-pass/consts/const-int-overflowing.rs => ui/consts/const-int-overflowing-rpass.rs} (98%) rename src/test/{run-pass/consts/const-int-rotate.rs => ui/consts/const-int-rotate-rpass.rs} (99%) rename src/test/{run-pass => ui}/consts/const-int-saturating-arith.rs (99%) rename src/test/{run-pass/consts/const-int-sign.rs => ui/consts/const-int-sign-rpass.rs} (97%) rename src/test/{run-pass/consts/const-int-wrapping.rs => ui/consts/const-int-wrapping-rpass.rs} (98%) rename src/test/{run-pass => ui}/consts/const-labeled-break.rs (84%) rename src/test/{run-pass => ui}/consts/const-meth-pattern.rs (100%) rename src/test/{run-pass => ui}/consts/const-needs_drop.rs (98%) rename src/test/{run-pass => ui}/consts/const-negation.rs (100%) rename src/test/{run-pass => ui}/consts/const-negative.rs (100%) rename src/test/{run-pass => ui}/consts/const-nullary-enum.rs (100%) rename src/test/{run-pass => ui}/consts/const-nullary-univariant-enum.rs (100%) rename src/test/{run-pass => ui}/consts/const-pattern-variant.rs (100%) rename src/test/{run-pass/consts/const-ptr-nonnull.rs => ui/consts/const-ptr-nonnull-rpass.rs} (100%) rename src/test/{run-pass/consts/const-ptr-unique.rs => ui/consts/const-ptr-unique-rpass.rs} (100%) rename src/test/{run-pass => ui}/consts/const-rec-and-tup.rs (100%) rename src/test/{run-pass => ui}/consts/const-region-ptrs-noncopy.rs (100%) rename src/test/{run-pass => ui}/consts/const-region-ptrs.rs (100%) rename src/test/{run-pass => ui}/consts/const-repeated-values.rs (100%) rename src/test/{run-pass => ui}/consts/const-size_of-align_of.rs (100%) rename src/test/{run-pass => ui}/consts/const-str-ptr.rs (100%) rename src/test/{run-pass => ui}/consts/const-struct-offsets.rs (100%) rename src/test/{run-pass => ui}/consts/const-struct.rs (100%) rename src/test/{run-pass => ui}/consts/const-trait-to-trait.rs (100%) rename src/test/{run-pass => ui}/consts/const-tuple-struct.rs (100%) rename src/test/{run-pass/consts/const-typeid-of.rs => ui/consts/const-typeid-of-rpass.rs} (100%) rename src/test/{run-pass => ui}/consts/const-unit-struct.rs (100%) rename src/test/{run-pass => ui}/consts/const-unsafe-fn.rs (100%) rename src/test/{run-pass => ui}/consts/const-vec-of-fns.rs (100%) rename src/test/{run-pass => ui}/consts/const-vec-syntax.rs (100%) rename src/test/{run-pass => ui}/consts/const-vecs-and-slices.rs (100%) rename src/test/{run-pass => ui}/consts/const.rs (100%) delete mode 100644 src/test/ui/consts/const_let_refutable.nll.stderr rename src/test/{run-pass => ui}/consts/consts-in-patterns.rs (100%) rename src/test/{run-pass => ui}/consts/deref_in_pattern.rs (100%) rename src/test/{run-pass => ui}/consts/ice-48279.rs (100%) rename src/test/{run-pass => ui}/consts/issue-37550.rs (100%) create mode 100644 src/test/ui/consts/issue-51559.rs create mode 100644 src/test/ui/consts/issue-51559.stderr rename src/test/{run-pass => ui}/consts/issue-broken-mir.rs (100%) rename src/test/{run-pass => ui}/consts/locals-in-const-fn.rs (100%) rename src/test/{run-pass => ui}/consts/match-const-fn-structs.rs (100%) rename src/test/{run-pass => ui}/consts/mozjs-error.rs (100%) rename src/test/{run-pass => ui}/consts/non-scalar-cast.rs (100%) create mode 100644 src/test/ui/consts/promote_const_let.polonius.stderr rename src/test/{run-pass => ui}/consts/promotion.rs (100%) rename src/test/{run-pass => ui}/consts/references.rs (100%) rename src/test/{run-pass => ui}/consts/repeat_match.rs (100%) rename src/test/{run-pass => ui}/consts/return-in-const-fn.rs (100%) create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.stderr create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.stderr create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.stderr create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.stderr create mode 100644 src/test/ui/consts/self_normalization.rs create mode 100644 src/test/ui/consts/self_normalization2.rs rename src/test/{run-pass => ui}/consts/signed_enum_discr.rs (100%) rename src/test/{run-pass => ui}/consts/transmute-const.rs (100%) rename src/test/{run-pass => ui}/consts/tuple-struct-constructors.rs (100%) rename src/test/{run-pass => ui}/core-run-destroy.rs (97%) rename src/test/{run-pass => ui}/crate-leading-sep.rs (88%) rename src/test/{run-pass => ui}/crate-method-reexport-grrrrrrr.rs (97%) rename src/test/{run-pass => ui}/crate-name-attr-used.rs (93%) rename src/test/{run-pass => ui}/cross-crate/anon-extern-mod-cross-crate-2.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/anon_trait_static_method_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_borrow_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_capture_clause.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_const.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_impl_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_iter_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_nested_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/cci_no_inline_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/moves_based_on_type_lib.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/newtype_struct_xc.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/pub_static_array.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/reexported_static_methods.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/xcrate_address_insignificant.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/xcrate_associated_type_defaults.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/xcrate_static_addresses.rs (100%) rename src/test/{run-pass => ui}/cross-crate/auxiliary/xcrate_unit_struct.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cci_borrow.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cci_capture_clause.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cci_impl_exe.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cci_iter_exe.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cci_nested_exe.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cci_no_inline_exe.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cross-crate-const-pat.rs (100%) rename src/test/{run-pass => ui}/cross-crate/cross-crate-newtype-struct-pat.rs (100%) rename src/test/{run-pass => ui}/cross-crate/moves-based-on-type-cross-crate.rs (100%) rename src/test/{run-pass => ui}/cross-crate/reexported-static-methods-cross-crate.rs (100%) rename src/test/{run-pass => ui}/cross-crate/static-array-across-crate.rs (100%) rename src/test/{run-pass => ui}/cross-crate/xcrate-address-insignificant.rs (100%) rename src/test/{run-pass => ui}/cross-crate/xcrate-associated-type-defaults.rs (100%) rename src/test/{run-pass => ui}/cross-crate/xcrate-static-addresses.rs (100%) rename src/test/{run-pass => ui}/cross-crate/xcrate-trait-lifetime-param.rs (100%) rename src/test/{run-pass => ui}/cross-crate/xcrate-unit-struct.rs (100%) rename src/test/{run-pass => ui}/cross-crate/xcrate_generic_fn_nested_return.rs (100%) rename src/test/{run-pass => ui}/crt-static-off-works.rs (94%) rename src/test/{run-pass => ui}/crt-static-on-works.rs (93%) rename src/test/{run-pass => ui}/cycle-generic-bound.rs (94%) rename src/test/{run-pass => ui}/dead-code-alias-in-pat.rs (92%) rename src/test/{run-pass => ui}/dead-code-leading-underscore.rs (96%) rename src/test/{run-pass => ui}/debuginfo-lto.rs (98%) rename src/test/{run-pass => ui}/deep.rs (94%) rename src/test/{run-pass => ui}/default-alloc-error-hook.rs (97%) rename src/test/{run-pass => ui}/default-associated-types.rs (96%) rename src/test/{run-pass => ui}/default-method-parsing.rs (88%) rename src/test/{run-pass => ui}/default-method-simple.rs (95%) rename src/test/{run-pass => ui}/defaults-well-formedness.rs (98%) create mode 100644 src/test/ui/definition-reachable/auxiliary/field-method-macro.rs create mode 100644 src/test/ui/definition-reachable/auxiliary/nested-fn-macro.rs create mode 100644 src/test/ui/definition-reachable/auxiliary/private-use-macro.rs create mode 100644 src/test/ui/definition-reachable/field-method.rs create mode 100644 src/test/ui/definition-reachable/nested-fn.rs create mode 100644 src/test/ui/definition-reachable/private-non-types.rs create mode 100644 src/test/ui/definition-reachable/private-types.rs create mode 100644 src/test/ui/definition-reachable/private-use.rs rename src/test/{run-pass => ui}/deprecation-in-force-unstable.rs (91%) rename src/test/{run-pass => ui}/deref-lval.rs (91%) rename src/test/{run-pass => ui}/deref-mut-on-ref.rs (95%) rename src/test/{run-pass => ui}/deref-on-ref.rs (96%) rename src/test/{run-pass => ui}/deref-rc.rs (88%) rename src/test/{run-pass => ui}/deref.rs (91%) create mode 100644 src/test/ui/derives/auxiliary/derive-marker-tricky.rs create mode 100644 src/test/ui/derives/derive-marker-tricky.rs rename src/test/{run-pass => ui}/deriving/auxiliary/derive-no-std.rs (100%) rename src/test/{run-pass => ui}/deriving/derive-no-std.rs (100%) rename src/test/{run-pass => ui}/deriving/derive-partialord-correctness.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-associated-types.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-bounds.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-array.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-generic-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-generic-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-generic-tuple-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-clone-tuple-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-cmp-generic-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-cmp-generic-struct-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-cmp-generic-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-cmp-generic-tuple-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-cmp-shortcircuit.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-copyclone.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-default-box.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-enum-single-variant.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-eq-ord-boxed-slice.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-hash.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-in-fn.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-in-macro.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-meta-multiple.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-meta.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-self-lifetime-totalord-totaleq.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-show-2.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-show.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-c-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-hash-enum.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-hash-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-struct-empty.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-struct-like-enum-variant.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-struct-tuple.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-struct.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-via-extension-type-params.rs (100%) rename src/test/{run-pass => ui}/deriving/deriving-with-repr-packed.rs (100%) rename src/test/{run-pass => ui}/dispatch_from_dyn_zst.rs (99%) rename src/test/{run-pass => ui}/diverging-fallback-control-flow.rs (99%) rename src/test/{run-pass => ui}/diverging-fallback-method-chain.rs (97%) rename src/test/{run-pass => ui}/diverging-fallback-option.rs (96%) rename src/test/{run-pass => ui}/double-ref.rs (98%) rename src/test/{run-pass => ui}/drop/auxiliary/dropck_eyepatch_extern_crate.rs (100%) rename src/test/{run-pass => ui}/drop/drop-on-empty-block-exit.rs (100%) rename src/test/{run-pass => ui}/drop/drop-on-ret.rs (100%) rename src/test/{run-pass => ui}/drop/drop-struct-as-object.rs (100%) rename src/test/{run-pass => ui}/drop/drop-trait-enum.rs (100%) rename src/test/{run-pass => ui}/drop/drop-trait-generic.rs (100%) rename src/test/{run-pass => ui}/drop/drop-trait.rs (100%) rename src/test/{run-pass => ui}/drop/drop-uninhabited-enum.rs (100%) rename src/test/{run-pass => ui}/drop/drop-with-type-ascription-1.rs (100%) rename src/test/{run-pass => ui}/drop/drop-with-type-ascription-2.rs (100%) rename src/test/{run-pass => ui}/drop/dropck-eyepatch-extern-crate.rs (100%) rename src/test/{run-pass => ui}/drop/dropck-eyepatch-reorder.rs (100%) rename src/test/{run-pass => ui}/drop/dropck-eyepatch.rs (100%) rename src/test/{run-pass => ui}/drop/dropck_legal_cycles.rs (100%) create mode 100644 src/test/ui/drop/dynamic-drop-async.rs rename src/test/{run-pass => ui}/drop/dynamic-drop.rs (99%) rename src/test/{run-pass => ui}/drop/no-drop-flag-size.rs (100%) rename src/test/{run-pass => ui}/drop/nondrop-cycle.rs (100%) create mode 100644 src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr rename src/test/{run-pass => ui}/dupe-first-attr.rc (100%) rename src/test/{run-pass => ui}/duplicated-external-mods.rs (94%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-coerce-custom.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-coerce-rc.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-coercions.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-deref-mut.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-deref.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-field-align.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-index.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-irrefutable-bind.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-raw.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-struct-sole.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-struct.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-trait-tuple.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-trait.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-tuple-sole.rs (100%) rename src/test/{run-pass => ui}/dynamically-sized-types/dst-tuple.rs (100%) rename src/test/{run-pass => ui}/early-ret-binop-add.rs (93%) rename src/test/{run-pass => ui}/early-vtbl-resolution.rs (96%) rename src/test/{run-pass => ui}/edition-keywords-2015-2015.rs (98%) rename src/test/{run-pass => ui}/edition-keywords-2015-2018.rs (98%) rename src/test/{run-pass => ui}/edition-keywords-2018-2015.rs (98%) rename src/test/{run-pass => ui}/edition-keywords-2018-2018.rs (98%) rename src/test/{run-pass => ui}/else-if.rs (97%) create mode 100644 src/test/ui/emit-artifact-notifications.polonius.stderr rename src/test/{run-pass => ui}/empty-allocation-non-null.rs (95%) rename src/test/{run-pass => ui}/empty-allocation-rvalue-non-null.rs (89%) rename src/test/{run-pass => ui}/empty-type-parameter-list.rs (97%) delete mode 100644 src/test/ui/empty/empty-never-array.nll.stderr rename src/test/{run-pass => ui}/empty_global_asm.rs (95%) rename src/test/{run-pass => ui}/env-args-reverse-iterator.rs (98%) rename src/test/{run-pass => ui}/env-funky-keys.rs (98%) rename src/test/{run-pass => ui}/env-home-dir.rs (99%) rename src/test/{run-pass => ui}/env-null-vars.rs (96%) rename src/test/{run-pass => ui}/env-vars.rs (96%) rename src/test/{run-pass => ui}/epoch-gate-feature.rs (95%) rename src/test/{run-pass => ui}/eq-multidispatch.rs (98%) rename src/test/{run-pass => ui}/estr-uniq.rs (96%) rename src/test/{run-pass => ui}/exec-env.rs (94%) delete mode 100644 src/test/ui/existential_types/auxiliary/cross_crate_ice.rs delete mode 100644 src/test/ui/existential_types/declared_but_never_defined.rs delete mode 100644 src/test/ui/existential_types/declared_but_not_defined_in_scope.rs delete mode 100644 src/test/ui/existential_types/existential-types-with-cycle-error.rs delete mode 100644 src/test/ui/existential_types/existential-types-with-cycle-error.stderr delete mode 100644 src/test/ui/existential_types/existential-types-with-cycle-error2.rs delete mode 100644 src/test/ui/existential_types/existential-types-with-cycle-error2.stderr delete mode 100644 src/test/ui/existential_types/generic_duplicate_lifetime_param.rs delete mode 100644 src/test/ui/existential_types/generic_duplicate_param_use10.rs delete mode 100644 src/test/ui/existential_types/generic_lifetime_param.rs delete mode 100644 src/test/ui/existential_types/no_inferrable_concrete_type.rs delete mode 100644 src/test/ui/existential_types/no_inferrable_concrete_type.stderr delete mode 100644 src/test/ui/existential_types/unused_generic_param.stderr rename src/test/{run-pass => ui}/explicit-i-suffix.rs (93%) rename src/test/{run-pass => ui}/export-glob-imports-target.rs (96%) rename src/test/{run-pass => ui}/export-multi.rs (92%) rename src/test/{run-pass => ui}/export-non-interference2.rs (92%) rename src/test/{run-pass => ui}/export-non-interference3.rs (90%) rename src/test/{run-pass => ui}/expr-block-fn.rs (90%) rename src/test/{run-pass => ui}/expr-block-generic-unique1.rs (97%) rename src/test/{run-pass => ui}/expr-block-generic-unique2.rs (96%) rename src/test/{run-pass => ui}/expr-block-generic.rs (97%) rename src/test/{run-pass => ui}/expr-block-slot.rs (94%) rename src/test/{run-pass => ui}/expr-block-unique.rs (87%) rename src/test/{run-pass => ui}/expr-block.rs (97%) rename src/test/{run-pass => ui}/expr-copy.rs (94%) rename src/test/{run-pass => ui}/expr-empty-ret.rs (93%) rename src/test/{run-pass => ui}/expr-fn.rs (98%) rename src/test/{run-pass => ui}/expr-if-generic.rs (98%) rename src/test/{run-pass => ui}/expr-if-panic-all.rs (94%) rename src/test/{run-pass => ui}/expr-if-panic.rs (96%) rename src/test/{run-pass => ui}/expr-if-unique.rs (94%) rename src/test/{run-pass => ui}/expr-if.rs (99%) rename src/test/{run-pass => ui}/expr-scope.rs (90%) rename src/test/{run-pass => ui}/ext-expand-inner-exprs.rs (90%) rename src/test/{run-pass => ui}/extend-for-unit.rs (92%) rename src/test/{run-pass => ui}/exterior.rs (97%) rename src/test/{run-pass => ui}/extern/auxiliary/extern-crosscrate-source.rs (100%) rename src/test/{run-pass => ui}/extern/auxiliary/extern-take-value.rs (100%) rename src/test/{run-pass => ui}/extern/auxiliary/extern_calling_convention.rs (100%) rename src/test/{run-pass => ui}/extern/auxiliary/extern_mod_ordering_lib.rs (100%) rename src/test/{run-pass => ui}/extern/auxiliary/fat_drop.rs (100%) rename src/test/{run-pass => ui}/extern/extern-1.rs (100%) rename src/test/{run-pass => ui}/extern/extern-call-deep.rs (100%) rename src/test/{run-pass => ui}/extern/extern-call-deep2.rs (100%) rename src/test/{run-pass => ui}/extern/extern-call-direct.rs (100%) rename src/test/{run-pass => ui}/extern/extern-call-indirect.rs (100%) rename src/test/{run-pass => ui}/extern/extern-call-scrub.rs (100%) rename src/test/{run-pass => ui}/extern/extern-calling-convention-test.rs (100%) rename src/test/{run-pass => ui}/extern/extern-compare-with-return-type.rs (100%) rename src/test/{run-pass => ui}/extern/extern-crosscrate.rs (100%) create mode 100644 src/test/ui/extern/extern-ffi-fn-with-body.rs create mode 100644 src/test/ui/extern/extern-ffi-fn-with-body.stderr rename src/test/{run-pass => ui}/extern/extern-foreign-crate.rs (100%) rename src/test/{run-pass => ui}/extern/extern-methods.rs (100%) rename src/test/{run-pass => ui}/extern/extern-mod-abi.rs (100%) rename src/test/{run-pass => ui}/extern/extern-mod-ordering-exe.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-TwoU16s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-TwoU32s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-TwoU64s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-TwoU8s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-char.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-double.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-empty.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-u32.rs (100%) rename src/test/{run-pass => ui}/extern/extern-pass-u64.rs (100%) rename src/test/{run-pass => ui}/extern/extern-prelude-core.rs (100%) rename src/test/{run-pass => ui}/extern/extern-prelude-core.stderr (82%) rename src/test/{run-pass => ui}/extern/extern-prelude-no-speculative.rs (100%) rename src/test/{run-pass => ui}/extern/extern-prelude-std.rs (100%) rename src/test/{run-pass => ui}/extern/extern-prelude-std.stderr (81%) rename src/test/{run-pass => ui}/extern/extern-pub.rs (100%) rename src/test/{run-pass => ui}/extern/extern-return-TwoU16s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-return-TwoU32s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-return-TwoU64s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-return-TwoU8s.rs (100%) rename src/test/{run-pass => ui}/extern/extern-rust.rs (100%) rename src/test/{run-pass => ui}/extern/extern-take-value.rs (100%) rename src/test/{run-pass => ui}/extern/extern-thiscall.rs (100%) rename src/test/{run-pass => ui}/extern/extern-types-inherent-impl.rs (100%) rename src/test/{run-pass => ui}/extern/extern-types-manual-sync-send.rs (100%) rename src/test/{run-pass => ui}/extern/extern-types-pointer-cast.rs (100%) rename src/test/{run-pass => ui}/extern/extern-types-size_of_val.rs (100%) rename src/test/{run-pass => ui}/extern/extern-types-thin-pointer.rs (100%) rename src/test/{run-pass => ui}/extern/extern-types-trait-impl.rs (100%) rename src/test/{run-pass => ui}/extern/extern-vectorcall.rs (100%) rename src/test/{run-pass => ui}/extern/extern_fat_drop.rs (100%) rename src/test/{run-pass => ui}/extoption_env-not-defined.rs (86%) rename src/test/{run-pass => ui}/fact.rs (96%) rename src/test/{run-pass => ui}/fat-lto.rs (88%) rename src/test/{run-pass/fat-ptr-cast.rs => ui/fat-ptr-cast-rpass.rs} (98%) rename src/test/{run-pass => ui}/fds-are-cloexec.rs (99%) delete mode 100644 src/test/ui/feature-gate/await-macro.rs delete mode 100644 src/test/ui/feature-gate/await-macro.stderr create mode 100644 src/test/ui/feature-gate/feature-gate-cfg_doctest.rs create mode 100644 src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr create mode 100644 src/test/ui/feature-gate/rustc-private.rs create mode 100644 src/test/ui/feature-gate/rustc-private.stderr create mode 100644 src/test/ui/feature-gates/bench.rs create mode 100644 src/test/ui/feature-gates/bench.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs create mode 100644 src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-existential-type.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-existential-type.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs create mode 100644 src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr rename src/test/{run-pass => ui}/filter-block-view-items.rs (94%) rename src/test/{run-pass => ui}/fixup-deref-mut.rs (98%) rename src/test/{run-pass => ui}/for-loop-while/auto-loop.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/break-value.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/break.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-destruct.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-goofiness.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-has-unit-body.rs (90%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-into-iterator.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-lifetime-of-unbound-values.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-macro.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-mut-ref-element.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-no-std.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-panic.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-external-iterators-break.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-external-iterators-hashmap.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-external-iterators-loop.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-external-iterators-nested.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-external-iterators.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-nested.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-put-structured.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/foreach-simple-outer-slot.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/label_break_value.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/labeled-break.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/linear-for-loop.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/liveness-assign-imm-local-after-loop.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/liveness-loop-break.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/liveness-move-in-loop.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-break-cont-1.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-break-cont.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-break-value.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-diverges.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-label-shadowing.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-labeled-break-value.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-no-reinit-needed-post-bot.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/loop-scope.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-cont.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-flow-graph.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-label.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-let.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-loop-constraints-2.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-prelude-drop.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while-with-break.rs (100%) rename src/test/{run-pass => ui}/for-loop-while/while.rs (100%) rename src/test/{run-pass => ui}/foreign/auxiliary/fn-abi.rs (100%) rename src/test/{run-pass => ui}/foreign/auxiliary/foreign_lib.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-call-no-runtime.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-dupe.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-fn-linkname.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-fn-with-byval.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-int-types.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-mod-src/compiletest-ignore-dir (100%) rename src/test/{run-pass => ui}/foreign/foreign-mod-src/inner.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-mod-unused-const.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-no-abi.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-src/compiletest-ignore-dir (100%) rename src/test/{run-pass => ui}/foreign/foreign-src/foreign.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign-truncated-arguments.rs (100%) rename src/test/{run-pass => ui}/foreign/foreign2.rs (100%) rename src/test/{run-pass => ui}/format-nan.rs (93%) rename src/test/{run-pass => ui}/format-no-std.rs (97%) rename src/test/{run-pass => ui}/format-ref-cell.rs (94%) rename src/test/{run-pass => ui}/fsu-moves-and-copies.rs (99%) rename src/test/{run-pass => ui}/fun-call-variants.rs (95%) rename src/test/{run-pass => ui}/fun-indirect-call.rs (90%) rename src/test/{run-pass => ui}/functions-closures/auxiliary/fn-abi.rs (100%) rename src/test/{run-pass => ui}/functions-closures/call-closure-from-overloaded-op.rs (100%) rename src/test/{run-pass => ui}/functions-closures/capture-clauses-boxed-closures.rs (100%) rename src/test/{run-pass => ui}/functions-closures/capture-clauses-unboxed-closures.rs (100%) rename src/test/{run-pass => ui}/functions-closures/clone-closure.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-bounds-can-capture-chan.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-expected-type/README.md (100%) rename src/test/{run-pass => ui}/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-expected-type/issue-38714.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-expected-type/supply-just-return-type.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-expected-type/supply-nothing.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-immediate.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-inference.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-inference2.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-reform.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-returning-closure.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure-to-fn-coercion.rs (100%) rename src/test/{run-pass => ui}/functions-closures/closure_to_fn_coercion-expected-types.rs (100%) rename src/test/{run-pass => ui}/functions-closures/copy-closure.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-abi.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-bare-assign.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-bare-coerce-to-block.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-bare-item.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-bare-size.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-bare-spawn.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-coerce-field.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-item-type-cast.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-item-type-coerce.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-item-type-zero-sized.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-lval.rs (100%) rename src/test/{run-pass => ui}/functions-closures/fn-type-infer.rs (100%) rename src/test/{run-pass => ui}/functions-closures/implied-bounds-closure-arg-outlives.rs (100%) rename src/test/{run-pass => ui}/functions-closures/nullable-pointer-opt-closures.rs (100%) rename src/test/{run-pass => ui}/functions-closures/parallel-codegen-closures.rs (100%) rename src/test/{run-pass => ui}/functions-closures/return-from-closure.rs (100%) rename src/test/{run-pass => ui}/generator/addassign-yield.rs (98%) rename src/test/{run-pass => ui}/generator/auxiliary/xcrate-reachable.rs (100%) rename src/test/{run-pass => ui}/generator/auxiliary/xcrate.rs (100%) rename src/test/{run-pass => ui}/generator/borrow-in-tail-expr.rs (100%) rename src/test/{run-pass => ui}/generator/conditional-drop.rs (100%) rename src/test/{run-pass => ui}/generator/control-flow.rs (100%) rename src/test/{run-pass => ui}/generator/drop-and-replace.rs (98%) rename src/test/{run-pass => ui}/generator/drop-env.rs (100%) rename src/test/{run-pass => ui}/generator/issue-44197.rs (100%) rename src/test/{run-pass => ui}/generator/issue-52398.rs (100%) rename src/test/{run-pass => ui}/generator/issue-57084.rs (100%) rename src/test/{run-pass => ui}/generator/issue-58888.rs (100%) create mode 100644 src/test/ui/generator/issue-62506-two_awaits.rs rename src/test/{run-pass => ui}/generator/iterator-count.rs (100%) rename src/test/{run-pass => ui}/generator/live-upvar-across-yield.rs (100%) rename src/test/{run-pass => ui}/generator/match-bindings.rs (100%) rename src/test/{run-pass => ui}/generator/nested_generators.rs (100%) rename src/test/{run-pass => ui}/generator/non-static-is-unpin.rs (100%) rename src/test/{run-pass => ui}/generator/overlap-locals.rs (97%) rename src/test/{run-pass => ui}/generator/panic-drops.rs (100%) rename src/test/{run-pass => ui}/generator/panic-safe.rs (100%) create mode 100644 src/test/ui/generator/partial-initialization-across-yield.rs create mode 100644 src/test/ui/generator/partial-initialization-across-yield.stderr rename src/test/{run-pass => ui}/generator/pin-box-generator.rs (100%) rename src/test/{run-pass => ui}/generator/reborrow-mut-upvar.rs (100%) create mode 100644 src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr rename src/test/{run-pass => ui}/generator/resume-after-return.rs (100%) rename src/test/{run-pass => ui}/generator/size-moved-locals.rs (83%) rename src/test/{run-pass => ui}/generator/smoke.rs (100%) rename src/test/{run-pass => ui}/generator/static-generators.rs (100%) rename src/test/{run-pass => ui}/generator/too-live-local-in-immovable-gen.rs (100%) rename src/test/{run-pass => ui}/generator/xcrate-reachable.rs (100%) rename src/test/{run-pass => ui}/generator/xcrate.rs (100%) rename src/test/{run-pass => ui}/generator/yield-in-args-rev.rs (100%) rename src/test/{run-pass => ui}/generator/yield-in-box.rs (100%) rename src/test/{run-pass => ui}/generator/yield-in-initializer.rs (100%) rename src/test/{run-pass => ui}/generator/yield-subtype.rs (100%) rename src/test/{run-pass => ui}/generics/auxiliary/default_type_params_xc.rs (100%) rename src/test/{run-pass => ui}/generics/generic-alias-unique.rs (100%) rename src/test/{run-pass => ui}/generics/generic-default-type-params-cross-crate.rs (100%) rename src/test/{run-pass => ui}/generics/generic-default-type-params.rs (100%) rename src/test/{run-pass => ui}/generics/generic-derived-type.rs (100%) rename src/test/{run-pass => ui}/generics/generic-exterior-unique.rs (100%) rename src/test/{run-pass => ui}/generics/generic-extern-mangle.rs (100%) rename src/test/{run-pass => ui}/generics/generic-fn-infer.rs (100%) rename src/test/{run-pass => ui}/generics/generic-fn-twice.rs (100%) rename src/test/{run-pass => ui}/generics/generic-fn-unique.rs (100%) rename src/test/{run-pass => ui}/generics/generic-fn.rs (100%) rename src/test/{run-pass => ui}/generics/generic-ivec-leak.rs (100%) rename src/test/{run-pass => ui}/generics/generic-newtype-struct.rs (100%) rename src/test/{run-pass => ui}/generics/generic-object.rs (100%) rename src/test/{run-pass => ui}/generics/generic-recursive-tag.rs (100%) rename src/test/{run-pass => ui}/generics/generic-static-methods.rs (100%) rename src/test/{run-pass => ui}/generics/generic-tag-corruption.rs (100%) rename src/test/{run-pass => ui}/generics/generic-tag-local.rs (100%) rename src/test/{run-pass => ui}/generics/generic-tag-match.rs (100%) rename src/test/{run-pass => ui}/generics/generic-tag-values.rs (100%) rename src/test/{run-pass => ui}/generics/generic-tag.rs (100%) rename src/test/{run-pass => ui}/generics/generic-temporary.rs (100%) rename src/test/{run-pass => ui}/generics/generic-tup.rs (100%) rename src/test/{run-pass => ui}/generics/generic-type-synonym.rs (100%) rename src/test/{run-pass => ui}/generics/generic-type.rs (100%) rename src/test/{run-pass => ui}/generics/generic-unique.rs (100%) rename src/test/{run-pass => ui}/global-scope.rs (94%) rename src/test/{run-pass => ui}/guards-not-exhaustive.rs (94%) rename src/test/{run-pass => ui}/guards.rs (97%) rename src/test/{run-pass => ui}/hashmap-memory.rs (99%) rename src/test/{run-pass => ui}/hello.rs (78%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-fn-like-trait.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-opt-in-copy.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-parse.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-type-outlives.rs (100%) rename src/test/{run-pass => ui}/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs (100%) create mode 100644 src/test/ui/hrtb/issue-30786.migrate.stderr create mode 100644 src/test/ui/hrtb/issue-30786.nll.stderr create mode 100644 src/test/ui/hrtb/issue-30786.rs create mode 100644 src/test/ui/hrtb/issue-62203-hrtb-ice.rs create mode 100644 src/test/ui/hrtb/issue-62203-hrtb-ice.stderr rename src/test/{run-pass => ui}/html-literals.rs (99%) create mode 100644 src/test/ui/huge-array-simple-32.rs create mode 100644 src/test/ui/huge-array-simple-32.stderr create mode 100644 src/test/ui/huge-array-simple-64.rs create mode 100644 src/test/ui/huge-array-simple-64.stderr delete mode 100644 src/test/ui/huge-array-simple.rs delete mode 100644 src/test/ui/huge-array-simple.stderr rename src/test/{run-pass => ui}/hygiene/auxiliary/legacy_interaction.rs (92%) rename src/test/{run-pass => ui}/hygiene/auxiliary/my_crate.rs (53%) create mode 100644 src/test/ui/hygiene/auxiliary/stdlib-prelude.rs rename src/test/{run-pass => ui}/hygiene/auxiliary/unhygienic_example.rs (98%) rename src/test/{run-pass => ui}/hygiene/auxiliary/xcrate.rs (96%) create mode 100644 src/test/ui/hygiene/duplicate_lifetimes.rs create mode 100644 src/test/ui/hygiene/duplicate_lifetimes.stderr create mode 100644 src/test/ui/hygiene/eager-from-opaque-2.rs create mode 100644 src/test/ui/hygiene/eager-from-opaque.rs create mode 100644 src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs create mode 100644 src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr create mode 100644 src/test/ui/hygiene/format-args.rs create mode 100644 src/test/ui/hygiene/generic_params.rs create mode 100644 src/test/ui/hygiene/generic_params.stderr rename src/test/{run-pass => ui}/hygiene/hygiene-dodging-1.rs (100%) rename src/test/{run-pass => ui}/hygiene/hygiene.rs (100%) rename src/test/{run-pass => ui}/hygiene/hygienic-labels-in-let.rs (100%) rename src/test/{run-pass => ui}/hygiene/hygienic-labels-in-let.stderr (100%) rename src/test/{run-pass => ui}/hygiene/hygienic-labels.rs (100%) rename src/test/{run-pass => ui}/hygiene/hygienic-labels.stderr (100%) rename src/test/{run-pass => ui}/hygiene/issue-44128.rs (94%) rename src/test/{run-pass => ui}/hygiene/issue-47311.rs (93%) rename src/test/{run-pass => ui}/hygiene/issue-47312.rs (95%) create mode 100644 src/test/ui/hygiene/issue-61574-const-parameters.rs create mode 100644 src/test/ui/hygiene/issue-61574-const-parameters.stderr rename src/test/{run-pass => ui}/hygiene/items.rs (97%) rename src/test/{run-pass => ui}/hygiene/legacy_interaction.rs (95%) rename src/test/{run-pass => ui}/hygiene/lexical.rs (96%) create mode 100644 src/test/ui/hygiene/privacy-early.rs create mode 100644 src/test/ui/hygiene/privacy-early.stderr create mode 100644 src/test/ui/hygiene/rustc-macro-transparency.rs create mode 100644 src/test/ui/hygiene/rustc-macro-transparency.stderr rename src/test/{run-pass => ui}/hygiene/specialization.rs (100%) create mode 100644 src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs create mode 100644 src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs rename src/test/{run-pass/hygiene/trait_items.rs => ui/hygiene/trait_items-2.rs} (95%) rename src/test/{run-make-fulldeps/pretty-expanded-hygiene/input.rs => ui/hygiene/unpretty-debug.rs} (50%) create mode 100644 src/test/ui/hygiene/unpretty-debug.stdout rename src/test/{run-pass => ui}/hygiene/wrap_unhygienic_example.rs (98%) rename src/test/{run-pass => ui}/hygiene/xcrate.rs (100%) rename src/test/{run-pass => ui}/if-bot.rs (87%) rename src/test/{run-pass => ui}/if-check.rs (95%) rename src/test/{run-pass => ui}/if-ret.rs (89%) rename src/test/{run-pass => ui}/ifmt.rs (99%) rename src/test/{run-pass => ui}/ignore-all-the-things.rs (98%) rename src/test/{run-pass => ui}/impl-for-never.rs (97%) rename src/test/{run-pass => ui}/impl-inherent-non-conflict.rs (97%) rename src/test/{run-pass => ui}/impl-not-adjacent-to-type.rs (93%) rename src/test/{run-pass => ui}/impl-privacy-xc-1.rs (93%) rename src/test/{run-pass => ui}/impl-privacy-xc-2.rs (95%) rename src/test/{run-pass => ui}/impl-trait-in-bindings.rs (98%) rename src/test/{run-pass => ui}/impl-trait-in-bindings.stderr (63%) rename src/test/ui/impl-trait/{associated-existential-type-generic-trait.rs => associated-impl-trait-type-generic-trait.rs} (72%) rename src/test/ui/impl-trait/{associated-existential-type-trivial.rs => associated-impl-trait-type-trivial.rs} (64%) rename src/test/ui/impl-trait/{associated-existential-type.rs => associated-impl-trait-type.rs} (71%) rename src/test/{run-pass/impl-trait/auto-trait-leak.rs => ui/impl-trait/auto-trait-leak-rpass.rs} (100%) rename src/test/{run-pass => ui}/impl-trait/auxiliary/xcrate.rs (100%) create mode 100644 src/test/ui/impl-trait/bound-normalization-fail.rs create mode 100644 src/test/ui/impl-trait/bound-normalization-fail.stderr create mode 100644 src/test/ui/impl-trait/bound-normalization-pass.rs create mode 100644 src/test/ui/impl-trait/bound-normalization-pass.stderr rename src/test/{run-pass => ui}/impl-trait/bounds_regression.rs (100%) rename src/test/{run-pass/impl-trait/equality.rs => ui/impl-trait/equality-rpass.rs} (100%) rename src/test/{run-pass => ui}/impl-trait/example-calendar.rs (100%) rename src/test/{run-pass => ui}/impl-trait/example-st.rs (100%) delete mode 100644 src/test/ui/impl-trait/existential_type_in_fn_body.rs create mode 100644 src/test/ui/impl-trait/issue-55872-1.rs create mode 100644 src/test/ui/impl-trait/issue-55872-1.stderr create mode 100644 src/test/ui/impl-trait/issue-55872-2.rs create mode 100644 src/test/ui/impl-trait/issue-55872-2.stderr create mode 100644 src/test/ui/impl-trait/issue-55872.rs create mode 100644 src/test/ui/impl-trait/issue-55872.stderr rename src/test/{run-pass => ui}/impl-trait/lifetimes.rs (100%) rename src/test/ui/impl-trait/multiple-lifetimes/{ordinary-bounds-pick-original-existential.rs => ordinary-bounds-pick-original-type-alias-impl-trait.rs} (88%) rename src/test/{run-pass => ui}/impl-trait/nesting.rs (100%) rename src/test/ui/impl-trait/{existential-minimal.rs => return-position-impl-trait-minimal.rs} (53%) create mode 100644 src/test/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs rename src/test/{run-pass => ui}/impl-trait/universal_hrtb_anon.rs (100%) rename src/test/{run-pass => ui}/impl-trait/universal_hrtb_named.rs (100%) rename src/test/{run-pass => ui}/impl-trait/universal_in_adt_in_parameters.rs (100%) rename src/test/{run-pass => ui}/impl-trait/universal_in_impl_trait_in_parameters.rs (100%) rename src/test/{run-pass => ui}/impl-trait/universal_in_trait_defn_parameters.rs (100%) rename src/test/{run-pass => ui}/impl-trait/universal_multiple_bounds.rs (100%) rename src/test/{run-pass => ui}/impl-trait/xcrate.rs (100%) rename src/test/{run-pass => ui}/impl-trait/xcrate_simple.rs (100%) rename src/test/{run-pass => ui}/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs (100%) rename src/test/{run-pass => ui}/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs (100%) rename src/test/{run-pass => ui}/imports/import-crate-with-invalid-spans/main.rs (100%) rename src/test/{run-pass => ui}/imports/import-from.rs (100%) rename src/test/{run-pass/imports/import-glob-0.rs => ui/imports/import-glob-0-rpass.rs} (100%) rename src/test/{run-pass => ui}/imports/import-glob-1.rs (100%) rename src/test/{run-pass => ui}/imports/import-glob-crate.rs (100%) rename src/test/{run-pass => ui}/imports/import-in-block.rs (100%) rename src/test/{run-pass => ui}/imports/import-prefix-macro.rs (100%) rename src/test/{run-pass => ui}/imports/import-rename.rs (100%) rename src/test/{run-pass => ui}/imports/import-trailing-comma.rs (100%) rename src/test/{run-pass => ui}/imports/import.rs (100%) rename src/test/{run-pass => ui}/imports/import2.rs (100%) rename src/test/{run-pass => ui}/imports/import3.rs (100%) rename src/test/{run-pass => ui}/imports/import4.rs (100%) rename src/test/{run-pass => ui}/imports/import5.rs (100%) rename src/test/{run-pass => ui}/imports/import6.rs (100%) rename src/test/{run-pass => ui}/imports/import7.rs (100%) rename src/test/{run-pass => ui}/imports/import8.rs (100%) rename src/test/{run-pass => ui}/imports/imports.rs (100%) rename src/test/{run-pass => ui}/in-band-lifetimes.rs (80%) rename src/test/{run-pass => ui}/inc-range-pat.rs (96%) rename src/test/{run-pass => ui}/infer-fn-tail-expr.rs (90%) rename src/test/{run-pass => ui}/inherit-env.rs (98%) rename src/test/{run-pass => ui}/init-large-type.rs (97%) rename src/test/{run-pass => ui}/init-res-into-things.rs (98%) rename src/test/{run-pass => ui}/inlined-main.rs (70%) rename src/test/{run-pass => ui}/inner-attrs-on-impl.rs (96%) rename src/test/{run-pass => ui}/inner-module.rs (93%) rename src/test/{run-pass => ui}/inner-static.rs (96%) rename src/test/{run-pass => ui}/instantiable.rs (96%) rename src/test/{run-pass => ui}/intrinsics/auxiliary/cci_intrinsic.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-alignment.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-assume.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-atomics-cc.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-atomics.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-move-val-cleanups.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-move-val.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-uninit.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsic-unreachable.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsics-integer.rs (100%) rename src/test/{run-pass => ui}/intrinsics/intrinsics-math.rs (100%) rename src/test/{run-pass => ui}/invalid_const_promotion.rs (98%) rename src/test/{run-pass => ui}/invoke-external-foreign.rs (96%) rename src/test/{run-pass => ui}/irrefutable-unit.rs (86%) rename src/test/{run-pass => ui}/issue-59020.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/cgu_test.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/cgu_test_a.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/cgu_test_b.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/i8.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/iss.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-10028.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-10031-aux.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-11224.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-11225-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-11225-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-11225-3.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-11508.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-11529.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-12133-dylib.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-12133-dylib2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-12133-rlib.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-12612-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-12612-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-12660-aux.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-13507.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-13620-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-13620-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-13872-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-13872-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-13872-3.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-14344-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-14344-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-14421.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-14422.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-15562.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-16643.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-17662.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-17718-aux.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-18501.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-18514.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-18711.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-18913-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-18913-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-19293.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-19340-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-20389.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2170-lib.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2316-a.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2316-b.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2380.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2414-a.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2414-b.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2472-b.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-25185-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-25185-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2526.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-25467.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2631-a.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-2723-a.rs (100%) create mode 100644 src/test/ui/issues/auxiliary/issue-29265.rs rename src/test/{run-pass => ui}/issues/auxiliary/issue-29485.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-3012-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-3136-a.rc (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-3136-a.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-31702-1.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-31702-2.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-34796-aux.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-36954.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-38190.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-38226-aux.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-38715-modern.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-38715.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-3979-traits.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-39823.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-40469.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-41053.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-41394.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-42007-s.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-4208-cc.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-4545.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-48984-aux.rs (100%) create mode 100644 src/test/ui/issues/auxiliary/issue-49544.rs rename src/test/{run-pass => ui}/issues/auxiliary/issue-5518.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-5521.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-7178.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-7899.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-8044.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-8259.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-8401.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-9123.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-9155.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-9188.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-9906.rs (100%) rename src/test/{run-pass => ui}/issues/auxiliary/issue-9968.rs (100%) create mode 100644 src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs rename src/test/{run-pass => ui}/issues/issue-10025.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10028.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10031.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10228.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10392.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10436.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10626.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10638.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10682.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10683.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10718.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10734.rs (100%) rename src/test/{run-pass/issues/issue-10764.rs => ui/issues/issue-10764-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-10767.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10802.rs (100%) rename src/test/{run-pass => ui}/issues/issue-10806.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11047.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11085.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1112.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11205.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11224.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11225-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11225-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11225-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11267.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11382.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11508.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11529.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11552.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11577.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11677.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11709.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11820.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11940.rs (100%) rename src/test/{run-pass => ui}/issues/issue-11958.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12033.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12133-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12133-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12133-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12285.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1257.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12582.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12612.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12660.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12677.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12699.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12744.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12860.rs (100%) rename src/test/{run-pass => ui}/issues/issue-12909.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13027.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13204.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13259-windows-tcb-trash.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13264.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13304.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13323.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13434.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13507-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13620.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13655.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13665.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13763.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13808.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13867.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13872.rs (100%) rename src/test/{run-pass => ui}/issues/issue-13902.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14229.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14308.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14344.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14382.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14393.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14399.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14421.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14422.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14456.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1451.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14589.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1460.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14821.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14865.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14875.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14919.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14940.rs (100%) rename src/test/{run-pass => ui}/issues/issue-14958.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15043.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15063.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15080.rs (82%) rename src/test/{run-pass => ui}/issues/issue-15104.rs (81%) rename src/test/{run-pass/issues/issue-15129.rs => ui/issues/issue-15129-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-15155.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15189.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15221.rs (100%) delete mode 100644 src/test/ui/issues/issue-15381.nll.stderr rename src/test/{run-pass => ui}/issues/issue-15444.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15487.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15523-big.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15523.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15562.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15571.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15673.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15689-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15730.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15734.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15763.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15774.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15793.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15858.rs (100%) rename src/test/{run-pass => ui}/issues/issue-15881-model-lexer-dotdotdot.rs (100%) create mode 100644 src/test/ui/issues/issue-15919-32.rs create mode 100644 src/test/ui/issues/issue-15919-32.stderr create mode 100644 src/test/ui/issues/issue-15919-64.rs create mode 100644 src/test/ui/issues/issue-15919-64.stderr delete mode 100644 src/test/ui/issues/issue-15919.rs delete mode 100644 src/test/ui/issues/issue-15919.stderr rename src/test/{run-pass => ui}/issues/issue-16151.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16256.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16272.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16278.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16441.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16452.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16492.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16530.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16560.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16597-empty.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16597.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1660.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16602-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16602-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16602-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16643.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16648.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16671.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16739.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16745.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16774.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16783.rs (100%) rename src/test/{run-pass => ui}/issues/issue-16819.rs (100%) rename src/test/{run-pass/issues/issue-16922.rs => ui/issues/issue-16922-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-1696.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1701.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17068.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17074.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17170.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17216.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17233.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17302.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17322.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17351.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17361.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17503.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17662.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17718-borrow-interior.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17718-parse-const.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17718-static-unsafe-interior.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17718.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17734.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17756.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17771.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17816.rs (100%) rename src/test/{run-pass => ui}/issues/issue-17877.rs (77%) rename src/test/{run-pass => ui}/issues/issue-17897.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18060.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18075.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18110.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18173.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18232.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18352.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18353.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18412.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18425.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18464.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18501.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18514.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18539.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18652.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18655.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18661.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18685.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18711.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18767.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18804/auxiliary/lib.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18804/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18845.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18859.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18913.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18937-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-18952.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19001.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19127.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19135.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19244.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19293.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19340-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19340-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19358.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19367.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19499.rs (100%) rename src/test/{run-pass => ui}/issues/issue-1974.rs (100%) rename src/test/{run-pass => ui}/issues/issue-19811-escape-unicode.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20055-box-trait.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20055-box-unsized-array.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20174.rs (100%) rename src/test/{run-pass/issues/issue-20313.rs => ui/issues/issue-20313-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-20343.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20389.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20427.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20544.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20575.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20616.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2063.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20676.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2074.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20803.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20823.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20847.rs (100%) rename src/test/{run-pass => ui}/issues/issue-20953.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21033.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21058.rs (88%) rename src/test/{run-pass => ui}/issues/issue-21291.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21306.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21361.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21384.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21400.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21475.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21486.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21655.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2170-exe.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21721.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2190-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21909.rs (100%) rename src/test/{run-pass => ui}/issues/issue-21922.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22008.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22036.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2214.rs (79%) rename src/test/{run-pass => ui}/issues/issue-2216.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22258.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22346.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22403.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22426.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22463.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22536-copy-mustnt-zero.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22546.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22577.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22629.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22828.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2284.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22864-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22864-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2288.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22992-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-22992.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23036.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2316-c.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23208.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23261.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23304-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23304-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23311.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23336.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23338-ensure-param-drop-order.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23338-params-outlive-temps-of-body.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23433.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23485.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23491.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23611-enum-swap-in-drop.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23649-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23649-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23699.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23781.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2380-b.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23808.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23825.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2383.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23833.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23891.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23898.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23958.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23968-const-not-overflow.rs (100%) rename src/test/{run-pass => ui}/issues/issue-23992.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24010.rs (94%) rename src/test/{run-pass => ui}/issues/issue-24086.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2414-c.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2428.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24308.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24313.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24353.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2445-b.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2445.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24533.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24589.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2463.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24687-embed-debuginfo/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2472.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24779.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24805-dropck-itemless.rs (91%) rename src/test/{run-pass => ui}/issues/issue-24945-repeat-dash-opts.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24947.rs (100%) rename src/test/{run-pass => ui}/issues/issue-24954.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25089.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25145.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25185.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2526-a.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25279.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25339.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25343.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25467.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25497.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2550.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25515.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25549-multiple-drop.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25679.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25693.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25700-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25700-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25746-bool-transmute.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25757.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25810.rs (100%) rename src/test/{run-pass => ui}/issues/issue-25916.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26127.rs (100%) delete mode 100644 src/test/ui/issues/issue-26158.rs delete mode 100644 src/test/ui/issues/issue-26158.stderr rename src/test/{run-pass => ui}/issues/issue-26251.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2631-b.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26322.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2633-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2633.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2642.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26468.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26484.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26641.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26655.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26709.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26802.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26805.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26873-multifile.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26873-multifile/A/B.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26873-multifile/A/C.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26873-multifile/A/mod.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26873-multifile/compiletest-ignore-dir (100%) rename src/test/{run-pass => ui}/issues/issue-26873-multifile/mod.rs (100%) rename src/test/{run-pass => ui}/issues/issue-26873-onefile.rs (100%) rename src/test/{run-pass/issues/issue-26905.rs => ui/issues/issue-26905-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-26996.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27021.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27054-primitive-binary-ops.rs (100%) rename src/test/{run-pass/issues/issue-27060.rs => ui/issues/issue-27060-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-2708.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2718.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2723-b.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27240.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27268.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27320.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2734.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2735-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2735-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2735.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27401-dropflag-reinit.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2748-b.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27639.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27859.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27890.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27901.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27949.rs (100%) rename src/test/{run-pass => ui}/issues/issue-27997.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28181.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28498-must-work-ex1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28498-must-work-ex2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28498-ugeh-ex1.rs (73%) rename src/test/{run-pass => ui}/issues/issue-28498-ugeh-with-lifetime-param.rs (73%) rename src/test/{run-pass => ui}/issues/issue-28498-ugeh-with-passed-to-fn.rs (76%) rename src/test/{run-pass => ui}/issues/issue-28498-ugeh-with-trait-bound.rs (66%) rename src/test/{run-pass => ui}/issues/issue-28550.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28676.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28777.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28828.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28839.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2895.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28950.rs (100%) rename src/test/{run-pass => ui}/issues/issue-28983.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29053.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29071-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29092.rs (100%) rename src/test/{run-pass/issues/issue-29147.rs => ui/issues/issue-29147-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-29166.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29227.rs (100%) create mode 100644 src/test/ui/issues/issue-29265.rs rename src/test/{run-pass => ui}/issues/issue-2935.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2936.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29466.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29485.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29488.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29522.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29663.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29668.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29746.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29844.rs (100%) rename src/test/{run-pass => ui}/issues/issue-2989.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29914-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29914-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29914.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29927-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29927.rs (100%) rename src/test/{run-pass => ui}/issues/issue-29948.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30018-nopanic.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30018-panic.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30081.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3012-2.rs (100%) rename src/test/{run-pass/issues/issue-30240.rs => ui/issues/issue-30240-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-3026.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3037.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30371.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30490.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3052.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30530.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30615.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30756.rs (100%) rename src/test/{run-pass => ui}/issues/issue-30891.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3091.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3109.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3121.rs (100%) rename src/test/{run-pass => ui}/issues/issue-31267-additional.rs (100%) rename src/test/{run-pass => ui}/issues/issue-31267.rs (100%) rename src/test/{run-pass => ui}/issues/issue-31299.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3136-b.rs (100%) rename src/test/{run-pass => ui}/issues/issue-31702.rs (100%) rename src/test/{run-pass => ui}/issues/issue-31776.rs (100%) rename src/test/{run-pass => ui}/issues/issue-32008.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3211.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3220.rs (100%) rename src/test/{run-pass => ui}/issues/issue-32292.rs (100%) rename src/test/{run-pass => ui}/issues/issue-32389.rs (100%) rename src/test/{run-pass => ui}/issues/issue-32518.rs (100%) rename src/test/{run-pass => ui}/issues/issue-32805.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3290.rs (100%) rename src/test/{run-pass => ui}/issues/issue-32947.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33096.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33185.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33187.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33202.rs (100%) rename src/test/{run-pass => ui}/issues/issue-333.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33387.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33461.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33498.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33537.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33687.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33770.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3389.rs (100%) rename src/test/{run-pass => ui}/issues/issue-33992.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34053.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34074.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3429.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34427.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3447.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34503.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34569.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34571.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34784.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34796.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34798.rs (100%) rename src/test/{run-pass => ui}/issues/issue-34932.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3500.rs (100%) rename src/test/{run-pass => ui}/issues/issue-35423.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3556.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3559.rs (100%) rename src/test/{run-pass => ui}/issues/issue-35600.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3563-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3574.rs (100%) rename src/test/{run-pass => ui}/issues/issue-35815.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36023.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36036-associated-type-layout.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36053.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36139-normalize-closure-sig.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36260.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36278-prefix-nesting.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36381.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36401.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36474.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3656.rs (86%) rename src/test/{run-pass => ui}/issues/issue-36744-bitcast-args-if-needed.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36768.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36786-resolve-call.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36792.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36816.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3683.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36856.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36936.rs (100%) rename src/test/{run-pass => ui}/issues/issue-36954.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3702.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37109.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37175.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37222.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37291/auxiliary/lib.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37291/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3743.rs (100%) create mode 100644 src/test/ui/issues/issue-37433.rs create mode 100644 src/test/ui/issues/issue-37433.stderr rename src/test/{run-pass => ui}/issues/issue-3753.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37686.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3794.rs (100%) rename src/test/{run-pass => ui}/issues/issue-37991.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38002.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38033.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38074.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38091.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38190.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38226.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38437.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3847.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38556.rs (100%) rename src/test/{run-pass/issues/issue-38715.rs => ui/issues/issue-38715-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-38763.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3878.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38942.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3895.rs (100%) rename src/test/{run-pass => ui}/issues/issue-38987.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3904.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39292.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3935.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39367.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39548.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39709.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39720.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39720.stderr (100%) rename src/test/{run-pass => ui}/issues/issue-3979-generics.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3979-xcrate.rs (100%) rename src/test/{run-pass => ui}/issues/issue-3979.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39808.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39823.rs (100%) rename src/test/{run-pass => ui}/issues/issue-39827.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40003.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40085.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40235.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40408.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40469.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40770.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40847.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40883.rs (100%) rename src/test/{run-pass => ui}/issues/issue-40951.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41053.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4107.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41213.rs (100%) rename src/test/{run-pass/issues/issue-41394.rs => ui/issues/issue-41394-rpass.rs} (100%) rename src/test/{run-pass => ui}/issues/issue-41479.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41498.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41604.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41677.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41696.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41744.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41803.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41849-variance-req.rs (100%) rename src/test/{run-pass => ui}/issues/issue-41888.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42007.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4208.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42148.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42210.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4228.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42453.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42463.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4252.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42552.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42679.rs (100%) rename src/test/{run-pass => ui}/issues/issue-42747.rs (100%) rename src/test/{run-pass => ui}/issues/issue-43132.rs (100%) rename src/test/{run-pass => ui}/issues/issue-43205.rs (100%) rename src/test/{run-pass => ui}/issues/issue-43291.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4333.rs (100%) create mode 100644 src/test/ui/issues/issue-43398.rs create mode 100644 src/test/ui/issues/issue-43623.rs create mode 100644 src/test/ui/issues/issue-43623.stderr rename src/test/{run-pass => ui}/issues/issue-43692.rs (100%) rename src/test/{run-pass => ui}/issues/issue-43853.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4387.rs (100%) rename src/test/{run-pass => ui}/issues/issue-43910.rs (100%) rename src/test/{run-pass => ui}/issues/issue-43923.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4401.rs (100%) rename src/test/{run-pass => ui}/issues/issue-44333.rs (100%) create mode 100644 src/test/ui/issues/issue-44405.rs create mode 100644 src/test/ui/issues/issue-44405.stderr rename src/test/{run-pass => ui}/issues/issue-4446.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4448.rs (100%) rename src/test/{run-pass => ui}/issues/issue-45124.rs (100%) rename src/test/{run-pass => ui}/issues/issue-45152.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4541.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4542.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4545.rs (100%) rename src/test/{run-pass => ui}/issues/issue-45510.rs (100%) rename src/test/{run-pass => ui}/issues/issue-45731.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46069.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46095.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46519.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46553.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46845.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46855.rs (100%) rename src/test/{run-pass => ui}/issues/issue-46920-byte-array-patterns.rs (100%) rename src/test/{run-pass => ui}/issues/issue-47139-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-47139-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4734.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4735.rs (100%) rename src/test/{run-pass => ui}/issues/issue-47364.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4759-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4759.rs (100%) rename src/test/{run-pass => ui}/issues/issue-47638.rs (100%) rename src/test/{run-pass => ui}/issues/issue-48006.rs (96%) rename src/test/{run-pass => ui}/issues/issue-48159.rs (100%) rename src/test/{run-pass => ui}/issues/issue-48508-aux.rs (100%) rename src/test/{run-pass => ui}/issues/issue-48508.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4865-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4865-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4865-3.rs (100%) rename src/test/{run-pass => ui}/issues/issue-4875.rs (100%) rename src/test/{run-pass => ui}/issues/issue-48962.rs (100%) rename src/test/{run-pass => ui}/issues/issue-48984.rs (100%) rename src/test/{run-pass => ui}/issues/issue-49298.rs (100%) create mode 100644 src/test/ui/issues/issue-49544.rs rename src/test/{run-pass => ui}/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs (100%) rename src/test/{run-pass => ui}/issues/issue-49632.rs (100%) rename src/test/{run-pass => ui}/issues/issue-49685.rs (100%) rename src/test/{run-pass => ui}/issues/issue-49854.rs (100%) create mode 100644 src/test/ui/issues/issue-49919.rs create mode 100644 src/test/ui/issues/issue-49919.stderr rename src/test/{run-pass => ui}/issues/issue-49955-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-49955.rs (100%) rename src/test/{run-pass => ui}/issues/issue-49973.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5008-borrowed-traitobject-method-call.rs (100%) create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs create mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs delete mode 100644 src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr rename src/test/{run-pass => ui}/issues/issue-50415.rs (100%) rename src/test/{run-pass => ui}/issues/issue-50442.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5060.rs (100%) rename src/test/{run-pass => ui}/issues/issue-50689.rs (100%) rename src/test/{run-pass => ui}/issues/issue-50731.rs (100%) rename src/test/{run-pass => ui}/issues/issue-50811.rs (100%) rename src/test/{run-pass => ui}/issues/issue-50865-private-impl-trait/auxiliary/lib.rs (100%) rename src/test/{run-pass => ui}/issues/issue-50865-private-impl-trait/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-51185.rs (100%) rename src/test/{run-pass => ui}/issues/issue-51345.rs (100%) rename src/test/{run-pass => ui}/issues/issue-51582.rs (100%) rename src/test/{run-pass => ui}/issues/issue-51907.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5192.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52140/auxiliary/some_crate.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52140/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52141/auxiliary/some_crate.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52141/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52169.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5239-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5243.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52557.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52705/auxiliary/png2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-52705/main.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5280.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5315.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5321-immediates-with-bare-self.rs (100%) rename src/test/{run-pass => ui}/issues/issue-53333.rs (100%) rename src/test/{run-pass => ui}/issues/issue-53728.rs (95%) rename src/test/{run-pass => ui}/issues/issue-53843.rs (95%) create mode 100644 src/test/ui/issues/issue-54062.rs create mode 100644 src/test/ui/issues/issue-54062.stderr rename src/test/{run-pass => ui}/issues/issue-54462-mutable-noalias-correctness.rs (98%) rename src/test/{run-pass => ui}/issues/issue-54467.rs (98%) rename src/test/{run-pass => ui}/issues/issue-54477-reduced-2.rs (98%) rename src/test/{run-pass => ui}/issues/issue-54696.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5518.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5521.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5530.rs (100%) rename src/test/{run-pass => ui}/issues/issue-55376.rs (95%) rename src/test/{run-pass => ui}/issues/issue-55380.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5550.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5554.rs (100%) rename src/test/{run-pass => ui}/issues/issue-56237.rs (92%) rename src/test/{run-pass => ui}/issues/issue-5666.rs (100%) create mode 100644 src/test/ui/issues/issue-56870.rs rename src/test/{run-pass => ui}/issues/issue-5688.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5708.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5718.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5741.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5791.rs (100%) rename src/test/{run-pass => ui}/issues/issue-58212.rs (86%) create mode 100644 src/test/ui/issues/issue-58375-monomorphize-default-impls.rs rename src/test/{run-pass => ui}/issues/issue-58435-ice-with-assoc-const.rs (97%) rename src/test/{run-pass => ui}/issues/issue-58463.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5917.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5988.rs (100%) rename src/test/{run-pass => ui}/issues/issue-5997.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6117.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6128.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6130.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6153.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6157.rs (100%) create mode 100644 src/test/ui/issues/issue-61696.rs create mode 100644 src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs rename src/test/{run-pass => ui}/issues/issue-61894.rs (80%) create mode 100644 src/test/ui/issues/issue-62375.rs create mode 100644 src/test/ui/issues/issue-62375.stderr create mode 100644 src/test/ui/issues/issue-62554.rs create mode 100644 src/test/ui/issues/issue-62554.stderr rename src/test/{run-pass => ui}/issues/issue-6318.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6334.rs (100%) create mode 100644 src/test/ui/issues/issue-63364.rs create mode 100644 src/test/ui/issues/issue-63364.stderr rename src/test/{run-pass => ui}/issues/issue-6344-let.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6344-match.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6449.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6892.rs (100%) rename src/test/{run-pass => ui}/issues/issue-6919.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7012.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7178.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7222.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7344.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7519-match-unit-in-arg.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7563.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7575.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7660.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7663.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7784.rs (95%) rename src/test/{run-pass => ui}/issues/issue-7899.rs (100%) rename src/test/{run-pass => ui}/issues/issue-7911.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8044.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8248.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8249.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8259.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8351-1.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8351-2.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8391.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8401.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8460.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8498.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8506.rs (100%) rename src/test/{run-pass => ui}/issues/issue-868.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8709.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8783.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8827.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8851.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8860.rs (100%) rename src/test/{run-pass => ui}/issues/issue-8898.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9047.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9123.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9129.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9155.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9188.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9259.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9382.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9394-inherited-trait-calls.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9396.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9446.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9737.rs (100%) rename src/test/{run-pass => ui}/issues/issue-979.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9837.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9906.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9918.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9942.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9951.rs (100%) rename src/test/{run-pass => ui}/issues/issue-9968.rs (100%) rename src/test/{run-pass => ui}/istr.rs (98%) rename src/test/{run-pass => ui}/item-name-overload.rs (91%) rename src/test/{run-pass => ui}/iterators/into-iterator-type-inference-shift.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-cloned-type-inference.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-range.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-step-overflow-debug.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-step-overflow-ndebug.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-sum-overflow-debug.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-sum-overflow-ndebug.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-sum-overflow-overflow-checks.rs (100%) rename src/test/{run-pass => ui}/iterators/iter-zip.rs (100%) create mode 100644 src/test/ui/json-and-color.rs create mode 100644 src/test/ui/json-and-color.stderr create mode 100644 src/test/ui/json-and-error-format.rs create mode 100644 src/test/ui/json-and-error-format.stderr create mode 100644 src/test/ui/json-invalid.rs create mode 100644 src/test/ui/json-invalid.stderr create mode 100644 src/test/ui/json-multiple.nll.stderr create mode 100644 src/test/ui/json-multiple.rs create mode 100644 src/test/ui/json-multiple.stderr create mode 100644 src/test/ui/json-options.nll.stderr create mode 100644 src/test/ui/json-options.rs create mode 100644 src/test/ui/json-options.stderr create mode 100644 src/test/ui/json-short.rs create mode 100644 src/test/ui/json-short.stderr rename src/test/{run-pass => ui}/keyword-changes-2012-07-31.rs (93%) rename src/test/{run-pass => ui}/kindck-implicit-close-over-mut-var.rs (98%) rename src/test/{run-pass => ui}/kinds-in-metadata.rs (96%) rename src/test/{run-pass => ui}/lambda-infer-unresolved.rs (96%) rename src/test/{run-pass => ui}/lambda-var-hygiene.rs (94%) rename src/test/{run-pass => ui}/large-records.rs (97%) rename src/test/{run-pass => ui}/last-use-in-block.rs (96%) rename src/test/{run-pass => ui}/last-use-in-cap-clause.rs (95%) rename src/test/{run-pass => ui}/last-use-is-capture.rs (95%) create mode 100644 src/test/ui/layout/issue-60431-unsized-tail-behind-projection.rs rename src/test/{run-pass => ui}/lazy-and-or.rs (95%) rename src/test/{run-pass => ui}/lazy-init.rs (91%) rename src/test/{run-pass => ui}/leak-unique-as-tydesc.rs (92%) rename src/test/{run-pass => ui}/lex-bare-cr-nondoc-comment.rs (92%) rename src/test/{run-pass => ui}/lexer-crlf-line-endings-string-literal-doc-comment.rs (95%) rename src/test/{run-pass => ui}/lexical-scoping.rs (96%) rename src/test/{run-pass => ui}/lib-defaults.rs (96%) rename src/test/{run-pass => ui}/link-cfg-works.rs (95%) rename src/test/{run-pass => ui}/link-section.rs (98%) rename src/test/{run-pass => ui}/linkage1.rs (98%) rename src/test/{run-pass => ui}/lint-cap.rs (88%) rename src/test/{run-pass => ui}/lint-dead-code-associated-type.rs (92%) rename src/test/{run-pass => ui}/lint-dead-code-variant.rs (90%) rename src/test/{run-pass => ui}/lint-expr-stmt-attrs-for-early-lints.rs (95%) rename src/test/{run-pass => ui}/lint-unknown-lints-at-crate-level.rs (90%) create mode 100644 src/test/ui/lint/lint-unused-variables.rs create mode 100644 src/test/ui/lint/lint-unused-variables.stderr create mode 100644 src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs create mode 100644 src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr create mode 100644 src/test/ui/lint/uninitialized-zeroed.rs create mode 100644 src/test/ui/lint/uninitialized-zeroed.stderr create mode 100644 src/test/ui/lint/unused_parens_json_suggestion.fixed create mode 100644 src/test/ui/lint/unused_parens_remove_json_suggestion.fixed create mode 100644 src/test/ui/lint/unused_parens_remove_json_suggestion.rs create mode 100644 src/test/ui/lint/unused_parens_remove_json_suggestion.stderr rename src/test/{run-pass => ui}/list.rs (94%) rename src/test/{run-pass => ui}/liveness-assign-imm-local-after-ret.rs (92%) rename src/test/{run-pass => ui}/llvm-pr32379.rs (97%) rename src/test/{run-pass => ui}/log-err-phi.rs (84%) rename src/test/{run-pass => ui}/log-knows-the-names-of-variants-in-std.rs (97%) rename src/test/{run-pass => ui}/log-knows-the-names-of-variants.rs (96%) rename src/test/{run-pass => ui}/log-poly.rs (93%) rename src/test/{run-pass => ui}/logging-only-prints-once.rs (97%) rename src/test/{run-pass => ui}/logging_before_rt_started.rs (97%) rename src/test/{run-pass => ui}/long-while.rs (93%) create mode 100644 src/test/ui/loops/loop-break-unsize.rs rename src/test/{run-pass => ui}/lto-many-codegen-units.rs (86%) rename src/test/{run-pass => ui}/lto-still-runs-thread-dtors.rs (97%) rename src/test/{run-pass => ui}/lub-glb-with-unbound-infer-var.rs (96%) rename src/test/{run-pass => ui}/macro-quote-cond.rs (98%) rename src/test/{run-pass => ui}/macro-quote-test.rs (94%) rename src/test/{run-pass => ui}/macros/assert-eq-macro-success.rs (100%) rename src/test/{run-pass => ui}/macros/assert-eq-macro-unsized.rs (100%) rename src/test/{run-pass => ui}/macros/assert-ne-macro-success.rs (100%) rename src/test/{run-pass => ui}/macros/assert-ne-macro-unsized.rs (100%) create mode 100644 src/test/ui/macros/auxiliary/deprecated-macros.rs create mode 100644 src/test/ui/macros/auxiliary/dollar-crate-nested-encoding.rs rename src/test/{run-pass => ui}/macros/auxiliary/macro-comma-support.rs (100%) rename src/test/{run-pass => ui}/macros/auxiliary/macro-include-items-expr.rs (100%) rename src/test/{run-pass => ui}/macros/auxiliary/macro-include-items-item.rs (100%) rename src/test/{run-pass => ui}/macros/auxiliary/macro_crate_def_only.rs (100%) rename src/test/{run-pass => ui}/macros/auxiliary/macro_export_inner_module.rs (100%) rename src/test/{run-pass => ui}/macros/auxiliary/macro_with_super_1.rs (100%) create mode 100644 src/test/ui/macros/auxiliary/proc_macro_sequence.rs rename src/test/{run-pass/macros/auxiliary/two_macros.rs => ui/macros/auxiliary/two_macros-rpass.rs} (100%) rename src/test/{run-pass => ui}/macros/auxiliary/use-macro-self.rs (100%) create mode 100644 src/test/ui/macros/builtin-prelude-no-accidents.rs create mode 100644 src/test/ui/macros/builtin-prelude-no-accidents.stderr create mode 100644 src/test/ui/macros/builtin-std-paths-fail.rs create mode 100644 src/test/ui/macros/builtin-std-paths-fail.stderr create mode 100644 src/test/ui/macros/builtin-std-paths.rs rename src/test/{run-pass => ui}/macros/colorful-write-macros.rs (100%) rename src/test/{run-pass => ui}/macros/conditional-debug-macro-on.rs (100%) create mode 100644 src/test/ui/macros/derive-in-eager-expansion-hang.rs create mode 100644 src/test/ui/macros/derive-in-eager-expansion-hang.stderr rename src/test/{run-pass => ui}/macros/die-macro.rs (100%) create mode 100644 src/test/ui/macros/dollar-crate-nested-encoding.rs rename src/test/{run-pass => ui}/macros/issue-25274.rs (95%) create mode 100644 src/test/ui/macros/issue-61053-different-kleene.rs create mode 100644 src/test/ui/macros/issue-61053-different-kleene.stderr create mode 100644 src/test/ui/macros/issue-61053-duplicate-binder.rs create mode 100644 src/test/ui/macros/issue-61053-duplicate-binder.stderr create mode 100644 src/test/ui/macros/issue-61053-missing-repetition.rs create mode 100644 src/test/ui/macros/issue-61053-missing-repetition.stderr create mode 100644 src/test/ui/macros/issue-61053-unbound.rs create mode 100644 src/test/ui/macros/issue-61053-unbound.stderr create mode 100644 src/test/ui/macros/issue-63102.rs rename src/test/{run-pass => ui}/macros/log_syntax-trace_macros-macro-locations.rs (100%) rename src/test/{run-pass => ui}/macros/log_syntax-trace_macros-macro-locations.stdout (100%) rename src/test/{run-pass => ui}/macros/macro-2.rs (100%) rename src/test/{run-pass => ui}/macros/macro-as-fn-body.rs (100%) rename src/test/{run-pass/macros/macro-at-most-once-rep-2015.rs => ui/macros/macro-at-most-once-rep-2015-rpass.rs} (100%) rename src/test/{run-pass/macros/macro-at-most-once-rep-2018.rs => ui/macros/macro-at-most-once-rep-2018-rpass.rs} (100%) rename src/test/{run-pass => ui}/macros/macro-attribute-expansion.rs (100%) rename src/test/{run-pass => ui}/macros/macro-attributes.rs (100%) rename src/test/{run-pass => ui}/macros/macro-block-nonterminal.rs (100%) rename src/test/{run-pass/macros/macro-comma-behavior.rs => ui/macros/macro-comma-behavior-rpass.rs} (100%) rename src/test/{run-pass/macros/macro-comma-support.rs => ui/macros/macro-comma-support-rpass.rs} (99%) rename src/test/{run-pass => ui}/macros/macro-crate-def-only.rs (100%) rename src/test/{run-pass => ui}/macros/macro-crate-nonterminal-renamed.rs (100%) rename src/test/{run-pass => ui}/macros/macro-crate-nonterminal.rs (100%) rename src/test/{run-pass => ui}/macros/macro-crate-use.rs (100%) rename src/test/{run-pass => ui}/macros/macro-deep_expansion.rs (100%) rename src/test/{run-pass => ui}/macros/macro-delimiter-significance.rs (100%) create mode 100644 src/test/ui/macros/macro-deprecation.rs create mode 100644 src/test/ui/macros/macro-deprecation.stderr rename src/test/{run-pass => ui}/macros/macro-doc-comments.rs (100%) rename src/test/{run-pass => ui}/macros/macro-doc-escapes.rs (100%) rename src/test/{run-pass => ui}/macros/macro-doc-raw-str-hashes.rs (100%) rename src/test/{run-pass => ui}/macros/macro-export-inner-module.rs (100%) rename src/test/{run-pass => ui}/macros/macro-first-set.rs (98%) rename src/test/{run-pass/macros/macro-follow.rs => ui/macros/macro-follow-rpass.rs} (100%) rename src/test/{run-pass => ui}/macros/macro-followed-by-seq.rs (100%) rename src/test/{run-pass => ui}/macros/macro-include-items.rs (100%) rename src/test/{run-pass => ui}/macros/macro-interpolation.rs (100%) rename src/test/{run-pass => ui}/macros/macro-invocation-in-count-expr-fixed-array-type.rs (100%) rename src/test/{run-pass => ui}/macros/macro-lifetime-used-with-bound.rs (100%) rename src/test/{run-pass => ui}/macros/macro-lifetime-used-with-labels.rs (100%) rename src/test/{run-pass => ui}/macros/macro-lifetime-used-with-labels.stderr (100%) rename src/test/{run-pass => ui}/macros/macro-lifetime-used-with-static.rs (100%) rename src/test/{run-pass => ui}/macros/macro-lifetime.rs (100%) rename src/test/{run-pass => ui}/macros/macro-literal.rs (100%) rename src/test/{run-pass => ui}/macros/macro-meta-items.rs (100%) rename src/test/{run-pass => ui}/macros/macro-method-issue-4621.rs (100%) rename src/test/{run-pass => ui}/macros/macro-multiple-items.rs (100%) rename src/test/{run-pass => ui}/macros/macro-named-default.rs (100%) rename src/test/{run-pass => ui}/macros/macro-nested_definition_issue-31946.rs (100%) rename src/test/{run-pass => ui}/macros/macro-nested_expr.rs (100%) rename src/test/{run-pass => ui}/macros/macro-nested_stmt_macros.rs (100%) rename src/test/{run-pass => ui}/macros/macro-nt-list.rs (100%) rename src/test/{run-pass => ui}/macros/macro-of-higher-order.rs (100%) rename src/test/{run-pass => ui}/macros/macro-pat-follow.rs (100%) rename src/test/{run-pass => ui}/macros/macro-pat-neg-lit.rs (100%) rename src/test/{run-pass => ui}/macros/macro-pat.rs (100%) rename src/test/{run-pass => ui}/macros/macro-path.rs (100%) rename src/test/{run-pass => ui}/macros/macro-pub-matcher.rs (100%) rename src/test/{run-pass => ui}/macros/macro-seq-followed-by-seq.rs (100%) rename src/test/{run-pass/macros/macro-stability.rs => ui/macros/macro-stability-rpass.rs} (84%) rename src/test/{run-pass => ui}/macros/macro-stmt.rs (100%) rename src/test/{run-pass => ui}/macros/macro-stmt_macro_in_expr_macro.rs (100%) rename src/test/{run-pass => ui}/macros/macro-tt-followed-by-seq.rs (100%) rename src/test/{run-pass => ui}/macros/macro-use-all-and-none.rs (50%) create mode 100644 src/test/ui/macros/macro-use-all-and-none.stderr rename src/test/{run-pass => ui}/macros/macro-use-all.rs (100%) rename src/test/{run-pass => ui}/macros/macro-use-both.rs (100%) rename src/test/{run-pass => ui}/macros/macro-use-one.rs (100%) rename src/test/{run-pass => ui}/macros/macro-with-attrs1.rs (100%) rename src/test/{run-pass => ui}/macros/macro-with-attrs2.rs (100%) rename src/test/{run-pass => ui}/macros/macro-with-braces-in-expr-position.rs (100%) rename src/test/{run-pass => ui}/macros/macro_with_super_2.rs (100%) rename src/test/{run-pass/macros/macros-in-extern.rs => ui/macros/macros-in-extern-rpass.rs} (100%) create mode 100644 src/test/ui/macros/meta-variable-misuse.rs rename src/test/{run-pass => ui}/macros/parse-complex-macro-invoc-op.rs (100%) rename src/test/{run-pass => ui}/macros/paths-in-macro-invocations.rs (85%) rename src/test/{run-pass => ui}/macros/pub-item-inside-macro.rs (100%) rename src/test/{run-pass => ui}/macros/pub-method-inside-macro.rs (100%) create mode 100644 src/test/ui/macros/same-sequence-span.rs create mode 100644 src/test/ui/macros/same-sequence-span.stderr rename src/test/{run-pass => ui}/macros/semi-after-macro-ty.rs (100%) rename src/test/{run-pass => ui}/macros/stmt_expr_attr_macro_parse.rs (100%) rename src/test/{run-pass => ui}/macros/syntax-extension-cfg.rs (100%) rename src/test/{run-pass => ui}/macros/syntax-extension-source-utils-files/includeme.fragment (100%) rename src/test/{run-pass => ui}/macros/syntax-extension-source-utils.rs (87%) rename src/test/{run-pass => ui}/macros/try-macro.rs (95%) rename src/test/{run-pass => ui}/macros/two-macro-use.rs (100%) rename src/test/{run-pass => ui}/macros/type-macros-hlist.rs (100%) rename src/test/{run-pass => ui}/macros/type-macros-simple.rs (100%) rename src/test/{run-pass => ui}/macros/typeck-macro-interaction-issue-8852.rs (100%) create mode 100644 src/test/ui/macros/unknown-builtin.rs create mode 100644 src/test/ui/macros/unknown-builtin.stderr rename src/test/{run-pass => ui}/macros/use-macro-self.rs (100%) create mode 100644 src/test/ui/match/issue-50900.rs create mode 100644 src/test/ui/match/issue-50900.stderr create mode 100644 src/test/ui/match/match-arm-resolving-to-never.rs create mode 100644 src/test/ui/match/match-arm-resolving-to-never.stderr rename src/test/{run-pass => ui}/max-min-classes.rs (97%) rename src/test/{run-pass => ui}/methods/auxiliary/method_self_arg1.rs (100%) rename src/test/{run-pass => ui}/methods/auxiliary/method_self_arg2.rs (100%) create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls.rs create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls.stderr create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls2.rs create mode 100644 src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr rename src/test/{run-pass => ui}/methods/method-argument-inference-associated-type.rs (100%) rename src/test/{run-pass => ui}/methods/method-early-bound-lifetimes-on-self.rs (100%) rename src/test/{run-pass => ui}/methods/method-mut-self-modifies-mut-slice-lvalue.rs (100%) rename src/test/{run-pass => ui}/methods/method-normalize-bounds-issue-20604.rs (100%) rename src/test/{run-pass => ui}/methods/method-probe-no-guessing-dyn-trait.rs (99%) rename src/test/{run-pass => ui}/methods/method-projection.rs (100%) rename src/test/{run-pass => ui}/methods/method-recursive-blanket-impl.rs (100%) rename src/test/{run-pass => ui}/methods/method-self-arg-aux1.rs (100%) rename src/test/{run-pass => ui}/methods/method-self-arg-aux2.rs (100%) rename src/test/{run-pass => ui}/methods/method-self-arg-trait.rs (100%) rename src/test/{run-pass => ui}/methods/method-self-arg.rs (100%) rename src/test/{run-pass => ui}/methods/method-two-trait-defer-resolution-1.rs (100%) rename src/test/{run-pass => ui}/methods/method-two-trait-defer-resolution-2.rs (100%) rename src/test/{run-pass => ui}/methods/method-two-traits-distinguished-via-where-clause.rs (100%) rename src/test/{run-pass => ui}/methods/method-where-clause.rs (100%) rename src/test/{run-pass => ui}/mid-path-type-params.rs (97%) rename src/test/{run-pass => ui}/minmax-stability-issue-23687.rs (99%) rename src/test/{run-pass => ui}/mir/auxiliary/mir_external_refs.rs (100%) rename src/test/{run-pass => ui}/mir/mir-inlining/ice-issue-45493.rs (100%) rename src/test/{run-pass => ui}/mir/mir-inlining/ice-issue-45885.rs (100%) rename src/test/{run-pass => ui}/mir/mir-inlining/no-trait-method-issue-40473.rs (100%) rename src/test/{run-pass => ui}/mir/mir-typeck-normalize-fn-sig.rs (100%) rename src/test/{run-pass => ui}/mir/mir_adt_construction.rs (100%) rename src/test/{run-pass => ui}/mir/mir_ascription_coercion.rs (100%) rename src/test/{run-pass => ui}/mir/mir_augmented_assignments.rs (100%) rename src/test/{run-pass => ui}/mir/mir_autoderef.rs (100%) rename src/test/{run-pass => ui}/mir/mir_boxing.rs (100%) rename src/test/{run-pass => ui}/mir/mir_build_match_comparisons.rs (100%) rename src/test/{run-pass => ui}/mir/mir_call_with_associated_type.rs (100%) rename src/test/{run-pass => ui}/mir/mir_calls_to_shims.rs (100%) rename src/test/{run-pass => ui}/mir/mir_cast_fn_ret.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_array.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_array_2.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_call_converging.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_calls.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_calls_variadic.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_critical_edge.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_spike1.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_switch.rs (100%) rename src/test/{run-pass => ui}/mir/mir_codegen_switchint.rs (100%) rename src/test/{run-pass => ui}/mir/mir_coercion_casts.rs (100%) rename src/test/{run-pass => ui}/mir/mir_coercions.rs (100%) rename src/test/{run-pass => ui}/mir/mir_constval_adts.rs (100%) rename src/test/{run-pass => ui}/mir/mir_drop_order.rs (100%) rename src/test/{run-pass => ui}/mir/mir_early_return_scope.rs (100%) rename src/test/{run-pass => ui}/mir/mir_fat_ptr.rs (100%) rename src/test/{run-pass => ui}/mir/mir_fat_ptr_drop.rs (100%) rename src/test/{run-pass => ui}/mir/mir_heavy_promoted.rs (100%) rename src/test/{run-pass => ui}/mir/mir_match_arm_guard.rs (100%) rename src/test/{run-pass => ui}/mir/mir_match_test.rs (100%) rename src/test/{run-pass => ui}/mir/mir_misc_casts.rs (100%) rename src/test/{run-pass => ui}/mir/mir_overflow_off.rs (100%) rename src/test/{run-pass => ui}/mir/mir_raw_fat_ptr.rs (100%) rename src/test/{run-pass => ui}/mir/mir_refs_correct.rs (100%) rename src/test/{run-pass => ui}/mir/mir_small_agg_arg.rs (100%) rename src/test/{run-pass => ui}/mir/mir_static_subtype.rs (92%) rename src/test/{run-pass => ui}/mir/mir_struct_with_assoc_ty.rs (100%) rename src/test/{run-pass => ui}/mir/mir_temp_promotions.rs (100%) rename src/test/{run-pass => ui}/mir/mir_void_return.rs (100%) rename src/test/{run-pass => ui}/mir/mir_void_return_2.rs (100%) rename src/test/{run-pass => ui}/modules/auxiliary/two_macros_2.rs (100%) rename src/test/{run-pass => ui}/modules/mod-inside-fn.rs (100%) rename src/test/{run-pass => ui}/modules/mod-view-items.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_implicit.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_implicit_aux/compiletest-ignore-dir (100%) rename src/test/{run-pass => ui}/modules/mod_dir_implicit_aux/mod.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_path.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_path2.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_path3.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_path_multi.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_recursive.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_simple.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_simple/compiletest-ignore-dir (100%) rename src/test/{run-pass => ui}/modules/mod_dir_simple/load_another_mod.rs (100%) rename src/test/{run-pass => ui}/modules/mod_dir_simple/test.rs (100%) rename src/test/{run-pass => ui}/modules/mod_file.rs (100%) rename src/test/{run-pass => ui}/modules/mod_file_aux.rs (100%) rename src/test/{run-pass => ui}/modules/mod_file_with_path_attr.rs (100%) rename src/test/{run-pass => ui}/modules/module-polymorphism3-files/compiletest-ignore-dir (100%) rename src/test/{run-pass => ui}/modules/module-polymorphism3-files/float-template/inst_f32.rs (58%) rename src/test/{run-pass => ui}/modules/module-polymorphism3-files/float-template/inst_f64.rs (58%) rename src/test/{run-pass => ui}/modules/module-polymorphism3-files/float-template/inst_float.rs (60%) rename src/test/{run-pass => ui}/monad.rs (98%) rename src/test/{run-pass => ui}/monomorphize-abi-alignment.rs (98%) rename src/test/{run-pass => ui}/monomorphized-callees-with-ty-params-3314.rs (97%) rename src/test/{run-pass => ui}/moves/move-1-unique.rs (100%) rename src/test/{run-pass => ui}/moves/move-2-unique.rs (100%) rename src/test/{run-pass => ui}/moves/move-2.rs (100%) rename src/test/{run-pass => ui}/moves/move-3-unique.rs (100%) rename src/test/{run-pass => ui}/moves/move-4-unique.rs (100%) rename src/test/{run-pass => ui}/moves/move-4.rs (100%) rename src/test/{run-pass => ui}/moves/move-arg-2-unique.rs (100%) rename src/test/{run-pass => ui}/moves/move-arg-2.rs (100%) rename src/test/{run-pass => ui}/moves/move-arg.rs (100%) rename src/test/{run-pass => ui}/moves/move-nullary-fn.rs (100%) rename src/test/{run-pass => ui}/moves/move-out-of-field.rs (100%) rename src/test/{run-pass => ui}/moves/move-scalar.rs (100%) rename src/test/{run-pass => ui}/moves/moves-based-on-type-capture-clause.rs (100%) rename src/test/{run-pass => ui}/mpsc_stress.rs (99%) rename src/test/{run-pass => ui}/msvc-data-only.rs (92%) rename src/test/{run-pass => ui}/multi-panic.rs (99%) rename src/test/{run-pass => ui}/multibyte.rs (91%) rename src/test/{run-pass => ui}/multidispatch-conditional-impl-not-considered.rs (96%) rename src/test/{run-pass => ui}/multidispatch1.rs (97%) rename src/test/{run-pass => ui}/multidispatch2.rs (97%) rename src/test/{run-pass => ui}/multiline-comment.rs (88%) rename src/test/{run-pass => ui}/multiple-reprs.rs (99%) rename src/test/{run-pass => ui}/mut-function-arguments.rs (95%) rename src/test/{run-pass => ui}/mut-vstore-expr.rs (88%) rename src/test/{run-pass => ui}/mutual-recursion-group.rs (95%) rename src/test/{run-pass => ui}/native-print-no-runtime.rs (89%) rename src/test/{run-pass => ui}/negative.rs (85%) rename src/test/{run-pass => ui}/nested-block-comment.rs (92%) rename src/test/{run-pass => ui}/nested-class.rs (96%) rename src/test/{run-pass => ui}/nested-function-names-issue-8587.rs (98%) rename src/test/{run-pass => ui}/nested_item_main.rs (93%) rename src/test/{run-pass => ui}/never-result.rs (96%) rename src/test/{run-pass => ui}/never-type-rvalues.rs (97%) rename src/test/{run-pass => ui}/never_coercions.rs (95%) rename src/test/{run-pass => ui}/new-box-syntax.rs (97%) rename src/test/{run-pass => ui}/new-box.rs (97%) rename src/test/{run-pass => ui}/new-impl-syntax.rs (97%) rename src/test/{run-pass => ui}/new-import-syntax.rs (78%) rename src/test/{run-pass => ui}/new-style-constants.rs (83%) rename src/test/{run-pass => ui}/new-unicode-escapes.rs (95%) rename src/test/{run-pass => ui}/new-unsafe-pointers.rs (91%) rename src/test/{run-pass => ui}/newlambdas-ret-infer.rs (94%) rename src/test/{run-pass => ui}/newlambdas-ret-infer2.rs (94%) rename src/test/{run-pass => ui}/newlambdas.rs (95%) rename src/test/{run-pass => ui}/newtype-polymorphic.rs (97%) rename src/test/{run-pass => ui}/newtype-temporary.rs (90%) rename src/test/{run-pass => ui}/newtype.rs (97%) rename src/test/{run-pass => ui}/nil-decl-in-foreign.rs (93%) create mode 100644 src/test/ui/nll/get_default.polonius.stderr create mode 100644 src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.rs create mode 100644 src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr rename src/test/{run-pass => ui}/nll/issue-47153-generic-const.rs (100%) rename src/test/{run-pass => ui}/nll/issue-47589.rs (100%) rename src/test/{run-pass => ui}/nll/issue-48623-closure.rs (100%) rename src/test/{run-pass => ui}/nll/issue-48623-generator.rs (100%) rename src/test/{run-pass => ui}/nll/issue-50343.rs (100%) rename src/test/{run-pass => ui}/nll/issue-50461-used-mut-from-moves.rs (100%) rename src/test/{run-pass => ui}/nll/issue-53123-raw-pointer-cast.rs (100%) create mode 100644 src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr create mode 100644 src/test/ui/nll/match-cfg-fake-edges2.rs create mode 100644 src/test/ui/nll/match-cfg-fake-edges2.stderr rename src/test/{run-pass => ui}/nll/mutating_references.rs (100%) create mode 100644 src/test/ui/nll/polonius/assignment-kills-loans.rs create mode 100644 src/test/ui/nll/polonius/assignment-to-differing-field.rs create mode 100644 src/test/ui/nll/polonius/assignment-to-differing-field.stderr create mode 100644 src/test/ui/nll/polonius/call-kills-loans.rs create mode 100644 src/test/ui/nll/polonius/issue-46589.rs rename src/test/ui/nll/{ => polonius}/polonius-smoke-test.rs (100%) rename src/test/ui/nll/{ => polonius}/polonius-smoke-test.stderr (100%) create mode 100644 src/test/ui/nll/polonius/storagedead-kills-loans.rs rename src/test/{run-pass => ui}/nll/process_or_insert_default.rs (100%) rename src/test/{run-pass => ui}/nll/rc-loop.rs (100%) create mode 100644 src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr rename src/test/{run-pass => ui}/no-core-1.rs (93%) rename src/test/{run-pass => ui}/no-core-2.rs (94%) rename src/test/{run-pass => ui}/no-landing-pads.rs (96%) rename src/test/{run-pass => ui}/no-std-1.rs (86%) rename src/test/{run-pass => ui}/no-std-2.rs (89%) rename src/test/{run-pass => ui}/no-std-3.rs (94%) rename src/test/{run-pass => ui}/no-stdio.rs (99%) rename src/test/{run-pass => ui}/non-built-in-quote.rs (90%) rename src/test/{run-pass => ui}/non-legacy-modes.rs (95%) rename src/test/{run-pass => ui}/non_modrs_mods/foors_mod.rs (93%) rename src/test/{run-pass => ui}/non_modrs_mods/foors_mod/compiletest-ignore-dir (100%) rename src/test/{run-pass/non_modrs_mods/modrs_mod => ui/non_modrs_mods/foors_mod}/inline/somename.rs (55%) rename src/test/{run-pass => ui}/non_modrs_mods/foors_mod/inner_foors_mod.rs (55%) rename src/test/{run-pass/non_modrs_mods/modrs_mod => ui/non_modrs_mods/foors_mod}/inner_foors_mod/innest.rs (55%) rename src/test/{run-pass/non_modrs_mods/modrs_mod => ui/non_modrs_mods/foors_mod}/inner_modrs_mod/innest.rs (55%) rename src/test/{run-pass/non_modrs_mods/modrs_mod => ui/non_modrs_mods/foors_mod}/inner_modrs_mod/mod.rs (55%) rename src/test/{run-pass => ui}/non_modrs_mods/modrs_mod/compiletest-ignore-dir (100%) rename src/test/{run-pass/non_modrs_mods/foors_mod => ui/non_modrs_mods/modrs_mod}/inline/somename.rs (55%) rename src/test/{run-pass => ui}/non_modrs_mods/modrs_mod/inner_foors_mod.rs (55%) rename src/test/{run-pass/non_modrs_mods/foors_mod => ui/non_modrs_mods/modrs_mod}/inner_foors_mod/innest.rs (55%) rename src/test/{run-pass/non_modrs_mods/foors_mod => ui/non_modrs_mods/modrs_mod}/inner_modrs_mod/innest.rs (55%) rename src/test/{run-pass/non_modrs_mods/some_crazy_attr_mod_dir => ui/non_modrs_mods/modrs_mod}/inner_modrs_mod/mod.rs (55%) rename src/test/{run-pass => ui}/non_modrs_mods/modrs_mod/mod.rs (89%) rename src/test/{run-pass => ui}/non_modrs_mods/non_modrs_mods.rs (100%) rename src/test/{run-pass => ui}/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs (65%) rename src/test/{run-pass => ui}/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir (100%) create mode 100644 src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs rename src/test/{run-pass/non_modrs_mods/foors_mod => ui/non_modrs_mods/some_crazy_attr_mod_dir}/inner_modrs_mod/mod.rs (55%) rename src/test/{run-pass => ui}/nul-characters.rs (98%) rename src/test/{run-pass => ui}/nullable-pointer-ffi-compat.rs (98%) rename src/test/{run-pass => ui}/nullable-pointer-iotareduction.rs (99%) rename src/test/{run-pass => ui}/nullable-pointer-size.rs (98%) rename src/test/{run-pass => ui}/numbers-arithmetic/arith-0.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/arith-1.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/arith-2.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/arith-unsigned.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/div-mod.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float-int-invalid-const-cast.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float-literal-inference.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float-nan.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float-signature.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float2.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/float_math.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/floatlits.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/i128-ffi.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/i128.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/i32-sub.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/i8-incr.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/int-abs-overflow.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/int.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/integer-literal-radix.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/integer-literal-suffix-inference-2.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/integer-literal-suffix-inference-3.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/integer-literal-suffix-inference.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/next-power-of-two-overflow-debug.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/num-wrapping.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/numeric-method-autoexport.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/promoted_overflow_opt.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/saturating-float-casts.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/shift-near-oflo.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/shift-various-types.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/shift.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/signed-shift-const-eval.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/u128-as-f32.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/u128.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/u32-decr.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/u8-incr-decr.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/u8-incr.rs (100%) rename src/test/{run-pass => ui}/numbers-arithmetic/uint.rs (100%) rename src/test/{run-pass => ui}/object-lifetime-default-default-to-static.rs (97%) rename src/test/{run-pass => ui}/object-lifetime-default-from-rptr-box.rs (97%) rename src/test/{run-pass => ui}/object-lifetime-default-from-rptr-mut.rs (97%) rename src/test/{run-pass => ui}/object-lifetime-default-from-rptr.rs (98%) rename src/test/{run-pass => ui}/object-method-numbering.rs (97%) rename src/test/{run-pass => ui}/objects-coerce-freeze-borrored.rs (98%) rename src/test/{run-pass => ui}/objects-owned-object-borrowed-method-headerless.rs (98%) rename src/test/{run-pass => ui}/objects-owned-object-owned-method.rs (97%) rename src/test/{run-pass => ui}/once-move-out-on-heap.rs (94%) rename src/test/{run-pass => ui}/one-tuple.rs (95%) rename src/test/{run-pass => ui}/op-assign-builtins-by-ref.rs (99%) rename src/test/{run-pass => ui}/opeq.rs (95%) rename src/test/{run-pass => ui}/operator-associativity.rs (88%) rename src/test/{run-pass => ui}/operator-multidispatch.rs (98%) rename src/test/{run-pass => ui}/operator-overloading.rs (99%) rename src/test/{run-pass => ui}/optimization-fuel-0.rs (95%) rename src/test/{run-pass => ui}/optimization-fuel-0.stderr (100%) rename src/test/{run-pass => ui}/optimization-fuel-1.rs (96%) rename src/test/{run-pass => ui}/optimization-fuel-1.stderr (100%) rename src/test/{run-pass => ui}/option-ext.rs (90%) rename src/test/{run-pass => ui}/option-unwrap.rs (97%) rename src/test/{run-pass => ui}/out-of-stack.rs (99%) rename src/test/{run-pass => ui}/out-pointer-aliasing.rs (95%) rename src/test/{run-pass => ui}/output-slot-variants.rs (99%) rename src/test/{run-pass => ui}/over-constrained-vregs.rs (94%) rename src/test/{run-pass => ui}/overlap-doesnt-conflict-with-specialization.rs (95%) rename src/test/{run-pass => ui}/overlap-permitted-for-annotated-marker-traits.rs (97%) rename src/test/{run-pass => ui}/overloaded/auxiliary/overloaded_autoderef_xc.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-autoderef-count.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-autoderef-indexing.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-autoderef-order.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-autoderef-vtable.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-autoderef-xcrate.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-autoderef.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-calls-object-one-arg.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-calls-object-two-args.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-calls-object-zero-args.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-calls-param-vtables.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-calls-simple.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-calls-zero-args.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-deref-count.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-deref.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-index-assoc-list.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-index-autoderef.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-index-in-field.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded-index.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded_deref_with_ref_pattern.rs (100%) rename src/test/{run-pass => ui}/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs (100%) rename src/test/{run-pass => ui}/owned-implies-static.rs (89%) rename src/test/{run-pass => ui}/packed/auxiliary/packed.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-borrow-element.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-drop-aligned.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-generic-layout.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-generic-size.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-layout.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-match.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-optimized-enum.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-size-xc.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-size.rs (100%) rename src/test/{run-pass => ui}/packed/packed-struct-vec.rs (100%) rename src/test/{run-pass => ui}/packed/packed-tuple-struct-layout.rs (100%) rename src/test/{run-pass => ui}/packed/packed-tuple-struct-size.rs (100%) create mode 100644 src/test/ui/packed/packed-with-inference-vars-issue-61402.rs rename src/test/{run-pass => ui}/panic-runtime/abort-link-to-unwinding-crates.rs (100%) rename src/test/{run-pass => ui}/panic-runtime/abort.rs (100%) rename src/test/{run-pass => ui}/panic-runtime/auxiliary/exit-success-if-unwind.rs (100%) rename src/test/{run-pass => ui}/panic-runtime/link-to-abort.rs (100%) rename src/test/{run-pass => ui}/panic-runtime/link-to-unwind.rs (100%) rename src/test/{run-pass => ui}/panic-runtime/lto-abort.rs (100%) rename src/test/{run-pass => ui}/panic-runtime/lto-unwind.rs (100%) rename src/test/{run-pass => ui}/panic-uninitialized-zeroed.rs (98%) rename src/test/{run-pass => ui}/panics/panic-handler-chain.rs (100%) rename src/test/{run-pass => ui}/panics/panic-handler-flail-wildly.rs (100%) rename src/test/{run-pass => ui}/panics/panic-handler-set-twice.rs (100%) rename src/test/{run-pass => ui}/panics/panic-in-dtor-drops-fields.rs (100%) rename src/test/{run-pass => ui}/panics/panic-recover-propagate.rs (100%) rename src/test/{run-pass => ui}/panics/panic-safe.rs (100%) rename src/test/{run-pass => ui}/paren-free.rs (92%) rename src/test/{run-pass => ui}/parse-assoc-type-lt.rs (90%) rename src/test/{run-pass => ui}/parse-panic.rs (90%) rename src/test/{run-pass => ui}/parser-unicode-whitespace.rs (97%) create mode 100644 src/test/ui/parser/issue-62913.rs create mode 100644 src/test/ui/parser/issue-62913.stderr create mode 100644 src/test/ui/parser/issue-62973.rs create mode 100644 src/test/ui/parser/issue-62973.stderr create mode 100644 src/test/ui/parser/issue-63115-range-pat-interpolated.rs create mode 100644 src/test/ui/parser/issue-63135.rs create mode 100644 src/test/ui/parser/issue-63135.stderr delete mode 100644 src/test/ui/parser/pat-tuple-2.stderr create mode 100644 src/test/ui/parser/recover-for-loop-parens-around-head.rs create mode 100644 src/test/ui/parser/recover-for-loop-parens-around-head.stderr create mode 100644 src/test/ui/parser/recover-from-homoglyph.rs create mode 100644 src/test/ui/parser/recover-from-homoglyph.stderr create mode 100644 src/test/ui/parser/recover-range-pats.rs create mode 100644 src/test/ui/parser/recover-range-pats.stderr create mode 100644 src/test/ui/parser/several-carriage-returns-in-doc-comment.rs create mode 100644 src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr rename src/test/{run-pass => ui}/path.rs (90%) rename src/test/{run-pass => ui}/paths-containing-nul.rs (99%) create mode 100644 src/test/ui/pattern/rest-pat-semantic-disallowed.rs create mode 100644 src/test/ui/pattern/rest-pat-semantic-disallowed.stderr create mode 100644 src/test/ui/pattern/rest-pat-syntactic.rs rename src/test/{run-pass => ui}/print-stdout-eprint-stderr.rs (98%) rename src/test/{run-pass => ui}/privacy/auxiliary/priv-impl-prim-ty.rs (100%) rename src/test/{run-pass => ui}/privacy/auxiliary/privacy_reexport.rs (100%) rename src/test/{run-pass => ui}/privacy/auxiliary/pub_use_mods_xcrate.rs (100%) rename src/test/{run-pass => ui}/privacy/auxiliary/pub_use_xcrate1.rs (100%) rename src/test/{run-pass => ui}/privacy/auxiliary/pub_use_xcrate2.rs (100%) rename src/test/{run-pass => ui}/privacy/priv-impl-prim-ty.rs (100%) rename src/test/{run-pass => ui}/privacy/privacy-ns.rs (100%) rename src/test/{run-pass => ui}/privacy/privacy-reexport.rs (100%) rename src/test/{run-pass/privacy/privacy1.rs => ui/privacy/privacy1-rpass.rs} (100%) rename src/test/{run-pass => ui}/privacy/private-class-field.rs (100%) rename src/test/ui/privacy/{private-in-public-existential.rs => private-in-public-type-alias-impl-trait.rs} (62%) rename src/test/{run-pass/privacy/private-method.rs => ui/privacy/private-method-rpass.rs} (100%) rename src/test/{run-pass => ui}/privacy/pub-extern-privacy.rs (100%) rename src/test/{run-pass => ui}/privacy/pub-use-xcrate.rs (100%) rename src/test/{run-pass => ui}/privacy/pub_use_mods_xcrate_exe.rs (100%) rename src/test/{run-pass => ui}/proc-macro/add-impl.rs (92%) rename src/test/{run-pass => ui}/proc-macro/append-impl.rs (95%) rename src/test/{run-pass => ui}/proc-macro/attr-args.rs (95%) rename src/test/{run-pass => ui}/proc-macro/attr-cfg.rs (96%) rename src/test/{run-pass => ui}/proc-macro/attr-on-trait.rs (94%) rename src/test/{run-pass/proc-macro/attr-stmt-expr.rs => ui/proc-macro/attr-stmt-expr-rpass.rs} (86%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/add-impl.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/append-impl.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/attr-args.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/attr-cfg.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/attr-on-trait.rs (100%) rename src/test/{run-pass/proc-macro/auxiliary/attr-stmt-expr.rs => ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs} (90%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/bang-macro.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/call-site.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/count_compound_ops.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/custom-attr-only-one-derive.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-a.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-atob.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-attr-cfg.rs (100%) rename src/test/{run-pass/proc-macro/auxiliary/derive-b.rs => ui/proc-macro/auxiliary/derive-b-rpass.rs} (86%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-ctod.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-nothing.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-same-struct.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-two-attrs.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/derive-union.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/double.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/empty-crate.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/expand-with-a-macro.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/external-crate-var.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/gen-lifetime-token.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/hygiene_example.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/hygiene_example_codegen.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/issue-39889.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/issue-42708.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/issue-50061.rs (100%) rename src/test/{run-pass/proc-macro/auxiliary/lifetimes.rs => ui/proc-macro/auxiliary/lifetimes-rpass.rs} (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/modify-ast.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/negative-token.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/not-joint.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/span-api-tests.rs (100%) rename src/test/{run-pass => ui}/proc-macro/auxiliary/span-test-macros.rs (100%) rename src/test/{run-pass/proc-macro/auxiliary/test-macros.rs => ui/proc-macro/auxiliary/test-macros-rpass.rs} (100%) rename src/test/{run-pass => ui}/proc-macro/bang-macro.rs (94%) rename src/test/{run-pass => ui}/proc-macro/call-site.rs (94%) rename src/test/{run-pass => ui}/proc-macro/count_compound_ops.rs (94%) rename src/test/{run-pass => ui}/proc-macro/crate-var.rs (98%) rename src/test/{run-pass => ui}/proc-macro/custom-attr-only-one-derive.rs (94%) rename src/test/{run-pass => ui}/proc-macro/derive-attr-cfg.rs (93%) rename src/test/{run-pass => ui}/proc-macro/derive-b.rs (75%) rename src/test/{run-pass => ui}/proc-macro/derive-same-struct.rs (93%) rename src/test/{run-pass => ui}/proc-macro/derive-same-struct.stdout (100%) rename src/test/{run-pass => ui}/proc-macro/derive-test.rs (96%) rename src/test/{run-pass => ui}/proc-macro/derive-two-attrs.rs (92%) rename src/test/{run-pass => ui}/proc-macro/derive-union.rs (93%) create mode 100644 src/test/ui/proc-macro/dollar-crate-issue-62325.rs create mode 100644 src/test/ui/proc-macro/dollar-crate-issue-62325.stdout rename src/test/{run-pass => ui}/proc-macro/empty-crate.rs (89%) rename src/test/{run-pass => ui}/proc-macro/expand-with-a-macro.rs (96%) rename src/test/{run-pass => ui}/proc-macro/gen-lifetime-token.rs (92%) rename src/test/{run-pass => ui}/proc-macro/hygiene_example.rs (97%) rename src/test/{run-pass => ui}/proc-macro/issue-39889.rs (92%) rename src/test/{run-pass => ui}/proc-macro/issue-42708.rs (96%) rename src/test/{run-pass => ui}/proc-macro/issue-50061.rs (96%) rename src/test/{run-pass/proc-macro/lifetimes.rs => ui/proc-macro/lifetimes-rpass.rs} (81%) rename src/test/{run-pass => ui}/proc-macro/load-two.rs (95%) rename src/test/{run-pass/proc-macro/macros-in-extern.rs => ui/proc-macro/macros-in-extern-rpass.rs} (84%) rename src/test/{run-pass => ui}/proc-macro/modify-ast.rs (96%) rename src/test/{run-pass => ui}/proc-macro/negative-token.rs (94%) rename src/test/{run-pass => ui}/proc-macro/not-joint.rs (95%) rename src/test/{run-pass => ui}/proc-macro/smoke.rs (95%) rename src/test/{run-pass => ui}/proc-macro/span-api-tests.rs (99%) rename src/test/{run-pass => ui}/proc-macro/struct-field-macro.rs (93%) rename src/test/{run-pass => ui}/proc_macro.rs (98%) rename src/test/{run-pass => ui}/process/process-envs.rs (98%) rename src/test/{run-pass => ui}/process/process-exit.rs (100%) rename src/test/{run-pass => ui}/process/process-remove-from-env.rs (97%) rename src/test/{run-pass => ui}/process/process-sigpipe.rs (97%) rename src/test/{run-pass => ui}/process/process-spawn-nonexistent.rs (100%) rename src/test/{run-pass => ui}/process/process-spawn-with-unicode-params.rs (100%) rename src/test/{run-pass => ui}/process/process-status-inherits-stdin.rs (100%) rename src/test/{run-pass => ui}/project-cache-issue-31849.rs (99%) rename src/test/{run-pass => ui}/project-cache-issue-37154.rs (97%) rename src/test/{run-pass => ui}/project-defer-unification.rs (99%) rename src/test/{run-pass/ptr-coercion.rs => ui/ptr-coercion-rpass.rs} (97%) rename src/test/{run-pass => ui}/pure-sum.rs (98%) rename src/test/{run-pass => ui}/purity-infer.rs (88%) rename src/test/{run-pass => ui}/range-type-infer.rs (97%) rename src/test/{run-pass => ui}/range.rs (98%) rename src/test/{run-pass => ui}/range_inclusive.rs (99%) rename src/test/{run-pass => ui}/range_inclusive_gate.rs (96%) rename src/test/{run-pass => ui}/ranges-precedence.rs (98%) rename src/test/{run-pass => ui}/raw-fat-ptr.rs (99%) rename src/test/{run-pass => ui}/raw-str.rs (98%) rename src/test/{run-pass => ui}/rcvr-borrowed-to-region.rs (97%) rename src/test/{run-pass => ui}/reachable-unnameable-items.rs (99%) rename src/test/{run-pass => ui}/reachable-unnameable-type-alias.rs (96%) rename src/test/{run-pass => ui}/readalias.rs (93%) rename src/test/{run-pass => ui}/realloc-16687.rs (99%) delete mode 100644 src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr rename src/test/{run-pass => ui}/reexport-should-still-link.rs (93%) rename src/test/{run-pass => ui}/reexport-star.rs (92%) rename src/test/{run-pass => ui}/reexport-test-harness-main.rs (94%) rename src/test/{run-pass => ui}/refer-to-other-statics-by-value.rs (86%) rename src/test/{run-pass => ui}/regions/regions-addr-of-interior-of-unique-box.rs (100%) rename src/test/{run-pass => ui}/regions/regions-addr-of-ret.rs (100%) rename src/test/{run-pass => ui}/regions/regions-assoc-type-region-bound.rs (100%) rename src/test/{run-pass => ui}/regions/regions-assoc-type-static-bound.rs (100%) rename src/test/{run-pass => ui}/regions/regions-borrow-at.rs (100%) rename src/test/{run-pass => ui}/regions/regions-borrow-evec-fixed.rs (100%) rename src/test/{run-pass => ui}/regions/regions-borrow-evec-uniq.rs (100%) rename src/test/{run-pass => ui}/regions/regions-borrow-uniq.rs (100%) rename src/test/{run-pass => ui}/regions/regions-bot.rs (100%) rename src/test/{run-pass => ui}/regions/regions-bound-lists-feature-gate-2.rs (100%) rename src/test/{run-pass => ui}/regions/regions-bound-lists-feature-gate.rs (100%) rename src/test/{run-pass => ui}/regions/regions-close-over-type-parameter-successfully.rs (100%) rename src/test/{run-pass => ui}/regions/regions-copy-closure.rs (100%) rename src/test/{run-pass => ui}/regions/regions-creating-enums2.rs (100%) rename src/test/{run-pass => ui}/regions/regions-creating-enums5.rs (100%) rename src/test/{run-pass => ui}/regions/regions-debruijn-of-object.rs (100%) rename src/test/{run-pass => ui}/regions/regions-dependent-addr-of.rs (100%) rename src/test/{run-pass => ui}/regions/regions-dependent-autofn.rs (100%) rename src/test/{run-pass => ui}/regions/regions-dependent-autoslice.rs (100%) rename src/test/{run-pass => ui}/regions/regions-dependent-let-ref.rs (100%) rename src/test/{run-pass => ui}/regions/regions-early-bound-lifetime-in-assoc-fn.rs (100%) rename src/test/{run-pass => ui}/regions/regions-early-bound-trait-param.rs (100%) rename src/test/{run-pass => ui}/regions/regions-early-bound-used-in-bound-method.rs (100%) rename src/test/{run-pass => ui}/regions/regions-early-bound-used-in-bound.rs (100%) rename src/test/{run-pass => ui}/regions/regions-early-bound-used-in-type-param.rs (100%) rename src/test/{run-pass => ui}/regions/regions-escape-into-other-fn.rs (100%) rename src/test/{run-pass => ui}/regions/regions-expl-self.rs (100%) rename src/test/{run-pass => ui}/regions/regions-fn-subtyping-2.rs (100%) rename src/test/{run-pass => ui}/regions/regions-fn-subtyping.rs (100%) rename src/test/{run-pass => ui}/regions/regions-free-region-outlives-static-outlives-free-region.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-borrow-scope-addr-of.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-borrow-scope-view.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-borrow-scope-within-loop-ok.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-borrow-scope.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-call-2.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-call.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-contravariance-due-to-ret.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-reborrow-ref-mut-recurse.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-region-in-fn-but-not-type.rs (100%) rename src/test/{run-pass => ui}/regions/regions-infer-static-from-proc.rs (100%) rename src/test/{run-pass => ui}/regions/regions-issue-21422.rs (100%) rename src/test/{run-pass => ui}/regions/regions-issue-22246.rs (100%) rename src/test/{run-pass => ui}/regions/regions-lifetime-nonfree-late-bound.rs (100%) rename src/test/{run-pass => ui}/regions/regions-lifetime-static-items-enclosing-scopes.rs (100%) rename src/test/{run-pass => ui}/regions/regions-link-fn-args.rs (100%) rename src/test/{run-pass => ui}/regions/regions-lub-ref-ref-rc.rs (100%) rename src/test/{run-pass => ui}/regions/regions-mock-codegen.rs (100%) rename src/test/{run-pass => ui}/regions/regions-no-bound-in-argument-cleanup.rs (100%) rename src/test/{run-pass => ui}/regions/regions-no-variance-from-fn-generics.rs (100%) rename src/test/{run-pass => ui}/regions/regions-nullary-variant.rs (100%) rename src/test/{run-pass => ui}/regions/regions-params.rs (100%) rename src/test/{run-pass => ui}/regions/regions-reassign-let-bound-pointer.rs (100%) rename src/test/{run-pass => ui}/regions/regions-reassign-match-bound-pointer.rs (100%) rename src/test/{run-pass => ui}/regions/regions-refcell.rs (100%) rename src/test/{run-pass => ui}/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs (100%) rename src/test/{run-pass => ui}/regions/regions-return-interior-of-option.rs (100%) rename src/test/{run-pass => ui}/regions/regions-scope-chain-example.rs (100%) rename src/test/{run-pass => ui}/regions/regions-self-impls.rs (100%) rename src/test/{run-pass => ui}/regions/regions-self-in-enums.rs (100%) rename src/test/{run-pass => ui}/regions/regions-simple.rs (100%) rename src/test/{run-pass/regions/regions-static-bound.rs => ui/regions/regions-static-bound-rpass.rs} (100%) rename src/test/{run-pass => ui}/regions/regions-static-closure.rs (100%) rename src/test/{run-pass => ui}/regions/regions-trait-object-1.rs (100%) rename src/test/{run-pass => ui}/regions/regions-variance-contravariant-use-contravariant.rs (100%) rename src/test/{run-pass => ui}/regions/regions-variance-covariant-use-covariant.rs (100%) rename src/test/{run-pass => ui}/repeat-expr-in-static.rs (90%) rename src/test/{run-pass => ui}/repr_c_int_align.rs (98%) rename src/test/{run-pass => ui}/resolve-issue-2428.rs (93%) rename src/test/{run-pass => ui}/resolve-pseudo-shadowing.rs (94%) create mode 100644 src/test/ui/resolve/visibility-indeterminate.rs create mode 100644 src/test/ui/resolve/visibility-indeterminate.stderr rename src/test/{run-pass => ui}/resource-assign-is-not-copy.rs (97%) rename src/test/{run-pass => ui}/resource-destruct.rs (98%) rename src/test/{run-pass => ui}/result-opt-conversions.rs (98%) rename src/test/{run-pass => ui}/ret-bang.rs (94%) rename src/test/{run-pass => ui}/ret-none.rs (94%) rename src/test/{run-pass => ui}/return-nil.rs (89%) create mode 100644 src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs create mode 100644 src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs create mode 100644 src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs create mode 100644 src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs create mode 100644 src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs create mode 100644 src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs create mode 100644 src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr create mode 100644 src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr create mode 100644 src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr create mode 100644 src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr create mode 100644 src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr create mode 100644 src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs create mode 100644 src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr create mode 100644 src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs create mode 100644 src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.rs create mode 100644 src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.stderr create mode 100644 src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs create mode 100644 src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr create mode 100644 src/test/ui/rfc1445/issue-63479-match-fnptr.rs create mode 100644 src/test/ui/rfc1445/match-empty-array-allowed-without-eq-issue-62336.rs create mode 100644 src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs create mode 100644 src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr rename src/test/{run-pass => ui}/rfcs/rfc-1014-2.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1014.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1789-as-cell/from-mut.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/box.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/constref.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/enum.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/for.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/general.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/lit.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/range.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/ref-region.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/reset-mode.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/slice.rs (91%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/struct.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2005-default-binding-mode/tuple.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2151-raw-identifiers/attr.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2151-raw-identifiers/basic.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2151-raw-identifiers/items.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2151-raw-identifiers/macros.rs (96%) rename src/test/{run-pass => ui}/rfcs/rfc-2175-or-if-while-let/basic.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2302-self-struct-ctor.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc1445/eq-allows-match.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc1623.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc1717/auxiliary/clibrary.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc1717/library-override.rs (100%) rename src/test/{run-pass => ui}/rfcs/rfc1857-drop-order.rs (100%) rename src/test/{run-pass/rmeta.rs => ui/rmeta-rpass.rs} (86%) rename src/test/{run-pass => ui}/running-with-no-runtime.rs (99%) rename src/test/{run-pass => ui}/rustc-rust-log.rs (97%) rename src/test/{run-pass => ui}/rvalue-static-promotion.rs (96%) create mode 100644 src/test/ui/save-analysis/emit-notifications.polonius.stderr rename src/test/{run-pass => ui}/segfault-no-out-of-stack.rs (99%) rename src/test/{run-pass => ui}/semistatement-in-lambda.rs (96%) rename src/test/{run-pass => ui}/sepcomp/auxiliary/sepcomp-extern-lib.rs (100%) rename src/test/{run-pass => ui}/sepcomp/auxiliary/sepcomp_cci_lib.rs (100%) rename src/test/{run-pass => ui}/sepcomp/auxiliary/sepcomp_lib.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-cci.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-extern.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-fns-backwards.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-fns.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-lib-lto.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-lib.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-statics.rs (100%) rename src/test/{run-pass => ui}/sepcomp/sepcomp-unwind.rs (100%) rename src/test/{run-pass => ui}/seq-compare.rs (97%) rename src/test/{run-pass => ui}/shadow.rs (97%) rename src/test/{run-pass => ui}/shadowed-use-visibility.rs (91%) rename src/test/{run-pass => ui}/shebang.rs (63%) rename src/test/{run-pass => ui}/signal-alternate-stack-cleanup.rs (98%) rename src/test/{run-pass => ui}/signal-exit-status.rs (97%) rename src/test/{run-pass => ui}/sigpipe-should-be-ignored.rs (98%) rename src/test/{run-pass => ui}/simd/simd-generics.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-float-math.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-float-minmax.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-arithmetic-saturating.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-arithmetic.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-bitmask.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-cast.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-comparison.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-elements.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-gather.rs (100%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-reduction.rs (94%) rename src/test/{run-pass => ui}/simd/simd-intrinsic-generic-select.rs (93%) rename src/test/{run-pass => ui}/simd/simd-size-align.rs (100%) rename src/test/{run-pass => ui}/simd/simd-target-feature-mixup.rs (100%) rename src/test/{run-pass => ui}/simd/simd-type.rs (100%) rename src/test/{run-pass => ui}/simple-infer.rs (85%) rename src/test/{run-pass => ui}/simple_global_asm.rs (96%) rename src/test/{run-pass => ui}/size-and-align.rs (97%) rename src/test/{run-pass => ui}/sized-borrowed-pointer.rs (93%) rename src/test/{run-pass => ui}/sized-owned-pointer.rs (94%) rename src/test/{run-pass => ui}/sleep.rs (97%) rename src/test/{run-pass => ui}/slowparse-bstring.rs (99%) rename src/test/{run-pass => ui}/slowparse-string.rs (99%) rename src/test/{run-pass/specialization/README.md => ui/specialization/README-rpass.md} (100%) rename src/test/{run-pass => ui}/specialization/assoc-ty-graph-cycle.rs (100%) rename src/test/{run-pass => ui}/specialization/auxiliary/cross_crates_defaults.rs (100%) rename src/test/{run-pass => ui}/specialization/auxiliary/go_trait.rs (100%) rename src/test/{run-pass => ui}/specialization/auxiliary/specialization_cross_crate.rs (100%) rename src/test/{run-pass => ui}/specialization/cross-crate-defaults.rs (100%) rename src/test/{run-pass => ui}/specialization/defaultimpl/allowed-cross-crate.rs (100%) rename src/test/{run-pass => ui}/specialization/defaultimpl/auxiliary/go_trait.rs (100%) rename src/test/{run-pass => ui}/specialization/defaultimpl/out-of-order.rs (100%) rename src/test/{run-pass => ui}/specialization/defaultimpl/overlap-projection.rs (100%) rename src/test/{run-pass => ui}/specialization/defaultimpl/projection.rs (100%) rename src/test/{run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs => ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs} (100%) create mode 100644 src/test/ui/specialization/issue-36804.rs rename src/test/{run-pass => ui}/specialization/issue-50452.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-allowed-cross-crate.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-assoc-fns.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-basics.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-cross-crate-no-gate.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-cross-crate.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-default-methods.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-on-projection.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-out-of-order.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-overlap-projection.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-projection-alias.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-projection.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-super-traits.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-translate-projections-with-lifetimes.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-translate-projections-with-params.rs (100%) rename src/test/{run-pass => ui}/specialization/specialization-translate-projections.rs (100%) rename src/test/{run-pass => ui}/sse2.rs (98%) rename src/test/{run-pass => ui}/stable-addr-of.rs (90%) rename src/test/{run-pass => ui}/stack-probes-lto.rs (96%) rename src/test/{run-pass => ui}/stack-probes.rs (98%) rename src/test/{run-pass => ui}/statics/auxiliary/static-function-pointer-aux.rs (100%) rename src/test/{run-pass => ui}/statics/auxiliary/static-methods-crate.rs (100%) rename src/test/{run-pass => ui}/statics/auxiliary/static_fn_inline_xc_aux.rs (100%) rename src/test/{run-pass => ui}/statics/auxiliary/static_fn_trait_xc_aux.rs (100%) rename src/test/{run-pass => ui}/statics/auxiliary/static_mut_xc.rs (100%) rename src/test/{run-pass => ui}/statics/static-fn-inline-xc.rs (100%) rename src/test/{run-pass => ui}/statics/static-fn-trait-xc.rs (100%) rename src/test/{run-pass => ui}/statics/static-function-pointer-xc.rs (100%) rename src/test/{run-pass => ui}/statics/static-function-pointer.rs (100%) rename src/test/{run-pass => ui}/statics/static-impl.rs (100%) rename src/test/{run-pass => ui}/statics/static-method-in-trait-with-tps-intracrate.rs (100%) rename src/test/{run-pass => ui}/statics/static-method-xcrate.rs (100%) rename src/test/{run-pass => ui}/statics/static-methods-in-traits.rs (100%) rename src/test/{run-pass => ui}/statics/static-methods-in-traits2.rs (100%) rename src/test/{run-pass => ui}/statics/static-mut-foreign.rs (100%) rename src/test/{run-pass => ui}/statics/static-mut-xc.rs (100%) rename src/test/{run-pass => ui}/statics/static-recursive.rs (100%) rename src/test/{run-pass => ui}/stdio-is-blocking.rs (99%) rename src/test/{run-pass => ui}/str-concat.rs (94%) rename src/test/{run-pass => ui}/str-multiline.rs (95%) rename src/test/{run-pass => ui}/string-box-error.rs (97%) rename src/test/{run-pass => ui}/string-escapes.rs (88%) rename src/test/{run-pass => ui}/struct-ctor-mangling.rs (95%) rename src/test/{run-pass => ui}/structs-enums/align-enum.rs (100%) rename src/test/{run-pass => ui}/structs-enums/align-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class_2.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class_3.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class_4.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class_6.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class_cast.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/cci_class_trait.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/empty-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/namespaced_enums.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/newtype_struct_xc.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/struct_destructuring_cross_crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/struct_variant_xc_aux.rs (100%) rename src/test/{run-pass => ui}/structs-enums/auxiliary/xcrate_struct_aliases.rs (100%) rename src/test/{run-pass => ui}/structs-enums/borrow-tuple-fields.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-cast-to-trait-cross-crate-2.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-cast-to-trait-multiple-types.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-cast-to-trait.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-dtor.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-exports.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-impl-very-parameterized-trait.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-implement-trait-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-implement-traits.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-method-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-methods-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-methods.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-poly-methods-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-poly-methods.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-separate-impl.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-str-field.rs (100%) rename src/test/{run-pass => ui}/structs-enums/class-typarams.rs (100%) rename src/test/{run-pass => ui}/structs-enums/classes-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/classes-self-referential.rs (100%) rename src/test/{run-pass => ui}/structs-enums/classes-simple-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/classes-simple-method.rs (100%) rename src/test/{run-pass => ui}/structs-enums/classes-simple.rs (100%) rename src/test/{run-pass => ui}/structs-enums/classes.rs (100%) rename src/test/{run-pass => ui}/structs-enums/codegen-tag-static-padding.rs (100%) rename src/test/{run-pass => ui}/structs-enums/compare-generic-enums.rs (100%) rename src/test/{run-pass => ui}/structs-enums/discrim-explicit-23030.rs (100%) rename src/test/{run-pass => ui}/structs-enums/empty-struct-braces.rs (100%) rename src/test/{run-pass => ui}/structs-enums/empty-tag.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-alignment.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-clike-ffi-as-int.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-discr.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-discrim-autosizing.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-discrim-manual-sizing.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-discrim-range-overflow.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-discrim-width-stuff.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-disr-val-pretty.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-export-inheritance.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-layout-optimization.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-non-c-like-repr-c-and-int.rs (99%) rename src/test/{run-pass => ui}/structs-enums/enum-non-c-like-repr-c.rs (99%) rename src/test/{run-pass => ui}/structs-enums/enum-non-c-like-repr-int.rs (99%) rename src/test/{run-pass => ui}/structs-enums/enum-null-pointer-opt.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-nullable-const-null-with-fields.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-nullable-simplifycfg-misopt.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-univariant-repr.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-variants.rs (100%) rename src/test/{run-pass => ui}/structs-enums/enum-vec-initializer.rs (100%) rename src/test/{run-pass => ui}/structs-enums/export-abstract-tag.rs (100%) rename src/test/{run-pass => ui}/structs-enums/export-tag-variant.rs (100%) rename src/test/{run-pass => ui}/structs-enums/expr-if-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/expr-match-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/field-destruction-order.rs (100%) rename src/test/{run-pass => ui}/structs-enums/foreign-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/functional-struct-upd.rs (100%) rename src/test/{run-pass => ui}/structs-enums/ivec-tag.rs (100%) rename src/test/{run-pass => ui}/structs-enums/module-qualified-struct-destructure.rs (100%) rename src/test/{run-pass => ui}/structs-enums/namespaced-enum-emulate-flat-xc.rs (100%) rename src/test/{run-pass => ui}/structs-enums/namespaced-enum-emulate-flat.rs (100%) rename src/test/{run-pass => ui}/structs-enums/namespaced-enum-glob-import-xcrate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/namespaced-enum-glob-import.rs (100%) rename src/test/{run-pass => ui}/structs-enums/namespaced-enums-xcrate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/namespaced-enums.rs (100%) rename src/test/{run-pass => ui}/structs-enums/nested-enum-same-names.rs (100%) rename src/test/{run-pass => ui}/structs-enums/newtype-struct-drop-run.rs (100%) rename src/test/{run-pass => ui}/structs-enums/newtype-struct-with-dtor.rs (100%) rename src/test/{run-pass => ui}/structs-enums/newtype-struct-xc-2.rs (100%) rename src/test/{run-pass => ui}/structs-enums/newtype-struct-xc.rs (100%) rename src/test/{run-pass => ui}/structs-enums/nonzero-enum.rs (100%) rename src/test/{run-pass => ui}/structs-enums/numeric-fields.rs (100%) rename src/test/{run-pass => ui}/structs-enums/object-lifetime-default-from-ref-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/object-lifetime-default-from-rptr-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/rec-align-u32.rs (100%) rename src/test/{run-pass => ui}/structs-enums/rec-align-u64.rs (100%) rename src/test/{run-pass => ui}/structs-enums/rec-auto.rs (100%) rename src/test/{run-pass => ui}/structs-enums/rec-extend.rs (100%) rename src/test/{run-pass => ui}/structs-enums/rec-tup.rs (100%) rename src/test/{run-pass => ui}/structs-enums/rec.rs (100%) rename src/test/{run-pass => ui}/structs-enums/record-pat.rs (100%) rename src/test/{run-pass => ui}/structs-enums/resource-in-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/simple-generic-tag.rs (100%) rename src/test/{run-pass => ui}/structs-enums/simple-match-generic-tag.rs (100%) rename src/test/{run-pass => ui}/structs-enums/small-enum-range-edge.rs (100%) rename src/test/{run-pass => ui}/structs-enums/small-enums-with-fields.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-aliases-xcrate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-aliases.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-destructuring-cross-crate.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-field-shorthand.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-like-variant-construct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-like-variant-match.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-lit-functional-no-fields.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-literal-dtor.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-new-as-field-name.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-order-of-eval-1.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-order-of-eval-2.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-order-of-eval-3.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-order-of-eval-4.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-partial-move-1.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-partial-move-2.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-path-associated-type.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-path-self.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-pattern-matching.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-return.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct-variant-field-visibility.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct_variant_xc.rs (100%) rename src/test/{run-pass => ui}/structs-enums/struct_variant_xc_match.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-align-dyn-u64.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-align-dyn-variants.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-align-shape.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-align-u64.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-disr-val-shape.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-exports.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-in-block.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-variant-disr-type-mismatch.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag-variant-disr-val.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tag.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tuple-struct-construct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tuple-struct-constructor-pointer.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tuple-struct-destructuring.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tuple-struct-matching.rs (100%) rename src/test/{run-pass => ui}/structs-enums/tuple-struct-trivial.rs (100%) rename src/test/{run-pass => ui}/structs-enums/uninstantiable-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/unit-like-struct-drop-run.rs (100%) rename src/test/{run-pass => ui}/structs-enums/unit-like-struct.rs (100%) rename src/test/{run-pass => ui}/structs-enums/variant-structs-trivial.rs (100%) rename src/test/{run-pass => ui}/structured-compare.rs (98%) create mode 100644 src/test/ui/suggestions/assoc-type-in-method-return.rs create mode 100644 src/test/ui/suggestions/assoc-type-in-method-return.stderr create mode 100644 src/test/ui/suggestions/auxiliary/issue-61963-1.rs create mode 100644 src/test/ui/suggestions/auxiliary/issue-61963.rs create mode 100644 src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs create mode 100644 src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr create mode 100644 src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs create mode 100644 src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr create mode 100644 src/test/ui/suggestions/issue-21673.rs create mode 100644 src/test/ui/suggestions/issue-21673.stderr create mode 100644 src/test/ui/suggestions/issue-61226.rs create mode 100644 src/test/ui/suggestions/issue-61226.stderr create mode 100644 src/test/ui/suggestions/issue-61963.rs create mode 100644 src/test/ui/suggestions/issue-61963.stderr create mode 100644 src/test/ui/suggestions/issue-62843.rs create mode 100644 src/test/ui/suggestions/issue-62843.stderr create mode 100644 src/test/ui/suggestions/vec-macro-in-pattern.fixed create mode 100644 src/test/ui/suggestions/vec-macro-in-pattern.rs create mode 100644 src/test/ui/suggestions/vec-macro-in-pattern.stderr rename src/test/{run-pass => ui}/super-fast-paren-parsing.rs (98%) rename src/test/{run-pass => ui}/super.rs (93%) rename src/test/{run-pass => ui}/supported-cast.rs (99%) rename src/test/{run-pass => ui}/svh-add-nothing.rs (95%) rename src/test/{run-pass => ui}/swap-1.rs (91%) rename src/test/{run-pass => ui}/swap-2.rs (95%) rename src/test/{run-pass => ui}/swap-overlapping.rs (98%) rename src/test/{run-pass => ui}/tail-call-arg-leak.rs (94%) rename src/test/{run-pass => ui}/tail-cps.rs (97%) rename src/test/{run-pass => ui}/tail-direct.rs (94%) rename src/test/{run-pass => ui}/tcp-stress.rs (99%) rename src/test/{run-pass => ui}/terminate-in-initializer.rs (98%) rename src/test/{run-pass => ui}/test-allow-dead-extern-static-no-warning.rs (90%) rename src/test/{run-pass => ui}/test-allow-fail-attr.rs (94%) rename src/test/{run-pass => ui}/test-fn-signature-verification-for-explicit-return-type.rs (93%) rename src/test/{run-pass => ui}/test-main-not-dead-attr.rs (88%) rename src/test/{run-pass => ui}/test-main-not-dead.rs (85%) rename src/test/{run-pass => ui}/test-runner-hides-buried-main.rs (93%) rename src/test/{run-pass => ui}/test-runner-hides-main.rs (91%) rename src/test/{run-pass => ui}/test-runner-hides-start.rs (90%) rename src/test/{run-pass => ui}/test-should-fail-good-message.rs (95%) rename src/test/{run-pass => ui}/test-vs-cfg-test.rs (91%) rename src/test/{run-pass => ui}/thin-lto-global-allocator.rs (91%) rename src/test/{run-pass => ui}/thinlto/all-crates.rs (100%) rename src/test/{run-pass => ui}/thinlto/auxiliary/dylib.rs (100%) rename src/test/{run-pass => ui}/thinlto/auxiliary/msvc-imp-present.rs (100%) rename src/test/{run-pass => ui}/thinlto/auxiliary/thin-lto-inlines-aux.rs (100%) rename src/test/{run-pass => ui}/thinlto/dylib-works.rs (100%) rename src/test/{run-pass => ui}/thinlto/msvc-imp-present.rs (100%) rename src/test/{run-pass => ui}/thinlto/thin-lto-inlines.rs (100%) rename src/test/{run-pass => ui}/thinlto/thin-lto-inlines2.rs (100%) rename src/test/{run-pass => ui}/thinlto/weak-works.rs (100%) rename src/test/{run-pass => ui}/thread-local-not-in-prelude.rs (87%) rename src/test/{run-pass => ui}/threads-sendsync/auxiliary/thread-local-extern-static.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/comm.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/send-is-not-static-par-for.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/send-resource.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/send-type-inference.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/send_str_hashmap.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/send_str_treemap.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sendable-class.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sendfn-is-a-block.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sendfn-spawn-with-fn-arg.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/spawn-fn.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/spawn-types.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/spawn.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/spawn2.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/spawning-with-debug.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/std-sync-right-kind-impls.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sync-send-atomics.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sync-send-in-std.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sync-send-iterators-in-libcollections.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/sync-send-iterators-in-libcore.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-0.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-1.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-10.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-11.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-12.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-13.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-14.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-15.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-16.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-17.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-3.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-4.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-5.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-6.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-7.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-9.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-comm-chan-nil.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-life-0.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-spawn-move-and-copy.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/task-stderr.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/thread-local-extern-static.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/thread-local-syntax.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/threads.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/tls-init-on-init.rs (100%) rename src/test/{run-pass => ui}/threads-sendsync/tls-try-with.rs (100%) rename src/test/{run-pass => ui}/tool_attributes.rs (93%) rename src/test/{run-pass/tool_lints.rs => ui/tool_lints-rpass.rs} (84%) rename src/test/{run-pass => ui}/tool_lints_2018_preview.rs (88%) rename src/test/{run-pass => ui}/trailing-comma.rs (90%) rename src/test/{run-pass => ui}/traits/anon-trait-static-method.rs (100%) rename src/test/{run-pass => ui}/traits/anon_trait_static_method_exe.rs (100%) rename src/test/{run-pass => ui}/traits/assignability-trait.rs (100%) rename src/test/{run-pass => ui}/traits/astconv-cycle-between-trait-and-type.rs (100%) rename src/test/{run-pass => ui}/traits/augmented-assignments-trait.rs (100%) rename src/test/{run-pass => ui}/traits/auto-traits.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/anon_trait_static_method_lib.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/go_trait.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_alias.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_default_method_xc_aux.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_default_method_xc_aux_2.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_inheritance_auto_xc_aux.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_inheritance_overloading_xc.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/trait_xc_call_aux.rs (100%) rename src/test/{run-pass => ui}/traits/auxiliary/traitimpl.rs (100%) rename src/test/{run-pass => ui}/traits/cycle-trait-type-trait.rs (100%) rename src/test/{run-pass => ui}/traits/default-method-supertrait-vtable.rs (100%) rename src/test/{run-pass => ui}/traits/dyn-trait.rs (100%) rename src/test/{run-pass => ui}/traits/fmt-pointer-trait.rs (100%) rename src/test/{run-pass => ui}/traits/impl-implicit-trait.rs (100%) rename src/test/{run-pass => ui}/traits/impl-inherent-prefer-over-trait.rs (100%) rename src/test/{run-pass => ui}/traits/infer-from-object-trait-issue-26952.rs (100%) rename src/test/{run-pass => ui}/traits/inherent-trait-method-order.rs (100%) rename src/test/{run-pass => ui}/traits/kindck-owned-trait-contains-1.rs (100%) rename src/test/{run-pass => ui}/traits/multiple-trait-bounds.rs (100%) rename src/test/{run-pass => ui}/traits/object-one-type-two-traits.rs (100%) rename src/test/{run-pass => ui}/traits/overlap-permitted-for-marker-traits-neg.rs (100%) rename src/test/{run-pass => ui}/traits/overlap-permitted-for-marker-traits.rs (100%) rename src/test/{run-pass => ui}/traits/parameterized-trait-with-bounds.rs (100%) rename src/test/{run-pass => ui}/traits/principal-less-trait-objects.rs (99%) rename src/test/{run-pass => ui}/traits/supertrait-default-generics.rs (100%) rename src/test/{run-pass => ui}/traits/syntax-trait-polarity.rs (100%) rename src/test/{run-pass => ui}/traits/trait-alias-import-cross-crate.rs (100%) rename src/test/{run-pass => ui}/traits/trait-alias-import.rs (97%) rename src/test/{run-pass => ui}/traits/trait-bounds-basic.rs (100%) rename src/test/{run-pass => ui}/traits/trait-bounds-impl-comparison-duplicates.rs (100%) rename src/test/{run-pass => ui}/traits/trait-bounds-in-arc.rs (97%) rename src/test/{run-pass/traits/trait-bounds-on-structs-and-enums.rs => ui/traits/trait-bounds-on-structs-and-enums-rpass.rs} (100%) rename src/test/{run-pass => ui}/traits/trait-bounds-recursion.rs (100%) rename src/test/{run-pass => ui}/traits/trait-bounds.rs (100%) rename src/test/{run-pass => ui}/traits/trait-cache-issue-18209.rs (100%) rename src/test/{run-pass => ui}/traits/trait-coercion-generic.rs (100%) rename src/test/{run-pass => ui}/traits/trait-coercion.rs (100%) rename src/test/{run-pass => ui}/traits/trait-composition-trivial.rs (100%) rename src/test/{run-pass => ui}/traits/trait-copy-guessing.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-bound-subst.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-bound-subst2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-bound-subst3.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-bound-subst4.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-bound.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-xc-2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-default-method-xc.rs (100%) rename src/test/{run-pass => ui}/traits/trait-false-ambiguity-where-clause-builtin-bound.rs (100%) rename src/test/{run-pass => ui}/traits/trait-generic.rs (100%) rename src/test/{run-pass => ui}/traits/trait-impl-2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-impl.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-auto-xc-2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-auto-xc.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-auto.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-call-bound-inherited.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-call-bound-inherited2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-cast-without-call-to-supertrait.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-cast.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-cross-trait-call-xc.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-cross-trait-call.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-diamond.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-multiple-inheritors.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-multiple-params.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-num.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-num0.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-num1.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-num2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-num3.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-num5.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-overloading-simple.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-overloading-xc-exe.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-overloading.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-self-in-supertype.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-self.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-simple.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-static.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-static2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-subst.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-subst2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance-visibility.rs (100%) rename src/test/{run-pass => ui}/traits/trait-inheritance2.rs (100%) rename src/test/{run-pass => ui}/traits/trait-item-inside-macro.rs (100%) rename src/test/{run-pass => ui}/traits/trait-object-auto-dedup.rs (100%) rename src/test/{run-pass => ui}/traits/trait-object-exclusion.rs (100%) rename src/test/{run-pass => ui}/traits/trait-object-generics.rs (100%) rename src/test/{run-pass => ui}/traits/trait-object-lifetime-first.rs (100%) rename src/test/{run-pass => ui}/traits/trait-object-with-lifetime-bound.rs (100%) rename src/test/{run-pass => ui}/traits/trait-region-pointer-simple.rs (100%) rename src/test/{run-pass => ui}/traits/trait-safety-ok-cc.rs (100%) rename src/test/{run-pass => ui}/traits/trait-safety-ok.rs (100%) rename src/test/{run-pass => ui}/traits/trait-static-method-overwriting.rs (100%) rename src/test/{run-pass => ui}/traits/trait-to-str.rs (100%) rename src/test/{run-pass => ui}/traits/trait-where-clause-vs-impl.rs (100%) rename src/test/{run-pass => ui}/traits/trait-with-bounds-default.rs (100%) rename src/test/{run-pass => ui}/traits/traits-assoc-type-in-supertrait.rs (100%) rename src/test/{run-pass => ui}/traits/traits-conditional-dispatch.rs (100%) rename src/test/{run-pass => ui}/traits/traits-conditional-model-fn.rs (100%) rename src/test/{run-pass => ui}/traits/traits-default-method-macro.rs (100%) rename src/test/{run-pass => ui}/traits/traits-default-method-mut.rs (100%) rename src/test/{run-pass => ui}/traits/traits-default-method-self.rs (100%) rename src/test/{run-pass => ui}/traits/traits-default-method-trivial.rs (100%) rename src/test/{run-pass => ui}/traits/traits-elaborate-type-region.rs (100%) rename src/test/{run-pass => ui}/traits/traits-impl-object-overlap-issue-23853.rs (100%) rename src/test/{run-pass => ui}/traits/traits-issue-22019.rs (100%) rename src/test/{run-pass => ui}/traits/traits-issue-22110.rs (100%) rename src/test/{run-pass => ui}/traits/traits-issue-22655.rs (100%) rename src/test/{run-pass => ui}/traits/traits-issue-23003.rs (100%) rename src/test/{run-pass => ui}/traits/traits-issue-26339.rs (100%) rename src/test/{run-pass => ui}/traits/traits-multidispatch-infer-convert-target.rs (100%) rename src/test/{run-pass/traits/traits-negative-impls.rs => ui/traits/traits-negative-impls-rpass.rs} (100%) rename src/test/{run-pass => ui}/traits/traits-repeated-supertrait.rs (100%) rename src/test/{run-pass => ui}/traits/ufcs-trait-object.rs (100%) rename src/test/{run-pass => ui}/traits/use-trait-before-def.rs (100%) rename src/test/{run-pass => ui}/transmute-non-immediate-to-immediate.rs (94%) rename src/test/{run-pass => ui}/transmute-specialization.rs (94%) rename src/test/{run-pass => ui}/trivial-message.rs (95%) rename src/test/{run-pass/trivial_casts.rs => ui/trivial_casts-rpass.rs} (99%) rename src/test/{run-pass => ui}/try-block.rs (99%) rename src/test/{run-pass => ui}/try-from-int-error-partial-eq.rs (93%) rename src/test/{run-pass => ui}/try-is-identifier-edition2015.rs (93%) rename src/test/{run-pass => ui}/try-operator-custom.rs (98%) rename src/test/{run-pass => ui}/try-operator-hygiene.rs (97%) rename src/test/{run-pass => ui}/try-operator.rs (99%) rename src/test/{run-pass => ui}/try-wait.rs (99%) rename src/test/{run-pass => ui}/try_from.rs (98%) rename src/test/{run-pass => ui}/tup.rs (96%) rename src/test/{run-pass => ui}/tuple-index-fat-types.rs (93%) rename src/test/{run-pass => ui}/tuple-index.rs (97%) create mode 100644 src/test/ui/tydesc-name.rs create mode 100644 src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs create mode 100644 src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs create mode 100644 src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr rename src/test/ui/{existential_types/existential-associated-type.rs => type-alias-impl-trait/associated-type-alias-impl-trait.rs} (72%) create mode 100644 src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs rename src/test/ui/{existential_types => type-alias-impl-trait}/auxiliary/cross_crate_ice2.rs (58%) rename src/test/ui/{existential_types => type-alias-impl-trait}/bound_reduction.rs (63%) rename src/test/ui/{existential_types => type-alias-impl-trait}/bound_reduction2.rs (79%) rename src/test/ui/{existential_types => type-alias-impl-trait}/bound_reduction2.stderr (62%) rename src/test/ui/{existential_types => type-alias-impl-trait}/cross_crate_ice.rs (81%) rename src/test/ui/{existential_types => type-alias-impl-trait}/cross_crate_ice2.rs (75%) create mode 100644 src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs rename src/test/ui/{existential_types => type-alias-impl-trait}/declared_but_never_defined.stderr (58%) create mode 100644 src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs rename src/test/ui/{existential_types => type-alias-impl-trait}/declared_but_not_defined_in_scope.stderr (55%) rename src/test/ui/{existential_types => type-alias-impl-trait}/different_defining_uses.rs (69%) rename src/test/ui/{existential_types => type-alias-impl-trait}/different_defining_uses.stderr (81%) rename src/test/ui/{existential_types => type-alias-impl-trait}/different_defining_uses_never_type.rs (77%) rename src/test/ui/{existential_types => type-alias-impl-trait}/different_defining_uses_never_type.stderr (81%) rename src/test/ui/{existential_types => type-alias-impl-trait}/different_defining_uses_never_type2.rs (79%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_different_defining_uses.rs (70%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_different_defining_uses.stderr (85%) create mode 100644 src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_lifetime_param.stderr (52%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use.rs (55%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use.stderr (58%) create mode 100644 src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use2.rs (59%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use2.stderr (62%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use3.rs (71%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use3.stderr (85%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use4.rs (58%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use4.stderr (62%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use5.rs (80%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use5.stderr (84%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use6.rs (80%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use6.stderr (84%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use7.rs (73%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use8.rs (77%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use8.stderr (85%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use9.rs (82%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_duplicate_param_use9.stderr (85%) create mode 100644 src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_nondefining_use.rs (56%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_nondefining_use.stderr (51%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_not_used.rs (73%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_not_used.stderr (67%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_type_does_not_live_long_enough.nll.stderr (73%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_type_does_not_live_long_enough.rs (79%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_type_does_not_live_long_enough.stderr (71%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_underconstrained.rs (59%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_underconstrained.stderr (55%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_underconstrained2.rs (76%) rename src/test/ui/{existential_types => type-alias-impl-trait}/generic_underconstrained2.stderr (50%) create mode 100644 src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-53096.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-53598.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-53598.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-57700.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-57700.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-58887.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-58887.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-58951.rs rename src/test/ui/{existential-type => type-alias-impl-trait}/issue-60371.rs (76%) rename src/test/ui/{existential-type => type-alias-impl-trait}/issue-60371.stderr (59%) create mode 100644 src/test/ui/type-alias-impl-trait/issue-60407.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-60564.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-60564.stderr rename src/test/ui/{existential_types/nested_existential_types.rs => type-alias-impl-trait/nested_type_alias_impl_trait.rs} (57%) rename src/test/ui/{existential_types => type-alias-impl-trait}/never_reveal_concrete_type.rs (75%) rename src/test/ui/{existential_types => type-alias-impl-trait}/never_reveal_concrete_type.stderr (100%) create mode 100644 src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs create mode 100644 src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr rename src/test/ui/{existential_types => type-alias-impl-trait}/no_revealing_outside_defining_module.rs (78%) rename src/test/ui/{existential_types => type-alias-impl-trait}/no_revealing_outside_defining_module.stderr (100%) rename src/test/ui/{existential_types => type-alias-impl-trait}/not_a_defining_use.rs (81%) rename src/test/ui/{existential_types => type-alias-impl-trait}/not_a_defining_use.stderr (78%) rename src/test/ui/{existential_types => type-alias-impl-trait}/not_well_formed.rs (58%) rename src/test/ui/{existential_types => type-alias-impl-trait}/not_well_formed.stderr (51%) rename src/test/ui/{existential_types => type-alias-impl-trait}/private_unused.rs (72%) create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs create mode 100644 src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr rename src/test/ui/{existential_types/existential-types-with-no-traits.rs => type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs} (75%) rename src/test/ui/{existential_types/existential-types-with-no-traits.stderr => type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr} (53%) rename src/test/{run-pass/existential_type.rs => ui/type-alias-impl-trait/type-alias-impl-trait.rs} (78%) rename src/test/ui/{existential_types => type-alias-impl-trait}/unused_generic_param.rs (73%) create mode 100644 src/test/ui/type-alias-impl-trait/unused_generic_param.stderr rename src/test/{run-pass => ui}/type-ascription.rs (98%) rename src/test/{run-pass => ui}/type-id-higher-rank-2.rs (98%) rename src/test/{run-pass => ui}/type-id-higher-rank.rs (99%) rename src/test/{run-pass => ui}/type-in-nested-module.rs (94%) rename src/test/{run-pass => ui}/type-infer-generalize-ty-var.rs (98%) rename src/test/{run-pass => ui}/type-namespace.rs (90%) rename src/test/{run-pass => ui}/type-param-constraints.rs (97%) rename src/test/{run-pass => ui}/type-param.rs (91%) rename src/test/{run-pass => ui}/type-params-in-for-each.rs (96%) rename src/test/{run-pass => ui}/type-ptr.rs (93%) rename src/test/{run-pass => ui}/type-sizes.rs (99%) rename src/test/{run-pass => ui}/type-use-i1-versus-i8.rs (93%) create mode 100644 src/test/ui/type/ascription/issue-34255-1.rs create mode 100644 src/test/ui/type/ascription/issue-34255-1.stderr create mode 100644 src/test/ui/type/ascription/issue-47666.rs create mode 100644 src/test/ui/type/ascription/issue-47666.stderr create mode 100644 src/test/ui/type/ascription/issue-54516.rs create mode 100644 src/test/ui/type/ascription/issue-54516.stderr create mode 100644 src/test/ui/type/ascription/issue-60933.rs create mode 100644 src/test/ui/type/ascription/issue-60933.stderr rename src/test/{run-pass => ui}/typeck-closure-to-unsafe-fn-ptr.rs (90%) rename src/test/{run-pass => ui}/typeck-fn-to-unsafe-fn-ptr.rs (94%) create mode 100644 src/test/ui/typeck/typeck_type_placeholder_item_help.rs create mode 100644 src/test/ui/typeck/typeck_type_placeholder_item_help.stderr rename src/test/{run-pass => ui}/typeck_type_placeholder_1.rs (97%) rename src/test/{run-pass => ui}/typeclasses-eq-example-static.rs (99%) rename src/test/{run-pass => ui}/typeclasses-eq-example.rs (99%) rename src/test/{run-pass => ui}/typeid-intrinsic.rs (83%) rename src/test/{run-pass => ui}/typestate-cfg-nesting.rs (96%) rename src/test/{run-pass => ui}/typestate-multi-decl.rs (87%) rename src/test/{run-pass => ui}/ufcs-polymorphic-paths.rs (99%) rename src/test/{run-pass => ui}/ufcs-type-params.rs (94%) rename src/test/{run-pass => ui}/unary-minus-suffix-inference.rs (96%) rename src/test/{run-pass => ui}/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-all-traits.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-blanket-fn-mut.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-blanket-fn.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-boxed.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-by-ref.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-call-fn-autoderef.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-call-sugar-object.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-counter-not-moved.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-cross-crate.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-direct-sugary-call.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-drop.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-extern-fn-hr.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-extern-fn.rs (100%) create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-generic.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-fnmut-move.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-fnmut.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-fnonce-move.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-fnonce.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-kind.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-recursive-fn.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-infer-upvar.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-manual-impl.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-monomorphization.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-move-mutable.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-prelude.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-simple.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-single-word-env.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-static-call-fn-once.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-sugar-object.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-unique-type-id.rs (100%) rename src/test/{run-pass => ui}/unboxed-closures/unboxed-closures-zero-args.rs (100%) rename src/test/{run-pass => ui}/underscore-lifetimes.rs (97%) rename src/test/{run-pass => ui}/underscore-method-after-integer.rs (90%) rename src/test/{run-pass => ui}/uniform-paths/auxiliary/issue-53691.rs (100%) rename src/test/{run-pass => ui}/uniform-paths/basic-nested.rs (100%) rename src/test/{run-pass => ui}/uniform-paths/basic.rs (100%) rename src/test/{run-pass => ui}/uniform-paths/issue-53691.rs (90%) rename src/test/{run-pass => ui}/uniform-paths/macros-nested.rs (100%) rename src/test/{run-pass => ui}/uniform-paths/macros.rs (100%) rename src/test/{run-pass => ui}/uniform-paths/same-crate.rs (100%) rename src/test/{run-pass => ui}/unify-return-ty.rs (96%) create mode 100644 src/test/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs rename src/test/{run-pass => ui}/uninit-empty-types.rs (89%) rename src/test/{run-pass => ui}/union/auxiliary/union.rs (100%) rename src/test/{run-pass => ui}/union/union-align.rs (100%) rename src/test/{run-pass => ui}/union/union-backcomp.rs (100%) rename src/test/{run-pass => ui}/union/union-basic.rs (100%) rename src/test/{run-pass => ui}/union/union-c-interop.rs (100%) rename src/test/{run-pass => ui}/union/union-const-codegen.rs (100%) rename src/test/{run-pass => ui}/union/union-const-eval-field.rs (100%) rename src/test/{run-pass/union/union-derive.rs => ui/union/union-derive-rpass.rs} (100%) rename src/test/{run-pass => ui}/union/union-drop-assign.rs (100%) rename src/test/{run-pass => ui}/union/union-drop.rs (100%) rename src/test/{run-pass/union/union-generic.rs => ui/union/union-generic-rpass.rs} (100%) rename src/test/{run-pass => ui}/union/union-inherent-method.rs (100%) rename src/test/{run-pass => ui}/union/union-macro.rs (100%) rename src/test/{run-pass => ui}/union/union-nodrop.rs (100%) rename src/test/{run-pass => ui}/union/union-nonzero.rs (100%) rename src/test/{run-pass => ui}/union/union-overwrite.rs (100%) rename src/test/{run-pass => ui}/union/union-packed.rs (100%) rename src/test/{run-pass => ui}/union/union-pat-refutability.rs (100%) rename src/test/{run-pass => ui}/union/union-trait-impl.rs (100%) rename src/test/{run-pass => ui}/union/union-transmute.rs (100%) rename src/test/{run-pass/union/union-with-drop-fields-lint.rs => ui/union/union-with-drop-fields-lint-rpass.rs} (100%) rename src/test/{run-pass => ui}/unique/unique-assign-copy.rs (100%) rename src/test/{run-pass => ui}/unique/unique-assign-drop.rs (100%) rename src/test/{run-pass => ui}/unique/unique-assign-generic.rs (100%) rename src/test/{run-pass => ui}/unique/unique-assign.rs (100%) rename src/test/{run-pass => ui}/unique/unique-autoderef-field.rs (100%) rename src/test/{run-pass => ui}/unique/unique-autoderef-index.rs (100%) rename src/test/{run-pass => ui}/unique/unique-cmp.rs (100%) rename src/test/{run-pass => ui}/unique/unique-containing-tag.rs (100%) rename src/test/{run-pass => ui}/unique/unique-create.rs (100%) rename src/test/{run-pass => ui}/unique/unique-decl-init-copy.rs (100%) rename src/test/{run-pass => ui}/unique/unique-decl-init.rs (100%) rename src/test/{run-pass => ui}/unique/unique-decl-move.rs (100%) rename src/test/{run-pass => ui}/unique/unique-decl.rs (100%) rename src/test/{run-pass => ui}/unique/unique-deref.rs (100%) rename src/test/{run-pass => ui}/unique/unique-destructure.rs (100%) rename src/test/{run-pass => ui}/unique/unique-drop-complex.rs (100%) rename src/test/{run-pass => ui}/unique/unique-ffi-symbols.rs (100%) rename src/test/{run-pass => ui}/unique/unique-fn-arg-move.rs (100%) rename src/test/{run-pass => ui}/unique/unique-fn-arg-mut.rs (100%) rename src/test/{run-pass => ui}/unique/unique-fn-arg.rs (100%) rename src/test/{run-pass => ui}/unique/unique-fn-ret.rs (100%) rename src/test/{run-pass => ui}/unique/unique-generic-assign.rs (100%) rename src/test/{run-pass => ui}/unique/unique-in-tag.rs (100%) rename src/test/{run-pass => ui}/unique/unique-in-vec-copy.rs (100%) rename src/test/{run-pass => ui}/unique/unique-in-vec.rs (100%) rename src/test/{run-pass => ui}/unique/unique-init.rs (100%) rename src/test/{run-pass => ui}/unique/unique-kinds.rs (100%) rename src/test/{run-pass => ui}/unique/unique-log.rs (100%) rename src/test/{run-pass => ui}/unique/unique-match-discrim.rs (100%) rename src/test/{run-pass => ui}/unique/unique-move-drop.rs (100%) rename src/test/{run-pass => ui}/unique/unique-move-temp.rs (100%) rename src/test/{run-pass => ui}/unique/unique-move.rs (100%) rename src/test/{run-pass => ui}/unique/unique-mutable.rs (100%) rename src/test/{run-pass => ui}/unique/unique-object-move.rs (100%) rename src/test/{run-pass => ui}/unique/unique-pat-2.rs (100%) rename src/test/{run-pass => ui}/unique/unique-pat-3.rs (100%) rename src/test/{run-pass => ui}/unique/unique-pat.rs (100%) rename src/test/{run-pass => ui}/unique/unique-rec.rs (100%) rename src/test/{run-pass => ui}/unique/unique-send-2.rs (100%) rename src/test/{run-pass => ui}/unique/unique-send.rs (100%) rename src/test/{run-pass => ui}/unique/unique-swap.rs (100%) rename src/test/{run-pass => ui}/unit.rs (95%) rename src/test/{run-pass => ui}/unnamed_argument_mode.rs (94%) rename src/test/{run-pass => ui}/unreachable-code-1.rs (95%) rename src/test/{run-pass => ui}/unreachable-code.rs (96%) rename src/test/{run-pass => ui}/unsafe-coercion.rs (95%) rename src/test/{run-pass => ui}/unsafe-fn-called-from-unsafe-blk.rs (93%) rename src/test/{run-pass => ui}/unsafe-fn-called-from-unsafe-fn.rs (93%) rename src/test/{run-pass => ui}/unsafe-pointer-assignability.rs (88%) rename src/test/{run-pass => ui}/unsized-locals/autoderef.rs (98%) rename src/test/{run-pass => ui}/unsized-locals/box-fnonce.rs (92%) rename src/test/{run-pass/unsized-locals/by-value-trait-object-safety.rs => ui/unsized-locals/by-value-trait-object-safety-rpass.rs} (96%) rename src/test/{run-pass => ui}/unsized-locals/by-value-trait-object-safety-withdefault.rs (96%) rename src/test/{run-pass => ui}/unsized-locals/reference-unsized-locals.rs (100%) rename src/test/{run-pass => ui}/unsized-locals/simple-unsized-locals.rs (100%) rename src/test/{run-pass/unsized-locals/unsized-exprs.rs => ui/unsized-locals/unsized-exprs-rpass.rs} (100%) rename src/test/{run-pass => ui}/unsized-locals/unsized-parameters.rs (100%) rename src/test/{run-pass => ui}/unsized-tuple-impls.rs (97%) rename src/test/{run-pass => ui}/unsized.rs (97%) rename src/test/{run-pass => ui}/unsized2.rs (99%) rename src/test/{run-pass/unsized3.rs => ui/unsized3-rpass.rs} (99%) rename src/test/{run-pass => ui}/unused-move-capture.rs (92%) rename src/test/{run-pass => ui}/unused-move.rs (95%) rename src/test/{run-pass => ui}/unwind-resource.rs (98%) rename src/test/{run-pass => ui}/unwind-unique.rs (94%) rename src/test/{run-pass => ui}/use-crate-name-alias.rs (88%) rename src/test/{run-pass => ui}/use-import-export.rs (93%) rename src/test/{run-pass => ui}/use-keyword-2.rs (95%) rename src/test/{run-pass => ui}/use-mod.rs (97%) rename src/test/{run-pass => ui}/use-nested-groups.rs (97%) rename src/test/{run-pass => ui}/use.rs (96%) rename src/test/{run-pass => ui}/use_inline_dtor.rs (92%) delete mode 100644 src/test/ui/user-defined-macro-rules.stderr rename src/test/{run-pass => ui}/using-target-feature-unstable.rs (93%) rename src/test/{run-pass => ui}/utf8-bom.rs (88%) rename src/test/{run-pass => ui}/utf8.rs (99%) rename src/test/{run-pass => ui}/utf8_chars.rs (98%) rename src/test/{run-pass/utf8_idents.rs => ui/utf8_idents-rpass.rs} (98%) rename src/test/{run-pass => ui}/variadic-ffi.rs (99%) rename src/test/{run-pass => ui}/variance-intersection-of-ref-and-opt-ref.rs (98%) rename src/test/{run-pass => ui}/variance-iterators-in-libcore.rs (91%) rename src/test/{run-pass => ui}/volatile-fat-ptr.rs (95%) rename src/test/{run-pass => ui}/wait-forked-but-failed-child.rs (97%) rename src/test/{run-pass => ui}/warn-ctypes-inhibit.rs (94%) rename src/test/{run-pass => ui}/weak-lang-item.rs (95%) rename src/test/{run-pass => ui}/weak-new-uninhabited-issue-48493.rs (88%) rename src/test/{run-pass => ui}/weird-exit-code.rs (98%) rename src/test/{run-pass => ui}/weird-exprs.rs (99%) rename src/test/{run-pass => ui}/wf-bound-region-in-object-type.rs (97%) rename src/test/{run-pass => ui}/where-clauses/auxiliary/where_clauses_xc.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clause-bounds-inconsistency.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clause-early-bound-lifetimes.rs (100%) rename src/test/{run-pass/where-clauses/where-clause-method-substituion.rs => ui/where-clauses/where-clause-method-substituion-rpass.rs} (100%) rename src/test/{run-pass => ui}/where-clauses/where-clause-region-outlives.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clauses-cross-crate.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clauses-lifetimes.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clauses-method.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clauses-unboxed-closures.rs (100%) rename src/test/{run-pass => ui}/where-clauses/where-clauses.rs (100%) rename src/test/{run-pass => ui}/wrapping-int-api.rs (99%) rename src/test/{run-pass => ui}/write-fmt-errors.rs (99%) rename src/test/{run-pass => ui}/writealias.rs (96%) rename src/test/{run-pass => ui}/wrong-hashset-issue-42918.rs (97%) rename src/test/{run-pass => ui}/x86stdcall.rs (95%) rename src/test/{run-pass => ui}/x86stdcall2.rs (98%) rename src/test/{run-pass => ui}/yield.rs (96%) rename src/test/{run-pass => ui}/yield1.rs (95%) rename src/test/{run-pass => ui}/yield2.rs (91%) rename src/test/{run-pass => ui}/z-crate-attr.rs (96%) rename src/test/{run-pass => ui}/zero-sized/zero-size-type-destructors.rs (100%) rename src/test/{run-pass => ui}/zero-sized/zero-sized-binary-heap-push.rs (100%) rename src/test/{run-pass => ui}/zero-sized/zero-sized-btreemap-insert.rs (100%) rename src/test/{run-pass => ui}/zero-sized/zero-sized-linkedlist-push.rs (100%) rename src/test/{run-pass => ui}/zero-sized/zero-sized-tuple-struct.rs (100%) rename src/test/{run-pass => ui}/zero-sized/zero-sized-vec-deque-push.rs (100%) rename src/test/{run-pass => ui}/zero-sized/zero-sized-vec-push.rs (100%) create mode 100644 src/tools/compiletest/src/header/tests.rs create mode 100644 src/tools/compiletest/src/runtest/tests.rs create mode 100644 src/tools/compiletest/src/tests.rs create mode 100644 src/tools/compiletest/src/util/tests.rs create mode 100644 src/tools/tidy/src/edition.rs create mode 100644 src/tools/tidy/src/features/tests.rs create mode 100644 src/tools/tidy/src/features/version/tests.rs delete mode 100644 src/tools/tidy/src/libcoretest.rs create mode 100644 src/tools/tidy/src/unit_tests.rs create mode 100644 vendor/annotate-snippets/CHANGELOG.md delete mode 100644 vendor/autocfg/.cargo-checksum.json delete mode 100644 vendor/autocfg/README.md delete mode 100644 vendor/autocfg/examples/integers.rs delete mode 100644 vendor/autocfg/examples/paths.rs delete mode 100644 vendor/autocfg/examples/traits.rs delete mode 100644 vendor/autocfg/examples/versions.rs delete mode 100644 vendor/autocfg/src/error.rs delete mode 100644 vendor/autocfg/src/lib.rs delete mode 100644 vendor/autocfg/src/tests.rs delete mode 100644 vendor/autocfg/src/version.rs delete mode 100644 vendor/backtrace/build.rs create mode 100755 vendor/backtrace/ci/android-sdk.sh create mode 100644 vendor/backtrace/ci/runtest-android.rs create mode 100644 vendor/bitflags/build.rs create mode 100644 vendor/c2-chacha/.cargo-checksum.json create mode 100644 vendor/c2-chacha/Cargo.toml create mode 100644 vendor/c2-chacha/LICENSE-APACHE create mode 100644 vendor/c2-chacha/LICENSE-MIT create mode 100644 vendor/c2-chacha/README.md create mode 100644 vendor/c2-chacha/benches/chacha20.rs create mode 100644 vendor/c2-chacha/benches/machine.rs create mode 100644 vendor/c2-chacha/src/guts.rs create mode 100644 vendor/c2-chacha/src/lib.rs create mode 100644 vendor/c2-chacha/src/rustcrypto_impl.rs create mode 100644 vendor/compiler_builtins/Cargo.lock create mode 100644 vendor/crossbeam-deque/.cargo-checksum.json create mode 100644 vendor/crossbeam-deque/CHANGELOG.md create mode 100644 vendor/crossbeam-deque/Cargo.toml rename vendor/{autocfg => crossbeam-deque}/LICENSE-APACHE (100%) rename vendor/{autocfg => crossbeam-deque}/LICENSE-MIT (97%) create mode 100644 vendor/crossbeam-deque/README.md create mode 100644 vendor/crossbeam-deque/src/lib.rs create mode 100644 vendor/crossbeam-deque/tests/fifo.rs create mode 100644 vendor/crossbeam-deque/tests/lifo.rs create mode 100644 vendor/crossbeam-epoch/.cargo-checksum.json create mode 100644 vendor/crossbeam-epoch/CHANGELOG.md create mode 100644 vendor/crossbeam-epoch/Cargo.lock create mode 100644 vendor/crossbeam-epoch/Cargo.toml rename vendor/{backtrace-sys => crossbeam-epoch}/LICENSE-APACHE (100%) create mode 100644 vendor/crossbeam-epoch/LICENSE-MIT create mode 100644 vendor/crossbeam-epoch/README.md create mode 100644 vendor/crossbeam-epoch/benches/defer.rs create mode 100644 vendor/crossbeam-epoch/benches/flush.rs create mode 100644 vendor/crossbeam-epoch/benches/pin.rs create mode 100644 vendor/crossbeam-epoch/examples/sanitize.rs create mode 100644 vendor/crossbeam-epoch/examples/treiber_stack.rs create mode 100644 vendor/crossbeam-epoch/src/atomic.rs create mode 100644 vendor/crossbeam-epoch/src/collector.rs create mode 100644 vendor/crossbeam-epoch/src/default.rs create mode 100644 vendor/crossbeam-epoch/src/deferred.rs create mode 100644 vendor/crossbeam-epoch/src/epoch.rs create mode 100644 vendor/crossbeam-epoch/src/guard.rs create mode 100644 vendor/crossbeam-epoch/src/internal.rs create mode 100644 vendor/crossbeam-epoch/src/lib.rs create mode 100644 vendor/crossbeam-epoch/src/sync/list.rs create mode 100644 vendor/crossbeam-epoch/src/sync/mod.rs create mode 100644 vendor/crossbeam-epoch/src/sync/queue.rs create mode 100644 vendor/crossbeam-queue/.cargo-checksum.json create mode 100644 vendor/crossbeam-queue/CHANGELOG.md rename vendor/{fuchsia-cprng => crossbeam-queue}/Cargo.toml (50%) rename vendor/{idna => crossbeam-queue}/LICENSE-APACHE (100%) rename vendor/{backtrace-sys => crossbeam-queue}/LICENSE-MIT (96%) create mode 100644 vendor/crossbeam-queue/LICENSE-THIRD-PARTY create mode 100644 vendor/crossbeam-queue/README.md create mode 100644 vendor/crossbeam-queue/src/array_queue.rs create mode 100644 vendor/crossbeam-queue/src/err.rs create mode 100644 vendor/crossbeam-queue/src/lib.rs create mode 100644 vendor/crossbeam-queue/src/seg_queue.rs create mode 100644 vendor/crossbeam-queue/tests/array_queue.rs create mode 100644 vendor/crossbeam-queue/tests/seg_queue.rs create mode 100644 vendor/crossbeam-utils/.cargo-checksum.json create mode 100644 vendor/crossbeam-utils/CHANGELOG.md create mode 100644 vendor/crossbeam-utils/Cargo.toml rename vendor/{percent-encoding => crossbeam-utils}/LICENSE-APACHE (100%) create mode 100644 vendor/crossbeam-utils/LICENSE-MIT create mode 100644 vendor/crossbeam-utils/README.md create mode 100644 vendor/crossbeam-utils/benches/atomic_cell.rs create mode 100644 vendor/crossbeam-utils/src/atomic/atomic_cell.rs create mode 100644 vendor/crossbeam-utils/src/atomic/consume.rs create mode 100644 vendor/crossbeam-utils/src/atomic/mod.rs create mode 100644 vendor/crossbeam-utils/src/backoff.rs create mode 100644 vendor/crossbeam-utils/src/cache_padded.rs create mode 100644 vendor/crossbeam-utils/src/lib.rs create mode 100644 vendor/crossbeam-utils/src/sync/mod.rs create mode 100644 vendor/crossbeam-utils/src/sync/parker.rs create mode 100644 vendor/crossbeam-utils/src/sync/sharded_lock.rs create mode 100644 vendor/crossbeam-utils/src/sync/wait_group.rs create mode 100644 vendor/crossbeam-utils/src/thread.rs create mode 100644 vendor/crossbeam-utils/tests/atomic_cell.rs create mode 100644 vendor/crossbeam-utils/tests/cache_padded.rs create mode 100644 vendor/crossbeam-utils/tests/parker.rs create mode 100644 vendor/crossbeam-utils/tests/sharded_lock.rs create mode 100644 vendor/crossbeam-utils/tests/thread.rs create mode 100644 vendor/crossbeam-utils/tests/wait_group.rs delete mode 100644 vendor/fuchsia-cprng/.cargo-checksum.json delete mode 100644 vendor/fuchsia-cprng/AUTHORS delete mode 100644 vendor/fuchsia-cprng/LICENSE delete mode 100644 vendor/fuchsia-cprng/PATENTS delete mode 100644 vendor/fuchsia-cprng/src/lib.rs create mode 100644 vendor/getrandom/.cargo-checksum.json create mode 100644 vendor/getrandom/CHANGELOG.md create mode 100644 vendor/getrandom/Cargo.toml create mode 100644 vendor/getrandom/LICENSE-APACHE rename vendor/{rand-0.4.6 => getrandom}/LICENSE-MIT (95%) create mode 100644 vendor/getrandom/README.md create mode 100644 vendor/getrandom/benches/mod.rs create mode 100644 vendor/getrandom/src/cloudabi.rs create mode 100644 vendor/getrandom/src/dummy.rs create mode 100644 vendor/getrandom/src/error.rs create mode 100644 vendor/getrandom/src/error_impls.rs create mode 100644 vendor/getrandom/src/freebsd.rs create mode 100644 vendor/getrandom/src/fuchsia.rs create mode 100644 vendor/getrandom/src/ios.rs create mode 100644 vendor/getrandom/src/lib.rs create mode 100644 vendor/getrandom/src/linux_android.rs create mode 100644 vendor/getrandom/src/macos.rs create mode 100644 vendor/getrandom/src/openbsd.rs create mode 100644 vendor/getrandom/src/rdrand.rs create mode 100644 vendor/getrandom/src/solaris_illumos.rs create mode 100644 vendor/getrandom/src/use_file.rs create mode 100644 vendor/getrandom/src/util.rs create mode 100644 vendor/getrandom/src/util_libc.rs create mode 100644 vendor/getrandom/src/wasi.rs create mode 100644 vendor/getrandom/src/wasm32_bindgen.rs create mode 100644 vendor/getrandom/src/wasm32_stdweb.rs create mode 100644 vendor/getrandom/src/windows.rs create mode 100644 vendor/getrandom/tests/mod.rs create mode 100644 vendor/handlebars/Cargo.lock create mode 100644 vendor/handlebars/tests/block_context.rs create mode 100644 vendor/hashbrown-0.4.0/.cargo-checksum.json create mode 100644 vendor/hashbrown-0.4.0/CHANGELOG.md create mode 100644 vendor/hashbrown-0.4.0/Cargo.toml rename vendor/{rand-0.4.6 => hashbrown-0.4.0}/LICENSE-APACHE (100%) create mode 100644 vendor/hashbrown-0.4.0/LICENSE-MIT create mode 100644 vendor/hashbrown-0.4.0/README.md create mode 100644 vendor/hashbrown-0.4.0/benches/bench.rs create mode 100644 vendor/hashbrown-0.4.0/clippy.toml create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/mod.rs create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/rayon/helpers.rs create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/rayon/map.rs create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/rayon/mod.rs create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/rayon/raw.rs create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/rayon/set.rs create mode 100644 vendor/hashbrown-0.4.0/src/external_trait_impls/serde.rs create mode 100644 vendor/hashbrown-0.4.0/src/fx.rs create mode 100644 vendor/hashbrown-0.4.0/src/lib.rs create mode 100644 vendor/hashbrown-0.4.0/src/macros.rs create mode 100644 vendor/hashbrown-0.4.0/src/map.rs create mode 100644 vendor/hashbrown-0.4.0/src/raw/bitmask.rs create mode 100644 vendor/hashbrown-0.4.0/src/raw/generic.rs create mode 100644 vendor/hashbrown-0.4.0/src/raw/mod.rs create mode 100644 vendor/hashbrown-0.4.0/src/raw/sse2.rs create mode 100644 vendor/hashbrown-0.4.0/src/rustc_entry.rs create mode 100644 vendor/hashbrown-0.4.0/src/scopeguard.rs create mode 100644 vendor/hashbrown-0.4.0/src/set.rs create mode 100644 vendor/hashbrown-0.4.0/tests/hasher.rs create mode 100644 vendor/hashbrown-0.4.0/tests/rayon.rs create mode 100644 vendor/hashbrown-0.4.0/tests/serde.rs create mode 100644 vendor/hashbrown-0.4.0/tests/set.rs rename vendor/{idna => idna-0.1.5}/.cargo-checksum.json (100%) rename vendor/{idna => idna-0.1.5}/Cargo.toml (100%) rename vendor/{url => idna-0.1.5}/LICENSE-APACHE (100%) rename vendor/{idna => idna-0.1.5}/LICENSE-MIT (100%) rename vendor/{idna => idna-0.1.5}/src/IdnaMappingTable.txt (100%) rename vendor/{idna => idna-0.1.5}/src/lib.rs (100%) rename vendor/{idna => idna-0.1.5}/src/make_uts46_mapping_table.py (100%) rename vendor/{idna => idna-0.1.5}/src/punycode.rs (100%) rename vendor/{idna => idna-0.1.5}/src/uts46.rs (100%) rename vendor/{idna => idna-0.1.5}/src/uts46_mapping_table.rs (100%) rename vendor/{idna => idna-0.1.5}/tests/IdnaTest.txt (100%) rename vendor/{idna => idna-0.1.5}/tests/punycode.rs (100%) rename vendor/{idna => idna-0.1.5}/tests/punycode_tests.json (100%) rename vendor/{idna => idna-0.1.5}/tests/tests.rs (100%) rename vendor/{idna => idna-0.1.5}/tests/unit.rs (100%) rename vendor/{idna => idna-0.1.5}/tests/uts46.rs (100%) create mode 100644 vendor/libc/src/fixed_width_ints.rs delete mode 100644 vendor/libc/src/redox/align.rs delete mode 100644 vendor/libc/src/redox/mod.rs delete mode 100644 vendor/libc/src/redox/net.rs delete mode 100644 vendor/libc/src/redox/no_align.rs create mode 100644 vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs create mode 100644 vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs create mode 100644 vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/x86_64.rs create mode 100644 vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs create mode 100644 vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs rename vendor/libc/src/unix/bsd/netbsdlike/{openbsdlike => }/openbsd/aarch64.rs (100%) rename vendor/libc/src/unix/bsd/netbsdlike/{openbsdlike => openbsd}/mod.rs (58%) rename vendor/libc/src/unix/bsd/netbsdlike/{openbsdlike => }/openbsd/x86.rs (100%) rename vendor/libc/src/unix/bsd/netbsdlike/{openbsdlike => }/openbsd/x86_64.rs (100%) delete mode 100644 vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs delete mode 100644 vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/x86.rs delete mode 100644 vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/x86_64.rs delete mode 100644 vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs rename vendor/libc/src/unix/{notbsd => linux_like}/android/b32/arm.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/android/b32/mod.rs (80%) rename vendor/libc/src/unix/{notbsd => linux_like}/android/b32/x86.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/android/b64/aarch64.rs (97%) rename vendor/libc/src/unix/{notbsd => linux_like}/android/b64/mod.rs (90%) rename vendor/libc/src/unix/{notbsd => linux_like}/android/b64/x86_64.rs (97%) rename vendor/libc/src/unix/{notbsd => linux_like}/android/mod.rs (91%) rename vendor/libc/src/unix/{notbsd => linux_like}/emscripten/align.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/emscripten/mod.rs (94%) rename vendor/libc/src/unix/{notbsd => linux_like}/emscripten/no_align.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/align.rs (94%) rename vendor/libc/src/unix/{notbsd/linux/mips => linux_like/linux/gnu}/align.rs (100%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b32/arm.rs (71%) rename vendor/libc/src/unix/{notbsd/linux/mips/mips32.rs => linux_like/linux/gnu/b32/mips.rs} (62%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b32/mod.rs (56%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b32/powerpc.rs (71%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b32/x86.rs (78%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b64/aarch64.rs (88%) rename vendor/libc/src/unix/{notbsd/linux/mips => linux_like/linux/gnu/b64}/mips64.rs (59%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b64/mod.rs (88%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b64/powerpc64.rs (89%) rename vendor/libc/src/unix/{notbsd/linux/s390x/mod.rs => linux_like/linux/gnu/b64/s390x.rs} (70%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/b64/sparc64.rs (89%) rename vendor/libc/src/unix/{notbsd/linux/other/b64/x86_64.rs => linux_like/linux/gnu/b64/x86_64/mod.rs} (85%) rename vendor/libc/src/unix/{notbsd/linux/other/b64 => linux_like/linux/gnu/b64/x86_64}/not_x32.rs (99%) rename vendor/libc/src/unix/{notbsd/linux/other/b64 => linux_like/linux/gnu/b64/x86_64}/x32.rs (99%) rename vendor/libc/src/unix/{notbsd/linux/other => linux_like/linux/gnu}/mod.rs (81%) rename vendor/libc/src/unix/{notbsd/linux/mips => linux_like/linux/gnu}/no_align.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/mod.rs (86%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b32/arm.rs (98%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b32/mips.rs (97%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b32/mod.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b32/powerpc.rs (98%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b32/x86.rs (98%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b64/aarch64.rs (98%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b64/mod.rs (97%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b64/powerpc64.rs (99%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/b64/x86_64.rs (99%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/musl/mod.rs (82%) rename vendor/libc/src/unix/{notbsd => linux_like}/linux/no_align.rs (100%) rename vendor/libc/src/unix/{notbsd => linux_like}/mod.rs (96%) delete mode 100644 vendor/libc/src/unix/notbsd/linux/mips/mod.rs delete mode 100644 vendor/libc/src/unix/notbsd/linux/other/align.rs delete mode 100644 vendor/libc/src/unix/notbsd/linux/other/no_align.rs delete mode 100644 vendor/libc/src/unix/notbsd/linux/s390x/align.rs delete mode 100644 vendor/libc/src/unix/notbsd/linux/s390x/no_align.rs create mode 100644 vendor/libc/src/unix/redox/mod.rs create mode 100644 vendor/lzma-sys/config.h create mode 100644 vendor/mdbook/tests/dummy_book/src/first/unicode.md create mode 100644 vendor/memoffset-0.2.1/.cargo-checksum.json rename vendor/{autocfg => memoffset-0.2.1}/Cargo.toml (60%) create mode 100644 vendor/memoffset-0.2.1/LICENSE create mode 100644 vendor/memoffset-0.2.1/README.md create mode 100644 vendor/memoffset-0.2.1/src/lib.rs create mode 100644 vendor/memoffset-0.2.1/src/offset_of.rs create mode 100644 vendor/memoffset-0.2.1/src/span_of.rs create mode 100644 vendor/memoffset/build.rs create mode 100644 vendor/minifier/Cargo.lock create mode 100644 vendor/minifier/tests/files/main.js create mode 100644 vendor/minifier/tests/files/minified_main.js create mode 100644 vendor/minifier/tests/js_minify.rs rename vendor/{percent-encoding => percent-encoding-1.0.1}/.cargo-checksum.json (100%) rename vendor/{percent-encoding => percent-encoding-1.0.1}/Cargo.toml (100%) create mode 100644 vendor/percent-encoding-1.0.1/LICENSE-APACHE rename vendor/{percent-encoding => percent-encoding-1.0.1}/LICENSE-MIT (100%) rename vendor/{percent-encoding => percent-encoding-1.0.1}/lib.rs (100%) create mode 100644 vendor/polonius-engine/src/output/liveness.rs create mode 100644 vendor/ppv-lite86/.cargo-checksum.json create mode 100644 vendor/ppv-lite86/Cargo.toml create mode 100644 vendor/ppv-lite86/LICENSE-APACHE create mode 100644 vendor/ppv-lite86/LICENSE-MIT create mode 100644 vendor/ppv-lite86/src/generic.rs create mode 100644 vendor/ppv-lite86/src/lib.rs create mode 100644 vendor/ppv-lite86/src/soft.rs create mode 100644 vendor/ppv-lite86/src/types.rs create mode 100644 vendor/ppv-lite86/src/x86_64/mod.rs create mode 100644 vendor/ppv-lite86/src/x86_64/sse2.rs delete mode 100644 vendor/rand-0.4.6/.cargo-checksum.json delete mode 100644 vendor/rand-0.4.6/CHANGELOG.md delete mode 100644 vendor/rand-0.4.6/Cargo.toml delete mode 100644 vendor/rand-0.4.6/README.md delete mode 100644 vendor/rand-0.4.6/appveyor.yml delete mode 100644 vendor/rand-0.4.6/benches/bench.rs delete mode 100644 vendor/rand-0.4.6/benches/distributions/exponential.rs delete mode 100644 vendor/rand-0.4.6/benches/distributions/gamma.rs delete mode 100644 vendor/rand-0.4.6/benches/distributions/mod.rs delete mode 100644 vendor/rand-0.4.6/benches/distributions/normal.rs delete mode 100644 vendor/rand-0.4.6/benches/generators.rs delete mode 100644 vendor/rand-0.4.6/benches/misc.rs delete mode 100644 vendor/rand-0.4.6/src/distributions/exponential.rs delete mode 100644 vendor/rand-0.4.6/src/distributions/mod.rs delete mode 100644 vendor/rand-0.4.6/src/distributions/range.rs delete mode 100644 vendor/rand-0.4.6/src/jitter.rs delete mode 100644 vendor/rand-0.4.6/src/lib.rs delete mode 100644 vendor/rand-0.4.6/src/os.rs delete mode 100644 vendor/rand-0.4.6/src/prng/chacha.rs delete mode 100644 vendor/rand-0.4.6/src/prng/isaac.rs delete mode 100644 vendor/rand-0.4.6/src/prng/isaac64.rs delete mode 100644 vendor/rand-0.4.6/src/prng/mod.rs delete mode 100644 vendor/rand-0.4.6/src/prng/xorshift.rs delete mode 100644 vendor/rand-0.4.6/src/rand_impls.rs delete mode 100644 vendor/rand-0.4.6/src/read.rs delete mode 100644 vendor/rand-0.4.6/src/reseeding.rs delete mode 100644 vendor/rand-0.4.6/src/seq.rs delete mode 100755 vendor/rand-0.4.6/utils/ziggurat_tables.py create mode 100644 vendor/rand-0.6.1/.cargo-checksum.json create mode 100644 vendor/rand-0.6.1/CHANGELOG.md create mode 100644 vendor/rand-0.6.1/COPYRIGHT create mode 100644 vendor/rand-0.6.1/Cargo.toml create mode 100644 vendor/rand-0.6.1/LICENSE-APACHE create mode 100644 vendor/rand-0.6.1/LICENSE-MIT create mode 100644 vendor/rand-0.6.1/README.md rename vendor/{rand => rand-0.6.1}/benches/distributions.rs (100%) create mode 100644 vendor/rand-0.6.1/benches/generators.rs create mode 100644 vendor/rand-0.6.1/benches/misc.rs create mode 100644 vendor/rand-0.6.1/benches/seq.rs rename vendor/{rand => rand-0.6.1}/build.rs (100%) create mode 100644 vendor/rand-0.6.1/examples/monte-carlo.rs create mode 100644 vendor/rand-0.6.1/examples/monty-hall.rs rename vendor/{rand => rand-0.6.1}/src/deprecated.rs (100%) create mode 100644 vendor/rand-0.6.1/src/distributions/bernoulli.rs create mode 100644 vendor/rand-0.6.1/src/distributions/binomial.rs create mode 100644 vendor/rand-0.6.1/src/distributions/cauchy.rs create mode 100644 vendor/rand-0.6.1/src/distributions/dirichlet.rs create mode 100644 vendor/rand-0.6.1/src/distributions/exponential.rs create mode 100644 vendor/rand-0.6.1/src/distributions/float.rs rename vendor/{rand-0.4.6 => rand-0.6.1}/src/distributions/gamma.rs (63%) create mode 100644 vendor/rand-0.6.1/src/distributions/integer.rs create mode 100644 vendor/rand-0.6.1/src/distributions/mod.rs rename vendor/{rand-0.4.6 => rand-0.6.1}/src/distributions/normal.rs (52%) create mode 100644 vendor/rand-0.6.1/src/distributions/other.rs create mode 100644 vendor/rand-0.6.1/src/distributions/pareto.rs create mode 100644 vendor/rand-0.6.1/src/distributions/poisson.rs create mode 100644 vendor/rand-0.6.1/src/distributions/triangular.rs create mode 100644 vendor/rand-0.6.1/src/distributions/uniform.rs create mode 100644 vendor/rand-0.6.1/src/distributions/unit_circle.rs create mode 100644 vendor/rand-0.6.1/src/distributions/unit_sphere.rs create mode 100644 vendor/rand-0.6.1/src/distributions/utils.rs create mode 100644 vendor/rand-0.6.1/src/distributions/weibull.rs rename vendor/{rand => rand-0.6.1}/src/distributions/weighted.rs (100%) rename vendor/{rand-0.4.6 => rand-0.6.1}/src/distributions/ziggurat_tables.rs (98%) create mode 100644 vendor/rand-0.6.1/src/lib.rs create mode 100644 vendor/rand-0.6.1/src/prelude.rs rename vendor/{rand => rand-0.6.1}/src/prng/mod.rs (100%) create mode 100644 vendor/rand-0.6.1/src/rngs/adapter/mod.rs create mode 100644 vendor/rand-0.6.1/src/rngs/adapter/read.rs create mode 100644 vendor/rand-0.6.1/src/rngs/adapter/reseeding.rs create mode 100644 vendor/rand-0.6.1/src/rngs/entropy.rs rename vendor/{rand => rand-0.6.1}/src/rngs/jitter.rs (100%) create mode 100644 vendor/rand-0.6.1/src/rngs/mock.rs create mode 100644 vendor/rand-0.6.1/src/rngs/mod.rs create mode 100644 vendor/rand-0.6.1/src/rngs/os.rs create mode 100644 vendor/rand-0.6.1/src/rngs/small.rs create mode 100644 vendor/rand-0.6.1/src/rngs/std.rs create mode 100644 vendor/rand-0.6.1/src/rngs/thread.rs create mode 100644 vendor/rand-0.6.1/src/seq/index.rs create mode 100644 vendor/rand-0.6.1/src/seq/mod.rs rename vendor/{rand => rand-0.6.1}/tests/uniformity.rs (100%) create mode 100644 vendor/rand/rustfmt.toml create mode 100644 vendor/rand/src/distributions/weighted/alias_method.rs create mode 100644 vendor/rand/src/distributions/weighted/mod.rs create mode 100644 vendor/rand_chacha-0.1.0/.cargo-checksum.json create mode 100644 vendor/rand_chacha-0.1.0/CHANGELOG.md create mode 100644 vendor/rand_chacha-0.1.0/COPYRIGHT create mode 100644 vendor/rand_chacha-0.1.0/Cargo.toml create mode 100644 vendor/rand_chacha-0.1.0/LICENSE-APACHE create mode 100644 vendor/rand_chacha-0.1.0/LICENSE-MIT create mode 100644 vendor/rand_chacha-0.1.0/README.md rename vendor/{rand_chacha => rand_chacha-0.1.0}/build.rs (100%) create mode 100644 vendor/rand_chacha-0.1.0/src/chacha.rs create mode 100644 vendor/rand_chacha-0.1.0/src/lib.rs create mode 100644 vendor/rand_core/.cargo-checksum.json create mode 100644 vendor/rand_core/CHANGELOG.md create mode 100644 vendor/rand_core/COPYRIGHT create mode 100644 vendor/rand_core/Cargo.toml create mode 100644 vendor/rand_core/LICENSE-APACHE create mode 100644 vendor/rand_core/LICENSE-MIT create mode 100644 vendor/rand_core/README.md create mode 100644 vendor/rand_core/src/block.rs create mode 100644 vendor/rand_core/src/error.rs create mode 100644 vendor/rand_core/src/impls.rs create mode 100644 vendor/rand_core/src/le.rs create mode 100644 vendor/rand_core/src/lib.rs create mode 100644 vendor/rand_hc-0.1.0/.cargo-checksum.json create mode 100644 vendor/rand_hc-0.1.0/CHANGELOG.md create mode 100644 vendor/rand_hc-0.1.0/COPYRIGHT rename vendor/{rdrand => rand_hc-0.1.0}/Cargo.toml (53%) create mode 100644 vendor/rand_hc-0.1.0/LICENSE-APACHE create mode 100644 vendor/rand_hc-0.1.0/LICENSE-MIT create mode 100644 vendor/rand_hc-0.1.0/README.md create mode 100644 vendor/rand_hc-0.1.0/src/hc128.rs create mode 100644 vendor/rand_hc-0.1.0/src/lib.rs create mode 100644 vendor/rand_xorshift-0.1.0/.cargo-checksum.json create mode 100644 vendor/rand_xorshift-0.1.0/CHANGELOG.md create mode 100644 vendor/rand_xorshift-0.1.0/COPYRIGHT create mode 100644 vendor/rand_xorshift-0.1.0/Cargo.toml create mode 100644 vendor/rand_xorshift-0.1.0/LICENSE-APACHE create mode 100644 vendor/rand_xorshift-0.1.0/LICENSE-MIT create mode 100644 vendor/rand_xorshift-0.1.0/README.md create mode 100644 vendor/rand_xorshift-0.1.0/src/lib.rs rename vendor/{rand_xorshift => rand_xorshift-0.1.0}/src/xorshift.rs (100%) create mode 100644 vendor/rand_xorshift/tests/mod.rs create mode 100644 vendor/rayon-core/src/private.rs create mode 100644 vendor/rayon-core/tests/scoped_threadpool.rs delete mode 100644 vendor/rayon/appveyor.yml delete mode 100644 vendor/rayon/bors.toml delete mode 100755 vendor/rayon/ci/highlander.sh delete mode 100755 vendor/rayon/scripts/analyze.sh rename vendor/rayon/{tests/compile-fail => src/compile_fail}/cannot_collect_filtermap_data.rs (90%) rename vendor/rayon/{tests/compile-fail => src/compile_fail}/cannot_zip_filtered_data.rs (75%) rename vendor/rayon/{tests/compile-fail => src/compile_fail}/cell_par_iter.rs (88%) create mode 100644 vendor/rayon/src/compile_fail/mod.rs create mode 100644 vendor/rayon/src/compile_fail/must_use.rs create mode 100644 vendor/rayon/src/compile_fail/no_send_par_iter.rs rename vendor/rayon/{tests/compile-fail => src/compile_fail}/rc_par_iter.rs (83%) create mode 100644 vendor/rayon/src/iter/panic_fuse.rs create mode 100644 vendor/rayon/src/iter/par_bridge.rs create mode 100644 vendor/rayon/src/iter/try_fold.rs create mode 100644 vendor/rayon/src/iter/try_reduce.rs create mode 100644 vendor/rayon/src/iter/try_reduce_with.rs create mode 100644 vendor/rayon/src/range_inclusive.rs delete mode 100644 vendor/rayon/src/test.rs delete mode 100644 vendor/rayon/tests/compile-fail-unstable/README.md delete mode 100644 vendor/rayon/tests/compile-fail/README.md delete mode 100644 vendor/rayon/tests/compile-fail/must_use.rs delete mode 100644 vendor/rayon/tests/compile-fail/no_send_par_iter.rs delete mode 100644 vendor/rayon/tests/compile-fail/quicksort_race1.rs delete mode 100644 vendor/rayon/tests/compile-fail/quicksort_race2.rs delete mode 100644 vendor/rayon/tests/compile-fail/quicksort_race3.rs delete mode 100644 vendor/rayon/tests/compile-fail/rc_return.rs delete mode 100644 vendor/rayon/tests/compile-fail/rc_upvar.rs delete mode 100644 vendor/rayon/tests/compile-fail/scope_join_bad.rs create mode 100644 vendor/rayon/tests/iter_panic.rs create mode 100644 vendor/rayon/tests/named-threads.rs create mode 100644 vendor/rayon/tests/octillion.rs delete mode 100644 vendor/rayon/tests/run-fail-unstable/README.md delete mode 100644 vendor/rayon/tests/run-fail/README.md delete mode 100644 vendor/rayon/tests/run-fail/iter_panic.rs delete mode 100644 vendor/rayon/tests/run-fail/simple_panic.rs delete mode 100644 vendor/rayon/tests/run-pass-unstable/README.md delete mode 100644 vendor/rayon/tests/run-pass/README.md delete mode 100644 vendor/rayon/tests/run-pass/double_init_fail.rs delete mode 100644 vendor/rayon/tests/run-pass/init_zero_threads.rs delete mode 100644 vendor/rayon/tests/run-pass/named-threads.rs delete mode 100644 vendor/rayon/tests/run-pass/scope_join.rs delete mode 100644 vendor/rayon/tests/run-pass/stack_overflow_crash.rs create mode 100644 vendor/rayon/tests/str.rs delete mode 100644 vendor/rdrand/.cargo-checksum.json delete mode 100644 vendor/rdrand/LICENSE delete mode 100644 vendor/rdrand/README.mkd delete mode 100644 vendor/rdrand/appveyor.yml delete mode 100644 vendor/rdrand/benches/rdrand.rs delete mode 100644 vendor/rdrand/benches/rdseed.rs delete mode 100644 vendor/rdrand/benches/std.rs delete mode 100644 vendor/rdrand/src/changelog.rs delete mode 100644 vendor/rdrand/src/lib.rs create mode 100644 vendor/rustfix/Changelog.md create mode 100644 vendor/ryu/benches/bench.rs rename vendor/ryu/{benchmark/benchmark.rs => examples/upstream_benchmark.rs} (94%) create mode 100644 vendor/scopeguard-0.3.3/.cargo-checksum.json create mode 100644 vendor/scopeguard-0.3.3/Cargo.toml create mode 100644 vendor/scopeguard-0.3.3/LICENSE-APACHE create mode 100644 vendor/scopeguard-0.3.3/LICENSE-MIT create mode 100644 vendor/scopeguard-0.3.3/README.rst create mode 100644 vendor/scopeguard-0.3.3/examples/readme.rs create mode 100644 vendor/scopeguard-0.3.3/src/lib.rs rename vendor/{url => url-1.7.2}/.cargo-checksum.json (100%) rename vendor/{url => url-1.7.2}/Cargo.toml (100%) create mode 100644 vendor/url-1.7.2/LICENSE-APACHE rename vendor/{url => url-1.7.2}/LICENSE-MIT (100%) rename vendor/{url => url-1.7.2}/README.md (100%) rename vendor/{url => url-1.7.2}/UPGRADING.md (100%) rename vendor/{url => url-1.7.2}/appveyor.yml (100%) rename vendor/{url => url-1.7.2}/benches/parse_url.rs (100%) rename vendor/{url => url-1.7.2}/docs/404.html (100%) rename vendor/{url => url-1.7.2}/docs/index.html (100%) rename vendor/{url => url-1.7.2}/src/encoding.rs (100%) rename vendor/{url => url-1.7.2}/src/form_urlencoded.rs (100%) rename vendor/{url => url-1.7.2}/src/host.rs (100%) rename vendor/{url => url-1.7.2}/src/lib.rs (100%) rename vendor/{url => url-1.7.2}/src/origin.rs (100%) rename vendor/{url => url-1.7.2}/src/parser.rs (100%) rename vendor/{url => url-1.7.2}/src/path_segments.rs (100%) rename vendor/{url => url-1.7.2}/src/quirks.rs (100%) rename vendor/{url => url-1.7.2}/src/slicing.rs (100%) rename vendor/{url => url-1.7.2}/tests/data.rs (100%) rename vendor/{url => url-1.7.2}/tests/setters_tests.json (100%) rename vendor/{url => url-1.7.2}/tests/unit.rs (100%) rename vendor/{url => url-1.7.2}/tests/urltestdata.json (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db37fa0caf..4daaa986a2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -179,7 +179,6 @@ Speaking of tests, Rust has a comprehensive test suite. More information about it can be found [here][rctd]. ### External Dependencies -[external-dependencies]: #external-dependencies Currently building Rust will also build the following external projects: @@ -209,7 +208,6 @@ Breakage is not allowed in the beta and stable channels, and must be addressed before the PR is merged. #### Breaking Tools Built With The Compiler -[breaking-tools-built-with-the-compiler]: #breaking-tools-built-with-the-compiler Rust's build system builds a number of tools that make use of the internals of the compiler. This includes @@ -242,7 +240,7 @@ Here are those same steps in detail: `config.toml.example` in the root directory of the Rust repository. Set `submodules = false` in the `[build]` section. This will prevent `x.py` from resetting to the original branch after you make your changes. If you - need to [update any submodules to their latest versions][updating-submodules], + need to [update any submodules to their latest versions](#updating-submodules), see the section of this file about that for more information. 2. (optional) Run `./x.py test src/tools/rustfmt` (substituting the submodule that broke for `rustfmt`). Fix any errors in the submodule (and possibly others). @@ -256,7 +254,6 @@ Here are those same steps in detail: 8. (optional) Send a PR to rust-lang/rust updating the submodule. #### Updating submodules -[updating-submodules]: #updating-submodules These instructions are specific to updating `rustfmt`, however they may apply to the other submodules as well. Please help by improving these instructions @@ -310,7 +307,6 @@ This should change the version listed in `Cargo.lock` to the new version you upd the submodule to. Running `./x.py build` should work now. ## Writing Documentation -[writing-documentation]: #writing-documentation Documentation improvements are very welcome. The source of `doc.rust-lang.org` is located in `src/doc` in the tree, and standard API documentation is generated @@ -337,7 +333,6 @@ tracker in that repo is also a great way to find things that need doing. There are issues for beginners and advanced compiler devs alike! ## Issue Triage -[issue-triage]: #issue-triage Sometimes, an issue will stay open, even though the bug has been fixed. And sometimes, the original bug may go stale because something has changed in the @@ -405,7 +400,6 @@ If you're looking for somewhere to start, check out the [E-easy][eeasy] tag. [rfcbot]: https://github.com/anp/rfcbot-rs/ ## Out-of-tree Contributions -[out-of-tree-contributions]: #out-of-tree-contributions There are a number of other ways to contribute to Rust that don't deal with this repository. @@ -425,7 +419,6 @@ valuable! [community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library ## Helpful Links and Information -[helpful-info]: #helpful-info For people new to Rust, and just starting to contribute, or even for more seasoned developers, some useful places to look for information diff --git a/Cargo.lock b/Cargo.lock index 98dd10955d..ab6731e4d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,14 +5,6 @@ name = "adler32" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "aho-corasick" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aho-corasick" version = "0.7.3" @@ -25,28 +17,15 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ammonia" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "html5ever 0.22.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ammonia" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "html5ever 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -59,7 +38,7 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -113,49 +92,46 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "autocfg" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "backtrace" -version = "0.3.29" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] [[package]] name = "backtrace-sys" -version = "0.1.27" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] [[package]] -name = "bitflags" -version = "0.9.1" +name = "base64" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "bitflags" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -186,12 +162,12 @@ dependencies = [ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -204,11 +180,6 @@ dependencies = [ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bufstream" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "build-manifest" version = "0.1.0" @@ -250,6 +221,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -258,18 +230,25 @@ name = "bytesize" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargo" -version = "0.38.0" +version = "0.39.0" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cargo-test-macro 0.1.0", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crates-io 0.26.0", + "crates-io 0.27.0", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -280,32 +259,34 @@ dependencies = [ "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "git2-curl 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "git2-curl 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", - "rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "strip-ansi-escapes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -313,8 +294,7 @@ dependencies = [ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -322,22 +302,6 @@ dependencies = [ [[package]] name = "cargo-test-macro" version = "0.1.0" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cargo_metadata" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "cargo_metadata" @@ -348,7 +312,7 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -365,7 +329,7 @@ name = "cfg-if" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -403,7 +367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -441,7 +405,7 @@ dependencies = [ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -457,7 +421,7 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -489,12 +453,12 @@ name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "compiler_builtins" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -509,13 +473,13 @@ dependencies = [ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -528,14 +492,14 @@ dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "tester 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -550,7 +514,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "core" version = "0.0.0" dependencies = [ - "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -559,7 +523,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -569,15 +533,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crates-io" -version = "0.26.0" +version = "0.27.0" dependencies = [ "curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -619,7 +584,7 @@ name = "crossbeam-deque" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -639,15 +604,23 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-queue" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -685,7 +658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -699,7 +672,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -794,12 +767,11 @@ dependencies = [ [[package]] name = "dirs" -version = "1.0.5" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -808,7 +780,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -818,11 +790,16 @@ name = "dlmalloc" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] +[[package]] +name = "dtoa" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "either" version = "1.5.0" @@ -837,7 +814,7 @@ dependencies = [ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "strum_macros 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -850,6 +827,14 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "encoding_rs" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.5.13" @@ -858,7 +843,6 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -874,20 +858,12 @@ dependencies = [ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "error-chain" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "error-chain" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -902,7 +878,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -928,7 +904,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -943,7 +919,7 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -979,7 +955,7 @@ name = "fortanix-sgx-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -988,7 +964,7 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1015,7 +991,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1035,9 +1011,18 @@ dependencies = [ [[package]] name = "futures" -version = "0.1.21" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "futures-cpupool" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fwdansi" version = "1.0.1" @@ -1063,29 +1048,38 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "getrandom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "git2" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "git2-curl" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1110,25 +1104,28 @@ name = "graphviz" version = "0.0.0" [[package]] -name = "handlebars" -version = "0.32.4" +name = "h2" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "handlebars" -version = "1.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1136,7 +1133,7 @@ dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1144,11 +1141,19 @@ name = "hashbrown" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-alloc 1.0.0", "rustc-std-workspace-core 1.0.0", ] +[[package]] +name = "hashbrown" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "heck" version = "0.3.0" @@ -1171,19 +1176,6 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "html5ever" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "markup5ever 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "html5ever" version = "0.23.0" @@ -1207,6 +1199,22 @@ dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "http-body" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "httparse" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "humantime" version = "1.2.0" @@ -1215,6 +1223,47 @@ dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper" +version = "0.12.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hyper-tls" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.31 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1230,6 +1279,16 @@ dependencies = [ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "if_chain" version = "1.0.0" @@ -1272,10 +1331,12 @@ name = "installer" version = "0.0.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1287,7 +1348,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1324,17 +1385,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jobserver" -version = "0.1.13" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1347,11 +1408,11 @@ name = "jsonrpc-core" version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1380,19 +1441,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.54" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-std-workspace-core 1.0.0", ] +[[package]] +name = "libflate" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libgit2-sys" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1405,7 +1478,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1414,7 +1487,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1427,7 +1500,7 @@ version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1467,7 +1540,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1476,24 +1549,23 @@ name = "lsp-types" version = "0.57.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lzma-sys" -version = "0.1.10" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1512,32 +1584,17 @@ name = "maplit" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "markup5ever" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "markup5ever" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1550,58 +1607,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mdbook" -version = "0.1.7" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ammonia 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ammonia 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "mdbook" +name = "mdbook-linkcheck" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ammonia 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mdbook 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1624,7 +1675,7 @@ name = "memmap" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1633,9 +1684,36 @@ name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memoffset" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mime" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mime_guess" +version = "2.0.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "minifier" -version = "0.0.30" +version = "0.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1647,7 +1725,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1665,7 +1743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1679,7 +1757,7 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1704,7 +1782,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1748,13 +1826,30 @@ dependencies = [ "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "native-tls" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1797,7 +1892,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1818,11 +1913,11 @@ name = "openssl" version = "0.10.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1833,7 +1928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-src" -version = "111.1.0+1.1.1a" +version = "111.3.0+1.1.1c" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1845,8 +1940,8 @@ version = "0.9.43" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-src 111.3.0+1.1.1c (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1882,9 +1977,9 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1893,9 +1988,9 @@ version = "0.0.0" dependencies = [ "alloc 0.0.0", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "unwind 0.0.0", ] @@ -1913,7 +2008,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1926,8 +2021,8 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "pest" -version = "1.0.6" +name = "percent-encoding" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1938,16 +2033,6 @@ dependencies = [ "ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "pest_derive" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "pest_derive" version = "2.1.0" @@ -1990,36 +2075,37 @@ dependencies = [ [[package]] name = "phf" -version = "0.7.22" +version = "0.7.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_codegen" -version = "0.7.22" +version = "0.7.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_generator" -version = "0.7.22" +version = "0.7.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_shared" -version = "0.7.22" +version = "0.7.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2029,7 +2115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "polonius-engine" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "datafrog 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2037,6 +2123,11 @@ dependencies = [ "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "precomputed-hash" version = "0.1.1" @@ -2078,25 +2169,16 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] [[package]] name = "pulldown-cmark" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pulldown-cmark" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2117,11 +2199,6 @@ name = "quine-mc_cluskey" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.6.12" @@ -2132,10 +2209,10 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.23" +version = "2.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2143,19 +2220,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2165,7 +2230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2176,13 +2241,34 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_chacha" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2195,6 +2281,14 @@ name = "rand_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -2203,6 +2297,14 @@ dependencies = [ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_isaac" version = "0.1.1" @@ -2218,7 +2320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2241,23 +2343,33 @@ dependencies = [ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_xorshift" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rayon" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2293,18 +2405,6 @@ dependencies = [ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "regex" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "regex" version = "1.1.6" @@ -2317,14 +2417,6 @@ dependencies = [ "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "regex-syntax" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "regex-syntax" version = "0.6.6" @@ -2343,24 +2435,58 @@ version = "0.1.0" [[package]] name = "remove_dir_all" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "reqwest" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.31 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rle-decode-fast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rls" -version = "1.37.0" +version = "1.38.0" dependencies = [ - "cargo 0.38.0", + "cargo 0.39.0", "cargo_metadata 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.212", "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2371,12 +2497,11 @@ dependencies = [ "lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-analysis 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-analysis 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-rustc 0.6.0", "rls-span 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2384,11 +2509,11 @@ dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 1.3.0", + "rustfmt-nightly 1.4.4", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-process 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2400,7 +2525,7 @@ dependencies = [ [[package]] name = "rls-analysis" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2411,14 +2536,9 @@ dependencies = [ "rls-data 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rls-blacklist" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rls-data" version = "0.19.0" @@ -2454,8 +2574,9 @@ name = "rustbook" version = "0.1.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "mdbook 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mdbook 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mdbook-linkcheck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2463,20 +2584,19 @@ name = "rustc" version = "0.0.0" dependencies = [ "arena 0.0.0", - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", - "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "measureme 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_apfloat 0.0.0", @@ -2490,48 +2610,37 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", "syntax_pos 0.0.0", - "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-arena" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-graphviz" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-ap-rustc_cratesio_shim" -version = "491.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc-ap-rustc_data_structures" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-graphviz 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-graphviz 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2541,23 +2650,27 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_errors" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc-ap-rustc_lexer" +version = "546.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-ap-rustc_macros" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2569,20 +2682,19 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_target" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-serialize" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2591,32 +2703,33 @@ dependencies = [ [[package]] name = "rustc-ap-syntax" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_macros 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_lexer 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_macros 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "491.0.0" +version = "546.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-arena 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_macros 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-arena 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_macros 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2626,7 +2739,7 @@ name = "rustc-demangle" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -2665,7 +2778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2693,36 +2806,22 @@ name = "rustc-workspace-hack" version = "1.0.0" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rustc_allocator" -version = "0.0.0" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc 0.0.0", - "rustc_data_structures 0.0.0", - "rustc_errors 0.0.0", - "rustc_target 0.0.0", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syntax 0.0.0", - "syntax_pos 0.0.0", -] - [[package]] name = "rustc_apfloat" version = "0.0.0" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_cratesio_shim 0.0.0", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2733,12 +2832,12 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] [[package]] -name = "rustc_borrowck" +name = "rustc_ast_borrowck" version = "0.0.0" dependencies = [ "graphviz 0.0.0", @@ -2746,7 +2845,6 @@ dependencies = [ "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_mir 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -2758,25 +2856,23 @@ dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_llvm 0.0.0", + "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc_codegen_ssa" version = "0.0.0" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_allocator 0.0.0", "rustc_apfloat 0.0.0", "rustc_codegen_utils 0.0.0", "rustc_data_structures 0.0.0", @@ -2806,31 +2902,22 @@ dependencies = [ "syntax_pos 0.0.0", ] -[[package]] -name = "rustc_cratesio_shim" -version = "0.0.0" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc_data_structures" version = "0.0.0" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_cratesio_shim 0.0.0", "serialize 0.0.0", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2840,35 +2927,21 @@ dependencies = [ name = "rustc_driver" version = "0.0.0" dependencies = [ - "arena 0.0.0", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_allocator 0.0.0", - "rustc_borrowck 0.0.0", + "rustc_ast_borrowck 0.0.0", "rustc_codegen_utils 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_incremental 0.0.0", "rustc_interface 0.0.0", - "rustc_lint 0.0.0", "rustc_metadata 0.0.0", "rustc_mir 0.0.0", - "rustc_passes 0.0.0", - "rustc_plugin 0.0.0", - "rustc_privacy 0.0.0", - "rustc_resolve 0.0.0", "rustc_save_analysis 0.0.0", "rustc_target 0.0.0", - "rustc_traits 0.0.0", - "rustc_typeck 0.0.0", - "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", - "syntax_ext 0.0.0", "syntax_pos 0.0.0", ] @@ -2876,10 +2949,9 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_cratesio_shim 0.0.0", "rustc_data_structures 0.0.0", "serialize 0.0.0", "syntax_pos 0.0.0", @@ -2913,8 +2985,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_allocator 0.0.0", - "rustc_borrowck 0.0.0", + "rustc_ast_borrowck 0.0.0", "rustc_codegen_ssa 0.0.0", "rustc_codegen_utils 0.0.0", "rustc_data_structures 0.0.0", @@ -2929,7 +3000,6 @@ dependencies = [ "rustc_resolve 0.0.0", "rustc_traits 0.0.0", "rustc_typeck 0.0.0", - "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", @@ -2938,6 +3008,13 @@ dependencies = [ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc_lexer" +version = "0.1.0" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc_lint" version = "0.0.0" @@ -2965,7 +3042,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2995,7 +3072,6 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", - "syntax_ext 0.0.0", "syntax_pos 0.0.0", ] @@ -3009,7 +3085,7 @@ dependencies = [ "graphviz 0.0.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_apfloat 0.0.0", "rustc_data_structures 0.0.0", @@ -3028,7 +3104,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3040,9 +3116,7 @@ dependencies = [ "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_mir 0.0.0", "syntax 0.0.0", - "syntax_ext 0.0.0", "syntax_pos 0.0.0", ] @@ -3074,7 +3148,7 @@ name = "rustc_resolve" version = "0.0.0" dependencies = [ "arena 0.0.0", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -3098,7 +3172,7 @@ dependencies = [ "rustc_data_structures 0.0.0", "rustc_target 0.0.0", "rustc_typeck 0.0.0", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -3107,9 +3181,8 @@ dependencies = [ name = "rustc_target" version = "0.0.0" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_cratesio_shim 0.0.0", "rustc_data_structures 0.0.0", "serialize 0.0.0", "syntax_pos 0.0.0", @@ -3128,7 +3201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "rustc_traits" version = "0.0.0" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3147,7 +3220,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3178,9 +3251,8 @@ dependencies = [ name = "rustdoc" version = "0.0.0" dependencies = [ - "minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "minifier 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3198,19 +3270,18 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustfmt-config_proc_macro" -version = "0.1.0" +version = "0.1.2" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3220,15 +3291,15 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.3.0" +version = "1.4.4" dependencies = [ - "annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3237,15 +3308,15 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", - "rustfmt-config_proc_macro 0.1.0", + "rustfmt-config_proc_macro 0.1.2", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3254,7 +3325,7 @@ dependencies = [ [[package]] name = "ryu" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3289,6 +3360,30 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "security-framework" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "security-framework-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "semver" version = "0.9.0" @@ -3331,12 +3426,23 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.33" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_urlencoded" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3374,7 +3480,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3406,7 +3512,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3421,15 +3527,15 @@ name = "std" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "panic_abort 0.0.0", "panic_unwind 0.0.0", "profiler_builtins 0.0.0", @@ -3441,6 +3547,14 @@ dependencies = [ "unwind 0.0.0", ] +[[package]] +name = "string" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "string_cache" version = "0.7.3" @@ -3448,7 +3562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3460,8 +3574,8 @@ name = "string_cache_codegen" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3487,16 +3601,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3521,16 +3635,6 @@ dependencies = [ "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syn" version = "0.15.35" @@ -3541,14 +3645,6 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "synstructure" version = "0.10.2" @@ -3564,11 +3660,12 @@ dependencies = [ name = "syntax" version = "0.0.0" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_lexer 0.1.0", "rustc_macros 0.1.0", "rustc_target 0.0.0", "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3604,13 +3701,18 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "tar" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3621,10 +3723,10 @@ version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3653,10 +3755,11 @@ dependencies = [ [[package]] name = "term" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3673,7 +3776,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3693,7 +3796,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3720,7 +3823,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3729,7 +3832,7 @@ name = "time" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3740,7 +3843,7 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3756,13 +3859,23 @@ dependencies = [ "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-buf" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-codec" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3771,7 +3884,7 @@ name = "tokio-current-thread" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3781,7 +3894,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3789,7 +3902,7 @@ name = "tokio-fs" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3800,7 +3913,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3809,8 +3922,8 @@ name = "tokio-process" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3825,7 +3938,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3841,8 +3954,8 @@ name = "tokio-signal" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3858,7 +3971,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3873,7 +3986,7 @@ dependencies = [ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3886,7 +3999,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3897,7 +4010,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3911,9 +4024,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3938,18 +4051,6 @@ dependencies = [ "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "toml-query" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "toml-query" version = "0.9.0" @@ -3974,6 +4075,11 @@ dependencies = [ "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "try-lock" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "typenum" version = "1.10.0" @@ -3989,6 +4095,14 @@ name = "ucd-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicase" version = "2.4.0" @@ -4020,11 +4134,6 @@ name = "unicode-width" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.1.0" @@ -4049,9 +4158,9 @@ version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4064,6 +4173,17 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "url_serde" version = "0.2.0" @@ -4088,6 +4208,14 @@ name = "utf8parse" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "uuid" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vcpkg" version = "0.2.6" @@ -4103,7 +4231,7 @@ name = "vergen" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4131,6 +4259,16 @@ dependencies = [ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "want" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -4191,7 +4329,7 @@ name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4199,7 +4337,7 @@ name = "xz2" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lzma-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4209,33 +4347,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" "checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" -"checksum ammonia 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8b93ecb80665873703bf3b0a77f369c96b183d8e0afaf30a3ff5ff07dfc6409" -"checksum ammonia 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c799ecf1ad77acb48b643e2f45b12d60ee41576287fc575031aa020de88b8f45" -"checksum annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bcdcd5b291ce85a78f2b9d082a8de9676c12b1840d386d67bc5eea6f9d2b4e" +"checksum ammonia 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "384d704f242a0a9faf793fff775a0be6ab9aa27edabffa097331d73779142520" +"checksum annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7021ce4924a3f25f802b2cccd1af585e39ea1a363a1aa2e72afe54b67a3a7a7" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" -"checksum backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)" = "2d631cd7af21b7ff796293f1990104e3cdb606852863bac32f000c193aa35dfb" -"checksum backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "6ea90dd7b012b3d1a2cb6bec16670a0db2c95d4e931e84f4047e0460c1b34c8d" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)" = "b5164d292487f037ece34ec0de2fcede2faa162f085dd96d2385ab81b12765ba" +"checksum backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5b3a000b9c543553af61bc01cbfc403b04b5caa9e421033866f2e98061eb3e61" +"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" "checksum bstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "853b090ce0f45d0265902666bf88039ea3da825e33796716c511a1ec9c170036" -"checksum bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be0fdd54b507df8f22012890aadd099979befdba27713c767993f8380112ca7c" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" -"checksum cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "585784cac9b05c93a53b17a0b24a5cdd1dfdda5256f030e089b549d2390cc720" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cargo_metadata 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "929766d993a2fde7a0ae962ee82429069cd7b68839cd9375b98efd719df65d3a" "checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" "checksum cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "89431bba4e6b7092fb5fcd00a6f6ca596c55cc26b2f1e6dcdd08a1f4933f66b2" @@ -4248,7 +4382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e79ed19793c99771b386d76e08c3419409bb3d418b81a8b8afc73524247461cf" +"checksum compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1c086a06d6f52f9c0d50cacdc021bfb6034ddeec9fb7e62f099f13f65472f4" "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" @@ -4259,7 +4393,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c" +"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" +"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" @@ -4275,15 +4410,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum directories 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ccc83e029c3cebb4c8155c644d34e3a070ccdb4ff90d369c74cd73f7cb3c984" -"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +"checksum dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1" "checksum dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d" "checksum dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f283302e035e61c23f2b86b3093e8c6273a4c3125742d6087e96ade001ca5e63" +"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455" "checksum ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc01d68e08ca384955a3aeba9217102ca1aa85b6e168639bf27739f1d749d87" +"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" -"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" @@ -4302,26 +4438,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" -"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" +"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" +"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34dd4c507af68d37ffef962063dfa1944ce0dd4d5b82043dbab1dabe088610c3" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450" -"checksum git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "924b2e7d2986e625dcad89e8a429a7b3adee3c3d71e585f4a66c4f7e78715e31" -"checksum git2-curl 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f21f0550fd5d3f7c5adb94797fcd3d1002d7fc1fa349c82fe44f3c97ef80b62c" +"checksum getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "34f33de6f0ae7c9cb5e574502a562e2b512799e32abb801cd1e79ad952b62b49" +"checksum git2 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cb400360e8a4d61b10e648285bbfa919bbf9519d0d5d5720354456f44349226" +"checksum git2-curl 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2293de73491c3dc4174c5949ef53d2cc037b27613f88d72032e3f5237247a7dd" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454" -"checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" -"checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166" +"checksum h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "a539b63339fbbb00e081e84b6e11bd1d9634a82d91da2984a18ac74a8823f392" +"checksum handlebars 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d" "checksum hashbrown 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9529213c67695ca2d146e6f263b7b72df8fa973368beadf767e8ed80c03f2f36" +"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff" -"checksum html5ever 0.22.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c213fa6a618dc1da552f54f85cba74b05d8e883c92ec4e89067736938084c26e" "checksum html5ever 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce65ac8028cf5a287a7dbf6c4e0a6cf2dcf022ed5b167a81bae66ebf599a8b7" "checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" +"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" +"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum hyper 0.12.31 (registry+https://github.com/rust-lang/crates.io-index)" = "6481fff8269772d4463253ca83c788104a7305cb3fb9136bc651a6211e46e03f" +"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum if_chain 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d" "checksum ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002" "checksum im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0197597d095c0d11107975d3175173f810ee572c2501ff4de64f4f3f119806" @@ -4332,15 +4475,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jemalloc-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bef0d4ce37578dfd80b466e3d8324bd9de788e249f1accebb0c472ea4b52bdc" -"checksum jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b3d51e24009d966c8285d524dbaf6d60926636b2a89caee9ce0bd612494ddc16" +"checksum jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "f74e73053eaf95399bf926e48fc7a2a3ce50bd0eaaa2357d391e95b2dcdd4f10" "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be" "checksum jsonrpc-core 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "288dca7f9713710a29e485076b9340156cb701edb46a881f5d0c31aa4f5b9143" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" -"checksum libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "941a41e23f77323b8c9d2ee118aec9ee39dfc176078c18b4757d3bad049d9ff7" +"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +"checksum libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "90c6f86f4b0caa347206f916f8b687b51d77c6ef8ff18d52dd007491fd580529" +"checksum libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4c179ed6d19cd3a051e68c177fbbc214e79ac4724fac3a850ec9f3d3eb8a5578" "checksum libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4" "checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" @@ -4349,20 +4493,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd" "checksum lsp-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "169d737ad89cf8ddd82d1804d9122f54568c49377665157277cc90d747b1d31a" "checksum lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b62b77309737b1e262b3bbf37ff8faa740562c633b14702afe9be85dbcb6f88a" -"checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614" +"checksum lzma-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "16b5c59c57cc4d39e7999f50431aa312ea78af7c93b23fbb0c3567bd672e7f35" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2c4deaccc2ead6a28c16c0ba82f07d52b6475397415ce40876e559b0b0ea510" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" -"checksum markup5ever 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "897636f9850c3eef4905a5540683ed53dc9393860f0846cab2c2ddf9939862ff" "checksum markup5ever 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1af46a727284117e09780d05038b1ce6fc9c76cc6df183c3dae5a8955a25e21" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f" -"checksum mdbook 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c8e2c6442721202fb3b5800741aaafcc7076cdd199b326f0a39ce52a042cd37" +"checksum mdbook 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "949bb2acb2cff9fa5c375cf9c43e70b3dba0a974d9fe01c31285d7a84d2a0fa2" +"checksum mdbook-linkcheck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77d1f0ba4d1e6b86fa18e8853d026d7d76a97eb7eb5eb052ed80901e43b7fc10" "checksum measureme 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d09de7dafa3aa334bc806447c7e4de69419723312f4b88b80b561dea66601ce8" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "4c909e78edf61f3aa0dd2086da168cdf304329044bbf248768ca3d20253ec8c0" +"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" +"checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425" +"checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" +"checksum minifier 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "70bf0db2475f5e627787da77ca52fe33c294063f49f4134b8bc662eedb5e7332" "checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649" "checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" "checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" @@ -4371,6 +4517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" @@ -4382,7 +4529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448" "checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)" = "26bb632127731bf4ac49bf86a5dde12d2ca0918c2234fc39d79d4da2ccbc6da7" +"checksum openssl-src 111.3.0+1.1.1c (registry+https://github.com/rust-lang/crates.io-index)" = "53ed5f31d294bdf5f7a4ba0a206c2754b0f60e9a63b7e3076babc5317873c797" "checksum openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)" = "33c86834957dd5b915623e94f2f4ab2c70dd8f6b70679824155d5ae21dbd495d" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024" @@ -4391,67 +4538,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" +"checksum percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba4f28a6faf4ffea762ba8f4baef48c61a6db348647c73095034041fc79dd954" "checksum pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3" -"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" "checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" "checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" "checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" -"checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" -"checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" -"checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" -"checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" +"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b24942fee141ea45628484a453762bb7e515099c3ec05fbeb76b7bf57b1aeed" +"checksum polonius-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6b8a5defa2aef9ba4999aaa745fbc01c622ecea35964a306adc3e44be4f3b5b" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" -"checksum pulldown-cmark 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "051e60ace841b3bfecd402fe5051c06cb3bec4a6e6fdd060a37aa8eb829a1db3" +"checksum pulldown-cmark 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "77043da1282374688ee212dc44b3f37ff929431de9c9adc3053bd3cee5630357" "checksum punycode 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ddd112cca70a4d30883b2d21568a1d376ff8be4758649f64f973c6845128ad3" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" -"checksum racer 2.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "94dbdea3d959d8f76a2e303b3eadf107fd76da886b231291e649168613d432fb" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum racer 2.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "0727b9d7baaf9e42851145545d7b980b5c1752bd16a4c77c925c5e573d0069d9" "checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" "checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" "checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" -"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" +"checksum rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" +"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" +"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" -"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" "checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" -"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rls-analysis 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d53d49a28f75da9d02790d9256fecf6c0481e0871374326023c7a33131295579" -"checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411" +"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +"checksum reqwest 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e542d9f077c126af32536b6aacc75bb7325400eab8cd0743543be5d91660780d" +"checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" +"checksum rls-analysis 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c0d208ad66717501222c74b42d9e823a7612592e85ed78b04074c8f58c0be0a" "checksum rls-data 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76c72ea97e045be5f6290bb157ebdc5ee9f2b093831ff72adfaf59025cf5c491" "checksum rls-span 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1cb4694410d8d2ce43ccff3682f1c782158a018d5a9a92185675677f7533eb3" "checksum rls-vfs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce4b57b25b4330ed5ec14028fc02141e083ddafda327e7eb598dc0569c8c83c9" -"checksum rustc-ap-arena 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc0ad4318f3425229ed7b117275368b83269bec75f9609d4965dcb9752483c86" -"checksum rustc-ap-graphviz 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b80b7ea7902919f397c4bb12d102abe896fced7893d09d84bcac233e555bb388" -"checksum rustc-ap-rustc_cratesio_shim 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "752463d2b80039d23e42e667a9f6fe08213bd865f6ea301fb35f8068d94955ac" -"checksum rustc-ap-rustc_data_structures 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c3d6a14181e11c132d0ef97a6c27e1bb1d4da09682d02222393875c10d1c364" -"checksum rustc-ap-rustc_errors 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55caea8426565de362e8df0df737e43b9f22d632e0e52710cbfe316acc6ce2f0" -"checksum rustc-ap-rustc_macros 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "071420d762d2c779d1d4972356f37f5d049dcdd6c49e78f1b037e04c5a0f1a19" -"checksum rustc-ap-rustc_target 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5464696d0748e3019b9e5daca5fcadc53889dc2bca1dc26bf42001fd1c4194f" -"checksum rustc-ap-serialize 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9464445c11c15cf32ef27815b3ec89315b0ed73c6c771cbcf8543be59a3c1502" -"checksum rustc-ap-syntax 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff53245ae370d8e8073dc9cc13f8921e6110d0ccd208b64c388c5653fa6b9c83" -"checksum rustc-ap-syntax_pos 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41896f0eb2eb2f4ddba406939aa6b07386160fa38bee8cde3f7f0d85663e3d47" +"checksum rustc-ap-arena 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc2e1e68b64268c543bfa6e63e3c0d9ea58074c71396f42f76931f35a9287f9" +"checksum rustc-ap-graphviz 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c108d647ce0dd46477b048eafff5a6273b5652e02d47424b0cd684147379c811" +"checksum rustc-ap-rustc_data_structures 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "656771744e0783cb8e4481e3b8b1f975687610aaf18833b898018111a0e0e582" +"checksum rustc-ap-rustc_errors 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e37064f6624bc799bfaa2968b61ee6880926dea2a8bba69f18aef6c8e69c9604" +"checksum rustc-ap-rustc_lexer 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef5bc0a971823637ea23a857f0ef1467f44b1e05d71968821f83a0abe53e0fe3" +"checksum rustc-ap-rustc_macros 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b90037e3336fe8835f468db44d0848ae10d9cc8533ae89b55828883f905b7e80" +"checksum rustc-ap-rustc_target 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cadf9ca07315eab3a7a21f63872f9cc81e250fd6ede0419c24f8926ade73a45d" +"checksum rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61673783f2089e01033ffa82d1988f55175402071b31253a358292e1624d4602" +"checksum rustc-ap-syntax 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28f3dd1346d5b0269c07a4a78855e309a298ab569c9c1302d4d4f57f8eee4e84" +"checksum rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45e67b526dbda3a0c7dab91c8947d43685e7697f52686a4949da3c179cd7c979" "checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2e07e19601f21c59aad953c2632172ba70cb27e685771514ea66e4062b3363" @@ -4459,19 +4607,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b725dadae9fabc488df69a287f5a99c5eaf5d10853842a8a3dfac52476f544ee" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "af7c21531a91512a4a51b490be6ba1c8eff34fdda0dc5bf87dc28d86748aac56" -"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" +"checksum rustfix 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7150ac777a2931a53489f5a41eb0937b84e3092a20cd0e73ad436b65b507f607" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" "checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" +"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be" "checksum serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" -"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" +"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" "checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" @@ -4482,24 +4634,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" +"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" "checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strip-ansi-escapes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d63676e2abafa709460982ddc02a3bb586b6d15a49b75c212e06edd3933acee" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fa19a5a708e22bb5be31c1b6108a2a902f909c4b9ba85cba44c06632386bc0ff" -"checksum structopt-derive 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d59d0ae8ef8de16e49e3ca7afa16024a3e0dfd974a75ef93fdc5464e34523f" +"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" +"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" "checksum strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e" "checksum strum_macros 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)" = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a303ba60a099fcd2aaa646b14d2724591a96a75283e4b7ed3d1a1658909d9ae2" "checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" -"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" +"checksum term 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd90505d5006a4422d3520b30c781d480b3f36768c2fa2187c3e950bc110464" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum tester 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e812cb26c597f86a49b26dbb58b878bd2a2b4b93fc069dc39499228fe556ff6" @@ -4507,6 +4659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4790d0be6f4ba6ae4f48190efa2ed7780c9e3567796abdb285003cf39840d9c5" +"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" "checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" @@ -4522,31 +4675,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039" -"checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" "checksum toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a24369a1894ac8224efcfd567c3d141aea360292f49888e7ec7dcc316527aebb" "checksum toml-query_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c99ca245ec273c7e75c8ee58f47b882d0146f3c2c8495158082c6671e8b5335" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" +"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f42f536e22f7fcbb407639765c8fd78707a33109301f834a594758bedd6e8cf" "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" +"checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/README.md b/README.md index 15d09f4aad..40df6a4737 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ standard library, and documentation. [Rust]: https://www.rust-lang.org ## Quick Start -[quick-start]: #quick-start Read ["Installation"] from [The Book]. @@ -14,11 +13,15 @@ Read ["Installation"] from [The Book]. [The Book]: https://doc.rust-lang.org/book/index.html ## Installing from Source -[building-from-source]: #building-from-source -_Note: If you wish to contribute to the compiler, you should read -[this chapter](https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html) -of the rustc-guide instead._ +_Note: If you wish to contribute to the compiler, you should read [this +chapter][rustcguidebuild] of the rustc-guide instead of this section._ + +The Rust build system has a Python script called `x.py` to bootstrap building +the compiler. More information about it may be found by running `./x.py --help` +or reading the [rustc guide][rustcguidebuild]. + +[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html ### Building on *nix 1. Make sure you have installed the dependencies: @@ -39,43 +42,36 @@ of the rustc-guide instead._ [source]: https://github.com/rust-lang/rust -3. Build and install: - - ```sh - $ ./x.py build && sudo ./x.py install - ``` +3. Configure the build settings: - If after running `sudo ./x.py install` you see an error message like + The Rust build system uses a file named `config.toml` in the root of the + source tree to determine various configuration settings for the build. + Copy the default `config.toml.example` to `config.toml` to get started. - ``` - error: failed to load source for a dependency on 'cc' + ```sh + $ cp config.toml.example config.toml ``` - then run these two commands and then try `sudo ./x.py install` again: + It is recommended that if you plan to use the Rust build system to create + an installation (using `./x.py install`) that you set the `prefix` value + in the `[install]` section to a directory that you have write permissions. - ``` - $ cargo install cargo-vendor - ``` +4. Build and install: + ```sh + $ ./x.py build && ./x.py install ``` - $ cargo vendor - ``` - - > ***Note:*** Install locations can be adjusted by copying the config file - > from `./config.toml.example` to `./config.toml`, and - > adjusting the `prefix` option under `[install]`. Various other options, such - > as enabling debug information, are also supported, and are documented in - > the config file. - When complete, `sudo ./x.py install` will place several programs into - `/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the + When complete, `./x.py install` will place several programs into + `$PREFIX/bin`: `rustc`, the Rust compiler, and `rustdoc`, the API-documentation tool. This install does not include [Cargo], - Rust's package manager, which you may also want to build. + Rust's package manager. To build and install Cargo, you may + run `./x.py install cargo` or set the `build.extended` key in + `config.toml` to `true` to build and install all tools. [Cargo]: https://github.com/rust-lang/cargo ### Building on Windows -[building-on-windows]: #building-on-windows There are two prominent ABIs in use on Windows: the native (MSVC) ABI used by Visual Studio, and the GNU ABI used by the GCC toolchain. Which version of Rust @@ -85,7 +81,6 @@ for interop with GNU software built using the MinGW/MSYS2 toolchain use the GNU build. #### MinGW -[windows-mingw]: #windows-mingw [MSYS2][msys2] can be used to easily build Rust on Windows: @@ -126,7 +121,6 @@ build. ``` #### MSVC -[windows-msvc]: #windows-msvc MSVC builds of Rust additionally require an installation of Visual Studio 2017 (or later) so `rustc` can use its linker. The simplest way is to get the @@ -155,7 +149,6 @@ by manually calling the appropriate vcvars file before running the bootstrap. ``` #### Specifying an ABI -[specifying-an-abi]: #specifying-an-abi Each specific ABI can also be used from either environment (for example, using the GNU ABI in PowerShell) by using an explicit build triple. The available @@ -169,11 +162,10 @@ Windows build triples are: The build triple can be specified by either specifying `--build=` when invoking `x.py` commands, or by copying the `config.toml` file (as described -in Building From Source), and modifying the `build` option under the `[build]` -section. +in [Installing From Source](#installing-from-source)), and modifying the +`build` option under the `[build]` section. ### Configure and Make -[configure-and-make]: #configure-and-make While it's not the recommended build system, this project also provides a configure script and makefile (the latter of which just invokes `x.py`). @@ -188,7 +180,6 @@ When using the configure script, the generated `config.mk` file may override the `config.mk` file. ## Building Documentation -[building-documentation]: #building-documentation If you’d like to build the documentation, it’s almost the same: @@ -201,7 +192,6 @@ the ABI used. I.e., if the ABI was `x86_64-pc-windows-msvc`, the directory will `build\x86_64-pc-windows-msvc\doc`. ## Notes -[notes]: #notes Since the Rust compiler is written in Rust, it must be built by a precompiled "snapshot" version of itself (made in an earlier stage of @@ -210,11 +200,11 @@ fetch snapshots, and an OS that can execute the available snapshot binaries. Snapshot binaries are currently built and tested on several platforms: -| Platform / Architecture | x86 | x86_64 | -|--------------------------|-----|--------| -| Windows (7, 8, 10, ...) | ✓ | ✓ | -| Linux (2.6.18 or later) | ✓ | ✓ | -| OSX (10.7 Lion or later) | ✓ | ✓ | +| Platform / Architecture | x86 | x86_64 | +|----------------------------|-----|--------| +| Windows (7, 8, 10, ...) | ✓ | ✓ | +| Linux (2.6.18 or later) | ✓ | ✓ | +| macOS (10.7 Lion or later) | ✓ | ✓ | You may find that other platforms work, but these are our officially supported build environments that are most likely to work. @@ -224,7 +214,6 @@ There is more advice about hacking on Rust in [CONTRIBUTING.md]. [CONTRIBUTING.md]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md ## Getting Help -[getting-help]: #getting-help The Rust community congregates in a few places: @@ -237,7 +226,6 @@ The Rust community congregates in a few places: [users.rust-lang.org]: https://users.rust-lang.org/ ## Contributing -[contributing]: #contributing To contribute to Rust, please see [CONTRIBUTING](CONTRIBUTING.md). @@ -258,7 +246,6 @@ Also, you may find the [rustdocs for the compiler itself][rustdocs] useful. [rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ ## License -[license]: #license Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various @@ -268,7 +255,6 @@ See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and [COPYRIGHT](COPYRIGHT) for details. ## Trademark -[trademark]: #trademark The Rust programming language is an open source, community project governed by a core team. It is also sponsored by the Mozilla Foundation (“Mozilla”), diff --git a/RELEASES.md b/RELEASES.md index 6049a8ef4c..ecf49278f4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,117 @@ +Version 1.38.0 (2019-09-26) +========================== + +Language +-------- +- [The `#[global_allocator]` attribute can now be used in submodules.][62735] +- [The `#[deprecated]` attribute can now be used on macros.][62042] + +Compiler +-------- +- [Added pipelined compilation support to `rustc`.][62766] This will + improve compilation times in some cases. For further information please refer + to the [_"Evaluating pipelined rustc compilation"_][pipeline-internals] thread. +- [Added tier 3\* support for the `aarch64-uwp-windows-msvc`, `i686-uwp-windows-gnu`, + `i686-uwp-windows-msvc`, `x86_64-uwp-windows-gnu`, and + `x86_64-uwp-windows-msvc` targets.][60260] +- [Added tier 3 support for the `armv7-unknown-linux-gnueabi` and + `armv7-unknown-linux-musleabi` targets.][63107] +- [Added tier 3 support for the `hexagon-unknown-linux-musl` target.][62814] +- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784] + +\* Refer to Rust's [platform support page][forge-platform-support] for more +information on Rust's tiered platform support. + +Libraries +--------- +- [`ascii::EscapeDefault` now implements `Clone` and `Display`.][63421] +- [Derive macros for prelude traits (e.g. `Clone`, `Debug`, `Hash`) are now + available at the same path as the trait.][63056] (e.g. The `Clone` derive macro + is available at `std::clone::Clone`). This also makes all built-in macros + available in `std`/`core` root. e.g. `std::include_bytes!`. +- [`str::Chars` now implements `Debug`.][63000] +- [`slice::{concat, connect, join}` now accepts `&[T]` in addition to `&T`.][62528] +- [`*const T` and `*mut T` now implement `marker::Unpin`.][62583] +- [`Arc<[T]>` and `Rc<[T]>` now implement `FromIterator`.][61953] +- [Added euclidean remainder and division operations (`div_euclid`, + `rem_euclid`) to all numeric primitives.][61884] Additionally `checked`, + `overflowing`, and `wrapping` versions are available for all + integer primitives. +- [`thread::AccessError` now implements `Clone`, `Copy`, `Eq`, `Error`, and + `PartialEq`.][61491] +- [`iter::{StepBy, Peekable, Take}` now implement `DoubleEndedIterator`.][61457] + +Stabilized APIs +--------------- +- [`<*const T>::cast`] +- [`<*mut T>::cast`] +- [`Duration::as_secs_f32`] +- [`Duration::as_secs_f64`] +- [`Duration::div_duration_f32`] +- [`Duration::div_duration_f64`] +- [`Duration::div_f32`] +- [`Duration::div_f64`] +- [`Duration::from_secs_f32`] +- [`Duration::from_secs_f64`] +- [`Duration::mul_f32`] +- [`Duration::mul_f64`] +- [`any::type_name`] + +Cargo +----- +- [Added pipelined compilation support to `cargo`.][cargo/7143] +- [You can now pass the `--features` option multiple times to enable + multiple features.][cargo/7084] + +Misc +---- +- [`rustc` will now warn about some incorrect uses of + `mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346] + +Compatibility Notes +------------------- +- Unfortunately the [`x86_64-unknown-uefi` platform can not be built][62785] + with rustc 1.39.0. +- The [`armv7-unknown-linux-gnueabihf` platform is also known to have + issues][62896] for certain crates such as libc. + +[60260]: https://github.com/rust-lang/rust/pull/60260/ +[61457]: https://github.com/rust-lang/rust/pull/61457/ +[61491]: https://github.com/rust-lang/rust/pull/61491/ +[61884]: https://github.com/rust-lang/rust/pull/61884/ +[61953]: https://github.com/rust-lang/rust/pull/61953/ +[62042]: https://github.com/rust-lang/rust/pull/62042/ +[62528]: https://github.com/rust-lang/rust/pull/62528/ +[62583]: https://github.com/rust-lang/rust/pull/62583/ +[62735]: https://github.com/rust-lang/rust/pull/62735/ +[62766]: https://github.com/rust-lang/rust/pull/62766/ +[62784]: https://github.com/rust-lang/rust/pull/62784/ +[62785]: https://github.com/rust-lang/rust/issues/62785/ +[62814]: https://github.com/rust-lang/rust/pull/62814/ +[62896]: https://github.com/rust-lang/rust/issues/62896/ +[63000]: https://github.com/rust-lang/rust/pull/63000/ +[63056]: https://github.com/rust-lang/rust/pull/63056/ +[63107]: https://github.com/rust-lang/rust/pull/63107/ +[63346]: https://github.com/rust-lang/rust/pull/63346/ +[63421]: https://github.com/rust-lang/rust/pull/63421/ +[cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/ +[cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/ +[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast +[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast +[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32 +[`Duration::as_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f64 +[`Duration::div_duration_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f32 +[`Duration::div_duration_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f64 +[`Duration::div_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f32 +[`Duration::div_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f64 +[`Duration::from_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f32 +[`Duration::from_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f64 +[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32 +[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64 +[`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html +[forge-platform-support]: https://forge.rust-lang.org/platform-support.html +[pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199 + Version 1.37.0 (2019-08-15) ========================== @@ -22,7 +136,7 @@ Language - [You can now use `_` as an identifier for consts.][61347] e.g. You can write `const _: u32 = 5;`. - [You can now use `#[repr(align(X)]` on enums.][61229] -- [The `?`/_"Kleene"_ macro operator is now available in the +- [The `?` Kleene macro operator is now available in the 2015 edition.][60932] Compiler @@ -179,10 +293,8 @@ Misc Compatibility Notes ------------------- -- [`std::arch::x86::_rdtsc` returns `u64` instead of `i64`][stdsimd/559] -- [`std::arch::x86_64::_mm_shuffle_ps` takes an `i32` instead of `u32` for `mask`][stdsimd/522] - With the stabilisation of `mem::MaybeUninit`, `mem::uninitialized` use is no - longer recommended, and will be deprecated in 1.38.0. + longer recommended, and will be deprecated in 1.39.0. [60318]: https://github.com/rust-lang/rust/pull/60318/ [60364]: https://github.com/rust-lang/rust/pull/60364/ @@ -217,8 +329,7 @@ Compatibility Notes [`task::Poll`]: https://doc.rust-lang.org/beta/std/task/enum.Poll.html [clippy-1-36-0]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-136 [cargo-1-36-0]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-136-2019-07-04 -[stdsimd/522]: https://github.com/rust-lang-nursery/stdsimd/issues/522 -[stdsimd/559]: https://github.com/rust-lang-nursery/stdsimd/issues/559 + Version 1.35.0 (2019-05-23) ========================== @@ -542,7 +653,7 @@ Compiler -------- - [You can now set a linker flavor for `rustc` with the `-Clinker-flavor` command line argument.][56351] -- [The mininum required LLVM version has been bumped to 6.0.][56642] +- [The minimum required LLVM version has been bumped to 6.0.][56642] - [Added support for the PowerPC64 architecture on FreeBSD.][57615] - [The `x86_64-fortanix-unknown-sgx` target support has been upgraded to tier 2 support.][57130] Visit the [platform support][platform-support] page for @@ -973,7 +1084,7 @@ Compiler Libraries --------- -- [You can now convert `num::NonZero*` types to their raw equivalvents using the +- [You can now convert `num::NonZero*` types to their raw equivalents using the `From` trait.][54240] E.g. `u8` now implements `From`. - [You can now convert a `&Option` into `Option<&T>` and `&mut Option` into `Option<&mut T>` using the `From` trait.][53218] @@ -1166,7 +1277,7 @@ Security Notes caused by an integer overflow. This has been fixed by deterministically panicking when an overflow happens. - Thank you to Scott McMurray for responsibily disclosing this vulnerability to + Thank you to Scott McMurray for responsibly disclosing this vulnerability to us. @@ -1438,7 +1549,7 @@ Security Notes given machine. This release fixes that vulnerability; you can read more about this on the [blog][rustdoc-sec]. The associated CVE is [CVE-2018-1000622]. - Thank you to Red Hat for responsibily disclosing this vulnerability to us. + Thank you to Red Hat for responsibly disclosing this vulnerability to us. Compatibility Notes ------------------- diff --git a/config.toml.example b/config.toml.example index c14adf8ce3..cb9f388a8e 100644 --- a/config.toml.example +++ b/config.toml.example @@ -57,14 +57,13 @@ # support. You'll need to write a target specification at least, and most # likely, teach rustc about the C ABI of the target. Get in touch with the # Rust team and file an issue if you need assistance in porting! -#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;MSP430;Sparc;NVPTX;Hexagon" +#targets = "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86" # LLVM experimental targets to build support for. These targets are specified in # the same format as above, but since these targets are experimental, they are # not built by default and the experimental Rust compilation targets that depend -# on them will not work unless the user opts in to building them. By default the -# `WebAssembly` and `RISCV` targets are enabled when compiling LLVM from scratch. -#experimental-targets = "WebAssembly;RISCV" +# on them will not work unless the user opts in to building them. +#experimental-targets = "" # Cap the number of parallel linker invocations when compiling LLVM. # This can be useful when building LLVM with debug info, which significantly @@ -369,10 +368,6 @@ # When creating source tarballs whether or not to create a source tarball. #dist-src = false -# Whether to also run the Miri tests suite when running tests. -# As a side-effect also generates MIR for all libraries. -#test-miri = false - # After building or testing extended tools (e.g. clippy and rustfmt), append the # result (broken, compiling, testing) into this JSON file. #save-toolstates = "/path/to/toolstates.json" diff --git a/git-commit-hash b/git-commit-hash index df8443341f..c039f4b9e7 100644 --- a/git-commit-hash +++ b/git-commit-hash @@ -1 +1 @@ -eae3437dfe991621e8afdc82734f4a172d7ddf9b \ No newline at end of file +625451e376bb2e5283fc4741caa0a3e8a2ca4d54 \ No newline at end of file diff --git a/src/README.md b/src/README.md index 14e773286b..32ca4a1057 100644 --- a/src/README.md +++ b/src/README.md @@ -5,10 +5,7 @@ This directory contains the source code of the rust project, including: For more information on how various parts of the compiler work, see the [rustc guide]. -There is also useful content in the following READMEs, which are gradually being moved over to the guide: -- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query -- https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph -- https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked -- https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve +There is also useful content in this README: +https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve. [rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index 1e01d68fb3..3e877fc4e3 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -55,11 +55,11 @@ The script accepts commands, flags, and arguments to determine what to do: # run all unit tests ./x.py test - # execute the run-pass test suite - ./x.py test src/test/run-pass + # execute the UI test suite + ./x.py test src/test/ui - # execute only some tests in the run-pass test suite - ./x.py test src/test/run-pass --test-args substring-of-test-name + # execute only some tests in the UI test suite + ./x.py test src/test/ui --test-args substring-of-test-name # execute tests in the standard library in stage0 ./x.py test --stage 0 src/libstd @@ -215,7 +215,7 @@ build/ # Output for all compiletest-based test suites test/ - run-pass/ + ui/ compile-fail/ debuginfo/ ... diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index 0732cb83f3..bd1a87c574 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -5,7 +5,8 @@ //! parent directory, and otherwise documentation can be found throughout the `build` //! directory in each respective module. -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::env; diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 595deb07ec..54b689fb06 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -15,7 +15,8 @@ //! switching compilers for the bootstrap and for build scripts will probably //! never get replaced. -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::env; use std::ffi::OsString; @@ -91,17 +92,16 @@ fn main() { cmd.args(&args) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); - let mut maybe_crate = None; // Get the name of the crate we're compiling, if any. - let maybe_crate_name = args.windows(2) - .find(|a| &*a[0] == "--crate-name") - .map(|crate_name| &*crate_name[1]); + let crate_name = args.windows(2) + .find(|args| args[0] == "--crate-name") + .and_then(|args| args[1].to_str()); - if let Some(current_crate) = maybe_crate_name { + if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { if target == "all" || - target.into_string().unwrap().split(",").any(|c| c.trim() == current_crate) + target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name) { cmd.arg("-Ztime"); } @@ -125,10 +125,29 @@ fn main() { cmd.arg(format!("-Cdebuginfo={}", debuginfo_level)); } + if env::var_os("RUSTC_DENY_WARNINGS").is_some() && + env::var_os("RUSTC_EXTERNAL_TOOL").is_none() { + // When extending this list, search for `NO-RUSTC-WRAPPER` and add the new lints + // there as well, some code doesn't go through this `rustc` wrapper. + cmd.arg("-Dwarnings"); + cmd.arg("-Drust_2018_idioms"); + cmd.arg("-Dunused_lifetimes"); + // cfg(not(bootstrap)): Remove this during the next stage 0 compiler update. + // `-Drustc::internal` is a new feature and `rustc_version` mis-reports the `stage`. + let cfg_not_bootstrap = stage != "0" && crate_name != Some("rustc_version"); + if cfg_not_bootstrap && use_internal_lints(crate_name) { + cmd.arg("-Zunstable-options"); + cmd.arg("-Drustc::internal"); + } + } + if let Some(target) = target { // The stage0 compiler has a special sysroot distinct from what we - // actually downloaded, so we just always pass the `--sysroot` option. - cmd.arg("--sysroot").arg(&sysroot); + // actually downloaded, so we just always pass the `--sysroot` option, + // unless one is already set. + if !args.iter().any(|arg| arg == "--sysroot") { + cmd.arg("--sysroot").arg(&sysroot); + } cmd.arg("-Zexternal-macro-backtrace"); @@ -167,9 +186,6 @@ fn main() { cmd.arg(format!("-Clinker={}", target_linker)); } - let crate_name = maybe_crate_name.unwrap(); - maybe_crate = Some(crate_name); - // If we're compiling specifically the `panic_abort` crate then we pass // the `-C panic=abort` option. Note that we do not do this for any // other crate intentionally as this is the only crate for now that we @@ -182,8 +198,8 @@ fn main() { // `compiler_builtins` are unconditionally compiled with panic=abort to // workaround undefined references to `rust_eh_unwind_resume` generated // otherwise, see issue https://github.com/rust-lang/rust/issues/43095. - if crate_name == "panic_abort" || - crate_name == "compiler_builtins" && stage != "0" { + if crate_name == Some("panic_abort") || + crate_name == Some("compiler_builtins") && stage != "0" { cmd.arg("-C").arg("panic=abort"); } @@ -196,7 +212,7 @@ fn main() { // The compiler builtins are pretty sensitive to symbols referenced in // libcore and such, so we never compile them with debug assertions. - if crate_name == "compiler_builtins" { + if crate_name == Some("compiler_builtins") { cmd.arg("-C").arg("debug-assertions=no"); } else { cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions)); @@ -272,20 +288,6 @@ fn main() { } } - // When running miri tests, we need to generate MIR for all libraries - if env::var("TEST_MIRI").ok().map_or(false, |val| val == "true") { - // The flags here should be kept in sync with `add_miri_default_args` - // in miri's `src/lib.rs`. - cmd.arg("-Zalways-encode-mir"); - cmd.arg("--cfg=miri"); - // These options are preferred by miri, to be able to perform better validation, - // but the bootstrap compiler might not understand them. - if stage != "0" { - cmd.arg("-Zmir-emit-retag"); - cmd.arg("-Zmir-opt-level=0"); - } - } - if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") { cmd.arg("--remap-path-prefix").arg(&map); } @@ -305,9 +307,6 @@ fn main() { } } - // This is required for internal lints. - cmd.arg("-Zunstable-options"); - // Force all crates compiled by this compiler to (a) be unstable and (b) // allow the `rustc_private` feature to link to other unstable crates // also in the sysroot. We also do this for host crates, since those @@ -320,13 +319,6 @@ fn main() { cmd.arg("--cfg").arg("parallel_compiler"); } - if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none() - { - cmd.arg("-Dwarnings"); - cmd.arg("-Dbare_trait_objects"); - cmd.arg("-Drust_2018_idioms"); - } - if verbose > 1 { eprintln!( "rustc command: {:?}={:?} {:?}", @@ -349,7 +341,7 @@ fn main() { } if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() { - if let Some(krate) = maybe_crate { + if let Some(crate_name) = crate_name { let start = Instant::now(); let status = cmd .status() @@ -358,7 +350,7 @@ fn main() { let is_test = args.iter().any(|a| a == "--test"); eprintln!("[RUSTC-TIMING] {} test:{} {}.{:03}", - krate.to_string_lossy(), + crate_name, is_test, dur.as_secs(), dur.subsec_nanos() / 1_000_000); @@ -377,6 +369,14 @@ fn main() { std::process::exit(code); } +// Rustc crates for which internal lints are in effect. +fn use_internal_lints(crate_name: Option<&str>) -> bool { + crate_name.map_or(false, |crate_name| { + crate_name.starts_with("rustc") || crate_name.starts_with("syntax") || + ["arena", "fmt_macros"].contains(&crate_name) + }) +} + #[cfg(unix)] fn exec_cmd(cmd: &mut Command) -> io::Result { use std::os::unix::process::CommandExt; diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 1c9f6e1ab2..ff38ee8788 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -2,7 +2,8 @@ //! //! See comments in `src/bootstrap/rustc.rs` for more information. -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::env; use std::process::Command; diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 1c2b882f66..86901792d7 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -735,6 +735,47 @@ class RustBuild(object): """Set download URL for development environment""" self._download_url = 'https://dev-static.rust-lang.org' + def check_vendored_status(self): + """Check that vendoring is configured properly""" + vendor_dir = os.path.join(self.rust_root, 'vendor') + if 'SUDO_USER' in os.environ and not self.use_vendored_sources: + if os.environ.get('USER') != os.environ['SUDO_USER']: + self.use_vendored_sources = True + print('info: looks like you are running this command under `sudo`') + print(' and so in order to preserve your $HOME this will now') + print(' use vendored sources by default.') + if not os.path.exists(vendor_dir): + print('error: vendoring required, but vendor directory does not exist.') + print(' Run `cargo vendor` without sudo to initialize the ' + 'vendor directory.') + raise Exception("{} not found".format(vendor_dir)) + + if self.use_vendored_sources: + if not os.path.exists('.cargo'): + os.makedirs('.cargo') + with output('.cargo/config') as cargo_config: + cargo_config.write( + "[source.crates-io]\n" + "replace-with = 'vendored-sources'\n" + "registry = 'https://example.com'\n" + "\n" + "[source.vendored-sources]\n" + "directory = '{}/vendor'\n" + .format(self.rust_root)) + else: + if os.path.exists('.cargo'): + shutil.rmtree('.cargo') + + def ensure_vendored(self): + """Ensure that the vendored sources are available if needed""" + vendor_dir = os.path.join(self.rust_root, 'vendor') + # Note that this does not handle updating the vendored dependencies if + # the rust git repository is updated. Normal development usually does + # not use vendoring, so hopefully this isn't too much of a problem. + if self.use_vendored_sources and not os.path.exists(vendor_dir): + run([self.cargo(), "vendor"], + verbose=self.verbose, cwd=self.rust_root) + def bootstrap(help_triggered): """Configure, fetch, build and run the initial bootstrap""" @@ -776,30 +817,7 @@ def bootstrap(help_triggered): build.use_locked_deps = '\nlocked-deps = true' in build.config_toml - if 'SUDO_USER' in os.environ and not build.use_vendored_sources: - if os.environ.get('USER') != os.environ['SUDO_USER']: - build.use_vendored_sources = True - print('info: looks like you are running this command under `sudo`') - print(' and so in order to preserve your $HOME this will now') - print(' use vendored sources by default. Note that if this') - print(' does not work you should run a normal build first') - print(' before running a command like `sudo ./x.py install`') - - if build.use_vendored_sources: - if not os.path.exists('.cargo'): - os.makedirs('.cargo') - with output('.cargo/config') as cargo_config: - cargo_config.write(""" - [source.crates-io] - replace-with = 'vendored-sources' - registry = 'https://example.com' - - [source.vendored-sources] - directory = '{}/vendor' - """.format(build.rust_root)) - else: - if os.path.exists('.cargo'): - shutil.rmtree('.cargo') + build.check_vendored_status() data = stage0_data(build.rust_root) build.date = data['date'] @@ -815,6 +833,7 @@ def bootstrap(help_triggered): build.build = args.build or build.build_triple() build.download_stage0() sys.stdout.flush() + build.ensure_vendored() build.build_bootstrap() sys.stdout.flush() diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 2e9df48d00..e54c9360ba 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -371,7 +371,6 @@ impl<'a> Builder<'a> { Kind::Test => describe!( test::Tidy, test::Ui, - test::RunPass, test::CompileFail, test::RunFail, test::RunPassValgrind, @@ -382,10 +381,8 @@ impl<'a> Builder<'a> { test::Incremental, test::Debuginfo, test::UiFullDeps, - test::RunPassFullDeps, test::Rustdoc, test::Pretty, - test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty, test::Crate, @@ -405,6 +402,7 @@ impl<'a> Builder<'a> { test::TheBook, test::UnstableBook, test::RustcBook, + test::RustcGuide, test::EmbeddedBook, test::EditionGuide, test::Rustfmt, @@ -545,15 +543,6 @@ impl<'a> Builder<'a> { parent: Cell::new(None), }; - if kind == Kind::Dist { - assert!( - !builder.config.test_miri, - "Do not distribute with miri enabled.\n\ - The distributed libraries would include all MIR (increasing binary size). - The distributed MIR would include validation statements." - ); - } - builder } @@ -983,7 +972,6 @@ impl<'a> Builder<'a> { PathBuf::from("/path/to/nowhere/rustdoc/not/required") }, ) - .env("TEST_MIRI", self.config.test_miri.to_string()) .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir()); if let Some(host_linker) = self.linker(compiler.host) { diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index cab7443bf3..d1542b1fca 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -629,7 +629,6 @@ fn test_with_no_doc_stage0() { fn test_exclude() { let mut config = configure(&[], &[]); config.exclude = vec![ - "src/test/run-pass".into(), "src/tools/tidy".into(), ]; config.cmd = Subcommand::Test { @@ -648,11 +647,9 @@ fn test_exclude() { let builder = Builder::new(&build); builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - // Ensure we have really excluded run-pass & tidy - assert!(!builder.cache.contains::()); + // Ensure we have really excluded tidy assert!(!builder.cache.contains::()); // Ensure other tests are not affected. - assert!(builder.cache.contains::()); assert!(builder.cache.contains::()); } diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index f137a7b8cc..53071df855 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -266,8 +266,10 @@ impl Cache { .expect("invalid type mapped"); stepcache.get(step).cloned() } +} - #[cfg(test)] +#[cfg(test)] +impl Cache { pub fn all(&mut self) -> Vec<(S, S::Output)> { let cache = self.0.get_mut(); let type_id = TypeId::of::(); @@ -279,7 +281,6 @@ impl Cache { v } - #[cfg(test)] pub fn contains(&self) -> bool { self.0.borrow().contains_key(&TypeId::of::()) } diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index 400375cd20..c58a98bac3 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -45,6 +45,8 @@ fn cc2ar(cc: &Path, target: &str) -> Option { Some(PathBuf::from("ar")) } else if target.contains("openbsd") { Some(PathBuf::from("ar")) + } else if target.contains("vxworks") { + Some(PathBuf::from("vx-ar")) } else { let parent = cc.parent().unwrap(); let file = cc.file_name().unwrap().to_str().unwrap(); diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 41235d911c..8e8d8f5e78 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -13,7 +13,7 @@ use build_helper::output; use crate::Build; // The version number -pub const CFG_RELEASE_NUM: &str = "1.37.0"; +pub const CFG_RELEASE_NUM: &str = "1.38.0"; pub struct GitInfo { inner: Option, diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index bdf5306d4b..11b082ac3f 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -50,7 +50,6 @@ impl Step for Std { let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind)); std_cargo(builder, &compiler, target, &mut cargo); - let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage)); builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target)); run_cargo(builder, &mut cargo, @@ -99,7 +98,6 @@ impl Step for Rustc { cargo_subcommand(builder.kind)); rustc_cargo(builder, &mut cargo); - let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage)); builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target)); run_cargo(builder, &mut cargo, @@ -153,7 +151,6 @@ impl Step for CodegenBackend { // We won't build LLVM if it's not available, as it shouldn't affect `check`. - let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage)); run_cargo(builder, &mut cargo, args(builder.kind), @@ -190,7 +187,6 @@ impl Step for Test { let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind)); test_cargo(builder, &compiler, target, &mut cargo); - let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage)); builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target)); run_cargo(builder, &mut cargo, @@ -239,7 +235,6 @@ impl Step for Rustdoc { SourceType::InTree, &[]); - let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage)); println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target); run_cargo(builder, &mut cargo, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 576267e694..4cd793adaf 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -95,7 +95,6 @@ impl Step for Std { let mut cargo = builder.cargo(compiler, Mode::Std, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); - let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage)); builder.info(&format!("Building stage{} std artifacts ({} -> {})", compiler.stage, &compiler.host, target)); run_cargo(builder, @@ -326,7 +325,7 @@ impl Step for StartupObjects { fn run(self, builder: &Builder<'_>) { let for_compiler = self.compiler; let target = self.target; - if !target.contains("pc-windows-gnu") { + if !target.contains("windows-gnu") { return } @@ -422,7 +421,6 @@ impl Step for Test { let mut cargo = builder.cargo(compiler, Mode::Test, target, "build"); test_cargo(builder, &compiler, target, &mut cargo); - let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage)); builder.info(&format!("Building stage{} test artifacts ({} -> {})", compiler.stage, &compiler.host, target)); run_cargo(builder, @@ -555,7 +553,6 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build"); rustc_cargo(builder, &mut cargo); - let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage)); builder.info(&format!("Building stage{} compiler artifacts ({} -> {})", compiler.stage, &compiler.host, target)); run_cargo(builder, @@ -710,7 +707,6 @@ impl Step for CodegenBackend { let tmp_stamp = out_dir.join(".tmp.stamp"); - let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage)); let files = run_cargo(builder, cargo.arg("--features").arg(features), vec![], @@ -1130,6 +1126,7 @@ pub fn run_cargo(builder: &Builder<'_>, // Skip files like executables if !filename.ends_with(".rlib") && !filename.ends_with(".lib") && + !filename.ends_with(".a") && !is_dylib(&filename) && !(is_check && filename.ends_with(".rmeta")) { continue; diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 66f504ea92..a5bfafdfdb 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -75,7 +75,7 @@ pub struct Config { pub llvm_link_shared: bool, pub llvm_clang_cl: Option, pub llvm_targets: Option, - pub llvm_experimental_targets: String, + pub llvm_experimental_targets: Option, pub llvm_link_jobs: Option, pub llvm_version_suffix: Option, pub llvm_use_linker: Option, @@ -128,7 +128,6 @@ pub struct Config { pub low_priority: bool, pub channel: String, pub verbose_tests: bool, - pub test_miri: bool, pub save_toolstates: Option, pub print_step_timings: bool, pub missing_tools: bool, @@ -315,7 +314,6 @@ struct Rust { debug: Option, dist_src: Option, verbose_tests: Option, - test_miri: Option, incremental: Option, save_toolstates: Option, codegen_backends: Option>, @@ -375,7 +373,6 @@ impl Config { config.codegen_tests = true; config.ignore_git = false; config.rust_dist_src = true; - config.test_miri = false; config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")]; config.rust_codegen_backends_dir = "codegen-backends".to_owned(); config.deny_warnings = true; @@ -405,7 +402,7 @@ impl Config { config.incremental = flags.incremental; config.dry_run = flags.dry_run; config.keep_stage = flags.keep_stage; - if let Some(value) = flags.warnings { + if let Some(value) = flags.deny_warnings { config.deny_warnings = value; } @@ -524,8 +521,7 @@ impl Config { set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); set(&mut config.llvm_link_shared, llvm.link_shared); config.llvm_targets = llvm.targets.clone(); - config.llvm_experimental_targets = llvm.experimental_targets.clone() - .unwrap_or_else(|| "WebAssembly;RISCV".to_string()); + config.llvm_experimental_targets = llvm.experimental_targets.clone(); config.llvm_link_jobs = llvm.link_jobs; config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); @@ -558,7 +554,6 @@ impl Config { set(&mut config.channel, rust.channel.clone()); set(&mut config.rust_dist_src, rust.dist_src); set(&mut config.verbose_tests, rust.verbose_tests); - set(&mut config.test_miri, rust.test_miri); // in the case "false" is set explicitly, do not overwrite the command line args if let Some(true) = rust.incremental { config.incremental = true; @@ -571,7 +566,7 @@ impl Config { config.rustc_default_linker = rust.default_linker.clone(); config.musl_root = rust.musl_root.clone().map(PathBuf::from); config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from); - set(&mut config.deny_warnings, rust.deny_warnings.or(flags.warnings)); + set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 907983d43a..346f0cb203 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -36,7 +36,6 @@ o("docs", "build.docs", "build standard library documentation") o("compiler-docs", "build.compiler-docs", "build compiler documentation") o("optimize-tests", "rust.optimize-tests", "build tests with optimizations") o("parallel-compiler", "rust.parallel-compiler", "build a multi-threaded rustc") -o("test-miri", "rust.test-miri", "run miri's test suite") o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests") o("ccache", "llvm.ccache", "invoke gcc/clang via ccache to reuse object files between builds") o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds") @@ -125,7 +124,9 @@ v("musl-root-armhf", "target.arm-unknown-linux-musleabihf.musl-root", "arm-unknown-linux-musleabihf install directory") v("musl-root-armv5te", "target.armv5te-unknown-linux-musleabi.musl-root", "armv5te-unknown-linux-musleabi install directory") -v("musl-root-armv7", "target.armv7-unknown-linux-musleabihf.musl-root", +v("musl-root-armv7", "target.armv7-unknown-linux-musleabi.musl-root", + "armv7-unknown-linux-musleabi install directory") +v("musl-root-armv7hf", "target.armv7-unknown-linux-musleabihf.musl-root", "armv7-unknown-linux-musleabihf install directory") v("musl-root-aarch64", "target.aarch64-unknown-linux-musl.musl-root", "aarch64-unknown-linux-musl install directory") diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 45bc77ec97..552965863d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -808,6 +808,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str] "llvm-project/lld", "llvm-project\\lld", "llvm-project/lldb", "llvm-project\\lldb", "llvm-project/llvm", "llvm-project\\llvm", + "llvm-project/compiler-rt", "llvm-project\\compiler-rt", ]; if spath.contains("llvm-project") && !spath.ends_with("llvm-project") && !LLVM_PROJECTS.iter().any(|path| spath.contains(path)) @@ -903,7 +904,7 @@ impl Step for Src { "src/libtest", "src/libterm", "src/libprofiler_builtins", - "src/stdsimd", + "src/stdarch", "src/libproc_macro", "src/tools/rustc-std-workspace-core", "src/tools/rustc-std-workspace-alloc", @@ -935,8 +936,6 @@ impl Step for Src { } } -const CARGO_VENDOR_VERSION: &str = "0.1.22"; - #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] pub struct PlainSourceTarball; @@ -998,26 +997,6 @@ impl Step for PlainSourceTarball { // If we're building from git sources, we need to vendor a complete distribution. if builder.rust_info.is_git() { - // Get cargo-vendor installed, if it isn't already. - let mut has_cargo_vendor = false; - let mut cmd = Command::new(&builder.initial_cargo); - for line in output(cmd.arg("install").arg("--list")).lines() { - has_cargo_vendor |= line.starts_with("cargo-vendor "); - } - if !has_cargo_vendor { - let mut cmd = builder.cargo( - builder.compiler(0, builder.config.build), - Mode::ToolBootstrap, - builder.config.build, - "install" - ); - cmd.arg("--force") - .arg("--debug") - .arg("--vers").arg(CARGO_VENDOR_VERSION) - .arg("cargo-vendor"); - builder.run(&mut cmd); - } - // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("vendor") diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 2969bbf5b0..36229720e4 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -23,7 +23,7 @@ use crate::cache::{INTERNER, Interned}; use crate::config::Config; macro_rules! book { - ($($name:ident, $path:expr, $book_name:expr, $book_ver:expr;)+) => { + ($($name:ident, $path:expr, $book_name:expr;)+) => { $( #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct $name { @@ -49,7 +49,6 @@ macro_rules! book { builder.ensure(RustbookSrc { target: self.target, name: INTERNER.intern_str($book_name), - version: $book_ver, src: doc_src(builder), }) } @@ -61,21 +60,15 @@ macro_rules! book { // NOTE: When adding a book here, make sure to ALSO build the book by // adding a build step in `src/bootstrap/builder.rs`! book!( - EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::Latest; - EmbeddedBook, "src/doc/embedded-book", "embedded-book", RustbookVersion::Latest; - Nomicon, "src/doc/nomicon", "nomicon", RustbookVersion::Latest; - Reference, "src/doc/reference", "reference", RustbookVersion::MdBook1; - RustByExample, "src/doc/rust-by-example", "rust-by-example", RustbookVersion::Latest; - RustcBook, "src/doc/rustc", "rustc", RustbookVersion::MdBook1; - RustdocBook, "src/doc/rustdoc", "rustdoc", RustbookVersion::Latest; + EditionGuide, "src/doc/edition-guide", "edition-guide"; + EmbeddedBook, "src/doc/embedded-book", "embedded-book"; + Nomicon, "src/doc/nomicon", "nomicon"; + Reference, "src/doc/reference", "reference"; + RustByExample, "src/doc/rust-by-example", "rust-by-example"; + RustcBook, "src/doc/rustc", "rustc"; + RustdocBook, "src/doc/rustdoc", "rustdoc"; ); -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -enum RustbookVersion { - MdBook1, - Latest, -} - fn doc_src(builder: &Builder<'_>) -> Interned { INTERNER.intern_path(builder.src.join("src/doc")) } @@ -108,7 +101,6 @@ impl Step for UnstableBook { target: self.target, name: INTERNER.intern_str("unstable-book"), src: builder.md_doc_out(self.target), - version: RustbookVersion::Latest, }) } } @@ -162,7 +154,6 @@ struct RustbookSrc { target: Interned, name: Interned, src: Interned, - version: RustbookVersion, } impl Step for RustbookSrc { @@ -194,18 +185,11 @@ impl Step for RustbookSrc { builder.info(&format!("Rustbook ({}) - {}", target, name)); let _ = fs::remove_dir_all(&out); - let vers = match self.version { - RustbookVersion::MdBook1 => "1", - RustbookVersion::Latest => "3", - }; - builder.run(rustbook_cmd .arg("build") .arg(&src) .arg("-d") - .arg(out) - .arg("-m") - .arg(vers)); + .arg(out)); } } @@ -251,7 +235,6 @@ impl Step for TheBook { builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(name.to_string()), - version: RustbookVersion::Latest, src: doc_src(builder), }); @@ -261,7 +244,6 @@ impl Step for TheBook { builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(source_name), - version: RustbookVersion::Latest, src: doc_src(builder), }); @@ -269,7 +251,6 @@ impl Step for TheBook { builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(source_name), - version: RustbookVersion::Latest, src: doc_src(builder), }); @@ -277,7 +258,6 @@ impl Step for TheBook { builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(source_name), - version: RustbookVersion::Latest, src: doc_src(builder), }); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 179accda0c..828865f10f 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -33,8 +33,11 @@ pub struct Flags { pub rustc_error_format: Option, pub dry_run: bool, - // true => deny - pub warnings: Option, + // This overrides the deny-warnings configuation option, + // which passes -Dwarnings to the compiler invocations. + // + // true => deny, false => allow + pub deny_warnings: Option, } pub enum Subcommand { @@ -327,7 +330,7 @@ Arguments: This subcommand accepts a number of paths to directories to tests that should be compiled and run. For example: - ./x.py test src/test/run-pass + ./x.py test src/test/ui ./x.py test src/libstd --test-args hash_map ./x.py test src/libstd --stage 0 --no-doc ./x.py test src/test/ui --bless @@ -468,7 +471,7 @@ Arguments: .into_iter() .map(|p| p.into()) .collect::>(), - warnings: matches.opt_str("warnings").map(|v| v == "deny"), + deny_warnings: parse_deny_warnings(&matches), } } } @@ -549,3 +552,18 @@ fn split(s: &[String]) -> Vec { .map(|s| s.to_string()) .collect() } + +fn parse_deny_warnings(matches: &getopts::Matches) -> Option { + match matches.opt_str("warnings").as_ref().map(|v| v.as_str()) { + Some("deny") => Some(true), + Some("allow") => Some(false), + Some(value) => { + eprintln!( + r#"invalid value for --warnings: {:?}, expected "allow" or "deny""#, + value, + ); + process::exit(1); + }, + None => None, + } +} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 4d297fa918..b72aa78f3d 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -103,8 +103,9 @@ //! More documentation can be found in each respective module below, and you can //! also check out the `src/bootstrap/README.md` file for more information. -#![deny(rust_2018_idioms)] -#![deny(warnings)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] + #![feature(core_intrinsics)] #![feature(drain_filter)] @@ -124,11 +125,11 @@ use std::os::unix::fs::symlink as symlink_file; use std::os::windows::fs::symlink_file; use build_helper::{ - mtime, output, run_silent, run_suppressed, t, try_run_silent, try_run_suppressed, + mtime, output, run, run_suppressed, t, try_run, try_run_suppressed, }; use filetime::FileTime; -use crate::util::{exe, libdir, OutputFolder, CiEnv}; +use crate::util::{exe, libdir, CiEnv}; mod cc_detect; mod channel; @@ -539,9 +540,7 @@ impl Build { Mode::Rustc => "-rustc", Mode::Codegen => "-codegen", Mode::ToolBootstrap => "-bootstrap-tools", - Mode::ToolStd => "-tools", - Mode::ToolTest => "-tools", - Mode::ToolRustc => "-tools", + Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools", }; self.out.join(&*compiler.host) .join(format!("stage{}{}", compiler.stage, suffix)) @@ -681,7 +680,7 @@ impl Build { fn run(&self, cmd: &mut Command) { if self.config.dry_run { return; } self.verbose(&format!("running: {:?}", cmd)); - run_silent(cmd) + run(cmd) } /// Runs a command, printing out nice contextual information if it fails. @@ -697,7 +696,7 @@ impl Build { fn try_run(&self, cmd: &mut Command) -> bool { if self.config.dry_run { return true; } self.verbose(&format!("running: {:?}", cmd)); - try_run_silent(cmd) + try_run(cmd) } /// Runs a command, printing out nice contextual information if it fails. @@ -1092,19 +1091,6 @@ impl Build { } } - /// Fold the output of the commands after this method into a group. The fold - /// ends when the returned object is dropped. Folding can only be used in - /// the Travis CI environment. - pub fn fold_output(&self, name: F) -> Option - where D: Into, F: FnOnce() -> D - { - if !self.config.dry_run && self.ci_env == CiEnv::Travis { - Some(OutputFolder::new(name().into())) - } else { - None - } - } - /// Updates the actual toolstate of a tool. /// /// The toolstates are saved to the file specified by the key @@ -1325,7 +1311,7 @@ fn chmod(path: &Path, perms: u32) { fn chmod(_path: &Path, _perms: u32) {} -impl<'a> Compiler { +impl Compiler { pub fn with_stage(mut self, stage: u32) -> Compiler { self.stage = stage; self diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index ea05b30ece..73d6fe532c 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -48,10 +48,8 @@ check: $(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS) check-aux: $(Q)$(BOOTSTRAP) test \ - src/test/run-pass/pretty \ src/test/run-fail/pretty \ src/test/run-pass-valgrind/pretty \ - src/test/run-pass-fulldeps/pretty \ $(AUX_ARGS) \ $(BOOTSTRAP_ARGS) check-bootstrap: @@ -75,9 +73,7 @@ check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu: TESTS_IN_2 := \ src/test/ui \ - src/test/run-pass \ src/test/compile-fail \ - src/test/run-pass-fulldeps \ src/tools/linkchecker ci-subset-1: diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 8b6e856a8a..f02def3e1b 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -104,7 +104,6 @@ impl Step for Llvm { } } - let _folder = builder.fold_output(|| "llvm"); let descriptor = if emscripten { "Emscripten " } else { "" }; builder.info(&format!("Building {}LLVM for {}", descriptor, target)); let _time = util::timeit(&builder); @@ -126,14 +125,18 @@ impl Step for Llvm { } else { match builder.config.llvm_targets { Some(ref s) => s, - None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;MSP430;Sparc;NVPTX;Hexagon", + None => "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\ + Sparc;SystemZ;WebAssembly;X86", } }; let llvm_exp_targets = if self.emscripten { "" } else { - &builder.config.llvm_experimental_targets[..] + match builder.config.llvm_experimental_targets { + Some(ref s) => s, + None => "", + } }; let assertions = if builder.config.llvm_assertions {"ON"} else {"OFF"}; @@ -151,6 +154,7 @@ impl Step for Llvm { .define("WITH_POLLY", "OFF") .define("LLVM_ENABLE_TERMINFO", "OFF") .define("LLVM_ENABLE_LIBEDIT", "OFF") + .define("LLVM_ENABLE_Z3_SOLVER", "OFF") .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string()) .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap()) .define("LLVM_DEFAULT_TARGET_TRIPLE", target); @@ -493,7 +497,6 @@ impl Step for Lld { return out_dir } - let _folder = builder.fold_output(|| "lld"); builder.info(&format!("Building LLD for {}", target)); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -548,7 +551,7 @@ impl Step for TestHelpers { } /// Compiles the `rust_test_helpers.c` library which we used in various - /// `run-pass` test suites for ABI testing. + /// `run-pass` tests for ABI testing. fn run(self, builder: &Builder<'_>) { if builder.config.dry_run { return; @@ -560,7 +563,6 @@ impl Step for TestHelpers { return } - let _folder = builder.fold_output(|| "build_test_helpers"); builder.info("Building test helpers"); t!(fs::create_dir_all(&dst)); let mut cfg = cc::Build::new(); diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index dc65fb9b79..4e3930c8da 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -78,8 +78,11 @@ pub fn check(build: &mut Build) { // We need cmake, but only if we're actually building LLVM or sanitizers. let building_llvm = build.hosts.iter() - .filter_map(|host| build.config.target_config.get(host)) - .any(|config| config.llvm_config.is_none()); + .map(|host| build.config.target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true)) + .any(|build_llvm_ourselves| build_llvm_ourselves); if building_llvm || build.config.sanitizers { cmd_finder.must_have("cmake"); } @@ -106,6 +109,14 @@ pub fn check(build: &mut Build) { build.config.ninja = true; } } + + if build.config.lldb_enabled { + cmd_finder.must_have("swig"); + let out = output(Command::new("swig").arg("-version")); + if !out.contains("SWIG Version 3") && !out.contains("SWIG Version 4") { + panic!("Ensure that Swig 3.x.x or 4.x.x is installed."); + } + } } build.config.python = build.config.python.take().map(|p| cmd_finder.must_have(p)) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 1d54ca16a3..c2c134bfd1 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -229,6 +229,9 @@ impl Step for Cargo { cargo.env("CFG_DISABLE_CROSS_TESTS", "1"); // Disable a test that has issues with mingw. cargo.env("CARGO_TEST_DISABLE_GIT_CLI", "1"); + // Forcibly disable tests using nightly features since any changes to + // those features won't be able to land. + cargo.env("CARGO_TEST_DISABLE_NIGHTLY", "1"); try_run( builder, @@ -360,11 +363,9 @@ pub struct Miri { impl Step for Miri { type Output = (); const ONLY_HOSTS: bool = true; - const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let test_miri = run.builder.config.test_miri; - run.path("src/tools/miri").default_condition(test_miri) + run.path("src/tools/miri") } fn make_run(run: RunConfig<'_>) { @@ -386,26 +387,92 @@ impl Step for Miri { extra_features: Vec::new(), }); if let Some(miri) = miri { - let mut cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - host, - "test", - "src/tools/miri", - SourceType::Submodule, - &[]); + // # Run `cargo miri setup`. + // As a side-effect, this will install xargo. + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "run", + "src/tools/miri", + SourceType::Submodule, + &[], + ); + cargo + .arg("--bin") + .arg("cargo-miri") + .arg("--") + .arg("miri") + .arg("setup"); + + // Tell `cargo miri` not to worry about the sysroot mismatch (we built with + // stage1 but run with stage2). + cargo.env("MIRI_SKIP_SYSROOT_CHECK", "1"); + // Tell `cargo miri setup` where to find the sources. + cargo.env("XARGO_RUST_SRC", builder.src.join("src")); + // Debug things. + cargo.env("RUST_BACKTRACE", "1"); + // Configure `cargo install` path, and let cargo-miri know that that's where + // xargo ends up. + cargo.env("CARGO_INSTALL_ROOT", &builder.out); // cargo adds a `bin/` + cargo.env("XARGO", builder.out.join("bin").join("xargo")); + + if !try_run(builder, &mut cargo) { + return; + } + + // # Determine where Miri put its sysroot. + // To this end, we run `cargo miri setup --env` and capture the output. + // (We do this separately from the above so that when the setup actually + // happens we get some output.) + // We re-use the `cargo` from above. + cargo.arg("--env"); + + // FIXME: Is there a way in which we can re-use the usual `run` helpers? + let miri_sysroot = if builder.config.dry_run { + String::new() + } else { + builder.verbose(&format!("running: {:?}", cargo)); + let out = cargo.output() + .expect("We already ran `cargo miri setup` before and that worked"); + assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code"); + // Output is "MIRI_SYSROOT=\n". + let stdout = String::from_utf8(out.stdout) + .expect("`cargo miri setup` stdout is not valid UTF-8"); + let stdout = stdout.trim(); + builder.verbose(&format!("`cargo miri setup --env` returned: {:?}", stdout)); + let sysroot = stdout.splitn(2, '=') + .nth(1).expect("`cargo miri setup` stdout did not contain '='"); + sysroot.to_owned() + }; + + // # Run `cargo test`. + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/miri", + SourceType::Submodule, + &[], + ); // miri tests need to know about the stage sysroot - cargo.env("MIRI_SYSROOT", builder.sysroot(compiler)); + cargo.env("MIRI_SYSROOT", miri_sysroot); cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler)); cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler)); cargo.env("MIRI_PATH", miri); builder.add_rustc_lib_path(compiler, &mut cargo); - if try_run(builder, &mut cargo) { - builder.save_toolstate("miri", ToolState::TestPass); + if !try_run(builder, &mut cargo) { + return; } + + // # Done! + builder.save_toolstate("miri", ToolState::TestPass); } else { eprintln!("failed to test miri: could not build"); } @@ -713,7 +780,6 @@ impl Step for Tidy { cmd.arg("--verbose"); } - let _folder = builder.fold_output(|| "tidy"); builder.info("tidy check"); try_run(builder, &mut cmd); } @@ -821,13 +887,6 @@ default_test_with_compare_mode!(Ui { compare_mode: "nll" }); -default_test_with_compare_mode!(RunPass { - path: "src/test/run-pass", - mode: "run-pass", - suite: "run-pass", - compare_mode: "nll" -}); - default_test!(CompileFail { path: "src/test/compile-fail", mode: "compile-fail", @@ -882,12 +941,6 @@ host_test!(UiFullDeps { suite: "ui-fulldeps" }); -host_test!(RunPassFullDeps { - path: "src/test/run-pass-fulldeps", - mode: "run-pass", - suite: "run-pass-fulldeps" -}); - host_test!(Rustdoc { path: "src/test/rustdoc", mode: "rustdoc", @@ -899,13 +952,6 @@ host_test!(Pretty { mode: "pretty", suite: "pretty" }); -test!(RunPassPretty { - path: "src/test/run-pass/pretty", - mode: "pretty", - suite: "run-pass", - default: false, - host: true -}); test!(RunFailPretty { path: "src/test/run-fail/pretty", mode: "pretty", @@ -1310,7 +1356,6 @@ impl Step for Compiletest { builder.ci_env.force_coloring_in_ci(&mut cmd); - let _folder = builder.fold_output(|| format!("test_{}", suite)); builder.info(&format!( "Check compiletest suite={} mode={} ({} -> {})", suite, mode, &compiler.host, target @@ -1320,7 +1365,6 @@ impl Step for Compiletest { if let Some(compare_mode) = compare_mode { cmd.arg("--compare-mode").arg(compare_mode); - let _folder = builder.fold_output(|| format!("test_{}_{}", suite, compare_mode)); builder.info(&format!( "Check compiletest suite={} mode={} compare_mode={} ({} -> {})", suite, mode, compare_mode, &compiler.host, target @@ -1364,7 +1408,6 @@ impl Step for DocTest { // tests for all files that end in `*.md` let mut stack = vec![builder.src.join(self.path)]; let _time = util::timeit(&builder); - let _folder = builder.fold_output(|| format!("test_{}", self.name)); let mut files = Vec::new(); while let Some(p) = stack.pop() { @@ -1495,10 +1538,9 @@ impl Step for ErrorIndex { .env("CFG_BUILD", &builder.config.build) .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir()); - let _folder = builder.fold_output(|| "test_error_index"); builder.info(&format!("Testing error-index stage{}", compiler.stage)); let _time = util::timeit(&builder); - builder.run(&mut tool); + builder.run_quiet(&mut tool); markdown_test(builder, compiler, &output); } } @@ -1530,6 +1572,34 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> } } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct RustcGuide; + +impl Step for RustcGuide { + type Output = (); + const DEFAULT: bool = false; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/doc/rustc-guide") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(RustcGuide); + } + + fn run(self, builder: &Builder<'_>) { + let src = builder.src.join("src/doc/rustc-guide"); + let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); + let toolstate = if try_run(builder, rustbook_cmd.arg("linkcheck").arg(&src)) { + ToolState::TestPass + } else { + ToolState::TestFail + }; + builder.save_toolstate("rustc-guide", toolstate); + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrateLibrustc { compiler: Compiler, @@ -1794,14 +1864,6 @@ impl Step for Crate { ); } - let _folder = builder.fold_output(|| { - format!( - "{}_stage{}-{}", - test_kind.subcommand(), - compiler.stage, - krate - ) - }); builder.info(&format!( "{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage, &compiler.host, target @@ -1869,8 +1931,6 @@ impl Step for CrateRustdoc { cargo.arg("--quiet"); } - let _folder = builder - .fold_output(|| format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage)); builder.info(&format!( "{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage, &compiler.host, target diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index bd77f7a91d..df7eb7c455 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -9,7 +9,7 @@ use build_helper::t; use crate::Mode; use crate::Compiler; use crate::builder::{Step, RunConfig, ShouldRun, Builder}; -use crate::util::{exe, add_lib_path}; +use crate::util::{exe, add_lib_path, CiEnv}; use crate::compile; use crate::channel::GitInfo; use crate::channel; @@ -74,7 +74,6 @@ impl Step for ToolBuild { &self.extra_features, ); - let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target)); let mut duplicates = Vec::new(); let is_expected = compile::stream_cargo(builder, &mut cargo, vec![], &mut |msg| { @@ -109,36 +108,63 @@ impl Step for ToolBuild { continue } - // Don't worry about libs that turn out to be host dependencies - // or build scripts, we only care about target dependencies that - // are in `deps`. - if let Some(maybe_target) = val.1 - .parent() // chop off file name - .and_then(|p| p.parent()) // chop off `deps` - .and_then(|p| p.parent()) // chop off `release` - .and_then(|p| p.file_name()) - .and_then(|p| p.to_str()) - { - if maybe_target != &*target { - continue + // Don't worry about compiles that turn out to be host + // dependencies or build scripts. To skip these we look for + // anything that goes in `.../release/deps` but *doesn't* go in + // `$target/release/deps`. This ensure that outputs in + // `$target/release` are still considered candidates for + // deduplication. + if let Some(parent) = val.1.parent() { + if parent.ends_with("release/deps") { + let maybe_target = parent + .parent() + .and_then(|p| p.parent()) + .and_then(|p| p.file_name()) + .and_then(|p| p.to_str()) + .unwrap(); + if maybe_target != &*target { + continue; + } } } + // Record that we've built an artifact for `id`, and if one was + // already listed then we need to see if we reused the same + // artifact or produced a duplicate. let mut artifacts = builder.tool_artifacts.borrow_mut(); let prev_artifacts = artifacts .entry(target) .or_default(); - if let Some(prev) = prev_artifacts.get(&*id) { - if prev.1 != val.1 { - duplicates.push(( - id.to_string(), - val, - prev.clone(), - )); + let prev = match prev_artifacts.get(&*id) { + Some(prev) => prev, + None => { + prev_artifacts.insert(id.to_string(), val); + continue; } - return + }; + if prev.1 == val.1 { + return; // same path, same artifact } - prev_artifacts.insert(id.to_string(), val); + + // If the paths are different and one of them *isn't* inside of + // `release/deps`, then it means it's probably in + // `$target/release`, or it's some final artifact like + // `libcargo.rlib`. In these situations Cargo probably just + // copied it up from `$target/release/deps/libcargo-xxxx.rlib`, + // so if the features are equal we can just skip it. + let prev_no_hash = prev.1.parent().unwrap().ends_with("release/deps"); + let val_no_hash = val.1.parent().unwrap().ends_with("release/deps"); + if prev.2 == val.2 || !prev_no_hash || !val_no_hash { + return; + } + + // ... and otherwise this looks like we duplicated some sort of + // compilation, so record it to generate an error later. + duplicates.push(( + id.to_string(), + val, + prev.clone(), + )); } }); @@ -253,11 +279,26 @@ pub fn prepare_tool_cargo( cargo } +fn rustbook_features() -> Vec { + let mut features = Vec::new(); + + // Due to CI budged and risk of spurious failures we want to limit jobs running this check. + // At same time local builds should run it regardless of the platform. + // `CiEnv::None` means it's local build and `CHECK_LINKS` is defined in x86_64-gnu-tools to + // explicitly enable it on single job + if CiEnv::current() == CiEnv::None || env::var("CHECK_LINKS").is_ok() { + features.push("linkcheck".to_string()); + } + + features +} + macro_rules! bootstrap_tool { ($( $name:ident, $path:expr, $tool_name:expr $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)* + $(,features = $features:expr)* ; )+) => { #[derive(Copy, PartialEq, Eq, Clone)] @@ -324,7 +365,12 @@ macro_rules! bootstrap_tool { } else { SourceType::InTree }, - extra_features: Vec::new(), + extra_features: { + // FIXME(#60643): avoid this lint by using `_` + let mut _tmp = Vec::new(); + $(_tmp.extend($features);)* + _tmp + }, }).expect("expected to build -- essential tool") } } @@ -333,7 +379,7 @@ macro_rules! bootstrap_tool { } bootstrap_tool!( - Rustbook, "src/tools/rustbook", "rustbook"; + Rustbook, "src/tools/rustbook", "rustbook", features = rustbook_features(); UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen"; Tidy, "src/tools/tidy", "tidy"; Linkchecker, "src/tools/linkchecker", "linkchecker"; @@ -482,7 +528,6 @@ impl Step for Rustdoc { &[], ); - let _folder = builder.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); builder.info(&format!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host)); builder.run(&mut cargo); diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 47f5edd156..98ae7b692b 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -6,10 +6,10 @@ use std::env; use std::str; use std::fs; -use std::io::{self, Write}; +use std::io; use std::path::{Path, PathBuf}; use std::process::Command; -use std::time::{SystemTime, Instant}; +use std::time::Instant; use build_helper::t; @@ -254,78 +254,12 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { } } -/// An RAII structure that indicates all output until this instance is dropped -/// is part of the same group. -/// -/// On Travis CI, these output will be folded by default, together with the -/// elapsed time in this block. This reduces noise from unnecessary logs, -/// allowing developers to quickly identify the error. -/// -/// Travis CI supports folding by printing `travis_fold:start:` and -/// `travis_fold:end:` around the block. Time elapsed is recognized -/// similarly with `travis_time:[start|end]:`. These are undocumented, but -/// can easily be deduced from source code of the [Travis build commands]. -/// -/// [Travis build commands]: -/// https://github.com/travis-ci/travis-build/blob/f603c0089/lib/travis/build/templates/header.sh -pub struct OutputFolder { - name: String, - start_time: SystemTime, // we need SystemTime to get the UNIX timestamp. -} - -impl OutputFolder { - /// Creates a new output folder with the given group name. - pub fn new(name: String) -> OutputFolder { - // "\r" moves the cursor to the beginning of the line, and "\x1b[0K" is - // the ANSI escape code to clear from the cursor to end of line. - // Travis seems to have trouble when _not_ using "\r\x1b[0K", that will - // randomly put lines to the top of the webpage. - print!("travis_fold:start:{0}\r\x1b[0Ktravis_time:start:{0}\r\x1b[0K", name); - OutputFolder { - name, - start_time: SystemTime::now(), - } - } -} - -impl Drop for OutputFolder { - fn drop(&mut self) { - use std::time::*; - use std::u64; - - fn to_nanos(duration: Result) -> u64 { - match duration { - Ok(d) => d.as_secs() * 1_000_000_000 + d.subsec_nanos() as u64, - Err(_) => u64::MAX, - } - } - - let end_time = SystemTime::now(); - let duration = end_time.duration_since(self.start_time); - let start = self.start_time.duration_since(UNIX_EPOCH); - let finish = end_time.duration_since(UNIX_EPOCH); - println!( - "travis_fold:end:{0}\r\x1b[0K\n\ - travis_time:end:{0}:start={1},finish={2},duration={3}\r\x1b[0K", - self.name, - to_nanos(start), - to_nanos(finish), - to_nanos(duration) - ); - io::stdout().flush().unwrap(); - } -} - /// The CI environment rustbuild is running in. This mainly affects how the logs /// are printed. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum CiEnv { /// Not a CI environment. None, - /// The Travis CI environment, for Linux (including Docker) and macOS builds. - Travis, - /// The AppVeyor environment, for Windows builds. - AppVeyor, /// The Azure Pipelines environment, for Linux (including Docker), Windows, and macOS builds. AzurePipelines, } @@ -333,11 +267,7 @@ pub enum CiEnv { impl CiEnv { /// Obtains the current CI environment. pub fn current() -> CiEnv { - if env::var("TRAVIS").ok().map_or(false, |e| &*e == "true") { - CiEnv::Travis - } else if env::var("APPVEYOR").ok().map_or(false, |e| &*e == "True") { - CiEnv::AppVeyor - } else if env::var("TF_BUILD").ok().map_or(false, |e| &*e == "True") { + if env::var("TF_BUILD").ok().map_or(false, |e| &*e == "True") { CiEnv::AzurePipelines } else { CiEnv::None diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 8b00c1d81b..a1aa18922b 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,4 +1,5 @@ -#![deny(rust_2018_idioms)] +// NO-RUSTC-WRAPPER +#![deny(warnings, rust_2018_idioms, unused_lifetimes)] use std::fs::File; use std::path::{Path, PathBuf}; @@ -44,18 +45,19 @@ pub fn restore_library_path() { } } -pub fn run(cmd: &mut Command) { +/// Run the command, printing what we are running. +pub fn run_verbose(cmd: &mut Command) { println!("running: {:?}", cmd); - run_silent(cmd); + run(cmd); } -pub fn run_silent(cmd: &mut Command) { - if !try_run_silent(cmd) { +pub fn run(cmd: &mut Command) { + if !try_run(cmd) { std::process::exit(1); } } -pub fn try_run_silent(cmd: &mut Command) -> bool { +pub fn try_run(cmd: &mut Command) -> bool { let status = match cmd.status() { Ok(status) => status, Err(e) => fail(&format!( diff --git a/src/ci/awscli-requirements.txt b/src/ci/awscli-requirements.txt deleted file mode 100644 index c1ffa525a1..0000000000 --- a/src/ci/awscli-requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -awscli==1.16.201 -botocore==1.12.191 -colorama==0.3.9 -docutils==0.14 -jmespath==0.9.4 -pyasn1==0.4.5 -python-dateutil==2.8.0 -PyYAML==5.1 -rsa==3.4.2 -s3transfer==0.2.1 -six==1.12.0 -urllib3==1.25.3 -futures==3.3.0; python_version < '3.0' diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 2e6c3b7a99..0c7c734e58 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -7,7 +7,7 @@ trigger: - auto variables: -- group: real-prod-credentials +- group: prod-credentials jobs: - job: Linux @@ -174,7 +174,7 @@ jobs: dist-x86_64-apple: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb --set rust.jemalloc + RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc DEPLOY: 1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -184,7 +184,7 @@ jobs: dist-x86_64-apple-alt: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --enable-lldb --set rust.jemalloc + RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc DEPLOY_ALT: 1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -202,7 +202,7 @@ jobs: dist-i686-apple: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --build=i686-apple-darwin --enable-full-tools --enable-profiler --enable-lldb --set rust.jemalloc + RUST_CONFIGURE_ARGS: --build=i686-apple-darwin --enable-full-tools --enable-profiler --set rust.jemalloc DEPLOY: 1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -254,7 +254,7 @@ jobs: x86_64-msvc-tools: MSYS_BITS: 64 SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json # 32/64-bit MinGW builds. # @@ -273,7 +273,7 @@ jobs: MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-subset-1 - MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 # FIXME(#59637) @@ -283,14 +283,14 @@ jobs: MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-subset-2 - MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 x86_64-mingw-1: MSYS_BITS: 64 SCRIPT: make ci-subset-1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu - MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 # FIXME(#59637) @@ -300,7 +300,7 @@ jobs: MSYS_BITS: 64 SCRIPT: make ci-subset-2 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu - MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 @@ -327,7 +327,7 @@ jobs: MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler SCRIPT: python x.py dist - MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 DIST_REQUIRE_ALL_TOOLS: 1 @@ -336,7 +336,7 @@ jobs: MSYS_BITS: 64 SCRIPT: python x.py dist RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler - MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 DIST_REQUIRE_ALL_TOOLS: 1 diff --git a/src/ci/azure-pipelines/master.yml b/src/ci/azure-pipelines/master.yml index 9742c71965..e2baa923d9 100644 --- a/src/ci/azure-pipelines/master.yml +++ b/src/ci/azure-pipelines/master.yml @@ -7,7 +7,7 @@ trigger: - master variables: -- group: real-prod-credentials +- group: prod-credentials pool: vmImage: ubuntu-16.04 diff --git a/src/ci/azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml index 88b5067b4a..62e23efe1e 100644 --- a/src/ci/azure-pipelines/pr.yml +++ b/src/ci/azure-pipelines/pr.yml @@ -6,6 +6,9 @@ trigger: none pr: - master +variables: +- group: public-credentials + jobs: - job: Linux timeoutInMinutes: 600 @@ -20,14 +23,13 @@ jobs: mingw-check: IMAGE: mingw-check -# TODO: enable this job if the commit message matches this regex, need tools -# figure out how to get the current commit message on azure and stick it in a -# condition somewhere -# if: commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/ -# - job: Linux-x86_64-gnu-tools -# pool: -# vmImage: ubuntu-16.04 -# steps: -# - template: steps/run.yml -# variables: -# IMAGE: x86_64-gnu-tools +- job: LinuxTools + timeoutInMinutes: 600 + pool: + vmImage: ubuntu-16.04 + steps: + - template: steps/run.yml + parameters: + only_on_updated_submodules: 'yes' + variables: + IMAGE: x86_64-gnu-tools diff --git a/src/ci/azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml index 0cd6f24e32..14daf81b43 100644 --- a/src/ci/azure-pipelines/steps/install-clang.yml +++ b/src/ci/azure-pipelines/steps/install-clang.yml @@ -26,12 +26,18 @@ steps: # # Original downloaded here came from # http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe -- script: | - powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf %TEMP%\LLVM-7.0.0-win64.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-7.0.0-win64.exe" - set CLANG_DIR=%CD%\citools\clang-rust - %TEMP%\LLVM-7.0.0-win64.exe /S /NCRC /D=%CLANG_DIR% - set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --set llvm.clang-cl=%CLANG_DIR%\bin\clang-cl.exe - echo ##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]%RUST_CONFIGURE_ARGS% +# That installer was run through `wine` on Linux and then the resulting +# installation directory (found in `$HOME/.wine/drive_c/Program Files/LLVM`) was +# packaged up into a tarball. We've had issues otherwise that the installer will +# randomly hang, provide not a lot of useful information, pollute global state, +# etc. In general the tarball is just more confined and easier to deal with when +# working with various CI environments. +- bash: | + set -e + mkdir -p citools + cd citools + curl -f https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/LLVM-7.0.0-win64.tar.gz | tar xzf - + echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --set llvm.clang-cl=`pwd`/clang-rust/bin/clang-cl.exe" condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],'')) displayName: Install clang (Windows) diff --git a/src/ci/azure-pipelines/steps/install-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml index 427e50f571..d4679c1c67 100644 --- a/src/ci/azure-pipelines/steps/install-sccache.yml +++ b/src/ci/azure-pipelines/steps/install-sccache.yml @@ -2,14 +2,14 @@ steps: - bash: | set -e - curl -fo /usr/local/bin/sccache https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin + curl -fo /usr/local/bin/sccache https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-apple-darwin chmod +x /usr/local/bin/sccache displayName: Install sccache (OSX) condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) - script: | md sccache - powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-26-sccache-x86_64-pc-windows-msvc" + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-26-sccache-x86_64-pc-windows-msvc" echo ##vso[task.prependpath]%CD%\sccache displayName: Install sccache (Windows) condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml index ed06679464..9aaeb4b79d 100644 --- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml +++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml @@ -1,4 +1,29 @@ steps: +# We use the WIX toolset to create combined installers for Windows, and these +# binaries are downloaded from +# https://github.com/wixtoolset/wix3 originally +- bash: | + set -e + curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/wix311-binaries.zip + echo "##vso[task.setvariable variable=WIX]`pwd`/wix" + mkdir -p wix/bin + cd wix/bin + 7z x ../../wix311-binaries.zip + displayName: Install wix + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + +# We use InnoSetup and its `iscc` program to also create combined installers. +# Honestly at this point WIX above and `iscc` are just holdovers from +# oh-so-long-ago and are required for creating installers on Windows. I think +# one is MSI installers and one is EXE, but they're not used so frequently at +# this point anyway so perhaps it's a wash! +- script: | + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe" + is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- + echo ##vso[task.prependpath]C:\Program Files (x86)\Inno Setup 5 + displayName: Install InnoSetup + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + # We've had issues with the default drive in use running out of space during a # build, and it looks like the `C:` drive has more space than the default `D:` # drive. We should probably confirm this with the azure pipelines team at some @@ -84,7 +109,7 @@ steps: # Note that this is originally from the github releases patch of Ninja - script: | md ninja - powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-03-15-ninja-win.zip" + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip" 7z x -oninja 2017-03-15-ninja-win.zip del 2017-03-15-ninja-win.zip set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index ab990575f9..a8791b4b3d 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -6,6 +6,11 @@ # # Check travis config for `gdb --batch` command to print all crash logs +parameters: + # When this parameter is set to anything other than an empty string the tests + # will only be executed when the commit updates submodules + only_on_updated_submodules: '' + steps: # Disable automatic line ending conversion, which is enabled by default on @@ -21,6 +26,22 @@ steps: - checkout: self fetchDepth: 2 +# Set the SKIP_JOB environment variable if this job is supposed to only run +# when submodules are updated and they were not. The following time consuming +# tasks will be skipped when the environment variable is present. +- ${{ if parameters.only_on_updated_submodules }}: + - bash: | + set -e + # Submodules pseudo-files inside git have the 160000 permissions, so when + # those files are present in the diff a submodule was updated. + if git diff HEAD^ | grep "^index .* 160000" >/dev/null 2>&1; then + echo "Executing the job since submodules are updated" + else + echo "Not executing this job since no submodules were updated" + echo "##vso[task.setvariable variable=SKIP_JOB;]1" + fi + displayName: Decide whether to run this job + # Spawn a background process to collect CPU usage statistics which we'll upload # at the end of the build. See the comments in the script here for more # information. @@ -30,10 +51,6 @@ steps: - bash: printenv | sort displayName: Show environment variables -# Log the date, even on failure. Attempting to debug SSL certificate errors. -- bash: date - displayName: Print out date (before build) - - bash: | set -e df -h @@ -45,17 +62,6 @@ steps: - template: install-sccache.yml - template: install-clang.yml -# Install some dependencies needed to build LLDB/Clang, currently only needed -# during the `dist` target -- bash: | - set -e - brew update - brew install xz - brew install swig@3 - brew link --force swig@3 - displayName: Install build dependencies (OSX) - condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'), eq(variables['SCRIPT'],'./x.py dist')) - # Switch to XCode 9.3 on OSX since it seems to be the last version that supports # i686-apple-darwin. We'll eventually want to upgrade this and it will probably # force us to drop i686-apple-darwin, but let's keep the wheels turning for now. @@ -75,7 +81,7 @@ steps: echo '{"ipv6":true,"fixed-cidr-v6":"fd9a:8454:6789:13f7::/64"}' | sudo tee /etc/docker/daemon.json sudo service docker restart displayName: Enable IPv6 - condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) + condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['Agent.OS'], 'Linux')) # Disable automatic line ending conversion (again). On Windows, when we're # installing dependencies, something switches the git configuration directory or @@ -91,12 +97,12 @@ steps: set -e mkdir -p $HOME/rustsrc $BUILD_SOURCESDIRECTORY/src/ci/init_repo.sh . $HOME/rustsrc - condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT')) + condition: and(succeeded(), not(variables.SKIP_JOB), ne(variables['Agent.OS'], 'Windows_NT')) displayName: Check out submodules (Unix) - script: | - if not exist D:\cache\rustsrc\NUL mkdir D:\cache\rustsrc - sh src/ci/init_repo.sh . /d/cache/rustsrc - condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc + sh src/ci/init_repo.sh . /c/cache/rustsrc + condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['Agent.OS'], 'Windows_NT')) displayName: Check out submodules (Windows) # See also the disable for autocrlf above, this just checks that it worked @@ -121,21 +127,17 @@ steps: # Ensure the `aws` CLI is installed so we can deploy later on, cache docker # images, etc. -- bash: | - set -e - source src/ci/shared.sh - sudo apt-get install -y python3-setuptools - retry pip3 install -r src/ci/awscli-requirements.txt --upgrade --user - echo "##vso[task.prependpath]$HOME/.local/bin" - displayName: Install awscli (Linux) - condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) -- script: pip install -r src/ci/awscli-requirements.txt - displayName: Install awscli (non-Linux) - condition: and(succeeded(), ne(variables['Agent.OS'], 'Linux')) +- bash: src/ci/install-awscli.sh + env: + AGENT_OS: $(Agent.OS) + condition: and(succeeded(), not(variables.SKIP_JOB)) + displayName: Install awscli # Configure our CI_JOB_NAME variable which log analyzers can use for the main # step to see what's going on. -- bash: echo "##vso[task.setvariable variable=CI_JOB_NAME]$SYSTEM_JOBNAME" +- bash: | + builder=$(echo $AGENT_JOBNAME | cut -d ' ' -f 2) + echo "##vso[task.setvariable variable=CI_JOB_NAME]$builder" displayName: Configure Job Name # As a quick smoke check on the otherwise very fast mingw-check linux builder @@ -147,7 +149,7 @@ steps: python2.7 "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" "" cd .. rm -rf rust-toolstate - condition: and(succeeded(), eq(variables['IMAGE'], 'mingw-check')) + condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check')) displayName: Verify the publish_toolstate script works - bash: | @@ -166,8 +168,10 @@ steps: env: CI: true SRC: . - AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) + AWS_ACCESS_KEY_ID: $(SCCACHE_AWS_ACCESS_KEY_ID) + AWS_SECRET_ACCESS_KEY: $(SCCACHE_AWS_SECRET_ACCESS_KEY) TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) + condition: and(succeeded(), not(variables.SKIP_JOB)) displayName: Run build # If we're a deploy builder, use the `aws` command to publish everything to our @@ -189,8 +193,9 @@ steps: fi retry aws s3 cp --no-progress --recursive --acl public-read ./$upload_dir s3://$DEPLOY_BUCKET/$deploy_dir/$BUILD_SOURCEVERSION env: - AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) - condition: and(succeeded(), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1'))) + AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID) + AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY) + condition: and(succeeded(), not(variables.SKIP_JOB), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1'))) displayName: Upload artifacts # Upload CPU usage statistics that we've been gathering this whole time. Always @@ -198,12 +203,8 @@ steps: # errors here ever fail the build since this is just informational. - bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$SYSTEM_JOBNAME.csv env: - AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) - condition: variables['AWS_SECRET_ACCESS_KEY'] + AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID) + AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY) + condition: variables['UPLOAD_AWS_SECRET_ACCESS_KEY'] continueOnError: true displayName: Upload CPU usage statistics - -# Log the date, even on failure. Attempting to debug SSL certificate errors. -- bash: date - continueOnError: true - displayName: Print out date (after build) diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index 6a22e57c12..c919b1023a 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -3,7 +3,7 @@ trigger: - try variables: -- group: real-prod-credentials +- group: prod-credentials jobs: - job: Linux @@ -36,7 +36,7 @@ jobs: # matrix: # dist-x86_64-apple: # SCRIPT: ./x.py dist -# RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb --set rust.jemalloc +# RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc # DEPLOY: 1 # RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -46,7 +46,7 @@ jobs: # # dist-x86_64-apple-alt: # SCRIPT: ./x.py dist -# RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --enable-lldb --set rust.jemalloc +# RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc # DEPLOY_ALT: 1 # RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # MACOSX_DEPLOYMENT_TARGET: 10.7 diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 34320ab441..367e438499 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -20,7 +20,7 @@ Images will output artifacts in an `obj` dir at the root of a repository. - Each directory, excluding `scripts` and `disabled`, corresponds to a docker image - `scripts` contains files shared by docker images -- `disabled` contains images that are not built on travis +- `disabled` contains images that are not built on CI ## Docker Toolbox on Windows diff --git a/src/ci/docker/armhf-gnu/Dockerfile b/src/ci/docker/armhf-gnu/Dockerfile index 235920833f..9493b33698 100644 --- a/src/ci/docker/armhf-gnu/Dockerfile +++ b/src/ci/docker/armhf-gnu/Dockerfile @@ -72,7 +72,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static # TODO: What is this?! # Source of the file: https://github.com/vfdev-5/qemu-rpi2-vexpress/raw/master/vexpress-v2p-ca15-tc1.dtb -RUN curl -O https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/vexpress-v2p-ca15-tc1.dtb +RUN curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/vexpress-v2p-ca15-tc1.dtb COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile index 01d6fce341..3abaab6b34 100644 --- a/src/ci/docker/asmjs/Dockerfile +++ b/src/ci/docker/asmjs/Dockerfile @@ -32,7 +32,7 @@ ENV TARGETS=asmjs-unknown-emscripten ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests ENV SCRIPT python2.7 ../x.py test --target $TARGETS \ - src/test/run-pass \ + src/test/ui \ src/test/run-fail \ src/libstd \ src/liballoc \ diff --git a/src/ci/docker/dist-powerpc-linux/Dockerfile b/src/ci/docker/dist-powerpc-linux/Dockerfile index f03aff060c..8c052db1b0 100644 --- a/src/ci/docker/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc-linux/Dockerfile @@ -36,7 +36,3 @@ ENV HOSTS=powerpc-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS - -# FIXME(#36150) this will fail the bootstrap. Probably means something bad is -# happening! -ENV NO_LLVM_ASSERTIONS 1 diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 5ab4be328a..ae2ea8ef95 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -64,7 +64,7 @@ RUN env \ env \ CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \ CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv7-a" \ - bash musl.sh armv7 && \ + bash musl.sh armv7hf && \ env \ CC=aarch64-linux-gnu-gcc \ CXX=aarch64-linux-gnu-g++ \ @@ -104,7 +104,9 @@ ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu -ENV TARGETS=$TARGETS,x86_64-unknown-redox +# FIXME: temporarily disable the redox builder, +# see: https://github.com/rust-lang/rust/issues/63160 +# ENV TARGETS=$TARGETS,x86_64-unknown-redox ENV TARGETS=$TARGETS,thumbv6m-none-eabi ENV TARGETS=$TARGETS,thumbv7m-none-eabi ENV TARGETS=$TARGETS,thumbv7em-none-eabi @@ -112,6 +114,7 @@ ENV TARGETS=$TARGETS,thumbv7em-none-eabihf ENV TARGETS=$TARGETS,thumbv8m.base-none-eabi ENV TARGETS=$TARGETS,thumbv8m.main-none-eabi ENV TARGETS=$TARGETS,thumbv8m.main-none-eabihf +ENV TARGETS=$TARGETS,riscv32i-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf @@ -134,7 +137,7 @@ ENV RUST_CONFIGURE_ARGS \ --musl-root-armv5te=/musl-armv5te \ --musl-root-arm=/musl-arm \ --musl-root-armhf=/musl-armhf \ - --musl-root-armv7=/musl-armv7 \ + --musl-root-armv7hf=/musl-armv7hf \ --musl-root-aarch64=/musl-aarch64 \ --musl-root-mips=/musl-mips \ --musl-root-mipsel=/musl-mipsel \ diff --git a/src/ci/docker/dist-various-1/install-mips-musl.sh b/src/ci/docker/dist-various-1/install-mips-musl.sh index 60a96e3b8e..29cfb5d960 100755 --- a/src/ci/docker/dist-various-1/install-mips-musl.sh +++ b/src/ci/docker/dist-various-1/install-mips-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mips-linux-musl # originally from # https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/ # OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror" +URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" FILE="OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mips-linux-musl --strip-components=2 diff --git a/src/ci/docker/dist-various-1/install-mipsel-musl.sh b/src/ci/docker/dist-various-1/install-mipsel-musl.sh index 9ae41218ee..de8c359d16 100755 --- a/src/ci/docker/dist-various-1/install-mipsel-musl.sh +++ b/src/ci/docker/dist-various-1/install-mipsel-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl # Note that this originally came from: # https://downloads.openwrt.org/snapshots/trunk/malta/generic/ # OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci2.s3.amazonaws.com/libc" +URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2 diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 53523d41a5..2ae6c58941 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -8,7 +8,8 @@ RUN sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no-install-recommends \ build-essential \ - gcc-multilib \ +# gcc-multilib can not be installed together with gcc-arm-linux-gnueabi + gcc-7-multilib \ libedit-dev \ libgmp-dev \ libisl-dev \ @@ -21,11 +22,20 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no unzip \ # Needed for apt-key to work: dirmngr \ - gpg-agent + gpg-agent \ + g++-7-arm-linux-gnueabi RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486 RUN add-apt-repository -y 'deb http://apt.dilos.org/dilos dilos2 main' +WORKDIR /build +COPY scripts/musl.sh /build +RUN env \ + CC=arm-linux-gnueabi-gcc-7 CFLAGS="-march=armv7-a" \ + CXX=arm-linux-gnueabi-g++-7 CXXFLAGS="-march=armv7-a" \ + bash musl.sh armv7 && \ + rm -rf /build/* + WORKDIR /tmp COPY dist-various-2/shared.sh /tmp/ COPY dist-various-2/build-cloudabi-toolchain.sh /tmp/ @@ -58,7 +68,11 @@ ENV \ CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \ AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \ CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \ - CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ + CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \ + CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-7 \ + CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-7 \ + CC=gcc-7 \ + CXX=g++-7 ENV CARGO_TARGET_X86_64_FUCHSIA_AR /usr/local/bin/llvm-ar ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \ @@ -81,9 +95,19 @@ ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda +ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi +ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/" +# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211 +# we need asm in the search path for gcc-7 (for gnux32) but not in the search path of the +# cross compilers. +# Luckily one of the folders is /usr/local/include so symlink /usr/include/asm-generic there +RUN ln -s /usr/include/asm-generic /usr/local/include/asm + ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \ - --set target.wasm32-wasi.wasi-root=/wasm32-wasi + --set target.wasm32-wasi.wasi-root=/wasm32-wasi \ + --musl-root-armv7=/musl-armv7 + ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh index 7bf8946c4f..f04ee78157 100755 --- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh @@ -5,7 +5,7 @@ set -ex # Originally from https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz -curl https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ +curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ tar xJf - export PATH=`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH diff --git a/src/ci/docker/dist-x86_64-linux/build-openssl.sh b/src/ci/docker/dist-x86_64-linux/build-openssl.sh index 13dae61690..be8a6c9394 100755 --- a/src/ci/docker/dist-x86_64-linux/build-openssl.sh +++ b/src/ci/docker/dist-x86_64-linux/build-openssl.sh @@ -4,7 +4,7 @@ set -ex source shared.sh VERSION=1.0.2k -URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/openssl-$VERSION.tar.gz +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/openssl-$VERSION.tar.gz curl $URL | tar xzf - diff --git a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh index 2e9b9dcc23..797f674b95 100755 --- a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -25,7 +25,7 @@ cd netbsd mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot -URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc # Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz curl $URL/2018-03-01-netbsd-src.tgz | tar xzf - diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index e6cd794887..415d6b63eb 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -17,9 +17,6 @@ dist=$objdir/build/dist source "$ci_dir/shared.sh" -travis_fold start build_docker -travis_time_start - if [ -f "$docker_dir/$image/Dockerfile" ]; then if [ "$CI" != "" ]; then hash_key=/tmp/.docker-hash-key.txt @@ -94,7 +91,6 @@ elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then echo Cannot run disabled images on CI! exit 1 fi - # retry messes with the pipe from tar to docker. Not needed on non-travis # Transform changes the context of disabled Dockerfiles to match the enabled ones tar --transform 's#^./disabled/#./#' -C $docker_dir -c . | docker \ build \ @@ -107,9 +103,6 @@ else exit 1 fi -travis_fold end build_docker -travis_time_finish - mkdir -p $HOME/.cargo mkdir -p $objdir/tmp mkdir -p $objdir/cores @@ -132,28 +125,61 @@ fi # goes ahead and sets it for all builders. args="$args --privileged" -exec docker \ +# Things get a little weird if this script is already running in a docker +# container. If we're already in a docker container then we assume it's set up +# to do docker-in-docker where we have access to a working `docker` command. +# +# If this is the case (we check via the presence of `/.dockerenv`) +# then we can't actually use the `--volume` argument. Typically we use +# `--volume` to efficiently share the build and source directory between this +# script and the container we're about to spawn. If we're inside docker already +# though the `--volume` argument maps the *host's* folder to the container we're +# about to spawn, when in fact we want the folder in this container itself. To +# work around this we use a recipe cribbed from +# https://circleci.com/docs/2.0/building-docker-images/#mounting-folders to +# create a temporary container with a volume. We then copy the entire source +# directory into this container, and then use that copy in the container we're +# about to spawn. Finally after the build finishes we re-extract the object +# directory. +# +# Note that none of this is necessary if we're *not* in a docker-in-docker +# scenario. If this script is run on a bare metal host then we share a bunch of +# data directories to share as much data as possible. Note that we also use +# `LOCAL_USER_ID` (recognized in `src/ci/run.sh`) to ensure that files are all +# read/written as the same user as the bare-metal user. +if [ -f /.dockerenv ]; then + docker create -v /checkout --name checkout alpine:3.4 /bin/true + docker cp . checkout:/checkout + args="$args --volumes-from checkout" +else + args="$args --volume $root_dir:/checkout:ro" + args="$args --volume $objdir:/checkout/obj" + args="$args --volume $HOME/.cargo:/cargo" + args="$args --volume $HOME/rustsrc:$HOME/rustsrc" + args="$args --env LOCAL_USER_ID=`id -u`" +fi + +docker \ run \ - --volume "$root_dir:/checkout:ro" \ - --volume "$objdir:/checkout/obj" \ --workdir /checkout/obj \ --env SRC=/checkout \ $args \ --env CARGO_HOME=/cargo \ --env DEPLOY \ --env DEPLOY_ALT \ - --env LOCAL_USER_ID=`id -u` \ --env CI \ - --env TRAVIS \ - --env TRAVIS_BRANCH \ --env TF_BUILD \ --env BUILD_SOURCEBRANCHNAME \ --env TOOLSTATE_REPO_ACCESS_TOKEN \ --env TOOLSTATE_REPO \ + --env TOOLSTATE_PUBLISH \ --env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \ - --volume "$HOME/.cargo:/cargo" \ - --volume "$HOME/rustsrc:$HOME/rustsrc" \ --init \ --rm \ rust-ci \ /checkout/src/ci/run.sh + +if [ -f /.dockerenv ]; then + rm -rf $objdir + docker cp checkout:/checkout/obj $objdir +fi diff --git a/src/ci/docker/scripts/android-sdk-manager.py b/src/ci/docker/scripts/android-sdk-manager.py index 7c9a8b82e9..c9e2961f6e 100755 --- a/src/ci/docker/scripts/android-sdk-manager.py +++ b/src/ci/docker/scripts/android-sdk-manager.py @@ -23,8 +23,9 @@ REPOSITORIES = [ HOST_OS = "linux" # Mirroring options -MIRROR_BUCKET = "rust-lang-ci2" -MIRROR_BASE_DIR = "rust-ci-mirror/android/" +MIRROR_BUCKET = "rust-lang-ci-mirrors" +MIRROR_BUCKET_REGION = "us-west-1" +MIRROR_BASE_DIR = "rustc/android/" import argparse import hashlib @@ -144,7 +145,8 @@ def cli_install(args): lockfile = Lockfile(args.lockfile) for package in lockfile.packages.values(): # Download the file from the mirror into a temp file - url = "https://" + MIRROR_BUCKET + ".s3.amazonaws.com/" + MIRROR_BASE_DIR + url = "https://" + MIRROR_BUCKET + ".s3-" + MIRROR_BUCKET_REGION + \ + ".amazonaws.com/" + MIRROR_BASE_DIR downloaded = package.download(url) # Extract the file in a temporary directory extract_dir = tempfile.mkdtemp() diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh index 8cef69d9c2..70155e770a 100755 --- a/src/ci/docker/scripts/freebsd-toolchain.sh +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -59,7 +59,7 @@ done # Originally downloaded from: # https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz -URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" # Fix up absolute symlinks from the system image. This can be removed diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh index 194de3c339..efeb0ed0d7 100644 --- a/src/ci/docker/scripts/sccache.sh +++ b/src/ci/docker/scripts/sccache.sh @@ -1,6 +1,6 @@ set -ex curl -fo /usr/local/bin/sccache \ - https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-02-sccache-x86_64-unknown-linux-musl + https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-unknown-linux-musl chmod +x /usr/local/bin/sccache diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile index c45b1a9a0f..6a2600d875 100644 --- a/src/ci/docker/test-various/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -11,6 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ + libssl-dev \ + pkg-config \ xz-utils \ wget \ patch @@ -41,7 +43,6 @@ ENV WASM_TARGETS=wasm32-unknown-unknown ENV WASM_SCRIPT python2.7 /checkout/x.py test --target $WASM_TARGETS \ src/test/run-make \ src/test/ui \ - src/test/run-pass \ src/test/compile-fail \ src/test/mir-opt \ src/test/codegen-units \ diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index 7a503ea4e9..b2748d9c2a 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -17,6 +17,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ + libssl-dev \ + pkg-config \ xz-utils \ lld \ clang @@ -31,7 +33,6 @@ ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-debug \ --enable-lld \ - --enable-lldb \ --enable-optimize \ --set llvm.use-linker=lld \ --set target.x86_64-unknown-linux-gnu.linker=clang \ diff --git a/src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile b/src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile index a157fee16c..207f972c3c 100644 --- a/src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile +++ b/src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile @@ -11,6 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ + libssl-dev \ + pkg-config \ xz-utils COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/x86_64-gnu-llvm-6.0/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-6.0/Dockerfile index ef97f59caf..6dbbb22034 100644 --- a/src/ci/docker/x86_64-gnu-llvm-6.0/Dockerfile +++ b/src/ci/docker/x86_64-gnu-llvm-6.0/Dockerfile @@ -13,6 +13,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ gdb \ llvm-6.0-tools \ libedit-dev \ + libssl-dev \ + pkg-config \ zlib1g-dev \ xz-utils diff --git a/src/ci/docker/x86_64-gnu-nopt/Dockerfile b/src/ci/docker/x86_64-gnu-nopt/Dockerfile index d0b244c9b7..6a5c7f5d9e 100644 --- a/src/ci/docker/x86_64-gnu-nopt/Dockerfile +++ b/src/ci/docker/x86_64-gnu-nopt/Dockerfile @@ -11,6 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ + libssl-dev \ + pkg-config \ xz-utils COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/x86_64-gnu-tools/Dockerfile b/src/ci/docker/x86_64-gnu-tools/Dockerfile index bab9145cbc..8035195c6e 100644 --- a/src/ci/docker/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/x86_64-gnu-tools/Dockerfile @@ -21,8 +21,10 @@ COPY x86_64-gnu-tools/checkregression.py /tmp/ COPY x86_64-gnu-tools/checktools.sh /tmp/ COPY x86_64-gnu-tools/repo.sh /tmp/ +# Run rustbook with `linkcheck` feature enabled +ENV CHECK_LINKS 1 + ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ - --enable-test-miri \ --save-toolstates=/tmp/toolstates.json ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstates.json linux diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index 0cc0a6329e..4fbb8c4d20 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -1,9 +1,18 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +## This script has two purposes: detect any tool that *regressed*, which is used +## during the week before the beta branches to reject PRs; and detect any tool +## that *changed* to see if we need to update the toolstate repo. + import sys import json +# Regressions for these tools during the beta cutoff week do not cause failure. +# See `status_check` in `checktools.sh` for tools that have to pass on the +# beta/stable branches. +REGRESSION_OK = ["rustc-guide", "miri", "embedded-book"] + if __name__ == '__main__': os_name = sys.argv[1] toolstate_file = sys.argv[2] @@ -32,7 +41,8 @@ if __name__ == '__main__': 'The state of "{}" has {} from "{}" to "{}"' .format(tool, verb, state, new_state) ) - regressed = True + if not (verb == 'regressed' and tool in REGRESSION_OK): + regressed = True if regressed: sys.exit(1) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 978732e3c0..4243effdf9 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -25,6 +25,7 @@ python2.7 "$X_PY" test --no-fail-fast \ src/doc/rust-by-example \ src/doc/embedded-book \ src/doc/edition-guide \ + src/doc/rustc-guide \ src/tools/clippy \ src/tools/rls \ src/tools/rustfmt \ @@ -41,7 +42,7 @@ check_tool_failed() { } # This function checks that if a tool's submodule changed, the tool's state must improve -verify_status() { +verify_submodule_changed() { echo "Verifying status of $1..." if echo "$CHANGED_FILES" | grep -q "^M[[:blank:]]$2$"; then echo "This PR updated '$2', verifying if status is 'test-pass'..." @@ -66,7 +67,7 @@ verify_status() { check_dispatch() { if [ "$1" = submodule_changed ]; then # ignore $2 (branch id) - verify_status $3 $4 + verify_submodule_changed $3 $4 elif [ "$2" = beta ]; then echo "Requiring test passing for $3..." if check_tool_failed "$3"; then @@ -75,7 +76,12 @@ check_dispatch() { fi } -# list all tools here +# List all tools here. +# This function gets called with "submodule_changed" for each PR that changed a submodule, +# and with "beta_required" for each PR that lands on beta/stable. +# The purpose of this function is to *reject* PRs if a tool is not "test-pass" and +# (a) the tool's submodule has been updated, or (b) we landed on beta/stable and the +# tool has to "test-pass" on that branch. status_check() { check_dispatch $1 beta book src/doc/book check_dispatch $1 beta nomicon src/doc/nomicon @@ -85,9 +91,13 @@ status_check() { check_dispatch $1 beta rls src/tools/rls check_dispatch $1 beta rustfmt src/tools/rustfmt check_dispatch $1 beta clippy-driver src/tools/clippy - # these tools are not required for beta to successfully branch + # These tools are not required on the beta/stable branches, but they *do* cause + # PRs to fail if a submodule update does not fix them. + # They will still cause failure during the beta cutoff week, unless `checkregression.py` + # exempts them from that. check_dispatch $1 nightly miri src/tools/miri check_dispatch $1 nightly embedded-book src/doc/embedded-book + check_dispatch $1 nightly rustc-guide src/doc/rustc-guide } # If this PR is intended to update one of these tools, do not let the build pass @@ -96,12 +106,14 @@ status_check() { status_check "submodule_changed" CHECK_NOT="$(readlink -f "$(dirname $0)/checkregression.py")" +# This callback is called by `commit_toolstate_change`, see `repo.sh`. change_toolstate() { # only update the history if python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" changed; then echo 'Toolstate is not changed. Not updating.' else if [ $SIX_WEEK_CYCLE -ge 35 ]; then + # Reject any regressions during the week before beta cutoff. python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" regressed fi sed -i "1 a\\ @@ -111,7 +123,7 @@ $COMMIT\t$(cat "$TOOLSTATE_FILE") } if [ "$RUST_RELEASE_CHANNEL" = nightly ]; then - if [ -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then + if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then . "$(dirname $0)/repo.sh" MESSAGE_FILE=$(mktemp -t msg.XXXXXX) echo "($OS CI update)" > "$MESSAGE_FILE" diff --git a/src/ci/docker/x86_64-gnu-tools/repo.sh b/src/ci/docker/x86_64-gnu-tools/repo.sh index 741d4dcbd9..82700a00fb 100644 --- a/src/ci/docker/x86_64-gnu-tools/repo.sh +++ b/src/ci/docker/x86_64-gnu-tools/repo.sh @@ -5,8 +5,8 @@ # # The function relies on a GitHub bot user, which should have a Personal access # token defined in the environment variable $TOOLSTATE_REPO_ACCESS_TOKEN. If for -# some reason you need to change the token, please update `.travis.yml` and -# `appveyor.yml`: +# some reason you need to change the token, please update the Azure Pipelines +# variable group. # # 1. Generate a new Personal access token: # @@ -18,28 +18,9 @@ # Save it somewhere secure, as the token would be gone once you leave # the page. # -# 2. Encrypt the token for Travis CI +# 2. Update the variable group in Azure Pipelines # -# * Install the `travis` tool locally (`gem install travis`). -# * Encrypt the token: -# ``` -# travis -r rust-lang/rust encrypt \ -# TOOLSTATE_REPO_ACCESS_TOKEN=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -# ``` -# * Copy output to replace the existing one in `.travis.yml`. -# * Details of this step can be found in -# -# -# 3. Encrypt the token for AppVeyor -# -# * Login to AppVeyor using your main account, and login as the rust-lang -# organization. -# * Open the ["Encrypt data" tool](https://ci.appveyor.com/tools/encrypt) -# * Paste the 40-digit token into the "Value to encrypt" box, then click -# "Encrypt" -# * Copy the output to replace the existing one in `appveyor.yml`. -# * Details of this step can be found in -# +# * Ping a member of the infrastructure team to do this. # # 4. Replace the email address below if the bot account identity is changed # @@ -62,6 +43,13 @@ commit_toolstate_change() { MESSAGE_FILE="$1" shift for RETRY_COUNT in 1 2 3 4 5; do + # Call the callback. + # - If we are in the `auto` branch (pre-landing), this is called from `checktools.sh` and + # the callback is `change_toolstate` in that file. The purpose of this is to publish the + # test results (the new commit-to-toolstate mapping) in the toolstate repo. + # - If we are in the `master` branch (post-landing), this is called by the CI pipeline + # and the callback is `src/tools/publish_toolstate.py`. The purpose is to publish + # the new "current" toolstate in the toolstate repo. "$@" # `git commit` failing means nothing to commit. FAILURE=0 diff --git a/src/ci/docker/x86_64-gnu/Dockerfile b/src/ci/docker/x86_64-gnu/Dockerfile index c3519a0077..4ec4364721 100644 --- a/src/ci/docker/x86_64-gnu/Dockerfile +++ b/src/ci/docker/x86_64-gnu/Dockerfile @@ -11,6 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ + libssl-dev \ + pkg-config \ xz-utils COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index 8b63581082..c7c3b0a5fb 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -11,9 +11,6 @@ set -o nounset ci_dir=$(cd $(dirname $0) && pwd) . "$ci_dir/shared.sh" -travis_fold start init_repo -travis_time_start - REPO_DIR="$1" CACHE_DIR="$2" @@ -73,5 +70,3 @@ retry sh -c "git submodule deinit -f $use_git && \ git submodule sync && \ git submodule update -j 16 --init --recursive $use_git" wait -travis_fold end init_repo -travis_time_finish diff --git a/src/ci/install-awscli.sh b/src/ci/install-awscli.sh new file mode 100755 index 0000000000..69c8d2e309 --- /dev/null +++ b/src/ci/install-awscli.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# This script downloads and installs awscli from the packages mirrored in our +# own S3 bucket. This follows the recommendations at: +# +# https://packaging.python.org/guides/index-mirrors-and-caches/#caching-with-pip +# +# To create a new mirrored copy you can run the command: +# +# pip wheel awscli +# +# Before compressing please make sure all the wheels end with `-none-any.whl`. +# If that's not the case you'll need to remove the non-cross-platform ones and +# replace them with the .tar.gz downloaded from https://pypi.org. Also make +# sure it's possible to call this script with both Python 2 and Python 3. + +set -euo pipefail +IFS=$'\n\t' + +MIRROR="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-07-27-awscli.tar" +DEPS_DIR="/tmp/awscli-deps" + +pip="pip" +pipflags="" +if [[ "${AGENT_OS}" == "Linux" ]]; then + pip="pip3" + pipflags="--user" + + sudo apt-get install -y python3-setuptools + echo "##vso[task.prependpath]$HOME/.local/bin" +fi + +mkdir -p "${DEPS_DIR}" +curl "${MIRROR}" | tar xf - -C "${DEPS_DIR}" +"${pip}" install ${pipflags} --no-index "--find-links=${DEPS_DIR}" awscli +rm -rf "${DEPS_DIR}" diff --git a/src/ci/run.sh b/src/ci/run.sh index f19bd4e7ec..a61e90b0af 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -25,7 +25,7 @@ source "$ci_dir/shared.sh" branch_name=$(getCIBranch) -if [ ! isCI ] || [ "$branch_name" = "auto" ]; then +if [ ! isCI ] || [ "$branch_name" = "auto" ] || [ "$branch_name" = "try" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.print-step-timings --enable-verbose-tests" fi @@ -91,27 +91,14 @@ if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then rm -rf build fi -travis_fold start configure -travis_time_start $SRC/configure $RUST_CONFIGURE_ARGS -travis_fold end configure -travis_time_finish -travis_fold start make-prepare -travis_time_start retry make prepare -travis_fold end make-prepare -travis_time_finish -travis_fold start check-bootstrap -travis_time_start make check-bootstrap -travis_fold end check-bootstrap -travis_time_finish # Display the CPU and memory information. This helps us know why the CI timing # is fluctuating. -travis_fold start log-system-info if isOSX; then system_profiler SPHardwareDataType || true sysctl hw || true @@ -121,19 +108,14 @@ else cat /proc/meminfo || true ncpus=$(grep processor /proc/cpuinfo | wc -l) fi -travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then sh -x -c "$SCRIPT" else do_make() { - travis_fold start "make-$1" - travis_time_start echo "make -j $ncpus $1" make -j $ncpus $1 local retval=$? - travis_fold end "make-$1" - travis_time_finish return $retval } diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 323d53f2be..b093a07ec5 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -25,53 +25,13 @@ function retry { } function isCI { - [ "$CI" = "true" ] || [ "$TRAVIS" = "true" ] || [ "$TF_BUILD" = "True" ] + [ "$CI" = "true" ] || [ "$TF_BUILD" = "True" ] } function isOSX { - [ "$TRAVIS_OS_NAME" = "osx" ] || [ "$AGENT_OS" = "Darwin" ] + [ "$AGENT_OS" = "Darwin" ] } function getCIBranch { - if [ "$TRAVIS" = "true" ]; then - echo "$TRAVIS_BRANCH" - elif [ "$APPVEYOR" = "True" ]; then - echo "$APPVEYOR_REPO_BRANCH" - else - echo "$BUILD_SOURCEBRANCHNAME" - fi; + echo "$BUILD_SOURCEBRANCHNAME" } - -if ! declare -F travis_fold; then - if [ "${TRAVIS-false}" = 'true' ]; then - # This is a trimmed down copy of - # https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh - travis_fold() { - echo -en "travis_fold:$1:$2\r\033[0K" - } - travis_time_start() { - travis_timer_id=$(printf %08x $(( RANDOM * RANDOM ))) - travis_start_time=$(travis_nanoseconds) - echo -en "travis_time:start:$travis_timer_id\r\033[0K" - } - travis_time_finish() { - travis_end_time=$(travis_nanoseconds) - local duration=$(($travis_end_time-$travis_start_time)) - local msg="travis_time:end:$travis_timer_id" - echo -en "\n$msg:start=$travis_start_time,finish=$travis_end_time,duration=$duration\r\033[0K" - } - if [ $(uname) = 'Darwin' ]; then - travis_nanoseconds() { - date -u '+%s000000000' - } - else - travis_nanoseconds() { - date -u '+%s%N' - } - fi - else - travis_fold() { return 0; } - travis_time_start() { return 0; } - travis_time_finish() { return 0; } - fi -fi diff --git a/src/doc/book/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md b/src/doc/book/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md index 8cb0dfadc4..ad584b72b4 100644 --- a/src/doc/book/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md +++ b/src/doc/book/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md @@ -22,9 +22,8 @@ removing some of the modules and functions. We’ll show two ways to call the the crate root. The `eat_at_restaurant` function is part of our library crate’s public API, so we mark it with the `pub` keyword. In the [”Exposing Paths with the `pub` Keyword”][pub] section, we’ll go into more detail -about `pub`. - -Note that this example won’t compile just yet; we’ll explain why in a bit. +about `pub`. Note that this example won’t compile just yet; we’ll explain why +in a bit. Filename: src/lib.rs diff --git a/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md b/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md index 3fcdb4bbe2..af15ace8b4 100644 --- a/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md +++ b/src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md @@ -291,14 +291,14 @@ crate. If we’re using multiple items defined in the same package or same module, listing each item on its own line can take up a lot of vertical space in our -files. For example, these two `use` statements we had in Listing 2-4 in the -Guessing Game bring items from `std` into scope: +files. For example, these two `use` statements we had in the Guessing Game in +Listing 2-4 bring items from `std` into scope: Filename: src/main.rs ```rust -use std::cmp::Ordering; use std::io; +use std::cmp::Ordering; // ---snip--- ``` diff --git a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md index 7d666e42e0..85c4192836 100644 --- a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md +++ b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md @@ -528,7 +528,7 @@ fn main() -> Result<(), Box> { } ``` -The `Box` type is called a *trait object*, which we’ll talk about in +The `Box` type is called a trait object, which we’ll talk about in the [“Using Trait Objects that Allow for Values of Different Types”][trait-objects] section in Chapter 17. For now, you can read `Box` to mean “any kind of error.” Using `?` in a `main` diff --git a/src/doc/book/src/ch11-01-writing-tests.md b/src/doc/book/src/ch11-01-writing-tests.md index b5c645f34c..42a5391878 100644 --- a/src/doc/book/src/ch11-01-writing-tests.md +++ b/src/doc/book/src/ch11-01-writing-tests.md @@ -282,11 +282,12 @@ larger rectangle can indeed hold a smaller rectangle Note that we’ve added a new line inside the `tests` module: `use super::*;`. The `tests` module is a regular module that follows the usual visibility rules -we covered in Chapter 7 in the [“Modules as the Privacy -Boundary”][modules-as-privacy-boundary] section. Because the -`tests` module is an inner module, we need to bring the code under test in the -outer module into the scope of the inner module. We use a glob here so anything -we define in the outer module is available to this `tests` module. +we covered in Chapter 7 in the [“Paths for Referring to an Item in the Module +Tree”][paths-for-referring-to-an-item-in-the-module-tree] +section. Because the `tests` module is an inner module, we need to bring the +code under test in the outer module into the scope of the inner module. We use +a glob here so anything we define in the outer module is available to this +`tests` module. We’ve named our test `larger_can_hold_smaller`, and we’ve created the two `Rectangle` instances that we need. Then we called the `assert!` macro and @@ -849,4 +850,4 @@ ch08-02-strings.html#concatenation-with-the--operator-or-the-format-macro ch11-02-running-tests.html#controlling-how-tests-are-run [derivable-traits]: appendix-03-derivable-traits.html [doc-comments]: ch14-02-publishing-to-crates-io.html#documentation-comments-as-tests -[modules-as-privacy-boundary]: ch07-02-defining-modules-to-control-scope-and-privacy.html +[paths-for-referring-to-an-item-in-the-module-tree]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html diff --git a/src/doc/book/src/ch11-03-test-organization.md b/src/doc/book/src/ch11-03-test-organization.md index 56bbccbae4..bc8255e306 100644 --- a/src/doc/book/src/ch11-03-test-organization.md +++ b/src/doc/book/src/ch11-03-test-organization.md @@ -291,7 +291,7 @@ fn it_adds_two() { ``` Note that the `mod common;` declaration is the same as the module declaration -we demonstrated in Listing 7-25. Then in the test function, we can call the +we demonstrated in Listing 7-21. Then in the test function, we can call the `common::setup()` function. #### Integration Tests for Binary Crates diff --git a/src/doc/book/src/ch19-06-macros.md b/src/doc/book/src/ch19-06-macros.md index b29337e61b..fbb2246934 100644 --- a/src/doc/book/src/ch19-06-macros.md +++ b/src/doc/book/src/ch19-06-macros.md @@ -298,7 +298,7 @@ definition in `hello_macro`, we’ll have to change the implementation of the procedural macro in `hello_macro_derive` as well. The two crates will need to be published separately, and programmers using these crates will need to add both as dependencies and bring them both into scope. We could instead have the -`hello_macro` crate use `hello_macro_derive` as a dependency and reexport the +`hello_macro` crate use `hello_macro_derive` as a dependency and re-export the procedural macro code. However, the way we’ve structured the project makes it possible for programmers to use `hello_macro` even if they don’t want the `derive` functionality. diff --git a/src/doc/book/src/title-page.md b/src/doc/book/src/title-page.md index 18a664a6b4..bc7fb9031b 100644 --- a/src/doc/book/src/title-page.md +++ b/src/doc/book/src/title-page.md @@ -2,15 +2,14 @@ *by Steve Klabnik and Carol Nichols, with contributions from the Rust Community* -Welcome to *The Rust Programming Language* book! This version of the text assumes -you’re using Rust 1.31.0 or later with `edition="2018"` in *Cargo.toml* of -all projects to use Rust 2018 Edition idioms. See the [“Installation” section -of Chapter 1][install] to install or update Rust, and see the -new [Appendix E][editions] for information on what editions of -Rust are. +This version of the text assumes you’re using Rust 1.31.0 or later with +`edition="2018"` in *Cargo.toml* of all projects to use Rust 2018 Edition +idioms. See the [“Installation” section of Chapter 1][install] +to install or update Rust, and see the new [Appendix E][editions] for information on editions. The 2018 Edition of the Rust language includes a number of improvements that -make Rust more ergonomic and easier to learn. This printing of the book +make Rust more ergonomic and easier to learn. This iteration of the book contains a number of changes to reflect those improvements: - Chapter 7, “Managing Growing Projects with Packages, Crates, and Modules,” @@ -20,7 +19,7 @@ contains a number of changes to reflect those improvements: Types that Implement Traits” that explain the new `impl Trait` syntax. - Chapter 11 has a new section titled “Using `Result` in Tests” that shows how to write tests that use the `?` operator. -- The “Advanced Lifetimes” section of Chapter 19 was removed because compiler +- The “Advanced Lifetimes” section in Chapter 19 was removed because compiler improvements have made the constructs in that section even rarer. - The previous Appendix D, “Macros,” has been expanded to include procedural macros and was moved to the “Macros” section in Chapter 19. @@ -31,7 +30,7 @@ contains a number of changes to reflect those improvements: - We fixed a number of small errors and imprecise wording throughout the book. Thank you to the readers who reported them! -Note that any code in the first printing of *The Rust Programming Language* +Note that any code in earlier iterations of *The Rust Programming Language* that compiled will continue to compile without `edition="2018"` in the project’s *Cargo.toml*, even as you update the Rust compiler version you’re using. That’s Rust’s backward compatibility guarantees at work! diff --git a/src/doc/edition-guide/.travis.yml b/src/doc/edition-guide/.travis.yml index a44cb43596..bb46f7103b 100644 --- a/src/doc/edition-guide/.travis.yml +++ b/src/doc/edition-guide/.travis.yml @@ -2,9 +2,7 @@ language: rust cache: cargo rust: nightly before_script: - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) - - (test -x $HOME/.cargo/bin/mdbook || cargo install mdbook) - - cargo install-update -a + - cargo install mdbook -Z install-upgrade - mdbook --version script: - mdbook build diff --git a/src/doc/edition-guide/README.md b/src/doc/edition-guide/README.md index de46eb63ee..f732918256 100644 --- a/src/doc/edition-guide/README.md +++ b/src/doc/edition-guide/README.md @@ -1,6 +1,6 @@ # The Rust Edition Guide -[![Build Status](https://travis-ci.org/rust-lang-nursery/edition-guide.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/edition-guide) +[![Build Status](https://api.travis-ci.com/rust-lang-nursery/edition-guide.svg?branch=master)](https://travis-ci.com/rust-lang-nursery/edition-guide) This book explains the concept of "editions", major new eras in [Rust]'s development. You can [read the book @@ -35,7 +35,7 @@ $ mdbook serve ``` This serves the book at http://localhost:3000, and rebuilds it on changes. -You can now view the book in your web browser. If you make changes to the book's source code, +You can now view the book in your web browser. If you make changes to the book's source code, you should only need to refresh your browser to see them. _Firefox:_ diff --git a/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-check-for-faster-checking.md b/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-check-for-faster-checking.md index 46166583f0..39812f703c 100644 --- a/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-check-for-faster-checking.md +++ b/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-check-for-faster-checking.md @@ -47,8 +47,8 @@ So how much speedup do you actually get? Like most performance related questions, the answer is "it depends." Here are some very un-scientific benchmarks at the time of writing. -| build | performance | check performance | speedup | +| use case | build performance | check performance | speedup | |--------|-------------|-------------------|---------| | initial compile | 11s | 5.6s | 1.96x | | second compile (no changes) | 3s | 1.9s | 1.57x | -| third compile with small change | 5.8s | 3s | 1.93x | \ No newline at end of file +| third compile with small change | 5.8s | 3s | 1.93x | diff --git a/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-install-for-easy-installation-of-tools.md b/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-install-for-easy-installation-of-tools.md index d45e84e93d..cb9010516b 100644 --- a/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-install-for-easy-installation-of-tools.md +++ b/src/doc/edition-guide/src/rust-2018/cargo-and-crates-io/cargo-install-for-easy-installation-of-tools.md @@ -19,6 +19,8 @@ And then use it with $ mdbook --help ``` +## Cargo Extensions + As an example of extending Cargo, you can use the [`cargo-update`](https://crates.io/crates/cargo-update) package. To install it: @@ -26,9 +28,5 @@ package. To install it: $ cargo install cargo-update ``` -This will allow you to use this command, which checks everything you've `cargo install`'d and -updates it to the latest version: - -```console -$ cargo install-update -a -``` \ No newline at end of file +This will allow you to use `cargo install-update -a` command, which checks everything you've `cargo install`'d and +updates it to the latest version. diff --git a/src/doc/edition-guide/src/rust-2018/macros/at-most-once.md b/src/doc/edition-guide/src/rust-2018/macros/at-most-once.md index 551934c175..56e30b9790 100644 --- a/src/doc/edition-guide/src/rust-2018/macros/at-most-once.md +++ b/src/doc/edition-guide/src/rust-2018/macros/at-most-once.md @@ -12,12 +12,12 @@ In Rust 2018, we have made a couple of changes to the macros-by-example syntax. For example, consider the following Rust 2015 code: -```rust2018 +```rust macro_rules! foo { ($a:ident, $b:expr) => { println!("{}", $a); println!("{}", $b); - } + }; ($a:ident) => { println!("{}", $a); } @@ -29,7 +29,7 @@ but you need a whole other matcher to represent this possibility. This is annoying if your matchers are long. In Rust 2018, one can simply write the following: -```rust2018 +```rust macro_rules! foo { ($a:ident $(, $b:expr)?) => { println!("{}", $a); diff --git a/src/doc/edition-guide/src/rust-2018/module-system/path-clarity.md b/src/doc/edition-guide/src/rust-2018/module-system/path-clarity.md index e4522c784f..19bbf7391c 100644 --- a/src/doc/edition-guide/src/rust-2018/module-system/path-clarity.md +++ b/src/doc/edition-guide/src/rust-2018/module-system/path-clarity.md @@ -169,10 +169,8 @@ mod submodule { In Rust 2015, if you have a submodule: ```rust,ignore -/// foo.rs -/// or -/// foo/mod.rs - +// This `mod` declaration looks for the `foo` module in +// `foo.rs` or `foo/mod.rs`. mod foo; ``` @@ -180,23 +178,43 @@ It can live in `foo.rs` or `foo/mod.rs`. If it has submodules of its own, it *must* be `foo/mod.rs`. So a `bar` submodule of `foo` would live at `foo/bar.rs`. -In Rust 2018, `mod.rs` is no longer needed. - -```rust,ignore -/// foo.rs -/// foo/bar.rs - -mod foo; - -/// in foo.rs -mod bar; -``` - -`foo.rs` can just be `foo.rs`, +In Rust 2018 the restriction that a module with submodules must be named +`mod.rs` is lifted. `foo.rs` can just be `foo.rs`, and the submodule is still `foo/bar.rs`. This eliminates the special name, and if you have a bunch of files open in your editor, you can clearly see their names, instead of having a bunch of tabs named `mod.rs`. + + + + + + + + + + + + + +
Rust 2015Rust 2018
+
+.
+├── lib.rs
+└── foo/
+    ├── mod.rs
+    └── bar.rs
+
+
+
+.
+├── lib.rs
+├── foo.rs
+└── foo/
+    └── bar.rs
+
+
+ ### `use` paths ![Minimum Rust version: 1.32](https://img.shields.io/badge/Minimum%20Rust%20Version-1.32-brightgreen.svg) diff --git a/src/doc/edition-guide/src/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.md b/src/doc/edition-guide/src/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.md index c7f083a9d6..aa2da7a508 100644 --- a/src/doc/edition-guide/src/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.md +++ b/src/doc/edition-guide/src/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.md @@ -16,11 +16,9 @@ struct StrWrap<'a>(&'a str); In Rust 2015, you might have written: ```rust -// Rust 2015 - -use std::fmt; - +# use std::fmt; # struct StrWrap<'a>(&'a str); +// Rust 2015 fn make_wrapper(string: &str) -> StrWrap { StrWrap(string) @@ -38,7 +36,6 @@ In Rust 2018, you can instead write: ```rust # use std::fmt; # struct StrWrap<'a>(&'a str); - // Rust 2018 fn make_wrapper(string: &str) -> StrWrap<'_> { diff --git a/src/doc/edition-guide/src/rust-2018/rustup-for-managing-rust-versions.md b/src/doc/edition-guide/src/rust-2018/rustup-for-managing-rust-versions.md index 73be9e6b2d..f2b2c81b79 100644 --- a/src/doc/edition-guide/src/rust-2018/rustup-for-managing-rust-versions.md +++ b/src/doc/edition-guide/src/rust-2018/rustup-for-managing-rust-versions.md @@ -145,15 +145,7 @@ information to know more about the functions you're trying to call. $ rustup component add rust-src ``` -### The "preview" components - -There are several components in a "preview" stage. These components currently -have `-preview` in their name, and this indicates that they're not quite 100% -ready for general consumption yet. Please try them out and give us feedback, -but know that they do not follow Rust's stability guarantees, and are still -actively changing, possibly in backwards-incompatible ways. - -#### `rustfmt-preview` for automatic code formatting +### `rustfmt` for automatic code formatting ![Minimum Rust version: 1.24](https://img.shields.io/badge/Minimum%20Rust%20Version-1.24-brightgreen.svg) @@ -161,7 +153,7 @@ If you'd like to have your code automatically formatted, you can install this component: ```console -$ rustup component add rustfmt-preview +$ rustup component add rustfmt ``` This will install two tools, `rustfmt` and `cargo-fmt`, that will reformat your @@ -173,7 +165,7 @@ $ cargo fmt will reformat your entire Cargo project. -#### `rls-preview` for IDE integration +### `rls` for IDE integration ![Minimum Rust version: 1.21](https://img.shields.io/badge/Minimum%20Rust%20Version-1.21-brightgreen.svg) @@ -182,17 +174,18 @@ protocol](http://langserver.org/). To gain support for Rust with these IDEs, you'll need to install the Rust language sever, aka the "RLS": ```console -$ rustup component add rls-preview +$ rustup component add rls ``` -Your IDE should take it from there. +For more information about integrating this into your IDE, see the [RLS +documentation](https://github.com/rust-lang/rls). -#### `clippy-preview` for more lints +### `clippy` for more lints For even more lints to help you write Rust code, you can install `clippy`: ```console -$ rustup component add clippy-preview +$ rustup component add clippy ``` This will install `cargo-clippy` for you: @@ -202,7 +195,15 @@ $ cargo clippy ``` For more, check out [clippy's -documentation](https://github.com/rust-lang-nursery/rust-clippy). +documentation](https://github.com/rust-lang/rust-clippy). + +### The "preview" components + +There are several components in a "preview" stage. These components currently +have `-preview` in their name, and this indicates that they're not quite 100% +ready for general consumption yet. Please try them out and give us feedback, +but know that they do not follow Rust's stability guarantees, and are still +actively changing, possibly in backwards-incompatible ways. #### `llvm-tools-preview` for using extra LLVM tools diff --git a/src/doc/edition-guide/src/rust-2018/the-compiler/improved-error-messages.md b/src/doc/edition-guide/src/rust-2018/the-compiler/improved-error-messages.md index 3b3b6896ae..711d00995f 100644 --- a/src/doc/edition-guide/src/rust-2018/the-compiler/improved-error-messages.md +++ b/src/doc/edition-guide/src/rust-2018/the-compiler/improved-error-messages.md @@ -8,42 +8,43 @@ error message system was created. For example, here's some code that produces an error: -```rust,ignore +```rust,compile_fail fn main() { let mut x = 5; - let y = &x; - x += 1; + println!("{} {}", x, y); } ``` Here's the error in Rust 1.11: ```text -foo.rs:6:5: 6:11 error: cannot assign to `x` because it is borrowed [E0506] -foo.rs:6 x += 1; +foo.rs:4:5: 4:11 error: cannot assign to `x` because it is borrowed [E0506] +foo.rs:4 x += 1; ^~~~~~ -foo.rs:4:14: 4:15 note: borrow of `x` occurs here -foo.rs:4 let y = &x; +foo.rs:3:14: 3:15 note: borrow of `x` occurs here +foo.rs:3 let y = &x; ^ -foo.rs:6:5: 6:11 help: run `rustc --explain E0506` to see a detailed explanation +foo.rs:4:5: 4:11 help: run `rustc --explain E0506` to see a detailed explanation +error: aborting due to previous error ``` Here's the error in Rust 1.28: ```text error[E0506]: cannot assign to `x` because it is borrowed - --> foo.rs:6:5 + --> foo.rs:4:5 | -4 | let y = &x; +3 | let y = &x; | - borrow of `x` occurs here -5 | -6 | x += 1; +4 | x += 1; | ^^^^^^ assignment to borrowed `x` occurs here error: aborting due to previous error + +For more information about this error, try `rustc --explain E0506`. ``` This error isn't terribly different, but shows off how the format has changed. It shows -off your code in context, rather than just showing the text of the lines themselves. \ No newline at end of file +off your code in context, rather than just showing the text of the lines themselves. diff --git a/src/doc/embedded-book/src/concurrency/index.md b/src/doc/embedded-book/src/concurrency/index.md index 75bd53c548..5035852f27 100644 --- a/src/doc/embedded-book/src/concurrency/index.md +++ b/src/doc/embedded-book/src/concurrency/index.md @@ -512,6 +512,66 @@ Since we can't move the `GPIOA` out of the `&Option`, we need to convert it to an `&Option<&GPIOA>` with `as_ref()`, which we can finally `unwrap()` to obtain the `&GPIOA` which lets us modify the peripheral. +If we need a mutable references to shared resources, then `borrow_mut` and `deref_mut` +should be used instead. The following code shows an example using the TIM2 timer. + +```rust,ignore +use core::cell::RefCell; +use core::ops::DerefMut; +use cortex_m::interrupt::{self, Mutex}; +use cortex_m::asm::wfi; +use stm32f4::stm32f405; + +static G_TIM: Mutex>>> = + Mutex::new(RefCell::new(None)); + +#[entry] +fn main() -> ! { + let mut cp = cm::Peripherals::take().unwrap(); + let dp = stm32f405::Peripherals::take().unwrap(); + + // Some sort of timer configuration function. + // Assume it configures the TIM2 timer, its NVIC interrupt, + // and finally starts the timer. + let tim = configure_timer_interrupt(&mut cp, dp); + + interrupt::free(|cs| { + G_TIM.borrow(cs).replace(Some(tim)); + }); + + loop { + wfi(); + } +} + +#[interrupt] +fn timer() { + interrupt::free(|cs| { + if let Some(ref mut tim)) = G_TIM.borrow(cs).borrow_mut().deref_mut() { + tim.start(1.hz()); + } + }); +} + +``` + +> **NOTE** +> +> At the moment, the `cortex-m` crate hides const versions of some functions +> (including `Mutex::new()`) behind the `const-fn` feature. So you need to add +> the `const-fn` feature as a dependency for cortex-m in the Cargo.toml to make +> the above examples work: +> +> ``` toml +> [dependencies.cortex-m] +> version="0.6.0" +> features=["const-fn"] +> ``` +> Meanwhile, `const-fn` has been working on stable Rust for some time now. +> So this additional switch in Cargo.toml will not be needed as soon as +> it is enabled in `cortex-m` by default. +> + Whew! This is safe, but it is also a little unwieldy. Is there anything else we can do? diff --git a/src/doc/embedded-book/src/interoperability/c-with-rust.md b/src/doc/embedded-book/src/interoperability/c-with-rust.md index bb90c8f51d..bf88fd03ab 100644 --- a/src/doc/embedded-book/src/interoperability/c-with-rust.md +++ b/src/doc/embedded-book/src/interoperability/c-with-rust.md @@ -84,8 +84,8 @@ Rather than manually generating these interfaces, which may be tedious and error 2. Write a `bindings.h` file, which `#include "..."`'s each of the files you gathered in step one 3. Feed this `bindings.h` file, along with any compilation flags used to compile your code into `bindgen`. Tip: use `Builder.ctypes_prefix("cty")` / - `--ctypes-prefix=cty` to make the generated code `#![no_std]` compatible. -4. `bindgen` will produce the generated Rust code to the output of the terminal window. This file may be piped to a file in your project, such as `bindings.rs`. You may use this file in your Rust project to interact with C/C++ code compiled and linked as an external library + `--ctypes-prefix=cty` and `Builder.use_core()` to make the generated code `#![no_std]` compatible. +4. `bindgen` will produce the generated Rust code to the output of the terminal window. This file may be piped to a file in your project, such as `bindings.rs`. You may use this file in your Rust project to interact with C/C++ code compiled and linked as an external library. Tip: don't forget to use the [`cty`](https://crates.io/crates/cty) crate if your types in the generated bindings are prefixed with `cty`. [bindgen]: https://github.com/rust-lang-nursery/rust-bindgen [bindgen user's manual]: https://rust-lang.github.io/rust-bindgen/ diff --git a/src/doc/embedded-book/src/intro/install/verify.md b/src/doc/embedded-book/src/intro/install/verify.md index 873fb3dba8..ad58c003ad 100644 --- a/src/doc/embedded-book/src/intro/install/verify.md +++ b/src/doc/embedded-book/src/intro/install/verify.md @@ -45,7 +45,7 @@ The contents may not match exactly but you should get the last line about breakpoints and watchpoints. If you got it then terminate the OpenOCD process and move to the [next section]. -[next section]: ../hardware.md +[next section]: ../../start/index.md If you didn't get the "breakpoints" line then try the following command. diff --git a/src/doc/embedded-book/src/start/exceptions.md b/src/doc/embedded-book/src/start/exceptions.md index 4abd55f082..816188d289 100644 --- a/src/doc/embedded-book/src/start/exceptions.md +++ b/src/doc/embedded-book/src/start/exceptions.md @@ -82,6 +82,7 @@ fn main() -> ! { syst.set_clock_source(SystClkSource::Core); // this is configured for the LM3S6965 which has a default CPU clock of 12 MHz syst.set_reload(12_000_000); + syst.clear_current(); syst.enable_counter(); syst.enable_interrupt(); diff --git a/src/doc/nomicon/README.md b/src/doc/nomicon/README.md index 1973ee15e4..650659e66c 100644 --- a/src/doc/nomicon/README.md +++ b/src/doc/nomicon/README.md @@ -6,11 +6,11 @@ Nicknamed "the Nomicon." ## NOTE: This is a draft document, and may contain serious errors -> Instead of the programs I had hoped for, there came only a shuddering blackness -and ineffable loneliness; and I saw at last a fearful truth which no one had -ever dared to breathe before — the unwhisperable secret of secrets — The fact -that this language of stone and stridor is not a sentient perpetuation of Rust -as London is of Old London and Paris of Old Paris, but that it is in fact +> Instead of the programs I had hoped for, there came only a shuddering +blackness and ineffable loneliness; and I saw at last a fearful truth which no +one had ever dared to breathe before — the unwhisperable secret of secrets — The +fact that this language of stone and stridor is not a sentient perpetuation of +Rust as London is of Old London and Paris of Old Paris, but that it is in fact quite unsafe, its sprawling body imperfectly embalmed and infested with queer animate things which have nothing to do with it as it was in compilation. @@ -23,40 +23,30 @@ infinitesimal fragments of despair. Building the Nomicon requires [mdBook]. To get it: -[mdBook]: https://github.com/azerupi/mdBook +[mdBook]: https://github.com/rust-lang-nursery/mdBook ```bash $ cargo install mdbook ``` -### Building +### `mdbook` usage -To build the Nomicon: +To build the Nomicon use the `build` sub-command: ```bash $ mdbook build ``` -The output will be in the `book` subdirectory. To check it out, open it in -your web browser. +The output will be placed in the `book` subdirectory. To check it out, open the +`index.html` file in your web browser. You can pass the `--open` flag to `mdbook +build` and it'll open the index page in your default browser (if the process is +successful) just like with `cargo doc --open`: -_Firefox:_ ```bash -$ firefox book/index.html # Linux -$ open -a "Firefox" book/index.html # OS X -$ Start-Process "firefox.exe" .\book\index.html # Windows (PowerShell) -$ start firefox.exe .\book\index.html # Windows (Cmd) +$ mdbook build --open ``` -_Chrome:_ -```bash -$ google-chrome book/index.html # Linux -$ open -a "Google Chrome" book/index.html # OS X -$ Start-Process "chrome.exe" .\book\index.html # Windows (PowerShell) -$ start chrome.exe .\book\index.html # Windows (Cmd) -``` - -To run the tests: +There is also a `test` sub-command to test all code samples contained in the book: ```bash $ mdbook test @@ -64,7 +54,8 @@ $ mdbook test ## Contributing -Given that the Nomicon is still in a draft state, we'd love your help! Please feel free to open -issues about anything, and send in PRs for things you'd like to fix or change. If your change is -large, please open an issue first, so we can make sure that it's something we'd accept before you -go through the work of getting a PR together. \ No newline at end of file +Given that the Nomicon is still in a draft state, we'd love your help! Please +feel free to open issues about anything, and send in PRs for things you'd like +to fix or change. If your change is large, please open an issue first, so we can +make sure that it's something we'd accept before you go through the work of +getting a PR together. diff --git a/src/doc/nomicon/src/README.md b/src/doc/nomicon/src/README.md index a0bcd739e2..cc50b5f459 100644 --- a/src/doc/nomicon/src/README.md +++ b/src/doc/nomicon/src/README.md @@ -17,7 +17,7 @@ language — this book contains lots of useful information. Unlike *[The Rust Programming Language][trpl]*, we will be assuming considerable prior knowledge. In particular, you should be comfortable with basic systems programming and Rust. If you don't feel comfortable with these topics, you -should consider [reading The Book][trpl] first. That said, we won't assume you +should consider reading [The Book][trpl] first. That said, we won't assume you have read it, and we will take care to occasionally give a refresher on the basics where appropriate. You can skip straight to this book if you want; just know that we won't be explaining everything from the ground up. diff --git a/src/doc/nomicon/src/dropck.md b/src/doc/nomicon/src/dropck.md index 61a96dd824..ada4853b7c 100644 --- a/src/doc/nomicon/src/dropck.md +++ b/src/doc/nomicon/src/dropck.md @@ -25,7 +25,7 @@ let y; There are some more complex situations which are not possible to desugar using scopes, but the order is still defined ‒ variables are dropped in the reverse order of their definition, fields of structs and tuples in order of their -definition. There are some more details about order of drop in [rfc1875]. +definition. There are some more details about order of drop in [RFC 1857][rfc1857]. Let's do this: diff --git a/src/doc/nomicon/src/lifetime-mismatch.md b/src/doc/nomicon/src/lifetime-mismatch.md index 5d7500dd99..d96240e376 100644 --- a/src/doc/nomicon/src/lifetime-mismatch.md +++ b/src/doc/nomicon/src/lifetime-mismatch.md @@ -80,7 +80,6 @@ This will eventually get fixed. ```rust,edition2018,compile_fail # use std::collections::HashMap; -# use std::cmp::Eq; # use std::hash::Hash; fn get_default<'m, K, V>(map: &'m mut HashMap, key: K) -> &'m mut V where diff --git a/src/doc/nomicon/src/transmutes.md b/src/doc/nomicon/src/transmutes.md index a17fab0246..bc056bd2a5 100644 --- a/src/doc/nomicon/src/transmutes.md +++ b/src/doc/nomicon/src/transmutes.md @@ -4,7 +4,7 @@ Get out of our way type system! We're going to reinterpret these bits or die trying! Even though this book is all about doing things that are unsafe, I really can't emphasize that you should deeply think about finding Another Way than the operations covered in this section. This is really, truly, the most -horribly unsafe thing you can do in Rust. The railguards here are dental floss. +horribly unsafe thing you can do in Rust. The guardrails here are dental floss. [`mem::transmute`][transmute] takes a value of type `T` and reinterprets it to have type `U`. The only restriction is that the `T` and `U` are verified diff --git a/src/doc/reference/.travis.yml b/src/doc/reference/.travis.yml index 83744b0019..3d8979ffe0 100644 --- a/src/doc/reference/.travis.yml +++ b/src/doc/reference/.travis.yml @@ -4,7 +4,7 @@ rust: - nightly install: - - travis_retry curl -Lf https://github.com/rust-lang-nursery/mdBook/releases/download/v0.1.7/mdbook-v0.1.7-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin + - travis_retry curl -Lf https://github.com/rust-lang-nursery/mdBook/releases/download/v0.3.1/mdbook-v0.3.1-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin script: - export PATH=$PATH:/home/travis/.cargo/bin && mdbook test diff --git a/src/doc/reference/book.toml b/src/doc/reference/book.toml index 5dd7556845..05a93bb3d1 100644 --- a/src/doc/reference/book.toml +++ b/src/doc/reference/book.toml @@ -4,5 +4,5 @@ title = "The Rust Reference" author = "The Rust Project Developers" [output.html] - -additional-css = ["src/theme/reference.css"] +additional-css = ["theme/reference.css"] +git-repository-url = "https://github.com/rust-lang-nursery/reference/" diff --git a/src/doc/reference/src/abi.md b/src/doc/reference/src/abi.md index 642ac42bcd..f244ead5db 100644 --- a/src/doc/reference/src/abi.md +++ b/src/doc/reference/src/abi.md @@ -85,11 +85,11 @@ to specify the symbol name. pub fn name_in_rust() { } ``` -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax -[`static` items]: items/static-items.html -[attribute]: attributes.html -[extern functions]: items/functions.html#extern-functions -[external blocks]: items/external-blocks.html -[function]: items/functions.html -[item]: items.html -[static]: items/static-items.html +[_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax +[`static` items]: items/static-items.md +[attribute]: attributes.md +[extern functions]: items/functions.md#extern-functions +[external blocks]: items/external-blocks.md +[function]: items/functions.md +[item]: items.md +[static]: items/static-items.md diff --git a/src/doc/reference/src/attributes.md b/src/doc/reference/src/attributes.md index 875e54ec34..df2bb460fe 100644 --- a/src/doc/reference/src/attributes.md +++ b/src/doc/reference/src/attributes.md @@ -237,72 +237,72 @@ The following is an index of all built-in attributes. - `feature` — Used to enable unstable or experimental compiler features. See [The Unstable Book] for features implemented in `rustc`. -[Doc comments]: comments.html#doc-comments +[Doc comments]: comments.md#doc-comments [ECMA-334]: https://www.ecma-international.org/publications/standards/Ecma-334.htm [ECMA-335]: https://www.ecma-international.org/publications/standards/Ecma-335.htm -[Expression Attributes]: expressions.html#expression-attributes -[IDENTIFIER]: identifiers.html -[RAW_STRING_LITERAL]: tokens.html#raw-string-literals -[STRING_LITERAL]: tokens.html#string-literals +[Expression Attributes]: expressions.md#expression-attributes +[IDENTIFIER]: identifiers.md +[RAW_STRING_LITERAL]: tokens.md#raw-string-literals +[STRING_LITERAL]: tokens.md#string-literals [The Rustdoc Book]: ../rustdoc/the-doc-attribute.html [The Unstable Book]: ../unstable-book/index.html -[_DelimTokenTree_]: macros.html -[_LiteralExpression_]: expressions/literal-expr.html -[_SimplePath_]: paths.html#simple-paths -[`allow`]: attributes/diagnostics.html#lint-check-attributes -[`cfg_attr`]: conditional-compilation.html#the-cfg_attr-attribute -[`cfg`]: conditional-compilation.html#the-cfg-attribute -[`cold`]: attributes/codegen.html#the-cold-attribute -[`crate_name`]: crates-and-source-files.html#the-crate_name-attribute -[`crate_type`]: linkage.html -[`deny`]: attributes/diagnostics.html#lint-check-attributes -[`deprecated`]: attributes/diagnostics.html#the-deprecated-attribute -[`derive`]: attributes/derive.html -[`export_name`]: abi.html#the-export_name-attribute -[`forbid`]: attributes/diagnostics.html#lint-check-attributes -[`global_allocator`]: runtime.html#the-global_allocator-attribute -[`ignore`]: attributes/testing.html#the-ignore-attribute -[`inline`]: attributes/codegen.html#the-inline-attribute -[`link_name`]: items/external-blocks.html#the-link_name-attribute -[`link_section`]: abi.html#the-link_section-attribute -[`link`]: items/external-blocks.html#the-link-attribute -[`macro_export`]: macros-by-example.html#path-based-scope -[`macro_use`]: macros-by-example.html#the-macro_use-attribute -[`meta` macro fragment specifier]: macros-by-example.html -[`must_use`]: attributes/diagnostics.html#the-must_use-attribute -[`no_builtins`]: attributes/codegen.html#the-no_builtins-attribute -[`no_implicit_prelude`]: items/modules.html#prelude-items -[`no_link`]: items/extern-crates.html#the-no_link-attribute -[`no_main`]: crates-and-source-files.html#the-no_main-attribute -[`no_mangle`]: abi.html#the-no_mangle-attribute -[`no_std`]: crates-and-source-files.html#preludes-and-no_std -[`panic_handler`]: runtime.html#the-panic_handler-attribute -[`path`]: items/modules.html#the-path-attribute -[`proc_macro_attribute`]: procedural-macros.html#attribute-macros -[`proc_macro_derive`]: procedural-macros.html#derive-macros -[`proc_macro`]: procedural-macros.html#function-like-procedural-macros -[`recursion_limit`]: attributes/limits.html#the-recursion_limit-attribute -[`repr`]: type-layout.html#representations -[`should_panic`]: attributes/testing.html#the-should_panic-attribute -[`target_feature`]: attributes/codegen.html#the-target_feature-attribute -[`test`]: attributes/testing.html#the-test-attribute -[`type_length_limit`]: attributes/limits.html#the-type_length_limit-attribute -[`used`]: abi.html#the-used-attribute -[`warn`]: attributes/diagnostics.html#lint-check-attributes -[`windows_subsystem`]: runtime.html#the-windows_subsystem-attribute -[attribute macros]: procedural-macros.html#attribute-macros -[block expressions]: expressions/block-expr.html +[_DelimTokenTree_]: macros.md +[_LiteralExpression_]: expressions/literal-expr.md +[_SimplePath_]: paths.md#simple-paths +[`allow`]: attributes/diagnostics.md#lint-check-attributes +[`cfg_attr`]: conditional-compilation.md#the-cfg_attr-attribute +[`cfg`]: conditional-compilation.md#the-cfg-attribute +[`cold`]: attributes/codegen.md#the-cold-attribute +[`crate_name`]: crates-and-source-files.md#the-crate_name-attribute +[`crate_type`]: linkage.md +[`deny`]: attributes/diagnostics.md#lint-check-attributes +[`deprecated`]: attributes/diagnostics.md#the-deprecated-attribute +[`derive`]: attributes/derive.md +[`export_name`]: abi.md#the-export_name-attribute +[`forbid`]: attributes/diagnostics.md#lint-check-attributes +[`global_allocator`]: runtime.md#the-global_allocator-attribute +[`ignore`]: attributes/testing.md#the-ignore-attribute +[`inline`]: attributes/codegen.md#the-inline-attribute +[`link_name`]: items/external-blocks.md#the-link_name-attribute +[`link_section`]: abi.md#the-link_section-attribute +[`link`]: items/external-blocks.md#the-link-attribute +[`macro_export`]: macros-by-example.md#path-based-scope +[`macro_use`]: macros-by-example.md#the-macro_use-attribute +[`meta` macro fragment specifier]: macros-by-example.md +[`must_use`]: attributes/diagnostics.md#the-must_use-attribute +[`no_builtins`]: attributes/codegen.md#the-no_builtins-attribute +[`no_implicit_prelude`]: items/modules.md#prelude-items +[`no_link`]: items/extern-crates.md#the-no_link-attribute +[`no_main`]: crates-and-source-files.md#the-no_main-attribute +[`no_mangle`]: abi.md#the-no_mangle-attribute +[`no_std`]: crates-and-source-files.md#preludes-and-no_std +[`panic_handler`]: runtime.md#the-panic_handler-attribute +[`path`]: items/modules.md#the-path-attribute +[`proc_macro_attribute`]: procedural-macros.md#attribute-macros +[`proc_macro_derive`]: procedural-macros.md#derive-macros +[`proc_macro`]: procedural-macros.md#function-like-procedural-macros +[`recursion_limit`]: attributes/limits.md#the-recursion_limit-attribute +[`repr`]: type-layout.md#representations +[`should_panic`]: attributes/testing.md#the-should_panic-attribute +[`target_feature`]: attributes/codegen.md#the-target_feature-attribute +[`test`]: attributes/testing.md#the-test-attribute +[`type_length_limit`]: attributes/limits.md#the-type_length_limit-attribute +[`used`]: abi.md#the-used-attribute +[`warn`]: attributes/diagnostics.md#lint-check-attributes +[`windows_subsystem`]: runtime.md#the-windows_subsystem-attribute +[attribute macros]: procedural-macros.md#attribute-macros +[block expressions]: expressions/block-expr.md [built-in attributes]: #built-in-attributes-index -[derive macro helper attributes]: procedural-macros.html#derive-macro-helper-attributes -[enum]: items/enumerations.html -[expression statement]: statements.html#expression-statements -[external blocks]: items/external-blocks.html -[functions]: items/functions.html -[generics]: items/generics.html -[implementations]: items/implementations.html -[item declarations]: items.html -[match expressions]: expressions/match-expr.html -[modules]: items/modules.html -[statements]: statements.html -[struct]: items/structs.html -[union]: items/unions.html +[derive macro helper attributes]: procedural-macros.md#derive-macro-helper-attributes +[enum]: items/enumerations.md +[expression statement]: statements.md#expression-statements +[external blocks]: items/external-blocks.md +[functions]: items/functions.md +[generics]: items/generics.md +[implementations]: items/implementations.md +[item declarations]: items.md +[match expressions]: expressions/match-expr.md +[modules]: items/modules.md +[statements]: statements.md +[struct]: items/structs.md +[union]: items/unions.md diff --git a/src/doc/reference/src/attributes/codegen.md b/src/doc/reference/src/attributes/codegen.md index a7f79c20d7..c9ac02d5bc 100644 --- a/src/doc/reference/src/attributes/codegen.md +++ b/src/doc/reference/src/attributes/codegen.md @@ -139,15 +139,15 @@ feature detection on the x86 platforms. > may be enabled or disabled for an entire crate with the > [`-C target-feature`] flag. -[_MetaListNameValueStr_]: attributes.html#meta-item-attribute-syntax -[`-C target-cpu`]: ../rustc/codegen-options/index.html#target-cpu -[`-C target-feature`]: ../rustc/codegen-options/index.html#target-feature -[`is_x86_feature_detected`]: ../std/macro.is_x86_feature_detected.html -[`target_feature` conditional compilation option]: conditional-compilation.html#target_feature -[attribute]: attributes.html -[attributes]: attributes.html -[functions]: items/functions.html -[target architecture]: conditional-compilation.html#target_arch -[trait]: items/traits.html -[undefined behavior]: behavior-considered-undefined.html -[unsafe function]: unsafe-functions.html +[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu +[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature +[`is_x86_feature_detected`]: ../../std/macro.is_x86_feature_detected.html +[`target_feature` conditional compilation option]: ../conditional-compilation.md#target_feature +[attribute]: ../attributes.md +[attributes]: ../attributes.md +[functions]: ../items/functions.md +[target architecture]: ../conditional-compilation.md#target_arch +[trait]: ../items/traits.md +[undefined behavior]: ../behavior-considered-undefined.md +[unsafe function]: ../unsafe-functions.md diff --git a/src/doc/reference/src/attributes/derive.md b/src/doc/reference/src/attributes/derive.md index ba0496a609..5859ca93d7 100644 --- a/src/doc/reference/src/attributes/derive.md +++ b/src/doc/reference/src/attributes/derive.md @@ -33,10 +33,10 @@ impl PartialEq for Foo { You can implement `derive` for your own traits through [procedural macros]. -[_MetaListPaths_]: attributes.html#meta-item-attribute-syntax -[`Clone`]: ../std/clone/trait.Clone.html -[`PartialEq`]: ../std/cmp/trait.PartialEq.html -[`impl` item]: items/implementations.html -[items]: items.html -[derive macros]: procedural-macros.html#derive-macros -[procedural macros]: procedural-macros.html#derive-macros +[_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax +[`Clone`]: ../../std/clone/trait.Clone.html +[`PartialEq`]: ../../std/cmp/trait.PartialEq.html +[`impl` item]: ../items/implementations.md +[items]: ../items.md +[derive macros]: ../procedural-macros.md#derive-macros +[procedural macros]: ../procedural-macros.md#derive-macros diff --git a/src/doc/reference/src/attributes/diagnostics.md b/src/doc/reference/src/attributes/diagnostics.md index c648e059d5..9357a5f268 100644 --- a/src/doc/reference/src/attributes/diagnostics.md +++ b/src/doc/reference/src/attributes/diagnostics.md @@ -253,29 +253,29 @@ When used on a function in a trait implementation, the attribute does nothing. > ``` [Clippy]: https://github.com/rust-lang/rust-clippy -[_MetaListNameValueStr_]: attributes.html#meta-item-attribute-syntax -[_MetaListPaths_]: attributes.html#meta-item-attribute-syntax -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax -[`Drop`]: special-types-and-traits.html#drop -[attributes]: attributes.html -[block expression]: expressions/block-expr.html -[call expression]: expressions/call-expr.html -[enum variant]: items/enumerations.html -[enum]: items/enumerations.html -[expression statement]: statements.html#expression-statements -[expression]: expressions.html -[external block item]: items/external-blocks.html -[functions]: items/functions.html -[impl trait]: types/impl-trait.html -[implementation]: items/implementations.html -[item]: items.html -[let statement]: statements.html#let-statements -[module]: items/modules.html -[rustc book]: ../rustc/lints/index.html -[struct field]: items/structs.html -[struct]: items/structs.html -[trait declaration]: items/traits.html -[trait implementation items]: items/implementations.html#trait-implementations -[trait item]: items/traits.html -[traits]: items/traits.html -[union]: items/unions.html +[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax +[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[`Drop`]: ../special-types-and-traits.md#drop +[attributes]: ../attributes.md +[block expression]: ../expressions/block-expr.md +[call expression]: ../expressions/call-expr.md +[enum variant]: ../items/enumerations.md +[enum]: ../items/enumerations.md +[expression statement]: ../statements.md#expression-statements +[expression]: ../expressions.md +[external block item]: ../items/external-blocks.md +[functions]: ../items/functions.md +[impl trait]: ../types/impl-trait.md +[implementation]: ../items/implementations.md +[item]: ../items.md +[let statement]: ../statements.md#let-statements +[module]: ../items/modules.md +[rustc book]: ../../rustc/lints/index.html +[struct field]: ../items/structs.md +[struct]: ../items/structs.md +[trait declaration]: ../items/traits.md +[trait implementation items]: ../items/implementations.md#trait-implementations +[trait item]: ../items/traits.md +[traits]: ../items/traits.md +[union]: ../items/unions.md diff --git a/src/doc/reference/src/attributes/limits.md b/src/doc/reference/src/attributes/limits.md index 1ff5b8883f..1cb80e302d 100644 --- a/src/doc/reference/src/attributes/limits.md +++ b/src/doc/reference/src/attributes/limits.md @@ -9,7 +9,7 @@ maximum depth for potentially infinitely-recursive compile-time operations like macro expansion or auto-dereference. It uses the [_MetaNameValueStr_] syntax to specify the recursion depth. -> Note: The default in `rustc` is 64. +> Note: The default in `rustc` is 128. ```rust,compile_fail #![recursion_limit = "4"] @@ -42,7 +42,11 @@ to set the limit based on the number of type substitutions. > Note: The default in `rustc` is 1048576. -```rust,compile_fail + + +```rust,compile_fail,ignore #![type_length_limit = "8"] fn f(x: T) {} @@ -50,9 +54,9 @@ fn f(x: T) {} // This fails to compile because monomorphizing to // `f::<(i32, i32, i32, i32, i32, i32, i32, i32, i32)>>` requires more // than 8 type elements. -f(((1, 2, 3, 4, 5, 6, 7, 8, 9)); +f((1, 2, 3, 4, 5, 6, 7, 8, 9)); ``` -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax -[attributes]: attributes.html -[crate]: crates-and-source-files.html +[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[attributes]: ../attributes.md +[crate]: ../crates-and-source-files.md diff --git a/src/doc/reference/src/attributes/testing.md b/src/doc/reference/src/attributes/testing.md index 54e05a5f55..e0181b1c34 100644 --- a/src/doc/reference/src/attributes/testing.md +++ b/src/doc/reference/src/attributes/testing.md @@ -82,8 +82,8 @@ fn mytest() { } ``` -[_MetaListNameValueStr_]: attributes.html#meta-item-attribute-syntax -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax -[`Termination`]: ../std/process/trait.Termination.html -[`test` conditional compilation option]: conditional-compilation.html#test -[attributes]: attributes.html +[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[`Termination`]: ../../std/process/trait.Termination.html +[`test` conditional compilation option]: ../conditional-compilation.md#test +[attributes]: ../attributes.md diff --git a/src/doc/reference/src/behavior-considered-undefined.md b/src/doc/reference/src/behavior-considered-undefined.md index 2a895d1940..b6a9aabe93 100644 --- a/src/doc/reference/src/behavior-considered-undefined.md +++ b/src/doc/reference/src/behavior-considered-undefined.md @@ -1,9 +1,16 @@ ## Behavior considered undefined -Rust code, including within `unsafe` blocks and `unsafe` functions is incorrect -if it exhibits any of the behaviors in the following list. It is the -programmer's responsibility when writing `unsafe` code that it is not possible -to let `safe` code exhibit these behaviors. +Rust code is incorrect if it exhibits any of the behaviors in the following +list. This includes code within `unsafe` blocks and `unsafe` functions. +`unsafe` only means that avoiding undefined behavior is on the programmer; it +does not change anything about the fact that Rust programs must never cause +undefined behavior. + +It is the programmer's responsibility when writing `unsafe` code to ensure that +any safe code interacting with the `unsafe` code cannot trigger these +behaviors. `unsafe` code that satisfies this property for any safe client is +called *sound*; if `unsafe` code can be misused by safe code to exhibit +undefined behavior, it is *unsound*.
@@ -52,7 +59,7 @@ code. [undef]: http://llvm.org/docs/LangRef.html#undefined-values [`offset`]: ../std/primitive.pointer.html#method.offset [`std::ptr::copy_nonoverlapping_memory`]: ../std/ptr/fn.copy_nonoverlapping.html -[`target_feature`]: attributes/codegen.html#the-target_feature-attribute +[`target_feature`]: attributes/codegen.md#the-target_feature-attribute [`UnsafeCell`]: ../std/cell/struct.UnsafeCell.html [`read_unaligned`]: ../std/ptr/fn.read_unaligned.html [`write_unaligned`]: ../std/ptr/fn.write_unaligned.html diff --git a/src/doc/reference/src/conditional-compilation.md b/src/doc/reference/src/conditional-compilation.md index 911a8c330d..a041bc3c7b 100644 --- a/src/doc/reference/src/conditional-compilation.md +++ b/src/doc/reference/src/conditional-compilation.md @@ -310,19 +310,19 @@ let machine_kind = if cfg!(unix) { println!("I'm running on a {} machine!", machine_kind); ``` -[IDENTIFIER]: identifiers.html -[RAW_STRING_LITERAL]: tokens.html#raw-string-literals -[STRING_LITERAL]: tokens.html#string-literals -[Testing]: attributes/testing.html -[_Attr_]: attributes.html -[`--cfg`]: ../rustc/command-line-arguments.html#a--cfg-configure-the-compilation-environment -[`--test`]: ../rustc/command-line-arguments.html#a--test-build-a-test-harness +[IDENTIFIER]: identifiers.md +[RAW_STRING_LITERAL]: tokens.md#raw-string-literals +[STRING_LITERAL]: tokens.md#string-literals +[Testing]: attributes/testing.md +[_Attr_]: attributes.md +[`--cfg`]: ../rustc/command-line-arguments.html#--cfg-configure-the-compilation-environment +[`--test`]: ../rustc/command-line-arguments.html#--test-build-a-test-harness [`cfg`]: #the-cfg-attribute [`cfg` macro]: #the-cfg-macro [`cfg_attr`]: #the-cfg_attr-attribute [`debug_assert!`]: ../std/macro.debug_assert.html -[`target_feature` attribute]: attributes/codegen.html#the-target_feature-attribute -[attribute]: attributes.html -[attributes]: attributes.html -[crate type]: linkage.html -[static C runtime]: linkage.html#static-and-dynamic-c-runtimes +[`target_feature` attribute]: attributes/codegen.md#the-target_feature-attribute +[attribute]: attributes.md +[attributes]: attributes.md +[crate type]: linkage.md +[static C runtime]: linkage.md#static-and-dynamic-c-runtimes diff --git a/src/doc/reference/src/const_eval.md b/src/doc/reference/src/const_eval.md index eacd2db2c2..6d9826c1cf 100644 --- a/src/doc/reference/src/const_eval.md +++ b/src/doc/reference/src/const_eval.md @@ -57,39 +57,39 @@ A _const context_ is one of the following: * [statics] * [enum discriminants] -[arithmetic, logical]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators -[array expressions]: expressions/array-expr.html -[array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions -[array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions -[array type length expressions]: types/array.html -[assignment expressions]: expressions/operator-expr.html#assignment-expressions -[assignment operator expressions]: expressions/operator-expr.html#compound-assignment-expressions -[block expressions]: expressions/block-expr.html -[borrow]: expressions/operator-expr.html#borrow-operators -[cast]: expressions/operator-expr.html#type-cast-expressions -[closure expressions]: expressions/closure-expr.html -[comparison]: expressions/operator-expr.html#comparison-operators -[const functions]: items/functions.html#const-functions -[constants]: items/constant-items.html -[dereference operator]: expressions/operator-expr.html#the-dereference-operator -[destructors]: destructors.html -[enum discriminants]: items/enumerations.html#custom-discriminant-values-for-field-less-enumerations -[enum variant]: expressions/enum-variant-expr.html -[expression statements]: statements.html#expression-statements -[expressions]: expressions.html -[field]: expressions/field-expr.html -[functions]: items/functions.html -[grouped]: expressions/grouped-expr.html -[interior mutability]: interior-mutability.html -[lazy boolean]: expressions/operator-expr.html#lazy-boolean-operators -[let statements]: statements.html#let-statements -[literals]: expressions/literal-expr.html -[negation]: expressions/operator-expr.html#negation-operators -[overflow]: expressions/operator-expr.html#overflow -[paths]: expressions/path-expr.html -[patterns]: patterns.html -[range expressions]: expressions/range-expr.html -[slice]: types/slice.html -[statics]: items/static-items.html -[struct]: expressions/struct-expr.html -[tuple expressions]: expressions/tuple-expr.html +[arithmetic, logical]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[array expressions]: expressions/array-expr.md +[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions +[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions +[array type length expressions]: types/array.md +[assignment expressions]: expressions/operator-expr.md#assignment-expressions +[assignment operator expressions]: expressions/operator-expr.md#compound-assignment-expressions +[block expressions]: expressions/block-expr.md +[borrow]: expressions/operator-expr.md#borrow-operators +[cast]: expressions/operator-expr.md#type-cast-expressions +[closure expressions]: expressions/closure-expr.md +[comparison]: expressions/operator-expr.md#comparison-operators +[const functions]: items/functions.md#const-functions +[constants]: items/constant-items.md +[dereference operator]: expressions/operator-expr.md#the-dereference-operator +[destructors]: destructors.md +[enum discriminants]: items/enumerations.md#custom-discriminant-values-for-field-less-enumerations +[enum variant]: expressions/enum-variant-expr.md +[expression statements]: statements.md#expression-statements +[expressions]: expressions.md +[field]: expressions/field-expr.md +[functions]: items/functions.md +[grouped]: expressions/grouped-expr.md +[interior mutability]: interior-mutability.md +[lazy boolean]: expressions/operator-expr.md#lazy-boolean-operators +[let statements]: statements.md#let-statements +[literals]: expressions/literal-expr.md +[negation]: expressions/operator-expr.md#negation-operators +[overflow]: expressions/operator-expr.md#overflow +[paths]: expressions/path-expr.md +[patterns]: patterns.md +[range expressions]: expressions/range-expr.md +[slice]: types/slice.md +[statics]: items/static-items.md +[struct]: expressions/struct-expr.md +[tuple expressions]: expressions/tuple-expr.md diff --git a/src/doc/reference/src/crates-and-source-files.md b/src/doc/reference/src/crates-and-source-files.md index d21655cbee..ce35a85fb7 100644 --- a/src/doc/reference/src/crates-and-source-files.md +++ b/src/doc/reference/src/crates-and-source-files.md @@ -152,21 +152,21 @@ or `-` (U+002D) characters. in the Owens and Flatt module system, or a *configuration* in Mesa. [Unicode alphanumeric]: ../std/primitive.char.html#method.is_alphanumeric -[_InnerAttribute_]: attributes.html -[_Item_]: items.html -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax +[_InnerAttribute_]: attributes.md +[_Item_]: items.md +[_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax [_shebang_]: https://en.wikipedia.org/wiki/Shebang_(Unix) [_utf8 byte order mark_]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 [`Termination`]: ../std/process/trait.Termination.html [`core`]: ../core/index.html [`core::prelude::v1`]: ../core/prelude/index.html -[`extern crate`]: items/extern-crates.html +[`extern crate`]: items/extern-crates.md [`std`]: ../std/index.html [`std::prelude::v1`]: ../std/prelude/index.html -[attribute]: attributes.html -[attributes]: attributes.html -[function]: items/functions.html -[module]: items/modules.html -[module path]: paths.html -[trait or lifetime bounds]: trait-bounds.html -[where clauses]: items/generics.html#where-clauses +[attribute]: attributes.md +[attributes]: attributes.md +[function]: items/functions.md +[module]: items/modules.md +[module path]: paths.md +[trait or lifetime bounds]: trait-bounds.md +[where clauses]: items/generics.md#where-clauses diff --git a/src/doc/reference/src/destructors.md b/src/doc/reference/src/destructors.md index 49a8613221..a24451d82e 100644 --- a/src/doc/reference/src/destructors.md +++ b/src/doc/reference/src/destructors.md @@ -63,10 +63,15 @@ loop { moved = ShowOnDrop("Drops when moved"); // drops now, but is then uninitialized moved; + + // Uninitialized does not drop. let uninitialized: ShowOnDrop; - // Only first element drops - let mut partially_initialized: (ShowOnDrop, ShowOnDrop); - partially_initialized.0 = ShowOnDrop("Partial tuple first"); + + // After a partial move, only the remaining fields are dropped. + let mut partial_move = (ShowOnDrop("first"), ShowOnDrop("forgotten")); + // Perform a partial move, leaving only `partial_move.0` initialized. + core::mem::forget(partial_move.1); + // When partial_move's scope ends, only the first field is dropped. } ``` @@ -76,17 +81,17 @@ Not running destructors in Rust is safe even if it has a type that isn't `'static`. [`std::mem::ManuallyDrop`] provides a wrapper to prevent a variable or field from being dropped automatically. -[initialized]: glossary.html#initialized -[variable]: variables.html -[temporary]: expressions.html#temporary-lifetimes -[Assignment]: expressions/operator-expr.html#assignment-expressions +[initialized]: glossary.md#initialized +[variable]: variables.md +[temporary]: expressions.md#temporary-lifetimes +[Assignment]: expressions/operator-expr.md#assignment-expressions [`std::ops::Drop::drop`]: ../std/ops/trait.Drop.html [RFC 1857]: https://github.com/rust-lang/rfcs/blob/master/text/1857-stabilize-drop-order.md -[struct]: types/struct.html -[tuple]: types/tuple.html -[enum variant]: types/enum.html -[array]: types/array.html -[closure]: types/closure.html -[Trait objects]: types/trait-object.html +[struct]: types/struct.md +[tuple]: types/tuple.md +[enum variant]: types/enum.md +[array]: types/array.md +[closure]: types/closure.md +[Trait objects]: types/trait-object.md [`std::ptr::drop_in_place`]: ../std/ptr/fn.drop_in_place.html [`std::mem::ManuallyDrop`]: ../std/mem/struct.ManuallyDrop.html diff --git a/src/doc/reference/src/dynamically-sized-types.md b/src/doc/reference/src/dynamically-sized-types.md index 7fd25ab30b..39154a2b51 100644 --- a/src/doc/reference/src/dynamically-sized-types.md +++ b/src/doc/reference/src/dynamically-sized-types.md @@ -23,10 +23,10 @@ types">DSTs. Such types can only be used in certain cases: Notably: [variables], function parameters, [const] and [static] items must be `Sized`. -[sized]: special-types-and-traits.html#sized -[Slices]: types/slice.html -[trait objects]: types/trait-object.html -[Pointer types]: types/pointer.html -[variables]: variables.html -[const]: items/constant-items.html -[static]: items/static-items.html +[sized]: special-types-and-traits.md#sized +[Slices]: types/slice.md +[trait objects]: types/trait-object.md +[Pointer types]: types/pointer.md +[variables]: variables.md +[const]: items/constant-items.md +[static]: items/static-items.md diff --git a/src/doc/reference/src/expressions.md b/src/doc/reference/src/expressions.md index 006a892796..c211fa933e 100644 --- a/src/doc/reference/src/expressions.md +++ b/src/doc/reference/src/expressions.md @@ -281,76 +281,76 @@ They are never allowed before: [_AssignmentExpression_], [_CompoundAssignmentExpression_]). -[block expressions]: expressions/block-expr.html -[call expressions]: expressions/call-expr.html -[enum variant]: expressions/enum-variant-expr.html -[field]: expressions/field-expr.html -[functional update]: expressions/struct-expr.html#functional-update-syntax -[`if let`]: expressions/if-expr.html#if-let-expressions -[match]: expressions/match-expr.html -[method-call]: expressions/method-call-expr.html -[paths]: expressions/path-expr.html -[struct]: expressions/struct-expr.html -[tuple expressions]: expressions/tuple-expr.html -[`while let`]: expressions/loop-expr.html#predicate-pattern-loops - -[array expressions]: expressions/array-expr.html -[array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions - -[assign]: expressions/operator-expr.html#assignment-expressions -[borrow]: expressions/operator-expr.html#borrow-operators -[comparison]: expressions/operator-expr.html#comparison-operators -[compound assignment]: expressions/operator-expr.html#compound-assignment-expressions -[deref]: expressions/operator-expr.html#the-dereference-operator - -[destructors]: destructors.html -[interior mutability]: interior-mutability.html -[`Box`]: ../std/boxed/struct.Box.html -[`Copy`]: special-types-and-traits.html#copy -[`Drop`]: special-types-and-traits.html#drop -[`Sized`]: special-types-and-traits.html#sized +[block expressions]: expressions/block-expr.md +[call expressions]: expressions/call-expr.md +[enum variant]: expressions/enum-variant-expr.md +[field]: expressions/field-expr.md +[functional update]: expressions/struct-expr.md#functional-update-syntax +[`if let`]: expressions/if-expr.md#if-let-expressions +[match]: expressions/match-expr.md +[method-call]: expressions/method-call-expr.md +[paths]: expressions/path-expr.md +[struct]: expressions/struct-expr.md +[tuple expressions]: expressions/tuple-expr.md +[`while let`]: expressions/loop-expr.md#predicate-pattern-loops + +[array expressions]: expressions/array-expr.md +[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions + +[assign]: expressions/operator-expr.md#assignment-expressions +[borrow]: expressions/operator-expr.md#borrow-operators +[comparison]: expressions/operator-expr.md#comparison-operators +[compound assignment]: expressions/operator-expr.md#compound-assignment-expressions +[deref]: expressions/operator-expr.md#the-dereference-operator + +[destructors]: destructors.md +[interior mutability]: interior-mutability.md +[`Box`]: ../std/boxed/struct.Box.md +[`Copy`]: special-types-and-traits.md#copy +[`Drop`]: special-types-and-traits.md#drop +[`Sized`]: special-types-and-traits.md#sized [implicit borrow]: #implicit-borrows [implicitly mutably borrowed]: #implicit-borrows -[let]: statements.html#let-statements -[let statement]: statements.html#let-statements -[Mutable `static` items]: items/static-items.html#mutable-statics -[scrutinee]: glossary.html#scrutinee -[slice]: types/slice.html -[statement]: statements.html -[static variables]: items/static-items.html +[let]: statements.md#let-statements +[let statement]: statements.md#let-statements +[Mutable `static` items]: items/static-items.md#mutable-statics +[scrutinee]: glossary.md#scrutinee +[slice]: types/slice.md +[statement]: statements.md +[static variables]: items/static-items.md [Temporary values]: #temporary-lifetimes -[Variables]: variables.html - - -[_ArithmeticOrLogicalExpression_]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators -[_ArrayExpression_]: expressions/array-expr.html -[_AssignmentExpression_]: expressions/operator-expr.html#assignment-expressions -[_BlockExpression_]: expressions/block-expr.html -[_BreakExpression_]: expressions/loop-expr.html#break-expressions -[_CallExpression_]: expressions/call-expr.html -[_ClosureExpression_]: expressions/closure-expr.html -[_ComparisonExpression_]: expressions/operator-expr.html#comparison-operators -[_CompoundAssignmentExpression_]: expressions/operator-expr.html#compound-assignment-expressions -[_ContinueExpression_]: expressions/loop-expr.html#continue-expressions -[_EnumerationVariantExpression_]: expressions/enum-variant-expr.html -[_FieldExpression_]: expressions/field-expr.html -[_GroupedExpression_]: expressions/grouped-expr.html -[_IfExpression_]: expressions/if-expr.html#if-expressions -[_IfLetExpression_]: expressions/if-expr.html#if-let-expressions -[_IndexExpression_]: expressions/array-expr.html#array-and-slice-indexing-expressions -[_LazyBooleanExpression_]: expressions/operator-expr.html#lazy-boolean-operators -[_LiteralExpression_]: expressions/literal-expr.html -[_LoopExpression_]: expressions/loop-expr.html -[_MacroInvocation_]: macros.html#macro-invocation -[_MatchExpression_]: expressions/match-expr.html -[_MethodCallExpression_]: expressions/method-call-expr.html -[_OperatorExpression_]: expressions/operator-expr.html -[_OuterAttribute_]: attributes.html -[_PathExpression_]: expressions/path-expr.html -[_RangeExpression_]: expressions/range-expr.html -[_ReturnExpression_]: expressions/return-expr.html -[_StructExpression_]: expressions/struct-expr.html -[_TupleExpression_]: expressions/tuple-expr.html -[_TupleIndexingExpression_]: expressions/tuple-expr.html#tuple-indexing-expressions -[_TypeCastExpression_]: expressions/operator-expr.html#type-cast-expressions -[_UnsafeBlockExpression_]: expressions/block-expr.html#unsafe-blocks +[Variables]: variables.md + + +[_ArithmeticOrLogicalExpression_]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[_ArrayExpression_]: expressions/array-expr.md +[_AssignmentExpression_]: expressions/operator-expr.md#assignment-expressions +[_BlockExpression_]: expressions/block-expr.md +[_BreakExpression_]: expressions/loop-expr.md#break-expressions +[_CallExpression_]: expressions/call-expr.md +[_ClosureExpression_]: expressions/closure-expr.md +[_ComparisonExpression_]: expressions/operator-expr.md#comparison-operators +[_CompoundAssignmentExpression_]: expressions/operator-expr.md#compound-assignment-expressions +[_ContinueExpression_]: expressions/loop-expr.md#continue-expressions +[_EnumerationVariantExpression_]: expressions/enum-variant-expr.md +[_FieldExpression_]: expressions/field-expr.md +[_GroupedExpression_]: expressions/grouped-expr.md +[_IfExpression_]: expressions/if-expr.md#if-expressions +[_IfLetExpression_]: expressions/if-expr.md#if-let-expressions +[_IndexExpression_]: expressions/array-expr.md#array-and-slice-indexing-expressions +[_LazyBooleanExpression_]: expressions/operator-expr.md#lazy-boolean-operators +[_LiteralExpression_]: expressions/literal-expr.md +[_LoopExpression_]: expressions/loop-expr.md +[_MacroInvocation_]: macros.md#macro-invocation +[_MatchExpression_]: expressions/match-expr.md +[_MethodCallExpression_]: expressions/method-call-expr.md +[_OperatorExpression_]: expressions/operator-expr.md +[_OuterAttribute_]: attributes.md +[_PathExpression_]: expressions/path-expr.md +[_RangeExpression_]: expressions/range-expr.md +[_ReturnExpression_]: expressions/return-expr.md +[_StructExpression_]: expressions/struct-expr.md +[_TupleExpression_]: expressions/tuple-expr.md +[_TupleIndexingExpression_]: expressions/tuple-expr.md#tuple-indexing-expressions +[_TypeCastExpression_]: expressions/operator-expr.md#type-cast-expressions +[_UnsafeBlockExpression_]: expressions/block-expr.md#unsafe-blocks diff --git a/src/doc/reference/src/expressions/array-expr.md b/src/doc/reference/src/expressions/array-expr.md index 7506934dd5..cf016acca7 100644 --- a/src/doc/reference/src/expressions/array-expr.md +++ b/src/doc/reference/src/expressions/array-expr.md @@ -10,7 +10,7 @@ >       [_Expression_] ( `,` [_Expression_] )\* `,`?\ >    | [_Expression_] `;` [_Expression_] -An _[array](types/array.html) expression_ can be written by +An _[array](../types/array.md) expression_ can be written by enclosing zero or more comma-separated expressions of uniform type in square brackets. This produces and array containing each of these values in the order they are written. @@ -18,11 +18,11 @@ order they are written. Alternatively there can be exactly two expressions inside the brackets, separated by a semi-colon. The expression after the `;` must be a have type `usize` and be a [constant expression], -such as a [literal](tokens.html#literals) or a [constant -item](items/constant-items.html). `[a; b]` creates an array containing `b` +such as a [literal](../tokens.md#literals) or a [constant +item](../items/constant-items.md). `[a; b]` creates an array containing `b` copies of the value of `a`. If the expression after the semi-colon has a value greater than 1 then this requires that the type of `a` is -[`Copy`](special-types-and-traits.html#copy). +[`Copy`](../special-types-and-traits.md#copy). ```rust [1, 2, 3, 4]; @@ -44,7 +44,7 @@ expressions]. > _IndexExpression_ :\ >    [_Expression_] `[` [_Expression_] `]` -[Array](types/array.html) and [slice](types/slice.html)-typed expressions can be +[Array](../types/array.md) and [slice](../types/slice.md)-typed expressions can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them. When the array is mutable, the resulting [memory location] can be assigned to. @@ -81,11 +81,11 @@ arr[10]; // warning: index out of bounds The array index expression can be implemented for types other than arrays and slices by implementing the [Index] and [IndexMut] traits. -[IndexMut]: ../std/ops/trait.IndexMut.html -[Index]: ../std/ops/trait.Index.html -[Inner attributes]: attributes.html -[_Expression_]: expressions.html -[_InnerAttribute_]: attributes.html -[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions -[constant expression]: const_eval.html#constant-expressions -[memory location]: expressions.html#place-expressions-and-value-expressions +[IndexMut]: ../../std/ops/trait.IndexMut.html +[Index]: ../../std/ops/trait.Index.html +[Inner attributes]: ../attributes.md +[_Expression_]: ../expressions.md +[_InnerAttribute_]: ../attributes.md +[attributes on block expressions]: block-expr.md#attributes-on-block-expressions +[constant expression]: ../const_eval.md#constant-expressions +[memory location]: ../expressions.md#place-expressions-and-value-expressions diff --git a/src/doc/reference/src/expressions/block-expr.md b/src/doc/reference/src/expressions/block-expr.md index 3175127c87..cfc7b0b082 100644 --- a/src/doc/reference/src/expressions/block-expr.md +++ b/src/doc/reference/src/expressions/block-expr.md @@ -86,7 +86,7 @@ fn move_by_block_expression() { > _UnsafeBlockExpression_ :\ >    `unsafe` _BlockExpression_ -_See [`unsafe` block](unsafe-blocks.html) for more information on when to use `unsafe`_ +_See [`unsafe` block](../unsafe-blocks.md) for more information on when to use `unsafe`_ A block of code can be prefixed with the `unsafe` keyword to permit [unsafe operations]. Examples: @@ -129,24 +129,24 @@ fn is_unix_platform() -> bool { } ``` -[_ExpressionWithoutBlock_]: expressions.html -[_InnerAttribute_]: attributes.html -[_Statement_]: statements.html -[`cfg`]: conditional-compilation.html -[`for`]: expressions/loop-expr.html#iterator-loops -[`loop`]: expressions/loop-expr.html#infinite-loops -[`while let`]: expressions/loop-expr.html#predicate-pattern-loops -[`while`]: expressions/loop-expr.html#predicate-loops -[array expressions]: expressions/array-expr.html -[call expressions]: expressions/call-expr.html -[enum variant]: expressions/enum-variant-expr.html -[function]: items/functions.html -[inner attributes]: attributes.html -[method]: items/associated-items.html#methods -[statement]: statements.html -[statements]: statements.html -[struct]: expressions/struct-expr.html -[the lint check attributes]: attributes/diagnostics.html#lint-check-attributes -[tuple expressions]: expressions/tuple-expr.html -[unsafe operations]: unsafety.html -[value expressions]: expressions.html#place-expressions-and-value-expressions +[_ExpressionWithoutBlock_]: ../expressions.md +[_InnerAttribute_]: ../attributes.md +[_Statement_]: ../statements.md +[`cfg`]: ../conditional-compilation.md +[`for`]: loop-expr.md#iterator-loops +[`loop`]: loop-expr.md#infinite-loops +[`while let`]: loop-expr.md#predicate-pattern-loops +[`while`]: loop-expr.md#predicate-loops +[array expressions]: array-expr.md +[call expressions]: call-expr.md +[enum variant]: enum-variant-expr.md +[function]: ../items/functions.md +[inner attributes]: ../attributes.md +[method]: ../items/associated-items.md#methods +[statement]: ../statements.md +[statements]: ../statements.md +[struct]: struct-expr.md +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[tuple expressions]: tuple-expr.md +[unsafe operations]: ../unsafety.md +[value expressions]: ../expressions.md#place-expressions-and-value-expressions diff --git a/src/doc/reference/src/expressions/call-expr.md b/src/doc/reference/src/expressions/call-expr.md index 9f3414a459..9759abd46e 100644 --- a/src/doc/reference/src/expressions/call-expr.md +++ b/src/doc/reference/src/expressions/call-expr.md @@ -10,7 +10,7 @@ A _call expression_ consists of an expression followed by a parenthesized expression-list. It invokes a function, providing zero or more input variables. If the function eventually returns, then the expression completes. For -[non-function types](types/function-item.html), the expression f(...) uses +[non-function types](../types/function-item.md), the expression f(...) uses the method on one of the [`std::ops::Fn`], [`std::ops::FnMut`] or [`std::ops::FnOnce`] traits, which differ in whether they take the type by reference, mutable reference, or take ownership respectively. An automatic @@ -93,9 +93,9 @@ fn main() { Refer to [RFC 132] for further details and motivations. -[`std::ops::Fn`]: ../std/ops/trait.Fn.html -[`std::ops::FnMut`]: ../std/ops/trait.FnMut.html -[`std::ops::FnOnce`]: ../std/ops/trait.FnOnce.html +[`std::ops::Fn`]: ../../std/ops/trait.Fn.html +[`std::ops::FnMut`]: ../../std/ops/trait.FnMut.html +[`std::ops::FnOnce`]: ../../std/ops/trait.FnOnce.html [RFC 132]: https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md -[_Expression_]: expressions.html +[_Expression_]: ../expressions.md diff --git a/src/doc/reference/src/expressions/closure-expr.md b/src/doc/reference/src/expressions/closure-expr.md index d02a4fd456..aa9299bd6d 100644 --- a/src/doc/reference/src/expressions/closure-expr.md +++ b/src/doc/reference/src/expressions/closure-expr.md @@ -31,7 +31,7 @@ functions, as an abbreviation for defining and capturing a separate function. Significantly, closure expressions _capture their environment_, which regular [function definitions] do not. Without the `move` keyword, the closure expression -[infers how it captures each variable from its environment](types/closure.html#capture-modes), +[infers how it captures each variable from its environment](../types/closure.md#capture-modes), preferring to capture by shared reference, effectively borrowing all outer variables mentioned inside the closure's body. If needed the compiler will infer that instead mutable references should be taken, or that the values @@ -41,10 +41,10 @@ prefixing it with the `move` keyword. This is often used to ensure that the closure's type is `'static`. The compiler will determine which of the [closure -traits](types/closure.html#call-traits-and-coercions) the closure's type will implement by how it +traits](../types/closure.md#call-traits-and-coercions) the closure's type will implement by how it acts on its captured variables. The closure will also implement -[`Send`](special-types-and-traits.html#send) and/or -[`Sync`](special-types-and-traits.html#sync) if all of its captured types do. +[`Send`](../special-types-and-traits.md#send) and/or +[`Sync`](../special-types-and-traits.md#sync) if all of its captured types do. These traits allow functions to accept closures using generics, even though the exact types can't be named. @@ -67,13 +67,13 @@ let word = "konnichiwa".to_owned(); ten_times(move |j| println!("{}, {}", word, j)); ``` -[block]: expressions/block-expr.html -[function definitions]: items/functions.html -[patterns]: patterns.html +[block]: block-expr.md +[function definitions]: ../items/functions.md +[patterns]: ../patterns.md -[_Expression_]: expressions.html -[_BlockExpression_]: expressions/block-expr.html -[_TypeNoBounds_]: types.html#type-expressions -[_Pattern_]: patterns.html -[_Type_]: types.html#type-expressions -[`let` binding]: statements.html#let-statements +[_Expression_]: ../expressions.md +[_BlockExpression_]: block-expr.md +[_TypeNoBounds_]: ../types.md#type-expressions +[_Pattern_]: ../patterns.md +[_Type_]: ../types.md#type-expressions +[`let` binding]: ../statements.md#let-statements diff --git a/src/doc/reference/src/expressions/enum-variant-expr.md b/src/doc/reference/src/expressions/enum-variant-expr.md index 39d3a0ab11..edaee7942e 100644 --- a/src/doc/reference/src/expressions/enum-variant-expr.md +++ b/src/doc/reference/src/expressions/enum-variant-expr.md @@ -40,8 +40,8 @@ let m = Message::Move { x: 50, y: 200 }; Enum variant expressions have the same syntax, behavior, and restrictions as [struct expressions][structs], except they do not support base update with the `..` syntax. -[IDENTIFIER]: identifiers.html -[TUPLE_INDEX]: tokens.html#integer-literals -[_Expression_]: expressions.html -[_PathInExpression_]: paths.html#paths-in-expressions -[structs]: expressions/struct-expr.html +[IDENTIFIER]: ../identifiers.md +[TUPLE_INDEX]: ../tokens.md#integer-literals +[_Expression_]: ../expressions.md +[_PathInExpression_]: ../paths.md#paths-in-expressions +[structs]: struct-expr.md diff --git a/src/doc/reference/src/expressions/field-expr.md b/src/doc/reference/src/expressions/field-expr.md index 043d7b4fb0..d9a7b9218c 100644 --- a/src/doc/reference/src/expressions/field-expr.md +++ b/src/doc/reference/src/expressions/field-expr.md @@ -27,7 +27,7 @@ possible. In cases of ambiguity, we prefer fewer autoderefs to more. Finally, the fields of a struct or a reference to a struct are treated as separate entities when borrowing. If the struct does not implement -[`Drop`](special-types-and-traits.html#drop) and is stored in a local variable, +[`Drop`](../special-types-and-traits.md#drop) and is stored in a local variable, this also applies to moving out of each of its fields. This also does not apply if automatic dereferencing is done though user defined types. @@ -45,10 +45,10 @@ let c: &String = &x.f2; // Can borrow again let d: String = x.f3; // Move out of x.f3 ``` -[_Expression_]: expressions.html -[IDENTIFIER]: identifiers.html -[method call expression]: expressions/method-call-expr.html -[struct]: items/structs.html -[union]: items/unions.html -[place expression]: expressions.html#place-expressions-and-value-expressions -[mutable]: expressions.html#mutability +[_Expression_]: ../expressions.md +[IDENTIFIER]: ../identifiers.md +[method call expression]: method-call-expr.md +[struct]: ../items/structs.md +[union]: ../items/unions.md +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[mutable]: ../expressions.md#mutability diff --git a/src/doc/reference/src/expressions/grouped-expr.md b/src/doc/reference/src/expressions/grouped-expr.md index c5845d2ad3..8e57cdbb7b 100644 --- a/src/doc/reference/src/expressions/grouped-expr.md +++ b/src/doc/reference/src/expressions/grouped-expr.md @@ -41,7 +41,7 @@ assert_eq!((a.f)(), "The field f"); group expression in the same expression contexts as [attributes on block expressions]. -[Inner attributes]: attributes.html -[_Expression_]: expressions.html -[_InnerAttribute_]: attributes.html -[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions +[Inner attributes]: ../attributes.md +[_Expression_]: ../expressions.md +[_InnerAttribute_]: ../attributes.md +[attributes on block expressions]: block-expr.md#attributes-on-block-expressions diff --git a/src/doc/reference/src/expressions/if-expr.md b/src/doc/reference/src/expressions/if-expr.md index 5501dc86f1..efe3849964 100644 --- a/src/doc/reference/src/expressions/if-expr.md +++ b/src/doc/reference/src/expressions/if-expr.md @@ -149,10 +149,10 @@ if let PAT = EXPR || EXPR { .. } if let PAT = ( EXPR || EXPR ) { .. } ``` -[_BlockExpression_]: expressions/block-expr.html -[_Expression_]: expressions.html -[_LazyBooleanOperatorExpression_]: expressions/operator-expr.html#lazy-boolean-operators -[_MatchArmPatterns_]: expressions/match-expr.html +[_BlockExpression_]: block-expr.md +[_Expression_]: ../expressions.md +[_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators +[_MatchArmPatterns_]: match-expr.md [_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018 -[`match` expression]: expressions/match-expr.html -[scrutinee]: glossary.html#scrutinee +[`match` expression]: match-expr.md +[scrutinee]: ../glossary.md#scrutinee diff --git a/src/doc/reference/src/expressions/literal-expr.md b/src/doc/reference/src/expressions/literal-expr.md index 26ccda81a6..c64c6d6c2f 100644 --- a/src/doc/reference/src/expressions/literal-expr.md +++ b/src/doc/reference/src/expressions/literal-expr.md @@ -12,7 +12,7 @@ >    | [FLOAT_LITERAL]\ >    | [BOOLEAN_LITERAL] -A _literal expression_ consists of one of the [literal](tokens.html#literals) +A _literal expression_ consists of one of the [literal](../tokens.md#literals) forms described earlier. It directly describes a number, character, string, or boolean value. @@ -22,12 +22,12 @@ or boolean value. 5; // integer type ``` -[CHAR_LITERAL]: tokens.html#character-literals -[STRING_LITERAL]: tokens.html#string-literals -[RAW_STRING_LITERAL]: tokens.html#raw-string-literals -[BYTE_LITERAL]: tokens.html#byte-literals -[BYTE_STRING_LITERAL]: tokens.html#byte-string-literals -[RAW_BYTE_STRING_LITERAL]: tokens.html#raw-byte-string-literals -[INTEGER_LITERAL]: tokens.html#integer-literals -[FLOAT_LITERAL]: tokens.html#floating-point-literals -[BOOLEAN_LITERAL]: tokens.html#boolean-literals +[CHAR_LITERAL]: ../tokens.md#character-literals +[STRING_LITERAL]: ../tokens.md#string-literals +[RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals +[BYTE_LITERAL]: ../tokens.md#byte-literals +[BYTE_STRING_LITERAL]: ../tokens.md#byte-string-literals +[RAW_BYTE_STRING_LITERAL]: ../tokens.md#raw-byte-string-literals +[INTEGER_LITERAL]: ../tokens.md#integer-literals +[FLOAT_LITERAL]: ../tokens.md#floating-point-literals +[BOOLEAN_LITERAL]: ../tokens.md#boolean-literals diff --git a/src/doc/reference/src/expressions/loop-expr.md b/src/doc/reference/src/expressions/loop-expr.md index 98c9d14b46..d95445c43d 100644 --- a/src/doc/reference/src/expressions/loop-expr.md +++ b/src/doc/reference/src/expressions/loop-expr.md @@ -37,7 +37,7 @@ A `loop` expression repeats execution of its body continuously: `loop { println!("I live."); }`. A `loop` expression without an associated `break` expression is diverging and -has type [`!`](types/never.html). A `loop` expression containing +has type [`!`](../types/never.md). A `loop` expression containing associated [`break` expression(s)](#break-expressions) may terminate, and must have type compatible with the value of the `break` expression(s). @@ -282,11 +282,11 @@ and the `loop` must have a type compatible with each `break` expression. `break` without an expression is considered identical to `break` with expression `()`. -[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels -[_BlockExpression_]: expressions/block-expr.html -[_Expression_]: expressions.html -[_MatchArmPatterns_]: expressions/match-expr.html -[_Pattern_]: patterns.html -[`match` expression]: expressions/match-expr.html -[scrutinee]: glossary.html#scrutinee -[temporary values]: expressions.html#temporary-lifetimes +[LIFETIME_OR_LABEL]: ../tokens.md#lifetimes-and-loop-labels +[_BlockExpression_]: block-expr.md +[_Expression_]: ../ expressions.md +[_MatchArmPatterns_]: match-expr.md +[_Pattern_]: ../patterns.md +[`match` expression]: match-expr.md +[scrutinee]: ../glossary.md#scrutinee +[temporary values]: ../expressions.md#temporary-lifetimes diff --git a/src/doc/reference/src/expressions/match-expr.md b/src/doc/reference/src/expressions/match-expr.md index e5c8dbb0d9..aea103326f 100644 --- a/src/doc/reference/src/expressions/match-expr.md +++ b/src/doc/reference/src/expressions/match-expr.md @@ -134,21 +134,21 @@ meaning on match arms are [`cfg`], [`cold`], and the [lint check attributes]. expression in the same expression contexts as [attributes on block expressions]. -[_Expression_]: expressions.html -[_BlockExpression_]: expressions/block-expr.html#block-expressions -[place expression]: expressions.html#place-expressions-and-value-expressions -[value expression]: expressions.html#place-expressions-and-value-expressions -[_InnerAttribute_]: attributes.html -[_OuterAttribute_]: attributes.html -[`cfg`]: conditional-compilation.html -[`cold`]: attributes/codegen.html#the-cold-attribute -[lint check attributes]: attributes/diagnostics.html#lint-check-attributes -[Range Expression]: expressions/range-expr.html - -[_Pattern_]: patterns.html -[pattern]: patterns.html -[Inner attributes]: attributes.html -[Range Pattern]: patterns.html#range-patterns -[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions -[binding mode]: patterns.html#binding-modes -[scrutinee]: glossary.html#scrutinee +[_Expression_]: ../expressions.md +[_BlockExpression_]: block-expr.md#block-expressions +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[value expression]: ../expressions.md#place-expressions-and-value-expressions +[_InnerAttribute_]: ../attributes.md +[_OuterAttribute_]: ../attributes.md +[`cfg`]: ../conditional-compilation.md +[`cold`]: ../attributes/codegen.md#the-cold-attribute +[lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[Range Expression]: range-expr.md + +[_Pattern_]: ../patterns.md +[pattern]: ../patterns.md +[Inner attributes]: ../attributes.md +[Range Pattern]: ../patterns.md#range-patterns +[attributes on block expressions]: block-expr.md#attributes-on-block-expressions +[binding mode]: ../patterns.md#binding-modes +[scrutinee]: ../glossary.md#scrutinee diff --git a/src/doc/reference/src/expressions/method-call-expr.md b/src/doc/reference/src/expressions/method-call-expr.md index 1b90d742a7..b6b139a52c 100644 --- a/src/doc/reference/src/expressions/method-call-expr.md +++ b/src/doc/reference/src/expressions/method-call-expr.md @@ -9,7 +9,7 @@ dot, an expression path segment, and a parenthesized expression-list. Method cal resolved to associated [methods] on specific traits, either statically dispatching to a method if the exact `self`-type of the left-hand-side is known, or dynamically dispatching if the left-hand-side expression is an indirect -[trait object](types/trait-object.html). +[trait object](../types/trait-object.md). ```rust let pi: Result = "3.14".parse(); @@ -97,13 +97,13 @@ method and you'll be fine.
-[_CallParams_]: expressions/call-expr.html -[_Expression_]: expressions.html -[_PathExprSegment_]: paths.html#paths-in-expressions -[visible]: visibility-and-privacy.html -[trait objects]: types/trait-object.html -[disambiguate call]: expressions/call-expr.html#disambiguating-function-calls -[disambiguating function call syntax]: expressions/call-expr.html#disambiguating-function-calls -[dereference]: expressions/operator-expr.html#the-dereference-operator -[methods]: items/associated-items.html#methods -[unsized coercion]: type-coercions.html#unsized-coercions +[_CallParams_]: call-expr.md +[_Expression_]: ../expressions.md +[_PathExprSegment_]: ../paths.md#paths-in-expressions +[visible]: ../visibility-and-privacy.md +[trait objects]: ../types/trait-object.md +[disambiguate call]: call-expr.md#disambiguating-function-calls +[disambiguating function call syntax]: call-expr.md#disambiguating-function-calls +[dereference]: operator-expr.md#the-dereference-operator +[methods]: ../items/associated-items.md#methods +[unsized coercion]: ../type-coercions.md#unsized-coercions diff --git a/src/doc/reference/src/expressions/operator-expr.md b/src/doc/reference/src/expressions/operator-expr.md index 428f053eff..f35d0328f9 100644 --- a/src/doc/reference/src/expressions/operator-expr.md +++ b/src/doc/reference/src/expressions/operator-expr.md @@ -85,14 +85,14 @@ let a = & & & & mut 10; >    `*` [_Expression_] The `*` (dereference) operator is also a unary prefix operator. When applied to -a [pointer](types/pointer.html) it denotes the pointed-to location. If +a [pointer](../types/pointer.md) it denotes the pointed-to location. If the expression is of type `&mut T` and `*mut T`, and is either a local variable, a (nested) field of a local variable or is a mutable [place expression], then the resulting memory location can be assigned to. Dereferencing a raw pointer requires `unsafe`. On non-pointer types `*x` is equivalent to `*std::ops::Deref::deref(&x)` in an -[immutable place expression context](expressions.html#mutability) and +[immutable place expression context](../expressions.md#mutability) and `*std::ops::DerefMut::deref_mut(&mut x)` in a mutable place expression context. ```rust @@ -331,7 +331,7 @@ fn average(values: &[f64]) -> f64 { } ``` -`as` can be used to explicitly perform [coercions](type-coercions.html), as +`as` can be used to explicitly perform [coercions](../type-coercions.md), as well as the following additional casts. Here `*T` means either `*const T` or `*mut T`. @@ -345,7 +345,7 @@ well as the following additional casts. Here `*T` means either `*const T` or | `*T` where `T: Sized` | Numeric type | Pointer to address cast | | Integer type | `*V` where `V: Sized` | Address to pointer cast | | `&[T; n]` | `*const T` | Array to pointer cast | -| [Function pointer](types/function-pointer.html) | `*V` where `V: Sized` | Function pointer to pointer cast | +| [Function pointer](../types/function-pointer.md) | `*V` where `V: Sized` | Function pointer to pointer cast | | Function pointer | Integer | Function pointer to address cast | | Closure \*\* | Function pointer | Closure to function pointer cast | @@ -398,9 +398,9 @@ An _assignment expression_ consists of a [place expression] followed by an equals sign (`=`) and a [value expression]. Such an expression always has the [`unit` type]. -Evaluating an assignment expression [drops](destructors.html) the left-hand +Evaluating an assignment expression [drops](../destructors.md) the left-hand operand, unless it's an uninitialized local variable or field of a local variable, -and [either copies or moves](expressions.html#moved-and-copied-types) its +and [either copies or moves](../expressions.md#moved-and-copied-types) its right-hand operand to its left-hand operand. The left-hand operand must be a place expression: using a value expression results in a compiler error, rather than promoting it to a temporary. @@ -441,12 +441,12 @@ x += 4; assert_eq!(x, 14); ``` -[place expression]: expressions.html#place-expressions-and-value-expressions -[value expression]: expressions.html#place-expressions-and-value-expressions -[temporary value]: expressions.html#temporary-lifetimes +[place expression]: ../expressions.md#place-expressions-and-value-expressions +[value expression]: ../expressions.md#place-expressions-and-value-expressions +[temporary value]: ../expressions.md#temporary-lifetimes [float-int]: https://github.com/rust-lang/rust/issues/10184 [float-float]: https://github.com/rust-lang/rust/issues/15536 -[`unit` type]: types/tuple.html +[`unit` type]: ../types/tuple.md [_BorrowExpression_]: #borrow-operators [_DereferenceExpression_]: #the-dereference-operator @@ -459,5 +459,5 @@ assert_eq!(x, 14); [_AssignmentExpression_]: #assignment-expressions [_CompoundAssignmentExpression_]: #compound-assignment-expressions -[_Expression_]: expressions.html -[_TypeNoBounds_]: types.html#type-expressions +[_Expression_]: ../expressions.md +[_TypeNoBounds_]: ../types.md#type-expressions diff --git a/src/doc/reference/src/expressions/path-expr.md b/src/doc/reference/src/expressions/path-expr.md index fdf019d1ad..84278da961 100644 --- a/src/doc/reference/src/expressions/path-expr.md +++ b/src/doc/reference/src/expressions/path-expr.md @@ -24,10 +24,10 @@ let push_integer = Vec::::push; let slice_reverse = <[i32]>::reverse; ``` -[_PathInExpression_]: paths.html#paths-in-expressions -[_QualifiedPathInExpression_]: paths.html#qualified-paths -[place expressions]: expressions.html#place-expressions-and-value-expressions -[value expressions]: expressions.html#place-expressions-and-value-expressions -[path]: paths.html -[`static mut`]: items/static-items.html#mutable-statics -[`unsafe` block]: expressions/block-expr.html#unsafe-blocks +[_PathInExpression_]: ../paths.md#paths-in-expressions +[_QualifiedPathInExpression_]: ../paths.md#qualified-paths +[place expressions]: ../expressions.md#place-expressions-and-value-expressions +[value expressions]: ../expressions.md#place-expressions-and-value-expressions +[path]: ../paths.md +[`static mut`]: ../items/static-items.md#mutable-statics +[`unsafe` block]: block-expr.md#unsafe-blocks diff --git a/src/doc/reference/src/expressions/range-expr.md b/src/doc/reference/src/expressions/range-expr.md index 4f478c373f..f46c45dce1 100644 --- a/src/doc/reference/src/expressions/range-expr.md +++ b/src/doc/reference/src/expressions/range-expr.md @@ -68,11 +68,11 @@ for i in 1..11 { } ``` -[_Expression_]: expressions.html +[_Expression_]: ../expressions.md -[std::ops::Range]: https://doc.rust-lang.org/std/ops/struct.Range.html -[std::ops::RangeFrom]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html -[std::ops::RangeTo]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html -[std::ops::RangeFull]: https://doc.rust-lang.org/std/ops/struct.RangeFull.html -[std::ops::RangeInclusive]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +[std::ops::Range]: https://doc.rust-lang.org/std/ops/struct.Range.html +[std::ops::RangeFrom]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html +[std::ops::RangeTo]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html +[std::ops::RangeFull]: https://doc.rust-lang.org/std/ops/struct.RangeFull.html +[std::ops::RangeInclusive]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html [std::ops::RangeToInclusive]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html diff --git a/src/doc/reference/src/expressions/return-expr.md b/src/doc/reference/src/expressions/return-expr.md index 77cfb35940..1146b6e4fe 100644 --- a/src/doc/reference/src/expressions/return-expr.md +++ b/src/doc/reference/src/expressions/return-expr.md @@ -20,4 +20,4 @@ fn max(a: i32, b: i32) -> i32 { } ``` -[_Expression_]: expressions.html +[_Expression_]: ../expressions.md diff --git a/src/doc/reference/src/expressions/struct-expr.md b/src/doc/reference/src/expressions/struct-expr.md index be29bfdac2..baeba7b8ac 100644 --- a/src/doc/reference/src/expressions/struct-expr.md +++ b/src/doc/reference/src/expressions/struct-expr.md @@ -138,20 +138,20 @@ let b = Gamma{}; // Exact same value as `a`. of a struct expression in the same expression contexts as [attributes on block expressions]. -[IDENTIFIER]: identifiers.html -[Inner attributes]: attributes.html -[TUPLE_INDEX]: tokens.html#integer-literals -[_Expression_]: expressions.html -[_InnerAttribute_]: attributes.html -[_PathInExpression_]: paths.html#paths-in-expressions -[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions -[call expression]: expressions/call-expr.html -[if let]: expressions/if-expr.html#if-let-expressions -[if]: expressions/if-expr.html#if-expressions -[loop]: expressions/loop-expr.html -[match]: expressions/match-expr.html -[parentheses]: http://localhost:3000/expressions/grouped-expr.html -[struct]: items/structs.html -[union]: items/unions.html -[visible]: visibility-and-privacy.html -[scrutinee]: glossary.html#scrutinee +[IDENTIFIER]: ../identifiers.md +[Inner attributes]: ../attributes.md +[TUPLE_INDEX]: ../tokens.md#integer-literals +[_Expression_]: ../expressions.md +[_InnerAttribute_]: ../attributes.md +[_PathInExpression_]: ../paths.md#paths-in-expressions +[attributes on block expressions]: block-expr.md#attributes-on-block-expressions +[call expression]: call-expr.md +[if let]: if-expr.md#if-let-expressions +[if]: if-expr.md#if-expressions +[loop]: loop-expr.md +[match]: match-expr.md +[parentheses]: grouped-expr.md +[struct]: ../items/structs.md +[union]: ../items/unions.md +[visible]: ../visibility-and-privacy.md +[scrutinee]: ../glossary.md#scrutinee diff --git a/src/doc/reference/src/expressions/tuple-expr.md b/src/doc/reference/src/expressions/tuple-expr.md index 68bc9f438d..b979a4f5fd 100644 --- a/src/doc/reference/src/expressions/tuple-expr.md +++ b/src/doc/reference/src/expressions/tuple-expr.md @@ -10,7 +10,7 @@ >    ( [_Expression_] `,` )+ [_Expression_]? Tuples are written by enclosing zero or more comma-separated expressions in -parentheses. They are used to create [tuple-typed](types/tuple.html) +parentheses. They are used to create [tuple-typed](../types/tuple.md) values. ```rust @@ -39,9 +39,9 @@ expressions]. > _TupleIndexingExpression_ :\ >    [_Expression_] `.` [TUPLE_INDEX] -[Tuples](types/tuple.html) and [struct tuples](items/structs.html) can be +[Tuples](../types/tuple.md) and [struct tuples](../items/structs.md) can be indexed using the number corresponding to the position of the field. The index -must be written as a [decimal literal](tokens.html#integer-literals) with no +must be written as a [decimal literal](../tokens.md#integer-literals) with no underscores or suffix. Tuple indexing expressions also differ from field expressions in that they can unambiguously be called as a function. In all other aspects they have the same behavior. @@ -54,8 +54,8 @@ let unit_x = Point(1.0, 0.0); assert_eq!(unit_x.0, 1.0); ``` -[Inner attributes]: attributes.html -[TUPLE_INDEX]: tokens.html#integer-literals -[_Expression_]: expressions.html -[_InnerAttribute_]: attributes.html -[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions +[Inner attributes]: ../attributes.md +[TUPLE_INDEX]: ../tokens.md#integer-literals +[_Expression_]: ../expressions.md +[_InnerAttribute_]: ../attributes.md +[attributes on block expressions]: block-expr.md#attributes-on-block-expressions diff --git a/src/doc/reference/src/glossary.md b/src/doc/reference/src/glossary.md index bea591a34f..6dc22b860f 100644 --- a/src/doc/reference/src/glossary.md +++ b/src/doc/reference/src/glossary.md @@ -159,18 +159,18 @@ but is not limited to: process termination or corruption; improper, incorrect, or unintended computation; or platform-specific results. [More][undefined-behavior]. -[alignment]: type-layout.html#size-and-alignment +[alignment]: type-layout.md#size-and-alignment [associated item]: #associated-item -[enums]: items/enumerations.html +[enums]: items/enumerations.md [free item]: #free-item -[implementation]: items/implementations.html -[implementations]: items/implementations.html -[inherent implementation]: items/implementations.html#inherent-implementations -[item]: items.html -[method]: items/associated-items.html#methods -[object safety]: items/traits.html#object-safety -[structs]: items/structs.html -[trait objects]: types/trait-object.html -[traits]: items/traits.html -[undefined-behavior]: behavior-considered-undefined.html -[unions]: items/unions.html +[implementation]: items/implementations.md +[implementations]: items/implementations.md +[inherent implementation]: items/implementations.md#inherent-implementations +[item]: items.md +[method]: items/associated-items.md#methods +[object safety]: items/traits.md#object-safety +[structs]: items/structs.md +[trait objects]: types/trait-object.md +[traits]: items/traits.md +[undefined-behavior]: behavior-considered-undefined.md +[unions]: items/unions.md diff --git a/src/doc/reference/src/identifiers.md b/src/doc/reference/src/identifiers.md index 37a66787dd..c0730d1330 100644 --- a/src/doc/reference/src/identifiers.md +++ b/src/doc/reference/src/identifiers.md @@ -30,5 +30,5 @@ the `r#` prefix is not included as part of the actual identifier.) Unlike a normal identifier, a raw identifier may be any strict or reserved keyword except the ones listed above for `RAW_IDENTIFIER`. -[strict]: keywords.html#strict-keywords -[reserved]: keywords.html#reserved-keywords +[strict]: keywords.md#strict-keywords +[reserved]: keywords.md#reserved-keywords diff --git a/src/doc/reference/src/interior-mutability.md b/src/doc/reference/src/interior-mutability.md index 74324e30e5..1133bc7973 100644 --- a/src/doc/reference/src/interior-mutability.md +++ b/src/doc/reference/src/interior-mutability.md @@ -20,8 +20,8 @@ borrow checks to ensure the usual rules around multiple references. The accessed with atomic operations, allowing the value to be shared and mutated across threads. -[shared reference]: types/pointer.html#shared-references- -[ub]: behavior-considered-undefined.html +[shared reference]: types/pointer.md#shared-references- +[ub]: behavior-considered-undefined.md [`std::cell::UnsafeCell`]: ../std/cell/struct.UnsafeCell.html [`std::cell::RefCell`]: ../std/cell/struct.RefCell.html [`std::sync::atomic`]: ../std/sync/atomic/index.html diff --git a/src/doc/reference/src/introduction.md b/src/doc/reference/src/introduction.md index 564cf994e5..66c45dc46f 100644 --- a/src/doc/reference/src/introduction.md +++ b/src/doc/reference/src/introduction.md @@ -136,12 +136,12 @@ attention to making those sections the best that they can be. [standard library]: ../std/index.html [the Rust Reference repository]: https://github.com/rust-lang-nursery/reference/ [Unstable Book]: https://doc.rust-lang.org/nightly/unstable-book/ -[_Expression_]: expressions.html +[_Expression_]: expressions.md [cargo book]: ../cargo/index.html [cargo reference]: ../cargo/reference/index.html -[expressions chapter]: expressions.html -[lifetime of temporaries]: expressions.html#temporary-lifetimes -[linkage]: linkage.html +[expressions chapter]: expressions.md +[lifetime of temporaries]: expressions.md#temporary-lifetimes +[linkage]: linkage.md [rustc book]: ../rustc/index.html -[Notation]: notation.html +[Notation]: notation.md [Discord]: https://discord.gg/rust-lang diff --git a/src/doc/reference/src/items.md b/src/doc/reference/src/items.md index fa1fc2bdba..addbe0efd2 100644 --- a/src/doc/reference/src/items.md +++ b/src/doc/reference/src/items.md @@ -63,34 +63,34 @@ qualified by the name of the enclosing item, or is private to the enclosing item (in the case of functions). The grammar specifies the exact locations in which sub-item declarations may appear. -[_ConstantItem_]: items/constant-items.html -[_Enumeration_]: items/enumerations.html -[_ExternBlock_]: items/external-blocks.html -[_ExternCrate_]: items/extern-crates.html -[_Function_]: items/functions.html -[_Implementation_]: items/implementations.html -[_MacroInvocationSemi_]: macros.html#macro-invocation -[_MacroRulesDefinition_]: macros-by-example.html -[_Module_]: items/modules.html -[_OuterAttribute_]: attributes.html -[_StaticItem_]: items/static-items.html -[_Struct_]: items/structs.html -[_Trait_]: items/traits.html -[_TypeAlias_]: items/type-aliases.html -[_Union_]: items/unions.html -[_UseDeclaration_]: items/use-declarations.html -[_Visibility_]: visibility-and-privacy.html -[`extern crate` declarations]: items/extern-crates.html -[`extern` blocks]: items/external-blocks.html -[`use` declarations]: items/use-declarations.html -[constant items]: items/constant-items.html -[enumeration definitions]: items/enumerations.html -[function definitions]: items/functions.html -[implementations]: items/implementations.html -[modules]: items/modules.html -[paths]: paths.html -[static items]: items/static-items.html -[struct definitions]: items/structs.html -[trait definitions]: items/traits.html -[type definitions]: items/type-aliases.html -[union definitions]: items/unions.html +[_ConstantItem_]: items/constant-items.md +[_Enumeration_]: items/enumerations.md +[_ExternBlock_]: items/external-blocks.md +[_ExternCrate_]: items/extern-crates.md +[_Function_]: items/functions.md +[_Implementation_]: items/implementations.md +[_MacroInvocationSemi_]: macros.md#macro-invocation +[_MacroRulesDefinition_]: macros-by-example.md +[_Module_]: items/modules.md +[_OuterAttribute_]: attributes.md +[_StaticItem_]: items/static-items.md +[_Struct_]: items/structs.md +[_Trait_]: items/traits.md +[_TypeAlias_]: items/type-aliases.md +[_Union_]: items/unions.md +[_UseDeclaration_]: items/use-declarations.md +[_Visibility_]: visibility-and-privacy.md +[`extern crate` declarations]: items/extern-crates.md +[`extern` blocks]: items/external-blocks.md +[`use` declarations]: items/use-declarations.md +[constant items]: items/constant-items.md +[enumeration definitions]: items/enumerations.md +[function definitions]: items/functions.md +[implementations]: items/implementations.md +[modules]: items/modules.md +[paths]: paths.md +[static items]: items/static-items.md +[struct definitions]: items/structs.md +[trait definitions]: items/traits.md +[type definitions]: items/type-aliases.md +[union definitions]: items/unions.md diff --git a/src/doc/reference/src/items/associated-items.md b/src/doc/reference/src/items/associated-items.md index a8bdcbf864..e8a18ad582 100644 --- a/src/doc/reference/src/items/associated-items.md +++ b/src/doc/reference/src/items/associated-items.md @@ -324,28 +324,28 @@ fn main() { } ``` -[_BlockExpression_]: expressions/block-expr.html -[_FunctionParam_]: items/functions.html -[_FunctionQualifiers_]: items/functions.html -[_FunctionReturnType_]: items/functions.html -[_Generics_]: items/generics.html -[_Lifetime_]: trait-bounds.html -[_Type_]: types.html#type-expressions -[_WhereClause_]: items/generics.html#where-clauses -[`Arc`]: special-types-and-traits.html#arct -[`Box`]: special-types-and-traits.html#boxt -[`Pin

`]: special-types-and-traits.html#pinp -[`Rc`]: special-types-and-traits.html#rct -[traits]: items/traits.html -[type aliases]: items/type-aliases.html -[inherent implementations]: items/implementations.html#inherent-implementations -[identifier]: identifiers.html -[identifier pattern]: patterns.html#identifier-patterns -[implementations]: items/implementations.html -[type]: types.html#type-expressions -[constants]: items/constant-items.html -[constant item]: items/constant-items.html -[functions]: items/functions.html -[function item]: types/function-item.html -[method call operator]: expressions/method-call-expr.html -[path]: paths.html +[_BlockExpression_]: ../expressions/block-expr.md +[_FunctionParam_]: functions.md +[_FunctionQualifiers_]: functions.md +[_FunctionReturnType_]: functions.md +[_Generics_]: generics.md +[_Lifetime_]: ../trait-bounds.md +[_Type_]: ../types.md#type-expressions +[_WhereClause_]: generics.md#where-clauses +[`Arc`]: ../special-types-and-traits.md#arct +[`Box`]: ../special-types-and-traits.md#boxt +[`Pin

`]: ../special-types-and-traits.md#pinp +[`Rc`]: ../special-types-and-traits.md#rct +[traits]: traits.md +[type aliases]: type-aliases.md +[inherent implementations]: implementations.md#inherent-implementations +[identifier]: ../identifiers.md +[identifier pattern]: ../patterns.md#identifier-patterns +[implementations]: implementations.md +[type]: ../types.md#type-expressions +[constants]: constant-items.md +[constant item]: constant-items.md +[functions]: functions.md +[function item]: ../types/function-item.md +[method call operator]: ../expressions/method-call-expr.md +[path]: ../paths.md diff --git a/src/doc/reference/src/items/constant-items.md b/src/doc/reference/src/items/constant-items.md index ab0b848309..83045eae62 100644 --- a/src/doc/reference/src/items/constant-items.md +++ b/src/doc/reference/src/items/constant-items.md @@ -86,11 +86,11 @@ m!(const _: () = ();); // const _: () = (); ``` -[associated]: glossary.html#associated-item -[constant value]: const_eval.html#constant-expressions -[free]: glossary.html#free-item -[static lifetime elision]: lifetime-elision.html#static-lifetime-elision -[IDENTIFIER]: identifiers.html -[underscore imports]: items/use-declarations.html#underscore-imports -[_Type_]: types.html#type-expressions -[_Expression_]: expressions.html +[associated]: ../glossary.md#associated-item +[constant value]: ../const_eval.md#constant-expressions +[free]: ../glossary.md#free-item +[static lifetime elision]: ../lifetime-elision.md#static-lifetime-elision +[IDENTIFIER]: ../identifiers.md +[underscore imports]: use-declarations.md#underscore-imports +[_Type_]: ../types.md#type-expressions +[_Expression_]: ../expressions.md diff --git a/src/doc/reference/src/items/enumerations.md b/src/doc/reference/src/items/enumerations.md index 258795503b..8779f61bb8 100644 --- a/src/doc/reference/src/items/enumerations.md +++ b/src/doc/reference/src/items/enumerations.md @@ -131,16 +131,16 @@ no valid values, they cannot be instantiated. enum ZeroVariants {} ``` -[IDENTIFIER]: identifiers.html -[_Generics_]: items/generics.html -[_WhereClause_]: items/generics.html#where-clauses -[_Expression_]: expressions.html -[_TupleFields_]: items/structs.html -[_StructFields_]: items/structs.html -[enumerated type]: types/enum.html -[`mem::discriminant`]: ../std/mem/fn.discriminant.html -[numeric cast]: expressions/operator-expr.html#semantics -[constant expression]: const_eval.html#constant-expressions -[default representation]: type-layout.html#the-default-representation -[primitive representation]: type-layout.html#primitive-representations -[`C` representation]: type-layout.html#the-c-representation +[IDENTIFIER]: ../identifiers.md +[_Generics_]: generics.md +[_WhereClause_]: generics.md#where-clauses +[_Expression_]: ../expressions.md +[_TupleFields_]: structs.md +[_StructFields_]: structs.md +[enumerated type]: ../types/enum.md +[`mem::discriminant`]: ../../std/mem/fn.discriminant.html +[numeric cast]: ../expressions/operator-expr.md#semantics +[constant expression]: ../const_eval.md#constant-expressions +[default representation]: ../type-layout.md#the-default-representation +[primitive representation]: ../type-layout.md#primitive-representations +[`C` representation]: ../type-layout.md#the-c-representation diff --git a/src/doc/reference/src/items/extern-crates.md b/src/doc/reference/src/items/extern-crates.md index ebd93f2ce7..ff66d50be9 100644 --- a/src/doc/reference/src/items/extern-crates.md +++ b/src/doc/reference/src/items/extern-crates.md @@ -102,12 +102,12 @@ The *`no_link` attribute* may be specified on an `extern crate` item to prevent linking the crate into the output. This is commonly used to load a crate to access only its macros. -[IDENTIFIER]: identifiers.html +[IDENTIFIER]: ../identifiers.md [RFC 940]: https://github.com/rust-lang/rfcs/blob/master/text/0940-hyphens-considered-harmful.md -[`macro_use` attribute]: macros-by-example.html#the-macro_use-attribute +[`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute [`alloc`]: https://doc.rust-lang.org/alloc/ -[`no_implicit_prelude`]: items/modules.html#prelude-items -[`no_std`]: crates-and-source-files.html#preludes-and-no_std +[`no_implicit_prelude`]: modules.md#prelude-items +[`no_std`]: ../crates-and-source-files.md#preludes-and-no_std [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ [`test`]: https://doc.rust-lang.org/test/ -[use declarations]: items/use-declarations.html +[use declarations]: use-declarations.md diff --git a/src/doc/reference/src/items/external-blocks.md b/src/doc/reference/src/items/external-blocks.md index bd38306610..9c69ad0ed9 100644 --- a/src/doc/reference/src/items/external-blocks.md +++ b/src/doc/reference/src/items/external-blocks.md @@ -163,16 +163,16 @@ extern { } ``` -[IDENTIFIER]: identifiers.html +[IDENTIFIER]: ../identifiers.md [WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html -[_Abi_]: items/functions.html -[_FunctionReturnType_]: items/functions.html -[_Generics_]: items/generics.html -[_InnerAttribute_]: attributes.html -[_MetaListNameValueStr_]: attributes.html#meta-item-attribute-syntax -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax -[_OuterAttribute_]: attributes.html -[_Type_]: types.html#type-expressions -[_Visibility_]: visibility-and-privacy.html -[_WhereClause_]: items/generics.html#where-clauses -[attributes]: attributes.html +[_Abi_]: functions.md +[_FunctionReturnType_]: functions.md +[_Generics_]: generics.md +[_InnerAttribute_]: ../attributes.md +[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax +[_OuterAttribute_]: ../attributes.md +[_Type_]: ../types.md#type-expressions +[_Visibility_]: ../visibility-and-privacy.md +[_WhereClause_]: generics.md#where-clauses +[attributes]: ../attributes.md diff --git a/src/doc/reference/src/items/functions.md b/src/doc/reference/src/items/functions.md index b798ae72af..bae5b8eff8 100644 --- a/src/doc/reference/src/items/functions.md +++ b/src/doc/reference/src/items/functions.md @@ -212,34 +212,34 @@ attributes], [`must_use`], [the procedural macro attributes], [the testing attributes], and [the optimization hint attributes]. Functions also accept attributes macros. -[IDENTIFIER]: identifiers.html -[RAW_STRING_LITERAL]: tokens.html#raw-string-literals -[STRING_LITERAL]: tokens.html#string-literals -[_BlockExpression_]: expressions/block-expr.html -[_Generics_]: items/generics.html -[_Pattern_]: patterns.html -[_Type_]: types.html#type-expressions -[_WhereClause_]: items/generics.html#where-clauses -[const context]: const_eval.html#const-context -[external blocks]: items/external-blocks.html -[path]: paths.html -[block]: expressions/block-expr.html -[variables]: variables.html -[type]: types.html#type-expressions -[*function item type*]: types/function-item.html -[Trait]: items/traits.html -[attributes]: attributes.html -[`cfg`]: conditional-compilation.html -[the lint check attributes]: attributes/diagnostics.html#lint-check-attributes -[the procedural macro attributes]: procedural-macros.html -[the testing attributes]: attributes/testing.html -[the optimization hint attributes]: attributes/codegen.html#optimization-hints -[`deprecated`]: attributes/diagnostics.html#the-deprecated-attribute -[`doc`]: ../rustdoc/the-doc-attribute.html -[`must_use`]: attributes/diagnostics.html#the-must_use-attribute -[patterns]: patterns.html -[`?Sized`]: trait-bounds.html#sized -[trait bounds]: trait-bounds.html -[`export_name`]: abi.html#the-export_name-attribute -[`link_section`]: abi.html#the-link_section-attribute -[`no_mangle`]: abi.html#the-no_mangle-attribute +[IDENTIFIER]: ../identifiers.md +[RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals +[STRING_LITERAL]: ../tokens.md#string-literals +[_BlockExpression_]: ../expressions/block-expr.md +[_Generics_]: generics.md +[_Pattern_]: ../patterns.md +[_Type_]: ../types.md#type-expressions +[_WhereClause_]: generics.md#where-clauses +[const context]: ../const_eval.md#const-context +[external blocks]: external-blocks.md +[path]: ../paths.md +[block]: ../expressions/block-expr.md +[variables]: ../variables.md +[type]: ../types.md#type-expressions +[*function item type*]: ../types/function-item.md +[Trait]: traits.md +[attributes]: ../attributes.md +[`cfg`]: ../conditional-compilation.md +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[the procedural macro attributes]: ../procedural-macros.md +[the testing attributes]: ../attributes/testing.md +[the optimization hint attributes]: ../attributes/codegen.md#optimization-hints +[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute +[`doc`]: ../../rustdoc/the-doc-attribute.html +[`must_use`]: ../attributes/diagnostics.md#the-must_use-attribute +[patterns]: ../patterns.md +[`?Sized`]: ../trait-bounds.md#sized +[trait bounds]: ../trait-bounds.md +[`export_name`]: ../abi.md#the-export_name-attribute +[`link_section`]: ../abi.md#the-link_section-attribute +[`no_mangle`]: ../abi.md#the-no_mangle-attribute diff --git a/src/doc/reference/src/items/generics.md b/src/doc/reference/src/items/generics.md index 39303ae507..f540ca7a79 100644 --- a/src/doc/reference/src/items/generics.md +++ b/src/doc/reference/src/items/generics.md @@ -100,22 +100,22 @@ generic parameter. } ``` -[IDENTIFIER]: identifiers.html -[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels - -[_LifetimeBounds_]: trait-bounds.html -[_Lifetime_]: trait-bounds.html -[_OuterAttribute_]: attributes.html -[_Type_]: types.html#type-expressions -[_TypeParamBounds_]: trait-bounds.html - -[arrays]: types/array.html -[function pointers]: types/function-pointer.html -[references]: types/pointer.html#shared-references- -[raw pointers]: types/pointer.html#raw-pointers-const-and-mut -[`Clone`]: special-types-and-traits.html#clone -[`Copy`]: special-types-and-traits.html#copy -[`Sized`]: special-types-and-traits.html#sized -[tuples]: types/tuple.html -[trait object]: types/trait-object.html -[attributes]: attributes.html +[IDENTIFIER]: ../identifiers.md +[LIFETIME_OR_LABEL]: ../tokens.md#lifetimes-and-loop-labels + +[_LifetimeBounds_]: ../trait-bounds.md +[_Lifetime_]: ../trait-bounds.md +[_OuterAttribute_]: ../attributes.md +[_Type_]: ../types.md#type-expressions +[_TypeParamBounds_]: ../trait-bounds.md + +[arrays]: ../types/array.md +[function pointers]: ../types/function-pointer.md +[references]: ../types/pointer.md#shared-references- +[raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut +[`Clone`]: ../special-types-and-traits.md#clone +[`Copy`]: ../special-types-and-traits.md#copy +[`Sized`]: ../special-types-and-traits.md#sized +[tuples]: ../types/tuple.md +[trait object]: ../types/trait-object.md +[attributes]: ../attributes.md diff --git a/src/doc/reference/src/items/implementations.md b/src/doc/reference/src/items/implementations.md index ea09c93cc9..fedc4c18c9 100644 --- a/src/doc/reference/src/items/implementations.md +++ b/src/doc/reference/src/items/implementations.md @@ -202,25 +202,25 @@ attributes must come before any associated items. That attributes that have meaning here are [`cfg`], [`deprecated`], [`doc`], and [the lint check attributes]. -[_ConstantItem_]: items/constant-items.html -[_Function_]: items/functions.html -[_Generics_]: items/generics.html -[_InnerAttribute_]: attributes.html -[_MacroInvocationSemi_]: macros.html#macro-invocation -[_Method_]: items/associated-items.html#methods -[_OuterAttribute_]: attributes.html -[_TypeAlias_]: items/type-aliases.html -[_TypePath_]: paths.html#paths-in-types -[_Type_]: types.html#type-expressions -[_Visibility_]: visibility-and-privacy.html -[_WhereClause_]: items/generics.html#where-clauses -[trait]: items/traits.html -[associated functions]: items/associated-items.html#associated-functions-and-methods -[associated constants]: items/associated-items.html#associated-constants -[attributes]: attributes.html -[`cfg`]: conditional-compilation.html -[`deprecated`]: attributes/diagnostics.html#the-deprecated-attribute -[`doc`]: ../rustdoc/the-doc-attribute.html -[path]: paths.html -[the lint check attributes]: attributes/diagnostics.html#lint-check-attributes -[Unsafe traits]: items/traits.html#unsafe-traits +[_ConstantItem_]: constant-items.md +[_Function_]: functions.md +[_Generics_]: generics.md +[_InnerAttribute_]: ../attributes.md +[_MacroInvocationSemi_]: ../macros.md#macro-invocation +[_Method_]: associated-items.md#methods +[_OuterAttribute_]: ../attributes.md +[_TypeAlias_]: type-aliases.md +[_TypePath_]: ../paths.md#paths-in-types +[_Type_]: ../types.md#type-expressions +[_Visibility_]: ../visibility-and-privacy.md +[_WhereClause_]: generics.md#where-clauses +[trait]: traits.md +[associated functions]: associated-items.md#associated-functions-and-methods +[associated constants]: associated-items.md#associated-constants +[attributes]: ../attributes.md +[`cfg`]: ../conditional-compilation.md +[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute +[`doc`]: ../../rustdoc/the-doc-attribute.html +[path]: ../paths.md +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes +[Unsafe traits]: traits.md#unsafe-traits diff --git a/src/doc/reference/src/items/modules.md b/src/doc/reference/src/items/modules.md index 87b8f07d12..c6f1f69c13 100644 --- a/src/doc/reference/src/items/modules.md +++ b/src/doc/reference/src/items/modules.md @@ -123,7 +123,7 @@ mod thread { ## Prelude Items Modules implicitly have some names in scope. These name are to built-in types, -macros imported with [`#[macro_use]`] on an extern crate, and by the crate's +macros imported with [`#[macro_use]`][macro_use] on an extern crate, and by the crate's [prelude]. These names are all made of a single identifier. These names are not part of the module, so for example, any name `name`, `self::name` is not a valid path. The names added by the [prelude] can be removed by placing the @@ -135,19 +135,19 @@ Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM and shebang. -The built-in attributes that have meaning on a function are [`cfg`], +The built-in attributes that have meaning on a module are [`cfg`], [`deprecated`], [`doc`], [the lint check attributes], `path`, and `no_implicit_prelude`. Modules also accept macro attributes. -[_InnerAttribute_]: attributes.html -[_Item_]: items.html -[`#[macro_use]`]: macros-by-example.html#the-macro_use-attribute -[`cfg`]: conditional-compilation.html -[`deprecated`]: attributes/diagnostics.html#the-deprecated-attribute -[`doc`]: ../rustdoc/the-doc-attribute.html -[IDENTIFIER]: identifiers.html -[attribute]: attributes.html -[items]: items.html -[module path]: paths.html -[prelude]: crates-and-source-files.html#preludes-and-no_std -[the lint check attributes]: attributes/diagnostics.html#lint-check-attributes +[_InnerAttribute_]: ../attributes.md +[_Item_]: ../items.md +[macro_use]: ../macros-by-example.md#the-macro_use-attribute +[`cfg`]: ../conditional-compilation.md +[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute +[`doc`]: ../../rustdoc/the-doc-attribute.html +[IDENTIFIER]: ../identifiers.md +[attribute]: ../attributes.md +[items]: ../items.md +[module path]: ../paths.md +[prelude]: ../crates-and-source-files.md#preludes-and-no_std +[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes diff --git a/src/doc/reference/src/items/static-items.md b/src/doc/reference/src/items/static-items.md index bcb4b6d7bd..e97e75903c 100644 --- a/src/doc/reference/src/items/static-items.md +++ b/src/doc/reference/src/items/static-items.md @@ -68,10 +68,10 @@ following are true: * The single-address property of statics is required. * Interior mutability is required. -[constant]: items/constant-items.html -[`drop`]: destructors.html -[constant expression]: const_eval.html#constant-expressions -[interior mutable]: interior-mutability.html -[IDENTIFIER]: identifiers.html -[_Type_]: types.html#type-expressions -[_Expression_]: expressions.html +[constant]: constant-items.md +[`drop`]: ../destructors.md +[constant expression]: ../const_eval.md#constant-expressions +[interior mutable]: ../interior-mutability.md +[IDENTIFIER]: ../identifiers.md +[_Type_]: ../types.md#type-expressions +[_Expression_]: ../expressions.md diff --git a/src/doc/reference/src/items/structs.md b/src/doc/reference/src/items/structs.md index 6634afb297..debd52cc78 100644 --- a/src/doc/reference/src/items/structs.md +++ b/src/doc/reference/src/items/structs.md @@ -49,8 +49,8 @@ let px: i32 = p.x; A _tuple struct_ is a nominal [tuple type], also defined with the keyword `struct`. For example: -[struct type]: types/struct.html -[tuple type]: types/tuple.html +[struct type]: ../types/struct.md +[tuple type]: ../types/tuple.md ```rust struct Point(i32, i32); @@ -78,11 +78,11 @@ let c = [Cookie, Cookie {}, Cookie, Cookie {}]; The precise memory layout of a struct is not specified. One can specify a particular layout using the [`repr` attribute]. -[`repr` attribute]: type-layout.html#representations +[`repr` attribute]: ../type-layout.md#representations -[_OuterAttribute_]: attributes.html -[IDENTIFIER]: identifiers.html -[_Generics_]: items/generics.html -[_WhereClause_]: items/generics.html#where-clauses -[_Visibility_]: visibility-and-privacy.html -[_Type_]: types.html#type-expressions +[_OuterAttribute_]: ../attributes.md +[IDENTIFIER]: ../identifiers.md +[_Generics_]: generics.md +[_WhereClause_]: generics.md#where-clauses +[_Visibility_]: ../visibility-and-privacy.md +[_Type_]: ../types.md#type-expressions diff --git a/src/doc/reference/src/items/traits.md b/src/doc/reference/src/items/traits.md index 5a60856fca..e835a6097e 100644 --- a/src/doc/reference/src/items/traits.md +++ b/src/doc/reference/src/items/traits.md @@ -49,9 +49,9 @@ A _trait_ describes an abstract interface that types can implement. This interface consists of [associated items], which come in three varieties: -- [functions](items/associated-items.html#associated-functions-and-methods) -- [types](items/associated-items.html#associated-types) -- [constants](items/associated-items.html#associated-constants) +- [functions](associated-items.md#associated-functions-and-methods) +- [types](associated-items.md#associated-types) +- [constants](associated-items.md#associated-constants) All traits define an implicit type parameter `Self` that refers to "the type that is implementing this interface". Traits may also contain additional type @@ -204,30 +204,30 @@ trait T { } ``` -[IDENTIFIER]: identifiers.html -[WildcardPattern]: patterns.html#wildcard-pattern -[_BlockExpression_]: expressions/block-expr.html -[_Expression_]: expressions.html -[_FunctionQualifiers_]: items/functions.html -[_FunctionReturnType_]: items/functions.html -[_Generics_]: items/generics.html -[_MacroInvocationSemi_]: macros.html#macro-invocation -[_OuterAttribute_]: attributes.html -[_Pattern_]: patterns.html -[_SelfParam_]: items/associated-items.html#methods -[_TypeParamBounds_]: trait-bounds.html -[_Type_]: types.html#type-expressions -[_WhereClause_]: items/generics.html#where-clauses -[bounds]: trait-bounds.html -[trait object]: types/trait-object.html +[IDENTIFIER]: ../identifiers.md +[WildcardPattern]: ../patterns.md#wildcard-pattern +[_BlockExpression_]: ../expressions/block-expr.md +[_Expression_]: ../expressions.md +[_FunctionQualifiers_]: functions.md +[_FunctionReturnType_]: functions.md +[_Generics_]: generics.md +[_MacroInvocationSemi_]: ../macros.md#macro-invocation +[_OuterAttribute_]: ../attributes.md +[_Pattern_]: ../patterns.md +[_SelfParam_]: associated-items.md#methods +[_TypeParamBounds_]: ../trait-bounds.md +[_Type_]: ../types.md#type-expressions +[_WhereClause_]: generics.md#where-clauses +[bounds]: ../trait-bounds.md +[trait object]: ../types/trait-object.md [RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md -[associated items]: items/associated-items.html -[method]: items/associated-items.html#methods -[implementations]: items/implementations.html -[generics]: items/generics.html -[where clauses]: items/generics.html#where-clauses -[generic functions]: items/functions.html#generic-functions -[unsafe]: unsafety.html -[trait implementation]: items/implementations.html#trait-implementations -[`Send`]: special-types-and-traits.html#send -[`Sync`]: special-types-and-traits.html#sync +[associated items]: associated-items.md +[method]: associated-items.md#methods +[implementations]: implementations.md +[generics]: generics.md +[where clauses]: generics.md#where-clauses +[generic functions]: functions.md#generic-functions +[unsafe]: ../unsafety.md +[trait implementation]: implementations.md#trait-implementations +[`Send`]: ../special-types-and-traits.md#send +[`Sync`]: ../special-types-and-traits.md#sync diff --git a/src/doc/reference/src/items/type-aliases.md b/src/doc/reference/src/items/type-aliases.md index 6ba22a87b0..b811a937b8 100644 --- a/src/doc/reference/src/items/type-aliases.md +++ b/src/doc/reference/src/items/type-aliases.md @@ -10,7 +10,7 @@ declared with the keyword `type`. Every value has a single, specific type, but may implement several different traits, or be compatible with several different type constraints. -[type]: types.html +[type]: ../types.md For example, the following defines the type `Point` as a synonym for the type `(u8, u8)`, the type of pairs of unsigned 8 bit integers: @@ -29,7 +29,7 @@ let _: F = E::A; // OK // let _: F = F::A; // Doesn't work ``` -[IDENTIFIER]: identifiers.html -[_Generics_]: items/generics.html -[_WhereClause_]: items/generics.html#where-clauses -[_Type_]: types.html#type-expressions +[IDENTIFIER]: ../identifiers.md +[_Generics_]: generics.md +[_WhereClause_]: generics.md#where-clauses +[_Type_]: ../types.md#type-expressions diff --git a/src/doc/reference/src/items/unions.md b/src/doc/reference/src/items/unions.md index 27c7668a24..f98c681bf7 100644 --- a/src/doc/reference/src/items/unions.md +++ b/src/doc/reference/src/items/unions.md @@ -20,6 +20,8 @@ The key property of unions is that all fields of a union share common storage. As a result writes to one field of a union can overwrite its other fields, and size of a union is determined by the size of its largest field. +## Initialization of a union + A value of a union type can be created using the same syntax that is used for struct types, except that it must specify exactly one field: @@ -37,13 +39,17 @@ struct fields: let f = u.f1; ``` +## Reading and writing union fields + Unions have no notion of an "active field". Instead, every union access just interprets the storage at the type of the field used for the access. Reading a -union field reads the bits of the union at the field's type. It is the -programmer's responsibility to make sure that the data is valid at that -type. Failing to do so results in undefined behavior. For example, reading the -value `3` at type `bool` is undefined behavior. Effectively, writing to and then -reading from a union is analogous to a [`transmute`] from the type used for +union field reads the bits of the union at the field's type. Fields might have a +non-zero offset (except when `#[repr(C)]` is used); in that case the bits +starting at the offset of the fields are read. It is the programmer's +responsibility to make sure that the data is valid at the field's type. Failing +to do so results in undefined behavior. For example, reading the value `3` at +type `bool` is undefined behavior. Effectively, writing to and then reading from +a `#[repr(C)]` union is analogous to a [`transmute`] from the type used for writing to the type used for reading. Consequently, all reads of union fields have to be placed in `unsafe` blocks: @@ -70,6 +76,8 @@ u.f1 = 2; Commonly, code using unions will provide safe wrappers around unsafe union field accesses. +## Pattern matching on unions + Another way to access union fields is to use pattern matching. Pattern matching on union fields uses the same syntax as struct patterns, except that the pattern must specify exactly one field. Since pattern matching is like reading the union @@ -119,6 +127,8 @@ fn is_zero(v: Value) -> bool { } ``` +## References to union fields + Since union fields share common storage, gaining write access to one field of a union can give write access to all its remaining fields. Borrow checking rules have to be adjusted to account for this fact. As a result, if one field of a @@ -148,8 +158,8 @@ aspects of Rust language (such as privacy, name resolution, type inference, generics, trait implementations, inherent implementations, coherence, pattern checking, etc etc etc). -[IDENTIFIER]: identifiers.html -[_Generics_]: items/generics.html -[_WhereClause_]: items/generics.html#where-clauses -[_StructFields_]: items/structs.html -[`transmute`]: ../std/mem/fn.transmute.html +[IDENTIFIER]: ../identifiers.md +[_Generics_]: generics.md +[_WhereClause_]: generics.md#where-clauses +[_StructFields_]: structs.md +[`transmute`]: ../../std/mem/fn.transmute.html diff --git a/src/doc/reference/src/items/use-declarations.md b/src/doc/reference/src/items/use-declarations.md index 264d52a543..aeddb83214 100644 --- a/src/doc/reference/src/items/use-declarations.md +++ b/src/doc/reference/src/items/use-declarations.md @@ -14,9 +14,9 @@ some other [path]. Usually a `use` declaration is used to shorten the path required to refer to a module item. These declarations may appear in [modules] and [blocks], usually at the top. -[path]: paths.html -[modules]: items/modules.html -[blocks]: expressions/block-expr.html +[path]: ../paths.md +[modules]: modules.md +[blocks]: ../expressions/block-expr.md Use declarations support a number of convenient shortcuts: @@ -195,8 +195,8 @@ m!(use std as _;); // use std as _; ``` -[IDENTIFIER]: identifiers.html -[_SimplePath_]: paths.html#simple-paths -[`extern crate`]: items/extern-crates.html -[extern prelude]: items/extern-crates.html#extern-prelude -[path qualifiers]: paths.html#path-qualifiers +[IDENTIFIER]: ../identifiers.md +[_SimplePath_]: ../paths.md#simple-paths +[`extern crate`]: extern-crates.md +[extern prelude]: extern-crates.md#extern-prelude +[path qualifiers]: ../paths.md#path-qualifiers diff --git a/src/doc/reference/src/keywords.md b/src/doc/reference/src/keywords.md index a0dc33dfa3..4eac070553 100644 --- a/src/doc/reference/src/keywords.md +++ b/src/doc/reference/src/keywords.md @@ -116,14 +116,14 @@ is possible to declare a variable or method with the name `union`. > **Lexer 2015**\ > KW_DYN : `dyn` -[items]: items.html -[Variables]: variables.html -[Type parameters]: types/parameters.html -[loop labels]: expressions/loop-expr.html#loop-labels -[Macros]: macros.html -[attributes]: attributes.html -[Macro placeholders]: macros-by-example.html -[Crates]: crates-and-source-files.html -[union]: items/unions.html -[variants]: items/enumerations.html -[`dyn`]: types/trait-object.html +[items]: items.md +[Variables]: variables.md +[Type parameters]: types/parameters.md +[loop labels]: expressions/loop-expr.md#loop-labels +[Macros]: macros.md +[attributes]: attributes.md +[Macro placeholders]: macros-by-example.md +[Crates]: crates-and-source-files.md +[union]: items/unions.md +[variants]: items/enumerations.md +[`dyn`]: types/trait-object.md diff --git a/src/doc/reference/src/lifetime-elision.md b/src/doc/reference/src/lifetime-elision.md index a90f38aec8..c4421b1040 100644 --- a/src/doc/reference/src/lifetime-elision.md +++ b/src/doc/reference/src/lifetime-elision.md @@ -169,11 +169,11 @@ const RESOLVED_MULTIPLE: &dyn Fn(&Foo, &Bar, &Baz) -> usize = .. const RESOLVED_STATIC: &dyn Fn(&Foo, &Bar) -> &Baz = .. ``` -[closure trait]: types/closure.html -[constant]: items/constant-items.html -[function item]: types/function-item.html -[function pointer]: types/function-pointer.html +[closure trait]: types/closure.md +[constant]: items/constant-items.md +[function item]: types/function-item.md +[function pointer]: types/function-pointer.md [RFC 599]: https://github.com/rust-lang/rfcs/blob/master/text/0599-default-object-bound.md [RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md -[static]: items/static-items.html -[trait object]: types/trait-object.html +[static]: items/static-items.md +[trait object]: types/trait-object.md diff --git a/src/doc/reference/src/linkage.md b/src/doc/reference/src/linkage.md index 1f27f80f8a..61a24f2a27 100644 --- a/src/doc/reference/src/linkage.md +++ b/src/doc/reference/src/linkage.md @@ -200,7 +200,7 @@ fn main() { } ``` -[cargo]: http://doc.crates.io/environment-variables.html#environment-variables-cargo-sets-for-build-scripts +[cargo]: ../cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts To use this feature locally, you typically will use the `RUSTFLAGS` environment variable to specify flags to the compiler through Cargo. For example to compile @@ -210,6 +210,6 @@ a statically linked binary on MSVC you would execute: RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc ``` -[`cfg` attribute `target_feature` option]: conditional-compilation.html#target_feature -[configuration option]: conditional-compilation.html -[procedural macros]: procedural-macros.html +[`cfg` attribute `target_feature` option]: conditional-compilation.md#target_feature +[configuration option]: conditional-compilation.md +[procedural macros]: procedural-macros.md diff --git a/src/doc/reference/src/macro-ambiguity.md b/src/doc/reference/src/macro-ambiguity.md index 1e0f3e26bd..f1dbb42850 100644 --- a/src/doc/reference/src/macro-ambiguity.md +++ b/src/doc/reference/src/macro-ambiguity.md @@ -372,6 +372,6 @@ why particular matchers are legal and others are not. * `($($e:expr)*)` : illegal, because expr NTs are not in FOLLOW(expr NT). -[Macros by Example]: macros-by-example.html +[Macros by Example]: macros-by-example.md [RFC 550]: https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.html [tracking issue]: https://github.com/rust-lang/rust/issues/56575 diff --git a/src/doc/reference/src/macros-by-example.md b/src/doc/reference/src/macros-by-example.md index 37fe5e9a0b..a47b3719f3 100644 --- a/src/doc/reference/src/macros-by-example.md +++ b/src/doc/reference/src/macros-by-example.md @@ -472,24 +472,24 @@ expansions, taking separators into account. This means: For more detail, see the [formal specification]. [Hygiene]: #hygiene -[IDENTIFIER]: identifiers.html -[IDENTIFIER_OR_KEYWORD]: identifiers.html -[LIFETIME_TOKEN]: tokens.html#lifetimes-and-loop-labels +[IDENTIFIER]: identifiers.md +[IDENTIFIER_OR_KEYWORD]: identifiers.md +[LIFETIME_TOKEN]: tokens.md#lifetimes-and-loop-labels [Metavariables]: #metavariables [Repetitions]: #repetitions -[_BlockExpression_]: expressions/block-expr.html -[_DelimTokenTree_]: macros.html -[_Expression_]: expressions.html -[_Item_]: items.html -[_LiteralExpression_]: expressions/literal-expr.html -[_MetaItem_]: attributes.html#meta-item-attribute-syntax -[_MetaListIdents_]: attributes.html#meta-item-attribute-syntax -[_Pattern_]: patterns.html -[_Statement_]: statements.html -[_TokenTree_]: macros.html#macro-invocation -[_Token_]: tokens.html -[_TypePath_]: paths.html#paths-in-types -[_Type_]: types.html#type-expressions -[_Visibility_]: visibility-and-privacy.html -[formal specification]: macro-ambiguity.html -[token]: tokens.html +[_BlockExpression_]: expressions/block-expr.md +[_DelimTokenTree_]: macros.md +[_Expression_]: expressions.md +[_Item_]: items.md +[_LiteralExpression_]: expressions/literal-expr.md +[_MetaItem_]: attributes.md#meta-item-attribute-syntax +[_MetaListIdents_]: attributes.md#meta-item-attribute-syntax +[_Pattern_]: patterns.md +[_Statement_]: statements.md +[_TokenTree_]: macros.md#macro-invocation +[_Token_]: tokens.md +[_TypePath_]: paths.md#paths-in-types +[_Type_]: types.md#type-expressions +[_Visibility_]: visibility-and-privacy.md +[formal specification]: macro-ambiguity.md +[token]: tokens.md diff --git a/src/doc/reference/src/macros.md b/src/doc/reference/src/macros.md index 42caaa1d78..cdac0b2bfc 100644 --- a/src/doc/reference/src/macros.md +++ b/src/doc/reference/src/macros.md @@ -86,16 +86,16 @@ macro_rules! example { example!(); ``` -[Macros by Example]: macros-by-example.html -[Procedural Macros]: procedural-macros.html -[_SimplePath_]: paths.html#simple-paths -[_Token_]: tokens.html -[associated items]: items/associated-items.html -[delimiters]: tokens.html#delimiters -[expressions]: expressions.html -[items]: items.html -[`macro_rules`]: macros-by-example.html -[patterns]: patterns.html -[statements]: statements.html -[types]: types.html -[visibility qualifiers]: visibility-and-privacy.html +[Macros by Example]: macros-by-example.md +[Procedural Macros]: procedural-macros.md +[_SimplePath_]: paths.md#simple-paths +[_Token_]: tokens.md +[associated items]: items/associated-items.md +[delimiters]: tokens.md#delimiters +[expressions]: expressions.md +[items]: items.md +[`macro_rules`]: macros-by-example.md +[patterns]: patterns.md +[statements]: statements.md +[types]: types.md +[visibility qualifiers]: visibility-and-privacy.md diff --git a/src/doc/reference/src/notation.md b/src/doc/reference/src/notation.md index 4dfff85d8d..2f9b42f010 100644 --- a/src/doc/reference/src/notation.md +++ b/src/doc/reference/src/notation.md @@ -35,7 +35,7 @@ When such a string in `monospace` font occurs inside the grammar, it is an implicit reference to a single member of such a string table production. See [tokens] for more information. -[binary operators]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators -[keywords]: keywords.html -[tokens]: tokens.html -[unary operators]: expressions/operator-expr.html#borrow-operators +[binary operators]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[keywords]: keywords.md +[tokens]: tokens.md +[unary operators]: expressions/operator-expr.md#borrow-operators diff --git a/src/doc/reference/src/paths.md b/src/doc/reference/src/paths.md index 9acf288784..5f13598df4 100644 --- a/src/doc/reference/src/paths.md +++ b/src/doc/reference/src/paths.md @@ -353,19 +353,19 @@ mod without { // ::without ``` [_GenericArgs_]: #paths-in-expressions -[_Lifetime_]: trait-bounds.html -[_Type_]: types.html#type-expressions -[item]: items.html -[variable]: variables.html -[implementations]: items/implementations.html -[use declarations]: items/use-declarations.html -[IDENTIFIER]: identifiers.html -[`use`]: items/use-declarations.html -[attributes]: attributes.html -[expressions]: expressions.html -[macro transcribers]: macros-by-example.html -[macros]: macros-by-example.html -[patterns]: patterns.html -[trait implementations]: items/implementations.html#trait-implementations -[traits]: items/traits.html -[visibility]: visibility-and-privacy.html +[_Lifetime_]: trait-bounds.md +[_Type_]: types.md#type-expressions +[item]: items.md +[variable]: variables.md +[implementations]: items/implementations.md +[use declarations]: items/use-declarations.md +[IDENTIFIER]: identifiers.md +[`use`]: items/use-declarations.md +[attributes]: attributes.md +[expressions]: expressions.md +[macro transcribers]: macros-by-example.md +[macros]: macros-by-example.md +[patterns]: patterns.md +[trait implementations]: items/implementations.md#trait-implementations +[traits]: items/traits.md +[visibility]: visibility-and-privacy.md diff --git a/src/doc/reference/src/patterns.md b/src/doc/reference/src/patterns.md index 87f1ac936c..8947467b0f 100644 --- a/src/doc/reference/src/patterns.md +++ b/src/doc/reference/src/patterns.md @@ -57,13 +57,13 @@ if let Patterns are used in: -* [`let` declarations](statements.html#let-statements) -* [Function](items/functions.html) and [closure](expressions/closure-expr.html) +* [`let` declarations](statements.md#let-statements) +* [Function](items/functions.md) and [closure](expressions/closure-expr.md) parameters -* [`match` expressions](expressions/match-expr.html) -* [`if let` expressions](expressions/if-expr.html) -* [`while let` expressions](expressions/loop-expr.html#predicate-pattern-loops) -* [`for` expressions](expressions/loop-expr.html#iterator-loops) +* [`match` expressions](expressions/match-expr.md) +* [`if let` expressions](expressions/if-expr.md) +* [`while let` expressions](expressions/loop-expr.md#predicate-pattern-loops) +* [`for` expressions](expressions/loop-expr.md#iterator-loops) ## Destructuring @@ -125,15 +125,15 @@ if let (a, 3) = (1, 2) { // "(a, 3)" is refutable, and will not match >    | `-`? [INTEGER_LITERAL]\ >    | `-`? [FLOAT_LITERAL] -[BOOLEAN_LITERAL]: tokens.html#boolean-literals -[CHAR_LITERAL]: tokens.html#character-literals -[BYTE_LITERAL]: tokens.html#byte-literals -[STRING_LITERAL]: tokens.html#string-literals -[RAW_STRING_LITERAL]: tokens.html#raw-string-literals -[BYTE_STRING_LITERAL]: tokens.html#byte-string-literals -[RAW_BYTE_STRING_LITERAL]: tokens.html#raw-byte-string-literals -[INTEGER_LITERAL]: tokens.html#integer-literals -[FLOAT_LITERAL]: tokens.html#floating-point-literals +[BOOLEAN_LITERAL]: tokens.md#boolean-literals +[CHAR_LITERAL]: tokens.md#character-literals +[BYTE_LITERAL]: tokens.md#byte-literals +[STRING_LITERAL]: tokens.md#string-literals +[RAW_STRING_LITERAL]: tokens.md#raw-string-literals +[BYTE_STRING_LITERAL]: tokens.md#byte-string-literals +[RAW_BYTE_STRING_LITERAL]: tokens.md#raw-byte-string-literals +[INTEGER_LITERAL]: tokens.md#integer-literals +[FLOAT_LITERAL]: tokens.md#floating-point-literals _Literal patterns_ match exactly the same value as what is created by the literal. Since negative numbers are not [literals], literal patterns also @@ -480,8 +480,8 @@ Reference patterns are always irrefutable. >    [_OuterAttribute_] \*\ >    `..` -[_OuterAttribute_]: attributes.html -[TUPLE_INDEX]: tokens.html#integer-literals +[_OuterAttribute_]: attributes.md +[TUPLE_INDEX]: tokens.md#integer-literals Struct patterns match struct values that match all criteria defined by its subpatterns. They are also used to [destructure](#destructuring) a struct. @@ -657,11 +657,11 @@ refer to refutable constants or enum variants for enums with multiple variants. [_GroupedPattern_]: #grouped-patterns [_IdentifierPattern_]: #identifier-patterns [_LiteralPattern_]: #literal-patterns -[_MacroInvocation_]: macros.html#macro-invocation -[_PathInExpression_]: paths.html#paths-in-expressions +[_MacroInvocation_]: macros.md#macro-invocation +[_PathInExpression_]: paths.md#paths-in-expressions [_PathPattern_]: #path-patterns [_Pattern_]: #patterns -[_QualifiedPathInExpression_]: paths.html#qualified-paths +[_QualifiedPathInExpression_]: paths.md#qualified-paths [_RangePattern_]: #range-patterns [_ReferencePattern_]: #reference-patterns [_SlicePattern_]: #slice-patterns @@ -670,10 +670,10 @@ refer to refutable constants or enum variants for enums with multiple variants. [_TupleStructPattern_]: #tuple-struct-patterns [_WildcardPattern_]: #wildcard-pattern -[`Copy`]: special-types-and-traits.html#copy -[IDENTIFIER]: identifiers.html -[enums]: items/enumerations.html -[literals]: expressions/literal-expr.html -[structs]: items/structs.html -[tuples]: types/tuple.html -[scrutinee]: glossary.html#scrutinee +[`Copy`]: special-types-and-traits.md#copy +[IDENTIFIER]: identifiers.md +[enums]: items/enumerations.md +[literals]: expressions/literal-expr.md +[structs]: items/structs.md +[tuples]: types/tuple.md +[scrutinee]: glossary.md#scrutinee diff --git a/src/doc/reference/src/procedural-macros.md b/src/doc/reference/src/procedural-macros.md index a73d09cc05..9818b26556 100644 --- a/src/doc/reference/src/procedural-macros.md +++ b/src/doc/reference/src/procedural-macros.md @@ -269,25 +269,25 @@ fn invoke4() {} [`TokenStream`]: ../proc_macro/struct.TokenStream.html [`TokenStream`s]: ../proc_macro/struct.TokenStream.html [`compile_error`]: ../std/macro.compile_error.html -[`derive` attribute]: attributes/derive.html +[`derive` attribute]: attributes/derive.md [`proc_macro` crate]: ../proc_macro/index.html [Cargo's build scripts]: ../cargo/reference/build-scripts.html [Derive macros]: #derive-macros [Attribute macros]: #attribute-macros [Function-like macros]: #function-like-procedural-macros -[attribute]: attributes.html -[attributes]: attributes.html -[block]: expressions/block-expr.html -[crate type]: linkage.html +[attribute]: attributes.md +[attributes]: attributes.md +[block]: expressions/block-expr.md +[crate type]: linkage.md [derive macro helper attributes]: #derive-macro-helper-attributes -[enum]: items/enumerations.html -[inert]: attributes.html#active-and-inert-attributes -[item]: items.html -[item declaration statements]: statements.html#item-declarations -[items]: items.html -[function]: items/functions.html -[module]: items/modules.html -[modules]: items/modules.html -[public]: visibility-and-privacy.html -[struct]: items/structs.html -[union]: items/unions.html +[enum]: items/enumerations.md +[inert]: attributes.md#active-and-inert-attributes +[item]: items.md +[item declaration statements]: statements.md#item-declarations +[items]: items.md +[function]: items/functions.md +[module]: items/modules.md +[modules]: items/modules.md +[public]: visibility-and-privacy.md +[struct]: items/structs.md +[union]: items/unions.md diff --git a/src/doc/reference/src/runtime.md b/src/doc/reference/src/runtime.md index 5a1f98b0ab..57680d051e 100644 --- a/src/doc/reference/src/runtime.md +++ b/src/doc/reference/src/runtime.md @@ -68,12 +68,12 @@ for non-`bin` [crate types]. #![windows_subsystem = "windows"] ``` -[_MetaNameValueStr_]: attributes.html#meta-item-attribute-syntax +[_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax [`GlobalAlloc`]: ../alloc/alloc/trait.GlobalAlloc.html [`PanicInfo`]: ../core/panic/struct.PanicInfo.html [abort]: ../book/ch09-01-unrecoverable-errors-with-panic.html -[attribute]: attributes.html -[crate types]: linkage.html +[attribute]: attributes.md +[crate types]: linkage.md [set_hook]: ../std/panic/fn.set_hook.html -[static item]: items/static-items.html +[static item]: items/static-items.md [subsystem]: https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx diff --git a/src/doc/reference/src/special-types-and-traits.md b/src/doc/reference/src/special-types-and-traits.md index 5cd095601e..be2fdaa05c 100644 --- a/src/doc/reference/src/special-types-and-traits.md +++ b/src/doc/reference/src/special-types-and-traits.md @@ -154,29 +154,29 @@ compiler, not by [implementation items]. [`UnwindSafe`]: ../std/panic/trait.UnwindSafe.html [`Sync`]: ../std/marker/trait.Sync.html -[Arrays]: types/array.html -[call expressions]: expressions/call-expr.html -[deref coercions]: type-coercions.html#coercion-types -[dereference operator]: expressions/operator-expr.html#the-dereference-operator -[destructor]: destructors.html +[Arrays]: types/array.md +[call expressions]: expressions/call-expr.md +[deref coercions]: type-coercions.md#coercion-types +[dereference operator]: expressions/operator-expr.md#the-dereference-operator +[destructor]: destructors.md [drop check]: ../nomicon/dropck.html -[dynamically sized type]: dynamically-sized-types.html -[Function pointers]: types/function-pointer.html -[function item types]: types/function-item.html -[implementation items]: items/implementations.html -[indexing expressions]: expressions/array-expr.html#array-and-slice-indexing-expressions -[interior mutability]: interior-mutability.html -[Numeric types]: types/numeric.html -[Methods]: items/associated-items.html#associated-functions-and-methods -[method resolution]: expressions/method-call-expr.html -[operators]: expressions/operator-expr.html -[orphan rules]: items/implementations.html#trait-implementation-coherence -[Raw pointers]: types/pointer.html#raw-pointers-const-and-mut -[`static` items]: items/static-items.html -[Shared references]: types/pointer.html#shared-references- +[dynamically sized type]: dynamically-sized-types.md +[Function pointers]: types/function-pointer.md +[function item types]: types/function-item.md +[implementation items]: items/implementations.md +[indexing expressions]: expressions/array-expr.md#array-and-slice-indexing-expressions +[interior mutability]: interior-mutability.md +[Numeric types]: types/numeric.md +[Methods]: items/associated-items.md#associated-functions-and-methods +[method resolution]: expressions/method-call-expr.md +[operators]: expressions/operator-expr.md +[orphan rules]: items/implementations.md#trait-implementation-coherence +[Raw pointers]: types/pointer.md#raw-pointers-const-and-mut +[`static` items]: items/static-items.md +[Shared references]: types/pointer.md#shared-references- [the standard library]: ../std/index.html -[trait object]: types/trait-object.html -[Tuples]: types/tuple.html -[Type parameters]: types/parameters.html -[variance]: subtyping.html#variance -[`!`]: types/never.html +[trait object]: types/trait-object.md +[Tuples]: types/tuple.md +[Type parameters]: types/parameters.md +[variance]: subtyping.md#variance +[`!`]: types/never.md diff --git a/src/doc/reference/src/statements.md b/src/doc/reference/src/statements.md index f5f4e565e7..c55f002986 100644 --- a/src/doc/reference/src/statements.md +++ b/src/doc/reference/src/statements.md @@ -115,23 +115,23 @@ if true { Statements accept [outer attributes]. The attributes that have meaning on a statement are [`cfg`], and [the lint check attributes]. -[block]: expressions/block-expr.html -[expression]: expressions.html -[function]: items/functions.html -[item]: items.html -[module]: items/modules.html -[canonical path]: paths.html#canonical-paths -[implementations]: items/implementations.html -[variables]: variables.html -[outer attributes]: attributes.html -[`cfg`]: conditional-compilation.html -[the lint check attributes]: attributes/diagnostics.html#lint-check-attributes -[pattern]: patterns.html +[block]: expressions/block-expr.md +[expression]: expressions.md +[function]: items/functions.md +[item]: items.md +[module]: items/modules.md +[canonical path]: paths.md#canonical-paths +[implementations]: items/implementations.md +[variables]: variables.md +[outer attributes]: attributes.md +[`cfg`]: conditional-compilation.md +[the lint check attributes]: attributes/diagnostics.md#lint-check-attributes +[pattern]: patterns.md [_ExpressionStatement_]: #expression-statements -[_Expression_]: expressions.html -[_Item_]: items.html +[_Expression_]: expressions.md +[_Item_]: items.md [_LetStatement_]: #let-statements -[_MacroInvocationSemi_]: macros.html#macro-invocation -[_OuterAttribute_]: attributes.html -[_Pattern_]: patterns.html -[_Type_]: types.html +[_MacroInvocationSemi_]: macros.md#macro-invocation +[_OuterAttribute_]: attributes.md +[_Pattern_]: patterns.md +[_Type_]: types.md diff --git a/src/doc/reference/src/subtyping.md b/src/doc/reference/src/subtyping.md index 3723b180cc..b886830ad7 100644 --- a/src/doc/reference/src/subtyping.md +++ b/src/doc/reference/src/subtyping.md @@ -82,6 +82,6 @@ struct Variance<'a, 'b, T, U: 'a> { } ``` -[function pointers]: types/function-pointer.html +[function pointers]: types/function-pointer.md [Higher-ranked]: ../nomicon/hrtb.html -[trait objects]: types/trait-object.html +[trait objects]: types/trait-object.md diff --git a/src/doc/reference/src/tokens.md b/src/doc/reference/src/tokens.md index d75ae765cb..a9aa87d183 100644 --- a/src/doc/reference/src/tokens.md +++ b/src/doc/reference/src/tokens.md @@ -14,14 +14,14 @@ into the following kinds of tokens: Within this documentation's grammar, "simple" tokens are given in [string table production] form, and appear in `monospace` font. -[string table production]: notation.html#string-table-productions +[string table production]: notation.md#string-table-productions ## Literals A literal is an expression consisting of a single token, rather than a sequence of tokens, that immediately and directly denotes the value it evaluates to, rather than referring to it by name or some other evaluation rule. A literal is -a form of [constant expression](const_eval.html#constant-expressions), so is +a form of [constant expression](const_eval.md#constant-expressions), so is evaluated (primarily) at compile time. ### Examples @@ -439,7 +439,7 @@ Note that the Rust syntax considers `-1i8` as an application of the [unary minus operator] to an integer literal `1i8`, rather than a single integer literal. -[unary minus operator]: expressions/operator-expr.html#negation-operators +[unary minus operator]: expressions/operator-expr.md#negation-operators #### Floating-point literals @@ -500,7 +500,7 @@ to call a method named `f64` on `2`. The representation semantics of floating-point numbers are described in ["Machine Types"]. -["Machine Types"]: types/numeric.html +["Machine Types"]: types/numeric.md ### Boolean literals @@ -525,7 +525,7 @@ Lifetime parameters and [loop labels] use LIFETIME_OR_LABEL tokens. Any LIFETIME_TOKEN will be accepted by the lexer, and for example, can be used in macros. -[loop labels]: expressions/loop-expr.html +[loop labels]: expressions/loop-expr.md ## Punctuation @@ -593,41 +593,41 @@ them are referred to as "token trees" in [macros]. The three types of brackets | `(` `)` | Parentheses | -[Inferred types]: types/inferred.html -[Range patterns]: patterns.html#range-patterns -[Reference patterns]: patterns.html#reference-patterns -[Subpattern binding]: patterns.html#identifier-patterns -[Wildcard patterns]: patterns.html#wildcard-pattern -[arith]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators -[array types]: types/array.html -[assignment]: expressions/operator-expr.html#assignment-expressions -[attributes]: attributes.html -[borrow]: expressions/operator-expr.html#borrow-operators -[closures]: expressions/closure-expr.html -[comparison]: expressions/operator-expr.html#comparison-operators -[compound]: expressions/operator-expr.html#compound-assignment-expressions -[dereference]: expressions/operator-expr.html#the-dereference-operator -[extern]: items/external-blocks.html -[field]: expressions/field-expr.html -[functions]: items/functions.html -[generics]: items/generics.html -[identifier]: identifiers.html -[keywords]: keywords.html -[lazy-bool]: expressions/operator-expr.html#lazy-boolean-operators -[macros]: macros-by-example.html -[match]: expressions/match-expr.html -[negation]: expressions/operator-expr.html#negation-operators -[never type]: types/never.html -[paths]: paths.html -[patterns]: patterns.html -[question]: expressions/operator-expr.html#the-question-mark-operator -[range]: expressions/range-expr.html -[raw pointers]: types/pointer.html#raw-pointers-const-and-mut -[references]: types/pointer.html -[sized]: trait-bounds.html#sized -[struct expressions]: expressions/struct-expr.html -[trait bounds]: trait-bounds.html -[tuple index]: expressions/tuple-expr.html#tuple-indexing-expressions -[tuple structs]: items/structs.html -[tuple variants]: items/enumerations.html -[tuples]: types/tuple.html +[Inferred types]: types/inferred.md +[Range patterns]: patterns.md#range-patterns +[Reference patterns]: patterns.md#reference-patterns +[Subpattern binding]: patterns.md#identifier-patterns +[Wildcard patterns]: patterns.md#wildcard-pattern +[arith]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators +[array types]: types/array.md +[assignment]: expressions/operator-expr.md#assignment-expressions +[attributes]: attributes.md +[borrow]: expressions/operator-expr.md#borrow-operators +[closures]: expressions/closure-expr.md +[comparison]: expressions/operator-expr.md#comparison-operators +[compound]: expressions/operator-expr.md#compound-assignment-expressions +[dereference]: expressions/operator-expr.md#the-dereference-operator +[extern]: items/external-blocks.md +[field]: expressions/field-expr.md +[functions]: items/functions.md +[generics]: items/generics.md +[identifier]: identifiers.md +[keywords]: keywords.md +[lazy-bool]: expressions/operator-expr.md#lazy-boolean-operators +[macros]: macros-by-example.md +[match]: expressions/match-expr.md +[negation]: expressions/operator-expr.md#negation-operators +[never type]: types/never.md +[paths]: paths.md +[patterns]: patterns.md +[question]: expressions/operator-expr.md#the-question-mark-operator +[range]: expressions/range-expr.md +[raw pointers]: types/pointer.md#raw-pointers-const-and-mut +[references]: types/pointer.md +[sized]: trait-bounds.md#sized +[struct expressions]: expressions/struct-expr.md +[trait bounds]: trait-bounds.md +[tuple index]: expressions/tuple-expr.md#tuple-indexing-expressions +[tuple structs]: items/structs.md +[tuple variants]: items/enumerations.md +[tuples]: types/tuple.md diff --git a/src/doc/reference/src/trait-bounds.md b/src/doc/reference/src/trait-bounds.md index cbdaf958ad..6c48e5e6ff 100644 --- a/src/doc/reference/src/trait-bounds.md +++ b/src/doc/reference/src/trait-bounds.md @@ -134,13 +134,13 @@ fn call_on_ref_zero(f: F) where F: for<'a> Fn(&'a i32) { } ``` -[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels -[_TypePath_]: paths.html#paths-in-types -[`Sized`]: special-types-and-traits.html#sized - -[associated types]: items/associated-items.html#associated-types -[supertraits]: items/traits.html#supertraits -[generic]: items/generics.html -[Trait]: items/traits.html#trait-bounds -[trait objects]: types/trait-object.html -[where clause]: items/generics.html#where-clauses +[LIFETIME_OR_LABEL]: tokens.md#lifetimes-and-loop-labels +[_TypePath_]: paths.md#paths-in-types +[`Sized`]: special-types-and-traits.md#sized + +[associated types]: items/associated-items.md#associated-types +[supertraits]: items/traits.md#supertraits +[generic]: items/generics.md +[Trait]: items/traits.md#trait-bounds +[trait objects]: types/trait-object.md +[where clause]: items/generics.md#where-clauses diff --git a/src/doc/reference/src/type-coercions.md b/src/doc/reference/src/type-coercions.md index 5b2fcb9644..377afe769b 100644 --- a/src/doc/reference/src/type-coercions.md +++ b/src/doc/reference/src/type-coercions.md @@ -140,7 +140,7 @@ Coercion is allowed between the following types: - `*mut T` - `Box` - and where `T` can obtained from `U` by [unsized coercion](#unsized-coercions). + and where `U` can be obtained from `T` by [unsized coercion](#unsized-coercions). lib.rs:2:5 diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index 7768b41f85..a6e4e166d7 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -165,7 +165,7 @@ pub struct Foo; When set to 'deny', this will produce: ```text -error: type does not implement `fmt::Debug`; consider adding #[derive(Debug)] or a manual implementation +error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation --> src/main.rs:3:1 | 3 | pub struct Foo; diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index c1740f272e..6574267f18 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -40,7 +40,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type` 4 | fn foo(t: T) {} | ^ | - = note: #[deny(invalid_type_param_default)] on by default + = note: `#[deny(invalid_type_param_default)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #36887 ``` @@ -74,7 +74,7 @@ error: private struct constructors are not usable through re-exports in outer mo 5 | ::S; | ^^^ | - = note: #[deny(legacy_constructor_visibility)] on by default + = note: `#[deny(legacy_constructor_visibility)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #39207 ``` @@ -84,9 +84,9 @@ error: private struct constructors are not usable through re-exports in outer mo The legacy_directory_ownership warning is issued when -* There is a non-inline module with a #[path] attribute (e.g. #[path = "foo.rs"] mod bar;), +* There is a non-inline module with a `#[path]` attribute (e.g. `#[path = "foo.rs"] mod bar;`), * The module's file ("foo.rs" in the above example) is not named "mod.rs", and -* The module's file contains a non-inline child module without a #[path] attribute. +* The module's file contains a non-inline child module without a `#[path]` attribute. The warning can be fixed by renaming the parent module to "mod.rs" and moving it into its own directory if appropriate. @@ -139,7 +139,7 @@ const FOO: i32 = 5; This will produce: ```text -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> src/main.rs:3:1 | 3 | const FOO: i32 = 5; @@ -187,7 +187,7 @@ error: parenthesized parameters may only be used with a trait 2 | let x = 5 as usize(); | ^^ | - = note: #[deny(parenthesized_params_in_types_and_modules)] on by default + = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 ``` diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index 6d4aa024c7..e486240fda 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -90,7 +90,7 @@ warning: floating-point literals cannot be used in patterns 4 | 5.0 => {}, | ^^^ | - = note: #[warn(illegal_floating_point_literal_pattern)] on by default + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 ``` @@ -109,7 +109,7 @@ extern "C" { This will produce: ```text -warning: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type +warning: found struct without foreign-function-safe representation annotation in foreign module, consider adding a `#[repr(C)]` attribute to the type --> src/main.rs:2:20 | 2 | static STATIC: String; @@ -146,7 +146,7 @@ warning: cannot specify lifetime arguments explicitly if late bound lifetime par 8 | S.late::<'static>(&0, &0); | ^^^^^^^ | - = note: #[warn(late_bound_lifetime_arguments)] on by default + = note: `#[warn(late_bound_lifetime_arguments)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 ``` @@ -327,7 +327,7 @@ warning: patterns aren't allowed in methods without bodies 2 | fn foo(mut arg: u8); | ^^^^^^^ | - = note: #[warn(patterns_in_fns_without_body)] on by default + = note: `#[warn(patterns_in_fns_without_body)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #35203 ``` @@ -406,7 +406,7 @@ fn foo() {} This will produce: ```text -warning: function is marked #[no_mangle], but not exported +warning: function is marked `#[no_mangle]`, but not exported --> src/main.rs:2:1 | 2 | fn foo() {} @@ -433,7 +433,7 @@ static X: i32 = 4; This will produce: ```text -warning: static is marked #[no_mangle], but not exported +warning: static is marked `#[no_mangle]`, but not exported --> src/main.rs:2:1 | 2 | static X: i32 = 4; @@ -496,7 +496,7 @@ warning: borrow of packed field requires unsafe function or block (error E0133) 11 | let y = &x.data.0; | ^^^^^^^^^ | - = note: #[warn(safe_packed_borrows)] on by default + = note: `#[warn(safe_packed_borrows)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 ``` @@ -542,7 +542,7 @@ warning: bounds on generic parameters are not enforced in type aliases 2 | type SendVec = Vec; | ^^^^ | - = note: #[warn(type_alias_bounds)] on by default + = note: `#[warn(type_alias_bounds)]` on by default = help: the bound will not be checked when the type alias is used, and should be removed ``` @@ -567,7 +567,7 @@ warning: type annotations needed 4 | if data.is_null() {} | ^^^^^^^ | - = note: #[warn(tyvar_behind_raw_pointer)] on by default + = note: `#[warn(tyvar_behind_raw_pointer)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #46906 ``` @@ -787,7 +787,7 @@ warning: doc comment not used by rustdoc ## unused-features -This lint detects unused or unknown features found in crate-level #[feature] directives. +This lint detects unused or unknown features found in crate-level `#[feature]` directives. To fix this, simply remove the feature flag. ## unused-imports @@ -839,7 +839,7 @@ warning: unused macro definition ## unused-must-use -This lint detects unused result of a type flagged as #[must_use]. Some +This lint detects unused result of a type flagged as `#[must_use]`. Some example code that triggers this lint: ```rust diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 3938df1a68..6e32468b64 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -183,9 +183,8 @@ Book][unstable-masked] and [its tracking issue][issue-masked]. As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This is useful if certain documentation is so long that it would break the flow of reading the source. -Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` (where `sometype.md` is -a file adjacent to the `lib.rs` for the crate) will ask Rustdoc to instead read that file and use it -as if it were written inline. +Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` will ask Rustdoc to +instead read that file and use it as if it were written inline. [RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990 @@ -212,6 +211,36 @@ pub struct BigX; Then, when looking for it through the `rustdoc` search, if you enter "x" or "big", search will show the `BigX` struct first. +### Include items only when collecting doctests + +Rustdoc's [documentation tests] can do some things that regular unit tests can't, so it can +sometimes be useful to extend your doctests with samples that wouldn't otherwise need to be in +documentation. To this end, Rustdoc allows you to have certain items only appear when it's +collecting doctests, so you can utilize doctest functionality without forcing the test to appear in +docs, or to find an arbitrary private item to include it on. + +If you add `#![feature(cfg_doctest)]` to your crate, Rustdoc will set `cfg(doctest)` when collecting +doctests. Note that they will still link against only the public items of your crate; if you need to +test private items, unit tests are still the way to go. + +In this example, we're adding doctests that we know won't compile, to verify that our struct can +only take in valid data: + +```rust +#![feature(cfg_doctest)] + +/// We have a struct here. Remember it doesn't accept negative numbers! +pub struct MyStruct(usize); + +/// ```compile_fail +/// let x = my_crate::MyStruct(-5); +/// ``` +#[cfg(doctest)] +pub struct MyStructOnlyTakesUsize; +``` + +[documentation tests]: documentation-tests.html + ## Unstable command-line arguments These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are diff --git a/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md b/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md new file mode 100644 index 0000000000..09d1b19b4c --- /dev/null +++ b/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md @@ -0,0 +1,11 @@ +# `const_in_array_repeat_expressions` + +The tracking issue for this feature is: [#49147] + +[#44109]: https://github.com/rust-lang/rust/issues/49147 + +------------------------ + +Relaxes the rules for repeat expressions, `[x; N]` such that `x` may also be `const` (strictly +speaking rvalue promotable), in addition to `typeof(x): Copy`. The result of `[x; N]` where `x` is +`const` is itself also `const`. diff --git a/src/doc/unstable-book/src/language-features/on-unimplemented.md b/src/doc/unstable-book/src/language-features/on-unimplemented.md index a770ab65c2..8db241e4b4 100644 --- a/src/doc/unstable-book/src/language-features/on-unimplemented.md +++ b/src/doc/unstable-book/src/language-features/on-unimplemented.md @@ -98,7 +98,8 @@ application of these fields based on a variety of attributes when using `crate_local`) or matching against a particular method. Currently used for `try`. - `from_desugaring`: usable both as boolean (whether the flag is present) - or matching against a particular desugaring. + or matching against a particular desugaring. The desugaring is identified + with its variant name in the `DesugaringKind` enum. For example, the `Iterator` trait can be annotated in the following way: diff --git a/src/doc/unstable-book/src/language-features/param-attrs.md b/src/doc/unstable-book/src/language-features/param-attrs.md new file mode 100644 index 0000000000..4b83c204ba --- /dev/null +++ b/src/doc/unstable-book/src/language-features/param-attrs.md @@ -0,0 +1,27 @@ +# `param_attrs` + +The tracking issue for this feature is: [#60406] + +[#60406]: https://github.com/rust-lang/rust/issues/60406 + +Allow attributes in formal function parameter position so external tools and compiler internals can +take advantage of the additional information that the parameters provide. + +Enables finer conditional compilation with `#[cfg(..)]` and linting control of variables. Moreover, +opens the path to richer DSLs created by users. + +------------------------ + +Example: + +```rust +#![feature(param_attrs)] + +fn len( + #[cfg(windows)] slice: &[u16], + #[cfg(not(windows))] slice: &[u8], +) -> usize +{ + slice.len() +} +``` diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 0e38e2865d..8be4d16998 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -44,7 +44,7 @@ code that manipulates syntax trees at compile time. Let's write a plugin -[`roman_numerals.rs`](https://github.com/rust-lang/rust/blob/master/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs) +[`roman_numerals.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/roman_numerals.rs) that implements Roman numeral integer literals. ```rust,ignore @@ -59,7 +59,6 @@ extern crate rustc_plugin; use syntax::parse::token::{self, Token}; use syntax::tokenstream::TokenTree; use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; -use syntax::ext::build::AstBuilder; // A trait for expr_usize. use syntax_pos::Span; use rustc_plugin::Registry; @@ -164,13 +163,6 @@ can continue and find further errors. To print syntax fragments for debugging, you can use `span_note` together with `syntax::print::pprust::*_to_string`. -The example above produced an integer literal using `AstBuilder::expr_usize`. -As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of -quasiquote macros. They are undocumented and very rough around the edges. -However, the implementation may be a good starting point for an improved -quasiquote as an ordinary plugin library. - - # Lint plugins Plugins can extend [Rust's lint diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md index 133174268e..cdb7449588 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -1,8 +1,8 @@ # `slice_patterns` -The tracking issue for this feature is: [#23121] +The tracking issue for this feature is: [#62254] -[#23121]: https://github.com/rust-lang/rust/issues/23121 +[#62254]: https://github.com/rust-lang/rust/issues/62254 ------------------------ @@ -17,7 +17,7 @@ matched against that pattern. For example: fn is_symmetric(list: &[u32]) -> bool { match list { &[] | &[_] => true, - &[x, ref inside.., y] if x == y => is_symmetric(inside), + &[x, ref inside @ .., y] if x == y => is_symmetric(inside), &[..] => false, } } diff --git a/src/doc/unstable-book/src/language-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md similarity index 100% rename from src/doc/unstable-book/src/language-features/asm.md rename to src/doc/unstable-book/src/library-features/asm.md diff --git a/src/doc/unstable-book/src/language-features/concat-idents.md b/src/doc/unstable-book/src/library-features/concat-idents.md similarity index 100% rename from src/doc/unstable-book/src/language-features/concat-idents.md rename to src/doc/unstable-book/src/library-features/concat-idents.md diff --git a/src/doc/unstable-book/src/library-features/debug-map-key-value.md b/src/doc/unstable-book/src/library-features/debug-map-key-value.md new file mode 100644 index 0000000000..ae839bf2ac --- /dev/null +++ b/src/doc/unstable-book/src/library-features/debug-map-key-value.md @@ -0,0 +1,9 @@ +# `debug_map_key_value` + +The tracking issue for this feature is: [#62482] + +[#62482]: https://github.com/rust-lang/rust/issues/62482 + +------------------------ + +Add the methods `key` and `value` to `DebugMap` so that an entry can be formatted across multiple calls without additional buffering. diff --git a/src/doc/unstable-book/src/language-features/global-asm.md b/src/doc/unstable-book/src/library-features/global-asm.md similarity index 100% rename from src/doc/unstable-book/src/language-features/global-asm.md rename to src/doc/unstable-book/src/library-features/global-asm.md diff --git a/src/doc/unstable-book/src/library-features/n16.md b/src/doc/unstable-book/src/library-features/n16.md deleted file mode 100644 index e556adaa13..0000000000 --- a/src/doc/unstable-book/src/library-features/n16.md +++ /dev/null @@ -1,5 +0,0 @@ -# `n16` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/language-features/trace-macros.md b/src/doc/unstable-book/src/library-features/trace-macros.md similarity index 100% rename from src/doc/unstable-book/src/language-features/trace-macros.md rename to src/doc/unstable-book/src/library-features/trace-macros.md diff --git a/src/etc/cpu-usage-over-time-plot.sh b/src/etc/cpu-usage-over-time-plot.sh index 724a21c3fc..0905789079 100755 --- a/src/etc/cpu-usage-over-time-plot.sh +++ b/src/etc/cpu-usage-over-time-plot.sh @@ -16,7 +16,7 @@ set -ex -bucket=rust-lang-ci-evalazure +bucket=rust-lang-ci2 commit=$1 builder=$2 diff --git a/src/etc/gdb_load_rust_pretty_printers.py b/src/etc/gdb_load_rust_pretty_printers.py index c551346bb0..fe38c49d27 100644 --- a/src/etc/gdb_load_rust_pretty_printers.py +++ b/src/etc/gdb_load_rust_pretty_printers.py @@ -1,2 +1,3 @@ +import gdb import gdb_rust_pretty_printing gdb_rust_pretty_printing.register_printers(gdb.current_objfile()) diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb index 0eb99423df..7b9b40e6b4 100755 --- a/src/etc/rust-lldb +++ b/src/etc/rust-lldb @@ -3,25 +3,30 @@ # Exit if anything fails set -e -# Find out where to look for the pretty printer Python module -RUSTC_SYSROOT=`rustc --print sysroot` - # Find the host triple so we can find lldb in rustlib. -host=`rustc -vV | sed -n -e 's/^host: //p'` +host=$(rustc -vV | sed -n -e 's/^host: //p') + +# Find out where to look for the pretty printer Python module +RUSTC_SYSROOT=$(rustc --print sysroot) +RUST_LLDB="$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" lldb=lldb -if [ -f "$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" ]; then - lldb="$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" +if [ -f "$RUST_LLDB" ]; then + lldb="$RUST_LLDB" else - LLDB_VERSION=`"$lldb" --version 2>/dev/null | head -1 | cut -d. -f1` + if ! command -v "$lldb" > /dev/null; then + echo "$lldb not found! Please install it." >&2 + exit 1 + else + LLDB_VERSION=$("$lldb" --version | cut -d ' ' -f3) - if [ "$LLDB_VERSION" = "lldb-350" ] - then - echo "***" - echo \ -"WARNING: This version of LLDB has known issues with Rust and cannot \ -display the contents of local variables!" - echo "***" + if [ "$LLDB_VERSION" = "3.5.0" ]; then + cat << EOF >&2 +*** +WARNING: This version of LLDB has known issues with Rust and cannot display the contents of local variables! +*** +EOF + fi fi fi diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index bcb27bb516..d1119f7b7c 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -15,8 +15,8 @@ core = { path = "../libcore" } compiler_builtins = { version = "0.1.10", features = ['rustc-dep-of-std'] } [dev-dependencies] -rand = "0.6" -rand_xorshift = "0.1" +rand = "0.7" +rand_xorshift = "0.2" [[test]] name = "collectionstests" diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 755feb8496..dc7fd1adc2 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -10,13 +10,15 @@ use core::usize; #[doc(inline)] pub use core::alloc::*; +#[cfg(test)] +mod tests; + extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates // them from the `#[global_allocator]` attribute if there is one, or uses the // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`) // otherwise. - #[cfg_attr(bootstrap, allocator)] - #[cfg_attr(not(bootstrap), rustc_allocator)] + #[rustc_allocator] #[rustc_allocator_nounwind] fn __rust_alloc(size: usize, align: usize) -> *mut u8; #[rustc_allocator_nounwind] @@ -245,36 +247,3 @@ pub fn handle_alloc_error(layout: Layout) -> ! { } unsafe { oom_impl(layout) } } - -#[cfg(test)] -mod tests { - extern crate test; - use test::Bencher; - use crate::boxed::Box; - use crate::alloc::{Global, Alloc, Layout, handle_alloc_error}; - - #[test] - fn allocate_zeroed() { - unsafe { - let layout = Layout::from_size_align(1024, 1).unwrap(); - let ptr = Global.alloc_zeroed(layout.clone()) - .unwrap_or_else(|_| handle_alloc_error(layout)); - - let mut i = ptr.cast::().as_ptr(); - let end = i.add(layout.size()); - while i < end { - assert_eq!(*i, 0); - i = i.offset(1); - } - Global.dealloc(ptr, layout); - } - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn alloc_owned_small(b: &mut Bencher) { - b.iter(|| { - let _: Box<_> = box 10; - }) - } -} diff --git a/src/liballoc/alloc/tests.rs b/src/liballoc/alloc/tests.rs new file mode 100644 index 0000000000..c69f4e49ee --- /dev/null +++ b/src/liballoc/alloc/tests.rs @@ -0,0 +1,30 @@ +use super::*; + +extern crate test; +use test::Bencher; +use crate::boxed::Box; + +#[test] +fn allocate_zeroed() { + unsafe { + let layout = Layout::from_size_align(1024, 1).unwrap(); + let ptr = Global.alloc_zeroed(layout.clone()) + .unwrap_or_else(|_| handle_alloc_error(layout)); + + let mut i = ptr.cast::().as_ptr(); + let end = i.add(layout.size()); + while i < end { + assert_eq!(*i, 0); + i = i.offset(1); + } + Global.dealloc(ptr, layout); + } +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn alloc_owned_small(b: &mut Bencher) { + b.iter(|| { + let _: Box<_> = box 10; + }) +} diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs index f17fb8212c..ef91d801dc 100644 --- a/src/liballoc/benches/slice.rs +++ b/src/liballoc/benches/slice.rs @@ -186,12 +186,12 @@ const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; fn gen_random(len: usize) -> Vec { let mut rng = XorShiftRng::from_seed(SEED); - rng.sample_iter(&Standard).take(len).collect() + (&mut rng).sample_iter(&Standard).take(len).collect() } fn gen_random_bytes(len: usize) -> Vec { let mut rng = XorShiftRng::from_seed(SEED); - rng.sample_iter(&Standard).take(len).collect() + (&mut rng).sample_iter(&Standard).take(len).collect() } fn gen_mostly_ascending(len: usize) -> Vec { @@ -221,14 +221,14 @@ fn gen_strings(len: usize) -> Vec { let mut v = vec![]; for _ in 0..len { let n = rng.gen::() % 20 + 1; - v.push(rng.sample_iter(&Alphanumeric).take(n).collect()); + v.push((&mut rng).sample_iter(&Alphanumeric).take(n).collect()); } v } fn gen_big_random(len: usize) -> Vec<[u64; 16]> { let mut rng = XorShiftRng::from_seed(SEED); - rng.sample_iter(&Standard).map(|x| [x; 16]).take(len).collect() + (&mut rng).sample_iter(&Standard).map(|x| [x; 16]).take(len).collect() } macro_rules! sort { diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index d5e15b3719..a9c5bce4c2 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -329,8 +329,8 @@ impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Cow<'_, B> - where B: fmt::Debug + ToOwned, - ::Owned: fmt::Debug +where + B: fmt::Debug + ToOwned, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { @@ -342,8 +342,8 @@ impl fmt::Debug for Cow<'_, B> #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Cow<'_, B> - where B: fmt::Display + ToOwned, - ::Owned: fmt::Display +where + B: fmt::Display + ToOwned, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { @@ -355,8 +355,8 @@ impl fmt::Display for Cow<'_, B> #[stable(feature = "default", since = "1.11.0")] impl Default for Cow<'_, B> - where B: ToOwned, - ::Owned: Default +where + B: ToOwned, { /// Creates an owned Cow<'a, B> with the default value for the contained owned value. fn default() -> Self { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9109a730cc..c92db517ca 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -1,6 +1,6 @@ //! A pointer type for heap allocation. //! -//! `Box`, casually referred to as a 'box', provides the simplest form of +//! [`Box`], casually referred to as a 'box', provides the simplest form of //! heap allocation in Rust. Boxes provide ownership for this allocation, and //! drop their contents when they go out of scope. //! @@ -48,7 +48,7 @@ //! //! It wouldn't work. This is because the size of a `List` depends on how many //! elements are in the list, and so we don't know how much memory to allocate -//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how +//! for a `Cons`. By introducing a [`Box`], which has a defined size, we know how //! big `Cons` needs to be. //! //! # Memory layout @@ -59,22 +59,27 @@ //! [`Layout`] used with the allocator is correct for the type. More precisely, //! a `value: *mut T` that has been allocated with the [`Global`] allocator //! with `Layout::for_value(&*value)` may be converted into a box using -//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut -//! T` obtained from `Box::::into_raw` may be deallocated using the -//! [`Global`] allocator with `Layout::for_value(&*value)`. +//! [`Box::::from_raw(value)`]. Conversely, the memory backing a `value: *mut +//! T` obtained from [`Box::::into_raw`] may be deallocated using the +//! [`Global`] allocator with [`Layout::for_value(&*value)`]. //! //! //! [dereferencing]: ../../std/ops/trait.Deref.html //! [`Box`]: struct.Box.html +//! [`Box`]: struct.Box.html +//! [`Box::::from_raw(value)`]: struct.Box.html#method.from_raw +//! [`Box::::into_raw`]: struct.Box.html#method.into_raw //! [`Global`]: ../alloc/struct.Global.html //! [`Layout`]: ../alloc/struct.Layout.html +//! [`Layout::for_value(&*value)`]: ../alloc/struct.Layout.html#method.for_value #![stable(feature = "rust1", since = "1.0.0")] use core::any::Any; +use core::array::LengthAtMost32; use core::borrow; use core::cmp::Ordering; -use core::convert::From; +use core::convert::{From, TryFrom}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; @@ -320,7 +325,7 @@ impl Box { /// This conversion does not allocate on the heap and happens in place. /// /// This is also available via [`From`]. - #[unstable(feature = "box_into_pin", issue = "0")] + #[unstable(feature = "box_into_pin", issue = "62370")] pub fn into_pin(boxed: Box) -> Pin> { // It's not possible to move or replace the insides of a `Pin>` // when `T: !Unpin`, so it's safe to pin it directly without any @@ -367,12 +372,19 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let y = x.clone(); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // But they are unique objects + /// assert_ne!(&*x as *const i32, &*y as *const i32); /// ``` #[rustfmt::skip] #[inline] fn clone(&self) -> Box { box { (**self).clone() } } + /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples @@ -380,10 +392,15 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let mut y = Box::new(10); + /// let yp: *const i32 = &*y; /// /// y.clone_from(&x); /// - /// assert_eq!(*y, 5); + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no allocation occurred + /// assert_eq!(yp, &*y); /// ``` #[inline] fn clone_from(&mut self, source: &Box) { @@ -596,6 +613,22 @@ impl From> for Box<[u8]> { } } +#[unstable(feature = "boxed_slice_try_from", issue = "0")] +impl TryFrom> for Box<[T; N]> +where + [T; N]: LengthAtMost32, +{ + type Error = Box<[T]>; + + fn try_from(boxed_slice: Box<[T]>) -> Result { + if boxed_slice.len() == N { + Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) }) + } else { + Err(boxed_slice) + } + } +} + impl Box { #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -716,6 +749,14 @@ impl Iterator for Box { (**self).nth(n) } } + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Box { + fn last(self) -> Option where I: Sized { + (*self).last() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for Box { fn next_back(&mut self) -> Option { diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index c898f064fd..9f531f5b83 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1035,6 +1035,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(self) -> Option<&'a T> { + self.iter.last() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87c..1683b81055 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -75,10 +75,10 @@ use Entry::*; /// /// // look up the values associated with some keys. /// let to_find = ["Up!", "Office Space"]; -/// for book in &to_find { -/// match movie_reviews.get(book) { -/// Some(review) => println!("{}: {}", book, review), -/// None => println!("{} is unreviewed.", book) +/// for movie in &to_find { +/// match movie_reviews.get(movie) { +/// Some(review) => println!("{}: {}", movie, review), +/// None => println!("{} is unreviewed.", movie) /// } /// } /// @@ -200,7 +200,7 @@ impl Clone for BTreeMap { } } - if self.len() == 0 { + if self.is_empty() { // Ideally we'd call `BTreeMap::new` here, but that has the `K: // Ord` constraint, which this method lacks. BTreeMap { @@ -759,19 +759,19 @@ impl BTreeMap { #[stable(feature = "btree_append", since = "1.11.0")] pub fn append(&mut self, other: &mut Self) { // Do we have to append anything at all? - if other.len() == 0 { + if other.is_empty() { return; } // We can just swap `self` and `other` if `self` is empty. - if self.len() == 0 { + if self.is_empty() { mem::swap(self, other); return; } // First, we merge `self` and `other` into a sorted sequence in linear time. - let self_iter = mem::replace(self, BTreeMap::new()).into_iter(); - let other_iter = mem::replace(other, BTreeMap::new()).into_iter(); + let self_iter = mem::take(self).into_iter(); + let other_iter = mem::take(other).into_iter(); let iter = MergeIter { left: self_iter.peekable(), right: other_iter.peekable(), @@ -1193,6 +1193,10 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1253,6 +1257,10 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1421,6 +1429,10 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a K> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1458,6 +1470,10 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a V> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1495,6 +1511,10 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1508,6 +1528,10 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a mut V> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1626,6 +1650,10 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } impl<'a, K, V> RangeMut<'a, K, V> { @@ -2004,7 +2032,7 @@ impl BTreeMap { /// assert_eq!(keys, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { + pub fn keys(&self) -> Keys<'_, K, V> { Keys { inner: self.iter() } } @@ -2025,7 +2053,7 @@ impl BTreeMap { /// assert_eq!(values, ["hello", "goodbye"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn values<'a>(&'a self) -> Values<'a, K, V> { + pub fn values(&self) -> Values<'_, K, V> { Values { inner: self.iter() } } @@ -2529,8 +2557,8 @@ enum UnderflowResult<'a, K, V> { Stole(NodeRef, K, V, marker::Internal>), } -fn handle_underfull_node<'a, K, V>(node: NodeRef, K, V, marker::LeafOrInternal>) - -> UnderflowResult<'a, K, V> { +fn handle_underfull_node(node: NodeRef, K, V, marker::LeafOrInternal>) + -> UnderflowResult<'_, K, V> { let parent = if let Ok(parent) = node.ascend() { parent } else { diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 581c66c708..e067096f0c 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -106,8 +106,8 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - keys: uninitialized_array![_; CAPACITY], - vals: uninitialized_array![_; CAPACITY], + keys: uninit_array![_; CAPACITY], + vals: uninit_array![_; CAPACITY], parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0 @@ -159,7 +159,7 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - edges: uninitialized_array![_; 2*B], + edges: uninit_array![_; 2*B], } } } @@ -394,7 +394,7 @@ impl NodeRef { } /// Temporarily takes out another, immutable reference to the same node. - fn reborrow<'a>(&'a self) -> NodeRef, K, V, Type> { + fn reborrow(&self) -> NodeRef, K, V, Type> { NodeRef { height: self.height, node: self.node, diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 16a96ca19b..d3af910a82 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1019,6 +1019,9 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { @@ -1073,6 +1076,10 @@ impl<'a, T> Iterator for Range<'a, T> { fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(k, _)| k) } + + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "btree_range", since = "1.17.0")] diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 40a82d6fea..a14a3fe999 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -23,6 +23,9 @@ use core::ptr::NonNull; use crate::boxed::Box; use super::SpecExtend; +#[cfg(test)] +mod tests; + /// A doubly-linked list with owned nodes. /// /// The `LinkedList` allows pushing and popping elements at either end @@ -237,15 +240,15 @@ impl LinkedList { // Not creating new mutable (unique!) references overlapping `element`. match node.prev { - Some(prev) => (*prev.as_ptr()).next = node.next.clone(), + Some(prev) => (*prev.as_ptr()).next = node.next, // this node is the head node - None => self.head = node.next.clone(), + None => self.head = node.next, }; match node.next { - Some(next) => (*next.as_ptr()).prev = node.prev.clone(), + Some(next) => (*next.as_ptr()).prev = node.prev, // this node is the tail node - None => self.tail = node.prev.clone(), + None => self.tail = node.prev, }; self.len -= 1; @@ -708,7 +711,7 @@ impl LinkedList { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::replace(self, Self::new()); + return mem::take(self); } else if at == len { return Self::new(); } @@ -832,6 +835,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -881,6 +889,11 @@ impl<'a, T> Iterator for IterMut<'a, T> { fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } + + #[inline] + fn last(mut self) -> Option<&'a mut T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1234,273 +1247,3 @@ unsafe impl Send for IterMut<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Sync for IterMut<'_, T> {} - -#[cfg(test)] -mod tests { - use std::thread; - use std::vec::Vec; - - use rand::{thread_rng, RngCore}; - - use super::{LinkedList, Node}; - - #[cfg(test)] - fn list_from(v: &[T]) -> LinkedList { - v.iter().cloned().collect() - } - - pub fn check_links(list: &LinkedList) { - unsafe { - let mut len = 0; - let mut last_ptr: Option<&Node> = None; - let mut node_ptr: &Node; - match list.head { - None => { - // tail node should also be None. - assert!(list.tail.is_none()); - assert_eq!(0, list.len); - return; - } - Some(node) => node_ptr = &*node.as_ptr(), - } - loop { - match (last_ptr, node_ptr.prev) { - (None, None) => {} - (None, _) => panic!("prev link for head"), - (Some(p), Some(pptr)) => { - assert_eq!(p as *const Node, pptr.as_ptr() as *const Node); - } - _ => panic!("prev link is none, not good"), - } - match node_ptr.next { - Some(next) => { - last_ptr = Some(node_ptr); - node_ptr = &*next.as_ptr(); - len += 1; - } - None => { - len += 1; - break; - } - } - } - - // verify that the tail node points to the last node. - let tail = list.tail.as_ref().expect("some tail node").as_ref(); - assert_eq!(tail as *const Node, node_ptr as *const Node); - // check that len matches interior links. - assert_eq!(len, list.len); - } - } - - #[test] - fn test_append() { - // Empty to empty - { - let mut m = LinkedList::::new(); - let mut n = LinkedList::new(); - m.append(&mut n); - check_links(&m); - assert_eq!(m.len(), 0); - assert_eq!(n.len(), 0); - } - // Non-empty to empty - { - let mut m = LinkedList::new(); - let mut n = LinkedList::new(); - n.push_back(2); - m.append(&mut n); - check_links(&m); - assert_eq!(m.len(), 1); - assert_eq!(m.pop_back(), Some(2)); - assert_eq!(n.len(), 0); - check_links(&m); - } - // Empty to non-empty - { - let mut m = LinkedList::new(); - let mut n = LinkedList::new(); - m.push_back(2); - m.append(&mut n); - check_links(&m); - assert_eq!(m.len(), 1); - assert_eq!(m.pop_back(), Some(2)); - check_links(&m); - } - - // Non-empty to non-empty - let v = vec![1, 2, 3, 4, 5]; - let u = vec![9, 8, 1, 2, 3, 4, 5]; - let mut m = list_from(&v); - let mut n = list_from(&u); - m.append(&mut n); - check_links(&m); - let mut sum = v; - sum.extend_from_slice(&u); - assert_eq!(sum.len(), m.len()); - for elt in sum { - assert_eq!(m.pop_front(), Some(elt)) - } - assert_eq!(n.len(), 0); - // let's make sure it's working properly, since we - // did some direct changes to private members - n.push_back(3); - assert_eq!(n.len(), 1); - assert_eq!(n.pop_front(), Some(3)); - check_links(&n); - } - - #[test] - fn test_insert_prev() { - let mut m = list_from(&[0, 2, 4, 6, 8]); - let len = m.len(); - { - let mut it = m.iter_mut(); - it.insert_next(-2); - loop { - match it.next() { - None => break, - Some(elt) => { - it.insert_next(*elt + 1); - match it.peek_next() { - Some(x) => assert_eq!(*x, *elt + 2), - None => assert_eq!(8, *elt), - } - } - } - } - it.insert_next(0); - it.insert_next(1); - } - check_links(&m); - assert_eq!(m.len(), 3 + len * 2); - assert_eq!(m.into_iter().collect::>(), - [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg(not(miri))] // Miri does not support threads - fn test_send() { - let n = list_from(&[1, 2, 3]); - thread::spawn(move || { - check_links(&n); - let a: &[_] = &[&1, &2, &3]; - assert_eq!(a, &*n.iter().collect::>()); - }) - .join() - .ok() - .unwrap(); - } - - #[test] - fn test_fuzz() { - for _ in 0..25 { - fuzz_test(3); - fuzz_test(16); - #[cfg(not(miri))] // Miri is too slow - fuzz_test(189); - } - } - - #[test] - fn test_26021() { - // There was a bug in split_off that failed to null out the RHS's head's prev ptr. - // This caused the RHS's dtor to walk up into the LHS at drop and delete all of - // its nodes. - // - // https://github.com/rust-lang/rust/issues/26021 - let mut v1 = LinkedList::new(); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption - assert_eq!(v1.len(), 3); - - assert_eq!(v1.iter().len(), 3); - assert_eq!(v1.iter().collect::>().len(), 3); - } - - #[test] - fn test_split_off() { - let mut v1 = LinkedList::new(); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - v1.push_front(1); - - // test all splits - for ix in 0..1 + v1.len() { - let mut a = v1.clone(); - let b = a.split_off(ix); - check_links(&a); - check_links(&b); - a.extend(b); - assert_eq!(v1, a); - } - } - - #[cfg(test)] - fn fuzz_test(sz: i32) { - let mut m: LinkedList<_> = LinkedList::new(); - let mut v = vec![]; - for i in 0..sz { - check_links(&m); - let r: u8 = thread_rng().next_u32() as u8; - match r % 6 { - 0 => { - m.pop_back(); - v.pop(); - } - 1 => { - if !v.is_empty() { - m.pop_front(); - v.remove(0); - } - } - 2 | 4 => { - m.push_front(-i); - v.insert(0, -i); - } - 3 | 5 | _ => { - m.push_back(i); - v.push(i); - } - } - } - - check_links(&m); - - let mut i = 0; - for (a, &b) in m.into_iter().zip(&v) { - i += 1; - assert_eq!(a, b); - } - assert_eq!(i, v.len()); - } - - #[test] - fn drain_filter_test() { - let mut m: LinkedList = LinkedList::new(); - m.extend(&[1, 2, 3, 4, 5, 6]); - let deleted = m.drain_filter(|v| *v < 4).collect::>(); - - check_links(&m); - - assert_eq!(deleted, &[1, 2, 3]); - assert_eq!(m.into_iter().collect::>(), &[4, 5, 6]); - } - - #[test] - fn drain_to_empty_test() { - let mut m: LinkedList = LinkedList::new(); - m.extend(&[1, 2, 3, 4, 5, 6]); - let deleted = m.drain_filter(|_| true).collect::>(); - - check_links(&m); - - assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); - assert_eq!(m.into_iter().collect::>(), &[]); - } -} diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs new file mode 100644 index 0000000000..9a6c57d286 --- /dev/null +++ b/src/liballoc/collections/linked_list/tests.rs @@ -0,0 +1,264 @@ +use super::*; + +use std::thread; +use std::vec::Vec; + +use rand::{thread_rng, RngCore}; + +fn list_from(v: &[T]) -> LinkedList { + v.iter().cloned().collect() +} + +pub fn check_links(list: &LinkedList) { + unsafe { + let mut len = 0; + let mut last_ptr: Option<&Node> = None; + let mut node_ptr: &Node; + match list.head { + None => { + // tail node should also be None. + assert!(list.tail.is_none()); + assert_eq!(0, list.len); + return; + } + Some(node) => node_ptr = &*node.as_ptr(), + } + loop { + match (last_ptr, node_ptr.prev) { + (None, None) => {} + (None, _) => panic!("prev link for head"), + (Some(p), Some(pptr)) => { + assert_eq!(p as *const Node, pptr.as_ptr() as *const Node); + } + _ => panic!("prev link is none, not good"), + } + match node_ptr.next { + Some(next) => { + last_ptr = Some(node_ptr); + node_ptr = &*next.as_ptr(); + len += 1; + } + None => { + len += 1; + break; + } + } + } + + // verify that the tail node points to the last node. + let tail = list.tail.as_ref().expect("some tail node").as_ref(); + assert_eq!(tail as *const Node, node_ptr as *const Node); + // check that len matches interior links. + assert_eq!(len, list.len); + } +} + +#[test] +fn test_append() { + // Empty to empty + { + let mut m = LinkedList::::new(); + let mut n = LinkedList::new(); + m.append(&mut n); + check_links(&m); + assert_eq!(m.len(), 0); + assert_eq!(n.len(), 0); + } + // Non-empty to empty + { + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); + n.push_back(2); + m.append(&mut n); + check_links(&m); + assert_eq!(m.len(), 1); + assert_eq!(m.pop_back(), Some(2)); + assert_eq!(n.len(), 0); + check_links(&m); + } + // Empty to non-empty + { + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); + m.push_back(2); + m.append(&mut n); + check_links(&m); + assert_eq!(m.len(), 1); + assert_eq!(m.pop_back(), Some(2)); + check_links(&m); + } + + // Non-empty to non-empty + let v = vec![1, 2, 3, 4, 5]; + let u = vec![9, 8, 1, 2, 3, 4, 5]; + let mut m = list_from(&v); + let mut n = list_from(&u); + m.append(&mut n); + check_links(&m); + let mut sum = v; + sum.extend_from_slice(&u); + assert_eq!(sum.len(), m.len()); + for elt in sum { + assert_eq!(m.pop_front(), Some(elt)) + } + assert_eq!(n.len(), 0); + // let's make sure it's working properly, since we + // did some direct changes to private members + n.push_back(3); + assert_eq!(n.len(), 1); + assert_eq!(n.pop_front(), Some(3)); + check_links(&n); +} + +#[test] +fn test_insert_prev() { + let mut m = list_from(&[0, 2, 4, 6, 8]); + let len = m.len(); + { + let mut it = m.iter_mut(); + it.insert_next(-2); + loop { + match it.next() { + None => break, + Some(elt) => { + it.insert_next(*elt + 1); + match it.peek_next() { + Some(x) => assert_eq!(*x, *elt + 2), + None => assert_eq!(8, *elt), + } + } + } + } + it.insert_next(0); + it.insert_next(1); + } + check_links(&m); + assert_eq!(m.len(), 3 + len * 2); + assert_eq!(m.into_iter().collect::>(), + [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads +fn test_send() { + let n = list_from(&[1, 2, 3]); + thread::spawn(move || { + check_links(&n); + let a: &[_] = &[&1, &2, &3]; + assert_eq!(a, &*n.iter().collect::>()); + }) + .join() + .ok() + .unwrap(); +} + +#[test] +fn test_fuzz() { + for _ in 0..25 { + fuzz_test(3); + fuzz_test(16); + #[cfg(not(miri))] // Miri is too slow + fuzz_test(189); + } +} + +#[test] +fn test_26021() { + // There was a bug in split_off that failed to null out the RHS's head's prev ptr. + // This caused the RHS's dtor to walk up into the LHS at drop and delete all of + // its nodes. + // + // https://github.com/rust-lang/rust/issues/26021 + let mut v1 = LinkedList::new(); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption + assert_eq!(v1.len(), 3); + + assert_eq!(v1.iter().len(), 3); + assert_eq!(v1.iter().collect::>().len(), 3); +} + +#[test] +fn test_split_off() { + let mut v1 = LinkedList::new(); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + v1.push_front(1); + + // test all splits + for ix in 0..1 + v1.len() { + let mut a = v1.clone(); + let b = a.split_off(ix); + check_links(&a); + check_links(&b); + a.extend(b); + assert_eq!(v1, a); + } +} + +fn fuzz_test(sz: i32) { + let mut m: LinkedList<_> = LinkedList::new(); + let mut v = vec![]; + for i in 0..sz { + check_links(&m); + let r: u8 = thread_rng().next_u32() as u8; + match r % 6 { + 0 => { + m.pop_back(); + v.pop(); + } + 1 => { + if !v.is_empty() { + m.pop_front(); + v.remove(0); + } + } + 2 | 4 => { + m.push_front(-i); + v.insert(0, -i); + } + 3 | 5 | _ => { + m.push_back(i); + v.push(i); + } + } + } + + check_links(&m); + + let mut i = 0; + for (a, &b) in m.into_iter().zip(&v) { + i += 1; + assert_eq!(a, b); + } + assert_eq!(i, v.len()); +} + +#[test] +fn drain_filter_test() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let deleted = m.drain_filter(|v| *v < 4).collect::>(); + + check_links(&m); + + assert_eq!(deleted, &[1, 2, 3]); + assert_eq!(m.into_iter().collect::>(), &[4, 5, 6]); +} + +#[test] +fn drain_to_empty_test() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let deleted = m.drain_filter(|_| true).collect::>(); + + check_links(&m); + + assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); + assert_eq!(m.into_iter().collect::>(), &[]); +} diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 71faf67296..9240346ace 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! A double-ended queue implemented with a growable ring buffer. //! //! This queue has `O(1)` amortized inserts and removals from both ends of the @@ -9,6 +7,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use core::array::LengthAtMost32; use core::cmp::{self, Ordering}; use core::fmt; use core::iter::{repeat_with, FromIterator, FusedIterator}; @@ -23,6 +22,9 @@ use crate::collections::CollectionAllocErr; use crate::raw_vec::RawVec; use crate::vec::Vec; +#[cfg(test)] +mod tests; + const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 const MINIMUM_CAPACITY: usize = 1; // 2 - 1 #[cfg(target_pointer_width = "16")] @@ -98,7 +100,7 @@ impl VecDeque { // For zero sized types, we are always at maximum capacity MAXIMUM_ZST_CAPACITY } else { - self.buf.cap() + self.buf.capacity() } } @@ -314,10 +316,10 @@ impl VecDeque { } /// Frobs the head and tail sections around to handle the fact that we - /// just reallocated. Unsafe because it trusts old_cap. + /// just reallocated. Unsafe because it trusts old_capacity. #[inline] - unsafe fn handle_cap_increase(&mut self, old_cap: usize) { - let new_cap = self.cap(); + unsafe fn handle_capacity_increase(&mut self, old_capacity: usize) { + let new_capacity = self.cap(); // Move the shortest contiguous section of the ring buffer // T H @@ -336,15 +338,15 @@ impl VecDeque { if self.tail <= self.head { // A // Nop - } else if self.head < old_cap - self.tail { + } else if self.head < old_capacity - self.tail { // B - self.copy_nonoverlapping(old_cap, 0, self.head); - self.head += old_cap; + self.copy_nonoverlapping(old_capacity, 0, self.head); + self.head += old_capacity; debug_assert!(self.head > self.tail); } else { // C - let new_tail = new_cap - (old_cap - self.tail); - self.copy_nonoverlapping(new_tail, self.tail, old_cap - self.tail); + let new_tail = new_capacity - (old_capacity - self.tail); + self.copy_nonoverlapping(new_tail, self.tail, old_capacity - self.tail); self.tail = new_tail; debug_assert!(self.head < self.tail); } @@ -551,7 +553,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.reserve_exact(used_cap, new_cap - used_cap); unsafe { - self.handle_cap_increase(old_cap); + self.handle_capacity_increase(old_cap); } } } @@ -641,7 +643,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.try_reserve_exact(used_cap, new_cap - used_cap)?; unsafe { - self.handle_cap_increase(old_cap); + self.handle_capacity_increase(old_cap); } } Ok(()) @@ -1887,7 +1889,7 @@ impl VecDeque { let old_cap = self.cap(); self.buf.double(); unsafe { - self.handle_cap_increase(old_cap); + self.handle_capacity_increase(old_cap); } debug_assert!(!self.is_full()); } @@ -2206,6 +2208,11 @@ impl<'a, T> Iterator for Iter<'a, T> { self.tail = self.head - iter.len(); final_res } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2319,6 +2326,11 @@ impl<'a, T> Iterator for IterMut<'a, T> { accum = front.iter_mut().fold(accum, &mut f); back.iter_mut().fold(accum, &mut f) } + + #[inline] + fn last(mut self) -> Option<&'a mut T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2561,13 +2573,14 @@ impl PartialEq for VecDeque { impl Eq for VecDeque {} macro_rules! __impl_slice_eq1 { - ($Lhs: ty, $Rhs: ty) => { - __impl_slice_eq1! { $Lhs, $Rhs, Sized } - }; - ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => { #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")] - impl PartialEq<$Rhs> for $Lhs where A: PartialEq { - fn eq(&self, other: &$Rhs) -> bool { + impl PartialEq<$rhs> for $lhs + where + A: PartialEq, + $($constraints)* + { + fn eq(&self, other: &$rhs) -> bool { if self.len() != other.len() { return false; } @@ -2579,26 +2592,12 @@ macro_rules! __impl_slice_eq1 { } } -__impl_slice_eq1! { VecDeque, Vec } -__impl_slice_eq1! { VecDeque, &[B] } -__impl_slice_eq1! { VecDeque, &mut [B] } - -macro_rules! array_impls { - ($($N: expr)+) => { - $( - __impl_slice_eq1! { VecDeque, [B; $N] } - __impl_slice_eq1! { VecDeque, &[B; $N] } - __impl_slice_eq1! { VecDeque, &mut [B; $N] } - )+ - } -} - -array_impls! { - 0 1 2 3 4 5 6 7 8 9 - 10 11 12 13 14 15 16 17 18 19 - 20 21 22 23 24 25 26 27 28 29 - 30 31 32 -} +__impl_slice_eq1! { [] VecDeque, Vec, } +__impl_slice_eq1! { [] VecDeque, &[B], } +__impl_slice_eq1! { [] VecDeque, &mut [B], } +__impl_slice_eq1! { [const N: usize] VecDeque, [B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] VecDeque, &[B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] VecDeque, &mut [B; N], [B; N]: LengthAtMost32 } #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for VecDeque { @@ -2711,6 +2710,9 @@ impl fmt::Debug for VecDeque { impl From> for VecDeque { /// Turn a [`Vec`] into a [`VecDeque`]. /// + /// [`Vec`]: crate::vec::Vec + /// [`VecDeque`]: crate::collections::VecDeque + /// /// This avoids reallocating where possible, but the conditions for that are /// strict, and subject to change, and so shouldn't be relied upon unless the /// `Vec` came from `From>` and hasn't been reallocated. @@ -2723,9 +2725,9 @@ impl From> for VecDeque { // We need to extend the buf if it's not a power of two, too small // or doesn't have at least one free space - if !buf.cap().is_power_of_two() || (buf.cap() < (MINIMUM_CAPACITY + 1)) || - (buf.cap() == len) { - let cap = cmp::max(buf.cap() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); + if !buf.capacity().is_power_of_two() || (buf.capacity() < (MINIMUM_CAPACITY + 1)) || + (buf.capacity() == len) { + let cap = cmp::max(buf.capacity() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); buf.reserve_exact(len, cap - len); } @@ -2742,6 +2744,9 @@ impl From> for VecDeque { impl From> for Vec { /// Turn a [`VecDeque`] into a [`Vec`]. /// + /// [`Vec`]: crate::vec::Vec + /// [`VecDeque`]: crate::collections::VecDeque + /// /// This never needs to re-allocate, but does need to do O(n) data movement if /// the circular buffer doesn't happen to be at the beginning of the allocation. /// @@ -2834,387 +2839,3 @@ impl From> for Vec { } } } - -#[cfg(test)] -mod tests { - use ::test; - - use super::VecDeque; - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_push_back_100(b: &mut test::Bencher) { - let mut deq = VecDeque::with_capacity(101); - b.iter(|| { - for i in 0..100 { - deq.push_back(i); - } - deq.head = 0; - deq.tail = 0; - }) - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_push_front_100(b: &mut test::Bencher) { - let mut deq = VecDeque::with_capacity(101); - b.iter(|| { - for i in 0..100 { - deq.push_front(i); - } - deq.head = 0; - deq.tail = 0; - }) - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_pop_back_100(b: &mut test::Bencher) { - let mut deq = VecDeque::::with_capacity(101); - - b.iter(|| { - deq.head = 100; - deq.tail = 0; - while !deq.is_empty() { - test::black_box(deq.pop_back()); - } - }) - } - - #[bench] - #[cfg(not(miri))] // Miri does not support benchmarks - fn bench_pop_front_100(b: &mut test::Bencher) { - let mut deq = VecDeque::::with_capacity(101); - - b.iter(|| { - deq.head = 100; - deq.tail = 0; - while !deq.is_empty() { - test::black_box(deq.pop_front()); - } - }) - } - - #[test] - fn test_swap_front_back_remove() { - fn test(back: bool) { - // This test checks that every single combination of tail position and length is tested. - // Capacity 15 should be large enough to cover every case. - let mut tester = VecDeque::with_capacity(15); - let usable_cap = tester.capacity(); - let final_len = usable_cap / 2; - - for len in 0..final_len { - let expected: VecDeque<_> = if back { - (0..len).collect() - } else { - (0..len).rev().collect() - }; - for tail_pos in 0..usable_cap { - tester.tail = tail_pos; - tester.head = tail_pos; - if back { - for i in 0..len * 2 { - tester.push_front(i); - } - for i in 0..len { - assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i)); - } - } else { - for i in 0..len * 2 { - tester.push_back(i); - } - for i in 0..len { - let idx = tester.len() - 1 - i; - assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i)); - } - } - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - test(true); - test(false); - } - - #[test] - fn test_insert() { - // This test checks that every single combination of tail position, length, and - // insertion position is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - - - // len is the length *after* insertion - for len in 1..cap { - // 0, 1, 2, .., len - 1 - let expected = (0..).take(len).collect::>(); - for tail_pos in 0..cap { - for to_insert in 0..len { - tester.tail = tail_pos; - tester.head = tail_pos; - for i in 0..len { - if i != to_insert { - tester.push_back(i); - } - } - tester.insert(to_insert, to_insert); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - } - - #[test] - fn test_remove() { - // This test checks that every single combination of tail position, length, and - // removal position is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - - // len is the length *after* removal - for len in 0..cap - 1 { - // 0, 1, 2, .., len - 1 - let expected = (0..).take(len).collect::>(); - for tail_pos in 0..cap { - for to_remove in 0..=len { - tester.tail = tail_pos; - tester.head = tail_pos; - for i in 0..len { - if i == to_remove { - tester.push_back(1234); - } - tester.push_back(i); - } - if to_remove == len { - tester.push_back(1234); - } - tester.remove(to_remove); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - } - - #[test] - fn test_drain() { - let mut tester: VecDeque = VecDeque::with_capacity(7); - - let cap = tester.capacity(); - for len in 0..=cap { - for tail in 0..=cap { - for drain_start in 0..=len { - for drain_end in drain_start..=len { - tester.tail = tail; - tester.head = tail; - for i in 0..len { - tester.push_back(i); - } - - // Check that we drain the correct values - let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect(); - let drained_expected: VecDeque<_> = (drain_start..drain_end).collect(); - assert_eq!(drained, drained_expected); - - // We shouldn't have changed the capacity or made the - // head or tail out of bounds - assert_eq!(tester.capacity(), cap); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - - // We should see the correct values in the VecDeque - let expected: VecDeque<_> = (0..drain_start) - .chain(drain_end..len) - .collect(); - assert_eq!(expected, tester); - } - } - } - } - } - - #[test] - fn test_shrink_to_fit() { - // This test checks that every single combination of head and tail position, - // is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - tester.reserve(63); - let max_cap = tester.capacity(); - - for len in 0..=cap { - // 0, 1, 2, .., len - 1 - let expected = (0..).take(len).collect::>(); - for tail_pos in 0..=max_cap { - tester.tail = tail_pos; - tester.head = tail_pos; - tester.reserve(63); - for i in 0..len { - tester.push_back(i); - } - tester.shrink_to_fit(); - assert!(tester.capacity() <= cap); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert_eq!(tester, expected); - } - } - } - - #[test] - fn test_split_off() { - // This test checks that every single combination of tail position, length, and - // split position is tested. Capacity 15 should be large enough to cover every case. - - let mut tester = VecDeque::with_capacity(15); - // can't guarantee we got 15, so have to get what we got. - // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else - // this test isn't covering what it wants to - let cap = tester.capacity(); - - // len is the length *before* splitting - for len in 0..cap { - // index to split at - for at in 0..=len { - // 0, 1, 2, .., at - 1 (may be empty) - let expected_self = (0..).take(at).collect::>(); - // at, at + 1, .., len - 1 (may be empty) - let expected_other = (at..).take(len - at).collect::>(); - - for tail_pos in 0..cap { - tester.tail = tail_pos; - tester.head = tail_pos; - for i in 0..len { - tester.push_back(i); - } - let result = tester.split_off(at); - assert!(tester.tail < tester.cap()); - assert!(tester.head < tester.cap()); - assert!(result.tail < result.cap()); - assert!(result.head < result.cap()); - assert_eq!(tester, expected_self); - assert_eq!(result, expected_other); - } - } - } - } - - #[test] - fn test_from_vec() { - use crate::vec::Vec; - for cap in 0..35 { - for len in 0..=cap { - let mut vec = Vec::with_capacity(cap); - vec.extend(0..len); - - let vd = VecDeque::from(vec.clone()); - assert!(vd.cap().is_power_of_two()); - assert_eq!(vd.len(), vec.len()); - assert!(vd.into_iter().eq(vec)); - } - } - } - - #[test] - fn test_vec_from_vecdeque() { - use crate::vec::Vec; - - fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) { - let mut vd = VecDeque::with_capacity(cap); - for _ in 0..offset { - vd.push_back(0); - vd.pop_front(); - } - vd.extend(0..len); - - let vec: Vec<_> = Vec::from(vd.clone()); - assert_eq!(vec.len(), vd.len()); - assert!(vec.into_iter().eq(vd)); - } - - #[cfg(not(miri))] // Miri is too slow - let max_pwr = 7; - #[cfg(miri)] - let max_pwr = 5; - - for cap_pwr in 0..max_pwr { - // Make capacity as a (2^x)-1, so that the ring size is 2^x - let cap = (2i32.pow(cap_pwr) - 1) as usize; - - // In these cases there is enough free space to solve it with copies - for len in 0..((cap + 1) / 2) { - // Test contiguous cases - for offset in 0..(cap - len) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at end of buffer is bigger than block at start - for offset in (cap - len)..(cap - (len / 2)) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at start of buffer is bigger than block at end - for offset in (cap - (len / 2))..cap { - create_vec_and_test_convert(cap, offset, len) - } - } - - // Now there's not (necessarily) space to straighten the ring with simple copies, - // the ring will use swapping when: - // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len)) - // right block size > free space && left block size > free space - for len in ((cap + 1) / 2)..cap { - // Test contiguous cases - for offset in 0..(cap - len) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at end of buffer is bigger than block at start - for offset in (cap - len)..(cap - (len / 2)) { - create_vec_and_test_convert(cap, offset, len) - } - - // Test cases where block at start of buffer is bigger than block at end - for offset in (cap - (len / 2))..cap { - create_vec_and_test_convert(cap, offset, len) - } - } - } - } - - #[test] - fn issue_53529() { - use crate::boxed::Box; - - let mut dst = VecDeque::new(); - dst.push_front(Box::new(1)); - dst.push_front(Box::new(2)); - assert_eq!(*dst.pop_back().unwrap(), 1); - - let mut src = VecDeque::new(); - src.push_front(Box::new(2)); - dst.append(&mut src); - for a in dst { - assert_eq!(*a, 2); - } - } - -} diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs new file mode 100644 index 0000000000..d253523997 --- /dev/null +++ b/src/liballoc/collections/vec_deque/tests.rs @@ -0,0 +1,379 @@ +use super::*; + +use ::test; + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_push_back_100(b: &mut test::Bencher) { + let mut deq = VecDeque::with_capacity(101); + b.iter(|| { + for i in 0..100 { + deq.push_back(i); + } + deq.head = 0; + deq.tail = 0; + }) +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_push_front_100(b: &mut test::Bencher) { + let mut deq = VecDeque::with_capacity(101); + b.iter(|| { + for i in 0..100 { + deq.push_front(i); + } + deq.head = 0; + deq.tail = 0; + }) +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_pop_back_100(b: &mut test::Bencher) { + let mut deq = VecDeque::::with_capacity(101); + + b.iter(|| { + deq.head = 100; + deq.tail = 0; + while !deq.is_empty() { + test::black_box(deq.pop_back()); + } + }) +} + +#[bench] +#[cfg(not(miri))] // Miri does not support benchmarks +fn bench_pop_front_100(b: &mut test::Bencher) { + let mut deq = VecDeque::::with_capacity(101); + + b.iter(|| { + deq.head = 100; + deq.tail = 0; + while !deq.is_empty() { + test::black_box(deq.pop_front()); + } + }) +} + +#[test] +fn test_swap_front_back_remove() { + fn test(back: bool) { + // This test checks that every single combination of tail position and length is tested. + // Capacity 15 should be large enough to cover every case. + let mut tester = VecDeque::with_capacity(15); + let usable_cap = tester.capacity(); + let final_len = usable_cap / 2; + + for len in 0..final_len { + let expected: VecDeque<_> = if back { + (0..len).collect() + } else { + (0..len).rev().collect() + }; + for tail_pos in 0..usable_cap { + tester.tail = tail_pos; + tester.head = tail_pos; + if back { + for i in 0..len * 2 { + tester.push_front(i); + } + for i in 0..len { + assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i)); + } + } else { + for i in 0..len * 2 { + tester.push_back(i); + } + for i in 0..len { + let idx = tester.len() - 1 - i; + assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i)); + } + } + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } + } + test(true); + test(false); +} + +#[test] +fn test_insert() { + // This test checks that every single combination of tail position, length, and + // insertion position is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + + + // len is the length *after* insertion + for len in 1..cap { + // 0, 1, 2, .., len - 1 + let expected = (0..).take(len).collect::>(); + for tail_pos in 0..cap { + for to_insert in 0..len { + tester.tail = tail_pos; + tester.head = tail_pos; + for i in 0..len { + if i != to_insert { + tester.push_back(i); + } + } + tester.insert(to_insert, to_insert); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } + } +} + +#[test] +fn test_remove() { + // This test checks that every single combination of tail position, length, and + // removal position is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + + // len is the length *after* removal + for len in 0..cap - 1 { + // 0, 1, 2, .., len - 1 + let expected = (0..).take(len).collect::>(); + for tail_pos in 0..cap { + for to_remove in 0..=len { + tester.tail = tail_pos; + tester.head = tail_pos; + for i in 0..len { + if i == to_remove { + tester.push_back(1234); + } + tester.push_back(i); + } + if to_remove == len { + tester.push_back(1234); + } + tester.remove(to_remove); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } + } +} + +#[test] +fn test_drain() { + let mut tester: VecDeque = VecDeque::with_capacity(7); + + let cap = tester.capacity(); + for len in 0..=cap { + for tail in 0..=cap { + for drain_start in 0..=len { + for drain_end in drain_start..=len { + tester.tail = tail; + tester.head = tail; + for i in 0..len { + tester.push_back(i); + } + + // Check that we drain the correct values + let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect(); + let drained_expected: VecDeque<_> = (drain_start..drain_end).collect(); + assert_eq!(drained, drained_expected); + + // We shouldn't have changed the capacity or made the + // head or tail out of bounds + assert_eq!(tester.capacity(), cap); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + + // We should see the correct values in the VecDeque + let expected: VecDeque<_> = (0..drain_start) + .chain(drain_end..len) + .collect(); + assert_eq!(expected, tester); + } + } + } + } +} + +#[test] +fn test_shrink_to_fit() { + // This test checks that every single combination of head and tail position, + // is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + tester.reserve(63); + let max_cap = tester.capacity(); + + for len in 0..=cap { + // 0, 1, 2, .., len - 1 + let expected = (0..).take(len).collect::>(); + for tail_pos in 0..=max_cap { + tester.tail = tail_pos; + tester.head = tail_pos; + tester.reserve(63); + for i in 0..len { + tester.push_back(i); + } + tester.shrink_to_fit(); + assert!(tester.capacity() <= cap); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert_eq!(tester, expected); + } + } +} + +#[test] +fn test_split_off() { + // This test checks that every single combination of tail position, length, and + // split position is tested. Capacity 15 should be large enough to cover every case. + + let mut tester = VecDeque::with_capacity(15); + // can't guarantee we got 15, so have to get what we got. + // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else + // this test isn't covering what it wants to + let cap = tester.capacity(); + + // len is the length *before* splitting + for len in 0..cap { + // index to split at + for at in 0..=len { + // 0, 1, 2, .., at - 1 (may be empty) + let expected_self = (0..).take(at).collect::>(); + // at, at + 1, .., len - 1 (may be empty) + let expected_other = (at..).take(len - at).collect::>(); + + for tail_pos in 0..cap { + tester.tail = tail_pos; + tester.head = tail_pos; + for i in 0..len { + tester.push_back(i); + } + let result = tester.split_off(at); + assert!(tester.tail < tester.cap()); + assert!(tester.head < tester.cap()); + assert!(result.tail < result.cap()); + assert!(result.head < result.cap()); + assert_eq!(tester, expected_self); + assert_eq!(result, expected_other); + } + } + } +} + +#[test] +fn test_from_vec() { + use crate::vec::Vec; + for cap in 0..35 { + for len in 0..=cap { + let mut vec = Vec::with_capacity(cap); + vec.extend(0..len); + + let vd = VecDeque::from(vec.clone()); + assert!(vd.cap().is_power_of_two()); + assert_eq!(vd.len(), vec.len()); + assert!(vd.into_iter().eq(vec)); + } + } +} + +#[test] +fn test_vec_from_vecdeque() { + use crate::vec::Vec; + + fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) { + let mut vd = VecDeque::with_capacity(capacity); + for _ in 0..offset { + vd.push_back(0); + vd.pop_front(); + } + vd.extend(0..len); + + let vec: Vec<_> = Vec::from(vd.clone()); + assert_eq!(vec.len(), vd.len()); + assert!(vec.into_iter().eq(vd)); + } + + #[cfg(not(miri))] // Miri is too slow + let max_pwr = 7; + #[cfg(miri)] + let max_pwr = 5; + + for cap_pwr in 0..max_pwr { + // Make capacity as a (2^x)-1, so that the ring size is 2^x + let cap = (2i32.pow(cap_pwr) - 1) as usize; + + // In these cases there is enough free space to solve it with copies + for len in 0..((cap + 1) / 2) { + // Test contiguous cases + for offset in 0..(cap - len) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at end of buffer is bigger than block at start + for offset in (cap - len)..(cap - (len / 2)) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at start of buffer is bigger than block at end + for offset in (cap - (len / 2))..cap { + create_vec_and_test_convert(cap, offset, len) + } + } + + // Now there's not (necessarily) space to straighten the ring with simple copies, + // the ring will use swapping when: + // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len)) + // right block size > free space && left block size > free space + for len in ((cap + 1) / 2)..cap { + // Test contiguous cases + for offset in 0..(cap - len) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at end of buffer is bigger than block at start + for offset in (cap - len)..(cap - (len / 2)) { + create_vec_and_test_convert(cap, offset, len) + } + + // Test cases where block at start of buffer is bigger than block at end + for offset in (cap - (len / 2))..cap { + create_vec_and_test_convert(cap, offset, len) + } + } + } +} + +#[test] +fn issue_53529() { + use crate::boxed::Box; + + let mut dst = VecDeque::new(); + dst.push_front(Box::new(1)); + dst.push_front(Box::new(2)); + assert_eq!(*dst.pop_back().unwrap(), 1); + + let mut src = VecDeque::new(); + src.push_front(Box::new(2)); + dst.append(&mut src); + for a in dst { + assert_eq!(*a, 2); + } +} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5fc58c8ab5..a1936b36ac 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -10,9 +10,9 @@ //! //! ## Boxed values //! -//! The [`Box`](boxed/index.html) type is a smart pointer type. There can -//! only be one owner of a `Box`, and the owner can decide to mutate the -//! contents, which live on the heap. +//! The [`Box`] type is a smart pointer type. There can only be one owner of a +//! [`Box`], and the owner can decide to mutate the contents, which live on the +//! heap. //! //! This type can be sent among threads efficiently as the size of a `Box` value //! is the same as that of a pointer. Tree-like data structures are often built @@ -20,20 +20,20 @@ //! //! ## Reference counted pointers //! -//! The [`Rc`](rc/index.html) type is a non-threadsafe reference-counted pointer -//! type intended for sharing memory within a thread. An `Rc` pointer wraps a -//! type, `T`, and only allows access to `&T`, a shared reference. +//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended +//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and +//! only allows access to `&T`, a shared reference. //! -//! This type is useful when inherited mutability (such as using `Box`) is too -//! constraining for an application, and is often paired with the `Cell` or -//! `RefCell` types in order to allow mutation. +//! This type is useful when inherited mutability (such as using [`Box`]) is too +//! constraining for an application, and is often paired with the [`Cell`] or +//! [`RefCell`] types in order to allow mutation. //! //! ## Atomically reference counted pointers //! -//! The [`Arc`](sync/index.html) type is the threadsafe equivalent of the `Rc` -//! type. It provides all the same functionality of `Rc`, except it requires -//! that the contained type `T` is shareable. Additionally, `Arc` is itself -//! sendable while `Rc` is not. +//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It +//! provides all the same functionality of [`Rc`], except it requires that the +//! contained type `T` is shareable. Additionally, [`Arc`][`Arc`] is itself +//! sendable while [`Rc`][`Rc`] is not. //! //! This type allows for shared access to the contained data, and is often //! paired with synchronization primitives such as mutexes to allow mutation of @@ -49,6 +49,12 @@ //! //! The [`alloc`](alloc/index.html) module defines the low-level interface to the //! default global allocator. It is not compatible with the libc allocator API. +//! +//! [`Arc`]: sync/index.html +//! [`Box`]: boxed/index.html +//! [`Cell`]: ../core/cell/index.html +//! [`Rc`]: rc/index.html +//! [`RefCell`]: ../core/cell/index.html #![allow(unused_attributes)] #![stable(feature = "alloc", since = "1.36.0")] @@ -62,9 +68,8 @@ #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings - -#![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] +#![cfg_attr(not(bootstrap), allow(incomplete_features))] #![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(test, feature(test))] @@ -77,14 +82,17 @@ #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] +#![feature(const_generic_impls_guard)] +#![feature(const_generics)] +#![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] -#![cfg_attr(bootstrap, feature(custom_attribute))] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(fundamental)] +#![feature(internal_uninit_const)] #![feature(lang_items)] #![feature(libc)] #![feature(nll)] @@ -94,6 +102,7 @@ #![feature(ptr_offset_from)] #![feature(rustc_attrs)] #![feature(receiver_trait)] +#![feature(slice_from_raw_parts)] #![feature(specialization)] #![feature(staged_api)] #![feature(std_internals)] @@ -112,6 +121,8 @@ #![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)] #![feature(alloc_layout_extra)] #![feature(try_trait)] +#![feature(mem_take)] +#![feature(associated_type_bounds)] // Allow testing this library diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index b6b01395ad..3cb285bf04 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -6,6 +6,5 @@ #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; -#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 0454a56443..0abab45e92 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -11,6 +11,9 @@ use crate::alloc::{Alloc, Layout, Global, handle_alloc_error}; use crate::collections::CollectionAllocErr::{self, *}; use crate::boxed::Box; +#[cfg(test)] +mod tests; + /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases /// involved. This type is excellent for building your own data structures like Vec and VecDeque. @@ -34,7 +37,7 @@ use crate::boxed::Box; /// that might occur with zero-sized types. /// /// However this means that you need to be careful when round-tripping this type -/// with a `Box<[T]>`: `cap()` won't yield the len. However `with_capacity`, +/// with a `Box<[T]>`: `capacity()` won't yield the len. However `with_capacity`, /// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity /// field. This allows zero-sized types to not be special-cased by consumers of /// this type. @@ -65,25 +68,25 @@ impl RawVec { /// Like `with_capacity` but parameterized over the choice of /// allocator for the returned RawVec. #[inline] - pub fn with_capacity_in(cap: usize, a: A) -> Self { - RawVec::allocate_in(cap, false, a) + pub fn with_capacity_in(capacity: usize, a: A) -> Self { + RawVec::allocate_in(capacity, false, a) } /// Like `with_capacity_zeroed` but parameterized over the choice /// of allocator for the returned RawVec. #[inline] - pub fn with_capacity_zeroed_in(cap: usize, a: A) -> Self { - RawVec::allocate_in(cap, true, a) + pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self { + RawVec::allocate_in(capacity, true, a) } - fn allocate_in(cap: usize, zeroed: bool, mut a: A) -> Self { + fn allocate_in(capacity: usize, zeroed: bool, mut a: A) -> Self { unsafe { let elem_size = mem::size_of::(); - let alloc_size = cap.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); + let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow()); - // handles ZSTs and `cap = 0` alike + // handles ZSTs and `capacity = 0` alike let ptr = if alloc_size == 0 { NonNull::::dangling() } else { @@ -102,7 +105,7 @@ impl RawVec { RawVec { ptr: ptr.into(), - cap, + cap: capacity, a, } } @@ -120,8 +123,8 @@ impl RawVec { } /// Creates a RawVec (on the system heap) with exactly the - /// capacity and alignment requirements for a `[T; cap]`. This is - /// equivalent to calling RawVec::new when `cap` is 0 or T is + /// capacity and alignment requirements for a `[T; capacity]`. This is + /// equivalent to calling RawVec::new when `capacity` is 0 or T is /// zero-sized. Note that if `T` is zero-sized this means you will /// *not* get a RawVec with the requested capacity! /// @@ -135,14 +138,14 @@ impl RawVec { /// /// Aborts on OOM #[inline] - pub fn with_capacity(cap: usize) -> Self { - RawVec::allocate_in(cap, false, Global) + pub fn with_capacity(capacity: usize) -> Self { + RawVec::allocate_in(capacity, false, Global) } /// Like `with_capacity` but guarantees the buffer is zeroed. #[inline] - pub fn with_capacity_zeroed(cap: usize) -> Self { - RawVec::allocate_in(cap, true, Global) + pub fn with_capacity_zeroed(capacity: usize) -> Self { + RawVec::allocate_in(capacity, true, Global) } } @@ -154,10 +157,10 @@ impl RawVec { /// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems). /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed. - pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: A) -> Self { + pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self { RawVec { ptr: Unique::new_unchecked(ptr), - cap, + cap: capacity, a, } } @@ -171,10 +174,10 @@ impl RawVec { /// The ptr must be allocated (on the system heap), and with the given capacity. The /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems). /// If the ptr and capacity come from a RawVec, then this is guaranteed. - pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self { + pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self { RawVec { ptr: Unique::new_unchecked(ptr), - cap, + cap: capacity, a: Global, } } @@ -191,7 +194,7 @@ impl RawVec { impl RawVec { /// Gets a raw pointer to the start of the allocation. Note that this is - /// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must + /// Unique::empty() if `capacity = 0` or T is zero-sized. In the former case, you must /// be careful. pub fn ptr(&self) -> *mut T { self.ptr.as_ptr() @@ -201,7 +204,7 @@ impl RawVec { /// /// This will always be `usize::MAX` if `T` is zero-sized. #[inline(always)] - pub fn cap(&self) -> usize { + pub fn capacity(&self) -> usize { if mem::size_of::() == 0 { !0 } else { @@ -240,7 +243,7 @@ impl RawVec { /// This function is ideal for when pushing elements one-at-a-time because /// you don't need to incur the costs of the more general computations /// reserve needs to do to guard against overflow. You do however need to - /// manually check if your `len == cap`. + /// manually check if your `len == capacity`. /// /// # Panics /// @@ -267,7 +270,7 @@ impl RawVec { /// /// impl MyVec { /// pub fn push(&mut self, elem: T) { - /// if self.len == self.buf.cap() { self.buf.double(); } + /// if self.len == self.buf.capacity() { self.buf.double(); } /// // double would have aborted or panicked if the len exceeded /// // `isize::MAX` so this is safe to do unchecked now. /// unsafe { @@ -381,20 +384,20 @@ impl RawVec { } /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting. - pub fn try_reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) + pub fn try_reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> Result<(), CollectionAllocErr> { - self.reserve_internal(used_cap, needed_extra_cap, Fallible, Exact) + self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Exact) } /// Ensures that the buffer contains at least enough space to hold - /// `used_cap + needed_extra_cap` elements. If it doesn't already, + /// `used_capacity + needed_extra_capacity` elements. If it doesn't already, /// will reallocate the minimum possible amount of memory necessary. /// Generally this will be exactly the amount of memory necessary, /// but in principle the allocator is free to give back more than /// we asked for. /// - /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate + /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate /// the requested space. This is not really unsafe, but the unsafe /// code *you* write that relies on the behavior of this function may break. /// @@ -407,22 +410,23 @@ impl RawVec { /// # Aborts /// /// Aborts on OOM - pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) { - match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Exact) { + pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) { + match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) { Err(CapacityOverflow) => capacity_overflow(), Err(AllocErr) => unreachable!(), Ok(()) => { /* yay */ } } } - /// Calculates the buffer's new size given that it'll hold `used_cap + - /// needed_extra_cap` elements. This logic is used in amortized reserve methods. + /// Calculates the buffer's new size given that it'll hold `used_capacity + + /// needed_extra_capacity` elements. This logic is used in amortized reserve methods. /// Returns `(new_capacity, new_alloc_size)`. - fn amortized_new_size(&self, used_cap: usize, needed_extra_cap: usize) + fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize) -> Result { // Nothing we can really do about these checks :( - let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?; + let required_cap = used_capacity.checked_add(needed_extra_capacity) + .ok_or(CapacityOverflow)?; // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`. let double_cap = self.cap * 2; // `double_cap` guarantees exponential growth. @@ -430,18 +434,18 @@ impl RawVec { } /// The same as `reserve`, but returns on errors instead of panicking or aborting. - pub fn try_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) + pub fn try_reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> Result<(), CollectionAllocErr> { - self.reserve_internal(used_cap, needed_extra_cap, Fallible, Amortized) + self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Amortized) } /// Ensures that the buffer contains at least enough space to hold - /// `used_cap + needed_extra_cap` elements. If it doesn't already have + /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have /// enough capacity, will reallocate enough space plus comfortable slack /// space to get amortized `O(1)` behavior. Will limit this behavior /// if it would needlessly cause itself to panic. /// - /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate + /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate /// the requested space. This is not really unsafe, but the unsafe /// code *you* write that relies on the behavior of this function may break. /// @@ -487,20 +491,20 @@ impl RawVec { /// # vector.push_all(&[1, 3, 5, 7, 9]); /// # } /// ``` - pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) { - match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Amortized) { + pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) { + match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Amortized) { Err(CapacityOverflow) => capacity_overflow(), Err(AllocErr) => unreachable!(), Ok(()) => { /* yay */ } } } /// Attempts to ensure that the buffer contains at least enough space to hold - /// `used_cap + needed_extra_cap` elements. If it doesn't already have + /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have /// enough capacity, will reallocate in place enough space plus comfortable slack /// space to get amortized `O(1)` behavior. Will limit this behaviour /// if it would needlessly cause itself to panic. /// - /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate + /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate /// the requested space. This is not really unsafe, but the unsafe /// code *you* write that relies on the behavior of this function may break. /// @@ -511,7 +515,7 @@ impl RawVec { /// * Panics if the requested capacity exceeds `usize::MAX` bytes. /// * Panics on 32-bit platforms if the requested capacity exceeds /// `isize::MAX` bytes. - pub fn reserve_in_place(&mut self, used_cap: usize, needed_extra_cap: usize) -> bool { + pub fn reserve_in_place(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> bool { unsafe { // NOTE: we don't early branch on ZSTs here because we want this // to actually catch "asking for more than usize::MAX" in that case. @@ -520,20 +524,20 @@ impl RawVec { // Don't actually need any more capacity. If the current `cap` is 0, we can't // reallocate in place. - // Wrapping in case they give a bad `used_cap` + // Wrapping in case they give a bad `used_capacity` let old_layout = match self.current_layout() { Some(layout) => layout, None => return false, }; - if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { + if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity { return false; } - let new_cap = self.amortized_new_size(used_cap, needed_extra_cap) + let new_cap = self.amortized_new_size(used_capacity, needed_extra_capacity) .unwrap_or_else(|_| capacity_overflow()); - // Here, `cap < used_cap + needed_extra_cap <= new_cap` - // (regardless of whether `self.cap - used_cap` wrapped). + // Here, `cap < used_capacity + needed_extra_capacity <= new_cap` + // (regardless of whether `self.cap - used_capacity` wrapped). // Therefore we can safely call grow_in_place. let new_layout = Layout::new::().repeat(new_cap).unwrap().0; @@ -632,8 +636,8 @@ use ReserveStrategy::*; impl RawVec { fn reserve_internal( &mut self, - used_cap: usize, - needed_extra_cap: usize, + used_capacity: usize, + needed_extra_capacity: usize, fallibility: Fallibility, strategy: ReserveStrategy, ) -> Result<(), CollectionAllocErr> { @@ -646,15 +650,15 @@ impl RawVec { // panic. // Don't actually need any more capacity. - // Wrapping in case they gave a bad `used_cap`. - if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { + // Wrapping in case they gave a bad `used_capacity`. + if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity { return Ok(()); } // Nothing we can really do about these checks :( let new_cap = match strategy { - Exact => used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?, - Amortized => self.amortized_new_size(used_cap, needed_extra_cap)?, + Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?, + Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?, }; let new_layout = Layout::array::(new_cap).map_err(|_| CapacityOverflow)?; @@ -694,7 +698,7 @@ impl RawVec { /// the rules around uninitialized boxed values are not finalized yet, /// but until they are, it is advisable to avoid them. pub unsafe fn into_box(self) -> Box<[T]> { - // NOTE: not calling `cap()` here, actually using the real `cap` field! + // NOTE: not calling `capacity()` here, actually using the real `cap` field! let slice = slice::from_raw_parts_mut(self.ptr(), self.cap); let output: Box<[T]> = Box::from_raw(slice); mem::forget(self); @@ -747,82 +751,3 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> { fn capacity_overflow() -> ! { panic!("capacity overflow") } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn allocator_param() { - use crate::alloc::AllocErr; - - // Writing a test of integration between third-party - // allocators and RawVec is a little tricky because the RawVec - // API does not expose fallible allocation methods, so we - // cannot check what happens when allocator is exhausted - // (beyond detecting a panic). - // - // Instead, this just checks that the RawVec methods do at - // least go through the Allocator API when it reserves - // storage. - - // A dumb allocator that consumes a fixed amount of fuel - // before allocation attempts start failing. - struct BoundedAlloc { fuel: usize } - unsafe impl Alloc for BoundedAlloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - let size = layout.size(); - if size > self.fuel { - return Err(AllocErr); - } - match Global.alloc(layout) { - ok @ Ok(_) => { self.fuel -= size; ok } - err @ Err(_) => err, - } - } - unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - Global.dealloc(ptr, layout) - } - } - - let a = BoundedAlloc { fuel: 500 }; - let mut v: RawVec = RawVec::with_capacity_in(50, a); - assert_eq!(v.a.fuel, 450); - v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel) - assert_eq!(v.a.fuel, 250); - } - - #[test] - fn reserve_does_not_overallocate() { - { - let mut v: RawVec = RawVec::new(); - // First `reserve` allocates like `reserve_exact` - v.reserve(0, 9); - assert_eq!(9, v.cap()); - } - - { - let mut v: RawVec = RawVec::new(); - v.reserve(0, 7); - assert_eq!(7, v.cap()); - // 97 if more than double of 7, so `reserve` should work - // like `reserve_exact`. - v.reserve(7, 90); - assert_eq!(97, v.cap()); - } - - { - let mut v: RawVec = RawVec::new(); - v.reserve(0, 12); - assert_eq!(12, v.cap()); - v.reserve(12, 3); - // 3 is less than half of 12, so `reserve` must grow - // exponentially. At the time of writing this test grow - // factor is 2, so new capacity is 24, however, grow factor - // of 1.5 is OK too. Hence `>= 18` in assert. - assert!(v.cap() >= 12 + 12 / 2); - } - } - - -} diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs new file mode 100644 index 0000000000..c389898d1e --- /dev/null +++ b/src/liballoc/raw_vec/tests.rs @@ -0,0 +1,73 @@ +use super::*; + +#[test] +fn allocator_param() { + use crate::alloc::AllocErr; + + // Writing a test of integration between third-party + // allocators and RawVec is a little tricky because the RawVec + // API does not expose fallible allocation methods, so we + // cannot check what happens when allocator is exhausted + // (beyond detecting a panic). + // + // Instead, this just checks that the RawVec methods do at + // least go through the Allocator API when it reserves + // storage. + + // A dumb allocator that consumes a fixed amount of fuel + // before allocation attempts start failing. + struct BoundedAlloc { fuel: usize } + unsafe impl Alloc for BoundedAlloc { + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + let size = layout.size(); + if size > self.fuel { + return Err(AllocErr); + } + match Global.alloc(layout) { + ok @ Ok(_) => { self.fuel -= size; ok } + err @ Err(_) => err, + } + } + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + Global.dealloc(ptr, layout) + } + } + + let a = BoundedAlloc { fuel: 500 }; + let mut v: RawVec = RawVec::with_capacity_in(50, a); + assert_eq!(v.a.fuel, 450); + v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel) + assert_eq!(v.a.fuel, 250); +} + +#[test] +fn reserve_does_not_overallocate() { + { + let mut v: RawVec = RawVec::new(); + // First `reserve` allocates like `reserve_exact` + v.reserve(0, 9); + assert_eq!(9, v.capacity()); + } + + { + let mut v: RawVec = RawVec::new(); + v.reserve(0, 7); + assert_eq!(7, v.capacity()); + // 97 if more than double of 7, so `reserve` should work + // like `reserve_exact`. + v.reserve(7, 90); + assert_eq!(97, v.capacity()); + } + + { + let mut v: RawVec = RawVec::new(); + v.reserve(0, 12); + assert_eq!(12, v.capacity()); + v.reserve(12, 3); + // 3 is less than half of 12, so `reserve` must grow + // exponentially. At the time of writing this test grow + // factor is 2, so new capacity is 24, however, grow factor + // of 1.5 is OK too. Hence `>= 18` in assert. + assert!(v.capacity() >= 12 + 12 / 2); + } +} diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index ee78839f7f..0c406a9202 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -232,25 +232,30 @@ use crate::boxed::Box; use std::boxed::Box; use core::any::Any; +use core::array::LengthAtMost32; use core::borrow; use core::cell::Cell; use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; +use core::iter; use core::marker::{self, Unpin, Unsize, PhantomData}; use core::mem::{self, align_of, align_of_val, forget, size_of_val}; use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; use core::pin::Pin; use core::ptr::{self, NonNull}; -use core::slice::from_raw_parts_mut; -use core::convert::From; +use core::slice::{self, from_raw_parts_mut}; +use core::convert::{From, TryFrom}; use core::usize; use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; use crate::string::String; use crate::vec::Vec; +#[cfg(test)] +mod tests; + struct RcBox { strong: Cell, weak: Cell, @@ -286,6 +291,19 @@ impl, U: ?Sized> CoerceUnsized> for Rc {} #[unstable(feature = "dispatch_from_dyn", issue = "0")] impl, U: ?Sized> DispatchFromDyn> for Rc {} +impl Rc { + fn from_inner(ptr: NonNull>) -> Self { + Self { + ptr, + phantom: PhantomData, + } + } + + unsafe fn from_ptr(ptr: *mut RcBox) -> Self { + Self::from_inner(NonNull::new_unchecked(ptr)) + } +} + impl Rc { /// Constructs a new `Rc`. /// @@ -298,18 +316,15 @@ impl Rc { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(value: T) -> Rc { - Rc { - // there is an implicit weak pointer owned by all the strong - // pointers, which ensures that the weak destructor never frees - // the allocation while the strong destructor is running, even - // if the weak pointer is stored inside the strong one. - ptr: Box::into_raw_non_null(box RcBox { - strong: Cell::new(1), - weak: Cell::new(1), - value, - }), - phantom: PhantomData, - } + // There is an implicit weak pointer owned by all the strong + // pointers, which ensures that the weak destructor never frees + // the allocation while the strong destructor is running, even + // if the weak pointer is stored inside the strong one. + Self::from_inner(Box::into_raw_non_null(box RcBox { + strong: Cell::new(1), + weak: Cell::new(1), + value, + })) } /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then @@ -422,10 +437,7 @@ impl Rc { let fake_ptr = ptr as *mut RcBox; let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Rc { - ptr: NonNull::new_unchecked(rc_ptr), - phantom: PhantomData, - } + Self::from_ptr(rc_ptr) } /// Consumes the `Rc`, returning the wrapped pointer as `NonNull`. @@ -683,7 +695,7 @@ impl Rc { if (*self).is::() { let ptr = self.ptr.cast::>(); forget(self); - Ok(Rc { ptr, phantom: PhantomData }) + Ok(Rc::from_inner(ptr)) } else { Err(self) } @@ -691,21 +703,29 @@ impl Rc { } impl Rc { - // Allocates an `RcBox` with sufficient space for an unsized value - unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { - // Calculate layout using the given value. + /// Allocates an `RcBox` with sufficient space for + /// an unsized value where the value has the layout provided. + /// + /// The function `mem_to_rcbox` is called with the data pointer + /// and must return back a (potentially fat)-pointer for the `RcBox`. + unsafe fn allocate_for_unsized( + value_layout: Layout, + mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox + ) -> *mut RcBox { + // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const RcBox)`, but this created a misaligned // reference (see #54908). let layout = Layout::new::>() - .extend(Layout::for_value(&*ptr)).unwrap().0 + .extend(value_layout).unwrap().0 .pad_to_align().unwrap(); + // Allocate for the layout. let mem = Global.alloc(layout) .unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the RcBox - let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox; + let inner = mem_to_rcbox(mem.as_ptr()); debug_assert_eq!(Layout::for_value(&*inner), layout); ptr::write(&mut (*inner).strong, Cell::new(1)); @@ -714,6 +734,15 @@ impl Rc { inner } + /// Allocates an `RcBox` with sufficient space for an unsized value + unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { + // Allocate for the `RcBox` using the given value. + Self::allocate_for_unsized( + Layout::for_value(&*ptr), + |mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox, + ) + } + fn from_box(v: Box) -> Rc { unsafe { let box_unique = Box::into_unique(v); @@ -731,44 +760,49 @@ impl Rc { // Free the allocation without dropping its contents box_free(box_unique); - Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } } -// Sets the data pointer of a `?Sized` raw pointer. -// -// For a slice/trait object, this sets the `data` field and leaves the rest -// unchanged. For a sized raw pointer, this simply sets the pointer. +impl Rc<[T]> { + /// Allocates an `RcBox<[T]>` with the given length. + unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { + Self::allocate_for_unsized( + Layout::array::(len).unwrap(), + |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>, + ) + } +} + +/// Sets the data pointer of a `?Sized` raw pointer. +/// +/// For a slice/trait object, this sets the `data` field and leaves the rest +/// unchanged. For a sized raw pointer, this simply sets the pointer. unsafe fn set_data_ptr(mut ptr: *mut T, data: *mut U) -> *mut T { ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8); ptr } impl Rc<[T]> { - // Copy elements from slice into newly allocated Rc<[T]> - // - // Unsafe because the caller must either take ownership or bind `T: Copy` + /// Copy elements from slice into newly allocated Rc<[T]> + /// + /// Unsafe because the caller must either take ownership or bind `T: Copy` unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(v.len()); ptr::copy_nonoverlapping( v.as_ptr(), &mut (*ptr).value as *mut [T] as *mut T, v.len()); - Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } -} - -trait RcFromSlice { - fn from_slice(slice: &[T]) -> Self; -} -impl RcFromSlice for Rc<[T]> { - #[inline] - default fn from_slice(v: &[T]) -> Self { + /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size. + /// + /// Behavior is undefined should the size be wrong. + unsafe fn from_iter_exact(iter: impl iter::Iterator, len: usize) -> Rc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written // into the new RcBox will be dropped, then the memory freed. @@ -785,37 +819,48 @@ impl RcFromSlice for Rc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem, self.layout.clone()); + Global.dealloc(self.mem, self.layout); } } } - unsafe { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(len); - let mem = ptr as *mut _ as *mut u8; - let layout = Layout::for_value(&*ptr); + let mem = ptr as *mut _ as *mut u8; + let layout = Layout::for_value(&*ptr); - // Pointer to first element - let elems = &mut (*ptr).value as *mut [T] as *mut T; + // Pointer to first element + let elems = &mut (*ptr).value as *mut [T] as *mut T; - let mut guard = Guard{ - mem: NonNull::new_unchecked(mem), - elems: elems, - layout: layout, - n_elems: 0, - }; + let mut guard = Guard { + mem: NonNull::new_unchecked(mem), + elems, + layout, + n_elems: 0, + }; - for (i, item) in v.iter().enumerate() { - ptr::write(elems.add(i), item.clone()); - guard.n_elems += 1; - } + for (i, item) in iter.enumerate() { + ptr::write(elems.add(i), item); + guard.n_elems += 1; + } + + // All clear. Forget the guard so it doesn't free the new RcBox. + forget(guard); + + Self::from_ptr(ptr) + } +} - // All clear. Forget the guard so it doesn't free the new RcBox. - forget(guard); +/// Specialization trait used for `From<&[T]>`. +trait RcFromSlice { + fn from_slice(slice: &[T]) -> Self; +} - Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } +impl RcFromSlice for Rc<[T]> { + #[inline] + default fn from_slice(v: &[T]) -> Self { + unsafe { + Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -907,7 +952,7 @@ impl Clone for Rc { #[inline] fn clone(&self) -> Rc { self.inc_strong(); - Rc { ptr: self.ptr, phantom: PhantomData } + Self::from_inner(self.ptr) } } @@ -1213,6 +1258,114 @@ impl From> for Rc<[T]> { } } +#[unstable(feature = "boxed_slice_try_from", issue = "0")] +impl TryFrom> for Rc<[T; N]> +where + [T; N]: LengthAtMost32, +{ + type Error = Rc<[T]>; + + fn try_from(boxed_slice: Rc<[T]>) -> Result { + if boxed_slice.len() == N { + Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) }) + } else { + Err(boxed_slice) + } + } +} + +#[stable(feature = "shared_from_iter", since = "1.37.0")] +impl iter::FromIterator for Rc<[T]> { + /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`. + /// + /// # Performance characteristics + /// + /// ## The general case + /// + /// In the general case, collecting into `Rc<[T]>` is done by first + /// collecting into a `Vec`. That is, when writing the following: + /// + /// ```rust + /// # use std::rc::Rc; + /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect(); + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// this behaves as if we wrote: + /// + /// ```rust + /// # use std::rc::Rc; + /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0) + /// .collect::>() // The first set of allocations happens here. + /// .into(); // A second allocation for `Rc<[T]>` happens here. + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// This will allocate as many times as needed for constructing the `Vec` + /// and then it will allocate once for turning the `Vec` into the `Rc<[T]>`. + /// + /// ## Iterators of known length + /// + /// When your `Iterator` implements `TrustedLen` and is of an exact size, + /// a single allocation will be made for the `Rc<[T]>`. For example: + /// + /// ```rust + /// # use std::rc::Rc; + /// let evens: Rc<[u8]> = (0..10).collect(); // Just a single allocation happens here. + /// # assert_eq!(&*evens, &*(0..10).collect::>()); + /// ``` + fn from_iter>(iter: I) -> Self { + RcFromIter::from_iter(iter.into_iter()) + } +} + +/// Specialization trait used for collecting into `Rc<[T]>`. +trait RcFromIter { + fn from_iter(iter: I) -> Self; +} + +impl> RcFromIter for Rc<[T]> { + default fn from_iter(iter: I) -> Self { + iter.collect::>().into() + } +} + +impl> RcFromIter for Rc<[T]> { + default fn from_iter(iter: I) -> Self { + // This is the case for a `TrustedLen` iterator. + let (low, high) = iter.size_hint(); + if let Some(high) = high { + debug_assert_eq!( + low, high, + "TrustedLen iterator's size hint is not exact: {:?}", + (low, high) + ); + + unsafe { + // SAFETY: We need to ensure that the iterator has an exact length and we have. + Rc::from_iter_exact(iter, low) + } + } else { + // Fall back to normal implementation. + iter.collect::>().into() + } + } +} + +impl<'a, T: 'a + Clone> RcFromIter<&'a T, slice::Iter<'a, T>> for Rc<[T]> { + fn from_iter(iter: slice::Iter<'a, T>) -> Self { + // Delegate to `impl From<&[T]> for Rc<[T]>`. + // + // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping` + // which is even more performant. + // + // In the fall-back case we have `T: Clone`. This is still better + // than the `TrustedLen` implementation as slices have a known length + // and so we get to avoid calling `size_hint` and avoid the branching. + iter.as_slice().into() + } +} + /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the /// managed value. The value is accessed by calling [`upgrade`] on the `Weak` /// pointer, which returns an [`Option`]`<`[`Rc`]`>`. @@ -1291,26 +1444,26 @@ impl Weak { /// ``` /// #![feature(weak_into_raw)] /// - /// use std::rc::{Rc, Weak}; + /// use std::rc::Rc; /// use std::ptr; /// /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); /// // Both point to the same object - /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + /// assert!(ptr::eq(&*strong, weak.as_raw())); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// assert_eq!("hello", unsafe { &*weak.as_raw() }); /// /// drop(strong); - /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// // assert_eq!("hello", unsafe { &*weak.as_raw() }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn as_raw(this: &Self) -> *const T { - match this.inner() { + pub fn as_raw(&self) -> *const T { + match self.inner() { None => ptr::null(), Some(inner) => { let offset = data_offset_sized::(); @@ -1341,7 +1494,7 @@ impl Weak { /// /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); - /// let raw = Weak::into_raw(weak); + /// let raw = weak.into_raw(); /// /// assert_eq!(1, Rc::weak_count(&strong)); /// assert_eq!("hello", unsafe { &*raw }); @@ -1353,9 +1506,9 @@ impl Weak { /// [`from_raw`]: struct.Weak.html#method.from_raw /// [`as_raw`]: struct.Weak.html#method.as_raw #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn into_raw(this: Self) -> *const T { - let result = Self::as_raw(&this); - mem::forget(this); + pub fn into_raw(self) -> *const T { + let result = self.as_raw(); + mem::forget(self); result } @@ -1382,18 +1535,18 @@ impl Weak { /// /// let strong = Rc::new("hello".to_owned()); /// - /// let raw_1 = Weak::into_raw(Rc::downgrade(&strong)); - /// let raw_2 = Weak::into_raw(Rc::downgrade(&strong)); + /// let raw_1 = Rc::downgrade(&strong).into_raw(); + /// let raw_2 = Rc::downgrade(&strong).into_raw(); /// /// assert_eq!(2, Rc::weak_count(&strong)); /// - /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); /// assert_eq!(1, Rc::weak_count(&strong)); /// /// drop(strong); /// /// // Decrement the last weak count. - /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none()); + /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html @@ -1456,7 +1609,7 @@ impl Weak { None } else { inner.inc_strong(); - Some(Rc { ptr: self.ptr, phantom: PhantomData }) + Some(Rc::from_inner(self.ptr)) } } @@ -1660,14 +1813,16 @@ trait RcBoxPtr { #[inline] fn inc_strong(&self) { + let strong = self.strong(); + // We want to abort on overflow instead of dropping the value. // The reference count will never be zero when this is called; // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. - if self.strong() == 0 || self.strong() == usize::max_value() { + if strong == 0 || strong == usize::max_value() { unsafe { abort(); } } - self.inner().strong.set(self.strong() + 1); + self.inner().strong.set(strong + 1); } #[inline] @@ -1682,14 +1837,16 @@ trait RcBoxPtr { #[inline] fn inc_weak(&self) { + let weak = self.weak(); + // We want to abort on overflow instead of dropping the value. // The reference count will never be zero when this is called; // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. - if self.weak() == 0 || self.weak() == usize::max_value() { + if weak == 0 || weak == usize::max_value() { unsafe { abort(); } } - self.inner().weak.set(self.weak() + 1); + self.inner().weak.set(weak + 1); } #[inline] @@ -1714,436 +1871,6 @@ impl RcBoxPtr for RcBox { } } -#[cfg(test)] -mod tests { - use super::{Rc, Weak}; - use std::boxed::Box; - use std::cell::RefCell; - use std::option::Option::{self, None, Some}; - use std::result::Result::{Err, Ok}; - use std::mem::drop; - use std::clone::Clone; - use std::convert::From; - - #[test] - fn test_clone() { - let x = Rc::new(RefCell::new(5)); - let y = x.clone(); - *x.borrow_mut() = 20; - assert_eq!(*y.borrow(), 20); - } - - #[test] - fn test_simple() { - let x = Rc::new(5); - assert_eq!(*x, 5); - } - - #[test] - fn test_simple_clone() { - let x = Rc::new(5); - let y = x.clone(); - assert_eq!(*x, 5); - assert_eq!(*y, 5); - } - - #[test] - fn test_destructor() { - let x: Rc> = Rc::new(box 5); - assert_eq!(**x, 5); - } - - #[test] - fn test_live() { - let x = Rc::new(5); - let y = Rc::downgrade(&x); - assert!(y.upgrade().is_some()); - } - - #[test] - fn test_dead() { - let x = Rc::new(5); - let y = Rc::downgrade(&x); - drop(x); - assert!(y.upgrade().is_none()); - } - - #[test] - fn weak_self_cyclic() { - struct Cycle { - x: RefCell>>, - } - - let a = Rc::new(Cycle { x: RefCell::new(None) }); - let b = Rc::downgrade(&a.clone()); - *a.x.borrow_mut() = Some(b); - - // hopefully we don't double-free (or leak)... - } - - #[test] - fn is_unique() { - let x = Rc::new(3); - assert!(Rc::is_unique(&x)); - let y = x.clone(); - assert!(!Rc::is_unique(&x)); - drop(y); - assert!(Rc::is_unique(&x)); - let w = Rc::downgrade(&x); - assert!(!Rc::is_unique(&x)); - drop(w); - assert!(Rc::is_unique(&x)); - } - - #[test] - fn test_strong_count() { - let a = Rc::new(0); - assert!(Rc::strong_count(&a) == 1); - let w = Rc::downgrade(&a); - assert!(Rc::strong_count(&a) == 1); - let b = w.upgrade().expect("upgrade of live rc failed"); - assert!(Rc::strong_count(&b) == 2); - assert!(Rc::strong_count(&a) == 2); - drop(w); - drop(a); - assert!(Rc::strong_count(&b) == 1); - let c = b.clone(); - assert!(Rc::strong_count(&b) == 2); - assert!(Rc::strong_count(&c) == 2); - } - - #[test] - fn test_weak_count() { - let a = Rc::new(0); - assert!(Rc::strong_count(&a) == 1); - assert!(Rc::weak_count(&a) == 0); - let w = Rc::downgrade(&a); - assert!(Rc::strong_count(&a) == 1); - assert!(Rc::weak_count(&a) == 1); - drop(w); - assert!(Rc::strong_count(&a) == 1); - assert!(Rc::weak_count(&a) == 0); - let c = a.clone(); - assert!(Rc::strong_count(&a) == 2); - assert!(Rc::weak_count(&a) == 0); - drop(c); - } - - #[test] - fn weak_counts() { - assert_eq!(Weak::weak_count(&Weak::::new()), None); - assert_eq!(Weak::strong_count(&Weak::::new()), 0); - - let a = Rc::new(0); - let w = Rc::downgrade(&a); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(1)); - let w2 = w.clone(); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(2)); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(2)); - drop(w); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(1)); - let a2 = a.clone(); - assert_eq!(Weak::strong_count(&w2), 2); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(a2); - drop(a); - assert_eq!(Weak::strong_count(&w2), 0); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(w2); - } - - #[test] - fn try_unwrap() { - let x = Rc::new(3); - assert_eq!(Rc::try_unwrap(x), Ok(3)); - let x = Rc::new(4); - let _y = x.clone(); - assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); - let x = Rc::new(5); - let _w = Rc::downgrade(&x); - assert_eq!(Rc::try_unwrap(x), Ok(5)); - } - - #[test] - fn into_from_raw() { - let x = Rc::new(box "hello"); - let y = x.clone(); - - let x_ptr = Rc::into_raw(x); - drop(y); - unsafe { - assert_eq!(**x_ptr, "hello"); - - let x = Rc::from_raw(x_ptr); - assert_eq!(**x, "hello"); - - assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello")); - } - } - - #[test] - fn test_into_from_raw_unsized() { - use std::fmt::Display; - use std::string::ToString; - - let rc: Rc = Rc::from("foo"); - - let ptr = Rc::into_raw(rc.clone()); - let rc2 = unsafe { Rc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }, "foo"); - assert_eq!(rc, rc2); - - let rc: Rc = Rc::new(123); - - let ptr = Rc::into_raw(rc.clone()); - let rc2 = unsafe { Rc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }.to_string(), "123"); - assert_eq!(rc2.to_string(), "123"); - } - - #[test] - fn get_mut() { - let mut x = Rc::new(3); - *Rc::get_mut(&mut x).unwrap() = 4; - assert_eq!(*x, 4); - let y = x.clone(); - assert!(Rc::get_mut(&mut x).is_none()); - drop(y); - assert!(Rc::get_mut(&mut x).is_some()); - let _w = Rc::downgrade(&x); - assert!(Rc::get_mut(&mut x).is_none()); - } - - #[test] - fn test_cowrc_clone_make_unique() { - let mut cow0 = Rc::new(75); - let mut cow1 = cow0.clone(); - let mut cow2 = cow1.clone(); - - assert!(75 == *Rc::make_mut(&mut cow0)); - assert!(75 == *Rc::make_mut(&mut cow1)); - assert!(75 == *Rc::make_mut(&mut cow2)); - - *Rc::make_mut(&mut cow0) += 1; - *Rc::make_mut(&mut cow1) += 2; - *Rc::make_mut(&mut cow2) += 3; - - assert!(76 == *cow0); - assert!(77 == *cow1); - assert!(78 == *cow2); - - // none should point to the same backing memory - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 != *cow2); - } - - #[test] - fn test_cowrc_clone_unique2() { - let mut cow0 = Rc::new(75); - let cow1 = cow0.clone(); - let cow2 = cow1.clone(); - - assert!(75 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - *Rc::make_mut(&mut cow0) += 1; - - assert!(76 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - // cow1 and cow2 should share the same contents - // cow0 should have a unique reference - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 == *cow2); - } - - #[test] - fn test_cowrc_clone_weak() { - let mut cow0 = Rc::new(75); - let cow1_weak = Rc::downgrade(&cow0); - - assert!(75 == *cow0); - assert!(75 == *cow1_weak.upgrade().unwrap()); - - *Rc::make_mut(&mut cow0) += 1; - - assert!(76 == *cow0); - assert!(cow1_weak.upgrade().is_none()); - } - - #[test] - fn test_show() { - let foo = Rc::new(75); - assert_eq!(format!("{:?}", foo), "75"); - } - - #[test] - fn test_unsized() { - let foo: Rc<[i32]> = Rc::new([1, 2, 3]); - assert_eq!(foo, foo.clone()); - } - - #[test] - fn test_from_owned() { - let foo = 123; - let foo_rc = Rc::from(foo); - assert!(123 == *foo_rc); - } - - #[test] - fn test_new_weak() { - let foo: Weak = Weak::new(); - assert!(foo.upgrade().is_none()); - } - - #[test] - fn test_ptr_eq() { - let five = Rc::new(5); - let same_five = five.clone(); - let other_five = Rc::new(5); - - assert!(Rc::ptr_eq(&five, &same_five)); - assert!(!Rc::ptr_eq(&five, &other_five)); - } - - #[test] - fn test_from_str() { - let r: Rc = Rc::from("foo"); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_copy_from_slice() { - let s: &[u32] = &[1, 2, 3]; - let r: Rc<[u32]> = Rc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_clone_from_slice() { - #[derive(Clone, Debug, Eq, PartialEq)] - struct X(u32); - - let s: &[X] = &[X(1), X(2), X(3)]; - let r: Rc<[X]> = Rc::from(s); - - assert_eq!(&r[..], s); - } - - #[test] - #[should_panic] - fn test_clone_from_slice_panic() { - use std::string::{String, ToString}; - - struct Fail(u32, String); - - impl Clone for Fail { - fn clone(&self) -> Fail { - if self.0 == 2 { - panic!(); - } - Fail(self.0, self.1.clone()) - } - } - - let s: &[Fail] = &[ - Fail(0, "foo".to_string()), - Fail(1, "bar".to_string()), - Fail(2, "baz".to_string()), - ]; - - // Should panic, but not cause memory corruption - let _r: Rc<[Fail]> = Rc::from(s); - } - - #[test] - fn test_from_box() { - let b: Box = box 123; - let r: Rc = Rc::from(b); - - assert_eq!(*r, 123); - } - - #[test] - fn test_from_box_str() { - use std::string::String; - - let s = String::from("foo").into_boxed_str(); - let r: Rc = Rc::from(s); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_from_box_slice() { - let s = vec![1, 2, 3].into_boxed_slice(); - let r: Rc<[u32]> = Rc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_from_box_trait() { - use std::fmt::Display; - use std::string::ToString; - - let b: Box = box 123; - let r: Rc = Rc::from(b); - - assert_eq!(r.to_string(), "123"); - } - - #[test] - fn test_from_box_trait_zero_sized() { - use std::fmt::Debug; - - let b: Box = box (); - let r: Rc = Rc::from(b); - - assert_eq!(format!("{:?}", r), "()"); - } - - #[test] - fn test_from_vec() { - let v = vec![1, 2, 3]; - let r: Rc<[u32]> = Rc::from(v); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_downcast() { - use std::any::Any; - - let r1: Rc = Rc::new(i32::max_value()); - let r2: Rc = Rc::new("abc"); - - assert!(r1.clone().downcast::().is_err()); - - let r1i32 = r1.downcast::(); - assert!(r1i32.is_ok()); - assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); - - assert!(r2.clone().downcast::().is_err()); - - let r2str = r2.downcast::<&'static str>(); - assert!(r2str.is_ok()); - assert_eq!(r2str.unwrap(), Rc::new("abc")); - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl borrow::Borrow for Rc { fn borrow(&self) -> &T { @@ -2162,18 +1889,20 @@ impl AsRef for Rc { impl Unpin for Rc { } unsafe fn data_offset(ptr: *const T) -> isize { - // Align the unsized value to the end of the RcBox. + // Align the unsized value to the end of the `RcBox`. // Because it is ?Sized, it will always be the last field in memory. - let align = align_of_val(&*ptr); - let layout = Layout::new::>(); - (layout.size() + layout.padding_needed_for(align)) as isize + data_offset_align(align_of_val(&*ptr)) } -/// Computes the offset of the data field within ArcInner. +/// Computes the offset of the data field within `RcBox`. /// /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. fn data_offset_sized() -> isize { - let align = align_of::(); + data_offset_align(align_of::()) +} + +#[inline] +fn data_offset_align(align: usize) -> isize { let layout = Layout::new::>(); (layout.size() + layout.padding_needed_for(align)) as isize } diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs new file mode 100644 index 0000000000..6fd3f90935 --- /dev/null +++ b/src/liballoc/rc/tests.rs @@ -0,0 +1,439 @@ +use super::*; + +use std::boxed::Box; +use std::cell::RefCell; +use std::option::Option::{self, None, Some}; +use std::result::Result::{Err, Ok}; +use std::mem::drop; +use std::clone::Clone; +use std::convert::{From, TryInto}; + +#[test] +fn test_clone() { + let x = Rc::new(RefCell::new(5)); + let y = x.clone(); + *x.borrow_mut() = 20; + assert_eq!(*y.borrow(), 20); +} + +#[test] +fn test_simple() { + let x = Rc::new(5); + assert_eq!(*x, 5); +} + +#[test] +fn test_simple_clone() { + let x = Rc::new(5); + let y = x.clone(); + assert_eq!(*x, 5); + assert_eq!(*y, 5); +} + +#[test] +fn test_destructor() { + let x: Rc> = Rc::new(box 5); + assert_eq!(**x, 5); +} + +#[test] +fn test_live() { + let x = Rc::new(5); + let y = Rc::downgrade(&x); + assert!(y.upgrade().is_some()); +} + +#[test] +fn test_dead() { + let x = Rc::new(5); + let y = Rc::downgrade(&x); + drop(x); + assert!(y.upgrade().is_none()); +} + +#[test] +fn weak_self_cyclic() { + struct Cycle { + x: RefCell>>, + } + + let a = Rc::new(Cycle { x: RefCell::new(None) }); + let b = Rc::downgrade(&a.clone()); + *a.x.borrow_mut() = Some(b); + + // hopefully we don't double-free (or leak)... +} + +#[test] +fn is_unique() { + let x = Rc::new(3); + assert!(Rc::is_unique(&x)); + let y = x.clone(); + assert!(!Rc::is_unique(&x)); + drop(y); + assert!(Rc::is_unique(&x)); + let w = Rc::downgrade(&x); + assert!(!Rc::is_unique(&x)); + drop(w); + assert!(Rc::is_unique(&x)); +} + +#[test] +fn test_strong_count() { + let a = Rc::new(0); + assert!(Rc::strong_count(&a) == 1); + let w = Rc::downgrade(&a); + assert!(Rc::strong_count(&a) == 1); + let b = w.upgrade().expect("upgrade of live rc failed"); + assert!(Rc::strong_count(&b) == 2); + assert!(Rc::strong_count(&a) == 2); + drop(w); + drop(a); + assert!(Rc::strong_count(&b) == 1); + let c = b.clone(); + assert!(Rc::strong_count(&b) == 2); + assert!(Rc::strong_count(&c) == 2); +} + +#[test] +fn test_weak_count() { + let a = Rc::new(0); + assert!(Rc::strong_count(&a) == 1); + assert!(Rc::weak_count(&a) == 0); + let w = Rc::downgrade(&a); + assert!(Rc::strong_count(&a) == 1); + assert!(Rc::weak_count(&a) == 1); + drop(w); + assert!(Rc::strong_count(&a) == 1); + assert!(Rc::weak_count(&a) == 0); + let c = a.clone(); + assert!(Rc::strong_count(&a) == 2); + assert!(Rc::weak_count(&a) == 0); + drop(c); +} + +#[test] +fn weak_counts() { + assert_eq!(Weak::weak_count(&Weak::::new()), None); + assert_eq!(Weak::strong_count(&Weak::::new()), 0); + + let a = Rc::new(0); + let w = Rc::downgrade(&a); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(1)); + let w2 = w.clone(); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(2)); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(2)); + drop(w); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); + let a2 = a.clone(); + assert_eq!(Weak::strong_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(a2); + drop(a); + assert_eq!(Weak::strong_count(&w2), 0); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(w2); +} + +#[test] +fn try_unwrap() { + let x = Rc::new(3); + assert_eq!(Rc::try_unwrap(x), Ok(3)); + let x = Rc::new(4); + let _y = x.clone(); + assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); + let x = Rc::new(5); + let _w = Rc::downgrade(&x); + assert_eq!(Rc::try_unwrap(x), Ok(5)); +} + +#[test] +fn into_from_raw() { + let x = Rc::new(box "hello"); + let y = x.clone(); + + let x_ptr = Rc::into_raw(x); + drop(y); + unsafe { + assert_eq!(**x_ptr, "hello"); + + let x = Rc::from_raw(x_ptr); + assert_eq!(**x, "hello"); + + assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello")); + } +} + +#[test] +fn test_into_from_raw_unsized() { + use std::fmt::Display; + use std::string::ToString; + + let rc: Rc = Rc::from("foo"); + + let ptr = Rc::into_raw(rc.clone()); + let rc2 = unsafe { Rc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }, "foo"); + assert_eq!(rc, rc2); + + let rc: Rc = Rc::new(123); + + let ptr = Rc::into_raw(rc.clone()); + let rc2 = unsafe { Rc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }.to_string(), "123"); + assert_eq!(rc2.to_string(), "123"); +} + +#[test] +fn get_mut() { + let mut x = Rc::new(3); + *Rc::get_mut(&mut x).unwrap() = 4; + assert_eq!(*x, 4); + let y = x.clone(); + assert!(Rc::get_mut(&mut x).is_none()); + drop(y); + assert!(Rc::get_mut(&mut x).is_some()); + let _w = Rc::downgrade(&x); + assert!(Rc::get_mut(&mut x).is_none()); +} + +#[test] +fn test_cowrc_clone_make_unique() { + let mut cow0 = Rc::new(75); + let mut cow1 = cow0.clone(); + let mut cow2 = cow1.clone(); + + assert!(75 == *Rc::make_mut(&mut cow0)); + assert!(75 == *Rc::make_mut(&mut cow1)); + assert!(75 == *Rc::make_mut(&mut cow2)); + + *Rc::make_mut(&mut cow0) += 1; + *Rc::make_mut(&mut cow1) += 2; + *Rc::make_mut(&mut cow2) += 3; + + assert!(76 == *cow0); + assert!(77 == *cow1); + assert!(78 == *cow2); + + // none should point to the same backing memory + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 != *cow2); +} + +#[test] +fn test_cowrc_clone_unique2() { + let mut cow0 = Rc::new(75); + let cow1 = cow0.clone(); + let cow2 = cow1.clone(); + + assert!(75 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + *Rc::make_mut(&mut cow0) += 1; + + assert!(76 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + // cow1 and cow2 should share the same contents + // cow0 should have a unique reference + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 == *cow2); +} + +#[test] +fn test_cowrc_clone_weak() { + let mut cow0 = Rc::new(75); + let cow1_weak = Rc::downgrade(&cow0); + + assert!(75 == *cow0); + assert!(75 == *cow1_weak.upgrade().unwrap()); + + *Rc::make_mut(&mut cow0) += 1; + + assert!(76 == *cow0); + assert!(cow1_weak.upgrade().is_none()); +} + +#[test] +fn test_show() { + let foo = Rc::new(75); + assert_eq!(format!("{:?}", foo), "75"); +} + +#[test] +fn test_unsized() { + let foo: Rc<[i32]> = Rc::new([1, 2, 3]); + assert_eq!(foo, foo.clone()); +} + +#[test] +fn test_from_owned() { + let foo = 123; + let foo_rc = Rc::from(foo); + assert!(123 == *foo_rc); +} + +#[test] +fn test_new_weak() { + let foo: Weak = Weak::new(); + assert!(foo.upgrade().is_none()); +} + +#[test] +fn test_ptr_eq() { + let five = Rc::new(5); + let same_five = five.clone(); + let other_five = Rc::new(5); + + assert!(Rc::ptr_eq(&five, &same_five)); + assert!(!Rc::ptr_eq(&five, &other_five)); +} + +#[test] +fn test_from_str() { + let r: Rc = Rc::from("foo"); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_copy_from_slice() { + let s: &[u32] = &[1, 2, 3]; + let r: Rc<[u32]> = Rc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_clone_from_slice() { + #[derive(Clone, Debug, Eq, PartialEq)] + struct X(u32); + + let s: &[X] = &[X(1), X(2), X(3)]; + let r: Rc<[X]> = Rc::from(s); + + assert_eq!(&r[..], s); +} + +#[test] +#[should_panic] +fn test_clone_from_slice_panic() { + use std::string::{String, ToString}; + + struct Fail(u32, String); + + impl Clone for Fail { + fn clone(&self) -> Fail { + if self.0 == 2 { + panic!(); + } + Fail(self.0, self.1.clone()) + } + } + + let s: &[Fail] = &[ + Fail(0, "foo".to_string()), + Fail(1, "bar".to_string()), + Fail(2, "baz".to_string()), + ]; + + // Should panic, but not cause memory corruption + let _r: Rc<[Fail]> = Rc::from(s); +} + +#[test] +fn test_from_box() { + let b: Box = box 123; + let r: Rc = Rc::from(b); + + assert_eq!(*r, 123); +} + +#[test] +fn test_from_box_str() { + use std::string::String; + + let s = String::from("foo").into_boxed_str(); + let r: Rc = Rc::from(s); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_from_box_slice() { + let s = vec![1, 2, 3].into_boxed_slice(); + let r: Rc<[u32]> = Rc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_from_box_trait() { + use std::fmt::Display; + use std::string::ToString; + + let b: Box = box 123; + let r: Rc = Rc::from(b); + + assert_eq!(r.to_string(), "123"); +} + +#[test] +fn test_from_box_trait_zero_sized() { + use std::fmt::Debug; + + let b: Box = box (); + let r: Rc = Rc::from(b); + + assert_eq!(format!("{:?}", r), "()"); +} + +#[test] +fn test_from_vec() { + let v = vec![1, 2, 3]; + let r: Rc<[u32]> = Rc::from(v); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_downcast() { + use std::any::Any; + + let r1: Rc = Rc::new(i32::max_value()); + let r2: Rc = Rc::new("abc"); + + assert!(r1.clone().downcast::().is_err()); + + let r1i32 = r1.downcast::(); + assert!(r1i32.is_ok()); + assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); + + assert!(r2.clone().downcast::().is_err()); + + let r2str = r2.downcast::<&'static str>(); + assert!(r2str.is_ok()); + assert_eq!(r2str.unwrap(), Rc::new("abc")); +} + +#[test] +fn test_array_from_slice() { + let v = vec![1, 2, 3]; + let r: Rc<[u32]> = Rc::from(v); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_ok()); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_err()); +} diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index f7b0a5e703..881d499c07 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -484,6 +484,57 @@ impl [T] { } buf } + + /// Flattens a slice of `T` into a single value `Self::Output`. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].concat(), "helloworld"); + /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn concat(&self) -> >::Output + where Self: Concat + { + Concat::concat(self) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].join(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); + /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]); + /// ``` + #[stable(feature = "rename_connect_to_join", since = "1.3.0")] + pub fn join(&self, sep: Separator) -> >::Output + where Self: Join + { + Join::join(self, sep) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// # #![allow(deprecated)] + /// assert_eq!(["hello", "world"].connect(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] + pub fn connect(&self, sep: Separator) -> >::Output + where Self: Join + { + Join::join(self, sep) + } + } #[lang = "slice_u8_alloc"] @@ -527,87 +578,84 @@ impl [u8] { //////////////////////////////////////////////////////////////////////////////// // Extension traits for slices over specific kinds of data //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -/// An extension trait for concatenating slices + +/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat). +/// +/// Note: the `Item` type parameter is not used in this trait, +/// but it allows impls to be more generic. +/// Without it, we get this error: +/// +/// ```error +/// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica +/// --> src/liballoc/slice.rs:608:6 +/// | +/// 608 | impl> Concat for [V] { +/// | ^ unconstrained type parameter +/// ``` /// -/// While this trait is unstable, the methods are stable. `SliceConcatExt` is -/// included in the [standard library prelude], so you can use [`join()`] and -/// [`concat()`] as if they existed on `[T]` itself. +/// This is because there could exist `V` types with multiple `Borrow<[_]>` impls, +/// such that multiple `T` types would apply: /// -/// [standard library prelude]: ../../std/prelude/index.html -/// [`join()`]: #tymethod.join -/// [`concat()`]: #tymethod.concat -pub trait SliceConcatExt { - #[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] +/// ``` +/// # #[allow(dead_code)] +/// pub struct Foo(Vec, Vec); +/// +/// impl std::borrow::Borrow<[u32]> for Foo { +/// fn borrow(&self) -> &[u32] { &self.0 } +/// } +/// +/// impl std::borrow::Borrow<[String]> for Foo { +/// fn borrow(&self) -> &[String] { &self.1 } +/// } +/// ``` +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait Concat { + #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; - /// Flattens a slice of `T` into a single value `Self::Output`. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].concat(), "helloworld"); - /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn concat(&self) -> Self::Output; + /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn concat(slice: &Self) -> Self::Output; +} - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].join(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - fn join(&self, sep: &T) -> Self::Output; +/// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join) +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait Join { + #[unstable(feature = "slice_concat_trait", issue = "27747")] + /// The resulting type after concatenation + type Output; - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// # #![allow(deprecated)] - /// assert_eq!(["hello", "world"].connect(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - fn connect(&self, sep: &T) -> Self::Output { - self.join(sep) - } + /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn join(slice: &Self, sep: Separator) -> Self::Output; } -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -impl> SliceConcatExt for [V] { +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Concat for [V] { type Output = Vec; - fn concat(&self) -> Vec { - let size = self.iter().map(|slice| slice.borrow().len()).sum(); + fn concat(slice: &Self) -> Vec { + let size = slice.iter().map(|slice| slice.borrow().len()).sum(); let mut result = Vec::with_capacity(size); - for v in self { + for v in slice { result.extend_from_slice(v.borrow()) } result } +} - fn join(&self, sep: &T) -> Vec { - let mut iter = self.iter(); +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join<&T> for [V] { + type Output = Vec; + + fn join(slice: &Self, sep: &T) -> Vec { + let mut iter = slice.iter(); let first = match iter.next() { Some(first) => first, None => return vec![], }; - let size = self.iter().map(|slice| slice.borrow().len()).sum::() + self.len() - 1; + let size = slice.iter().map(|v| v.borrow().len()).sum::() + slice.len() - 1; let mut result = Vec::with_capacity(size); result.extend_from_slice(first.borrow()); @@ -619,6 +667,29 @@ impl> SliceConcatExt for [V] { } } +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join<&[T]> for [V] { + type Output = Vec; + + fn join(slice: &Self, sep: &[T]) -> Vec { + let mut iter = slice.iter(); + let first = match iter.next() { + Some(first) => first, + None => return vec![], + }; + let size = slice.iter().map(|v| v.borrow().len()).sum::() + + sep.len() * (slice.len() - 1); + let mut result = Vec::with_capacity(size); + result.extend_from_slice(first.borrow()); + + for v in iter { + result.extend_from_slice(sep); + result.extend_from_slice(v.borrow()) + } + result + } +} + //////////////////////////////////////////////////////////////////////////////// // Standard trait implementations for slices //////////////////////////////////////////////////////////////////////////////// diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 40104554fe..9a1342c30d 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,7 +37,7 @@ use core::unicode::conversions; use crate::borrow::ToOwned; use crate::boxed::Box; -use crate::slice::{SliceConcatExt, SliceIndex}; +use crate::slice::{Concat, Join, SliceIndex}; use crate::string::String; use crate::vec::Vec; @@ -71,19 +71,24 @@ pub use core::str::SplitAsciiWhitespace; #[stable(feature = "str_escape", since = "1.34.0")] pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -impl> SliceConcatExt for [S] { +/// Note: `str` in `Concat` is not meaningful here. +/// This type parameter of the trait only exists to enable another impl. +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Concat for [S] { type Output = String; - fn concat(&self) -> String { - self.join("") + fn concat(slice: &Self) -> String { + Join::join(slice, "") } +} + +#[unstable(feature = "slice_concat_ext", issue = "27747")] +impl> Join<&str> for [S] { + type Output = String; - fn join(&self, sep: &str) -> String { + fn join(slice: &Self, sep: &str) -> String { unsafe { - String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) ) + String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) } } } @@ -126,7 +131,7 @@ macro_rules! copy_slice_and_advance { // Optimized join implementation that works for both Vec (T: Copy) and String's inner vec // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262) -// For this reason SliceConcatExt is not specialized for T: Copy and SliceConcatExt is the +// For this reason SliceConcat is not specialized for T: Copy and SliceConcat is the // only user of this function. It is left in place for the time when that is fixed. // // the bounds for String-join are S: Borrow and for Vec-join Borrow<[T]> @@ -203,7 +208,7 @@ impl ToOwned for str { } fn clone_into(&self, target: &mut String) { - let mut b = mem::replace(target, String::new()).into_bytes(); + let mut b = mem::take(target).into_bytes(); self.as_bytes().clone_into(&mut b); *target = unsafe { String::from_utf8_unchecked(b) } } diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 7f7722548f..eca726cd41 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -552,7 +552,7 @@ impl String { /// assert_eq!("Hello �World", output); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> { + pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> { let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks(); let (first_valid, first_broken) = if let Some(chunk) = iter.next() { @@ -1838,6 +1838,7 @@ impl PartialEq for String { macro_rules! impl_eq { ($lhs:ty, $rhs: ty) => { #[stable(feature = "rust1", since = "1.0.0")] + #[allow(unused_lifetimes)] impl<'a, 'b> PartialEq<$rhs> for $lhs { #[inline] fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&self[..], &other[..]) } @@ -1846,6 +1847,7 @@ macro_rules! impl_eq { } #[stable(feature = "rust1", since = "1.0.0")] + #[allow(unused_lifetimes)] impl<'a, 'b> PartialEq<$lhs> for $rhs { #[inline] fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&self[..], &other[..]) } @@ -2385,6 +2387,11 @@ impl Iterator for Drain<'_> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 6c23b3179e..7d3b2656a7 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -7,11 +7,13 @@ //! [arc]: struct.Arc.html use core::any::Any; +use core::array::LengthAtMost32; use core::sync::atomic; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; use core::borrow; use core::fmt; use core::cmp::{self, Ordering}; +use core::iter; use core::intrinsics::abort; use core::mem::{self, align_of, align_of_val, size_of_val}; use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; @@ -20,8 +22,8 @@ use core::ptr::{self, NonNull}; use core::marker::{Unpin, Unsize, PhantomData}; use core::hash::{Hash, Hasher}; use core::{isize, usize}; -use core::convert::From; -use core::slice::from_raw_parts_mut; +use core::convert::{From, TryFrom}; +use core::slice::{self, from_raw_parts_mut}; use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; use crate::boxed::Box; @@ -29,6 +31,9 @@ use crate::rc::is_dangling; use crate::string::String; use crate::vec::Vec; +#[cfg(test)] +mod tests; + /// A soft limit on the amount of references that may be made to an `Arc`. /// /// Going above this limit will abort your program (although not @@ -206,6 +211,19 @@ impl, U: ?Sized> CoerceUnsized> for Arc {} #[unstable(feature = "dispatch_from_dyn", issue = "0")] impl, U: ?Sized> DispatchFromDyn> for Arc {} +impl Arc { + fn from_inner(ptr: NonNull>) -> Self { + Self { + ptr, + phantom: PhantomData, + } + } + + unsafe fn from_ptr(ptr: *mut ArcInner) -> Self { + Self::from_inner(NonNull::new_unchecked(ptr)) + } +} + /// `Weak` is a version of [`Arc`] that holds a non-owning reference to the /// managed value. The value is accessed by calling [`upgrade`] on the `Weak` /// pointer, which returns an [`Option`]`<`[`Arc`]`>`. @@ -290,7 +308,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), data, }; - Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData } + Self::from_inner(Box::into_raw_non_null(x)) } /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then @@ -403,10 +421,7 @@ impl Arc { let fake_ptr = ptr as *mut ArcInner; let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Arc { - ptr: NonNull::new_unchecked(arc_ptr), - phantom: PhantomData, - } + Self::from_ptr(arc_ptr) } /// Consumes the `Arc`, returning the wrapped pointer as `NonNull`. @@ -577,21 +592,28 @@ impl Arc { } impl Arc { - // Allocates an `ArcInner` with sufficient space for an unsized value - unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { - // Calculate layout using the given value. + /// Allocates an `ArcInner` with sufficient space for + /// an unsized value where the value has the layout provided. + /// + /// The function `mem_to_arcinner` is called with the data pointer + /// and must return back a (potentially fat)-pointer for the `ArcInner`. + unsafe fn allocate_for_unsized( + value_layout: Layout, + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner + ) -> *mut ArcInner { + // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const ArcInner)`, but this created a misaligned // reference (see #54908). let layout = Layout::new::>() - .extend(Layout::for_value(&*ptr)).unwrap().0 + .extend(value_layout).unwrap().0 .pad_to_align().unwrap(); let mem = Global.alloc(layout) .unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the ArcInner - let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner; + let inner = mem_to_arcinner(mem.as_ptr()); debug_assert_eq!(Layout::for_value(&*inner), layout); ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1)); @@ -600,6 +622,15 @@ impl Arc { inner } + /// Allocates an `ArcInner` with sufficient space for an unsized value. + unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { + // Allocate for the `ArcInner` using the given value. + Self::allocate_for_unsized( + Layout::for_value(&*ptr), + |mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner, + ) + } + fn from_box(v: Box) -> Arc { unsafe { let box_unique = Box::into_unique(v); @@ -617,45 +648,49 @@ impl Arc { // Free the allocation without dropping its contents box_free(box_unique); - Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } } } -// Sets the data pointer of a `?Sized` raw pointer. -// -// For a slice/trait object, this sets the `data` field and leaves the rest -// unchanged. For a sized raw pointer, this simply sets the pointer. +impl Arc<[T]> { + /// Allocates an `ArcInner<[T]>` with the given length. + unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { + Self::allocate_for_unsized( + Layout::array::(len).unwrap(), + |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>, + ) + } +} + +/// Sets the data pointer of a `?Sized` raw pointer. +/// +/// For a slice/trait object, this sets the `data` field and leaves the rest +/// unchanged. For a sized raw pointer, this simply sets the pointer. unsafe fn set_data_ptr(mut ptr: *mut T, data: *mut U) -> *mut T { ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8); ptr } impl Arc<[T]> { - // Copy elements from slice into newly allocated Arc<[T]> - // - // Unsafe because the caller must either take ownership or bind `T: Copy` + /// Copy elements from slice into newly allocated Arc<[T]> + /// + /// Unsafe because the caller must either take ownership or bind `T: Copy`. unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(v.len()); ptr::copy_nonoverlapping( v.as_ptr(), &mut (*ptr).data as *mut [T] as *mut T, v.len()); - Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } + Self::from_ptr(ptr) } -} - -// Specialization trait used for From<&[T]> -trait ArcFromSlice { - fn from_slice(slice: &[T]) -> Self; -} -impl ArcFromSlice for Arc<[T]> { - #[inline] - default fn from_slice(v: &[T]) -> Self { + /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size. + /// + /// Behavior is undefined should the size be wrong. + unsafe fn from_iter_exact(iter: impl iter::Iterator, len: usize) -> Arc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written // into the new ArcInner will be dropped, then the memory freed. @@ -672,37 +707,48 @@ impl ArcFromSlice for Arc<[T]> { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); - Global.dealloc(self.mem.cast(), self.layout.clone()); + Global.dealloc(self.mem.cast(), self.layout); } } } - unsafe { - let v_ptr = v as *const [T]; - let ptr = Self::allocate_for_ptr(v_ptr); + let ptr = Self::allocate_for_slice(len); - let mem = ptr as *mut _ as *mut u8; - let layout = Layout::for_value(&*ptr); + let mem = ptr as *mut _ as *mut u8; + let layout = Layout::for_value(&*ptr); - // Pointer to first element - let elems = &mut (*ptr).data as *mut [T] as *mut T; + // Pointer to first element + let elems = &mut (*ptr).data as *mut [T] as *mut T; - let mut guard = Guard{ - mem: NonNull::new_unchecked(mem), - elems: elems, - layout: layout, - n_elems: 0, - }; + let mut guard = Guard { + mem: NonNull::new_unchecked(mem), + elems, + layout, + n_elems: 0, + }; - for (i, item) in v.iter().enumerate() { - ptr::write(elems.add(i), item.clone()); - guard.n_elems += 1; - } + for (i, item) in iter.enumerate() { + ptr::write(elems.add(i), item); + guard.n_elems += 1; + } + + // All clear. Forget the guard so it doesn't free the new ArcInner. + mem::forget(guard); + + Self::from_ptr(ptr) + } +} - // All clear. Forget the guard so it doesn't free the new ArcInner. - mem::forget(guard); +/// Specialization trait used for `From<&[T]>`. +trait ArcFromSlice { + fn from_slice(slice: &[T]) -> Self; +} - Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } +impl ArcFromSlice for Arc<[T]> { + #[inline] + default fn from_slice(v: &[T]) -> Self { + unsafe { + Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -760,7 +806,7 @@ impl Clone for Arc { } } - Arc { ptr: self.ptr, phantom: PhantomData } + Self::from_inner(self.ptr) } } @@ -1039,7 +1085,7 @@ impl Arc { if (*self).is::() { let ptr = self.ptr.cast::>(); mem::forget(self); - Ok(Arc { ptr, phantom: PhantomData }) + Ok(Arc::from_inner(ptr)) } else { Err(self) } @@ -1080,26 +1126,26 @@ impl Weak { /// ``` /// #![feature(weak_into_raw)] /// - /// use std::sync::{Arc, Weak}; + /// use std::sync::Arc; /// use std::ptr; /// /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); /// // Both point to the same object - /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + /// assert!(ptr::eq(&*strong, weak.as_raw())); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// assert_eq!("hello", unsafe { &*weak.as_raw() }); /// /// drop(strong); - /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); + /// // assert_eq!("hello", unsafe { &*weak.as_raw() }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn as_raw(this: &Self) -> *const T { - match this.inner() { + pub fn as_raw(&self) -> *const T { + match self.inner() { None => ptr::null(), Some(inner) => { let offset = data_offset_sized::(); @@ -1130,7 +1176,7 @@ impl Weak { /// /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); - /// let raw = Weak::into_raw(weak); + /// let raw = weak.into_raw(); /// /// assert_eq!(1, Arc::weak_count(&strong)); /// assert_eq!("hello", unsafe { &*raw }); @@ -1142,9 +1188,9 @@ impl Weak { /// [`from_raw`]: struct.Weak.html#method.from_raw /// [`as_raw`]: struct.Weak.html#method.as_raw #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn into_raw(this: Self) -> *const T { - let result = Self::as_raw(&this); - mem::forget(this); + pub fn into_raw(self) -> *const T { + let result = self.as_raw(); + mem::forget(self); result } @@ -1172,18 +1218,18 @@ impl Weak { /// /// let strong = Arc::new("hello".to_owned()); /// - /// let raw_1 = Weak::into_raw(Arc::downgrade(&strong)); - /// let raw_2 = Weak::into_raw(Arc::downgrade(&strong)); + /// let raw_1 = Arc::downgrade(&strong).into_raw(); + /// let raw_2 = Arc::downgrade(&strong).into_raw(); /// /// assert_eq!(2, Arc::weak_count(&strong)); /// - /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap()); /// assert_eq!(1, Arc::weak_count(&strong)); /// /// drop(strong); /// /// // Decrement the last weak count. - /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none()); + /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html @@ -1260,11 +1306,7 @@ impl Weak { // Relaxed is valid for the same reason it is on Arc's Clone impl match inner.strong.compare_exchange_weak(n, n + 1, Relaxed, Relaxed) { - Ok(_) => return Some(Arc { - // null checked above - ptr: self.ptr, - phantom: PhantomData, - }), + Ok(_) => return Some(Arc::from_inner(self.ptr)), // null checked above Err(old) => n = old, } } @@ -1785,486 +1827,111 @@ impl From> for Arc<[T]> { } } -#[cfg(test)] -mod tests { - use std::boxed::Box; - use std::clone::Clone; - use std::sync::mpsc::channel; - use std::mem::drop; - use std::ops::Drop; - use std::option::Option::{self, None, Some}; - use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; - use std::thread; - use std::sync::Mutex; - use std::convert::From; - - use super::{Arc, Weak}; - use crate::vec::Vec; - - struct Canary(*mut atomic::AtomicUsize); - - impl Drop for Canary { - fn drop(&mut self) { - unsafe { - match *self { - Canary(c) => { - (*c).fetch_add(1, SeqCst); - } - } - } - } - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg(not(miri))] // Miri does not support threads - fn manually_share_arc() { - let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let arc_v = Arc::new(v); - - let (tx, rx) = channel(); - - let _t = thread::spawn(move || { - let arc_v: Arc> = rx.recv().unwrap(); - assert_eq!((*arc_v)[3], 4); - }); - - tx.send(arc_v.clone()).unwrap(); - - assert_eq!((*arc_v)[2], 3); - assert_eq!((*arc_v)[4], 5); - } - - #[test] - fn test_arc_get_mut() { - let mut x = Arc::new(3); - *Arc::get_mut(&mut x).unwrap() = 4; - assert_eq!(*x, 4); - let y = x.clone(); - assert!(Arc::get_mut(&mut x).is_none()); - drop(y); - assert!(Arc::get_mut(&mut x).is_some()); - let _w = Arc::downgrade(&x); - assert!(Arc::get_mut(&mut x).is_none()); - } - - #[test] - fn weak_counts() { - assert_eq!(Weak::weak_count(&Weak::::new()), None); - assert_eq!(Weak::strong_count(&Weak::::new()), 0); - - let a = Arc::new(0); - let w = Arc::downgrade(&a); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(1)); - let w2 = w.clone(); - assert_eq!(Weak::strong_count(&w), 1); - assert_eq!(Weak::weak_count(&w), Some(2)); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(2)); - drop(w); - assert_eq!(Weak::strong_count(&w2), 1); - assert_eq!(Weak::weak_count(&w2), Some(1)); - let a2 = a.clone(); - assert_eq!(Weak::strong_count(&w2), 2); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(a2); - drop(a); - assert_eq!(Weak::strong_count(&w2), 0); - assert_eq!(Weak::weak_count(&w2), Some(1)); - drop(w2); - } - - #[test] - fn try_unwrap() { - let x = Arc::new(3); - assert_eq!(Arc::try_unwrap(x), Ok(3)); - let x = Arc::new(4); - let _y = x.clone(); - assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4))); - let x = Arc::new(5); - let _w = Arc::downgrade(&x); - assert_eq!(Arc::try_unwrap(x), Ok(5)); - } - - #[test] - fn into_from_raw() { - let x = Arc::new(box "hello"); - let y = x.clone(); - - let x_ptr = Arc::into_raw(x); - drop(y); - unsafe { - assert_eq!(**x_ptr, "hello"); - - let x = Arc::from_raw(x_ptr); - assert_eq!(**x, "hello"); - - assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello")); - } - } - - #[test] - fn test_into_from_raw_unsized() { - use std::fmt::Display; - use std::string::ToString; - - let arc: Arc = Arc::from("foo"); - - let ptr = Arc::into_raw(arc.clone()); - let arc2 = unsafe { Arc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }, "foo"); - assert_eq!(arc, arc2); - - let arc: Arc = Arc::new(123); - - let ptr = Arc::into_raw(arc.clone()); - let arc2 = unsafe { Arc::from_raw(ptr) }; - - assert_eq!(unsafe { &*ptr }.to_string(), "123"); - assert_eq!(arc2.to_string(), "123"); - } - - #[test] - fn test_cowarc_clone_make_mut() { - let mut cow0 = Arc::new(75); - let mut cow1 = cow0.clone(); - let mut cow2 = cow1.clone(); - - assert!(75 == *Arc::make_mut(&mut cow0)); - assert!(75 == *Arc::make_mut(&mut cow1)); - assert!(75 == *Arc::make_mut(&mut cow2)); - - *Arc::make_mut(&mut cow0) += 1; - *Arc::make_mut(&mut cow1) += 2; - *Arc::make_mut(&mut cow2) += 3; - - assert!(76 == *cow0); - assert!(77 == *cow1); - assert!(78 == *cow2); - - // none should point to the same backing memory - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 != *cow2); - } - - #[test] - fn test_cowarc_clone_unique2() { - let mut cow0 = Arc::new(75); - let cow1 = cow0.clone(); - let cow2 = cow1.clone(); - - assert!(75 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); +#[unstable(feature = "boxed_slice_try_from", issue = "0")] +impl TryFrom> for Arc<[T; N]> +where + [T; N]: LengthAtMost32, +{ + type Error = Arc<[T]>; - *Arc::make_mut(&mut cow0) += 1; - assert!(76 == *cow0); - assert!(75 == *cow1); - assert!(75 == *cow2); - - // cow1 and cow2 should share the same contents - // cow0 should have a unique reference - assert!(*cow0 != *cow1); - assert!(*cow0 != *cow2); - assert!(*cow1 == *cow2); - } - - #[test] - fn test_cowarc_clone_weak() { - let mut cow0 = Arc::new(75); - let cow1_weak = Arc::downgrade(&cow0); - - assert!(75 == *cow0); - assert!(75 == *cow1_weak.upgrade().unwrap()); - - *Arc::make_mut(&mut cow0) += 1; - - assert!(76 == *cow0); - assert!(cow1_weak.upgrade().is_none()); - } - - #[test] - fn test_live() { - let x = Arc::new(5); - let y = Arc::downgrade(&x); - assert!(y.upgrade().is_some()); - } - - #[test] - fn test_dead() { - let x = Arc::new(5); - let y = Arc::downgrade(&x); - drop(x); - assert!(y.upgrade().is_none()); - } - - #[test] - fn weak_self_cyclic() { - struct Cycle { - x: Mutex>>, - } - - let a = Arc::new(Cycle { x: Mutex::new(None) }); - let b = Arc::downgrade(&a.clone()); - *a.x.lock().unwrap() = Some(b); - - // hopefully we don't double-free (or leak)... - } - - #[test] - fn drop_arc() { - let mut canary = atomic::AtomicUsize::new(0); - let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); - drop(x); - assert!(canary.load(Acquire) == 1); - } - - #[test] - fn drop_arc_weak() { - let mut canary = atomic::AtomicUsize::new(0); - let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); - let arc_weak = Arc::downgrade(&arc); - assert!(canary.load(Acquire) == 0); - drop(arc); - assert!(canary.load(Acquire) == 1); - drop(arc_weak); - } - - #[test] - fn test_strong_count() { - let a = Arc::new(0); - assert!(Arc::strong_count(&a) == 1); - let w = Arc::downgrade(&a); - assert!(Arc::strong_count(&a) == 1); - let b = w.upgrade().expect(""); - assert!(Arc::strong_count(&b) == 2); - assert!(Arc::strong_count(&a) == 2); - drop(w); - drop(a); - assert!(Arc::strong_count(&b) == 1); - let c = b.clone(); - assert!(Arc::strong_count(&b) == 2); - assert!(Arc::strong_count(&c) == 2); - } - - #[test] - fn test_weak_count() { - let a = Arc::new(0); - assert!(Arc::strong_count(&a) == 1); - assert!(Arc::weak_count(&a) == 0); - let w = Arc::downgrade(&a); - assert!(Arc::strong_count(&a) == 1); - assert!(Arc::weak_count(&a) == 1); - let x = w.clone(); - assert!(Arc::weak_count(&a) == 2); - drop(w); - drop(x); - assert!(Arc::strong_count(&a) == 1); - assert!(Arc::weak_count(&a) == 0); - let c = a.clone(); - assert!(Arc::strong_count(&a) == 2); - assert!(Arc::weak_count(&a) == 0); - let d = Arc::downgrade(&c); - assert!(Arc::weak_count(&c) == 1); - assert!(Arc::strong_count(&c) == 2); - - drop(a); - drop(c); - drop(d); - } - - #[test] - fn show_arc() { - let a = Arc::new(5); - assert_eq!(format!("{:?}", a), "5"); - } - - // Make sure deriving works with Arc - #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)] - struct Foo { - inner: Arc, - } - - #[test] - fn test_unsized() { - let x: Arc<[i32]> = Arc::new([1, 2, 3]); - assert_eq!(format!("{:?}", x), "[1, 2, 3]"); - let y = Arc::downgrade(&x.clone()); - drop(x); - assert!(y.upgrade().is_none()); - } - - #[test] - fn test_from_owned() { - let foo = 123; - let foo_arc = Arc::from(foo); - assert!(123 == *foo_arc); - } - - #[test] - fn test_new_weak() { - let foo: Weak = Weak::new(); - assert!(foo.upgrade().is_none()); - } - - #[test] - fn test_ptr_eq() { - let five = Arc::new(5); - let same_five = five.clone(); - let other_five = Arc::new(5); - - assert!(Arc::ptr_eq(&five, &same_five)); - assert!(!Arc::ptr_eq(&five, &other_five)); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - #[cfg(not(miri))] // Miri does not support threads - fn test_weak_count_locked() { - let mut a = Arc::new(atomic::AtomicBool::new(false)); - let a2 = a.clone(); - let t = thread::spawn(move || { - for _i in 0..1000000 { - Arc::get_mut(&mut a); - } - a.store(true, SeqCst); - }); - - while !a2.load(SeqCst) { - let n = Arc::weak_count(&a2); - assert!(n < 2, "bad weak count: {}", n); + fn try_from(boxed_slice: Arc<[T]>) -> Result { + if boxed_slice.len() == N { + Ok(unsafe { Arc::from_raw(Arc::into_raw(boxed_slice) as *mut [T; N]) }) + } else { + Err(boxed_slice) } - t.join().unwrap(); - } - - #[test] - fn test_from_str() { - let r: Arc = Arc::from("foo"); - - assert_eq!(&r[..], "foo"); } +} - #[test] - fn test_copy_from_slice() { - let s: &[u32] = &[1, 2, 3]; - let r: Arc<[u32]> = Arc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); +#[stable(feature = "shared_from_iter", since = "1.37.0")] +impl iter::FromIterator for Arc<[T]> { + /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`. + /// + /// # Performance characteristics + /// + /// ## The general case + /// + /// In the general case, collecting into `Arc<[T]>` is done by first + /// collecting into a `Vec`. That is, when writing the following: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect(); + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// this behaves as if we wrote: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0) + /// .collect::>() // The first set of allocations happens here. + /// .into(); // A second allocation for `Arc<[T]>` happens here. + /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]); + /// ``` + /// + /// This will allocate as many times as needed for constructing the `Vec` + /// and then it will allocate once for turning the `Vec` into the `Arc<[T]>`. + /// + /// ## Iterators of known length + /// + /// When your `Iterator` implements `TrustedLen` and is of an exact size, + /// a single allocation will be made for the `Arc<[T]>`. For example: + /// + /// ```rust + /// # use std::sync::Arc; + /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here. + /// # assert_eq!(&*evens, &*(0..10).collect::>()); + /// ``` + fn from_iter>(iter: I) -> Self { + ArcFromIter::from_iter(iter.into_iter()) } +} - #[test] - fn test_clone_from_slice() { - #[derive(Clone, Debug, Eq, PartialEq)] - struct X(u32); - - let s: &[X] = &[X(1), X(2), X(3)]; - let r: Arc<[X]> = Arc::from(s); +/// Specialization trait used for collecting into `Arc<[T]>`. +trait ArcFromIter { + fn from_iter(iter: I) -> Self; +} - assert_eq!(&r[..], s); +impl> ArcFromIter for Arc<[T]> { + default fn from_iter(iter: I) -> Self { + iter.collect::>().into() } +} - #[test] - #[should_panic] - fn test_clone_from_slice_panic() { - use std::string::{String, ToString}; - - struct Fail(u32, String); +impl> ArcFromIter for Arc<[T]> { + default fn from_iter(iter: I) -> Self { + // This is the case for a `TrustedLen` iterator. + let (low, high) = iter.size_hint(); + if let Some(high) = high { + debug_assert_eq!( + low, high, + "TrustedLen iterator's size hint is not exact: {:?}", + (low, high) + ); - impl Clone for Fail { - fn clone(&self) -> Fail { - if self.0 == 2 { - panic!(); - } - Fail(self.0, self.1.clone()) + unsafe { + // SAFETY: We need to ensure that the iterator has an exact length and we have. + Arc::from_iter_exact(iter, low) } + } else { + // Fall back to normal implementation. + iter.collect::>().into() } - - let s: &[Fail] = &[ - Fail(0, "foo".to_string()), - Fail(1, "bar".to_string()), - Fail(2, "baz".to_string()), - ]; - - // Should panic, but not cause memory corruption - let _r: Arc<[Fail]> = Arc::from(s); - } - - #[test] - fn test_from_box() { - let b: Box = box 123; - let r: Arc = Arc::from(b); - - assert_eq!(*r, 123); - } - - #[test] - fn test_from_box_str() { - use std::string::String; - - let s = String::from("foo").into_boxed_str(); - let r: Arc = Arc::from(s); - - assert_eq!(&r[..], "foo"); - } - - #[test] - fn test_from_box_slice() { - let s = vec![1, 2, 3].into_boxed_slice(); - let r: Arc<[u32]> = Arc::from(s); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_from_box_trait() { - use std::fmt::Display; - use std::string::ToString; - - let b: Box = box 123; - let r: Arc = Arc::from(b); - - assert_eq!(r.to_string(), "123"); } +} - #[test] - fn test_from_box_trait_zero_sized() { - use std::fmt::Debug; - - let b: Box = box (); - let r: Arc = Arc::from(b); - - assert_eq!(format!("{:?}", r), "()"); - } - - #[test] - fn test_from_vec() { - let v = vec![1, 2, 3]; - let r: Arc<[u32]> = Arc::from(v); - - assert_eq!(&r[..], [1, 2, 3]); - } - - #[test] - fn test_downcast() { - use std::any::Any; - - let r1: Arc = Arc::new(i32::max_value()); - let r2: Arc = Arc::new("abc"); - - assert!(r1.clone().downcast::().is_err()); - - let r1i32 = r1.downcast::(); - assert!(r1i32.is_ok()); - assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value())); - - assert!(r2.clone().downcast::().is_err()); - - let r2str = r2.downcast::<&'static str>(); - assert!(r2str.is_ok()); - assert_eq!(r2str.unwrap(), Arc::new("abc")); +impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> { + fn from_iter(iter: slice::Iter<'a, T>) -> Self { + // Delegate to `impl From<&[T]> for Arc<[T]>`. + // + // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping` + // which is even more performant. + // + // In the fall-back case we have `T: Clone`. This is still better + // than the `TrustedLen` implementation as slices have a known length + // and so we get to avoid calling `size_hint` and avoid the branching. + iter.as_slice().into() } } @@ -2285,20 +1952,22 @@ impl AsRef for Arc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Arc { } -/// Computes the offset of the data field within ArcInner. +/// Computes the offset of the data field within `ArcInner`. unsafe fn data_offset(ptr: *const T) -> isize { - // Align the unsized value to the end of the ArcInner. - // Because it is ?Sized, it will always be the last field in memory. - let align = align_of_val(&*ptr); - let layout = Layout::new::>(); - (layout.size() + layout.padding_needed_for(align)) as isize + // Align the unsized value to the end of the `ArcInner`. + // Because it is `?Sized`, it will always be the last field in memory. + data_offset_align(align_of_val(&*ptr)) } -/// Computes the offset of the data field within ArcInner. +/// Computes the offset of the data field within `ArcInner`. /// /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. fn data_offset_sized() -> isize { - let align = align_of::(); + data_offset_align(align_of::()) +} + +#[inline] +fn data_offset_align(align: usize) -> isize { let layout = Layout::new::>(); (layout.size() + layout.padding_needed_for(align)) as isize } diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs new file mode 100644 index 0000000000..9220f5e033 --- /dev/null +++ b/src/liballoc/sync/tests.rs @@ -0,0 +1,492 @@ +use super::*; + +use std::boxed::Box; +use std::clone::Clone; +use std::sync::mpsc::channel; +use std::mem::drop; +use std::ops::Drop; +use std::option::Option::{self, None, Some}; +use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; +use std::thread; +use std::sync::Mutex; +use std::convert::{From, TryInto}; + +use crate::vec::Vec; + +struct Canary(*mut atomic::AtomicUsize); + +impl Drop for Canary { + fn drop(&mut self) { + unsafe { + match *self { + Canary(c) => { + (*c).fetch_add(1, SeqCst); + } + } + } + } +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads +fn manually_share_arc() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let arc_v = Arc::new(v); + + let (tx, rx) = channel(); + + let _t = thread::spawn(move || { + let arc_v: Arc> = rx.recv().unwrap(); + assert_eq!((*arc_v)[3], 4); + }); + + tx.send(arc_v.clone()).unwrap(); + + assert_eq!((*arc_v)[2], 3); + assert_eq!((*arc_v)[4], 5); +} + +#[test] +fn test_arc_get_mut() { + let mut x = Arc::new(3); + *Arc::get_mut(&mut x).unwrap() = 4; + assert_eq!(*x, 4); + let y = x.clone(); + assert!(Arc::get_mut(&mut x).is_none()); + drop(y); + assert!(Arc::get_mut(&mut x).is_some()); + let _w = Arc::downgrade(&x); + assert!(Arc::get_mut(&mut x).is_none()); +} + +#[test] +fn weak_counts() { + assert_eq!(Weak::weak_count(&Weak::::new()), None); + assert_eq!(Weak::strong_count(&Weak::::new()), 0); + + let a = Arc::new(0); + let w = Arc::downgrade(&a); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(1)); + let w2 = w.clone(); + assert_eq!(Weak::strong_count(&w), 1); + assert_eq!(Weak::weak_count(&w), Some(2)); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(2)); + drop(w); + assert_eq!(Weak::strong_count(&w2), 1); + assert_eq!(Weak::weak_count(&w2), Some(1)); + let a2 = a.clone(); + assert_eq!(Weak::strong_count(&w2), 2); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(a2); + drop(a); + assert_eq!(Weak::strong_count(&w2), 0); + assert_eq!(Weak::weak_count(&w2), Some(1)); + drop(w2); +} + +#[test] +fn try_unwrap() { + let x = Arc::new(3); + assert_eq!(Arc::try_unwrap(x), Ok(3)); + let x = Arc::new(4); + let _y = x.clone(); + assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4))); + let x = Arc::new(5); + let _w = Arc::downgrade(&x); + assert_eq!(Arc::try_unwrap(x), Ok(5)); +} + +#[test] +fn into_from_raw() { + let x = Arc::new(box "hello"); + let y = x.clone(); + + let x_ptr = Arc::into_raw(x); + drop(y); + unsafe { + assert_eq!(**x_ptr, "hello"); + + let x = Arc::from_raw(x_ptr); + assert_eq!(**x, "hello"); + + assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello")); + } +} + +#[test] +fn test_into_from_raw_unsized() { + use std::fmt::Display; + use std::string::ToString; + + let arc: Arc = Arc::from("foo"); + + let ptr = Arc::into_raw(arc.clone()); + let arc2 = unsafe { Arc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }, "foo"); + assert_eq!(arc, arc2); + + let arc: Arc = Arc::new(123); + + let ptr = Arc::into_raw(arc.clone()); + let arc2 = unsafe { Arc::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }.to_string(), "123"); + assert_eq!(arc2.to_string(), "123"); +} + +#[test] +fn test_cowarc_clone_make_mut() { + let mut cow0 = Arc::new(75); + let mut cow1 = cow0.clone(); + let mut cow2 = cow1.clone(); + + assert!(75 == *Arc::make_mut(&mut cow0)); + assert!(75 == *Arc::make_mut(&mut cow1)); + assert!(75 == *Arc::make_mut(&mut cow2)); + + *Arc::make_mut(&mut cow0) += 1; + *Arc::make_mut(&mut cow1) += 2; + *Arc::make_mut(&mut cow2) += 3; + + assert!(76 == *cow0); + assert!(77 == *cow1); + assert!(78 == *cow2); + + // none should point to the same backing memory + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 != *cow2); +} + +#[test] +fn test_cowarc_clone_unique2() { + let mut cow0 = Arc::new(75); + let cow1 = cow0.clone(); + let cow2 = cow1.clone(); + + assert!(75 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + *Arc::make_mut(&mut cow0) += 1; + assert!(76 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + // cow1 and cow2 should share the same contents + // cow0 should have a unique reference + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 == *cow2); +} + +#[test] +fn test_cowarc_clone_weak() { + let mut cow0 = Arc::new(75); + let cow1_weak = Arc::downgrade(&cow0); + + assert!(75 == *cow0); + assert!(75 == *cow1_weak.upgrade().unwrap()); + + *Arc::make_mut(&mut cow0) += 1; + + assert!(76 == *cow0); + assert!(cow1_weak.upgrade().is_none()); +} + +#[test] +fn test_live() { + let x = Arc::new(5); + let y = Arc::downgrade(&x); + assert!(y.upgrade().is_some()); +} + +#[test] +fn test_dead() { + let x = Arc::new(5); + let y = Arc::downgrade(&x); + drop(x); + assert!(y.upgrade().is_none()); +} + +#[test] +fn weak_self_cyclic() { + struct Cycle { + x: Mutex>>, + } + + let a = Arc::new(Cycle { x: Mutex::new(None) }); + let b = Arc::downgrade(&a.clone()); + *a.x.lock().unwrap() = Some(b); + + // hopefully we don't double-free (or leak)... +} + +#[test] +fn drop_arc() { + let mut canary = atomic::AtomicUsize::new(0); + let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); + drop(x); + assert!(canary.load(Acquire) == 1); +} + +#[test] +fn drop_arc_weak() { + let mut canary = atomic::AtomicUsize::new(0); + let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize)); + let arc_weak = Arc::downgrade(&arc); + assert!(canary.load(Acquire) == 0); + drop(arc); + assert!(canary.load(Acquire) == 1); + drop(arc_weak); +} + +#[test] +fn test_strong_count() { + let a = Arc::new(0); + assert!(Arc::strong_count(&a) == 1); + let w = Arc::downgrade(&a); + assert!(Arc::strong_count(&a) == 1); + let b = w.upgrade().expect(""); + assert!(Arc::strong_count(&b) == 2); + assert!(Arc::strong_count(&a) == 2); + drop(w); + drop(a); + assert!(Arc::strong_count(&b) == 1); + let c = b.clone(); + assert!(Arc::strong_count(&b) == 2); + assert!(Arc::strong_count(&c) == 2); +} + +#[test] +fn test_weak_count() { + let a = Arc::new(0); + assert!(Arc::strong_count(&a) == 1); + assert!(Arc::weak_count(&a) == 0); + let w = Arc::downgrade(&a); + assert!(Arc::strong_count(&a) == 1); + assert!(Arc::weak_count(&a) == 1); + let x = w.clone(); + assert!(Arc::weak_count(&a) == 2); + drop(w); + drop(x); + assert!(Arc::strong_count(&a) == 1); + assert!(Arc::weak_count(&a) == 0); + let c = a.clone(); + assert!(Arc::strong_count(&a) == 2); + assert!(Arc::weak_count(&a) == 0); + let d = Arc::downgrade(&c); + assert!(Arc::weak_count(&c) == 1); + assert!(Arc::strong_count(&c) == 2); + + drop(a); + drop(c); + drop(d); +} + +#[test] +fn show_arc() { + let a = Arc::new(5); + assert_eq!(format!("{:?}", a), "5"); +} + +// Make sure deriving works with Arc +#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)] +struct Foo { + inner: Arc, +} + +#[test] +fn test_unsized() { + let x: Arc<[i32]> = Arc::new([1, 2, 3]); + assert_eq!(format!("{:?}", x), "[1, 2, 3]"); + let y = Arc::downgrade(&x.clone()); + drop(x); + assert!(y.upgrade().is_none()); +} + +#[test] +fn test_from_owned() { + let foo = 123; + let foo_arc = Arc::from(foo); + assert!(123 == *foo_arc); +} + +#[test] +fn test_new_weak() { + let foo: Weak = Weak::new(); + assert!(foo.upgrade().is_none()); +} + +#[test] +fn test_ptr_eq() { + let five = Arc::new(5); + let same_five = five.clone(); + let other_five = Arc::new(5); + + assert!(Arc::ptr_eq(&five, &same_five)); + assert!(!Arc::ptr_eq(&five, &other_five)); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads +fn test_weak_count_locked() { + let mut a = Arc::new(atomic::AtomicBool::new(false)); + let a2 = a.clone(); + let t = thread::spawn(move || { + for _i in 0..1000000 { + Arc::get_mut(&mut a); + } + a.store(true, SeqCst); + }); + + while !a2.load(SeqCst) { + let n = Arc::weak_count(&a2); + assert!(n < 2, "bad weak count: {}", n); + } + t.join().unwrap(); +} + +#[test] +fn test_from_str() { + let r: Arc = Arc::from("foo"); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_copy_from_slice() { + let s: &[u32] = &[1, 2, 3]; + let r: Arc<[u32]> = Arc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_clone_from_slice() { + #[derive(Clone, Debug, Eq, PartialEq)] + struct X(u32); + + let s: &[X] = &[X(1), X(2), X(3)]; + let r: Arc<[X]> = Arc::from(s); + + assert_eq!(&r[..], s); +} + +#[test] +#[should_panic] +fn test_clone_from_slice_panic() { + use std::string::{String, ToString}; + + struct Fail(u32, String); + + impl Clone for Fail { + fn clone(&self) -> Fail { + if self.0 == 2 { + panic!(); + } + Fail(self.0, self.1.clone()) + } + } + + let s: &[Fail] = &[ + Fail(0, "foo".to_string()), + Fail(1, "bar".to_string()), + Fail(2, "baz".to_string()), + ]; + + // Should panic, but not cause memory corruption + let _r: Arc<[Fail]> = Arc::from(s); +} + +#[test] +fn test_from_box() { + let b: Box = box 123; + let r: Arc = Arc::from(b); + + assert_eq!(*r, 123); +} + +#[test] +fn test_from_box_str() { + use std::string::String; + + let s = String::from("foo").into_boxed_str(); + let r: Arc = Arc::from(s); + + assert_eq!(&r[..], "foo"); +} + +#[test] +fn test_from_box_slice() { + let s = vec![1, 2, 3].into_boxed_slice(); + let r: Arc<[u32]> = Arc::from(s); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_from_box_trait() { + use std::fmt::Display; + use std::string::ToString; + + let b: Box = box 123; + let r: Arc = Arc::from(b); + + assert_eq!(r.to_string(), "123"); +} + +#[test] +fn test_from_box_trait_zero_sized() { + use std::fmt::Debug; + + let b: Box = box (); + let r: Arc = Arc::from(b); + + assert_eq!(format!("{:?}", r), "()"); +} + +#[test] +fn test_from_vec() { + let v = vec![1, 2, 3]; + let r: Arc<[u32]> = Arc::from(v); + + assert_eq!(&r[..], [1, 2, 3]); +} + +#[test] +fn test_downcast() { + use std::any::Any; + + let r1: Arc = Arc::new(i32::max_value()); + let r2: Arc = Arc::new("abc"); + + assert!(r1.clone().downcast::().is_err()); + + let r1i32 = r1.downcast::(); + assert!(r1i32.is_ok()); + assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value())); + + assert!(r2.clone().downcast::().is_err()); + + let r2str = r2.downcast::<&'static str>(); + assert!(r2str.is_ok()); + assert_eq!(r2str.unwrap(), Arc::new("abc")); +} + +#[test] +fn test_array_from_slice() { + let v = vec![1, 2, 3]; + let r: Arc<[u32]> = Arc::from(v); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_ok()); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_err()); +} diff --git a/src/liballoc/tests.rs b/src/liballoc/tests.rs index 654eabd070..ed46ba8a1b 100644 --- a/src/liballoc/tests.rs +++ b/src/liballoc/tests.rs @@ -1,6 +1,7 @@ //! Test for `boxed` mod. use core::any::Any; +use core::convert::TryInto; use core::ops::Deref; use core::result::Result::{Err, Ok}; use core::clone::Clone; @@ -138,3 +139,15 @@ fn boxed_slice_from_iter() { assert_eq!(boxed.len(), 100); assert_eq!(boxed[7], 7); } + +#[test] +fn test_array_from_slice() { + let v = vec![1, 2, 3]; + let r: Box<[u32]> = v.into_boxed_slice(); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_ok()); + + let a: Result, _> = r.clone().try_into(); + assert!(a.is_err()); +} diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index 2759b1b1ca..cf2ad2a8e6 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -2,6 +2,8 @@ use std::any::Any; use std::sync::{Arc, Weak}; use std::cell::RefCell; use std::cmp::PartialEq; +use std::iter::TrustedLen; +use std::mem; #[test] fn uninhabited() { @@ -85,3 +87,122 @@ fn eq() { assert!(!(x != x)); assert_eq!(*x.0.borrow(), 0); } + +// The test code below is identical to that in `rc.rs`. +// For better maintainability we therefore define this type alias. +type Rc = Arc; + +const SHARED_ITER_MAX: u16 = 100; + +fn assert_trusted_len(_: &I) {} + +#[test] +fn shared_from_iter_normal() { + // Exercise the base implementation for non-`TrustedLen` iterators. + { + // `Filter` is never `TrustedLen` since we don't + // know statically how many elements will be kept: + let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. +} + +#[test] +fn shared_from_iter_trustedlen_normal() { + // Exercise the `TrustedLen` implementation under normal circumstances + // where `size_hint()` matches `(_, Some(exact_len))`. + { + let iter = (0..SHARED_ITER_MAX).map(Box::new); + assert_trusted_len(&iter); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(mem::size_of::>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. + + // Try a ZST to make sure it is handled well. + { + let iter = (0..SHARED_ITER_MAX).map(|_| ()); + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(0, mem::size_of_val(&*rc)); + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } +} + +#[test] +#[should_panic = "I've almost got 99 problems."] +fn shared_from_iter_trustedlen_panic() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where `.next()` drops before the last iteration. + let iter = (0..SHARED_ITER_MAX) + .map(|val| { + match val { + 98 => panic!("I've almost got 99 problems."), + _ => Box::new(val), + } + }); + assert_trusted_len(&iter); + let _ = iter.collect::>(); + + panic!("I am unreachable."); +} + +#[test] +fn shared_from_iter_trustedlen_no_fuse() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner. + struct Iter(std::vec::IntoIter>>); + + unsafe impl TrustedLen for Iter {} + + impl Iterator for Iter { + fn size_hint(&self) -> (usize, Option) { + (2, Some(2)) + } + + type Item = Box; + + fn next(&mut self) -> Option { + self.0.next().flatten() + } + } + + let vec = vec![ + Some(Box::new(42)), + Some(Box::new(24)), + None, + Some(Box::new(12)), + ]; + let iter = Iter(vec.into_iter()); + assert_trusted_len(&iter); + assert_eq!( + &[Box::new(42), Box::new(24)], + &*iter.collect::>() + ); +} diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 844afe8707..266a0d055d 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -689,7 +689,10 @@ fn test_split_off_empty_left() { #[test] fn test_split_off_large_random_sorted() { + #[cfg(not(miri))] // Miri is too slow let mut data = rand_data(1529); + #[cfg(miri)] + let mut data = rand_data(529); // special case with maximum height. data.sort(); diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index 989beb3b1b..62ccb53fce 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -10,7 +10,7 @@ fn test_clone_eq() { m.insert(1); m.insert(2); - assert!(m.clone() == m); + assert_eq!(m.clone(), m); } #[test] @@ -28,7 +28,7 @@ fn test_hash() { y.insert(2); y.insert(1); - assert!(hash(&x) == hash(&y)); + assert_eq!(hash(&x), hash(&y)); } fn check(a: &[i32], b: &[i32], expected: &[i32], f: F) @@ -69,6 +69,11 @@ fn test_intersection() { check_intersection(&[11, 1, 3, 77, 103, 5, -5], &[2, 11, 77, -9, -42, 5, 3], &[3, 5, 11, 77]); + + if cfg!(miri) { // Miri is too slow + return; + } + let large = (0..1000).collect::>(); check_intersection(&[], &large, &[]); check_intersection(&large, &[], &[]); @@ -98,6 +103,11 @@ fn test_difference() { check_difference(&[-5, 11, 22, 33, 40, 42], &[-12, -5, 14, 23, 34, 38, 39, 50], &[11, 22, 33, 40, 42]); + + if cfg!(miri) { // Miri is too slow + return; + } + let large = (0..1000).collect::>(); check_difference(&[], &large, &[]); check_difference(&[-1], &large, &[-1]); @@ -166,6 +176,17 @@ fn test_is_subset() { assert_eq!(is_subset(&[1, 2], &[1]), false); assert_eq!(is_subset(&[1, 2], &[1, 2]), true); assert_eq!(is_subset(&[1, 2], &[2, 3]), false); + assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42], + &[-12, -5, 14, 23, 11, 34, 22, 38, 33, 42, 39, 40]), + true); + assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42], + &[-12, -5, 14, 23, 34, 38, 22, 11]), + false); + + if cfg!(miri) { // Miri is too slow + return; + } + let large = (0..1000).collect::>(); assert_eq!(is_subset(&[], &large), true); assert_eq!(is_subset(&large, &[]), false); @@ -371,7 +392,10 @@ fn test_split_off_empty_left() { #[test] fn test_split_off_large_random_sorted() { + #[cfg(not(miri))] // Miri is too slow let mut data = rand_data(1529); + #[cfg(miri)] + let mut data = rand_data(529); // special case with maximum height. data.sort(); diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs index c225ebfa96..904b3e7e1b 100644 --- a/src/liballoc/tests/heap.rs +++ b/src/liballoc/tests/heap.rs @@ -1,6 +1,6 @@ use std::alloc::{Global, Alloc, Layout, System}; -/// Issue #45955. +/// Issue #45955 and #62251. #[test] fn alloc_system_overaligned_request() { check_overalign_requests(System) @@ -12,21 +12,23 @@ fn std_heap_overaligned_request() { } fn check_overalign_requests(mut allocator: T) { - let size = 8; - let align = 16; // greater than size - let iterations = 100; - unsafe { - let pointers: Vec<_> = (0..iterations).map(|_| { - allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() - }).collect(); - for &ptr in &pointers { - assert_eq!((ptr.as_ptr() as usize) % align, 0, - "Got a pointer less aligned than requested") - } + for &align in &[4, 8, 16, 32] { // less than and bigger than `MIN_ALIGN` + for &size in &[align/2, align-1] { // size less than alignment + let iterations = 128; + unsafe { + let pointers: Vec<_> = (0..iterations).map(|_| { + allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() + }).collect(); + for &ptr in &pointers { + assert_eq!((ptr.as_ptr() as usize) % align, 0, + "Got a pointer less aligned than requested") + } - // Clean up - for &ptr in &pointers { - allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) + // Clean up + for &ptr in &pointers { + allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) + } + } } } } diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index ddb3120e89..5723a30c0f 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -2,11 +2,13 @@ #![feature(box_syntax)] #![feature(drain_filter)] #![feature(exact_size_is_empty)] +#![feature(option_flattening)] #![feature(pattern)] #![feature(repeat_generic_slice)] +#![feature(trusted_len)] #![feature(try_reserve)] #![feature(unboxed_closures)] -#![deny(rust_2018_idioms)] +#![feature(associated_type_bounds)] use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; diff --git a/src/liballoc/tests/linked_list.rs b/src/liballoc/tests/linked_list.rs index 0fbfbdccd4..8a26454c38 100644 --- a/src/liballoc/tests/linked_list.rs +++ b/src/liballoc/tests/linked_list.rs @@ -40,12 +40,10 @@ fn test_basic() { assert_eq!(n.pop_front(), Some(1)); } -#[cfg(test)] fn generate_test() -> LinkedList { list_from(&[0, 1, 2, 3, 4, 5, 6]) } -#[cfg(test)] fn list_from(v: &[T]) -> LinkedList { v.iter().cloned().collect() } diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index 18f82e8041..7854ca0fc1 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -2,6 +2,8 @@ use std::any::Any; use std::rc::{Rc, Weak}; use std::cell::RefCell; use std::cmp::PartialEq; +use std::mem; +use std::iter::TrustedLen; #[test] fn uninhabited() { @@ -85,3 +87,118 @@ fn eq() { assert!(!(x != x)); assert_eq!(*x.0.borrow(), 0); } + +const SHARED_ITER_MAX: u16 = 100; + +fn assert_trusted_len(_: &I) {} + +#[test] +fn shared_from_iter_normal() { + // Exercise the base implementation for non-`TrustedLen` iterators. + { + // `Filter` is never `TrustedLen` since we don't + // know statically how many elements will be kept: + let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. +} + +#[test] +fn shared_from_iter_trustedlen_normal() { + // Exercise the `TrustedLen` implementation under normal circumstances + // where `size_hint()` matches `(_, Some(exact_len))`. + { + let iter = (0..SHARED_ITER_MAX).map(Box::new); + assert_trusted_len(&iter); + + // Collecting into a `Vec` or `Rc<[T]>` should make no difference: + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(mem::size_of::>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); + + // Clone a bit and let these get dropped. + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } // Drop what hasn't been here. + + // Try a ZST to make sure it is handled well. + { + let iter = (0..SHARED_ITER_MAX).map(|_| ()); + let vec = iter.clone().collect::>(); + let rc = iter.collect::>(); + assert_eq!(&*vec, &*rc); + assert_eq!(0, mem::size_of_val(&*rc)); + { + let _rc_2 = rc.clone(); + let _rc_3 = rc.clone(); + let _rc_4 = Rc::downgrade(&_rc_3); + } + } +} + +#[test] +#[should_panic = "I've almost got 99 problems."] +fn shared_from_iter_trustedlen_panic() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where `.next()` drops before the last iteration. + let iter = (0..SHARED_ITER_MAX) + .map(|val| { + match val { + 98 => panic!("I've almost got 99 problems."), + _ => Box::new(val), + } + }); + assert_trusted_len(&iter); + let _ = iter.collect::>(); + + panic!("I am unreachable."); +} + +#[test] +fn shared_from_iter_trustedlen_no_fuse() { + // Exercise the `TrustedLen` implementation when `size_hint()` matches + // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner. + struct Iter(std::vec::IntoIter>>); + + unsafe impl TrustedLen for Iter {} + + impl Iterator for Iter { + fn size_hint(&self) -> (usize, Option) { + (2, Some(2)) + } + + type Item = Box; + + fn next(&mut self) -> Option { + self.0.next().flatten() + } + } + + let vec = vec![ + Some(Box::new(42)), + Some(Box::new(24)), + None, + Some(Box::new(12)), + ]; + let iter = Iter(vec.into_iter()); + assert_trusted_len(&iter); + assert_eq!( + &[Box::new(42), Box::new(24)], + &*iter.collect::>() + ); +} diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b197516403..4332b2e90f 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -1108,6 +1108,16 @@ fn test_iterator_last() { assert_eq!(it.last(), Some('m')); } +#[test] +fn test_chars_debug() { + let s = "ศไทย中华Việt Nam"; + let c = s.chars(); + assert_eq!( + format!("{:?}", c), + r#"Chars(['ศ', 'ไ', 'ท', 'ย', '中', '华', 'V', 'i', 'ệ', 't', ' ', 'N', 'a', 'm'])"# + ); +} + #[test] fn test_bytesator() { let s = "ศไทย中华Việt Nam"; @@ -1628,10 +1638,12 @@ mod pattern { } } - fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str, - right: Vec) - where P::Searcher: ReverseSearcher<'a> - { + fn cmp_search_to_vec<'a>( + rev: bool, + pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>, + haystack: &'a str, + right: Vec + ) { let mut searcher = pat.into_searcher(haystack); let mut v = vec![]; loop { diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 5ddac673c9..6e8ffe1852 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -761,7 +761,6 @@ fn from_into_inner() { it.next().unwrap(); let vec = it.collect::>(); assert_eq!(vec, [2, 3]); - #[cfg(not(miri))] // Miri does not support comparing dangling pointers assert!(ptr != vec.as_ptr()); } @@ -945,6 +944,115 @@ fn drain_filter_complex() { } } +#[test] +#[cfg(not(miri))] // Miri does not support catching panics +fn drain_filter_consumed_panic() { + use std::rc::Rc; + use std::sync::Mutex; + + struct Check { + index: usize, + drop_counts: Rc>>, + }; + + impl Drop for Check { + fn drop(&mut self) { + self.drop_counts.lock().unwrap()[self.index] += 1; + println!("drop: {}", self.index); + } + } + + let check_count = 10; + let drop_counts = Rc::new(Mutex::new(vec![0_usize; check_count])); + let mut data: Vec = (0..check_count) + .map(|index| Check { index, drop_counts: Rc::clone(&drop_counts) }) + .collect(); + + let _ = std::panic::catch_unwind(move || { + let filter = |c: &mut Check| { + if c.index == 2 { + panic!("panic at index: {}", c.index); + } + // Verify that if the filter could panic again on another element + // that it would not cause a double panic and all elements of the + // vec would still be dropped exactly once. + if c.index == 4 { + panic!("panic at index: {}", c.index); + } + c.index < 6 + }; + let drain = data.drain_filter(filter); + + // NOTE: The DrainFilter is explictly consumed + drain.for_each(drop); + }); + + let drop_counts = drop_counts.lock().unwrap(); + assert_eq!(check_count, drop_counts.len()); + + for (index, count) in drop_counts.iter().cloned().enumerate() { + assert_eq!(1, count, "unexpected drop count at index: {} (count: {})", index, count); + } +} + +#[test] +#[cfg(not(miri))] // Miri does not support catching panics +fn drain_filter_unconsumed_panic() { + use std::rc::Rc; + use std::sync::Mutex; + + struct Check { + index: usize, + drop_counts: Rc>>, + }; + + impl Drop for Check { + fn drop(&mut self) { + self.drop_counts.lock().unwrap()[self.index] += 1; + println!("drop: {}", self.index); + } + } + + let check_count = 10; + let drop_counts = Rc::new(Mutex::new(vec![0_usize; check_count])); + let mut data: Vec = (0..check_count) + .map(|index| Check { index, drop_counts: Rc::clone(&drop_counts) }) + .collect(); + + let _ = std::panic::catch_unwind(move || { + let filter = |c: &mut Check| { + if c.index == 2 { + panic!("panic at index: {}", c.index); + } + // Verify that if the filter could panic again on another element + // that it would not cause a double panic and all elements of the + // vec would still be dropped exactly once. + if c.index == 4 { + panic!("panic at index: {}", c.index); + } + c.index < 6 + }; + let _drain = data.drain_filter(filter); + + // NOTE: The DrainFilter is dropped without being consumed + }); + + let drop_counts = drop_counts.lock().unwrap(); + assert_eq!(check_count, drop_counts.len()); + + for (index, count) in drop_counts.iter().cloned().enumerate() { + assert_eq!(1, count, "unexpected drop count at index: {} (count: {})", index, count); + } +} + +#[test] +fn drain_filter_unconsumed() { + let mut vec = vec![1, 2, 3, 4]; + let drain = vec.drain_filter(|&mut x| x % 2 != 0); + drop(drain); + assert_eq!(vec, [2, 4]); +} + #[test] fn test_reserve_exact() { // This is all the same as test_reserve diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index e0fe10a55f..1bbcca97b3 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -44,7 +44,6 @@ fn test_simple() { assert_eq!(d[3], 4); } -#[cfg(test)] fn test_parameterized(a: T, b: T, c: T, d: T) { let mut deq = VecDeque::new(); assert_eq!(deq.len(), 0); diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 92fe0834dd..dac04e4e62 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -56,6 +56,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use core::array::LengthAtMost32; use core::cmp::{self, Ordering}; use core::fmt; use core::hash::{self, Hash}; @@ -432,7 +433,7 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn capacity(&self) -> usize { - self.buf.cap() + self.buf.capacity() } /// Reserves capacity for at least `additional` more elements to be inserted @@ -947,7 +948,7 @@ impl Vec { assert!(index <= len); // space for the new element - if len == self.buf.cap() { + if len == self.buf.capacity() { self.reserve(1); } @@ -1098,7 +1099,7 @@ impl Vec { pub fn push(&mut self, value: T) { // This will panic or abort if we would allocate > isize::MAX bytes // or if the length increment would overflow for zero-sized types. - if self.len == self.buf.cap() { + if self.len == self.buf.capacity() { self.reserve(1); } unsafe { @@ -1367,6 +1368,40 @@ impl Vec { self.truncate(new_len); } } + + /// Consumes and leaks the `Vec`, returning a mutable reference to the contents, + /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime + /// `'a`. If the type has only static references, or none at all, then this + /// may be chosen to be `'static`. + /// + /// This function is similar to the `leak` function on `Box`. + /// + /// This function is mainly useful for data that lives for the remainder of + /// the program's life. Dropping the returned reference will cause a memory + /// leak. + /// + /// # Examples + /// + /// Simple usage: + /// + /// ``` + /// #![feature(vec_leak)] + /// + /// fn main() { + /// let x = vec![1, 2, 3]; + /// let static_ref: &'static mut [usize] = Vec::leak(x); + /// static_ref[0] += 1; + /// assert_eq!(static_ref, &[2, 2, 3]); + /// } + /// ``` + #[unstable(feature = "vec_leak", issue = "62195")] + #[inline] + pub fn leak<'a>(vec: Vec) -> &'a mut [T] + where + T: 'a // Technically not needed, but kept to be explicit. + { + Box::leak(vec.into_boxed_slice()) + } } impl Vec { @@ -1824,7 +1859,7 @@ impl IntoIterator for Vec { } else { begin.add(self.len()) as *const T }; - let cap = self.buf.cap(); + let cap = self.buf.capacity(); mem::forget(self); IntoIter { buf: NonNull::new_unchecked(begin), @@ -2118,6 +2153,7 @@ impl Vec { del: 0, old_len, pred: filter, + panic_flag: false, } } } @@ -2136,47 +2172,36 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for Vec { } macro_rules! __impl_slice_eq1 { - ($Lhs: ty, $Rhs: ty) => { - __impl_slice_eq1! { $Lhs, $Rhs, Sized } - }; - ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => { #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { + impl PartialEq<$rhs> for $lhs + where + A: PartialEq, + $($constraints)* + { #[inline] - fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } + fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } #[inline] - fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } + fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] } } } } -__impl_slice_eq1! { Vec, Vec } -__impl_slice_eq1! { Vec, &'b [B] } -__impl_slice_eq1! { Vec, &'b mut [B] } -__impl_slice_eq1! { Cow<'a, [A]>, &'b [B], Clone } -__impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B], Clone } -__impl_slice_eq1! { Cow<'a, [A]>, Vec, Clone } - -macro_rules! array_impls { - ($($N: expr)+) => { - $( - // NOTE: some less important impls are omitted to reduce code bloat - __impl_slice_eq1! { Vec, [B; $N] } - __impl_slice_eq1! { Vec, &'b [B; $N] } - // __impl_slice_eq1! { Vec, &'b mut [B; $N] } - // __impl_slice_eq1! { Cow<'a, [A]>, [B; $N], Clone } - // __impl_slice_eq1! { Cow<'a, [A]>, &'b [B; $N], Clone } - // __impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B; $N], Clone } - )+ - } -} +__impl_slice_eq1! { [] Vec, Vec, } +__impl_slice_eq1! { [] Vec, &[B], } +__impl_slice_eq1! { [] Vec, &mut [B], } +__impl_slice_eq1! { [] Cow<'_, [A]>, &[B], A: Clone } +__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B], A: Clone } +__impl_slice_eq1! { [] Cow<'_, [A]>, Vec, A: Clone } +__impl_slice_eq1! { [const N: usize] Vec, [B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] Vec, &[B; N], [B; N]: LengthAtMost32 } -array_impls! { - 0 1 2 3 4 5 6 7 8 9 - 10 11 12 13 14 15 16 17 18 19 - 20 21 22 23 24 25 26 27 28 29 - 30 31 32 -} +// NOTE: some less important impls are omitted to reduce code bloat +// FIXME(Centril): Reconsider this? +//__impl_slice_eq1! { [const N: usize] Vec, &mut [B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], [B; N]: LengthAtMost32 } /// Implements comparison of vectors, lexicographically. #[stable(feature = "rust1", since = "1.0.0")] @@ -2745,10 +2770,20 @@ pub struct DrainFilter<'a, T, F> where F: FnMut(&mut T) -> bool, { vec: &'a mut Vec, + /// The index of the item that will be inspected by the next call to `next`. idx: usize, + /// The number of items that have been drained (removed) thus far. del: usize, + /// The original length of `vec` prior to draining. old_len: usize, + /// The filter test predicate. pred: F, + /// A flag that indicates a panic has occured in the filter test prodicate. + /// This is used as a hint in the drop implmentation to prevent consumption + /// of the remainder of the `DrainFilter`. Any unprocessed items will be + /// backshifted in the `vec`, but no further items will be dropped or + /// tested by the filter predicate. + panic_flag: bool, } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] @@ -2759,20 +2794,23 @@ impl Iterator for DrainFilter<'_, T, F> fn next(&mut self) -> Option { unsafe { - while self.idx != self.old_len { + while self.idx < self.old_len { let i = self.idx; - self.idx += 1; let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); - if (self.pred)(&mut v[i]) { + self.panic_flag = true; + let drained = (self.pred)(&mut v[i]); + self.panic_flag = false; + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; + if drained { self.del += 1; return Some(ptr::read(&v[i])); } else if self.del > 0 { let del = self.del; let src: *const T = &v[i]; let dst: *mut T = &mut v[i - del]; - // This is safe because self.vec has length 0 - // thus its elements will not have Drop::drop - // called on them in the event of a panic. ptr::copy_nonoverlapping(src, dst, 1); } } @@ -2790,9 +2828,46 @@ impl Drop for DrainFilter<'_, T, F> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - self.for_each(drop); - unsafe { - self.vec.set_len(self.old_len - self.del); + struct BackshiftOnDrop<'a, 'b, T, F> + where + F: FnMut(&mut T) -> bool, + { + drain: &'b mut DrainFilter<'a, T, F>, + } + + impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F> + where + F: FnMut(&mut T) -> bool + { + fn drop(&mut self) { + unsafe { + if self.drain.idx < self.drain.old_len && self.drain.del > 0 { + // This is a pretty messed up state, and there isn't really an + // obviously right thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the unprocessed + // elements and tell the vec that they still exist. The backshift + // is required to prevent a double-drop of the last successfully + // drained item prior to a panic in the predicate. + let ptr = self.drain.vec.as_mut_ptr(); + let src = ptr.add(self.drain.idx); + let dst = src.sub(self.drain.del); + let tail_len = self.drain.old_len - self.drain.idx; + src.copy_to(dst, tail_len); + } + self.drain.vec.set_len(self.drain.old_len - self.drain.del); + } + } + } + + let backshift = BackshiftOnDrop { + drain: self + }; + + // Attempt to consume any remaining elements if the filter predicate + // has not yet panicked. We'll backshift any remaining elements + // whether we've already panicked or if the consumption here panics. + if !backshift.drain.panic_flag { + backshift.drain.for_each(drop); } } } diff --git a/src/libarena/Cargo.toml b/src/libarena/Cargo.toml index aa1bf38b99..2643912f6d 100644 --- a/src/libarena/Cargo.toml +++ b/src/libarena/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [lib] name = "arena" path = "lib.rs" -crate-type = ["dylib"] [dependencies] rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 3d16e335cd..690d8344ac 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -11,10 +11,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(no_crate_inject, attr(deny(warnings))))] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(raw_vec_internals)] @@ -100,7 +96,7 @@ impl TypedArenaChunk { // A pointer as large as possible for zero-sized elements. !0 as *mut T } else { - self.start().add(self.storage.cap()) + self.start().add(self.storage.capacity()) } } } @@ -271,7 +267,7 @@ impl TypedArena { self.end.set(last_chunk.end()); return; } else { - new_capacity = last_chunk.storage.cap(); + new_capacity = last_chunk.storage.capacity(); loop { new_capacity = new_capacity.checked_mul(2).unwrap(); if new_capacity >= currently_used_cap + n { @@ -406,7 +402,7 @@ impl DroplessArena { self.end.set(last_chunk.end()); return; } else { - new_capacity = last_chunk.storage.cap(); + new_capacity = last_chunk.storage.capacity(); loop { new_capacity = new_capacity.checked_mul(2).unwrap(); if new_capacity >= used_bytes + needed_bytes { diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml index ede5fff5f4..ac07ffb14f 100644 --- a/src/libcore/Cargo.toml +++ b/src/libcore/Cargo.toml @@ -21,7 +21,7 @@ name = "corebenches" path = "../libcore/benches/lib.rs" [dev-dependencies] -rand = "0.6" +rand = "0.7" [features] # Make panics and failed asserts immediately abort without formatting any message diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index f25631e028..5d0333d522 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -359,9 +359,12 @@ impl fmt::Display for AllocErr { } } -/// The `CannotReallocInPlace` error is used when `grow_in_place` or -/// `shrink_in_place` were unable to reuse the given memory block for +/// The `CannotReallocInPlace` error is used when [`grow_in_place`] or +/// [`shrink_in_place`] were unable to reuse the given memory block for /// a requested layout. +/// +/// [`grow_in_place`]: ./trait.Alloc.html#method.grow_in_place +/// [`shrink_in_place`]: ./trait.Alloc.html#method.shrink_in_place #[unstable(feature = "allocator_api", issue = "32838")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct CannotReallocInPlace; @@ -824,11 +827,11 @@ pub unsafe trait Alloc { let old_size = layout.size(); if new_size >= old_size { - if let Ok(()) = self.grow_in_place(ptr, layout.clone(), new_size) { + if let Ok(()) = self.grow_in_place(ptr, layout, new_size) { return Ok(ptr); } } else if new_size < old_size { - if let Ok(()) = self.shrink_in_place(ptr, layout.clone(), new_size) { + if let Ok(()) = self.shrink_in_place(ptr, layout, new_size) { return Ok(ptr); } } diff --git a/src/libcore/any.rs b/src/libcore/any.rs index d043ce34ef..078091a9b5 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -450,3 +450,30 @@ impl TypeId { } } } + +/// Returns the name of a type as a string slice. +/// +/// # Note +/// +/// This is intended for diagnostic use. The exact contents and format of the +/// string are not specified, other than being a best-effort description of the +/// type. For example, `type_name::>()` could return the +/// `"Option"` or `"std::option::Option"`, but not +/// `"foobar"`. In addition, the output may change between versions of the +/// compiler. +/// +/// The type name should not be considered a unique identifier of a type; +/// multiple types may share the same type name. +/// +/// The current implementation uses the same infrastructure as compiler +/// diagnostics and debuginfo, but this is not guaranteed. +#[stable(feature = "type_name", since = "1.38.0")] +#[rustc_const_unstable(feature = "const_type_name")] +pub const fn type_name() -> &'static str { + #[cfg(bootstrap)] + unsafe { + intrinsics::type_name::() + } + #[cfg(not(bootstrap))] + intrinsics::type_name::() +} diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 03094bfd33..b5614010e5 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -24,9 +24,12 @@ use crate::slice::{Iter, IterMut}; /// layout in memory of a fixed size array (for example, for unsafe /// initialization). /// -/// Note that the traits AsRef and AsMut provide similar methods for types that +/// Note that the traits [`AsRef`] and [`AsMut`] provide similar methods for types that /// may not be fixed-size arrays. Implementors should prefer those traits /// instead. +/// +/// [`AsRef`]: ../convert/trait.AsRef.html +/// [`AsMut`]: ../convert/trait.AsMut.html #[unstable(feature = "fixed_size_array", issue = "27778")] pub unsafe trait FixedSizeArray { /// Converts the array to immutable slice @@ -81,185 +84,312 @@ impl From for TryFromSliceError { } } -macro_rules! __impl_slice_eq1 { - ($Lhs: ty, $Rhs: ty) => { - __impl_slice_eq1! { $Lhs, $Rhs, Sized } - }; - ($Lhs: ty, $Rhs: ty, $Bound: ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { - #[inline] - fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } - #[inline] - fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRef<[T]> for [T; N] +where + [T; N]: LengthAtMost32, +{ + #[inline] + fn as_ref(&self) -> &[T] { + &self[..] + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsMut<[T]> for [T; N] +where + [T; N]: LengthAtMost32, +{ + #[inline] + fn as_mut(&mut self) -> &mut [T] { + &mut self[..] + } +} + +#[stable(feature = "array_borrow", since = "1.4.0")] +impl Borrow<[T]> for [T; N] +where + [T; N]: LengthAtMost32, +{ + fn borrow(&self) -> &[T] { + self + } +} + +#[stable(feature = "array_borrow", since = "1.4.0")] +impl BorrowMut<[T]> for [T; N] +where + [T; N]: LengthAtMost32, +{ + fn borrow_mut(&mut self) -> &mut [T] { + self + } +} + +#[stable(feature = "try_from", since = "1.34.0")] +impl TryFrom<&[T]> for [T; N] +where + T: Copy, + [T; N]: LengthAtMost32, +{ + type Error = TryFromSliceError; + + fn try_from(slice: &[T]) -> Result<[T; N], TryFromSliceError> { + <&Self>::try_from(slice).map(|r| *r) + } +} + +#[stable(feature = "try_from", since = "1.34.0")] +impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] +where + [T; N]: LengthAtMost32, +{ + type Error = TryFromSliceError; + + fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> { + if slice.len() == N { + let ptr = slice.as_ptr() as *const [T; N]; + unsafe { Ok(&*ptr) } + } else { + Err(TryFromSliceError(())) } } } -macro_rules! __impl_slice_eq2 { - ($Lhs: ty, $Rhs: ty) => { - __impl_slice_eq2! { $Lhs, $Rhs, Sized } - }; - ($Lhs: ty, $Rhs: ty, $Bound: ident) => { - __impl_slice_eq1!($Lhs, $Rhs, $Bound); - - #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq { - #[inline] - fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] } - #[inline] - fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] } +#[stable(feature = "try_from", since = "1.34.0")] +impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] +where + [T; N]: LengthAtMost32, +{ + type Error = TryFromSliceError; + + fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> { + if slice.len() == N { + let ptr = slice.as_mut_ptr() as *mut [T; N]; + unsafe { Ok(&mut *ptr) } + } else { + Err(TryFromSliceError(())) } } } -// macro for implementing n-element array functions and operations -macro_rules! array_impls { - ($($N:expr)+) => { - $( - #[stable(feature = "rust1", since = "1.0.0")] - impl AsRef<[T]> for [T; $N] { - #[inline] - fn as_ref(&self) -> &[T] { - &self[..] - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for [T; N] +where + [T; N]: LengthAtMost32, +{ + fn hash(&self, state: &mut H) { + Hash::hash(&self[..], state) + } +} - #[stable(feature = "rust1", since = "1.0.0")] - impl AsMut<[T]> for [T; $N] { - #[inline] - fn as_mut(&mut self) -> &mut [T] { - &mut self[..] - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for [T; N] +where + [T; N]: LengthAtMost32, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&&self[..], f) + } +} - #[stable(feature = "array_borrow", since = "1.4.0")] - impl Borrow<[T]> for [T; $N] { - fn borrow(&self) -> &[T] { - self - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, const N: usize> IntoIterator for &'a [T; N] +where + [T; N]: LengthAtMost32, +{ + type Item = &'a T; + type IntoIter = Iter<'a, T>; - #[stable(feature = "array_borrow", since = "1.4.0")] - impl BorrowMut<[T]> for [T; $N] { - fn borrow_mut(&mut self) -> &mut [T] { - self - } - } + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} - #[stable(feature = "try_from", since = "1.34.0")] - impl TryFrom<&[T]> for [T; $N] where T: Copy { - type Error = TryFromSliceError; +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] +where + [T; N]: LengthAtMost32, +{ + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; - fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> { - <&Self>::try_from(slice).map(|r| *r) - } - } + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} - #[stable(feature = "try_from", since = "1.34.0")] - impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] { - type Error = TryFromSliceError; - - fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> { - if slice.len() == $N { - let ptr = slice.as_ptr() as *const [T; $N]; - unsafe { Ok(&*ptr) } - } else { - Err(TryFromSliceError(())) - } - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq<[B; N]> for [A; N] +where + A: PartialEq, + [A; N]: LengthAtMost32, + [B; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &[B; N]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &[B; N]) -> bool { + self[..] != other[..] + } +} - #[stable(feature = "try_from", since = "1.34.0")] - impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] { - type Error = TryFromSliceError; - - fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> { - if slice.len() == $N { - let ptr = slice.as_mut_ptr() as *mut [T; $N]; - unsafe { Ok(&mut *ptr) } - } else { - Err(TryFromSliceError(())) - } - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq<[B]> for [A; N] +where + A: PartialEq, + [A; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &[B]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &[B]) -> bool { + self[..] != other[..] + } +} - #[stable(feature = "rust1", since = "1.0.0")] - impl Hash for [T; $N] { - fn hash(&self, state: &mut H) { - Hash::hash(&self[..], state) - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq<[A; N]> for [B] +where + B: PartialEq, + [A; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &[A; N]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &[A; N]) -> bool { + self[..] != other[..] + } +} - #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Debug for [T; $N] { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&&self[..], f) - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N] +where + A: PartialEq, + [A; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &&'b [B]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &&'b [B]) -> bool { + self[..] != other[..] + } +} - #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, T> IntoIterator for &'a [T; $N] { - type Item = &'a T; - type IntoIter = Iter<'a, T>; +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B] +where + B: PartialEq, + [A; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &[A; N]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &[A; N]) -> bool { + self[..] != other[..] + } +} - fn into_iter(self) -> Iter<'a, T> { - self.iter() - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N] +where + A: PartialEq, + [A; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &&'b mut [B]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &&'b mut [B]) -> bool { + self[..] != other[..] + } +} - #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, T> IntoIterator for &'a mut [T; $N] { - type Item = &'a mut T; - type IntoIter = IterMut<'a, T>; +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B] +where + B: PartialEq, + [A; N]: LengthAtMost32, +{ + #[inline] + fn eq(&self, other: &[A; N]) -> bool { + self[..] == other[..] + } + #[inline] + fn ne(&self, other: &[A; N]) -> bool { + self[..] != other[..] + } +} - fn into_iter(self) -> IterMut<'a, T> { - self.iter_mut() - } - } +// NOTE: some less important impls are omitted to reduce code bloat +// __impl_slice_eq2! { [A; $N], &'b [B; $N] } +// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } - // NOTE: some less important impls are omitted to reduce code bloat - __impl_slice_eq1! { [A; $N], [B; $N] } - __impl_slice_eq2! { [A; $N], [B] } - __impl_slice_eq2! { [A; $N], &'b [B] } - __impl_slice_eq2! { [A; $N], &'b mut [B] } - // __impl_slice_eq2! { [A; $N], &'b [B; $N] } - // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } - - #[stable(feature = "rust1", since = "1.0.0")] - impl Eq for [T; $N] { } - - #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd for [T; $N] { - #[inline] - fn partial_cmp(&self, other: &[T; $N]) -> Option { - PartialOrd::partial_cmp(&&self[..], &&other[..]) - } - #[inline] - fn lt(&self, other: &[T; $N]) -> bool { - PartialOrd::lt(&&self[..], &&other[..]) - } - #[inline] - fn le(&self, other: &[T; $N]) -> bool { - PartialOrd::le(&&self[..], &&other[..]) - } - #[inline] - fn ge(&self, other: &[T; $N]) -> bool { - PartialOrd::ge(&&self[..], &&other[..]) - } - #[inline] - fn gt(&self, other: &[T; $N]) -> bool { - PartialOrd::gt(&&self[..], &&other[..]) - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for [T; N] where [T; N]: LengthAtMost32 {} - #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for [T; $N] { - #[inline] - fn cmp(&self, other: &[T; $N]) -> Ordering { - Ord::cmp(&&self[..], &&other[..]) - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialOrd for [T; N] +where + [T; N]: LengthAtMost32, +{ + #[inline] + fn partial_cmp(&self, other: &[T; N]) -> Option { + PartialOrd::partial_cmp(&&self[..], &&other[..]) + } + #[inline] + fn lt(&self, other: &[T; N]) -> bool { + PartialOrd::lt(&&self[..], &&other[..]) + } + #[inline] + fn le(&self, other: &[T; N]) -> bool { + PartialOrd::le(&&self[..], &&other[..]) + } + #[inline] + fn ge(&self, other: &[T; N]) -> bool { + PartialOrd::ge(&&self[..], &&other[..]) + } + #[inline] + fn gt(&self, other: &[T; N]) -> bool { + PartialOrd::gt(&&self[..], &&other[..]) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Ord for [T; N] +where + [T; N]: LengthAtMost32, +{ + #[inline] + fn cmp(&self, other: &[T; N]) -> Ordering { + Ord::cmp(&&self[..], &&other[..]) + } +} + +/// Implemented for lengths where trait impls are allowed on arrays in core/std +#[rustc_on_unimplemented( + message="arrays only have std trait implementations for lengths 0..=32", +)] +#[unstable(feature = "const_generic_impls_guard", issue = "0", + reason = "will never be stable, just a temporary step until const generics are stable")] +pub trait LengthAtMost32 {} + +macro_rules! array_impls { + ($($N:literal)+) => { + $( + #[unstable(feature = "const_generic_impls_guard", issue = "0")] + impl LengthAtMost32 for [T; $N] {} )+ } } diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index c0ab364380..e6a6fdde54 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -117,6 +117,7 @@ impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { diff --git a/src/libcore/benches/slice.rs b/src/libcore/benches/slice.rs index 484753c1a0..711a8dff2c 100644 --- a/src/libcore/benches/slice.rs +++ b/src/libcore/benches/slice.rs @@ -55,3 +55,29 @@ fn binary_search_l2_with_dups(b: &mut Bencher) { fn binary_search_l3_with_dups(b: &mut Bencher) { binary_search(b, Cache::L3, |i| i / 16 * 16); } + +macro_rules! rotate { + ($fn:ident, $n:expr, $mapper:expr) => { + #[bench] + fn $fn(b: &mut Bencher) { + let mut x = (0usize..$n).map(&$mapper).collect::>(); + b.iter(|| { + for s in 0..x.len() { + x[..].rotate_right(s); + } + black_box(x[0].clone()) + }) + } + }; +} + +#[derive(Clone)] +struct Rgb(u8, u8, u8); + +rotate!(rotate_u8, 32, |i| i as u8); +rotate!(rotate_rgb, 32, |i| Rgb(i as u8, (i as u8).wrapping_add(7), (i as u8).wrapping_add(42))); +rotate!(rotate_usize, 32, |i| i); +rotate!(rotate_16_usize_4, 16, |i| [i; 4]); +rotate!(rotate_16_usize_5, 16, |i| [i; 5]); +rotate!(rotate_64_usize_4, 64, |i| [i; 4]); +rotate!(rotate_64_usize_5, 64, |i| [i; 5]); diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index beafddc5a1..8579dbf353 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -290,7 +290,7 @@ impl Clone for Cell { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Cell { +impl Default for Cell { /// Creates a `Cell`, with the `Default` value for T. #[inline] fn default() -> Cell { @@ -299,7 +299,7 @@ impl Default for Cell { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for Cell { +impl PartialEq for Cell { #[inline] fn eq(&self, other: &Cell) -> bool { self.get() == other.get() @@ -307,10 +307,10 @@ impl PartialEq for Cell { } #[stable(feature = "cell_eq", since = "1.2.0")] -impl Eq for Cell {} +impl Eq for Cell {} #[stable(feature = "cell_ord", since = "1.10.0")] -impl PartialOrd for Cell { +impl PartialOrd for Cell { #[inline] fn partial_cmp(&self, other: &Cell) -> Option { self.get().partial_cmp(&other.get()) @@ -338,7 +338,7 @@ impl PartialOrd for Cell { } #[stable(feature = "cell_ord", since = "1.10.0")] -impl Ord for Cell { +impl Ord for Cell { #[inline] fn cmp(&self, other: &Cell) -> Ordering { self.get().cmp(&other.get()) @@ -1008,7 +1008,7 @@ impl Clone for RefCell { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for RefCell { +impl Default for RefCell { /// Creates a `RefCell`, with the `Default` value for T. #[inline] fn default() -> RefCell { @@ -1101,13 +1101,23 @@ struct BorrowRef<'b> { impl<'b> BorrowRef<'b> { #[inline] fn new(borrow: &'b Cell) -> Option> { - let b = borrow.get(); - if is_writing(b) || b == isize::max_value() { - // If there's currently a writing borrow, or if incrementing the - // refcount would overflow into a writing borrow. + let b = borrow.get().wrapping_add(1); + if !is_reading(b) { + // Incrementing borrow can result in a non-reading value (<= 0) in these cases: + // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow + // due to Rust's reference aliasing rules + // 2. It was isize::max_value() (the max amount of reading borrows) and it overflowed + // into isize::min_value() (the max amount of writing borrows) so we can't allow + // an additional read borrow because isize can't represent so many read borrows + // (this can only happen if you mem::forget more than a small constant amount of + // `Ref`s, which is not good practice) None } else { - borrow.set(b + 1); + // Incrementing borrow can result in a reading value (> 0) in these cases: + // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow + // 2. It was > 0 and < isize::max_value(), i.e. there were read borrows, and isize + // is large enough to represent having one more read borrow + borrow.set(b); Some(BorrowRef { borrow }) } } @@ -1412,8 +1422,9 @@ impl fmt::Display for RefMut<'_, T> { /// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are /// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably /// aliased or mutated, and that `&mut T` is unique. `UnsafeCell` is the only core language -/// feature to work around this restriction. All other types that allow internal mutability, such as -/// `Cell` and `RefCell`, use `UnsafeCell` to wrap their internal data. +/// feature to work around the restriction that `&T` may not be mutated. All other types that +/// allow internal mutability, such as `Cell` and `RefCell`, use `UnsafeCell` to wrap their +/// internal data. There is *no* legal way to obtain aliasing `&mut`, not even with `UnsafeCell`. /// /// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to /// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly. diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs index e843303380..aa834db2b9 100644 --- a/src/libcore/char/methods.rs +++ b/src/libcore/char/methods.rs @@ -547,29 +547,34 @@ impl char { } } - /// Returns `true` if this `char` satisfies the 'XID_Start' Unicode property, and false + /// Returns `true` if this `char` satisfies the `XID_Start` Unicode property, and false /// otherwise. /// - /// 'XID_Start' is a Unicode Derived Property specified in + /// `XID_Start` is a Unicode Derived Property specified in /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications), /// mostly similar to `ID_Start` but modified for closure under `NFKx`. - #[unstable(feature = "rustc_private", - reason = "mainly needed for compiler internals", - issue = "27812")] - #[inline] + #[cfg_attr(bootstrap, + unstable(feature = "rustc_private", + reason = "mainly needed for compiler internals", + issue = "27812"))] + #[cfg_attr(not(bootstrap), + unstable(feature = "unicode_internals", issue = "0"))] pub fn is_xid_start(self) -> bool { derived_property::XID_Start(self) } - /// Returns `true` if this `char` satisfies the 'XID_Continue' Unicode property, and false + /// Returns `true` if this `char` satisfies the `XID_Continue` Unicode property, and false /// otherwise. /// - /// 'XID_Continue' is a Unicode Derived Property specified in + /// `XID_Continue` is a Unicode Derived Property specified in /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications), - /// mostly similar to 'ID_Continue' but modified for closure under NFKx. - #[unstable(feature = "rustc_private", - reason = "mainly needed for compiler internals", - issue = "27812")] + /// mostly similar to `ID_Continue` but modified for closure under NFKx. + #[cfg_attr(bootstrap, + unstable(feature = "rustc_private", + reason = "mainly needed for compiler internals", + issue = "27812"))] + #[cfg_attr(not(bootstrap), + unstable(feature = "unicode_internals", issue = "0"))] #[inline] pub fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) @@ -661,7 +666,7 @@ impl char { /// Returns `true` if this `char` is alphanumeric. /// /// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories - /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'. + /// `Nd`, `Nl`, `No` and the Derived Core Property `Alphabetic`. /// /// # Examples /// @@ -715,7 +720,7 @@ impl char { /// Returns `true` if this `char` is numeric. /// /// 'Numeric'-ness is defined in terms of the Unicode General Categories - /// 'Nd', 'Nl', 'No'. + /// `Nd`, `Nl`, `No`. /// /// # Examples /// diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 9e32acb97d..0c99356390 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -133,6 +133,14 @@ pub trait Clone : Sized { } } +/// Derive macro generating an impl of the trait `Clone`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics, derive_clone_copy)] +pub macro Clone($item:item) { /* compiler built-in */ } + // FIXME(aburka): these structs are used solely by #[derive] to // assert that every component of a type implements Clone or Copy. // diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 59088e4329..38a52d97da 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -200,6 +200,14 @@ pub trait PartialEq { fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } } +/// Derive macro generating an impl of the trait `PartialEq`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics)] +pub macro PartialEq($item:item) { /* compiler built-in */ } + /// Trait for equality comparisons which are [equivalence relations]( /// https://en.wikipedia.org/wiki/Equivalence_relation). /// @@ -256,6 +264,14 @@ pub trait Eq: PartialEq { fn assert_receiver_is_total_eq(&self) {} } +/// Derive macro generating an impl of the trait `Eq`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics, derive_eq)] +pub macro Eq($item:item) { /* compiler built-in */ } + // FIXME: this struct is used solely by #[derive] to // assert that every component of a type implements Eq. // @@ -319,7 +335,7 @@ impl Ordering { /// This method can be used to reverse a comparison: /// /// ``` - /// let mut data: &mut [_] = &mut [2, 10, 5, 8]; + /// let data: &mut [_] = &mut [2, 10, 5, 8]; /// /// // sort the array from largest to smallest. /// data.sort_by(|a, b| a.cmp(b).reverse()); @@ -600,6 +616,14 @@ pub trait Ord: Eq + PartialOrd { } } +/// Derive macro generating an impl of the trait `Ord`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics)] +pub macro Ord($item:item) { /* compiler built-in */ } + #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Ordering {} @@ -842,6 +866,14 @@ pub trait PartialOrd: PartialEq { } } +/// Derive macro generating an impl of the trait `PartialOrd`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics)] +pub macro PartialOrd($item:item) { /* compiler built-in */ } + /// Compares and returns the minimum of two values. /// /// Returns the first argument if the comparison determines them to be equal. diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index a697b7bd6e..641621f492 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -251,12 +251,12 @@ pub trait AsMut { /// /// # Examples /// -/// [`String`] implements `Into>`: +/// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`: /// /// In order to express that we want a generic function to take all arguments that can be /// converted to a specified type `T`, we can use a trait bound of [`Into`]``. /// For example: The function `is_hello` takes all arguments that can be converted into a -/// `Vec`. +/// [`Vec`]`<`[`u8`]`>`. /// /// ``` /// fn is_hello>>(s: T) { @@ -274,6 +274,7 @@ pub trait AsMut { /// [`String`]: ../../std/string/struct.String.html /// [`From`]: trait.From.html /// [`Into`]: trait.Into.html +/// [`Vec`]: ../../std/vec/struct.Vec.html #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { /// Performs the conversion. @@ -410,12 +411,12 @@ pub trait TryInto: Sized { /// /// This is useful when you are doing a type conversion that may /// trivially succeed but may also need special handling. -/// For example, there is no way to convert an `i64` into an `i32` -/// using the [`From`] trait, because an `i64` may contain a value -/// that an `i32` cannot represent and so the conversion would lose data. -/// This might be handled by truncating the `i64` to an `i32` (essentially -/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning -/// `i32::MAX`, or by some other method. The `From` trait is intended +/// For example, there is no way to convert an [`i64`] into an [`i32`] +/// using the [`From`] trait, because an [`i64`] may contain a value +/// that an [`i32`] cannot represent and so the conversion would lose data. +/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially +/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning +/// [`i32::MAX`], or by some other method. The [`From`] trait is intended /// for perfect conversions, so the `TryFrom` trait informs the /// programmer when a type conversion could go bad and lets them /// decide how to handle it. @@ -425,8 +426,8 @@ pub trait TryInto: Sized { /// - `TryFrom for U` implies [`TryInto`]` for T` /// - [`try_from`] is reflexive, which means that `TryFrom for T` /// is implemented and cannot fail -- the associated `Error` type for -/// calling `T::try_from()` on a value of type `T` is `Infallible`. -/// When the `!` type is stablized `Infallible` and `!` will be +/// calling `T::try_from()` on a value of type `T` is [`Infallible`]. +/// When the [`!`] type is stabilized [`Infallible`] and [`!`] will be /// equivalent. /// /// `TryFrom` can be implemented as follows: @@ -451,7 +452,7 @@ pub trait TryInto: Sized { /// /// # Examples /// -/// As described, [`i32`] implements `TryFrom`: +/// As described, [`i32`] implements `TryFrom<`[`i64`]`>`: /// /// ``` /// use std::convert::TryFrom; @@ -474,6 +475,9 @@ pub trait TryInto: Sized { /// /// [`try_from`]: trait.TryFrom.html#tymethod.try_from /// [`TryInto`]: trait.TryInto.html +/// [`i32::MAX`]: ../../std/i32/constant.MAX.html +/// [`!`]: ../../std/primitive.never.html +/// [`Infallible`]: enum.Infallible.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. @@ -509,7 +513,7 @@ impl AsRef for &mut T where T: AsRef // FIXME (#45742): replace the above impls for &/&mut with the following more general one: // // As lifts over Deref -// impl AsRef for D where D::Target: AsRef { +// impl>, U: ?Sized> AsRef for D { // fn as_ref(&self) -> &U { // self.deref().as_ref() // } @@ -526,7 +530,7 @@ impl AsMut for &mut T where T: AsMut // FIXME (#45742): replace the above impl for &mut with the following more general one: // // AsMut lifts over DerefMut -// impl AsMut for D where D::Target: AsMut { +// impl>, U: ?Sized> AsMut for D { // fn as_mut(&mut self) -> &mut U { // self.deref_mut().as_mut() // } diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 5ad05b3824..8d95e9de15 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -115,6 +115,14 @@ pub trait Default: Sized { fn default() -> Self; } +/// Derive macro generating an impl of the trait `Default`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics)] +pub macro Default($item:item) { /* compiler built-in */ } + macro_rules! default_impl { ($t:ty, $v:expr, $doc:tt) => { #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 49090fb8e4..eda0e7c518 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -60,7 +60,10 @@ impl fmt::Debug for c_void { #[lang = "va_list"] pub struct VaListImpl<'f> { ptr: *mut c_void, - _marker: PhantomData<&'f c_void>, + + // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to + // the region of the function it's defined in + _marker: PhantomData<&'f mut &'f c_void>, } #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), @@ -96,7 +99,7 @@ pub struct VaListImpl<'f> { vr_top: *mut c_void, gr_offs: i32, vr_offs: i32, - _marker: PhantomData<&'f c_void>, + _marker: PhantomData<&'f mut &'f c_void>, } /// PowerPC ABI implementation of a `va_list`. @@ -114,7 +117,7 @@ pub struct VaListImpl<'f> { reserved: u16, overflow_arg_area: *mut c_void, reg_save_area: *mut c_void, - _marker: PhantomData<&'f c_void>, + _marker: PhantomData<&'f mut &'f c_void>, } /// x86_64 ABI implementation of a `va_list`. @@ -131,7 +134,7 @@ pub struct VaListImpl<'f> { fp_offset: i32, overflow_arg_area: *mut c_void, reg_save_area: *mut c_void, - _marker: PhantomData<&'f c_void>, + _marker: PhantomData<&'f mut &'f c_void>, } /// asm.js ABI implementation of a `va_list`. @@ -148,7 +151,7 @@ pub struct VaListImpl<'f> { #[lang = "va_list"] pub struct VaListImpl<'f> { inner: [crate::mem::MaybeUninit; 4], - _marker: PhantomData<&'f c_void>, + _marker: PhantomData<&'f mut &'f c_void>, } #[cfg(all(target_arch = "asmjs", not(windows)))] @@ -302,7 +305,6 @@ impl sealed_trait::VaArgSafe for *const T {} reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[cfg(not(bootstrap))] impl<'f> VaListImpl<'f> { /// Advance to the next arg. #[inline] @@ -324,7 +326,6 @@ impl<'f> VaListImpl<'f> { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[cfg(not(bootstrap))] impl<'f> Clone for VaListImpl<'f> { #[inline] fn clone(&self) -> Self { @@ -340,7 +341,6 @@ impl<'f> Clone for VaListImpl<'f> { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[cfg(not(bootstrap))] impl<'f> Drop for VaListImpl<'f> { fn drop(&mut self) { // FIXME: this should call `va_end`, but there's no clean way to @@ -359,15 +359,12 @@ impl<'f> Drop for VaListImpl<'f> { extern "rust-intrinsic" { /// Destroy the arglist `ap` after initialization with `va_start` or /// `va_copy`. - #[cfg(not(bootstrap))] fn va_end(ap: &mut VaListImpl<'_>); /// Copies the current location of arglist `src` to the arglist `dst`. - #[cfg(not(bootstrap))] fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); /// Loads an argument of type `T` from the `va_list` `ap` and increment the /// argument `ap` points to. - #[cfg(not(bootstrap))] fn va_arg(ap: &mut VaListImpl<'_>) -> T; } diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index df86da5fc3..cb4e32622f 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -1,37 +1,50 @@ use crate::fmt; -struct PadAdapter<'a> { - buf: &'a mut (dyn fmt::Write + 'a), +struct PadAdapter<'buf, 'state> { + buf: &'buf mut (dyn fmt::Write + 'buf), + state: &'state mut PadAdapterState, +} + +struct PadAdapterState { on_newline: bool, } -impl<'a> PadAdapter<'a> { - fn wrap<'b, 'c: 'a+'b>(fmt: &'c mut fmt::Formatter<'_>, slot: &'b mut Option) - -> fmt::Formatter<'b> { +impl Default for PadAdapterState { + fn default() -> Self { + PadAdapterState { + on_newline: true, + } + } +} + +impl<'buf, 'state> PadAdapter<'buf, 'state> { + fn wrap<'slot, 'fmt: 'buf+'slot>(fmt: &'fmt mut fmt::Formatter<'_>, + slot: &'slot mut Option, + state: &'state mut PadAdapterState) -> fmt::Formatter<'slot> { fmt.wrap_buf(move |buf| { *slot = Some(PadAdapter { buf, - on_newline: true, + state, }); slot.as_mut().unwrap() }) } } -impl fmt::Write for PadAdapter<'_> { +impl fmt::Write for PadAdapter<'_, '_> { fn write_str(&mut self, mut s: &str) -> fmt::Result { while !s.is_empty() { - if self.on_newline { + if self.state.on_newline { self.buf.write_str(" ")?; } let split = match s.find('\n') { Some(pos) => { - self.on_newline = true; + self.state.on_newline = true; pos + 1 } None => { - self.on_newline = false; + self.state.on_newline = false; s.len() } }; @@ -133,7 +146,8 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { self.fmt.write_str(" {\n")?; } let mut slot = None; - let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot); + let mut state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); writer.write_str(name)?; writer.write_str(": ")?; value.fmt(&mut writer)?; @@ -279,7 +293,8 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> { self.fmt.write_str("(\n")?; } let mut slot = None; - let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot); + let mut state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); value.fmt(&mut writer)?; writer.write_str(",\n") } else { @@ -349,7 +364,8 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> { self.fmt.write_str("\n")?; } let mut slot = None; - let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot); + let mut state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); entry.fmt(&mut writer)?; writer.write_str(",\n") } else { @@ -676,6 +692,9 @@ pub struct DebugMap<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, has_fields: bool, + has_key: bool, + // The state of newlines is tracked between keys and values + state: PadAdapterState, } pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { @@ -684,6 +703,8 @@ pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b fmt, result, has_fields: false, + has_key: false, + state: Default::default(), } } @@ -712,25 +733,123 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { + self.key(key).value(value) + } + + /// Adds the key part of a new entry to the map output. + /// + /// This method, together with `value`, is an alternative to `entry` that + /// can be used when the complete entry isn't known upfront. Prefer the `entry` + /// method when it's possible to use. + /// + /// # Panics + /// + /// `key` must be called before `value` and each call to `key` must be followed + /// by a corresponding call to `value`. Otherwise this method will panic. + /// + /// # Examples + /// + /// ``` + /// # #![feature(debug_map_key_value)] + /// use std::fmt; + /// + /// struct Foo(Vec<(String, i32)>); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + /// fmt.debug_map() + /// .key(&"whole").value(&self.0) // We add the "whole" entry. + /// .finish() + /// } + /// } + /// + /// assert_eq!( + /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), + /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", + /// ); + /// ``` + #[unstable(feature = "debug_map_key_value", + reason = "recently added", + issue = "62482")] + pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { + assert!(!self.has_key, "attempted to begin a new map entry \ + without completing the previous one"); + self.result = self.result.and_then(|_| { if self.is_pretty() { if !self.has_fields { self.fmt.write_str("\n")?; } let mut slot = None; - let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot); + self.state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state); key.fmt(&mut writer)?; writer.write_str(": ")?; - value.fmt(&mut writer)?; - writer.write_str(",\n") } else { if self.has_fields { self.fmt.write_str(", ")? } key.fmt(self.fmt)?; self.fmt.write_str(": ")?; - value.fmt(self.fmt) } + + self.has_key = true; + Ok(()) + }); + + self + } + + /// Adds the value part of a new entry to the map output. + /// + /// This method, together with `key`, is an alternative to `entry` that + /// can be used when the complete entry isn't known upfront. Prefer the `entry` + /// method when it's possible to use. + /// + /// # Panics + /// + /// `key` must be called before `value` and each call to `key` must be followed + /// by a corresponding call to `value`. Otherwise this method will panic. + /// + /// # Examples + /// + /// ``` + /// # #![feature(debug_map_key_value)] + /// use std::fmt; + /// + /// struct Foo(Vec<(String, i32)>); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + /// fmt.debug_map() + /// .key(&"whole").value(&self.0) // We add the "whole" entry. + /// .finish() + /// } + /// } + /// + /// assert_eq!( + /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), + /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", + /// ); + /// ``` + #[unstable(feature = "debug_map_key_value", + reason = "recently added", + issue = "62482")] + pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { + assert!(self.has_key, "attempted to format a map value before its key"); + + self.result = self.result.and_then(|_| { + if self.is_pretty() { + let mut slot = None; + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state); + value.fmt(&mut writer)?; + writer.write_str(",\n")?; + } else { + value.fmt(self.fmt)?; + } + + self.has_key = false; + Ok(()) }); self.has_fields = true; @@ -775,6 +894,11 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// Finishes output and returns any error encountered. /// + /// # Panics + /// + /// `key` must be called before `value` and each call to `key` must be followed + /// by a corresponding call to `value`. Otherwise this method will panic. + /// /// # Examples /// /// ``` @@ -797,6 +921,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { + assert!(!self.has_key, "attempted to finish a map with a partial entry"); + self.result.and_then(|_| self.fmt.write_str("}")) } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 4bd7d3b4b2..a2fff913ac 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -12,10 +12,11 @@ fn float_to_decimal_common_exact(fmt: &mut Formatter<'_>, num: &T, unsafe { let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit(); - // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized - // `MaybeUninit` (here and elsewhere in this file). Revisit this once + // FIXME(#53491): This is calling `get_mut` on an uninitialized + // `MaybeUninit` (here and elsewhere in this file). Revisit this once // we decided whether that is valid or not. - // Using `freeze` is *not enough*; `flt2dec::Part` is an enum! + // We can do this only because we are libstd and coupled to the compiler. + // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!) let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, false, buf.get_mut(), parts.get_mut()); diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 17ea584388..0ea01d4b84 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -545,6 +545,21 @@ pub trait Debug { fn fmt(&self, f: &mut Formatter<'_>) -> Result; } +// Separate module to reexport the macro `Debug` from prelude without the trait `Debug`. +#[cfg(not(bootstrap))] +pub(crate) mod macros { + /// Derive macro generating an impl of the trait `Debug`. + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] + #[allow_internal_unstable(core_intrinsics)] + pub macro Debug($item:item) { /* compiler built-in */ } +} +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(inline)] +pub use macros::Debug; + /// Format trait for an empty format, `{}`. /// /// `Display` is similar to [`Debug`][debug], but `Display` is for user-facing @@ -2172,5 +2187,5 @@ impl Debug for UnsafeCell { } } -// If you expected tests to be here, look instead at the run-pass/ifmt.rs test, +// If you expected tests to be here, look instead at the ui/ifmt.rs test, // it's a lot easier than creating all of the rt::Piece structures here. diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index f9b4c26496..3b5c9fbff2 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -51,7 +51,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf = uninitialized_array![u8; 128]; + let mut buf = [MaybeUninit::::uninit(); 128]; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -189,7 +189,7 @@ static DEC_DIGITS_LUT: &[u8; 200] = macro_rules! impl_Display { ($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => { fn $name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buf = uninitialized_array![u8; 39]; + let mut buf = [MaybeUninit::::uninit(); 39]; let mut curr = buf.len() as isize; let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index acca8d7ba1..f14ed38b9b 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -17,15 +17,17 @@ use crate::task::{Context, Poll}; /// final value. This method does not block if the value is not ready. Instead, /// the current task is scheduled to be woken up when it's possible to make /// further progress by `poll`ing again. The `context` passed to the `poll` -/// method can provide a `Waker`, which is a handle for waking up the current +/// method can provide a [`Waker`], which is a handle for waking up the current /// task. /// /// When using a future, you generally won't call `poll` directly, but instead /// `.await` the value. +/// +/// [`Waker`]: ../task/struct.Waker.html #[doc(spotlight)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] -#[cfg_attr(not(bootstrap), lang = "future_trait")] +#[lang = "future_trait"] pub trait Future { /// The type of value produced on completion. #[stable(feature = "futures_api", since = "1.36.0")] @@ -109,8 +111,7 @@ impl Future for &mut F { #[stable(feature = "futures_api", since = "1.36.0")] impl

Future for Pin

where - P: Unpin + ops::DerefMut, - P::Target: Future, + P: Unpin + ops::DerefMut, { type Output = <

::Target as Future>::Output; diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 38e3864284..c4cbf40a93 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -198,6 +198,21 @@ pub trait Hash { } } +// Separate module to reexport the macro `Hash` from prelude without the trait `Hash`. +#[cfg(not(bootstrap))] +pub(crate) mod macros { + /// Derive macro generating an impl of the trait `Hash`. + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] + #[allow_internal_unstable(core_intrinsics)] + pub macro Hash($item:item) { /* compiler built-in */ } +} +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(inline)] +pub use macros::Hash; + /// A trait for hashing an arbitrary stream of bytes. /// /// Instances of `Hasher` usually represent state that is changed while hashing diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index 519212bb6c..3b2b28217f 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -110,7 +110,7 @@ pub fn spin_loop() { /// /// This function is a no-op, and does not even read from `dummy`. #[inline] -#[unstable(feature = "test", issue = "27812")] +#[unstable(feature = "test", issue = "50297")] #[allow(unreachable_code)] // this makes #[cfg] a bit easier below. pub fn black_box(dummy: T) -> T { // We need to "use" the argument in some way LLVM can't introspect, and on diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b30eff8baa..ceaa870d2b 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -36,6 +36,8 @@ issue = "0")] #![allow(missing_docs)] +use crate::mem; + #[stable(feature = "drop_in_place", since = "1.8.0")] #[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.18.0")] @@ -700,6 +702,13 @@ extern "rust-intrinsic" { /// which is unsafe unless `T` is `Copy`. Also, even if T is /// `Copy`, an all-zero value may not correspond to any legitimate /// state for the type in question. + #[unstable(feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ + they should be used through stabilized interfaces \ + in the rest of the standard library", + issue = "0")] + #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned", + since = "1.38.0")] pub fn init() -> T; /// Creates an uninitialized value. @@ -709,6 +718,13 @@ extern "rust-intrinsic" { /// state, which means it may claim either dropped or /// undropped. In the general case one must use `ptr::write` to /// initialize memory previous set to the result of `uninit`. + #[unstable(feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ + they should be used through stabilized interfaces \ + in the rest of the standard library", + issue = "0")] + #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned", + since = "1.38.0")] pub fn uninit() -> T; /// Moves a value out of scope without running drop glue. @@ -1052,16 +1068,12 @@ extern "rust-intrinsic" { pub fn fabsf64(x: f64) -> f64; /// Returns the minimum of two `f32` values. - #[cfg(not(bootstrap))] pub fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values. - #[cfg(not(bootstrap))] pub fn minnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f32` values. - #[cfg(not(bootstrap))] pub fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values. - #[cfg(not(bootstrap))] pub fn maxnumf64(x: f64, y: f64) -> f64; /// Copies the sign from `y` to `x` for `f32` values. @@ -1255,17 +1267,14 @@ extern "rust-intrinsic" { /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`. - #[cfg(not(bootstrap))] pub fn unchecked_add(x: T, y: T) -> T; /// Returns the result of an unchecked substraction, resulting in /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`. - #[cfg(not(bootstrap))] pub fn unchecked_sub(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`. - #[cfg(not(bootstrap))] pub fn unchecked_mul(x: T, y: T) -> T; /// Performs rotate left. @@ -1331,6 +1340,26 @@ extern "rust-intrinsic" { // (`transmute` also falls into this category, but it cannot be wrapped due to the // check that `T` and `U` have the same size.) +/// Checks whether `ptr` is properly aligned with respect to +/// `align_of::()`. +pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { + !ptr.is_null() && ptr as usize % mem::align_of::() == 0 +} + +/// Checks whether the regions of memory starting at `src` and `dst` of size +/// `count * size_of::()` overlap. +fn overlaps(src: *const T, dst: *const T, count: usize) -> bool { + let src_usize = src as usize; + let dst_usize = dst as usize; + let size = mem::size_of::().checked_mul(count).unwrap(); + let diff = if src_usize > dst_usize { + src_usize - dst_usize + } else { + dst_usize - src_usize + }; + size > diff +} + /// Copies `count * size_of::()` bytes from `src` to `dst`. The source /// and destination must *not* overlap. /// @@ -1420,7 +1449,11 @@ pub unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); } - copy_nonoverlapping(src, dst, count); + + debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer"); + debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer"); + debug_assert!(!overlaps(src, dst, count), "attempt to copy to overlapping memory"); + copy_nonoverlapping(src, dst, count) } /// Copies `count * size_of::()` bytes from `src` to `dst`. The source @@ -1480,6 +1513,9 @@ pub unsafe fn copy(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { fn copy(src: *const T, dst: *mut T, count: usize); } + + debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer"); + debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer"); copy(src, dst, count) } @@ -1561,55 +1597,7 @@ pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { extern "rust-intrinsic" { fn write_bytes(dst: *mut T, val: u8, count: usize); } - write_bytes(dst, val, count) -} -// Simple bootstrap implementations of minnum/maxnum for stage0 compilation. - -/// Returns the minimum of two `f32` values. -#[cfg(bootstrap)] -pub fn minnumf32(x: f32, y: f32) -> f32 { - // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the - // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it - // is either x or y, canonicalized (this means results might differ among implementations). - // When either x or y is a signaling NaN, then the result is according to 6.2. - // - // Since we do not support sNaN in Rust yet, we do not need to handle them. - // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by - // multiplying by 1.0. Should switch to the `canonicalize` when it works. - (if x < y || y != y { x } else { y }) * 1.0 -} - -/// Returns the minimum of two `f64` values. -#[cfg(bootstrap)] -pub fn minnumf64(x: f64, y: f64) -> f64 { - // Identical to the `f32` case. - (if x < y || y != y { x } else { y }) * 1.0 -} - -/// Returns the maximum of two `f32` values. -#[cfg(bootstrap)] -pub fn maxnumf32(x: f32, y: f32) -> f32 { - // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the - // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it - // is either x or y, canonicalized (this means results might differ among implementations). - // When either x or y is a signaling NaN, then the result is according to 6.2. - // - // Since we do not support sNaN in Rust yet, we do not need to handle them. - // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by - // multiplying by 1.0. Should switch to the `canonicalize` when it works. - (if x < y || x != x { y } else { x }) * 1.0 -} - -/// Returns the maximum of two `f64` values. -#[cfg(bootstrap)] -pub fn maxnumf64(x: f64, y: f64) -> f64 { - // Identical to the `f32` case. - (if x < y || x != x { y } else { x }) * 1.0 -} - -/// For bootstrapping, implement unchecked_sub as just wrapping_sub. -#[cfg(bootstrap)] -pub unsafe fn unchecked_sub(x: T, y: T) -> T { - sub_with_overflow(x, y).0 + debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer"); + write_bytes(dst, val, count) } diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs index 8c2aae477b..d8d41a2a31 100644 --- a/src/libcore/iter/adapters/flatten.rs +++ b/src/libcore/iter/adapters/flatten.rs @@ -24,15 +24,17 @@ impl U> FlatMap { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for FlatMap - where ::IntoIter: Clone +impl Clone for FlatMap +where + U: Clone + IntoIterator, { fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } } } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for FlatMap - where U::IntoIter: fmt::Debug +impl fmt::Debug for FlatMap +where + U: IntoIterator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("FlatMap").field("inner", &self.inner).finish() @@ -68,9 +70,10 @@ impl Iterator for FlatMap #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for FlatMap - where F: FnMut(I::Item) -> U, - U: IntoIterator, - U::IntoIter: DoubleEndedIterator +where + F: FnMut(I::Item) -> U, + U: IntoIterator, + U::IntoIter: DoubleEndedIterator, { #[inline] fn next_back(&mut self) -> Option { self.inner.next_back() } @@ -105,11 +108,13 @@ impl FusedIterator for FlatMap #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iterator_flatten", since = "1.29.0")] pub struct Flatten -where I::Item: IntoIterator { +where + I::Item: IntoIterator, +{ inner: FlattenCompat::IntoIter>, } -impl Flatten -where I::Item: IntoIterator { + +impl> Flatten { pub(in super::super) fn new(iter: I) -> Flatten { Flatten { inner: FlattenCompat::new(iter) } } @@ -117,8 +122,9 @@ where I::Item: IntoIterator { #[stable(feature = "iterator_flatten", since = "1.29.0")] impl fmt::Debug for Flatten - where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug, - I::Item: IntoIterator, +where + I: fmt::Debug + Iterator>, + U: fmt::Debug + Iterator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Flatten").field("inner", &self.inner).finish() @@ -127,16 +133,18 @@ impl fmt::Debug for Flatten #[stable(feature = "iterator_flatten", since = "1.29.0")] impl Clone for Flatten - where I: Iterator + Clone, U: Iterator + Clone, - I::Item: IntoIterator, +where + I: Clone + Iterator>, + U: Clone + Iterator, { fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } } } #[stable(feature = "iterator_flatten", since = "1.29.0")] impl Iterator for Flatten - where I: Iterator, U: Iterator, - I::Item: IntoIterator +where + I: Iterator>, + U: Iterator, { type Item = U::Item; @@ -163,8 +171,9 @@ impl Iterator for Flatten #[stable(feature = "iterator_flatten", since = "1.29.0")] impl DoubleEndedIterator for Flatten - where I: DoubleEndedIterator, U: DoubleEndedIterator, - I::Item: IntoIterator +where + I: DoubleEndedIterator>, + U: DoubleEndedIterator, { #[inline] fn next_back(&mut self) -> Option { self.inner.next_back() } @@ -186,8 +195,10 @@ impl DoubleEndedIterator for Flatten #[stable(feature = "iterator_flatten", since = "1.29.0")] impl FusedIterator for Flatten - where I: FusedIterator, U: Iterator, - I::Item: IntoIterator {} +where + I: FusedIterator>, + U: Iterator, +{} /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. @@ -205,8 +216,9 @@ impl FlattenCompat { } impl Iterator for FlattenCompat - where I: Iterator, U: Iterator, - I::Item: IntoIterator +where + I: Iterator>, + U: Iterator, { type Item = U::Item; @@ -274,8 +286,9 @@ impl Iterator for FlattenCompat } impl DoubleEndedIterator for FlattenCompat - where I: DoubleEndedIterator, U: DoubleEndedIterator, - I::Item: IntoIterator +where + I: DoubleEndedIterator>, + U: DoubleEndedIterator, { #[inline] fn next_back(&mut self) -> Option { diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index c2edcd22f9..b270290295 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -485,6 +485,39 @@ impl Iterator for StepBy where I: Iterator { } } +impl StepBy where I: ExactSizeIterator { + // The zero-based index starting from the end of the iterator of the + // last element. Used in the `DoubleEndedIterator` implementation. + fn next_back_index(&self) -> usize { + let rem = self.iter.len() % (self.step + 1); + if self.first_take { + if rem == 0 { self.step } else { rem - 1 } + } else { + rem + } + } +} + +#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")] +impl DoubleEndedIterator for StepBy where I: DoubleEndedIterator + ExactSizeIterator { + #[inline] + fn next_back(&mut self) -> Option { + self.iter.nth_back(self.next_back_index()) + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + // `self.iter.nth_back(usize::MAX)` does the right thing here when `n` + // is out of bounds because the length of `self.iter` does not exceed + // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is + // zero-indexed + let n = n + .saturating_mul(self.step + 1) + .saturating_add(self.next_back_index()); + self.iter.nth_back(n) + } +} + // StepBy can only make the iterator shorter, so the len will still fit. #[stable(feature = "iterator_step_by", since = "1.28.0")] impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} @@ -1158,6 +1191,45 @@ impl Iterator for Peekable { } } +#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")] +impl DoubleEndedIterator for Peekable where I: DoubleEndedIterator { + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x)) + } + + #[inline] + fn try_rfold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + match self.peeked.take() { + Some(None) => return Try::from_ok(init), + Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() { + Ok(acc) => f(acc, v), + Err(e) => { + self.peeked = Some(Some(v)); + Try::from_error(e) + } + }, + None => self.iter.try_rfold(init, f), + } + } + + #[inline] + fn rfold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + match self.peeked { + Some(None) => return init, + Some(Some(v)) => { + let acc = self.iter.rfold(init, &mut fold); + fold(acc, v) + } + None => self.iter.rfold(init, fold), + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Peekable {} @@ -1627,6 +1699,51 @@ impl Iterator for Take where I: Iterator{ } } +#[stable(feature = "double_ended_take_iterator", since = "1.38.0")] +impl DoubleEndedIterator for Take where I: DoubleEndedIterator + ExactSizeIterator { + #[inline] + fn next_back(&mut self) -> Option { + if self.n == 0 { + None + } else { + let n = self.n; + self.n -= 1; + self.iter.nth_back(self.iter.len().saturating_sub(n)) + } + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + let len = self.iter.len(); + if self.n > n { + let m = len.saturating_sub(self.n) + n; + self.n -= n + 1; + self.iter.nth_back(m) + } else { + if len > 0 { + self.iter.nth_back(len - 1); + } + None + } + } + + #[inline] + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where + Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try + { + if self.n == 0 { + Try::from_ok(init) + } else { + let len = self.iter.len(); + if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() { + Try::from_ok(init) + } else { + self.iter.try_rfold(init, fold) + } + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Take where I: ExactSizeIterator {} @@ -2062,3 +2179,66 @@ impl ExactSizeIterator for Inspect #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Inspect where F: FnMut(&I::Item) {} + +/// An iterator adapter that produces output as long as the underlying +/// iterator produces `Result::Ok` values. +/// +/// If an error is encountered, the iterator stops and the error is +/// stored. +pub(crate) struct ResultShunt<'a, I, E> { + iter: I, + error: &'a mut Result<(), E>, +} + +/// Process the given iterator as if it yielded a `T` instead of a +/// `Result`. Any errors will stop the inner iterator and +/// the overall result will be an error. +pub(crate) fn process_results(iter: I, mut f: F) -> Result +where + I: Iterator>, + for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U, +{ + let mut error = Ok(()); + let shunt = ResultShunt { + iter, + error: &mut error, + }; + let value = f(shunt); + error.map(|()| value) +} + +impl Iterator for ResultShunt<'_, I, E> + where I: Iterator> +{ + type Item = T; + + fn next(&mut self) -> Option { + self.find(|_| true) + } + + fn size_hint(&self) -> (usize, Option) { + if self.error.is_err() { + (0, Some(0)) + } else { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } + } + + fn try_fold(&mut self, init: B, mut f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + let error = &mut *self.error; + self.iter + .try_fold(init, |acc, x| match x { + Ok(x) => LoopState::from_try(f(acc, x)), + Err(e) => { + *error = Err(e); + LoopState::Break(Try::from_ok(acc)) + } + }) + .into_try() + } +} diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 6eccb9d1ea..aba8e84d58 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -360,7 +360,7 @@ pub use self::adapters::Flatten; #[stable(feature = "iter_copied", since = "1.36.0")] pub use self::adapters::Copied; -pub(crate) use self::adapters::TrustedRandomAccess; +pub(crate) use self::adapters::{TrustedRandomAccess, process_results}; mod range; mod sources; diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs index adfb639bae..812463e77f 100644 --- a/src/libcore/iter/traits/accum.rs +++ b/src/libcore/iter/traits/accum.rs @@ -1,5 +1,6 @@ use crate::ops::{Mul, Add}; use crate::num::Wrapping; +use crate::iter; /// Trait to represent types that can be created by summing up an iterator. /// @@ -114,74 +115,6 @@ macro_rules! float_sum_product { integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } float_sum_product! { f32 f64 } -/// An iterator adapter that produces output as long as the underlying -/// iterator produces `Result::Ok` values. -/// -/// If an error is encountered, the iterator stops and the error is -/// stored. The error may be recovered later via `reconstruct`. -struct ResultShunt { - iter: I, - error: Option, -} - -impl ResultShunt - where I: Iterator> -{ - /// Process the given iterator as if it yielded a `T` instead of a - /// `Result`. Any errors will stop the inner iterator and - /// the overall result will be an error. - pub fn process(iter: I, mut f: F) -> Result - where F: FnMut(&mut Self) -> U - { - let mut shunt = ResultShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - ResultShunt { - iter, - error: None, - } - } - - /// Consume the adapter and rebuild a `Result` value. This should - /// *always* be called, otherwise any potential error would be - /// lost. - fn reconstruct(self, val: U) -> Result { - match self.error { - None => Ok(val), - Some(e) => Err(e), - } - } -} - -impl Iterator for ResultShunt - where I: Iterator> -{ - type Item = T; - - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Ok(v)) => Some(v), - Some(Err(e)) => { - self.error = Some(e); - None - } - None => None, - } - } - - fn size_hint(&self) -> (usize, Option) { - if self.error.is_some() { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } - } -} - #[stable(feature = "iter_arith_traits_result", since="1.16.0")] impl Sum> for Result where T: Sum, @@ -206,7 +139,7 @@ impl Sum> for Result fn sum(iter: I) -> Result where I: Iterator>, { - ResultShunt::process(iter, |i| i.sum()) + iter::process_results(iter, |i| i.sum()) } } @@ -220,74 +153,7 @@ impl Product> for Result fn product(iter: I) -> Result where I: Iterator>, { - ResultShunt::process(iter, |i| i.product()) - } -} - -/// An iterator adapter that produces output as long as the underlying -/// iterator produces `Option::Some` values. -struct OptionShunt { - iter: I, - exited_early: bool, -} - -impl OptionShunt -where - I: Iterator>, -{ - /// Process the given iterator as if it yielded a `T` instead of a - /// `Option`. Any `None` value will stop the inner iterator and - /// the overall result will be a `None`. - pub fn process(iter: I, mut f: F) -> Option - where - F: FnMut(&mut Self) -> U, - { - let mut shunt = OptionShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - OptionShunt { - iter, - exited_early: false, - } - } - - /// Consume the adapter and rebuild a `Option` value. - fn reconstruct(self, val: U) -> Option { - if self.exited_early { - None - } else { - Some(val) - } - } -} - -impl Iterator for OptionShunt -where - I: Iterator>, -{ - type Item = T; - - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Some(v)) => Some(v), - Some(None) => { - self.exited_early = true; - None - } - None => None, - } - } - - fn size_hint(&self) -> (usize, Option) { - if self.exited_early { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } + iter::process_results(iter, |i| i.product()) } } @@ -314,7 +180,7 @@ where where I: Iterator>, { - OptionShunt::process(iter, |i| i.sum()) + iter.map(|x| x.ok_or(())).sum::>().ok() } } @@ -330,6 +196,6 @@ where where I: Iterator>, { - OptionShunt::process(iter, |i| i.product()) + iter.map(|x| x.ok_or(())).product::>().ok() } } diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs index 1865160bc3..25439136b8 100644 --- a/src/libcore/iter/traits/collect.rs +++ b/src/libcore/iter/traits/collect.rs @@ -195,8 +195,9 @@ pub trait FromIterator: Sized { /// /// ```rust /// fn collect_as_strings(collection: T) -> Vec -/// where T: IntoIterator, -/// T::Item: std::fmt::Debug, +/// where +/// T: IntoIterator, +/// T::Item: std::fmt::Debug, /// { /// collection /// .into_iter() diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 30923c7414..7e941267ce 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -263,9 +263,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn last(self) -> Option where Self: Sized { - let mut last = None; - for x in self { last = Some(x); } - last + self.fold(None, |_, x| Some(x)) } /// Returns the `n`th element of the iterator. @@ -1472,6 +1470,11 @@ pub trait Iterator { /// `partition()` returns a pair, all of the elements for which it returned /// `true`, and all of the elements for which it returned `false`. /// + /// See also [`is_partitioned()`] and [`partition_in_place()`]. + /// + /// [`is_partitioned()`]: #method.is_partitioned + /// [`partition_in_place()`]: #method.partition_in_place + /// /// # Examples /// /// Basic usage: @@ -1506,6 +1509,101 @@ pub trait Iterator { (left, right) } + /// Reorder the elements of this iterator *in-place* according to the given predicate, + /// such that all those that return `true` precede all those that return `false`. + /// Returns the number of `true` elements found. + /// + /// The relative order of partitioned items is not maintained. + /// + /// See also [`is_partitioned()`] and [`partition()`]. + /// + /// [`is_partitioned()`]: #method.is_partitioned + /// [`partition()`]: #method.partition + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_partition_in_place)] + /// + /// let mut a = [1, 2, 3, 4, 5, 6, 7]; + /// + /// // Partition in-place between evens and odds + /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0); + /// + /// assert_eq!(i, 3); + /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens + /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds + /// ``` + #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] + fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize + where + Self: Sized + DoubleEndedIterator, + P: FnMut(&T) -> bool, + { + // FIXME: should we worry about the count overflowing? The only way to have more than + // `usize::MAX` mutable references is with ZSTs, which aren't useful to partition... + + // These closure "factory" functions exist to avoid genericity in `Self`. + + #[inline] + fn is_false<'a, T>( + predicate: &'a mut impl FnMut(&T) -> bool, + true_count: &'a mut usize, + ) -> impl FnMut(&&mut T) -> bool + 'a { + move |x| { + let p = predicate(&**x); + *true_count += p as usize; + !p + } + } + + #[inline] + fn is_true( + predicate: &mut impl FnMut(&T) -> bool + ) -> impl FnMut(&&mut T) -> bool + '_ { + move |x| predicate(&**x) + } + + // Repeatedly find the first `false` and swap it with the last `true`. + let mut true_count = 0; + while let Some(head) = self.find(is_false(predicate, &mut true_count)) { + if let Some(tail) = self.rfind(is_true(predicate)) { + crate::mem::swap(head, tail); + true_count += 1; + } else { + break; + } + } + true_count + } + + /// Checks if the elements of this iterator are partitioned according to the given predicate, + /// such that all those that return `true` precede all those that return `false`. + /// + /// See also [`partition()`] and [`partition_in_place()`]. + /// + /// [`partition()`]: #method.partition + /// [`partition_in_place()`]: #method.partition_in_place + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_is_partitioned)] + /// + /// assert!("Iterator".chars().is_partitioned(char::is_uppercase)); + /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase)); + /// ``` + #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")] + fn is_partitioned

(mut self, mut predicate: P) -> bool + where + Self: Sized, + P: FnMut(Self::Item) -> bool, + { + // Either all items test `true`, or the first clause stops at `false` + // and we check that there are no more `true` items after that. + self.all(&mut predicate) || !self.any(predicate) + } + /// An iterator method that applies a function as long as it returns /// successfully, producing a single, final value. /// @@ -2572,13 +2670,13 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] - fn is_sorted_by_key(self, mut f: F) -> bool + fn is_sorted_by_key(self, f: F) -> bool where Self: Sized, - F: FnMut(&Self::Item) -> K, + F: FnMut(Self::Item) -> K, K: PartialOrd { - self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b))) + self.map(f).is_sorted() } } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 04c50329de..678ff76879 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -62,9 +62,8 @@ #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings - -#![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] +#![cfg_attr(not(bootstrap), allow(incomplete_features))] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] @@ -74,6 +73,9 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(const_fn_union)] +#![feature(const_generics)] +#![feature(custom_inner_attributes)] +#![feature(decl_macro)] #![feature(doc_cfg)] #![feature(doc_spotlight)] #![feature(extern_types)] @@ -99,7 +101,7 @@ #![feature(staged_api)] #![feature(std_internals)] #![feature(stmt_expr_attributes)] -#![cfg_attr(not(bootstrap), feature(transparent_unions))] +#![feature(transparent_unions)] #![feature(unboxed_closures)] #![feature(unsized_locals)] #![feature(untagged_unions)] @@ -115,6 +117,9 @@ #![feature(wasm_target_feature)] #![feature(avx512_target_feature)] #![feature(cmpxchg16b_target_feature)] +#![feature(rtm_target_feature)] +#![feature(f16c_target_feature)] +#![feature(hexagon_target_feature)] #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] @@ -126,6 +131,8 @@ #![feature(adx_target_feature)] #![feature(maybe_uninit_slice, maybe_uninit_array)] #![feature(external_doc)] +#![feature(mem_take)] +#![feature(associated_type_bounds)] #[prelude_import] #[allow(unused)] @@ -224,12 +231,12 @@ mod tuple; mod unit; // Pull in the `core_arch` crate directly into libcore. The contents of -// `core_arch` are in a different repository: rust-lang-nursery/stdsimd. +// `core_arch` are in a different repository: rust-lang/stdarch. // // `core_arch` depends on libcore, but the contents of this module are // set up in such a way that directly pulling it here works such that the // crate uses the this crate as its libcore. -#[path = "../stdsimd/crates/core_arch/src/mod.rs"] +#[path = "../stdarch/crates/core_arch/src/mod.rs"] #[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)] #[unstable(feature = "stdsimd", issue = "48556")] mod core_arch; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 589061b282..680fcd12c4 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -145,11 +145,11 @@ macro_rules! assert_ne { /// # Uses /// /// Unlike [`assert!`], `debug_assert!` statements are only enabled in non -/// optimized builds by default. An optimized build will omit all +/// optimized builds by default. An optimized build will not execute /// `debug_assert!` statements unless `-C debug-assertions` is passed to the /// compiler. This makes `debug_assert!` useful for checks that are too /// expensive to be present in a release build but may be helpful during -/// development. +/// development. The result of expanding `debug_assert!` is always type checked. /// /// An unchecked assertion allows a program in an inconsistent state to keep /// running, which might have unexpected consequences but does not introduce @@ -190,11 +190,11 @@ macro_rules! debug_assert { /// debug representations. /// /// Unlike [`assert_eq!`], `debug_assert_eq!` statements are only enabled in non -/// optimized builds by default. An optimized build will omit all +/// optimized builds by default. An optimized build will not execute /// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the /// compiler. This makes `debug_assert_eq!` useful for checks that are too /// expensive to be present in a release build but may be helpful during -/// development. +/// development. The result of expanding `debug_assert_eq!` is always type checked. /// /// [`assert_eq!`]: ../std/macro.assert_eq.html /// @@ -217,11 +217,11 @@ macro_rules! debug_assert_eq { /// debug representations. /// /// Unlike [`assert_ne!`], `debug_assert_ne!` statements are only enabled in non -/// optimized builds by default. An optimized build will omit all +/// optimized builds by default. An optimized build will not execute /// `debug_assert_ne!` statements unless `-C debug-assertions` is passed to the /// compiler. This makes `debug_assert_ne!` useful for checks that are too /// expensive to be present in a release build but may be helpful during -/// development. +/// development. The result of expanding `debug_assert_ne!` is always type checked. /// /// [`assert_ne!`]: ../std/macro.assert_ne.html /// @@ -302,6 +302,7 @@ macro_rules! debug_assert_ne { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")] #[doc(alias = "?")] macro_rules! r#try { ($expr:expr) => (match $expr { @@ -335,11 +336,14 @@ macro_rules! r#try { /// ``` /// use std::io::Write; /// -/// let mut w = Vec::new(); -/// write!(&mut w, "test").unwrap(); -/// write!(&mut w, "formatted {}", "arguments").unwrap(); +/// fn main() -> std::io::Result<()> { +/// let mut w = Vec::new(); +/// write!(&mut w, "test")?; +/// write!(&mut w, "formatted {}", "arguments")?; /// -/// assert_eq!(w, b"testformatted arguments"); +/// assert_eq!(w, b"testformatted arguments"); +/// Ok(()) +/// } /// ``` /// /// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects @@ -350,11 +354,15 @@ macro_rules! r#try { /// use std::fmt::Write as FmtWrite; /// use std::io::Write as IoWrite; /// -/// let mut s = String::new(); -/// let mut v = Vec::new(); -/// write!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt -/// write!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt -/// assert_eq!(v, b"s = \"abc 123\""); +/// fn main() -> Result<(), Box> { +/// let mut s = String::new(); +/// let mut v = Vec::new(); +/// +/// write!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt +/// write!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt +/// assert_eq!(v, b"s = \"abc 123\""); +/// Ok(()) +/// } /// ``` /// /// Note: This macro can be used in `no_std` setups as well. @@ -396,14 +404,17 @@ macro_rules! write { /// # Examples /// /// ``` -/// use std::io::Write; +/// use std::io::{Write, Result}; /// -/// let mut w = Vec::new(); -/// writeln!(&mut w).unwrap(); -/// writeln!(&mut w, "test").unwrap(); -/// writeln!(&mut w, "formatted {}", "arguments").unwrap(); +/// fn main() -> Result<()> { +/// let mut w = Vec::new(); +/// writeln!(&mut w)?; +/// writeln!(&mut w, "test")?; +/// writeln!(&mut w, "formatted {}", "arguments")?; /// -/// assert_eq!(&w[..], "\ntest\nformatted arguments\n".as_bytes()); +/// assert_eq!(&w[..], "\ntest\nformatted arguments\n".as_bytes()); +/// Ok(()) +/// } /// ``` /// /// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects @@ -414,11 +425,15 @@ macro_rules! write { /// use std::fmt::Write as FmtWrite; /// use std::io::Write as IoWrite; /// -/// let mut s = String::new(); -/// let mut v = Vec::new(); -/// writeln!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt -/// writeln!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt -/// assert_eq!(v, b"s = \"abc 123\\n\"\n"); +/// fn main() -> Result<(), Box> { +/// let mut s = String::new(); +/// let mut v = Vec::new(); +/// +/// writeln!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt +/// writeln!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt +/// assert_eq!(v, b"s = \"abc 123\\n\"\n"); +/// Ok(()) +/// } /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] @@ -623,202 +638,684 @@ macro_rules! todo { /// Creates an array of [`MaybeUninit`]. /// /// This macro constructs an uninitialized array of the type `[MaybeUninit; N]`. +/// It exists solely because bootstrap does not yet support const array-init expressions. /// /// [`MaybeUninit`]: mem/union.MaybeUninit.html +// FIXME: Remove both versions of this macro once bootstrap is 1.38. #[macro_export] #[unstable(feature = "maybe_uninit_array", issue = "53491")] -macro_rules! uninitialized_array { +#[cfg(bootstrap)] +macro_rules! uninit_array { // This `assume_init` is safe because an array of `MaybeUninit` does not // require initialization. - // FIXME(#49147): Could be replaced by an array initializer, once those can - // be any const expression. ($t:ty; $size:expr) => (unsafe { MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init() }); } -/// Built-in macros to the compiler itself. +/// Creates an array of [`MaybeUninit`]. /// -/// These macros do not have any corresponding definition with a `macro_rules!` -/// macro, but are documented here. Their implementations can be found hardcoded -/// into libsyntax itself. +/// This macro constructs an uninitialized array of the type `[MaybeUninit; N]`. +/// It exists solely because bootstrap does not yet support const array-init expressions. +/// +/// [`MaybeUninit`]: mem/union.MaybeUninit.html +// FIXME: Just inline this version of the macro once bootstrap is 1.38. +#[macro_export] +#[unstable(feature = "maybe_uninit_array", issue = "53491")] +#[cfg(not(bootstrap))] +macro_rules! uninit_array { + ($t:ty; $size:expr) => ( + [MaybeUninit::<$t>::UNINIT; $size] + ); +} + +/// Definitions of built-in macros. /// -/// For more information, see documentation for `std`'s macros. -#[cfg(rustdoc)] -mod builtin { +/// Most of the macro properties (stability, visibility, etc.) are taken from the source code here, +/// with exception of expansion functions transforming macro inputs into outputs, +/// those functions are provided by the compiler. +#[cfg(not(bootstrap))] +pub(crate) mod builtin { /// Causes compilation to fail with the given error message when encountered. /// - /// For more information, see the documentation for [`std::compile_error!`]. + /// This macro should be used when a crate uses a conditional compilation strategy to provide + /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`], + /// but emits an error during *compilation* rather than at *runtime*. + /// + /// # Examples + /// + /// Two such examples are macros and `#[cfg]` environments. + /// + /// Emit better compiler error if a macro is passed invalid values. Without the final branch, + /// the compiler would still emit an error, but the error's message would not mention the two + /// valid values. /// - /// [`std::compile_error!`]: ../std/macro.compile_error.html + /// ```compile_fail + /// macro_rules! give_me_foo_or_bar { + /// (foo) => {}; + /// (bar) => {}; + /// ($x:ident) => { + /// compile_error!("This macro only accepts `foo` or `bar`"); + /// } + /// } + /// + /// give_me_foo_or_bar!(neither); + /// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`" + /// ``` + /// + /// Emit compiler error if one of a number of features isn't available. + /// + /// ```compile_fail + /// #[cfg(not(any(feature = "foo", feature = "bar")))] + /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate."); + /// ``` + /// + /// [`panic!`]: ../std/macro.panic.html #[stable(feature = "compile_error_macro", since = "1.20.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! compile_error { ($msg:expr) => ({ /* compiler built-in */ }); - ($msg:expr,) => ({ /* compiler built-in */ }); + ($msg:expr,) => ({ /* compiler built-in */ }) } /// Constructs parameters for the other string-formatting macros. /// - /// For more information, see the documentation for [`std::format_args!`]. + /// This macro functions by taking a formatting string literal containing + /// `{}` for each additional argument passed. `format_args!` prepares the + /// additional parameters to ensure the output can be interpreted as a string + /// and canonicalizes the arguments into a single type. Any value that implements + /// the [`Display`] trait can be passed to `format_args!`, as can any + /// [`Debug`] implementation be passed to a `{:?}` within the formatting string. + /// + /// This macro produces a value of type [`fmt::Arguments`]. This value can be + /// passed to the macros within [`std::fmt`] for performing useful redirection. + /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are + /// proxied through this one. `format_args!`, unlike its derived macros, avoids + /// heap allocations. + /// + /// You can use the [`fmt::Arguments`] value that `format_args!` returns + /// in `Debug` and `Display` contexts as seen below. The example also shows + /// that `Debug` and `Display` format to the same thing: the interpolated + /// format string in `format_args!`. + /// + /// ```rust + /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); + /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2)); + /// assert_eq!("1 foo 2", display); + /// assert_eq!(display, debug); + /// ``` /// - /// [`std::format_args!`]: ../std/macro.format_args.html + /// For more information, see the documentation in [`std::fmt`]. + /// + /// [`Display`]: ../std/fmt/trait.Display.html + /// [`Debug`]: ../std/fmt/trait.Debug.html + /// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html + /// [`std::fmt`]: ../std/fmt/index.html + /// [`format!`]: ../std/macro.format.html + /// [`write!`]: ../std/macro.write.html + /// [`println!`]: ../std/macro.println.html + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// let s = fmt::format(format_args!("hello {}", "world")); + /// assert_eq!(s, format!("hello {}", "world")); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[allow_internal_unstable(fmt_internals)] + #[rustc_builtin_macro] + #[macro_export] + #[rustc_macro_transparency = "opaque"] macro_rules! format_args { ($fmt:expr) => ({ /* compiler built-in */ }); - ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); + ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) + } + + /// Same as `format_args`, but adds a newline in the end. + #[unstable(feature = "format_args_nl", issue = "0", + reason = "`format_args_nl` is only for internal \ + language use and is subject to change")] + #[allow_internal_unstable(fmt_internals)] + #[rustc_builtin_macro] + #[macro_export] + #[rustc_macro_transparency = "opaque"] + macro_rules! format_args_nl { + ($fmt:expr) => ({ /* compiler built-in */ }); + ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) } /// Inspects an environment variable at compile time. /// - /// For more information, see the documentation for [`std::env!`]. + /// This macro will expand to the value of the named environment variable at + /// compile time, yielding an expression of type `&'static str`. + /// + /// If the environment variable is not defined, then a compilation error + /// will be emitted. To not emit a compile error, use the [`option_env!`] + /// macro instead. /// - /// [`std::env!`]: ../std/macro.env.html + /// [`option_env!`]: ../std/macro.option_env.html + /// + /// # Examples + /// + /// ``` + /// let path: &'static str = env!("PATH"); + /// println!("the $PATH variable at the time of compiling was: {}", path); + /// ``` + /// + /// You can customize the error message by passing a string as the second + /// parameter: + /// + /// ```compile_fail + /// let doc: &'static str = env!("documentation", "what's that?!"); + /// ``` + /// + /// If the `documentation` environment variable is not defined, you'll get + /// the following error: + /// + /// ```text + /// error: what's that?! + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }); - ($name:expr,) => ({ /* compiler built-in */ }); + ($name:expr,) => ({ /* compiler built-in */ }) } /// Optionally inspects an environment variable at compile time. /// - /// For more information, see the documentation for [`std::option_env!`]. + /// If the named environment variable is present at compile time, this will + /// expand into an expression of type `Option<&'static str>` whose value is + /// `Some` of the value of the environment variable. If the environment + /// variable is not present, then this will expand to `None`. See + /// [`Option`][option] for more information on this type. + /// + /// A compile time error is never emitted when using this macro regardless + /// of whether the environment variable is present or not. /// - /// [`std::option_env!`]: ../std/macro.option_env.html + /// [option]: ../std/option/enum.Option.html + /// + /// # Examples + /// + /// ``` + /// let key: Option<&'static str> = option_env!("SECRET_KEY"); + /// println!("the secret key might be: {:?}", key); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }); - ($name:expr,) => ({ /* compiler built-in */ }); + ($name:expr,) => ({ /* compiler built-in */ }) } /// Concatenates identifiers into one identifier. /// - /// For more information, see the documentation for [`std::concat_idents!`]. + /// This macro takes any number of comma-separated identifiers, and + /// concatenates them all into one, yielding an expression which is a new + /// identifier. Note that hygiene makes it such that this macro cannot + /// capture local variables. Also, as a general rule, macros are only + /// allowed in item, statement or expression position. That means while + /// you may use this macro for referring to existing variables, functions or + /// modules etc, you cannot define a new one with it. + /// + /// # Examples + /// + /// ``` + /// #![feature(concat_idents)] /// - /// [`std::concat_idents!`]: ../std/macro.concat_idents.html - #[unstable(feature = "concat_idents_macro", issue = "29599")] - #[rustc_doc_only_macro] + /// # fn main() { + /// fn foobar() -> u32 { 23 } + /// + /// let f = concat_idents!(foo, bar); + /// println!("{}", f()); + /// + /// // fn concat_idents!(new, fun, name) { } // not usable in this way! + /// # } + /// ``` + #[unstable(feature = "concat_idents", issue = "29599", + reason = "`concat_idents` is not stable enough for use and is subject to change")] + #[rustc_builtin_macro] + #[macro_export] macro_rules! concat_idents { ($($e:ident),+) => ({ /* compiler built-in */ }); - ($($e:ident,)+) => ({ /* compiler built-in */ }); + ($($e:ident,)+) => ({ /* compiler built-in */ }) } /// Concatenates literals into a static string slice. /// - /// For more information, see the documentation for [`std::concat!`]. + /// This macro takes any number of comma-separated literals, yielding an + /// expression of type `&'static str` which represents all of the literals + /// concatenated left-to-right. + /// + /// Integer and floating point literals are stringified in order to be + /// concatenated. /// - /// [`std::concat!`]: ../std/macro.concat.html + /// # Examples + /// + /// ``` + /// let s = concat!("test", 10, 'b', true); + /// assert_eq!(s, "test10btrue"); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }); - ($($e:expr,)*) => ({ /* compiler built-in */ }); + ($($e:expr,)*) => ({ /* compiler built-in */ }) } /// Expands to the line number on which it was invoked. /// - /// For more information, see the documentation for [`std::line!`]. + /// With [`column!`] and [`file!`], these macros provide debugging information for + /// developers about the location within the source. + /// + /// The expanded expression has type `u32` and is 1-based, so the first line + /// in each file evaluates to 1, the second to 2, etc. This is consistent + /// with error messages by common compilers or popular editors. + /// The returned line is *not necessarily* the line of the `line!` invocation itself, + /// but rather the first macro invocation leading up to the invocation + /// of the `line!` macro. + /// + /// [`column!`]: macro.column.html + /// [`file!`]: macro.file.html + /// + /// # Examples /// - /// [`std::line!`]: ../std/macro.line.html + /// ``` + /// let current_line = line!(); + /// println!("defined on line: {}", current_line); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! line { () => ({ /* compiler built-in */ }) } + #[rustc_builtin_macro] + #[macro_export] + macro_rules! line { () => { /* compiler built-in */ } } - /// Expands to the column number on which it was invoked. + /// Expands to the column number at which it was invoked. + /// + /// With [`line!`] and [`file!`], these macros provide debugging information for + /// developers about the location within the source. + /// + /// The expanded expression has type `u32` and is 1-based, so the first column + /// in each line evaluates to 1, the second to 2, etc. This is consistent + /// with error messages by common compilers or popular editors. + /// The returned column is *not necessarily* the line of the `column!` invocation itself, + /// but rather the first macro invocation leading up to the invocation + /// of the `column!` macro. + /// + /// [`line!`]: macro.line.html + /// [`file!`]: macro.file.html /// - /// For more information, see the documentation for [`std::column!`]. + /// # Examples /// - /// [`std::column!`]: ../std/macro.column.html + /// ``` + /// let current_col = column!(); + /// println!("defined on column: {}", current_col); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! column { () => ({ /* compiler built-in */ }) } + #[rustc_builtin_macro] + #[macro_export] + macro_rules! column { () => { /* compiler built-in */ } } - /// Expands to the file name from which it was invoked. + /// Same as `column`, but less likely to be shadowed. + #[unstable(feature = "__rust_unstable_column", issue = "0", + reason = "internal implementation detail of the `panic` macro")] + #[rustc_builtin_macro] + #[macro_export] + macro_rules! __rust_unstable_column { () => { /* compiler built-in */ } } + + /// Expands to the file name in which it was invoked. + /// + /// With [`line!`] and [`column!`], these macros provide debugging information for + /// developers about the location within the source. + /// + /// + /// The expanded expression has type `&'static str`, and the returned file + /// is not the invocation of the `file!` macro itself, but rather the + /// first macro invocation leading up to the invocation of the `file!` + /// macro. /// - /// For more information, see the documentation for [`std::file!`]. + /// [`line!`]: macro.line.html + /// [`column!`]: macro.column.html /// - /// [`std::file!`]: ../std/macro.file.html + /// # Examples + /// + /// ``` + /// let this_file = file!(); + /// println!("defined in file: {}", this_file); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! file { () => ({ /* compiler built-in */ }) } + #[rustc_builtin_macro] + #[macro_export] + macro_rules! file { () => { /* compiler built-in */ } } /// Stringifies its arguments. /// - /// For more information, see the documentation for [`std::stringify!`]. + /// This macro will yield an expression of type `&'static str` which is the + /// stringification of all the tokens passed to the macro. No restrictions + /// are placed on the syntax of the macro invocation itself. + /// + /// Note that the expanded results of the input tokens may change in the + /// future. You should be careful if you rely on the output. /// - /// [`std::stringify!`]: ../std/macro.stringify.html + /// # Examples + /// + /// ``` + /// let one_plus_one = stringify!(1 + 1); + /// assert_eq!(one_plus_one, "1 + 1"); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) } + #[rustc_builtin_macro] + #[macro_export] + macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } } /// Includes a utf8-encoded file as a string. /// - /// For more information, see the documentation for [`std::include_str!`]. + /// The file is located relative to the current file. (similarly to how + /// modules are found) + /// + /// This macro will yield an expression of type `&'static str` which is the + /// contents of the file. /// - /// [`std::include_str!`]: ../std/macro.include_str.html + /// # Examples + /// + /// Assume there are two files in the same directory with the following + /// contents: + /// + /// File 'spanish.in': + /// + /// ```text + /// adiós + /// ``` + /// + /// File 'main.rs': + /// + /// ```ignore (cannot-doctest-external-file-dependency) + /// fn main() { + /// let my_str = include_str!("spanish.in"); + /// assert_eq!(my_str, "adiós\n"); + /// print!("{}", my_str); + /// } + /// ``` + /// + /// Compiling 'main.rs' and running the resulting binary will print "adiós". #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }); - ($file:expr,) => ({ /* compiler built-in */ }); + ($file:expr,) => ({ /* compiler built-in */ }) } /// Includes a file as a reference to a byte array. /// - /// For more information, see the documentation for [`std::include_bytes!`]. + /// The file is located relative to the current file. (similarly to how + /// modules are found) + /// + /// This macro will yield an expression of type `&'static [u8; N]` which is + /// the contents of the file. /// - /// [`std::include_bytes!`]: ../std/macro.include_bytes.html + /// # Examples + /// + /// Assume there are two files in the same directory with the following + /// contents: + /// + /// File 'spanish.in': + /// + /// ```text + /// adiós + /// ``` + /// + /// File 'main.rs': + /// + /// ```ignore (cannot-doctest-external-file-dependency) + /// fn main() { + /// let bytes = include_bytes!("spanish.in"); + /// assert_eq!(bytes, b"adi\xc3\xb3s\n"); + /// print!("{}", String::from_utf8_lossy(bytes)); + /// } + /// ``` + /// + /// Compiling 'main.rs' and running the resulting binary will print "adiós". #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }); - ($file:expr,) => ({ /* compiler built-in */ }); + ($file:expr,) => ({ /* compiler built-in */ }) } /// Expands to a string that represents the current module path. /// - /// For more information, see the documentation for [`std::module_path!`]. + /// The current module path can be thought of as the hierarchy of modules + /// leading back up to the crate root. The first component of the path + /// returned is the name of the crate currently being compiled. + /// + /// # Examples + /// + /// ``` + /// mod test { + /// pub fn foo() { + /// assert!(module_path!().ends_with("test")); + /// } + /// } /// - /// [`std::module_path!`]: ../std/macro.module_path.html + /// test::foo(); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! module_path { () => ({ /* compiler built-in */ }) } + #[rustc_builtin_macro] + #[macro_export] + macro_rules! module_path { () => { /* compiler built-in */ } } - /// Evaluates boolean combinations of configuration flags, at compile-time. + /// Evaluates boolean combinations of configuration flags at compile-time. /// - /// For more information, see the documentation for [`std::cfg!`]. + /// In addition to the `#[cfg]` attribute, this macro is provided to allow + /// boolean expression evaluation of configuration flags. This frequently + /// leads to less duplicated code. /// - /// [`std::cfg!`]: ../std/macro.cfg.html + /// The syntax given to this macro is the same syntax as the [`cfg`] + /// attribute. + /// + /// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute + /// + /// # Examples + /// + /// ``` + /// let my_directory = if cfg!(windows) { + /// "windows-specific-directory" + /// } else { + /// "unix-directory" + /// }; + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) } + #[rustc_builtin_macro] + #[macro_export] + macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } } /// Parses a file as an expression or an item according to the context. /// - /// For more information, see the documentation for [`std::include!`]. + /// The file is located relative to the current file (similarly to how + /// modules are found). + /// + /// Using this macro is often a bad idea, because if the file is + /// parsed as an expression, it is going to be placed in the + /// surrounding code unhygienically. This could result in variables + /// or functions being different from what the file expected if + /// there are variables or functions that have the same name in + /// the current file. + /// + /// # Examples + /// + /// Assume there are two files in the same directory with the following + /// contents: + /// + /// File 'monkeys.in': /// - /// [`std::include!`]: ../std/macro.include.html + /// ```ignore (only-for-syntax-highlight) + /// ['🙈', '🙊', '🙉'] + /// .iter() + /// .cycle() + /// .take(6) + /// .collect::() + /// ``` + /// + /// File 'main.rs': + /// + /// ```ignore (cannot-doctest-external-file-dependency) + /// fn main() { + /// let my_string = include!("monkeys.in"); + /// assert_eq!("🙈🙊🙉🙈🙊🙉", my_string); + /// println!("{}", my_string); + /// } + /// ``` + /// + /// Compiling 'main.rs' and running the resulting binary will print + /// "🙈🙊🙉🙈🙊🙉". #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] + #[rustc_builtin_macro] + #[macro_export] macro_rules! include { ($file:expr) => ({ /* compiler built-in */ }); - ($file:expr,) => ({ /* compiler built-in */ }); + ($file:expr,) => ({ /* compiler built-in */ }) } /// Asserts that a boolean expression is `true` at runtime. /// - /// For more information, see the documentation for [`std::assert!`]. + /// This will invoke the [`panic!`] macro if the provided expression cannot be + /// evaluated to `true` at runtime. + /// + /// # Uses + /// + /// Assertions are always checked in both debug and release builds, and cannot + /// be disabled. See [`debug_assert!`] for assertions that are not enabled in + /// release builds by default. + /// + /// Unsafe code relies on `assert!` to enforce run-time invariants that, if + /// violated could lead to unsafety. + /// + /// Other use-cases of `assert!` include testing and enforcing run-time + /// invariants in safe code (whose violation cannot result in unsafety). + /// + /// # Custom Messages + /// + /// This macro has a second form, where a custom panic message can + /// be provided with or without arguments for formatting. See [`std::fmt`] + /// for syntax for this form. + /// + /// [`panic!`]: macro.panic.html + /// [`debug_assert!`]: macro.debug_assert.html + /// [`std::fmt`]: ../std/fmt/index.html + /// + /// # Examples + /// + /// ``` + /// // the panic message for these assertions is the stringified value of the + /// // expression given. + /// assert!(true); + /// + /// fn some_computation() -> bool { true } // a very simple function + /// + /// assert!(some_computation()); + /// + /// // assert with a custom message + /// let x = true; + /// assert!(x, "x wasn't true!"); /// - /// [`std::assert!`]: ../std/macro.assert.html - #[rustc_doc_only_macro] + /// let a = 3; let b = 27; + /// assert!(a + b == 30, "a = {}, b = {}", a, b); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_builtin_macro] + #[macro_export] macro_rules! assert { ($cond:expr) => ({ /* compiler built-in */ }); ($cond:expr,) => ({ /* compiler built-in */ }); - ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }); + ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }) } + + /// Inline assembly. + #[unstable(feature = "asm", issue = "29722", + reason = "inline assembly is not stable enough for use and is subject to change")] + #[rustc_builtin_macro] + #[macro_export] + macro_rules! asm { ("assembly template" + : $("output"(operand),)* + : $("input"(operand),)* + : $("clobbers",)* + : $("options",)*) => { /* compiler built-in */ } } + + /// Module-level inline assembly. + #[unstable(feature = "global_asm", issue = "35119", + reason = "`global_asm!` is not stable enough for use and is subject to change")] + #[rustc_builtin_macro] + #[macro_export] + macro_rules! global_asm { ("assembly") => { /* compiler built-in */ } } + + /// Prints passed tokens into the standard output. + #[unstable(feature = "log_syntax", issue = "29598", + reason = "`log_syntax!` is not stable enough for use and is subject to change")] + #[rustc_builtin_macro] + #[macro_export] + macro_rules! log_syntax { ($($arg:tt)*) => { /* compiler built-in */ } } + + /// Enables or disables tracing functionality used for debugging other macros. + #[unstable(feature = "trace_macros", issue = "29598", + reason = "`trace_macros` is not stable enough for use and is subject to change")] + #[rustc_builtin_macro] + #[macro_export] + macro_rules! trace_macros { + (true) => ({ /* compiler built-in */ }); + (false) => ({ /* compiler built-in */ }) + } + + /// Attribute macro applied to a function to turn it into a unit test. + #[stable(feature = "rust1", since = "1.0.0")] + #[allow_internal_unstable(test, rustc_attrs)] + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + pub macro test($item:item) { /* compiler built-in */ } + + /// Attribute macro applied to a function to turn it into a benchmark test. + #[cfg_attr(not(boostrap_stdarch_ignore_this), unstable(soft, feature = "test", issue = "50297", + reason = "`bench` is a part of custom test frameworks which are unstable"))] + #[cfg_attr(boostrap_stdarch_ignore_this, unstable(feature = "test", issue = "50297", + reason = "`bench` is a part of custom test frameworks which are unstable"))] + #[allow_internal_unstable(test, rustc_attrs)] + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + pub macro bench($item:item) { /* compiler built-in */ } + + /// An implementation detail of the `#[test]` and `#[bench]` macros. + #[unstable(feature = "custom_test_frameworks", issue = "50297", + reason = "custom test frameworks are an unstable feature")] + #[allow_internal_unstable(test, rustc_attrs)] + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + pub macro test_case($item:item) { /* compiler built-in */ } + + /// Attribute macro applied to a static to register it as a global allocator. + #[stable(feature = "global_allocator", since = "1.28.0")] + #[allow_internal_unstable(rustc_attrs)] + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + pub macro global_allocator($item:item) { /* compiler built-in */ } + + /// Unstable implementation detail of the `rustc` compiler, do not use. + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + #[stable(feature = "rust1", since = "1.0.0")] + #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)] + pub macro RustcDecodable($item:item) { /* compiler built-in */ } + + /// Unstable implementation detail of the `rustc` compiler, do not use. + #[rustc_builtin_macro] + #[rustc_macro_transparency = "semitransparent"] + #[stable(feature = "rust1", since = "1.0.0")] + #[allow_internal_unstable(core_intrinsics)] + pub macro RustcEncodable($item:item) { /* compiler built-in */ } } diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index d9757d78dc..78a2736116 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -288,6 +288,14 @@ pub trait Copy : Clone { // Empty. } +/// Derive macro generating an impl of the trait `Copy`. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[rustc_macro_transparency = "semitransparent"] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow_internal_unstable(core_intrinsics, derive_clone_copy)] +pub macro Copy($item:item) { /* compiler built-in */ } + /// Types for which it is safe to share references between threads. /// /// This trait is automatically implemented when the compiler determines @@ -498,7 +506,7 @@ macro_rules! impls{ /// # end: *const T, /// # phantom: PhantomData<&'a T>, /// # } -/// fn borrow_vec<'a, T>(vec: &'a Vec) -> Slice<'a, T> { +/// fn borrow_vec(vec: &Vec) -> Slice<'_, T> { /// let ptr = vec.as_ptr(); /// Slice { /// start: ptr, @@ -655,6 +663,12 @@ impl<'a, T: ?Sized + 'a> Unpin for &'a T {} #[stable(feature = "pin", since = "1.33.0")] impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {} +#[stable(feature = "pin_raw", since = "1.38.0")] +impl Unpin for *const T {} + +#[stable(feature = "pin_raw", since = "1.38.0")] +impl Unpin for *mut T {} + /// Implementations of `Copy` for primitive types. /// /// Implementations that cannot be described in Rust diff --git a/src/libcore/mem/manually_drop.rs b/src/libcore/mem/manually_drop.rs index 3ad1223e33..bb35399323 100644 --- a/src/libcore/mem/manually_drop.rs +++ b/src/libcore/mem/manually_drop.rs @@ -119,6 +119,8 @@ impl ManuallyDrop { /// This function runs the destructor of the contained value and thus the wrapped value /// now represents uninitialized data. It is up to the user of this method to ensure the /// uninitialized data is not actually used. + /// In particular, this function can only be called called at most once + /// for a given instance of `ManuallyDrop`. /// /// [`ManuallyDrop::into_inner`]: #method.into_inner #[stable(feature = "manually_drop", since = "1.20.0")] diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 28e1e22ba7..1bbea02e0c 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -13,6 +13,7 @@ use crate::mem::ManuallyDrop; /// ever gets used to access memory: /// /// ```rust,no_run +/// # #![allow(invalid_value)] /// use std::mem::{self, MaybeUninit}; /// /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! @@ -27,6 +28,7 @@ use crate::mem::ManuallyDrop; /// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior: /// /// ```rust,no_run +/// # #![allow(invalid_value)] /// use std::mem::{self, MaybeUninit}; /// /// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! @@ -40,6 +42,7 @@ use crate::mem::ManuallyDrop; /// which otherwise can hold any *fixed* bit pattern: /// /// ```rust,no_run +/// # #![allow(invalid_value)] /// use std::mem::{self, MaybeUninit}; /// /// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! @@ -51,7 +54,8 @@ use crate::mem::ManuallyDrop; /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] -/// is considered initialized because the only requirement the compiler knows about it +/// is considered initialized (under the current implementation; this does not constitute +/// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most /// safe operations (including dropping it). @@ -112,7 +116,6 @@ use crate::mem::ManuallyDrop; /// /// ``` /// use std::mem::{self, MaybeUninit}; -/// use std::ptr; /// /// let data = { /// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is @@ -122,10 +125,13 @@ use crate::mem::ManuallyDrop; /// MaybeUninit::uninit().assume_init() /// }; /// -/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop, -/// // we have a memory leak, but there is no memory safety issue. +/// // Dropping a `MaybeUninit` does nothing. Thus using raw pointer +/// // assignment instead of `ptr::write` does not cause the old +/// // uninitialized value to be dropped. Also if there is a panic during +/// // this loop, we have a memory leak, but there is no memory safety +/// // issue. /// for elem in &mut data[..] { -/// unsafe { ptr::write(elem.as_mut_ptr(), vec![42]); } +/// *elem = MaybeUninit::new(vec![42]); /// } /// /// // Everything is initialized. Transmute the array to the @@ -151,7 +157,7 @@ use crate::mem::ManuallyDrop; /// let mut data_len: usize = 0; /// /// for elem in &mut data[0..500] { -/// unsafe { ptr::write(elem.as_mut_ptr(), String::from("hello")); } +/// *elem = MaybeUninit::new(String::from("hello")); /// data_len += 1; /// } /// @@ -206,8 +212,10 @@ use crate::mem::ManuallyDrop; /// guarantee may evolve. #[allow(missing_debug_implementations)] #[stable(feature = "maybe_uninit", since = "1.36.0")] +// Lang item so we can wrap other types in it. This is useful for generators. +#[cfg_attr(not(bootstrap), lang = "maybe_uninit")] #[derive(Copy)] -#[cfg_attr(not(bootstrap), repr(transparent))] +#[repr(transparent)] pub union MaybeUninit { uninit: (), value: ManuallyDrop, @@ -250,6 +258,11 @@ impl MaybeUninit { MaybeUninit { uninit: () } } + /// A promotable constant, equivalent to `uninit()`. + #[unstable(feature = "internal_uninit_const", issue = "0", + reason = "hack to work around promotability")] + pub const UNINIT: Self = Self::uninit(); + /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, @@ -395,6 +408,14 @@ impl MaybeUninit { /// /// [inv]: #initialization-invariant /// + /// On top of that, remember that most types have additional invariants beyond merely + /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] + /// is considered initialized (under the current implementation; this does not constitute + /// a stable guarantee) because the only requirement the compiler knows about it + /// is that the data pointer must be non-null. Creating such a `Vec` does not cause + /// *immediate* undefined behavior, but will cause undefined behavior with most + /// safe operations (including dropping it). + /// /// # Examples /// /// Correct usage of this method: @@ -427,7 +448,7 @@ impl MaybeUninit { /// Reads the value from the `MaybeUninit` container. The resulting `T` is subject /// to the usual drop handling. /// - /// Whenever possible, it is preferrable to use [`assume_init`] instead, which + /// Whenever possible, it is preferable to use [`assume_init`] instead, which /// prevents duplicating the content of the `MaybeUninit`. /// /// # Safety diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index e110e93a95..2534400b83 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -414,10 +414,10 @@ pub const fn needs_drop() -> bool { intrinsics::needs_drop::() } -/// Creates a value whose bytes are all zero. +/// Returns the value of type `T` represented by the all-zero byte-pattern. /// -/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed]. -/// It is useful for FFI sometimes, but should generally be avoided. +/// This means that, for example, the padding byte in `(u8, u16)` is not +/// necessarily zeroed. /// /// There is no guarantee that an all-zero byte-pattern represents a valid value of /// some type `T`. For example, the all-zero byte-pattern is not a valid value @@ -425,6 +425,9 @@ pub const fn needs_drop() -> bool { /// causes immediate [undefined behavior][ub] because [the Rust compiler assumes][inv] /// that there always is a valid value in a variable it considers initialized. /// +/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed]. +/// It is useful for FFI sometimes, but should generally be avoided. +/// /// [zeroed]: union.MaybeUninit.html#method.zeroed /// [ub]: ../../reference/behavior-considered-undefined.html /// [inv]: union.MaybeUninit.html#initialization-invariant @@ -442,13 +445,16 @@ pub const fn needs_drop() -> bool { /// /// *Incorrect* usage of this function: initializing a reference with zero. /// -/// ```no_run +/// ```rust,no_run +/// # #![allow(invalid_value)] /// use std::mem; /// /// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior! /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(bootstrap, allow(deprecated_in_future))] +#[allow(deprecated)] pub unsafe fn zeroed() -> T { intrinsics::panic_if_uninhabited::(); intrinsics::init() @@ -457,7 +463,7 @@ pub unsafe fn zeroed() -> T { /// Bypasses Rust's normal memory-initialization checks by pretending to /// produce a value of type `T`, while doing nothing at all. /// -/// **This functon is deprecated.** Use [`MaybeUninit`] instead. +/// **This function is deprecated.** Use [`MaybeUninit`] instead. /// /// The reason for deprecation is that the function basically cannot be used /// correctly: [the Rust compiler assumes][inv] that values are properly initialized. @@ -473,8 +479,10 @@ pub unsafe fn zeroed() -> T { /// [`MaybeUninit`]: union.MaybeUninit.html /// [inv]: union.MaybeUninit.html#initialization-invariant #[inline] -#[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")] +#[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(bootstrap, allow(deprecated_in_future))] +#[allow(deprecated)] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); intrinsics::uninit() @@ -552,6 +560,12 @@ pub fn swap(x: &mut T, y: &mut T) { /// mem::take(&mut self.buf) /// } /// } +/// +/// let mut buffer = Buffer { buf: vec![0, 1] }; +/// assert_eq!(buffer.buf.len(), 2); +/// +/// assert_eq!(buffer.get_and_reset(), vec![0, 1]); +/// assert_eq!(buffer.buf.len(), 0); /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html @@ -586,17 +600,17 @@ pub fn take(dest: &mut T) -> T { /// struct Buffer { buf: Vec } /// /// impl Buffer { -/// fn get_and_reset(&mut self) -> Vec { +/// fn replace_index(&mut self, i: usize, v: T) -> T { /// // error: cannot move out of dereference of `&mut`-pointer -/// let buf = self.buf; -/// self.buf = Vec::new(); -/// buf +/// let t = self.buf[i]; +/// self.buf[i] = v; +/// t /// } /// } /// ``` /// -/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset -/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from +/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to +/// avoid the move. But `replace` can be used to disassociate the original value at that index from /// `self`, allowing it to be returned: /// /// ``` @@ -605,10 +619,16 @@ pub fn take(dest: &mut T) -> T { /// /// # struct Buffer { buf: Vec } /// impl Buffer { -/// fn get_and_reset(&mut self) -> Vec { -/// mem::replace(&mut self.buf, Vec::new()) +/// fn replace_index(&mut self, i: usize, v: T) -> T { +/// mem::replace(&mut self.buf[i], v) /// } /// } +/// +/// let mut buffer = Buffer { buf: vec![0, 1] }; +/// assert_eq!(buffer.buf[0], 0); +/// +/// assert_eq!(buffer.replace_index(0, 2), 0); +/// assert_eq!(buffer.buf[0], 2); /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 0bcd371b52..8ff78166a9 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -450,10 +450,8 @@ impl f32 { /// # Examples /// /// ``` - /// use std::f32; /// let v = f32::from_bits(0x41480000); - /// let difference = (v - 12.5).abs(); - /// assert!(difference <= 1e-5); + /// assert_eq!(v, 12.5); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] #[inline] @@ -461,4 +459,121 @@ impl f32 { // It turns out the safety issues with sNaN were overblown! Hooray! unsafe { mem::transmute(v) } } + + /// Return the memory representation of this floating point number as a byte array in + /// big-endian (network) byte order. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let bytes = 12.5f32.to_be_bytes(); + /// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn to_be_bytes(self) -> [u8; 4] { + self.to_bits().to_be_bytes() + } + + /// Return the memory representation of this floating point number as a byte array in + /// little-endian byte order. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let bytes = 12.5f32.to_le_bytes(); + /// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn to_le_bytes(self) -> [u8; 4] { + self.to_bits().to_le_bytes() + } + + /// Return the memory representation of this floating point number as a byte array in + /// native byte order. + /// + /// As the target platform's native endianness is used, portable code + /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead. + /// + /// [`to_be_bytes`]: #method.to_be_bytes + /// [`to_le_bytes`]: #method.to_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let bytes = 12.5f32.to_ne_bytes(); + /// assert_eq!( + /// bytes, + /// if cfg!(target_endian = "big") { + /// [0x41, 0x48, 0x00, 0x00] + /// } else { + /// [0x00, 0x00, 0x48, 0x41] + /// } + /// ); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn to_ne_bytes(self) -> [u8; 4] { + self.to_bits().to_ne_bytes() + } + + /// Create a floating point value from its representation as a byte array in big endian. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let value = f32::from_be_bytes([0x41, 0x48, 0x00, 0x00]); + /// assert_eq!(value, 12.5); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn from_be_bytes(bytes: [u8; 4]) -> Self { + Self::from_bits(u32::from_be_bytes(bytes)) + } + + /// Create a floating point value from its representation as a byte array in little endian. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let value = f32::from_le_bytes([0x00, 0x00, 0x48, 0x41]); + /// assert_eq!(value, 12.5); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn from_le_bytes(bytes: [u8; 4]) -> Self { + Self::from_bits(u32::from_le_bytes(bytes)) + } + + /// Create a floating point value from its representation as a byte array in native endian. + /// + /// As the target platform's native endianness is used, portable code + /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as + /// appropriate instead. + /// + /// [`from_be_bytes`]: #method.from_be_bytes + /// [`from_le_bytes`]: #method.from_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let value = f32::from_ne_bytes(if cfg!(target_endian = "big") { + /// [0x41, 0x48, 0x00, 0x00] + /// } else { + /// [0x00, 0x00, 0x48, 0x41] + /// }); + /// assert_eq!(value, 12.5); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn from_ne_bytes(bytes: [u8; 4]) -> Self { + Self::from_bits(u32::from_ne_bytes(bytes)) + } } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 4d4a2c9c5a..d45c04f45a 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -463,10 +463,8 @@ impl f64 { /// # Examples /// /// ``` - /// use std::f64; /// let v = f64::from_bits(0x4029000000000000); - /// let difference = (v - 12.5).abs(); - /// assert!(difference <= 1e-5); + /// assert_eq!(v, 12.5); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] #[inline] @@ -474,4 +472,121 @@ impl f64 { // It turns out the safety issues with sNaN were overblown! Hooray! unsafe { mem::transmute(v) } } + + /// Return the memory representation of this floating point number as a byte array in + /// big-endian (network) byte order. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let bytes = 12.5f64.to_be_bytes(); + /// assert_eq!(bytes, [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn to_be_bytes(self) -> [u8; 8] { + self.to_bits().to_be_bytes() + } + + /// Return the memory representation of this floating point number as a byte array in + /// little-endian byte order. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let bytes = 12.5f64.to_le_bytes(); + /// assert_eq!(bytes, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn to_le_bytes(self) -> [u8; 8] { + self.to_bits().to_le_bytes() + } + + /// Return the memory representation of this floating point number as a byte array in + /// native byte order. + /// + /// As the target platform's native endianness is used, portable code + /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead. + /// + /// [`to_be_bytes`]: #method.to_be_bytes + /// [`to_le_bytes`]: #method.to_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let bytes = 12.5f64.to_ne_bytes(); + /// assert_eq!( + /// bytes, + /// if cfg!(target_endian = "big") { + /// [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + /// } else { + /// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40] + /// } + /// ); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn to_ne_bytes(self) -> [u8; 8] { + self.to_bits().to_ne_bytes() + } + + /// Create a floating point value from its representation as a byte array in big endian. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let value = f64::from_be_bytes([0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); + /// assert_eq!(value, 12.5); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn from_be_bytes(bytes: [u8; 8]) -> Self { + Self::from_bits(u64::from_be_bytes(bytes)) + } + + /// Create a floating point value from its representation as a byte array in little endian. + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let value = f64::from_le_bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]); + /// assert_eq!(value, 12.5); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn from_le_bytes(bytes: [u8; 8]) -> Self { + Self::from_bits(u64::from_le_bytes(bytes)) + } + + /// Create a floating point value from its representation as a byte array in native endian. + /// + /// As the target platform's native endianness is used, portable code + /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as + /// appropriate instead. + /// + /// [`from_be_bytes`]: #method.from_be_bytes + /// [`from_le_bytes`]: #method.from_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(float_to_from_bytes)] + /// let value = f64::from_ne_bytes(if cfg!(target_endian = "big") { + /// [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + /// } else { + /// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40] + /// }); + /// assert_eq!(value, 12.5); + /// ``` + #[unstable(feature = "float_to_from_bytes", issue = "60446")] + #[inline] + pub fn from_ne_bytes(bytes: [u8; 8]) -> Self { + Self::from_bits(u64::from_ne_bytes(bytes)) + } } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d70f556701..67e30e7ffc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -50,7 +50,7 @@ assert_eq!(size_of::>(), size_of::<", s #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] - #[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)] + #[rustc_nonnull_optimization_guaranteed] pub struct $Ty($Int); } @@ -717,13 +717,12 @@ returning `None` if `rhs == 0` or the division results in overflow. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!((", stringify!($SelfT), "::min_value() + 1).checked_div_euclid(-1), Some(", stringify!($Max), ")); assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euclid(-1), None); assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -774,14 +773,13 @@ if `rhs == 0` or the division results in overflow. Basic usage: ``` -#![feature(euclidean_division)] use std::", stringify!($SelfT), "; assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1)); assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1210,11 +1208,10 @@ This function will panic if `rhs` is 0. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); assert_eq!((-128i8).wrapping_div_euclid(-1), -128); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1269,11 +1266,10 @@ This function will panic if `rhs` is 0. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); assert_eq!((-128i8).wrapping_rem_euclid(-1), 0); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1566,7 +1562,6 @@ This function will panic if `rhs` is 0. Basic usage: ``` -#![feature(euclidean_division)] use std::", stringify!($SelfT), "; assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false)); @@ -1574,7 +1569,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi "::MIN, true)); ```"), #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { @@ -1636,13 +1631,12 @@ This function will panic if `rhs` is 0. Basic usage: ``` -#![feature(euclidean_division)] use std::", stringify!($SelfT), "; assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true)); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1873,7 +1867,6 @@ This function will panic if `rhs` is 0. Basic usage: ``` -#![feature(euclidean_division)] let a: ", stringify!($SelfT), " = 7; // or any other integer type let b = 4; @@ -1882,7 +1875,7 @@ assert_eq!(a.div_euclid(-b), -1); // 7 >= -4 * -1 assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2 assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2 ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1913,7 +1906,6 @@ This function will panic if `rhs` is 0. Basic usage: ``` -#![feature(euclidean_division)] let a: ", stringify!($SelfT), " = 7; // or any other integer type let b = 4; @@ -1922,7 +1914,7 @@ assert_eq!((-a).rem_euclid(b), 1); assert_eq!(a.rem_euclid(-b), 3); assert_eq!((-a).rem_euclid(-b), 1); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2753,11 +2745,10 @@ if `rhs == 0`. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64)); assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2805,11 +2796,10 @@ if `rhs == 0`. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1)); assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3127,10 +3117,9 @@ is exactly equal to `self.wrapping_div(rhs)`. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3179,10 +3168,9 @@ is exactly equal to `self.wrapping_rem(rhs)`. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3448,11 +3436,10 @@ This function will panic if `rhs` is 0. Basic usage ``` -#![feature(euclidean_division)] assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false)); ```"), #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { @@ -3508,11 +3495,10 @@ This function will panic if `rhs` is 0. Basic usage ``` -#![feature(euclidean_division)] assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); ```"), #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { @@ -3696,10 +3682,9 @@ is exactly equal to `self / rhs`. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -3722,10 +3707,9 @@ is exactly equal to `self % rhs`. Basic usage: ``` -#![feature(euclidean_division)] assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type ```"), - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs index c69f5fd989..b9552eaa1a 100644 --- a/src/libcore/ops/function.rs +++ b/src/libcore/ops/function.rs @@ -137,6 +137,10 @@ pub trait Fn : FnMut { #[rustc_paren_sugar] #[rustc_on_unimplemented( on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"), + on( + all(Args="(char,)", _Self="std::string::String"), + note="borrowing the `{Self}` might fix the problem" + ), message="expected a `{FnMut}<{Args}>` closure, found `{Self}`", label="expected an `FnMut<{Args}>` closure, found `{Self}`", )] diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index 3158f58e95..9cff474a76 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -105,7 +105,7 @@ pub trait Index { /// impl Index for Balance { /// type Output = Weight; /// -/// fn index<'a>(&'a self, index: Side) -> &'a Self::Output { +/// fn index(&self, index: Side) -> &Self::Output { /// println!("Accessing {:?}-side of balance immutably", index); /// match index { /// Side::Left => &self.left, @@ -115,7 +115,7 @@ pub trait Index { /// } /// /// impl IndexMut for Balance { -/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output { +/// fn index_mut(&mut self, index: Side) -> &mut Self::Output { /// println!("Accessing {:?}-side of balance mutably", index); /// match index { /// Side::Left => &mut self.left, diff --git a/src/libcore/ops/try.rs b/src/libcore/ops/try.rs index 9fa2c81954..76fec1020f 100644 --- a/src/libcore/ops/try.rs +++ b/src/libcore/ops/try.rs @@ -8,12 +8,12 @@ #[rustc_on_unimplemented( on(all( any(from_method="from_error", from_method="from_ok"), - from_desugaring="?"), + from_desugaring="QuestionMark"), message="the `?` operator can only be used in a \ function that returns `Result` or `Option` \ (or another type that implements `{Try}`)", label="cannot use the `?` operator in a function that returns `{Self}`"), - on(all(from_method="into_result", from_desugaring="?"), + on(all(from_method="into_result", from_desugaring="QuestionMark"), message="the `?` operator can only be applied to values \ that implement `{Try}`", label="the `?` operator cannot be applied to type `{Self}`") diff --git a/src/libcore/option.rs b/src/libcore/option.rs index eec4b149dd..259ed36c57 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -8,7 +8,7 @@ //! * Initial values //! * Return values for functions that are not defined //! over their entire input range (partial functions) -//! * Return value for otherwise reporting simple errors, where `None` is +//! * Return value for otherwise reporting simple errors, where [`None`] is //! returned on error //! * Optional struct fields //! * Struct fields that can be loaned or "taken" @@ -136,7 +136,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{FromIterator, FusedIterator, TrustedLen}; -use crate::{convert, hint, mem, ops::{self, Deref}}; +use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}}; use crate::pin::Pin; // Note that this is not a lang item per se, but it has a hidden dependency on @@ -178,7 +178,7 @@ impl Option { /// ``` /// /// [`Some`]: #variant.Some - #[must_use] + #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_some(&self) -> bool { @@ -201,13 +201,40 @@ impl Option { /// ``` /// /// [`None`]: #variant.None - #[must_use] + #[must_use = "if you intended to assert that this doesn't have a value, consider \ + `.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_none(&self) -> bool { !self.is_some() } + /// Returns `true` if the option is a [`Some`] value containing the given value. + /// + /// # Examples + /// + /// ``` + /// #![feature(option_result_contains)] + /// + /// let x: Option = Some(2); + /// assert_eq!(x.contains(&2), true); + /// + /// let x: Option = Some(3); + /// assert_eq!(x.contains(&2), false); + /// + /// let x: Option = None; + /// assert_eq!(x.contains(&2), false); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "option_result_contains", issue = "62358")] + pub fn contains(&self, x: &U) -> bool where U: PartialEq { + match self { + Some(y) => x == y, + None => false, + } + } + ///////////////////////////////////////////////////////////////////////// // Adapter for working with references ///////////////////////////////////////////////////////////////////////// @@ -263,7 +290,9 @@ impl Option { } - /// Converts from `Pin<&Option>` to `Option>` + /// Converts from [`Pin`]`<&Option>` to `Option<`[`Pin`]`<&T>>`. + /// + /// [`Pin`]: ../pin/struct.Pin.html #[inline] #[stable(feature = "pin", since = "1.33.0")] pub fn as_pin_ref<'a>(self: Pin<&'a Option>) -> Option> { @@ -272,7 +301,9 @@ impl Option { } } - /// Converts from `Pin<&mut Option>` to `Option>` + /// Converts from [`Pin`]`<&mut Option>` to `Option<`[`Pin`]`<&mut T>>`. + /// + /// [`Pin`]: ../pin/struct.Pin.html #[inline] #[stable(feature = "pin", since = "1.33.0")] pub fn as_pin_mut<'a>(self: Pin<&'a mut Option>) -> Option> { @@ -626,14 +657,14 @@ impl Option { } } - /// Returns `None` if the option is `None`, otherwise calls `predicate` + /// Returns [`None`] if the option is [`None`], otherwise calls `predicate` /// with the wrapped value and returns: /// - /// - `Some(t)` if `predicate` returns `true` (where `t` is the wrapped + /// - [`Some(t)`] if `predicate` returns `true` (where `t` is the wrapped /// value), and - /// - `None` if `predicate` returns `false`. + /// - [`None`] if `predicate` returns `false`. /// - /// This function works similar to `Iterator::filter()`. You can imagine + /// This function works similar to [`Iterator::filter()`]. You can imagine /// the `Option` being an iterator over one or zero elements. `filter()` /// lets you decide which elements to keep. /// @@ -648,6 +679,10 @@ impl Option { /// assert_eq!(Some(3).filter(is_even), None); /// assert_eq!(Some(4).filter(is_even), Some(4)); /// ``` + /// + /// [`None`]: #variant.None + /// [`Some(t)`]: #variant.Some + /// [`Iterator::filter()`]: ../../std/iter/trait.Iterator.html#method.filter #[inline] #[stable(feature = "option_filter", since = "1.27.0")] pub fn filter bool>(self, predicate: P) -> Self { @@ -717,7 +752,7 @@ impl Option { } } - /// Returns [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns `None`. + /// Returns [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns [`None`]. /// /// [`Some`]: #variant.Some /// [`None`]: #variant.None @@ -777,15 +812,7 @@ impl Option { #[inline] #[stable(feature = "option_entry", since = "1.20.0")] pub fn get_or_insert(&mut self, v: T) -> &mut T { - match *self { - None => *self = Some(v), - _ => (), - } - - match *self { - Some(ref mut v) => v, - None => unsafe { hint::unreachable_unchecked() }, - } + self.get_or_insert_with(|| v) } /// Inserts a value computed from `f` into the option if it is [`None`], then @@ -845,7 +872,7 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn take(&mut self) -> Option { - mem::replace(self, None) + mem::take(self) } /// Replaces the actual value in the option by the value given in parameter, @@ -950,6 +977,92 @@ impl Option<&mut T> { } } +impl Option { + /// Unwraps an option, expecting [`None`] and returning nothing. + /// + /// # Panics + /// + /// Panics if the value is a [`Some`], with a panic message including the + /// passed message, and the content of the [`Some`]. + /// + /// [`Some`]: #variant.Some + /// [`None`]: #variant.None + /// + /// # Examples + /// + /// ``` + /// #![feature(option_expect_none)] + /// + /// use std::collections::HashMap; + /// let mut squares = HashMap::new(); + /// for i in -10..=10 { + /// // This will not panic, since all keys are unique. + /// squares.insert(i, i * i).expect_none("duplicate key"); + /// } + /// ``` + /// + /// ```{.should_panic} + /// #![feature(option_expect_none)] + /// + /// use std::collections::HashMap; + /// let mut sqrts = HashMap::new(); + /// for i in -10..=10 { + /// // This will panic, since both negative and positive `i` will + /// // insert the same `i * i` key, returning the old `Some(i)`. + /// sqrts.insert(i * i, i).expect_none("duplicate key"); + /// } + /// ``` + #[inline] + #[unstable(feature = "option_expect_none", reason = "newly added", issue = "62633")] + pub fn expect_none(self, msg: &str) { + if let Some(val) = self { + expect_none_failed(msg, &val); + } + } + + /// Unwraps an option, expecting [`None`] and returning nothing. + /// + /// # Panics + /// + /// Panics if the value is a [`Some`], with a custom panic message provided + /// by the [`Some`]'s value. + /// + /// [`Some(v)`]: #variant.Some + /// [`None`]: #variant.None + /// + /// # Examples + /// + /// ``` + /// #![feature(option_unwrap_none)] + /// + /// use std::collections::HashMap; + /// let mut squares = HashMap::new(); + /// for i in -10..=10 { + /// // This will not panic, since all keys are unique. + /// squares.insert(i, i * i).unwrap_none(); + /// } + /// ``` + /// + /// ```{.should_panic} + /// #![feature(option_unwrap_none)] + /// + /// use std::collections::HashMap; + /// let mut sqrts = HashMap::new(); + /// for i in -10..=10 { + /// // This will panic, since both negative and positive `i` will + /// // insert the same `i * i` key, returning the old `Some(i)`. + /// sqrts.insert(i * i, i).unwrap_none(); + /// } + /// ``` + #[inline] + #[unstable(feature = "option_unwrap_none", reason = "newly added", issue = "62633")] + pub fn unwrap_none(self) { + if let Some(val) = self { + expect_none_failed("called `Option::unwrap_none()` on a `Some` value", &val); + } + } +} + impl Option { /// Returns the contained value or a default /// @@ -991,20 +1104,39 @@ impl Option { #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Option { - /// Converts from `&Option` to `Option<&T::Target>`. + /// Converts from `Option` (or `&Option`) to `Option<&T::Target>`. /// /// Leaves the original Option in-place, creating a new one with a reference - /// to the original one, additionally coercing the contents via `Deref`. - pub fn deref(&self) -> Option<&T::Target> { + /// to the original one, additionally coercing the contents via [`Deref`]. + /// + /// [`Deref`]: ../../std/ops/trait.Deref.html + pub fn as_deref(&self) -> Option<&T::Target> { self.as_ref().map(|t| t.deref()) } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Option { + /// Converts from `Option` (or `&mut Option`) to `Option<&mut T::Target>`. + /// + /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to + /// the inner type's `Deref::Target` type. + pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> { + self.as_mut().map(|t| t.deref_mut()) + } +} + impl Option> { - /// Transposes an `Option` of a `Result` into a `Result` of an `Option`. + /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`. + /// + /// [`None`] will be mapped to [`Ok`]`(`[`None`]`)`. + /// [`Some`]`(`[`Ok`]`(_))` and [`Some`]`(`[`Err`]`(_))` will be mapped to + /// [`Ok`]`(`[`Some`]`(_))` and [`Err`]`(_)`. /// - /// `None` will be mapped to `Ok(None)`. - /// `Some(Ok(_))` and `Some(Err(_))` will be mapped to `Ok(Some(_))` and `Err(_)`. + /// [`None`]: #variant.None + /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok + /// [`Some`]: #variant.Some + /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// /// # Examples /// @@ -1034,6 +1166,13 @@ fn expect_failed(msg: &str) -> ! { panic!("{}", msg) } +// This is a separate function to reduce the code size of .expect_none() itself. +#[inline(never)] +#[cold] +fn expect_none_failed(msg: &str, value: &dyn fmt::Debug) -> ! { + panic!("{}: {:?}", msg, value) +} + ///////////////////////////////////////////////////////////////////////////// // Trait implementations ///////////////////////////////////////////////////////////////////////////// @@ -1360,45 +1499,10 @@ impl> FromIterator> for Option { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. - struct Adapter { - iter: Iter, - found_none: bool, - } - - impl>> Iterator for Adapter { - type Item = T; - - #[inline] - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Some(value)) => Some(value), - Some(None) => { - self.found_none = true; - None - } - None => None, - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - if self.found_none { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } - } - } - - let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; - let v: V = FromIterator::from_iter(adapter.by_ref()); - - if adapter.found_none { - None - } else { - Some(v) - } + iter.into_iter() + .map(|x| x.ok_or(())) + .collect::>() + .ok() } } diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index c063cee522..6efeaf9ee7 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -11,13 +11,13 @@ //! until it gets dropped. We say that the pointee is "pinned". //! //! By default, all types in Rust are movable. Rust allows passing all types by-value, -//! and common smart-pointer types such as `Box` and `&mut T` allow replacing and -//! moving the values they contain: you can move out of a `Box`, or you can use [`mem::swap`]. -//! [`Pin

`] wraps a pointer type `P`, so `Pin>` functions much like a regular `Box`: -//! when a `Pin>` gets dropped, so do its contents, and the memory gets deallocated. -//! Similarly, `Pin<&mut T>` is a lot like `&mut T`. However, [`Pin

`] does not let clients -//! actually obtain a `Box` or `&mut T` to pinned data, which implies that you cannot use -//! operations such as [`mem::swap`]: +//! and common smart-pointer types such as [`Box`] and `&mut T` allow replacing and +//! moving the values they contain: you can move out of a [`Box`], or you can use [`mem::swap`]. +//! [`Pin

`] wraps a pointer type `P`, so [`Pin`]`<`[`Box`]`>` functions much like a regular +//! [`Box`]: when a [`Pin`]`<`[`Box`]`>` gets dropped, so do its contents, and the memory gets +//! deallocated. Similarly, [`Pin`]`<&mut T>` is a lot like `&mut T`. However, [`Pin

`] does +//! not let clients actually obtain a [`Box`] or `&mut T` to pinned data, which implies that you +//! cannot use operations such as [`mem::swap`]: //! //! ``` //! use std::pin::Pin; @@ -30,15 +30,15 @@ //! ``` //! //! It is worth reiterating that [`Pin

`] does *not* change the fact that a Rust compiler -//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, `Pin

` -//! prevents certain *values* (pointed to by pointers wrapped in `Pin

`) from being +//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, [`Pin

`] +//! prevents certain *values* (pointed to by pointers wrapped in [`Pin

`]) from being //! moved by making it impossible to call methods that require `&mut T` on them //! (like [`mem::swap`]). //! //! [`Pin

`] can be used to wrap any pointer type `P`, and as such it interacts with -//! [`Deref`] and [`DerefMut`]. A `Pin

` where `P: Deref` should be considered -//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin>` is -//! an owned pointer to a pinned `T`, and a `Pin>` is a reference-counted +//! [`Deref`] and [`DerefMut`]. A [`Pin

`] where `P: Deref` should be considered +//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a [`Pin`]`<`[`Box`]`>` is +//! an owned pointer to a pinned `T`, and a [`Pin`]`<`[`Rc`]`>` is a reference-counted //! pointer to a pinned `T`. //! For correctness, [`Pin

`] relies on the implementations of [`Deref`] and //! [`DerefMut`] not to move out of their `self` parameter, and only ever to @@ -48,15 +48,15 @@ //! //! Many types are always freely movable, even when pinned, because they do not //! rely on having a stable address. This includes all the basic types (like -//! `bool`, `i32`, and references) as well as types consisting solely of these +//! [`bool`], [`i32`], and references) as well as types consisting solely of these //! types. Types that do not care about pinning implement the [`Unpin`] //! auto-trait, which cancels the effect of [`Pin

`]. For `T: Unpin`, -//! `Pin>` and `Box` function identically, as do `Pin<&mut T>` and +//! [`Pin`]`<`[`Box`]`>` and [`Box`] function identically, as do [`Pin`]`<&mut T>` and //! `&mut T`. //! -//! Note that pinning and `Unpin` only affect the pointed-to type `P::Target`, not the pointer -//! type `P` itself that got wrapped in `Pin

`. For example, whether or not `Box` is -//! `Unpin` has no effect on the behavior of `Pin>` (here, `T` is the +//! Note that pinning and [`Unpin`] only affect the pointed-to type `P::Target`, not the pointer +//! type `P` itself that got wrapped in [`Pin

`]. For example, whether or not [`Box`] is +//! [`Unpin`] has no effect on the behavior of [`Pin`]`<`[`Box`]`>` (here, `T` is the //! pointed-to type). //! //! # Example: self-referential struct @@ -122,15 +122,15 @@ //! //! To make this work, every element has pointers to its predecessor and successor in //! the list. Elements can only be added when they are pinned, because moving the elements -//! around would invalidate the pointers. Moreover, the `Drop` implementation of a linked +//! around would invalidate the pointers. Moreover, the [`Drop`] implementation of a linked //! list element will patch the pointers of its predecessor and successor to remove itself //! from the list. //! -//! Crucially, we have to be able to rely on `drop` being called. If an element -//! could be deallocated or otherwise invalidated without calling `drop`, the pointers into it +//! Crucially, we have to be able to rely on [`drop`] being called. If an element +//! could be deallocated or otherwise invalidated without calling [`drop`], the pointers into it //! from its neighbouring elements would become invalid, which would break the data structure. //! -//! Therefore, pinning also comes with a `drop`-related guarantee. +//! Therefore, pinning also comes with a [`drop`]-related guarantee. //! //! # `Drop` guarantee //! @@ -139,7 +139,7 @@ //! otherwise invalidating the memory used to store the data is restricted, too. //! Concretely, for pinned data you have to maintain the invariant //! that *its memory will not get invalidated or repurposed from the moment it gets pinned until -//! when `drop` is called*. Memory can be invalidated by deallocation, but also by +//! when [`drop`] is called*. Memory can be invalidated by deallocation, but also by //! replacing a [`Some(v)`] by [`None`], or calling [`Vec::set_len`] to "kill" some elements //! off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without //! calling the destructor first. @@ -148,26 +148,27 @@ //! section needs to function correctly. //! //! Notice that this guarantee does *not* mean that memory does not leak! It is still -//! completely okay not ever to call `drop` on a pinned element (e.g., you can still -//! call [`mem::forget`] on a `Pin>`). In the example of the doubly-linked +//! completely okay not ever to call [`drop`] on a pinned element (e.g., you can still +//! call [`mem::forget`] on a [`Pin`]`<`[`Box`]`>`). In the example of the doubly-linked //! list, that element would just stay in the list. However you may not free or reuse the storage -//! *without calling `drop`*. +//! *without calling [`drop`]*. //! //! # `Drop` implementation //! //! If your type uses pinning (such as the two examples above), you have to be careful -//! when implementing `Drop`. The `drop` function takes `&mut self`, but this +//! when implementing [`Drop`]. The [`drop`] function takes `&mut self`, but this //! is called *even if your type was previously pinned*! It is as if the -//! compiler automatically called `get_unchecked_mut`. +//! compiler automatically called [`Pin::get_unchecked_mut`]. //! //! This can never cause a problem in safe code because implementing a type that //! relies on pinning requires unsafe code, but be aware that deciding to make //! use of pinning in your type (for example by implementing some operation on -//! `Pin<&Self>` or `Pin<&mut Self>`) has consequences for your `Drop` +//! [`Pin`]`<&Self>` or [`Pin`]`<&mut Self>`) has consequences for your [`Drop`] //! implementation as well: if an element of your type could have been pinned, -//! you must treat Drop as implicitly taking `Pin<&mut Self>`. +//! you must treat [`Drop`] as implicitly taking [`Pin`]`<&mut Self>`. //! //! For example, you could implement `Drop` as follows: +//! //! ```rust,no_run //! # use std::pin::Pin; //! # struct Type { } @@ -182,20 +183,22 @@ //! } //! } //! ``` -//! The function `inner_drop` has the type that `drop` *should* have, so this makes sure that +//! +//! The function `inner_drop` has the type that [`drop`] *should* have, so this makes sure that //! you do not accidentally use `self`/`this` in a way that is in conflict with pinning. //! //! Moreover, if your type is `#[repr(packed)]`, the compiler will automatically -//! move fields around to be able to drop them. As a consequence, you cannot use +//! move fields around to be able to drop them. It might even do +//! that for fields that happen to be sufficiently aligned. As a consequence, you cannot use //! pinning with a `#[repr(packed)]` type. //! //! # Projections and Structural Pinning //! //! When working with pinned structs, the question arises how one can access the -//! fields of that struct in a method that takes just `Pin<&mut Struct>`. +//! fields of that struct in a method that takes just [`Pin`]`<&mut Struct>`. //! The usual approach is to write helper methods (so called *projections*) -//! that turn `Pin<&mut Struct>` into a reference to the field, but what -//! type should that reference have? Is it `Pin<&mut Field>` or `&mut Field`? +//! that turn [`Pin`]`<&mut Struct>` into a reference to the field, but what +//! type should that reference have? Is it [`Pin`]`<&mut Field>` or `&mut Field`? //! The same question arises with the fields of an `enum`, and also when considering //! container/wrapper types such as [`Vec`], [`Box`], or [`RefCell`]. //! (This question applies to both mutable and shared references, we just @@ -203,7 +206,7 @@ //! //! It turns out that it is actually up to the author of the data structure //! to decide whether the pinned projection for a particular field turns -//! `Pin<&mut Struct>` into `Pin<&mut Field>` or `&mut Field`. There are some +//! [`Pin`]`<&mut Struct>` into [`Pin`]`<&mut Field>` or `&mut Field`. There are some //! constraints though, and the most important constraint is *consistency*: //! every field can be *either* projected to a pinned reference, *or* have //! pinning removed as part of the projection. If both are done for the same field, @@ -218,12 +221,13 @@ //! ## Pinning *is not* structural for `field` //! //! It may seem counter-intuitive that the field of a pinned struct might not be pinned, -//! but that is actually the easiest choice: if a `Pin<&mut Field>` is never created, +//! but that is actually the easiest choice: if a [`Pin`]`<&mut Field>` is never created, //! nothing can go wrong! So, if you decide that some field does not have structural pinning, //! all you have to ensure is that you never create a pinned reference to that field. //! //! Fields without structural pinning may have a projection method that turns -//! `Pin<&mut Struct>` into `&mut Field`: +//! [`Pin`]`<&mut Struct>` into `&mut Field`: +//! //! ```rust,no_run //! # use std::pin::Pin; //! # type Field = i32; @@ -237,16 +241,17 @@ //! ``` //! //! You may also `impl Unpin for Struct` *even if* the type of `field` -//! is not `Unpin`. What that type thinks about pinning is not relevant -//! when no `Pin<&mut Field>` is ever created. +//! is not [`Unpin`]. What that type thinks about pinning is not relevant +//! when no [`Pin`]`<&mut Field>` is ever created. //! //! ## Pinning *is* structural for `field` //! //! The other option is to decide that pinning is "structural" for `field`, //! meaning that if the struct is pinned then so is the field. //! -//! This allows writing a projection that creates a `Pin<&mut Field>`, thus +//! This allows writing a projection that creates a [`Pin`]`<&mut Field>`, thus //! witnessing that the field is pinned: +//! //! ```rust,no_run //! # use std::pin::Pin; //! # type Field = i32; @@ -262,30 +267,30 @@ //! However, structural pinning comes with a few extra requirements: //! //! 1. The struct must only be [`Unpin`] if all the structural fields are -//! `Unpin`. This is the default, but `Unpin` is a safe trait, so as the author of +//! [`Unpin`]. This is the default, but [`Unpin`] is a safe trait, so as the author of //! the struct it is your responsibility *not* to add something like //! `impl Unpin for Struct`. (Notice that adding a projection operation -//! requires unsafe code, so the fact that `Unpin` is a safe trait does not break +//! requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break //! the principle that you only have to worry about any of this if you use `unsafe`.) //! 2. The destructor of the struct must not move structural fields out of its argument. This //! is the exact point that was raised in the [previous section][drop-impl]: `drop` takes //! `&mut self`, but the struct (and hence its fields) might have been pinned before. -//! You have to guarantee that you do not move a field inside your `Drop` implementation. +//! You have to guarantee that you do not move a field inside your [`Drop`] implementation. //! In particular, as explained previously, this means that your struct must *not* //! be `#[repr(packed)]`. -//! See that section for how to write `drop` in a way that the compiler can help you +//! See that section for how to write [`drop`] in a way that the compiler can help you //! not accidentally break pinning. //! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]: //! once your struct is pinned, the memory that contains the //! content is not overwritten or deallocated without calling the content's destructors. -//! This can be tricky, as witnessed by [`VecDeque`]: the destructor of `VecDeque` -//! can fail to call `drop` on all elements if one of the destructors panics. This violates the -//! `Drop` guarantee, because it can lead to elements being deallocated without -//! their destructor being called. (`VecDeque` has no pinning projections, so this +//! This can be tricky, as witnessed by [`VecDeque`]: the destructor of [`VecDeque`] +//! can fail to call [`drop`] on all elements if one of the destructors panics. This violates +//! the [`Drop`] guarantee, because it can lead to elements being deallocated without +//! their destructor being called. ([`VecDeque`] has no pinning projections, so this //! does not cause unsoundness.) //! 4. You must not offer any other operations that could lead to data being moved out of //! the structural fields when your type is pinned. For example, if the struct contains an -//! `Option` and there is a `take`-like operation with type +//! [`Option`] and there is a `take`-like operation with type //! `fn(Pin<&mut Struct>) -> Option`, //! that operation can be used to move a `T` out of a pinned `Struct` -- which means //! pinning cannot be structural for the field holding this data. @@ -301,37 +306,39 @@ //! let content = &mut *b; // And here we have `&mut T` to the same data. //! } //! ``` -//! This is catastrophic, it means we can first pin the content of the `RefCell` +//! This is catastrophic, it means we can first pin the content of the [`RefCell`] //! (using `RefCell::get_pin_mut`) and then move that content using the mutable //! reference we got later. //! //! ## Examples //! //! For a type like [`Vec`], both possibilites (structural pinning or not) make sense. -//! A `Vec` with structural pinning could have `get_pin`/`get_pin_mut` methods to get +//! A [`Vec`] with structural pinning could have `get_pin`/`get_pin_mut` methods to get //! pinned references to elements. However, it could *not* allow calling -//! `pop` on a pinned `Vec` because that would move the (structurally pinned) contents! -//! Nor could it allow `push`, which might reallocate and thus also move the contents. -//! A `Vec` without structural pinning could `impl Unpin for Vec`, because the contents -//! are never pinned and the `Vec` itself is fine with being moved as well. +//! [`pop`][Vec::pop] on a pinned [`Vec`] because that would move the (structurally pinned) +//! contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also move the +//! contents. +//! +//! A [`Vec`] without structural pinning could `impl Unpin for Vec`, because the contents +//! are never pinned and the [`Vec`] itself is fine with being moved as well. //! At that point pinning just has no effect on the vector at all. //! //! In the standard library, pointer types generally do not have structural pinning, //! and thus they do not offer pinning projections. This is why `Box: Unpin` holds for all `T`. //! It makes sense to do this for pointer types, because moving the `Box` -//! does not actually move the `T`: the `Box` can be freely movable (aka `Unpin`) even if the `T` -//! is not. In fact, even `Pin>` and `Pin<&mut T>` are always `Unpin` themselves, -//! for the same reason: their contents (the `T`) are pinned, but the pointers themselves -//! can be moved without moving the pinned data. For both `Box` and `Pin>`, -//! whether the content is pinned is entirely independent of whether the pointer is -//! pinned, meaning pinning is *not* structural. +//! does not actually move the `T`: the [`Box`] can be freely movable (aka `Unpin`) even if +//! the `T` is not. In fact, even [`Pin`]`<`[`Box`]`>` and [`Pin`]`<&mut T>` are always +//! [`Unpin`] themselves, for the same reason: their contents (the `T`) are pinned, but the +//! pointers themselves can be moved without moving the pinned data. For both [`Box`] and +//! [`Pin`]`<`[`Box`]`>`, whether the content is pinned is entirely independent of whether the +//! pointer is pinned, meaning pinning is *not* structural. //! //! When implementing a [`Future`] combinator, you will usually need structural pinning -//! for the nested futures, as you need to get pinned references to them to call `poll`. +//! for the nested futures, as you need to get pinned references to them to call [`poll`]. //! But if your combinator contains any other data that does not need to be pinned, //! you can make those fields not structural and hence freely access them with a -//! mutable reference even when you just have `Pin<&mut Self>` (such as in your own -//! `poll` implementation). +//! mutable reference even when you just have [`Pin`]`<&mut Self>` (such as in your own +//! [`poll`] implementation). //! //! [`Pin

`]: struct.Pin.html //! [`Unpin`]: ../marker/trait.Unpin.html @@ -342,6 +349,16 @@ //! [`Box`]: ../../std/boxed/struct.Box.html //! [`Vec`]: ../../std/vec/struct.Vec.html //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len +//! [`Pin`]: struct.Pin.html +//! [`Box`]: ../../std/boxed/struct.Box.html +//! [Vec::pop]: ../../std/vec/struct.Vec.html#method.pop +//! [Vec::push]: ../../std/vec/struct.Vec.html#method.push +//! [`Rc`]: ../../std/rc/struct.Rc.html +//! [`RefCell`]: ../../std/cell/struct.RefCell.html +//! [`Drop`]: ../../std/ops/trait.Drop.html +//! [`drop`]: ../../std/ops/trait.Drop.html#tymethod.drop +//! [`VecDeque`]: ../../std/collections/struct.VecDeque.html +//! [`Option`]: ../../std/option/enum.Option.html //! [`VecDeque`]: ../../std/collections/struct.VecDeque.html //! [`RefCell`]: ../cell/struct.RefCell.html //! [`None`]: ../option/enum.Option.html#variant.None @@ -350,6 +367,8 @@ //! [`Future`]: ../future/trait.Future.html //! [drop-impl]: #drop-implementation //! [drop-guarantee]: #drop-guarantee +//! [`poll`]: ../../std/future/trait.Future.html#tymethod.poll +//! [`Pin::get_unchecked_mut`]: struct.Pin.html#method.get_unchecked_mut #![stable(feature = "pin", since = "1.33.0")] @@ -421,10 +440,7 @@ where } } -impl Pin

-where - P::Target: Unpin, -{ +impl> Pin

{ /// Construct a new `Pin

` around a pointer to some data of a type that /// implements [`Unpin`]. /// @@ -712,10 +728,7 @@ impl Deref for Pin

{ } #[stable(feature = "pin", since = "1.33.0")] -impl DerefMut for Pin

-where - P::Target: Unpin -{ +impl> DerefMut for Pin

{ fn deref_mut(&mut self) -> &mut P::Target { Pin::get_mut(Pin::as_mut(self)) } @@ -757,7 +770,7 @@ where {} #[stable(feature = "pin", since = "1.33.0")] -impl<'a, P, U> DispatchFromDyn> for Pin

+impl DispatchFromDyn> for Pin

where P: DispatchFromDyn, {} diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index 501a41d0d1..84cf85f339 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -44,3 +44,54 @@ pub use crate::option::Option::{self, Some, None}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use crate::result::Result::{self, Ok, Err}; + +// Re-exported built-in macros +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use crate::fmt::macros::Debug; +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use crate::hash::macros::Hash; + +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use crate::{ + __rust_unstable_column, + asm, + assert, + cfg, + column, + compile_error, + concat, + concat_idents, + env, + file, + format_args, + format_args_nl, + global_asm, + include, + include_bytes, + include_str, + line, + log_syntax, + module_path, + option_env, + stringify, + trace_macros, +}; + +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow(deprecated)] +#[doc(no_inline)] +pub use crate::macros::builtin::{ + RustcDecodable, + RustcEncodable, + bench, + global_allocator, + test, + test_case, +}; diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index fccb00d768..f5fbd1a6b1 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -100,7 +100,11 @@ pub use unique::Unique; /// as the compiler doesn't need to prove that it's sound to elide the /// copy. /// +/// Unaligned values cannot be dropped in place, they must be copied to an aligned +/// location first using [`ptr::read_unaligned`]. +/// /// [`ptr::read`]: ../ptr/fn.read.html +/// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html /// /// # Safety /// @@ -108,8 +112,7 @@ pub use unique::Unique; /// /// * `to_drop` must be [valid] for reads. /// -/// * `to_drop` must be properly aligned. See the example below for how to drop -/// an unaligned pointer. +/// * `to_drop` must be properly aligned. /// /// Additionally, if `T` is not [`Copy`], using the pointed-to value after /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop = @@ -153,31 +156,6 @@ pub use unique::Unique; /// assert!(weak.upgrade().is_none()); /// ``` /// -/// Unaligned values cannot be dropped in place, they must be copied to an aligned -/// location first: -/// ``` -/// use std::ptr; -/// use std::mem::{self, MaybeUninit}; -/// -/// unsafe fn drop_after_copy(to_drop: *mut T) { -/// let mut copy: MaybeUninit = MaybeUninit::uninit(); -/// ptr::copy(to_drop, copy.as_mut_ptr(), 1); -/// drop(copy.assume_init()); -/// } -/// -/// #[repr(packed, C)] -/// struct Packed { -/// _padding: u8, -/// unaligned: Vec, -/// } -/// -/// let mut p = Packed { _padding: 0, unaligned: vec![42] }; -/// unsafe { -/// drop_after_copy(&mut p.unaligned as *mut _); -/// mem::forget(p); -/// } -/// ``` -/// /// Notice that the compiler performs this copy automatically when dropping packed structs, /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually. @@ -647,41 +625,65 @@ pub unsafe fn read(src: *const T) -> T { /// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value /// [valid]: ../ptr/index.html#safety /// -/// # Examples +/// ## On `packed` structs /// -/// Access members of a packed struct by reference: +/// It is currently impossible to create raw pointers to unaligned fields +/// of a packed struct. /// -/// ``` -/// use std::ptr; +/// Attempting to create a raw pointer to an `unaligned` struct field with +/// an expression such as `&packed.unaligned as *const FieldType` creates an +/// intermediate unaligned reference before converting that to a raw pointer. +/// That this reference is temporary and immediately cast is inconsequential +/// as the compiler always expects references to be properly aligned. +/// As a result, using `&packed.unaligned as *const FieldType` causes immediate +/// *undefined behavior* in your program. /// +/// An example of what not to do and how this relates to `read_unaligned` is: +/// +/// ```no_run /// #[repr(packed, C)] /// struct Packed { /// _padding: u8, /// unaligned: u32, /// } /// -/// let x = Packed { +/// let packed = Packed { /// _padding: 0x00, /// unaligned: 0x01020304, /// }; /// /// let v = unsafe { -/// // Take the address of a 32-bit integer which is not aligned. -/// // This must be done as a raw pointer; unaligned references are invalid. -/// let unaligned = &x.unaligned as *const u32; -/// -/// // Dereferencing normally will emit an aligned load instruction, -/// // causing undefined behavior. -/// // let v = *unaligned; // ERROR +/// // Here we attempt to take the address of a 32-bit integer which is not aligned. +/// let unaligned = +/// // A temporary unaligned reference is created here which results in +/// // undefined behavior regardless of whether the reference is used or not. +/// &packed.unaligned +/// // Casting to a raw pointer doesn't help; the mistake already happened. +/// as *const u32; /// -/// // Instead, use `read_unaligned` to read improperly aligned values. -/// let v = ptr::read_unaligned(unaligned); +/// let v = std::ptr::read_unaligned(unaligned); /// /// v /// }; +/// ``` +/// +/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however. +// FIXME: Update docs based on outcome of RFC #2582 and friends. +/// +/// # Examples +/// +/// Read an usize value from a byte buffer: /// -/// // Accessing unaligned values directly is safe. -/// assert!(x.unaligned == v); +/// ``` +/// use std::mem; +/// +/// fn read_usize(x: &[u8]) -> usize { +/// assert!(x.len() >= mem::size_of::()); +/// +/// let ptr = x.as_ptr() as *const usize; +/// +/// unsafe { ptr.read_unaligned() } +/// } /// ``` #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] @@ -811,37 +813,63 @@ pub unsafe fn write(dst: *mut T, src: T) { /// /// [valid]: ../ptr/index.html#safety /// -/// # Examples +/// ## On `packed` structs /// -/// Access fields in a packed struct: +/// It is currently impossible to create raw pointers to unaligned fields +/// of a packed struct. /// -/// ``` -/// use std::{mem, ptr}; +/// Attempting to create a raw pointer to an `unaligned` struct field with +/// an expression such as `&packed.unaligned as *const FieldType` creates an +/// intermediate unaligned reference before converting that to a raw pointer. +/// That this reference is temporary and immediately cast is inconsequential +/// as the compiler always expects references to be properly aligned. +/// As a result, using `&packed.unaligned as *const FieldType` causes immediate +/// *undefined behavior* in your program. +/// +/// An example of what not to do and how this relates to `write_unaligned` is: /// +/// ```no_run /// #[repr(packed, C)] -/// #[derive(Default)] /// struct Packed { /// _padding: u8, /// unaligned: u32, /// } /// /// let v = 0x01020304; -/// let mut x: Packed = unsafe { mem::zeroed() }; +/// let mut packed: Packed = unsafe { std::mem::zeroed() }; /// -/// unsafe { -/// // Take a reference to a 32-bit integer which is not aligned. -/// let unaligned = &mut x.unaligned as *mut u32; +/// let v = unsafe { +/// // Here we attempt to take the address of a 32-bit integer which is not aligned. +/// let unaligned = +/// // A temporary unaligned reference is created here which results in +/// // undefined behavior regardless of whether the reference is used or not. +/// &mut packed.unaligned +/// // Casting to a raw pointer doesn't help; the mistake already happened. +/// as *mut u32; /// -/// // Dereferencing normally will emit an aligned store instruction, -/// // causing undefined behavior because the pointer is not aligned. -/// // *unaligned = v; // ERROR +/// std::ptr::write_unaligned(unaligned, v); /// -/// // Instead, use `write_unaligned` to write improperly aligned values. -/// ptr::write_unaligned(unaligned, v); -/// } +/// v +/// }; +/// ``` +/// +/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however. +// FIXME: Update docs based on outcome of RFC #2582 and friends. +/// +/// # Examples +/// +/// Write an usize value to a byte buffer: +/// +/// ``` +/// use std::mem; +/// +/// fn write_usize(x: &mut [u8], val: usize) { +/// assert!(x.len() >= mem::size_of::()); +/// +/// let ptr = x.as_mut_ptr() as *mut usize; /// -/// // Accessing unaligned values directly is safe. -/// assert!(x.unaligned == v); +/// unsafe { ptr.write_unaligned(val) } +/// } /// ``` #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] @@ -1015,7 +1043,7 @@ impl *const T { } /// Cast to a pointer to a different type - #[unstable(feature = "ptr_cast", issue = "60602")] + #[stable(feature = "ptr_cast", since = "1.38.0")] #[inline] pub const fn cast(self) -> *const U { self as _ @@ -1092,7 +1120,8 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -1112,10 +1141,12 @@ impl *const T { /// Extension. As such, memory acquired directly from allocators or memory /// mapped files *may* be too large to handle with this function. /// - /// Consider using `wrapping_offset` instead if these constraints are + /// Consider using [`wrapping_offset`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// [`wrapping_offset`]: #method.wrapping_offset + /// /// # Examples /// /// Basic usage: @@ -1144,15 +1175,26 @@ impl *const T { /// /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). - /// In particular, the resulting pointer may *not* be used to access a - /// different allocated object than the one `self` points to. In other - /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is + /// + /// In particular, the resulting pointer remains attached to the same allocated + /// object that `self` points to. It may *not* be used to access a + /// different allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. + /// + /// In other words, `x.wrapping_offset(y.wrapping_offset_from(x))` is /// *not* the same as `y`, and dereferencing it is undefined behavior /// unless `x` and `y` point into the same allocated object. /// - /// Always use `.offset(count)` instead when possible, because `offset` - /// allows the compiler to optimize better. If you need to cross object - /// boundaries, cast the pointer to an integer and do the arithmetic there. + /// Compared to [`offset`], this method basically delays the requirement of staying + /// within the same allocated object: [`offset`] is immediate Undefined Behavior when + /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads + /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized + /// better and is thus preferrable in performance-sensitive code. + /// + /// If you need to cross object boundaries, cast the pointer to an integer and + /// do the arithmetic there. + /// + /// [`offset`]: #method.offset /// /// # Examples /// @@ -1195,7 +1237,8 @@ impl *const T { /// Behavior: /// /// * Both the starting and other pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. /// @@ -1310,7 +1353,8 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -1330,10 +1374,12 @@ impl *const T { /// Extension. As such, memory acquired directly from allocators or memory /// mapped files *may* be too large to handle with this function. /// - /// Consider using `wrapping_offset` instead if these constraints are + /// Consider using [`wrapping_add`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// [`wrapping_add`]: #method.wrapping_add + /// /// # Examples /// /// Basic usage: @@ -1367,7 +1413,8 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The computed offset cannot exceed `isize::MAX` **bytes**. /// @@ -1387,10 +1434,12 @@ impl *const T { /// Extension. As such, memory acquired directly from allocators or memory /// mapped files *may* be too large to handle with this function. /// - /// Consider using `wrapping_offset` instead if these constraints are + /// Consider using [`wrapping_sub`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// [`wrapping_sub`]: #method.wrapping_sub + /// /// # Examples /// /// Basic usage: @@ -1423,8 +1472,21 @@ impl *const T { /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). /// - /// Always use `.add(count)` instead when possible, because `add` - /// allows the compiler to optimize better. + /// In particular, the resulting pointer remains attached to the same allocated + /// object that `self` points to. It may *not* be used to access a + /// different allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. + /// + /// Compared to [`add`], this method basically delays the requirement of staying + /// within the same allocated object: [`add`] is immediate Undefined Behavior when + /// crossing object boundaries; `wrapping_add` produces a pointer but still leads + /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized + /// better and is thus preferrable in performance-sensitive code. + /// + /// If you need to cross object boundaries, cast the pointer to an integer and + /// do the arithmetic there. + /// + /// [`add`]: #method.add /// /// # Examples /// @@ -1464,8 +1526,21 @@ impl *const T { /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). /// - /// Always use `.sub(count)` instead when possible, because `sub` - /// allows the compiler to optimize better. + /// In particular, the resulting pointer remains attached to the same allocated + /// object that `self` points to. It may *not* be used to access a + /// different allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. + /// + /// Compared to [`sub`], this method basically delays the requirement of staying + /// within the same allocated object: [`sub`] is immediate Undefined Behavior when + /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads + /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized + /// better and is thus preferrable in performance-sensitive code. + /// + /// If you need to cross object boundaries, cast the pointer to an integer and + /// do the arithmetic there. + /// + /// [`sub`]: #method.sub /// /// # Examples /// @@ -1578,12 +1653,14 @@ impl *const T { /// `align`. /// /// If it is not possible to align the pointer, the implementation returns - /// `usize::max_value()`. + /// `usize::max_value()`. It is permissible for the implementation to *always* + /// return `usize::max_value()`. Only your algorithm's performance can depend + /// on getting a usable offset here, not its correctness. /// /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be - /// used with the `offset` or `offset_to` methods. + /// used with the `wrapping_add` method. /// - /// There are no guarantees whatsover that offsetting the pointer will not overflow or go + /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go /// beyond the allocation that the pointer points into. It is up to the caller to ensure that /// the returned offset is correct in all terms other than alignment. /// @@ -1650,7 +1727,7 @@ impl *mut T { } /// Cast to a pointer to a different type - #[unstable(feature = "ptr_cast", issue = "60602")] + #[stable(feature = "ptr_cast", since = "1.38.0")] #[inline] pub const fn cast(self) -> *mut U { self as _ @@ -1727,7 +1804,8 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -1747,10 +1825,12 @@ impl *mut T { /// Extension. As such, memory acquired directly from allocators or memory /// mapped files *may* be too large to handle with this function. /// - /// Consider using `wrapping_offset` instead if these constraints are + /// Consider using [`wrapping_offset`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// [`wrapping_offset`]: #method.wrapping_offset + /// /// # Examples /// /// Basic usage: @@ -1778,15 +1858,26 @@ impl *mut T { /// /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). - /// In particular, the resulting pointer may *not* be used to access a - /// different allocated object than the one `self` points to. In other - /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is + /// + /// In particular, the resulting pointer remains attached to the same allocated + /// object that `self` points to. It may *not* be used to access a + /// different allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. + /// + /// In other words, `x.wrapping_offset(y.wrapping_offset_from(x))` is /// *not* the same as `y`, and dereferencing it is undefined behavior /// unless `x` and `y` point into the same allocated object. /// - /// Always use `.offset(count)` instead when possible, because `offset` - /// allows the compiler to optimize better. If you need to cross object - /// boundaries, cast the pointer to an integer and do the arithmetic there. + /// Compared to [`offset`], this method basically delays the requirement of staying + /// within the same allocated object: [`offset`] is immediate Undefined Behavior when + /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads + /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized + /// better and is thus preferrable in performance-sensitive code. + /// + /// If you need to cross object boundaries, cast the pointer to an integer and + /// do the arithmetic there. + /// + /// [`offset`]: #method.offset /// /// # Examples /// @@ -1873,7 +1964,8 @@ impl *mut T { /// Behavior: /// /// * Both the starting and other pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. /// @@ -1977,7 +2069,8 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -1997,10 +2090,12 @@ impl *mut T { /// Extension. As such, memory acquired directly from allocators or memory /// mapped files *may* be too large to handle with this function. /// - /// Consider using `wrapping_offset` instead if these constraints are + /// Consider using [`wrapping_add`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// [`wrapping_add`]: #method.wrapping_add + /// /// # Examples /// /// Basic usage: @@ -2034,7 +2129,8 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. + /// byte past the end of the same allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. /// /// * The computed offset cannot exceed `isize::MAX` **bytes**. /// @@ -2054,10 +2150,12 @@ impl *mut T { /// Extension. As such, memory acquired directly from allocators or memory /// mapped files *may* be too large to handle with this function. /// - /// Consider using `wrapping_offset` instead if these constraints are + /// Consider using [`wrapping_sub`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// [`wrapping_sub`]: #method.wrapping_sub + /// /// # Examples /// /// Basic usage: @@ -2090,8 +2188,21 @@ impl *mut T { /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). /// - /// Always use `.add(count)` instead when possible, because `add` - /// allows the compiler to optimize better. + /// In particular, the resulting pointer remains attached to the same allocated + /// object that `self` points to. It may *not* be used to access a + /// different allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. + /// + /// Compared to [`add`], this method basically delays the requirement of staying + /// within the same allocated object: [`add`] is immediate Undefined Behavior when + /// crossing object boundaries; `wrapping_add` produces a pointer but still leads + /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized + /// better and is thus preferrable in performance-sensitive code. + /// + /// If you need to cross object boundaries, cast the pointer to an integer and + /// do the arithmetic there. + /// + /// [`add`]: #method.add /// /// # Examples /// @@ -2131,8 +2242,21 @@ impl *mut T { /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). /// - /// Always use `.sub(count)` instead when possible, because `sub` - /// allows the compiler to optimize better. + /// In particular, the resulting pointer remains attached to the same allocated + /// object that `self` points to. It may *not* be used to access a + /// different allocated object. Note that in Rust, + /// every (stack-allocated) variable is considered a separate allocated object. + /// + /// Compared to [`sub`], this method basically delays the requirement of staying + /// within the same allocated object: [`sub`] is immediate Undefined Behavior when + /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads + /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized + /// better and is thus preferrable in performance-sensitive code. + /// + /// If you need to cross object boundaries, cast the pointer to an integer and + /// do the arithmetic there. + /// + /// [`sub`]: #method.sub /// /// # Examples /// @@ -2379,12 +2503,14 @@ impl *mut T { /// `align`. /// /// If it is not possible to align the pointer, the implementation returns - /// `usize::max_value()`. + /// `usize::max_value()`. It is permissible for the implementation to *always* + /// return `usize::max_value()`. Only your algorithm's performance can depend + /// on getting a usable offset here, not its correctness. /// /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be - /// used with the `offset` or `offset_to` methods. + /// used with the `wrapping_add` method. /// - /// There are no guarantees whatsover that offsetting the pointer will not overflow or go + /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go /// beyond the allocation that the pointer points into. It is up to the caller to ensure that /// the returned offset is correct in all terms other than alignment. /// diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs index 46dde7c1da..ad3d1ce396 100644 --- a/src/libcore/ptr/non_null.rs +++ b/src/libcore/ptr/non_null.rs @@ -38,7 +38,7 @@ use crate::cmp::Ordering; #[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] -#[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)] +#[rustc_nonnull_optimization_guaranteed] pub struct NonNull { pointer: *const T, } diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs index 5911518919..f0d011fe6b 100644 --- a/src/libcore/ptr/unique.rs +++ b/src/libcore/ptr/unique.rs @@ -26,8 +26,8 @@ use crate::ptr::NonNull; /// Unlike `*mut T`, `Unique` is covariant over `T`. This should always be correct /// for any type which upholds Unique's aliasing requirements. #[unstable(feature = "ptr_internals", issue = "0", - reason = "use NonNull instead and consider PhantomData \ - (if you also use #[may_dangle]), Send, and/or Sync")] + reason = "use `NonNull` instead and consider `PhantomData` \ + (if you also use `#[may_dangle]`), `Send`, and/or `Sync`")] #[doc(hidden)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] @@ -172,7 +172,7 @@ impl From<&T> for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] -impl<'a, T: ?Sized> From> for Unique { +impl From> for Unique { #[inline] fn from(p: NonNull) -> Self { unsafe { Unique::new_unchecked(p.as_ptr()) } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 8a09877ce1..8c60a9c1b5 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -231,8 +231,8 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; -use crate::iter::{FromIterator, FusedIterator, TrustedLen}; -use crate::ops::{self, Deref}; +use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; +use crate::ops::{self, Deref, DerefMut}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// @@ -277,7 +277,7 @@ impl Result { /// let x: Result = Err("Some error message"); /// assert_eq!(x.is_ok(), false); /// ``` - #[must_use] + #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_ok(&self) -> bool { @@ -302,13 +302,65 @@ impl Result { /// let x: Result = Err("Some error message"); /// assert_eq!(x.is_err(), true); /// ``` - #[must_use] + #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_err(&self) -> bool { !self.is_ok() } + /// Returns `true` if the result is an [`Ok`] value containing the given value. + /// + /// # Examples + /// + /// ``` + /// #![feature(option_result_contains)] + /// + /// let x: Result = Ok(2); + /// assert_eq!(x.contains(&2), true); + /// + /// let x: Result = Ok(3); + /// assert_eq!(x.contains(&2), false); + /// + /// let x: Result = Err("Some error message"); + /// assert_eq!(x.contains(&2), false); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "option_result_contains", issue = "62358")] + pub fn contains(&self, x: &U) -> bool where U: PartialEq { + match self { + Ok(y) => x == y, + Err(_) => false + } + } + + /// Returns `true` if the result is an [`Err`] value containing the given value. + /// + /// # Examples + /// + /// ``` + /// #![feature(result_contains_err)] + /// + /// let x: Result = Ok(2); + /// assert_eq!(x.contains_err(&"Some error message"), false); + /// + /// let x: Result = Err("Some error message"); + /// assert_eq!(x.contains_err(&"Some error message"), true); + /// + /// let x: Result = Err("Some other error message"); + /// assert_eq!(x.contains_err(&"Some error message"), false); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "result_contains_err", issue = "62358")] + pub fn contains_err(&self, f: &F) -> bool where F: PartialEq { + match self { + Ok(_) => false, + Err(e) => f == e + } + } + ///////////////////////////////////////////////////////////////////////// // Adapter for each variant ///////////////////////////////////////////////////////////////////////// @@ -797,7 +849,7 @@ impl Result { pub fn unwrap(self) -> T { match self { Ok(t) => t, - Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", e), + Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e), } } @@ -824,7 +876,7 @@ impl Result { pub fn expect(self, msg: &str) -> T { match self { Ok(t) => t, - Err(e) => unwrap_failed(msg, e), + Err(e) => unwrap_failed(msg, &e), } } } @@ -856,7 +908,7 @@ impl Result { #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap_err(self) -> E { match self { - Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", t), + Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t), Err(e) => e, } } @@ -883,7 +935,7 @@ impl Result { #[stable(feature = "result_expect_err", since = "1.17.0")] pub fn expect_err(self, msg: &str) -> E { match self { - Ok(t) => unwrap_failed(msg, t), + Ok(t) => unwrap_failed(msg, &t), Err(e) => e, } } @@ -929,24 +981,22 @@ impl Result { #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - /// Converts from `&Result` to `Result<&T::Target, &E>`. + /// Converts from `Result` (or `&Result`) to `Result<&T::Target, &E>`. /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing the `Ok` arm of the Result via - /// `Deref`. - pub fn deref_ok(&self) -> Result<&T::Target, &E> { + /// Leaves the original `Result` in-place, creating a new one containing a reference to the + /// `Ok` type's `Deref::Target` type. + pub fn as_deref_ok(&self) -> Result<&T::Target, &E> { self.as_ref().map(|t| t.deref()) } } #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - /// Converts from `&Result` to `Result<&T, &E::Target>`. + /// Converts from `Result` (or `&Result`) to `Result<&T, &E::Target>`. /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing the `Err` arm of the Result via - /// `Deref`. - pub fn deref_err(&self) -> Result<&T, &E::Target> + /// Leaves the original `Result` in-place, creating a new one containing a reference to the + /// `Err` type's `Deref::Target` type. + pub fn as_deref_err(&self) -> Result<&T, &E::Target> { self.as_ref().map_err(|e| e.deref()) } @@ -954,17 +1004,52 @@ impl Result { #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. + /// Converts from `Result` (or `&Result`) to `Result<&T::Target, &E::Target>`. /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing both the `Ok` and `Err` arms - /// of the Result via `Deref`. - pub fn deref(&self) -> Result<&T::Target, &E::Target> + /// Leaves the original `Result` in-place, creating a new one containing a reference to both + /// the `Ok` and `Err` types' `Deref::Target` types. + pub fn as_deref(&self) -> Result<&T::Target, &E::Target> { self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { + /// Converts from `Result` (or `&mut Result`) to `Result<&mut T::Target, &mut E>`. + /// + /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to + /// the `Ok` type's `Deref::Target` type. + pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> { + self.as_mut().map(|t| t.deref_mut()) + } +} + +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { + /// Converts from `Result` (or `&mut Result`) to `Result<&mut T, &mut E::Target>`. + /// + /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to + /// the `Err` type's `Deref::Target` type. + pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> + { + self.as_mut().map_err(|e| e.deref_mut()) + } +} + +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { + /// Converts from `Result` (or `&mut Result`) to + /// `Result<&mut T::Target, &mut E::Target>`. + /// + /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to + /// both the `Ok` and `Err` types' `Deref::Target` types. + pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target> + { + self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut()) + } +} + impl Result, E> { /// Transposes a `Result` of an `Option` into an `Option` of a `Result`. /// @@ -995,7 +1080,7 @@ impl Result, E> { // This is a separate function to reduce the code size of the methods #[inline(never)] #[cold] -fn unwrap_failed(msg: &str, error: E) -> ! { +fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! { panic!("{}: {:?}", msg, error) } @@ -1258,39 +1343,7 @@ impl> FromIterator> for Result { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. - struct Adapter { - iter: Iter, - err: Option, - } - - impl>> Iterator for Adapter { - type Item = T; - - #[inline] - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Ok(value)) => Some(value), - Some(Err(err)) => { - self.err = Some(err); - None - } - None => None, - } - } - - fn size_hint(&self) -> (usize, Option) { - let (_min, max) = self.iter.size_hint(); - (0, max) - } - } - - let mut adapter = Adapter { iter: iter.into_iter(), err: None }; - let v: V = FromIterator::from_iter(adapter.by_ref()); - - match adapter.err { - Some(err) => Err(err), - None => Ok(v), - } + iter::process_results(iter.into_iter(), |i| i.collect()) } } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index c6d44324ef..ce5af13d4c 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -25,7 +25,7 @@ use crate::cmp::Ordering::{self, Less, Equal, Greater}; use crate::cmp; use crate::fmt; -use crate::intrinsics::{assume, exact_div, unchecked_sub}; +use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null}; use crate::isize; use crate::iter::*; use crate::ops::{FnMut, Try, self}; @@ -292,10 +292,13 @@ impl [T] { /// Returns a reference to an element or subslice, without doing bounds /// checking. /// - /// This is generally not recommended, use with caution! For a safe - /// alternative see [`get`]. + /// This is generally not recommended, use with caution! + /// Calling this method with an out-of-bounds index is *[undefined behavior]* + /// even if the resulting reference is not used. + /// For a safe alternative see [`get`]. /// /// [`get`]: #method.get + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// /// # Examples /// @@ -317,10 +320,13 @@ impl [T] { /// Returns a mutable reference to an element or subslice, without doing /// bounds checking. /// - /// This is generally not recommended, use with caution! For a safe - /// alternative see [`get_mut`]. + /// This is generally not recommended, use with caution! + /// Calling this method with an out-of-bounds index is *[undefined behavior]* + /// even if the resulting reference is not used. + /// For a safe alternative see [`get_mut`]. /// /// [`get_mut`]: #method.get_mut + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// /// # Examples /// @@ -611,7 +617,7 @@ impl [T] { /// /// See [`chunks_exact`] for a variant of this iterator that returns chunks of always exactly /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the - /// slice of the slice. + /// slice. /// /// # Panics /// @@ -645,7 +651,7 @@ impl [T] { /// /// See [`chunks_exact_mut`] for a variant of this iterator that returns chunks of always /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at - /// the end of the slice of the slice. + /// the end of the slice. /// /// # Panics /// @@ -727,7 +733,7 @@ impl [T] { /// /// See [`chunks_mut`] for a variant of this iterator that also returns the remainder as a /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of - /// the slice of the slice. + /// the slice. /// /// # Panics /// @@ -1263,6 +1269,15 @@ impl [T] { /// assert!(v.contains(&30)); /// assert!(!v.contains(&50)); /// ``` + /// + /// If you do not have an `&T`, but just an `&U` such that `T: Borrow` + /// (e.g. `String: Borrow`), you can use `iter().any`: + /// + /// ``` + /// let v = [String::from("hello"), String::from("world")]; // slice of `String` + /// assert!(v.iter().any(|e| e == "hello")); // search with `&str` + /// assert!(!v.iter().any(|e| e == "hi")); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, x: &T) -> bool where T: PartialEq @@ -1349,6 +1364,17 @@ impl [T] { /// let r = s.binary_search(&1); /// assert!(match r { Ok(1..=4) => true, _ => false, }); /// ``` + /// + /// If you want to insert an item to a sorted vector, while maintaining + /// sort order: + /// + /// ``` + /// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// let num = 42; + /// let idx = s.binary_search(&num).unwrap_or_else(|x| x); + /// s.insert(idx, num); + /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn binary_search(&self, x: &T) -> Result where T: Ord @@ -2293,9 +2319,10 @@ impl [T] { /// maintained. /// /// This method splits the slice into three distinct slices: prefix, correctly aligned middle - /// slice of a new type, and the suffix slice. The method does a best effort to make the - /// middle slice the greatest length possible for a given type and input slice, but only - /// your algorithm's performance should depend on that, not its correctness. + /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest + /// length possible for a given type and input slice, but only your algorithm's performance + /// should depend on that, not its correctness. It is permissible for all of the input data to + /// be returned as the prefix or suffix slice. /// /// This method has no purpose when either input element `T` or output element `U` are /// zero-sized and will return the original slice without splitting anything. @@ -2346,9 +2373,10 @@ impl [T] { /// maintained. /// /// This method splits the slice into three distinct slices: prefix, correctly aligned middle - /// slice of a new type, and the suffix slice. The method does a best effort to make the - /// middle slice the greatest length possible for a given type and input slice, but only - /// your algorithm's performance should depend on that, not its correctness. + /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest + /// length possible for a given type and input slice, but only your algorithm's performance + /// should depend on that, not its correctness. It is permissible for all of the input data to + /// be returned as the prefix or suffix slice. /// /// This method has no purpose when either input element `T` or output element `U` are /// zero-sized and will return the original slice without splitting anything. @@ -2459,12 +2487,12 @@ impl [T] { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] - pub fn is_sorted_by_key(&self, mut f: F) -> bool + pub fn is_sorted_by_key(&self, f: F) -> bool where F: FnMut(&T) -> K, K: PartialOrd { - self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b))) + self.iter().is_sorted_by_key(f) } } @@ -2620,11 +2648,17 @@ pub trait SliceIndex: private_slice_index::Sealed { /// Returns a shared reference to the output at this location, without /// performing any bounds checking. + /// Calling this method with an out-of-bounds index is *[undefined behavior]* + /// even if the resulting reference is not used. + /// [undefined behavior]: ../../reference/behavior-considered-undefined.html #[unstable(feature = "slice_index_methods", issue = "0")] unsafe fn get_unchecked(self, slice: &T) -> &Self::Output; /// Returns a mutable reference to the output at this location, without /// performing any bounds checking. + /// Calling this method with an out-of-bounds index is *[undefined behavior]* + /// even if the resulting reference is not used. + /// [undefined behavior]: ../../reference/behavior-considered-undefined.html #[unstable(feature = "slice_index_methods", issue = "0")] unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output; @@ -4330,6 +4364,25 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> { Some(tail) } } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + let len = self.len(); + if n >= len { + self.v = &mut []; + None + } else { + let start = (len - 1 - n) * self.chunk_size; + let end = match start.checked_add(self.chunk_size) { + Some(res) => cmp::min(res, self.v.len()), + None => self.v.len(), + }; + let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end); + let (head, nth_back) = temp.split_at_mut(start); + self.v = head; + Some(nth_back) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -4453,6 +4506,21 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> { Some(snd) } } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + let len = self.len(); + if n >= len { + self.v = &[]; + None + } else { + let start = (len - 1 - n) * self.chunk_size; + let end = start + self.chunk_size; + let nth_back = &self.v[start..end]; + self.v = &self.v[..start]; + Some(nth_back) + } + } } #[stable(feature = "chunks_exact", since = "1.31.0")] @@ -5213,7 +5281,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { - debug_assert!(data as usize % mem::align_of::() == 0, "attempt to create unaligned slice"); + debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering half the address space"); &*ptr::slice_from_raw_parts(data, len) @@ -5234,7 +5302,7 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { - debug_assert!(data as usize % mem::align_of::() == 0, "attempt to create unaligned slice"); + debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering half the address space"); &mut *ptr::slice_from_raw_parts_mut(data, len) @@ -5327,13 +5395,24 @@ impl SlicePartialEq for [A] return false; } - for i in 0..self.len() { - if !self[i].eq(&other[i]) { - return false; - } + self.iter().zip(other.iter()).all(|(x, y)| x == y) + } +} + +// Use an equal-pointer optimization when types are `Eq` +impl SlicePartialEq for [A] + where A: PartialEq + Eq +{ + default fn equal(&self, other: &[A]) -> bool { + if self.len() != other.len() { + return false; + } + + if self.as_ptr() == other.as_ptr() { + return true; } - true + self.iter().zip(other.iter()).all(|(x, y)| x == y) } } @@ -5442,7 +5521,7 @@ impl SliceOrd for [u8] { #[doc(hidden)] /// Trait implemented for types that can be compared for equality using /// their bytewise representation -trait BytewiseEquality { } +trait BytewiseEquality: Eq + Copy { } macro_rules! impl_marker_for { ($traitname:ident, $($ty:ty)*) => { diff --git a/src/libcore/slice/rotate.rs b/src/libcore/slice/rotate.rs index f69b219715..f73e14f27e 100644 --- a/src/libcore/slice/rotate.rs +++ b/src/libcore/slice/rotate.rs @@ -2,32 +2,9 @@ use crate::cmp; use crate::mem::{self, MaybeUninit}; use crate::ptr; -/// Rotation is much faster if it has access to a little bit of memory. This -/// union provides a RawVec-like interface, but to a fixed-size stack buffer. -#[allow(unions_with_drop_fields)] -union RawArray { - /// Ensure this is appropriately aligned for T, and is big - /// enough for two elements even if T is enormous. - typed: [T; 2], - /// For normally-sized types, especially things like u8, having more - /// than 2 in the buffer is necessary for usefulness, so pad it out - /// enough to be helpful, but not so big as to risk overflow. - _extra: [usize; 32], -} - -impl RawArray { - fn cap() -> usize { - if mem::size_of::() == 0 { - usize::max_value() - } else { - mem::size_of::() / mem::size_of::() - } - } -} - -/// Rotates the range `[mid-left, mid+right)` such that the element at `mid` -/// becomes the first element. Equivalently, rotates the range `left` -/// elements to the left or `right` elements to the right. +/// Rotates the range `[mid-left, mid+right)` such that the element at `mid` becomes the first +/// element. Equivalently, rotates the range `left` elements to the left or `right` elements to the +/// right. /// /// # Safety /// @@ -35,55 +12,161 @@ impl RawArray { /// /// # Algorithm /// -/// For longer rotations, swap the left-most `delta = min(left, right)` -/// elements with the right-most `delta` elements. LLVM vectorizes this, -/// which is profitable as we only reach this step for a "large enough" -/// rotation. Doing this puts `delta` elements on the larger side into the -/// correct position, leaving a smaller rotate problem. Demonstration: -/// +/// Algorithm 1 is used for small values of `left + right` or for large `T`. The elements are moved +/// into their final positions one at a time starting at `mid - left` and advancing by `right` steps +/// modulo `left + right`, such that only one temporary is needed. Eventually, we arrive back at +/// `mid - left`. However, if `gcd(left + right, right)` is not 1, the above steps skipped over +/// elements. For example: /// ```text -/// [ 6 7 8 9 10 11 12 13 . 1 2 3 4 5 ] -/// 1 2 3 4 5 [ 11 12 13 . 6 7 8 9 10 ] -/// 1 2 3 4 5 [ 8 9 10 . 6 7 ] 11 12 13 -/// 1 2 3 4 5 6 7 [ 10 . 8 9 ] 11 12 13 -/// 1 2 3 4 5 6 7 [ 9 . 8 ] 10 11 12 13 -/// 1 2 3 4 5 6 7 8 [ . ] 9 10 11 12 13 +/// left = 10, right = 6 +/// the `^` indicates an element in its final place +/// 6 7 8 9 10 11 12 13 14 15 . 0 1 2 3 4 5 +/// after using one step of the above algorithm (The X will be overwritten at the end of the round, +/// and 12 is stored in a temporary): +/// X 7 8 9 10 11 6 13 14 15 . 0 1 2 3 4 5 +/// ^ +/// after using another step (now 2 is in the temporary): +/// X 7 8 9 10 11 6 13 14 15 . 0 1 12 3 4 5 +/// ^ ^ +/// after the third step (the steps wrap around, and 8 is in the temporary): +/// X 7 2 9 10 11 6 13 14 15 . 0 1 12 3 4 5 +/// ^ ^ ^ +/// after 7 more steps, the round ends with the temporary 0 getting put in the X: +/// 0 7 2 9 4 11 6 13 8 15 . 10 1 12 3 14 5 +/// ^ ^ ^ ^ ^ ^ ^ ^ /// ``` +/// Fortunately, the number of skipped over elements between finalized elements is always equal, so +/// we can just offset our starting position and do more rounds (the total number of rounds is the +/// `gcd(left + right, right)` value). The end result is that all elements are finalized once and +/// only once. +/// +/// Algorithm 2 is used if `left + right` is large but `min(left, right)` is small enough to +/// fit onto a stack buffer. The `min(left, right)` elements are copied onto the buffer, `memmove` +/// is applied to the others, and the ones on the buffer are moved back into the hole on the +/// opposite side of where they originated. +/// +/// Algorithms that can be vectorized outperform the above once `left + right` becomes large enough. +/// Algorithm 1 can be vectorized by chunking and performing many rounds at once, but there are too +/// few rounds on average until `left + right` is enormous, and the worst case of a single +/// round is always there. Instead, algorithm 3 utilizes repeated swapping of +/// `min(left, right)` elements until a smaller rotate problem is left. /// -/// Once the rotation is small enough, copy some elements into a stack -/// buffer, `memmove` the others, and move the ones back from the buffer. -pub unsafe fn ptr_rotate(mut left: usize, mid: *mut T, mut right: usize) { +/// ```text +/// left = 11, right = 4 +/// [4 5 6 7 8 9 10 11 12 13 14 . 0 1 2 3] +/// ^ ^ ^ ^ ^ ^ ^ ^ swapping the right most elements with elements to the left +/// [4 5 6 7 8 9 10 . 0 1 2 3] 11 12 13 14 +/// ^ ^ ^ ^ ^ ^ ^ ^ swapping these +/// [4 5 6 . 0 1 2 3] 7 8 9 10 11 12 13 14 +/// we cannot swap any more, but a smaller rotation problem is left to solve +/// ``` +/// when `left < right` the swapping happens from the left instead. +pub unsafe fn ptr_rotate(mut left: usize, mut mid: *mut T, mut right: usize) { + type BufType = [usize; 32]; + if mem::size_of::() == 0 { + return; + } loop { - let delta = cmp::min(left, right); - if delta <= RawArray::::cap() { - // We will always hit this immediately for ZST. - break; + // N.B. the below algorithms can fail if these cases are not checked + if (right == 0) || (left == 0) { + return; } - - ptr::swap_nonoverlapping( - mid.sub(left), - mid.add(right - delta), - delta); - - if left <= right { - right -= delta; + if (left + right < 24) || (mem::size_of::() > mem::size_of::<[usize; 4]>()) { + // Algorithm 1 + // Microbenchmarks indicate that the average performance for random shifts is better all + // the way until about `left + right == 32`, but the worst case performance breaks even + // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4 + // `usize`s, this algorithm also outperforms other algorithms. + let x = mid.sub(left); + // beginning of first round + let mut tmp: T = x.read(); + let mut i = right; + // `gcd` can be found before hand by calculating `gcd(left + right, right)`, + // but it is faster to do one loop which calculates the gcd as a side effect, then + // doing the rest of the chunk + let mut gcd = right; + // benchmarks reveal that it is faster to swap temporaries all the way through instead + // of reading one temporary once, copying backwards, and then writing that temporary at + // the very end. This is possibly due to the fact that swapping or replacing temporaries + // uses only one memory address in the loop instead of needing to manage two. + loop { + tmp = x.add(i).replace(tmp); + // instead of incrementing `i` and then checking if it is outside the bounds, we + // check if `i` will go outside the bounds on the next increment. This prevents + // any wrapping of pointers or `usize`. + if i >= left { + i -= left; + if i == 0 { + // end of first round + x.write(tmp); + break; + } + // this conditional must be here if `left + right >= 15` + if i < gcd { + gcd = i; + } + } else { + i += right; + } + } + // finish the chunk with more rounds + for start in 1..gcd { + tmp = x.add(start).read(); + i = start + right; + loop { + tmp = x.add(i).replace(tmp); + if i >= left { + i -= left; + if i == start { + x.add(start).write(tmp); + break; + } + } else { + i += right; + } + } + } + return; + // `T` is not a zero-sized type, so it's okay to divide by its size. + } else if cmp::min(left, right) <= mem::size_of::() / mem::size_of::() { + // Algorithm 2 + // The `[T; 0]` here is to ensure this is appropriately aligned for T + let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); + let buf = rawarray.as_mut_ptr() as *mut T; + let dim = mid.sub(left).add(right); + if left <= right { + ptr::copy_nonoverlapping(mid.sub(left), buf, left); + ptr::copy(mid, mid.sub(left), right); + ptr::copy_nonoverlapping(buf, dim, left); + } else { + ptr::copy_nonoverlapping(mid, buf, right); + ptr::copy(mid.sub(left), dim, left); + ptr::copy_nonoverlapping(buf, mid.sub(left), right); + } + return; + } else if left >= right { + // Algorithm 3 + // There is an alternate way of swapping that involves finding where the last swap + // of this algorithm would be, and swapping using that last chunk instead of swapping + // adjacent chunks like this algorithm is doing, but this way is still faster. + loop { + ptr::swap_nonoverlapping(mid.sub(right), mid, right); + mid = mid.sub(right); + left -= right; + if left < right { + break; + } + } } else { - left -= delta; + // Algorithm 3, `left < right` + loop { + ptr::swap_nonoverlapping(mid.sub(left), mid, left); + mid = mid.add(left); + right -= left; + if right < left { + break; + } + } } } - - let mut rawarray = MaybeUninit::>::uninit(); - let buf = &mut (*rawarray.as_mut_ptr()).typed as *mut [T; 2] as *mut T; - - let dim = mid.sub(left).add(right); - if left <= right { - ptr::copy_nonoverlapping(mid.sub(left), buf, left); - ptr::copy(mid, mid.sub(left), right); - ptr::copy_nonoverlapping(buf, dim, left); - } - else { - ptr::copy_nonoverlapping(mid, buf, right); - ptr::copy(mid.sub(left), dim, left); - ptr::copy_nonoverlapping(buf, mid.sub(left), right); - } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index c293b19001..2f2170f7ff 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,14 +216,14 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - let mut offsets_l: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; + let mut offsets_l = [MaybeUninit::::uninit(); BLOCK]; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; + let mut offsets_r = [MaybeUninit::::uninit(); BLOCK]; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index b291579553..e8f747f1a6 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -46,7 +46,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { type Item = Utf8LossyChunk<'a>; fn next(&mut self) -> Option> { - if self.source.len() == 0 { + if self.source.is_empty() { return None; } @@ -141,7 +141,7 @@ impl fmt::Display for Utf8Lossy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // If we're the empty string then our iterator won't actually yield // anything, so perform the formatting manually - if self.bytes.len() == 0 { + if self.bytes.is_empty() { return "".fmt(f) } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 34f2d8917e..f20cb7bfbc 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -464,7 +464,7 @@ Section: Iterators /// /// [`chars`]: ../../std/primitive.str.html#method.chars /// [`str`]: ../../std/primitive.str.html -#[derive(Clone, Debug)] +#[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chars<'a> { iter: slice::Iter<'a, u8> @@ -600,6 +600,16 @@ impl<'a> Iterator for Chars<'a> { } } +#[stable(feature = "chars_debug_impl", since = "1.38.0")] +impl fmt::Debug for Chars<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Chars(")?; + f.debug_list().entries(self.clone()).finish()?; + write!(f, ")")?; + Ok(()) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a> DoubleEndedIterator for Chars<'a> { #[inline] @@ -841,8 +851,9 @@ unsafe impl TrustedRandomAccess for Bytes<'_> { /// wrapper types of the form X<'a, P> macro_rules! derive_pattern_clone { (clone $t:ident with |$s:ident| $e:expr) => { - impl<'a, P: Pattern<'a>> Clone for $t<'a, P> - where P::Searcher: Clone + impl<'a, P> Clone for $t<'a, P> + where + P: Pattern<'a, Searcher: Clone>, { fn clone(&self) -> Self { let $s = self; @@ -918,8 +929,9 @@ macro_rules! generate_pattern_iterators { pub struct $forward_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>); $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> fmt::Debug for $forward_iterator<'a, P> - where P::Searcher: fmt::Debug + impl<'a, P> fmt::Debug for $forward_iterator<'a, P> + where + P: Pattern<'a, Searcher: fmt::Debug>, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple(stringify!($forward_iterator)) @@ -939,8 +951,9 @@ macro_rules! generate_pattern_iterators { } $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> Clone for $forward_iterator<'a, P> - where P::Searcher: Clone + impl<'a, P> Clone for $forward_iterator<'a, P> + where + P: Pattern<'a, Searcher: Clone>, { fn clone(&self) -> Self { $forward_iterator(self.0.clone()) @@ -952,8 +965,9 @@ macro_rules! generate_pattern_iterators { pub struct $reverse_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>); $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> fmt::Debug for $reverse_iterator<'a, P> - where P::Searcher: fmt::Debug + impl<'a, P> fmt::Debug for $reverse_iterator<'a, P> + where + P: Pattern<'a, Searcher: fmt::Debug>, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple(stringify!($reverse_iterator)) @@ -963,8 +977,9 @@ macro_rules! generate_pattern_iterators { } $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> Iterator for $reverse_iterator<'a, P> - where P::Searcher: ReverseSearcher<'a> + impl<'a, P> Iterator for $reverse_iterator<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { type Item = $iterty; @@ -975,8 +990,9 @@ macro_rules! generate_pattern_iterators { } $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> Clone for $reverse_iterator<'a, P> - where P::Searcher: Clone + impl<'a, P> Clone for $reverse_iterator<'a, P> + where + P: Pattern<'a, Searcher: Clone>, { fn clone(&self) -> Self { $reverse_iterator(self.0.clone()) @@ -987,8 +1003,10 @@ macro_rules! generate_pattern_iterators { impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {} #[stable(feature = "fused", since = "1.26.0")] - impl<'a, P: Pattern<'a>> FusedIterator for $reverse_iterator<'a, P> - where P::Searcher: ReverseSearcher<'a> {} + impl<'a, P> FusedIterator for $reverse_iterator<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, + {} generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*, $forward_iterator, @@ -1000,8 +1018,9 @@ macro_rules! generate_pattern_iterators { $reverse_iterator:ident, $iterty:ty } => { $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> DoubleEndedIterator for $forward_iterator<'a, P> - where P::Searcher: DoubleEndedSearcher<'a> + impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P> + where + P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>, { #[inline] fn next_back(&mut self) -> Option<$iterty> { @@ -1010,8 +1029,9 @@ macro_rules! generate_pattern_iterators { } $(#[$common_stability_attribute])* - impl<'a, P: Pattern<'a>> DoubleEndedIterator for $reverse_iterator<'a, P> - where P::Searcher: DoubleEndedSearcher<'a> + impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P> + where + P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>, { #[inline] fn next_back(&mut self) -> Option<$iterty> { @@ -1039,7 +1059,10 @@ struct SplitInternal<'a, P: Pattern<'a>> { finished: bool, } -impl<'a, P: Pattern<'a>> fmt::Debug for SplitInternal<'a, P> where P::Searcher: fmt::Debug { +impl<'a, P> fmt::Debug for SplitInternal<'a, P> +where + P: Pattern<'a, Searcher: fmt::Debug>, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SplitInternal") .field("start", &self.start) @@ -1156,7 +1179,10 @@ struct SplitNInternal<'a, P: Pattern<'a>> { count: usize, } -impl<'a, P: Pattern<'a>> fmt::Debug for SplitNInternal<'a, P> where P::Searcher: fmt::Debug { +impl<'a, P> fmt::Debug for SplitNInternal<'a, P> +where + P: Pattern<'a, Searcher: fmt::Debug>, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SplitNInternal") .field("iter", &self.iter) @@ -1212,7 +1238,10 @@ derive_pattern_clone!{ struct MatchIndicesInternal<'a, P: Pattern<'a>>(P::Searcher); -impl<'a, P: Pattern<'a>> fmt::Debug for MatchIndicesInternal<'a, P> where P::Searcher: fmt::Debug { +impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P> +where + P: Pattern<'a, Searcher: fmt::Debug>, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("MatchIndicesInternal") .field(&self.0) @@ -1263,7 +1292,10 @@ derive_pattern_clone!{ struct MatchesInternal<'a, P: Pattern<'a>>(P::Searcher); -impl<'a, P: Pattern<'a>> fmt::Debug for MatchesInternal<'a, P> where P::Searcher: fmt::Debug { +impl<'a, P> fmt::Debug for MatchesInternal<'a, P> +where + P: Pattern<'a, Searcher: fmt::Debug>, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("MatchesInternal") .field(&self.0) @@ -1333,6 +1365,11 @@ impl<'a> Iterator for Lines<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1417,6 +1454,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let usize_bytes = mem::size_of::(); let ascii_block_size = 2 * usize_bytes; let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 }; + let align = v.as_ptr().align_offset(usize_bytes); while index < len { let old_offset = index; @@ -1496,12 +1534,8 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // Ascii case, try to skip forward quickly. // When the pointer is aligned, read 2 words of data per iteration // until we find a word containing a non-ascii byte. - let ptr = v.as_ptr(); - let align = unsafe { - // the offset is safe, because `index` is guaranteed inbounds - ptr.add(index).align_offset(usize_bytes) - }; - if align == 0 { + if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 { + let ptr = v.as_ptr(); while index < blocks_end { unsafe { let block = ptr.add(index) as *const usize; @@ -2870,8 +2904,9 @@ impl str { /// assert!(!bananas.ends_with("nana")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool - where P::Searcher: ReverseSearcher<'a> + pub fn ends_with<'a, P>(&'a self, pat: P) -> bool + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { pat.is_suffix_of(self) } @@ -2963,8 +2998,9 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option - where P::Searcher: ReverseSearcher<'a> + pub fn rfind<'a, P>(&'a self, pat: P) -> Option + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { pat.into_searcher(self).next_match_back().map(|(i, _)| i) } @@ -3130,8 +3166,9 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> - where P::Searcher: ReverseSearcher<'a> + pub fn rsplit<'a, P>(&'a self, pat: P) -> RSplit<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { RSplit(self.split(pat).0) } @@ -3221,8 +3258,9 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> - where P::Searcher: ReverseSearcher<'a> + pub fn rsplit_terminator<'a, P>(&'a self, pat: P) -> RSplitTerminator<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { RSplitTerminator(self.split_terminator(pat).0) } @@ -3321,8 +3359,9 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P> - where P::Searcher: ReverseSearcher<'a> + pub fn rsplitn<'a, P>(&'a self, n: usize, pat: P) -> RSplitN<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { RSplitN(self.splitn(n, pat).0) } @@ -3394,8 +3433,9 @@ impl str { /// ``` #[stable(feature = "str_matches", since = "1.2.0")] #[inline] - pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> - where P::Searcher: ReverseSearcher<'a> + pub fn rmatches<'a, P>(&'a self, pat: P) -> RMatches<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { RMatches(self.matches(pat).0) } @@ -3479,8 +3519,9 @@ impl str { /// ``` #[stable(feature = "str_match_indices", since = "1.5.0")] #[inline] - pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> - where P::Searcher: ReverseSearcher<'a> + pub fn rmatch_indices<'a, P>(&'a self, pat: P) -> RMatchIndices<'a, P> + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { RMatchIndices(self.match_indices(pat).0) } @@ -3688,8 +3729,9 @@ impl str { #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str - where P::Searcher: DoubleEndedSearcher<'a> + pub fn trim_matches<'a, P>(&'a self, pat: P) -> &'a str + where + P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>, { let mut i = 0; let mut j = 0; @@ -3716,10 +3758,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. 'Left' in this context means the first - /// position of that byte string; for a language like Arabic or Hebrew - /// which are 'right to left' rather than 'left to right', this will be - /// the _right_ side, not the left. + /// A string is a sequence of bytes. `start` in this context means the first + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be left side, and for right-to-left languages like + /// like Arabic or Hebrew, this will be the right side. /// /// # Examples /// @@ -3755,10 +3797,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. 'Right' in this context means the last - /// position of that byte string; for a language like Arabic or Hebrew - /// which are 'right to left' rather than 'left to right', this will be - /// the _left_ side, not the right. + /// A string is a sequence of bytes. `end` in this context means the last + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be right side, and for right-to-left languages like + /// like Arabic or Hebrew, this will be the left side. /// /// # Examples /// @@ -3780,8 +3822,9 @@ impl str { #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] - pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str - where P::Searcher: ReverseSearcher<'a> + pub fn trim_end_matches<'a, P>(&'a self, pat: P) -> &'a str + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { let mut j = 0; let mut matcher = pat.into_searcher(self); @@ -3804,10 +3847,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. `start` in this context means the first - /// position of that byte string; for a left-to-right language like English or - /// Russian, this will be left side, and for right-to-left languages like - /// like Arabic or Hebrew, this will be the right side. + /// A string is a sequence of bytes. 'Left' in this context means the first + /// position of that byte string; for a language like Arabic or Hebrew + /// which are 'right to left' rather than 'left to right', this will be + /// the _right_ side, not the left. /// /// # Examples /// @@ -3840,10 +3883,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. `end` in this context means the last - /// position of that byte string; for a left-to-right language like English or - /// Russian, this will be right side, and for right-to-left languages like - /// like Arabic or Hebrew, this will be the left side. + /// A string is a sequence of bytes. 'Right' in this context means the last + /// position of that byte string; for a language like Arabic or Hebrew + /// which are 'right to left' rather than 'left to right', this will be + /// the _left_ side, not the right. /// /// # Examples /// @@ -3868,8 +3911,9 @@ impl str { reason = "superseded by `trim_end_matches`", suggestion = "trim_end_matches", )] - pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str - where P::Searcher: ReverseSearcher<'a> + pub fn trim_right_matches<'a, P>(&'a self, pat: P) -> &'a str + where + P: Pattern<'a, Searcher: ReverseSearcher<'a>>, { self.trim_end_matches(pat) } @@ -4241,6 +4285,11 @@ impl<'a> Iterator for SplitWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "split_whitespace", since = "1.1.0")] @@ -4267,6 +4316,11 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index f1247239f4..65e2936428 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -31,7 +31,7 @@ impl RawWaker { /// The `data` pointer can be used to store arbitrary data as required /// by the executor. This could be e.g. a type-erased pointer to an `Arc` /// that is associated with the task. - /// The value of this poiner will get passed to all functions that are part + /// The value of this pointer will get passed to all functions that are part /// of the `vtable` as the first parameter. /// /// The `vtable` customizes the behavior of a `Waker` which gets created @@ -217,7 +217,7 @@ impl fmt::Debug for Context<'_> { /// This handle encapsulates a [`RawWaker`] instance, which defines the /// executor-specific wakeup behavior. /// -/// Implements [`Clone`], [`Send`], and [`Sync`]. +/// Implements [`Clone`], [`trait@Send`], and [`trait@Sync`]. /// /// [`RawWaker`]: struct.RawWaker.html #[repr(transparent)] diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs index ec98e0464c..439ed0c81c 100644 --- a/src/libcore/tests/ascii.rs +++ b/src/libcore/tests/ascii.rs @@ -151,7 +151,7 @@ macro_rules! assert_none { stringify!($what), b); } } - )* + )+ }}; ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+)) } diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index 62fe09c5eb..200659b91b 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -211,9 +211,9 @@ mod debug_map { #[test] fn test_single() { - struct Foo; + struct Entry; - impl fmt::Debug for Foo { + impl fmt::Debug for Entry { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_map() .entry(&"bar", &true) @@ -221,19 +221,32 @@ mod debug_map { } } - assert_eq!("{\"bar\": true}", format!("{:?}", Foo)); + struct KeyValue; + + impl fmt::Debug for KeyValue { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map() + .key(&"bar").value(&true) + .finish() + } + } + + assert_eq!(format!("{:?}", Entry), format!("{:?}", KeyValue)); + assert_eq!(format!("{:#?}", Entry), format!("{:#?}", KeyValue)); + + assert_eq!("{\"bar\": true}", format!("{:?}", Entry)); assert_eq!( "{ \"bar\": true, }", - format!("{:#?}", Foo)); + format!("{:#?}", Entry)); } #[test] fn test_multiple() { - struct Foo; + struct Entry; - impl fmt::Debug for Foo { + impl fmt::Debug for Entry { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_map() .entry(&"bar", &true) @@ -242,13 +255,27 @@ mod debug_map { } } - assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo)); + struct KeyValue; + + impl fmt::Debug for KeyValue { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map() + .key(&"bar").value(&true) + .key(&10).value(&format_args!("{}/{}", 10, 20)) + .finish() + } + } + + assert_eq!(format!("{:?}", Entry), format!("{:?}", KeyValue)); + assert_eq!(format!("{:#?}", Entry), format!("{:#?}", KeyValue)); + + assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Entry)); assert_eq!( "{ \"bar\": true, 10: 10/20, }", - format!("{:#?}", Foo)); + format!("{:#?}", Entry)); } #[test] @@ -291,6 +318,56 @@ mod debug_map { }", format!("{:#?}", Bar)); } + + #[test] + #[should_panic] + fn test_invalid_key_when_entry_is_incomplete() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map() + .key(&"bar") + .key(&"invalid") + .finish() + } + } + + format!("{:?}", Foo); + } + + #[test] + #[should_panic] + fn test_invalid_finish_incomplete_entry() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map() + .key(&"bar") + .finish() + } + } + + format!("{:?}", Foo); + } + + #[test] + #[should_panic] + fn test_invalid_value_before_key() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map() + .value(&"invalid") + .key(&"bar") + .finish() + } + } + + format!("{:?}", Foo); + } } mod debug_set { diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs index df1deeaeb9..d86e21cf40 100644 --- a/src/libcore/tests/fmt/mod.rs +++ b/src/libcore/tests/fmt/mod.rs @@ -3,7 +3,6 @@ mod float; mod num; #[test] -#[cfg(not(miri))] // Miri cannot print pointers fn test_format_flags() { // No residual flags left by pointer formatting let p = "".as_ptr(); @@ -13,7 +12,6 @@ fn test_format_flags() { } #[test] -#[cfg(not(miri))] // Miri cannot print pointers fn test_pointer_formats_data_pointer() { let b: &[u8] = b""; let s: &str = ""; diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 4d840ef24c..3615fab791 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -188,6 +188,19 @@ fn test_iterator_step_by() { assert_eq!(it.next(), Some(6)); assert_eq!(it.next(), Some(9)); assert_eq!(it.next(), None); + + let mut it = (0..3).step_by(1); + assert_eq!(it.next_back(), Some(2)); + assert_eq!(it.next_back(), Some(1)); + assert_eq!(it.next_back(), Some(0)); + assert_eq!(it.next_back(), None); + + let mut it = (0..11).step_by(3); + assert_eq!(it.next_back(), Some(9)); + assert_eq!(it.next_back(), Some(6)); + assert_eq!(it.next_back(), Some(3)); + assert_eq!(it.next_back(), Some(0)); + assert_eq!(it.next_back(), None); } #[test] @@ -252,6 +265,31 @@ fn test_iterator_step_by_nth_overflow() { assert_eq!(it.0, (usize::MAX as Bigger) * 1); } +#[test] +fn test_iterator_step_by_nth_back() { + let mut it = (0..16).step_by(5); + assert_eq!(it.nth_back(0), Some(15)); + assert_eq!(it.nth_back(0), Some(10)); + assert_eq!(it.nth_back(0), Some(5)); + assert_eq!(it.nth_back(0), Some(0)); + assert_eq!(it.nth_back(0), None); + + let mut it = (0..16).step_by(5); + assert_eq!(it.next(), Some(0)); // to set `first_take` to `false` + assert_eq!(it.nth_back(0), Some(15)); + assert_eq!(it.nth_back(0), Some(10)); + assert_eq!(it.nth_back(0), Some(5)); + assert_eq!(it.nth_back(0), None); + + let it = || (0..18).step_by(5); + assert_eq!(it().nth_back(0), Some(15)); + assert_eq!(it().nth_back(1), Some(10)); + assert_eq!(it().nth_back(2), Some(5)); + assert_eq!(it().nth_back(3), Some(0)); + assert_eq!(it().nth_back(4), None); + assert_eq!(it().nth_back(42), None); +} + #[test] #[should_panic] fn test_iterator_step_by_zero() { @@ -465,8 +503,8 @@ fn test_iterator_filter_fold() { #[test] fn test_iterator_peekable() { let xs = vec![0, 1, 2, 3, 4, 5]; - let mut it = xs.iter().cloned().peekable(); + let mut it = xs.iter().cloned().peekable(); assert_eq!(it.len(), 6); assert_eq!(it.peek().unwrap(), &0); assert_eq!(it.len(), 6); @@ -492,6 +530,33 @@ fn test_iterator_peekable() { assert_eq!(it.len(), 0); assert!(it.next().is_none()); assert_eq!(it.len(), 0); + + let mut it = xs.iter().cloned().peekable(); + assert_eq!(it.len(), 6); + assert_eq!(it.peek().unwrap(), &0); + assert_eq!(it.len(), 6); + assert_eq!(it.next_back().unwrap(), 5); + assert_eq!(it.len(), 5); + assert_eq!(it.next_back().unwrap(), 4); + assert_eq!(it.len(), 4); + assert_eq!(it.next_back().unwrap(), 3); + assert_eq!(it.len(), 3); + assert_eq!(it.peek().unwrap(), &0); + assert_eq!(it.len(), 3); + assert_eq!(it.peek().unwrap(), &0); + assert_eq!(it.len(), 3); + assert_eq!(it.next_back().unwrap(), 2); + assert_eq!(it.len(), 2); + assert_eq!(it.next_back().unwrap(), 1); + assert_eq!(it.len(), 1); + assert_eq!(it.peek().unwrap(), &0); + assert_eq!(it.len(), 1); + assert_eq!(it.next_back().unwrap(), 0); + assert_eq!(it.len(), 0); + assert!(it.peek().is_none()); + assert_eq!(it.len(), 0); + assert!(it.next_back().is_none()); + assert_eq!(it.len(), 0); } #[test] @@ -564,6 +629,18 @@ fn test_iterator_peekable_fold() { assert_eq!(i, xs.len()); } +#[test] +fn test_iterator_peekable_rfold() { + let xs = [0, 1, 2, 3, 4, 5]; + let mut it = xs.iter().peekable(); + assert_eq!(it.peek(), Some(&&0)); + let i = it.rfold(0, |i, &x| { + assert_eq!(x, xs[xs.len() - 1 - i]); + i + 1 + }); + assert_eq!(i, xs.len()); +} + /// This is an iterator that follows the Iterator contract, /// but it is not fused. After having returned None once, it will start /// producing elements if .next() is called again. @@ -812,13 +889,25 @@ fn test_iterator_skip_fold() { fn test_iterator_take() { let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19]; let ys = [0, 1, 2, 3, 5]; - let mut it = xs.iter().take(5); + + let mut it = xs.iter().take(ys.len()); let mut i = 0; - assert_eq!(it.len(), 5); + assert_eq!(it.len(), ys.len()); while let Some(&x) = it.next() { assert_eq!(x, ys[i]); i += 1; - assert_eq!(it.len(), 5-i); + assert_eq!(it.len(), ys.len() - i); + } + assert_eq!(i, ys.len()); + assert_eq!(it.len(), 0); + + let mut it = xs.iter().take(ys.len()); + let mut i = 0; + assert_eq!(it.len(), ys.len()); + while let Some(&x) = it.next_back() { + i += 1; + assert_eq!(x, ys[ys.len() - i]); + assert_eq!(it.len(), ys.len() - i); } assert_eq!(i, ys.len()); assert_eq!(it.len(), 0); @@ -848,19 +937,51 @@ fn test_iterator_take_nth() { } } +#[test] +fn test_iterator_take_nth_back() { + let xs = [0, 1, 2, 4, 5]; + let mut it = xs.iter(); + { + let mut take = it.by_ref().take(3); + let mut i = 0; + while let Some(&x) = take.nth_back(0) { + i += 1; + assert_eq!(x, 3 - i); + } + } + assert_eq!(it.nth_back(0), None); + + let xs = [0, 1, 2, 3, 4]; + let mut it = xs.iter().take(7); + assert_eq!(it.nth_back(1), Some(&3)); + assert_eq!(it.nth_back(1), Some(&1)); + assert_eq!(it.nth_back(1), None); +} + #[test] fn test_iterator_take_short() { let xs = [0, 1, 2, 3]; - let ys = [0, 1, 2, 3]; + let mut it = xs.iter().take(5); let mut i = 0; - assert_eq!(it.len(), 4); + assert_eq!(it.len(), xs.len()); while let Some(&x) = it.next() { - assert_eq!(x, ys[i]); + assert_eq!(x, xs[i]); i += 1; - assert_eq!(it.len(), 4-i); + assert_eq!(it.len(), xs.len() - i); } - assert_eq!(i, ys.len()); + assert_eq!(i, xs.len()); + assert_eq!(it.len(), 0); + + let mut it = xs.iter().take(5); + let mut i = 0; + assert_eq!(it.len(), xs.len()); + while let Some(&x) = it.next_back() { + i += 1; + assert_eq!(x, xs[xs.len() - i]); + assert_eq!(it.len(), xs.len() - i); + } + assert_eq!(i, xs.len()); assert_eq!(it.len(), 0); } @@ -1082,6 +1203,23 @@ fn test_iterator_sum_result() { assert_eq!(v.iter().cloned().sum::>(), Ok(10)); let v: &[Result] = &[Ok(1), Err(()), Ok(3), Ok(4)]; assert_eq!(v.iter().cloned().sum::>(), Err(())); + + #[derive(PartialEq, Debug)] + struct S(Result); + + impl Sum> for S { + fn sum>>(mut iter: I) -> Self { + // takes the sum by repeatedly calling `next` on `iter`, + // thus testing that repeated calls to `ResultShunt::try_fold` + // produce the expected results + Self(iter.by_ref().sum()) + } + } + + let v: &[Result] = &[Ok(1), Ok(2), Ok(3), Ok(4)]; + assert_eq!(v.iter().cloned().sum::(), S(Ok(10))); + let v: &[Result] = &[Ok(1), Err(()), Ok(3), Ok(4)]; + assert_eq!(v.iter().cloned().sum::(), S(Err(()))); } #[test] @@ -2278,17 +2416,50 @@ fn test_enumerate_try_folds() { } #[test] -fn test_peek_try_fold() { +fn test_peek_try_folds() { let f = &|acc, x| i32::checked_add(2*acc, x); + assert_eq!((1..20).peekable().try_fold(7, f), (1..20).try_fold(7, f)); + assert_eq!((1..20).peekable().try_rfold(7, f), (1..20).try_rfold(7, f)); + let mut iter = (1..20).peekable(); assert_eq!(iter.peek(), Some(&1)); assert_eq!(iter.try_fold(7, f), (1..20).try_fold(7, f)); + let mut iter = (1..20).peekable(); + assert_eq!(iter.peek(), Some(&1)); + assert_eq!(iter.try_rfold(7, f), (1..20).try_rfold(7, f)); + let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable(); assert_eq!(iter.peek(), Some(&100)); assert_eq!(iter.try_fold(0, i8::checked_add), None); assert_eq!(iter.peek(), Some(&40)); + + let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable(); + assert_eq!(iter.peek(), Some(&100)); + assert_eq!(iter.try_rfold(0, i8::checked_add), None); + assert_eq!(iter.peek(), Some(&100)); + assert_eq!(iter.next_back(), Some(50)); + + let mut iter = (2..5).peekable(); + assert_eq!(iter.peek(), Some(&2)); + assert_eq!(iter.try_for_each(Err), Err(2)); + assert_eq!(iter.peek(), Some(&3)); + assert_eq!(iter.try_for_each(Err), Err(3)); + assert_eq!(iter.peek(), Some(&4)); + assert_eq!(iter.try_for_each(Err), Err(4)); + assert_eq!(iter.peek(), None); + assert_eq!(iter.try_for_each(Err), Ok(())); + + let mut iter = (2..5).peekable(); + assert_eq!(iter.peek(), Some(&2)); + assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(4)); + assert_eq!(iter.peek(), Some(&2)); + assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(3)); + assert_eq!(iter.peek(), Some(&2)); + assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(2)); + assert_eq!(iter.peek(), None); + assert_eq!(iter.try_rfold((), |(), x| Err(x)), Ok(())); } #[test] @@ -2371,13 +2542,25 @@ fn test_skip_nth_back() { fn test_take_try_folds() { let f = &|acc, x| i32::checked_add(2*acc, x); assert_eq!((10..30).take(10).try_fold(7, f), (10..20).try_fold(7, f)); - //assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f)); + assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f)); let mut iter = (10..30).take(20); assert_eq!(iter.try_fold(0, i8::checked_add), None); assert_eq!(iter.next(), Some(20)); - //assert_eq!(iter.try_rfold(0, i8::checked_add), None); - //assert_eq!(iter.next_back(), Some(24)); + assert_eq!(iter.try_rfold(0, i8::checked_add), None); + assert_eq!(iter.next_back(), Some(24)); + + let mut iter = (2..20).take(3); + assert_eq!(iter.try_for_each(Err), Err(2)); + assert_eq!(iter.try_for_each(Err), Err(3)); + assert_eq!(iter.try_for_each(Err), Err(4)); + assert_eq!(iter.try_for_each(Err), Ok(())); + + let mut iter = (2..20).take(3).rev(); + assert_eq!(iter.try_for_each(Err), Err(4)); + assert_eq!(iter.try_for_each(Err), Err(3)); + assert_eq!(iter.try_for_each(Err), Err(2)); + assert_eq!(iter.try_for_each(Err), Ok(())); } #[test] @@ -2460,3 +2643,39 @@ fn test_is_sorted() { assert!(!["c", "bb", "aaa"].iter().is_sorted()); assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); } + +#[test] +fn test_partition() { + fn check(xs: &mut [i32], ref p: impl Fn(&i32) -> bool, expected: usize) { + let i = xs.iter_mut().partition_in_place(p); + assert_eq!(expected, i); + assert!(xs[..i].iter().all(p)); + assert!(!xs[i..].iter().any(p)); + assert!(xs.iter().is_partitioned(p)); + if i == 0 || i == xs.len() { + assert!(xs.iter().rev().is_partitioned(p)); + } else { + assert!(!xs.iter().rev().is_partitioned(p)); + } + } + + check(&mut [], |_| true, 0); + check(&mut [], |_| false, 0); + + check(&mut [0], |_| true, 1); + check(&mut [0], |_| false, 0); + + check(&mut [-1, 1], |&x| x > 0, 1); + check(&mut [-1, 1], |&x| x < 0, 1); + + let ref mut xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + check(xs, |_| true, 10); + check(xs, |_| false, 0); + check(xs, |&x| x % 2 == 0, 5); // evens + check(xs, |&x| x % 2 == 1, 5); // odds + check(xs, |&x| x % 3 == 0, 4); // multiple of 3 + check(xs, |&x| x % 4 == 0, 3); // multiple of 4 + check(xs, |&x| x % 5 == 0, 2); // multiple of 5 + check(xs, |&x| x < 3, 3); // small + check(xs, |&x| x > 6, 3); // large +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index bf072a9243..a3b108b2e9 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -3,8 +3,8 @@ #![feature(cell_update)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] +#![feature(debug_map_key_value)] #![feature(dec2flt)] -#![feature(euclidean_division)] #![feature(exact_size_is_empty)] #![feature(fixed_size_array)] #![feature(flt2dec)] @@ -30,7 +30,8 @@ #![feature(slice_partition_dedup)] #![feature(int_error_matching)] #![feature(const_fn)] -#![warn(rust_2018_idioms)] +#![feature(iter_partition_in_place)] +#![feature(iter_is_partitioned)] extern crate test; diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs index 0e71426c64..46eacb4200 100644 --- a/src/libcore/tests/num/dec2flt/mod.rs +++ b/src/libcore/tests/num/dec2flt/mod.rs @@ -77,6 +77,7 @@ fn infinity() { fn zero() { test_literal!(0.0); test_literal!(1e-325); + #[cfg(not(miri))] // Miri is too slow test_literal!(1e-326); #[cfg(not(miri))] // Miri is too slow test_literal!(1e-500); diff --git a/src/libcore/tests/num/flt2dec/estimator.rs b/src/libcore/tests/num/flt2dec/estimator.rs index 2dbb8e3a5f..c51451708f 100644 --- a/src/libcore/tests/num/flt2dec/estimator.rs +++ b/src/libcore/tests/num/flt2dec/estimator.rs @@ -42,7 +42,12 @@ fn test_estimate_scaling_factor() { assert_almost_eq!(estimate_scaling_factor(1, -1074), -323); assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309); - for i in -1074..972 { + #[cfg(not(miri))] // Miri is too slow + let iter = -1074..972; + #[cfg(miri)] + let iter = (-1074..972).step_by(37); + + for i in iter { let expected = super::ldexp_f64(1.0, i).log10().ceil(); assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16); } diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs index f42f500c2d..c41d35efce 100644 --- a/src/libcore/tests/num/flt2dec/mod.rs +++ b/src/libcore/tests/num/flt2dec/mod.rs @@ -1,5 +1,3 @@ -#![cfg(not(miri))] // Miri does not implement ldexp, which most tests here need - use std::prelude::v1::*; use std::{str, i16, f32, f64, fmt}; @@ -257,6 +255,7 @@ pub fn f32_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) check_shortest!(f(minf32) => b"1", -44); } +#[cfg(not(miri))] // Miri is too slow pub fn f32_exact_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { let minf32 = ldexp_f32(1.0, -149); @@ -362,6 +361,7 @@ pub fn f64_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) check_shortest!(f(minf64) => b"5", -323); } +#[cfg(not(miri))] // Miri is too slow pub fn f64_exact_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { let minf64 = ldexp_f64(1.0, -1074); @@ -553,6 +553,10 @@ pub fn to_shortest_str_test(mut f_: F) assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", "")); + if cfg!(miri) { // Miri is too slow + return; + } + // very large output assert_eq!(to_string(f, 1.1, Minus, 80000, false), format!("1.1{:0>79999}", "")); } @@ -807,6 +811,10 @@ pub fn to_exact_exp_str_test(mut f_: F) "1.401298464324817070923729583289916131280261941876515771757068283\ 8897910826858606014866381883621215820312500000000000000000000000e-45"); + if cfg!(miri) { // Miri is too slow + return; + } + assert_eq!(to_string(f, f64::MAX, Minus, 1, false), "2e308"); assert_eq!(to_string(f, f64::MAX, Minus, 2, false), "1.8e308"); assert_eq!(to_string(f, f64::MAX, Minus, 4, false), "1.798e308"); @@ -1040,6 +1048,10 @@ pub fn to_exact_fixed_str_test(mut f_: F) assert_eq!(to_string(f, f32::MAX, Minus, 2, false), "340282346638528859811704183484516925440.00"); + if cfg!(miri) { // Miri is too slow + return; + } + let minf32 = ldexp_f32(1.0, -149); assert_eq!(to_string(f, minf32, Minus, 0, false), "0"); assert_eq!(to_string(f, minf32, Minus, 1, false), "0.0"); diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs index 35e3fbcbb7..d954379339 100644 --- a/src/libcore/tests/num/flt2dec/random.rs +++ b/src/libcore/tests/num/flt2dec/random.rs @@ -8,8 +8,8 @@ use core::num::flt2dec::strategy::grisu::format_exact_opt; use core::num::flt2dec::strategy::grisu::format_shortest_opt; use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded}; -use rand::FromEntropy; -use rand::rngs::SmallRng; +use rand::SeedableRng; +use rand::rngs::StdRng; use rand::distributions::{Distribution, Uniform}; pub fn decode_finite(v: T) -> Decoded { @@ -65,7 +65,7 @@ pub fn f32_random_equivalence_test(f: F, g: G, k: usize, n: usize) if cfg!(target_os = "emscripten") { return // using rng pulls in i128 support, which doesn't work } - let mut rng = SmallRng::from_entropy(); + let mut rng = StdRng::from_entropy(); let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000); iterate("f32_random_equivalence_test", k, n, f, g, |_| { let x = f32::from_bits(f32_range.sample(&mut rng)); @@ -79,7 +79,7 @@ pub fn f64_random_equivalence_test(f: F, g: G, k: usize, n: usize) if cfg!(target_os = "emscripten") { return // using rng pulls in i128 support, which doesn't work } - let mut rng = SmallRng::from_entropy(); + let mut rng = StdRng::from_entropy(); let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000); iterate("f64_random_equivalence_test", k, n, f, g, |_| { let x = f64::from_bits(f64_range.sample(&mut rng)); @@ -109,8 +109,13 @@ pub fn f32_exhaustive_equivalence_test(f: F, g: G, k: usize) #[test] fn shortest_random_equivalence_test() { use core::num::flt2dec::strategy::dragon::format_shortest as fallback; - f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000); - f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000); + #[cfg(not(miri))] // Miri is too slow + const N: usize = 10_000; + #[cfg(miri)] + const N: usize = 10; + + f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N); + f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N); } #[test] #[ignore] // it is too expensive @@ -138,17 +143,27 @@ fn shortest_f64_hard_random_equivalence_test() { #[test] fn exact_f32_random_equivalence_test() { use core::num::flt2dec::strategy::dragon::format_exact as fallback; + #[cfg(not(miri))] // Miri is too slow + const N: usize = 1_000; + #[cfg(miri)] + const N: usize = 3; + for k in 1..21 { f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN), - |d, buf| fallback(d, buf, i16::MIN), k, 1_000); + |d, buf| fallback(d, buf, i16::MIN), k, N); } } #[test] fn exact_f64_random_equivalence_test() { use core::num::flt2dec::strategy::dragon::format_exact as fallback; + #[cfg(not(miri))] // Miri is too slow + const N: usize = 1_000; + #[cfg(miri)] + const N: usize = 3; + for k in 1..21 { f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN), - |d, buf| fallback(d, buf, i16::MIN), k, 1_000); + |d, buf| fallback(d, buf, i16::MIN), k, N); } } diff --git a/src/libcore/tests/num/flt2dec/strategy/dragon.rs b/src/libcore/tests/num/flt2dec/strategy/dragon.rs index 5e4cc23d33..dc4d78bfae 100644 --- a/src/libcore/tests/num/flt2dec/strategy/dragon.rs +++ b/src/libcore/tests/num/flt2dec/strategy/dragon.rs @@ -23,6 +23,7 @@ fn shortest_sanity_test() { } #[test] +#[cfg(not(miri))] // Miri is too slow fn exact_sanity_test() { // This test ends up running what I can only assume is some corner-ish case // of the `exp2` library function, defined in whatever C runtime we're diff --git a/src/libcore/tests/num/flt2dec/strategy/grisu.rs b/src/libcore/tests/num/flt2dec/strategy/grisu.rs index f1afd7d4bf..f8bdddfe2e 100644 --- a/src/libcore/tests/num/flt2dec/strategy/grisu.rs +++ b/src/libcore/tests/num/flt2dec/strategy/grisu.rs @@ -36,6 +36,7 @@ fn shortest_sanity_test() { } #[test] +#[cfg(not(miri))] // Miri is too slow fn exact_sanity_test() { // See comments in dragon.rs's exact_sanity_test for why this test is // ignored on MSVC diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index b059b13486..ff43fc49f7 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -1,6 +1,8 @@ use core::option::*; use core::mem; use core::clone::Clone; +use core::array::FixedSizeArray; +use core::ops::DerefMut; #[test] fn test_get_ptr() { @@ -310,20 +312,38 @@ fn test_try() { } #[test] -fn test_option_deref() { +fn test_option_as_deref() { // Some: &Option::Some(T) -> Option<&T::Deref::Target>::Some(&*T) let ref_option = &Some(&42); - assert_eq!(ref_option.deref(), Some(&42)); + assert_eq!(ref_option.as_deref(), Some(&42)); let ref_option = &Some(String::from("a result")); - assert_eq!(ref_option.deref(), Some("a result")); + assert_eq!(ref_option.as_deref(), Some("a result")); let ref_option = &Some(vec![1, 2, 3, 4, 5]); - assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..])); + assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice())); // None: &Option>::None -> None let ref_option: &Option<&i32> = &None; - assert_eq!(ref_option.deref(), None); + assert_eq!(ref_option.as_deref(), None); +} + +#[test] +fn test_option_as_deref_mut() { + // Some: &mut Option::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T) + let mut val = 42; + let ref_option = &mut Some(&mut val); + assert_eq!(ref_option.as_deref_mut(), Some(&mut 42)); + + let ref_option = &mut Some(String::from("a result")); + assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut())); + + let ref_option = &mut Some(vec![1, 2, 3, 4, 5]); + assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice())); + + // None: &mut Option>::None -> None + let ref_option: &mut Option<&mut i32> = &mut None; + assert_eq!(ref_option.as_deref_mut(), None); } #[test] diff --git a/src/libcore/tests/pattern.rs b/src/libcore/tests/pattern.rs index b78ed02107..06c3a78c16 100644 --- a/src/libcore/tests/pattern.rs +++ b/src/libcore/tests/pattern.rs @@ -5,7 +5,7 @@ use std::str::pattern::*; macro_rules! search_asserts { ($haystack:expr, $needle:expr, $testname:expr, [$($func:ident),*], $result:expr) => { let mut searcher = $needle.into_searcher($haystack); - let arr = [$( Step::from(searcher.$func()) ),+]; + let arr = [$( Step::from(searcher.$func()) ),*]; assert_eq!(&arr[..], &$result, $testname); } } diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 03fe1fe5a7..1a6be3a9bb 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -145,7 +145,6 @@ fn test_as_ref() { } #[test] -#[cfg(not(miri))] // This test is UB according to Stacked Borrows fn test_as_mut() { unsafe { let p: *mut isize = null_mut(); @@ -164,7 +163,7 @@ fn test_as_mut() { // Pointers to unsized types -- slices let s: &mut [u8] = &mut [1, 2, 3]; let ms: *mut [u8] = s; - assert_eq!(ms.as_mut(), Some(s)); + assert_eq!(ms.as_mut(), Some(&mut [1, 2, 3][..])); let mz: *mut [u8] = &mut []; assert_eq!(mz.as_mut(), Some(&mut [][..])); @@ -253,7 +252,6 @@ fn test_unsized_nonnull() { #[test] #[allow(warnings)] -#[cfg(not(miri))] // Miri cannot hash pointers // Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the // ABI, or even point to an actual executable code, because the function itself is never invoked. #[no_mangle] @@ -293,7 +291,7 @@ fn write_unaligned_drop() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn align_offset_zst() { // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at // all, because no amount of elements will align the pointer. @@ -308,7 +306,7 @@ fn align_offset_zst() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn align_offset_stride1() { // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to // number of bytes. diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 1fab07526a..163f8d0ab3 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -1,4 +1,6 @@ use core::option::*; +use core::array::FixedSizeArray; +use core::ops::DerefMut; fn op1() -> Result { Ok(666) } fn op2() -> Result { Err("sadface") } @@ -225,94 +227,213 @@ fn test_try() { } #[test] -fn test_result_deref() { - // &Result::Ok(T).deref_ok() -> +fn test_result_as_deref() { + // &Result::Ok(T).as_deref_ok() -> // Result<&T::Deref::Target, &E>::Ok(&*T) let ref_ok = &Result::Ok::<&i32, u8>(&42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.deref_ok(), expected_result); + assert_eq!(ref_ok.as_deref_ok(), expected_result); let ref_ok = &Result::Ok::(String::from("a result")); let expected_result = Result::Ok::<&str, &u32>("a result"); - assert_eq!(ref_ok.deref_ok(), expected_result); + assert_eq!(ref_ok.as_deref_ok(), expected_result); let ref_ok = &Result::Ok::, u32>(vec![1, 2, 3, 4, 5]); - let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]); - assert_eq!(ref_ok.deref_ok(), expected_result); + let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); + assert_eq!(ref_ok.as_deref_ok(), expected_result); - // &Result::Ok(T).deref() -> + // &Result::Ok(T).as_deref() -> // Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T) let ref_ok = &Result::Ok::<&i32, &u8>(&42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.deref(), expected_result); + assert_eq!(ref_ok.as_deref(), expected_result); let ref_ok = &Result::Ok::(String::from("a result")); let expected_result = Result::Ok::<&str, &u32>("a result"); - assert_eq!(ref_ok.deref(), expected_result); + assert_eq!(ref_ok.as_deref(), expected_result); let ref_ok = &Result::Ok::, &u32>(vec![1, 2, 3, 4, 5]); - let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]); - assert_eq!(ref_ok.deref(), expected_result); + let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); + assert_eq!(ref_ok.as_deref(), expected_result); - // &Result::Err(T).deref_err() -> + // &Result::Err(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Err(&*E) let ref_err = &Result::Err::(&41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.deref_err(), expected_result); + assert_eq!(ref_err.as_deref_err(), expected_result); let ref_err = &Result::Err::(String::from("an error")); let expected_result = Result::Err::<&u32, &str>("an error"); - assert_eq!(ref_err.deref_err(), expected_result); + assert_eq!(ref_err.as_deref_err(), expected_result); let ref_err = &Result::Err::>(vec![5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); - assert_eq!(ref_err.deref_err(), expected_result); + let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice()); + assert_eq!(ref_err.as_deref_err(), expected_result); - // &Result::Err(T).deref_err() -> + // &Result::Err(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Err(&*E) let ref_err = &Result::Err::<&u8, &i32>(&41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.deref(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); let ref_err = &Result::Err::<&u32, String>(String::from("an error")); let expected_result = Result::Err::<&u32, &str>("an error"); - assert_eq!(ref_err.deref(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); let ref_err = &Result::Err::<&u32, Vec>(vec![5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); - assert_eq!(ref_err.deref(), expected_result); + let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice()); + assert_eq!(ref_err.as_deref(), expected_result); - // The following cases test calling deref_* with the wrong variant (i.e. - // `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`. - // While unusual, these cases are supported to ensure that an `inner_deref` + // The following cases test calling `as_deref_*` with the wrong variant (i.e. + // `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`. + // While uncommon, these cases are supported to ensure that an `as_deref_*` // call can still be made even when one of the Result types does not implement // `Deref` (for example, std::io::Error). - // &Result::Ok(T).deref_err() -> + // &Result::Ok(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Ok(&T) let ref_ok = &Result::Ok::(42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.deref_err(), expected_result); + assert_eq!(ref_ok.as_deref_err(), expected_result); let ref_ok = &Result::Ok::<&str, &u32>("a result"); let expected_result = Result::Ok::<&&str, &u32>(&"a result"); - assert_eq!(ref_ok.deref_err(), expected_result); + assert_eq!(ref_ok.as_deref_err(), expected_result); let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]); let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]); - assert_eq!(ref_ok.deref_err(), expected_result); + assert_eq!(ref_ok.as_deref_err(), expected_result); - // &Result::Err(E).deref_ok() -> + // &Result::Err(E).as_deref_ok() -> // Result<&T::Deref::Target, &E>::Err(&E) let ref_err = &Result::Err::<&u8, i32>(41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.deref_ok(), expected_result); + assert_eq!(ref_err.as_deref_ok(), expected_result); let ref_err = &Result::Err::<&u32, &str>("an error"); let expected_result = Result::Err::<&u32, &&str>(&"an error"); - assert_eq!(ref_err.deref_ok(), expected_result); + assert_eq!(ref_err.as_deref_ok(), expected_result); let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]); let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]); - assert_eq!(ref_err.deref_ok(), expected_result); + assert_eq!(ref_err.as_deref_ok(), expected_result); +} + +#[test] +fn test_result_as_deref_mut() { + // &mut Result::Ok(T).as_deref_mut_ok() -> + // Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T) + let mut val = 42; + let mut expected_val = 42; + let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val); + let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); + assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); + + let mut expected_string = String::from("a result"); + let mut_ok = &mut Result::Ok::(expected_string.clone()); + let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut()); + assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); + + let mut expected_vec = vec![1, 2, 3, 4, 5]; + let mut_ok = &mut Result::Ok::, u32>(expected_vec.clone()); + let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); + assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); + + // &mut Result::Ok(T).as_deref_mut() -> + // Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T) + let mut val = 42; + let mut expected_val = 42; + let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val); + let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); + assert_eq!(mut_ok.as_deref_mut(), expected_result); + + let mut expected_string = String::from("a result"); + let mut_ok = &mut Result::Ok::(expected_string.clone()); + let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut()); + assert_eq!(mut_ok.as_deref_mut(), expected_result); + + let mut expected_vec = vec![1, 2, 3, 4, 5]; + let mut_ok = &mut Result::Ok::, &mut u32>(expected_vec.clone()); + let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); + assert_eq!(mut_ok.as_deref_mut(), expected_result); + + // &mut Result::Err(T).as_deref_mut_err() -> + // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) + let mut val = 41; + let mut expected_val = 41; + let mut_err = &mut Result::Err::(&mut val); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + assert_eq!(mut_err.as_deref_mut_err(), expected_result); + + let mut expected_string = String::from("an error"); + let mut_err = &mut Result::Err::(expected_string.clone()); + let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut()); + assert_eq!(mut_err.as_deref_mut_err(), expected_result); + + let mut expected_vec = vec![5, 4, 3, 2, 1]; + let mut_err = &mut Result::Err::>(expected_vec.clone()); + let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice()); + assert_eq!(mut_err.as_deref_mut_err(), expected_result); + + // &mut Result::Err(T).as_deref_mut_err() -> + // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) + let mut val = 41; + let mut expected_val = 41; + let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + assert_eq!(mut_err.as_deref_mut(), expected_result); + + let mut expected_string = String::from("an error"); + let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone()); + let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str()); + assert_eq!(mut_err.as_deref_mut(), expected_result); + + let mut expected_vec = vec![5, 4, 3, 2, 1]; + let mut_err = &mut Result::Err::<&mut u32, Vec>(expected_vec.clone()); + let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice()); + assert_eq!(mut_err.as_deref_mut(), expected_result); + + // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e. + // `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`. + // While uncommon, these cases are supported to ensure that an `as_deref_mut_*` + // call can still be made even when one of the Result types does not implement + // `Deref` (for example, std::io::Error). + + // &mut Result::Ok(T).as_deref_mut_err() -> + // Result<&mut T, &mut E::Deref::Target>::Ok(&mut T) + let mut expected_val = 42; + let mut_ok = &mut Result::Ok::(expected_val.clone()); + let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); + assert_eq!(mut_ok.as_deref_mut_err(), expected_result); + + let string = String::from("a result"); + let expected_string = string.clone(); + let mut ref_str = expected_string.as_ref(); + let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str()); + let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str); + assert_eq!(mut_ok.as_deref_mut_err(), expected_result); + + let mut expected_arr = [1, 2, 3, 4, 5]; + let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone()); + let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr); + assert_eq!(mut_ok.as_deref_mut_err(), expected_result); + + // &mut Result::Err(E).as_deref_mut_ok() -> + // Result<&mut T::Deref::Target, &mut E>::Err(&mut E) + let mut expected_val = 41; + let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone()); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + + let string = String::from("an error"); + let expected_string = string.clone(); + let mut ref_str = expected_string.as_ref(); + let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str()); + let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str); + assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + + let mut expected_arr = [5, 4, 3, 2, 1]; + let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone()); + let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr); + assert_eq!(mut_err.as_deref_mut_ok(), expected_result); } diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 03e65d2fe0..4790152512 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -3,19 +3,19 @@ use core::result::Result::{Ok, Err}; #[test] fn test_position() { let b = [1, 2, 3, 5, 5]; - assert!(b.iter().position(|&v| v == 9) == None); - assert!(b.iter().position(|&v| v == 5) == Some(3)); - assert!(b.iter().position(|&v| v == 3) == Some(2)); - assert!(b.iter().position(|&v| v == 0) == None); + assert_eq!(b.iter().position(|&v| v == 9), None); + assert_eq!(b.iter().position(|&v| v == 5), Some(3)); + assert_eq!(b.iter().position(|&v| v == 3), Some(2)); + assert_eq!(b.iter().position(|&v| v == 0), None); } #[test] fn test_rposition() { let b = [1, 2, 3, 5, 5]; - assert!(b.iter().rposition(|&v| v == 9) == None); - assert!(b.iter().rposition(|&v| v == 5) == Some(4)); - assert!(b.iter().rposition(|&v| v == 3) == Some(2)); - assert!(b.iter().rposition(|&v| v == 0) == None); + assert_eq!(b.iter().rposition(|&v| v == 9), None); + assert_eq!(b.iter().rposition(|&v| v == 5), Some(4)); + assert_eq!(b.iter().rposition(|&v| v == 3), Some(2)); + assert_eq!(b.iter().rposition(|&v| v == 0), None); } #[test] @@ -222,6 +222,28 @@ fn test_chunks_mut_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_mut_nth_back() { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + let mut c = v.chunks_mut(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[0, 1]); + + let v1: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let mut c1 = v1.chunks_mut(3); + assert_eq!(c1.nth_back(1).unwrap(), &[0, 1, 2]); + assert_eq!(c1.next(), None); + + let v3: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let mut c3 = v3.chunks_mut(10); + assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]); + assert_eq!(c3.next(), None); + + let v4: &mut [i32] = &mut [0, 1, 2]; + let mut c4 = v4.chunks_mut(10); + assert_eq!(c4.nth_back(1_000_000_000usize), None); +} + #[test] fn test_chunks_mut_last() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; @@ -275,6 +297,25 @@ fn test_chunks_exact_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_exact_nth_back() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.chunks_exact(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); + + let v2: &[i32] = &[0, 1, 2, 3, 4]; + let mut c2 = v2.chunks_exact(3); + assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]); + assert_eq!(c2.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &[i32] = &[0, 1, 2, 3, 4]; + let mut c3 = v3.chunks_exact(10); + assert_eq!(c3.nth_back(0), None); +} + #[test] fn test_chunks_exact_last() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; @@ -1111,12 +1152,50 @@ fn test_rotate_right() { } } +#[test] +#[cfg(not(miri))] // Miri is too slow +fn brute_force_rotate_test_0() { + // In case of edge cases involving multiple algorithms + let n = 300; + for len in 0..n { + for s in 0..len { + let mut v = Vec::with_capacity(len); + for i in 0..len { + v.push(i); + } + v[..].rotate_right(s); + for i in 0..v.len() { + assert_eq!(v[i], v.len().wrapping_add(i.wrapping_sub(s)) % v.len()); + } + } + } +} + +#[test] +fn brute_force_rotate_test_1() { + // `ptr_rotate` covers so many kinds of pointer usage, that this is just a good test for + // pointers in general. This uses a `[usize; 4]` to hit all algorithms without overwhelming miri + let n = 30; + for len in 0..n { + for s in 0..len { + let mut v: Vec<[usize; 4]> = Vec::with_capacity(len); + for i in 0..len { + v.push([i, 0, 0, 0]); + } + v[..].rotate_right(s); + for i in 0..v.len() { + assert_eq!(v[i][0], v.len().wrapping_add(i.wrapping_sub(s)) % v.len()); + } + } + } +} + #[test] #[cfg(not(target_arch = "wasm32"))] fn sort_unstable() { use core::cmp::Ordering::{Equal, Greater, Less}; use core::slice::heapsort; - use rand::{FromEntropy, Rng, rngs::SmallRng, seq::SliceRandom}; + use rand::{SeedableRng, Rng, rngs::StdRng, seq::SliceRandom}; #[cfg(not(miri))] // Miri is too slow let large_range = 500..510; @@ -1130,7 +1209,7 @@ fn sort_unstable() { let mut v = [0; 600]; let mut tmp = [0; 600]; - let mut rng = SmallRng::from_entropy(); + let mut rng = StdRng::from_entropy(); for len in (2..25).chain(large_range) { let v = &mut v[0..len]; @@ -1196,11 +1275,11 @@ fn sort_unstable() { #[cfg(not(miri))] // Miri is too slow fn partition_at_index() { use core::cmp::Ordering::{Equal, Greater, Less}; - use rand::rngs::SmallRng; + use rand::rngs::StdRng; use rand::seq::SliceRandom; - use rand::{FromEntropy, Rng}; + use rand::{SeedableRng, Rng}; - let mut rng = SmallRng::from_entropy(); + let mut rng = StdRng::from_entropy(); for len in (2..21).chain(500..501) { let mut orig = vec![0; len]; @@ -1396,7 +1475,7 @@ pub mod memchr { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn test_align_to_simple() { let bytes = [1u8, 2, 3, 4, 5, 6, 7]; let (prefix, aligned, suffix) = unsafe { bytes.align_to::() }; @@ -1420,7 +1499,7 @@ fn test_align_to_zst() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn test_align_to_non_trivial() { #[repr(align(8))] struct U64(u64, u64); #[repr(align(8))] struct U64U64U32(u64, u64, u32); diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 6efd22572d..fac70c468c 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -2,7 +2,7 @@ use core::time::Duration; #[test] fn creation() { - assert!(Duration::from_secs(1) != Duration::from_secs(0)); + assert_ne!(Duration::from_secs(1), Duration::from_secs(0)); assert_eq!(Duration::from_secs(1) + Duration::from_secs(2), Duration::from_secs(3)); assert_eq!(Duration::from_millis(10) + Duration::from_secs(4), diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 0f5f91f41a..5a0e4388e0 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -505,15 +505,14 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); /// assert_eq!(dur.as_secs_f64(), 2.7); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] - pub const fn as_secs_f64(&self) -> f64 { + pub fn as_secs_f64(&self) -> f64 { (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64) } @@ -523,15 +522,14 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); /// assert_eq!(dur.as_secs_f32(), 2.7); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] - pub const fn as_secs_f32(&self) -> f32 { + pub fn as_secs_f32(&self) -> f32 { (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32) } @@ -543,13 +541,12 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::from_secs_f64(2.7); /// assert_eq!(dur, Duration::new(2, 700_000_000)); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] pub fn from_secs_f64(secs: f64) -> Duration { const MAX_NANOS_F64: f64 = @@ -579,13 +576,12 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::from_secs_f32(2.7); /// assert_eq!(dur, Duration::new(2, 700_000_000)); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] pub fn from_secs_f32(secs: f32) -> Duration { const MAX_NANOS_F32: f32 = @@ -614,14 +610,13 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000)); /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0)); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] pub fn mul_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(rhs * self.as_secs_f64()) @@ -634,7 +629,6 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); @@ -643,7 +637,7 @@ impl Duration { /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] pub fn mul_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(rhs * self.as_secs_f32()) @@ -656,7 +650,6 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); @@ -664,7 +657,7 @@ impl Duration { /// // note that truncation is used, not rounding /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598)); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] pub fn div_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(self.as_secs_f64() / rhs) @@ -677,7 +670,6 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); @@ -687,7 +679,7 @@ impl Duration { /// // note that truncation is used, not rounding /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[stable(feature = "duration_float", since = "1.38.0")] #[inline] pub fn div_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(self.as_secs_f32() / rhs) @@ -697,14 +689,14 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] + /// #![feature(div_duration)] /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[unstable(feature = "div_duration", issue = "63139")] #[inline] pub fn div_duration_f64(self, rhs: Duration) -> f64 { self.as_secs_f64() / rhs.as_secs_f64() @@ -714,14 +706,14 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(duration_float)] + /// #![feature(div_duration)] /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` - #[unstable(feature = "duration_float", issue = "54361")] + #[unstable(feature = "div_duration", issue = "63139")] #[inline] pub fn div_duration_f32(self, rhs: Duration) -> f32 { self.as_secs_f32() / rhs.as_secs_f32() diff --git a/src/libcore/unicode/printable.py b/src/libcore/unicode/printable.py index 1288a78412..748917f1d3 100644 --- a/src/libcore/unicode/printable.py +++ b/src/libcore/unicode/printable.py @@ -111,17 +111,17 @@ def compress_normal(normal): return compressed def print_singletons(uppers, lowers, uppersname, lowersname): - print("const {}: &'static [(u8, u8)] = &[".format(uppersname)) + print("const {}: &[(u8, u8)] = &[".format(uppersname)) for u, c in uppers: print(" ({:#04x}, {}),".format(u, c)) print("];") - print("const {}: &'static [u8] = &[".format(lowersname)) + print("const {}: &[u8] = &[".format(lowersname)) for i in range(0, len(lowers), 8): print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8]))) print("];") def print_normal(normal, normalname): - print("const {}: &'static [u8] = &[".format(normalname)) + print("const {}: &[u8] = &[".format(normalname)) for v in normal: print(" {}".format(" ".join("{:#04x},".format(i) for i in v))) print("];") diff --git a/src/libcore/unicode/printable.rs b/src/libcore/unicode/printable.rs index a950e82cba..d411dda7dc 100644 --- a/src/libcore/unicode/printable.rs +++ b/src/libcore/unicode/printable.rs @@ -82,7 +82,7 @@ const SINGLETONS0U: &[(u8, u8)] = &[ (0x0b, 25), (0x0c, 20), (0x0d, 18), - (0x0e, 22), + (0x0e, 13), (0x0f, 4), (0x10, 3), (0x12, 18), @@ -96,13 +96,14 @@ const SINGLETONS0U: &[(u8, u8)] = &[ (0x1d, 1), (0x1f, 22), (0x20, 3), - (0x2b, 6), + (0x2b, 4), (0x2c, 2), (0x2d, 11), (0x2e, 1), (0x30, 3), (0x31, 2), - (0x32, 2), + (0x32, 1), + (0xa7, 2), (0xa9, 2), (0xaa, 4), (0xab, 8), @@ -130,27 +131,26 @@ const SINGLETONS0L: &[u8] = &[ 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04, 0x0d, 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0, - 0xf1, 0x83, 0x85, 0x86, 0x89, 0x8b, 0x8c, 0x98, - 0xa0, 0xa4, 0xa6, 0xa8, 0xa9, 0xac, 0xba, 0xbe, - 0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48, - 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e, - 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, - 0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, - 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe, - 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, - 0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, - 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17, - 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, - 0x5c, 0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, - 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, - 0x75, 0x96, 0x97, 0xc9, 0xff, 0x2f, 0x5f, 0x26, - 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, - 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, - 0x1f, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, - 0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef, - 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, - 0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, - 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff, + 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, + 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, + 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f, + 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, + 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, + 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff, + 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, + 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, + 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1e, + 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, + 0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, + 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, + 0x96, 0x97, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, + 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf, 0x9a, + 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, 0xc1, + 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, + 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef, 0x6e, 0x6f, + 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, 0xfe, + 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, + 0xd8, 0xd9, 0xe7, 0xfe, 0xff, ]; const SINGLETONS1U: &[(u8, u8)] = &[ (0x00, 6), @@ -168,7 +168,7 @@ const SINGLETONS1U: &[(u8, u8)] = &[ (0x14, 2), (0x15, 2), (0x17, 2), - (0x1a, 2), + (0x19, 4), (0x1c, 5), (0x1d, 8), (0x24, 1), @@ -182,10 +182,12 @@ const SINGLETONS1U: &[(u8, u8)] = &[ (0xd7, 2), (0xda, 1), (0xe0, 5), + (0xe1, 2), (0xe8, 2), (0xee, 32), (0xf0, 4), - (0xf9, 4), + (0xf9, 6), + (0xfa, 2), ]; const SINGLETONS1L: &[u8] = &[ 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, @@ -195,19 +197,20 @@ const SINGLETONS1L: &[u8] = &[ 0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c, - 0xb6, 0xb7, 0x1b, 0x1c, 0x84, 0x85, 0x09, 0x37, - 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66, - 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, - 0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55, 0x9d, 0xa0, - 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc, - 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, - 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd, 0xa0, 0x07, - 0x19, 0x1a, 0x22, 0x25, 0xc5, 0xc6, 0x04, 0x20, - 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, - 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, - 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b, 0x73, - 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, - 0xc0, 0xd0, 0x3f, 0x71, 0x72, 0x7b, + 0xb6, 0xb7, 0x1b, 0x1c, 0xa8, 0xa9, 0xd8, 0xd9, + 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, + 0x3e, 0x66, 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, + 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55, + 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, + 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, + 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd, + 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, + 0xc5, 0xc6, 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, + 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, + 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, + 0x65, 0x66, 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, + 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x0c, 0x72, + 0xa3, 0xa4, 0xcb, 0xcc, 0x6e, 0x6f, ]; const NORMAL0: &[u8] = &[ 0x00, 0x20, @@ -246,8 +249,8 @@ const NORMAL0: &[u8] = &[ 0x3a, 0x03, 0x11, 0x07, 0x06, 0x05, - 0x10, 0x08, - 0x56, 0x07, + 0x10, 0x07, + 0x57, 0x07, 0x02, 0x07, 0x15, 0x0d, 0x50, 0x04, @@ -258,8 +261,7 @@ const NORMAL0: &[u8] = &[ 0x0f, 0x0c, 0x3a, 0x04, 0x1d, 0x25, - 0x0d, 0x06, - 0x4c, 0x20, + 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80, 0xc8, 0x05, @@ -294,7 +296,7 @@ const NORMAL0: &[u8] = &[ 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, - 0x2a, 0x06, + 0x2b, 0x05, 0x82, 0xff, 0x11, 0x18, 0x08, 0x2f, 0x11, @@ -309,7 +311,7 @@ const NORMAL0: &[u8] = &[ 0x3b, 0x07, 0x02, 0x0e, 0x18, 0x09, - 0x80, 0xaf, 0x31, + 0x80, 0xb0, 0x30, 0x74, 0x0c, 0x80, 0xd6, 0x1a, 0x0c, 0x05, @@ -322,7 +324,7 @@ const NORMAL0: &[u8] = &[ 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, - 0x80, 0xba, 0x3d, + 0x80, 0xc7, 0x30, 0x35, 0x04, 0x0a, 0x06, 0x38, 0x08, @@ -335,7 +337,7 @@ const NORMAL0: &[u8] = &[ 0x80, 0x83, 0x18, 0x1c, 0x0a, 0x16, 0x09, - 0x46, 0x0a, + 0x48, 0x08, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17, 0x04, @@ -405,7 +407,8 @@ const NORMAL1: &[u8] = &[ 0x0a, 0x81, 0x26, 0x1f, 0x80, 0x81, 0x28, 0x08, - 0x2a, 0x80, 0xa6, + 0x2a, 0x80, 0x86, + 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e, @@ -422,20 +425,21 @@ const NORMAL1: &[u8] = &[ 0x01, 0x05, 0x10, 0x03, 0x05, 0x80, 0x8b, - 0x5f, 0x21, + 0x60, 0x20, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22, 0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, - 0x38, 0x08, + 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04, 0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, - 0x01, 0x81, 0x00, + 0x01, 0x80, 0xa0, + 0x45, 0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, @@ -447,8 +451,9 @@ const NORMAL1: &[u8] = &[ 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81, 0x36, - 0x19, 0x81, 0x07, - 0x83, 0x9a, 0x66, + 0x19, 0x80, 0xc7, + 0x32, 0x0d, + 0x83, 0x9b, 0x66, 0x75, 0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, @@ -461,13 +466,15 @@ const NORMAL1: &[u8] = &[ 0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, - 0x45, 0x0b, - 0x2f, 0x10, + 0x4b, 0x04, + 0x39, 0x07, 0x11, 0x40, - 0x02, 0x1e, - 0x97, 0xf2, 0x0e, + 0x04, 0x1c, + 0x97, 0xf8, 0x08, 0x82, 0xf3, 0xa5, 0x0d, - 0x81, 0x1f, 0x51, + 0x81, 0x1f, 0x31, + 0x03, 0x11, + 0x04, 0x08, 0x81, 0x8c, 0x89, 0x04, 0x6b, 0x05, 0x0d, 0x03, @@ -483,12 +490,18 @@ const NORMAL1: &[u8] = &[ 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50, - 0x2b, 0x87, 0xd5, + 0x2b, 0x80, 0xd5, + 0x2d, 0x03, + 0x1a, 0x04, + 0x02, 0x81, 0x70, + 0x3a, 0x05, + 0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, - 0x4b, 0x05, + 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83, 0x11, - 0x44, 0x81, 0x4b, + 0x44, 0x4c, + 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05, @@ -498,28 +511,29 @@ const NORMAL1: &[u8] = &[ 0x64, 0x0c, 0x56, 0x0a, 0x0d, 0x03, - 0x5c, 0x04, + 0x5d, 0x03, 0x3d, 0x39, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80, 0x9a, - 0x83, 0xd5, 0x0b, + 0x83, 0xd6, 0x0a, 0x0d, 0x03, - 0x0a, 0x06, + 0x0b, 0x05, 0x74, 0x0c, - 0x59, 0x27, + 0x59, 0x07, + 0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x1e, 0x52, - 0x0c, 0x04, - 0x67, 0x03, - 0x29, 0x0d, - 0x0a, 0x06, + 0x77, 0x03, + 0x31, 0x03, + 0x80, 0xa6, 0x0c, + 0x14, 0x04, + 0x03, 0x05, 0x03, 0x0d, - 0x30, 0x60, - 0x0e, 0x85, 0x92, + 0x06, 0x85, 0x6a, ]; diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs index 758cdb0b7c..3fae3a46ad 100644 --- a/src/libcore/unicode/tables.rs +++ b/src/libcore/unicode/tables.rs @@ -1,6 +1,6 @@ // NOTE: The following code was generated by "./unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] use crate::unicode::version::UnicodeVersion; use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie}; @@ -9,13 +9,13 @@ use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie}; /// `char` and `str` methods are based on. #[unstable(feature = "unicode_version", issue = "49726")] pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion { - major: 11, - minor: 0, + major: 12, + minor: 1, micro: 0, _priv: (), }; -pub mod general_category { - pub const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie { +pub(crate) mod general_category { + const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie { r1: &[ 0, 1, 0 ], @@ -28,7 +28,7 @@ pub mod general_category { Cc_table.lookup(c) } - pub const N_table: &super::BoolTrie = &super::BoolTrie { + const N_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -103,20 +103,21 @@ pub mod general_category { 0, 0, 0, 0, 9, 10, 11, 12, 0, 13, 14, 0, 15, 16, 17, 0, 18, 19, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 22, 0, 0, 23, 24, 0, 0, 0, 25, 0, 21, 26, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0, 28, 0, 28, 0, 0, 0, 0, 0, 28, 0, 29, 30, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 32, 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 38, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 28, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 28, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0 ], r6: &[ 0x0000000000000000, 0x000fffffffffff80, 0x01ffffffffffffff, 0x0000000000000c00, @@ -127,9 +128,10 @@ pub mod general_category { 0xfc00000000000000, 0x03ff000000000000, 0x7fffffff00000000, 0x0000007fe0000000, 0x00000000001e0000, 0x0000fffffffc0000, 0xffc0000000000000, 0x001ffffe03ff0000, 0x0000000003ff0000, 0x00000000000003ff, 0x0fff000000000000, 0x0007ffff00000000, - 0x00001fffffff0000, 0xffffffffffffffff, 0x00007fffffffffff, 0x00000003fbff0000, - 0x00000000007fffff, 0x000fffff00000000, 0x01ffffff00000000, 0xffffffffffffc000, - 0x000000000000ff80, 0xfffe000000000000, 0x001eefffffffffff, 0x0000000000001fff + 0x00001fffffff0000, 0x00000000001fffff, 0xffffffffffffffff, 0x00007fffffffffff, + 0x00000003fbff0000, 0x00000000007fffff, 0x000fffff00000000, 0x01ffffff00000000, + 0xffffffffffffc000, 0x000000000000ff80, 0xfffe000000000000, 0x001eefffffffffff, + 0x3fffbffffffffffe, 0x0000000000001fff ], }; @@ -139,8 +141,8 @@ pub mod general_category { } -pub mod derived_property { - pub const Alphabetic_table: &super::BoolTrie = &super::BoolTrie { +pub(crate) mod derived_property { + const Alphabetic_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, @@ -155,11 +157,11 @@ pub mod derived_property { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 37, 38, 39, 40, 41, 42, 43, 44, 36, 36, 36, 36, 36, 36, 36, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 55, 67, 68, 69, 36, 36, 36, 70, 36, 36, - 36, 36, 71, 72, 73, 74, 31, 75, 76, 31, 77, 78, 79, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 80, 81, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 82, 83, 36, 84, 85, 86, 87, 88, 89, 31, 31, 31, - 31, 31, 31, 31, 90, 44, 91, 92, 93, 36, 94, 95, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, + 56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 67, 68, 69, 70, 36, 36, 36, 71, 36, 36, + 36, 36, 72, 73, 74, 75, 31, 76, 77, 31, 78, 79, 80, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 81, 82, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 83, 84, 36, 85, 86, 87, 88, 89, 90, 31, 31, 31, + 31, 31, 31, 31, 91, 44, 92, 93, 94, 36, 95, 96, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, @@ -179,9 +181,9 @@ pub mod derived_property { 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 96, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 97, 98, 36, 36, 36, 36, 99, 100, 36, 96, 101, 36, 102, - 103, 104, 105, 36, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 36, 117, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 97, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 98, 99, 36, 36, 36, 36, 100, 101, 36, 97, 102, 36, 103, + 104, 105, 106, 36, 107, 108, 109, 110, 111, 67, 112, 113, 114, 115, 116, 36, 117, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, @@ -196,8 +198,8 @@ pub mod derived_property { 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 127, 128, - 129, 31, 130, 36, 131, 132, 133, 113, 134 + 36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 33, 127, 128, + 31, 129, 36, 130, 131, 132, 113, 133 ], r3: &[ 0x00001ffffcffffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0xffff03f8fff00000, @@ -206,34 +208,34 @@ pub mod derived_property { 0xe3edfdfffff99fee, 0x0002000fb0c0199f, 0xc3ffc718d63dc7ec, 0x0000000000811dc7, 0xe3fffdfffffddfef, 0x0000000f07601ddf, 0xe3effdfffffddfef, 0x0006000f40601ddf, 0xe7fffffffffddfef, 0xfc00000f80f05ddf, 0x2ffbfffffc7fffec, 0x000c0000ff5f807f, - 0x07fffffffffffffe, 0x000000000000207f, 0x3bffecaefef02596, 0x00000000f000205f, + 0x07fffffffffffffe, 0x000000000000207f, 0x3bffffaffffff7d6, 0x00000000f000205f, 0x0000000000000001, 0xfffe1ffffffffeff, 0x1ffffffffeffff03, 0x0000000000000000, - 0xf97fffffffffffff, 0xffffc1e7ffff0000, 0xffffffff3000407f, 0xf7ffffffffff20bf, + 0xf97fffffffffffff, 0xffffffffffff0000, 0xffffffff3c00ffff, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d, - 0xffffffffff3dffff, 0x0000000087ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff, + 0xffffffffff3dffff, 0x0000000007ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff, 0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x000fffff000fdfff, 0x000ddfff000fffff, 0xffcfffffffffffff, 0x00000000108001ff, 0xffffffff00000000, 0x01ffffffffffffff, 0xffff07ffffffffff, 0x003fffffffffffff, 0x01ff0fff7fffffff, 0x001f3fffffff0000, 0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff0fffffff, 0x001ffffe7fffffff, 0x0000008000000000, 0xffefffffffffffff, - 0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x3ffffffffc00e000, - 0xe7ffffffffff01ff, 0x006fde0000000000, 0x001fff8000000000, 0xffffffff3f3fffff, - 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000, - 0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, 0x00000000000001ff, - 0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, - 0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff, - 0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0, 0xfffffffee07fffff, - 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, - 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, - 0x8ff07fffffffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, 0xff80000000000000, - 0x000000fffffff7bb, 0x000fffffffffffff, 0x68fc00000000002f, 0xffff07fffffffc00, - 0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffdf00008000, 0x007fffffffffffff, - 0xc47fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e, - 0xffff003ff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, + 0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x007fffffffffffff, + 0x3ffffffffc00e000, 0xe7ffffffffff01ff, 0x046fde0000000000, 0x001fff8000000000, + 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, + 0x8002000000000000, 0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, + 0x00000000000001ff, 0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, + 0xffffffff7fffffff, 0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, + 0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0, + 0xfffffffee07fffff, 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, + 0xffff000000000000, 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, + 0x00000c00ffff1fff, 0x8ff07fffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, + 0xff8000000000007c, 0x000000ffffffffbf, 0x000fffffffffffff, 0xe8fc00000000002f, + 0xffff07fffffffc00, 0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffff00008000, + 0xfc7fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e, + 0xffff00fff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, 0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb, - 0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xffffffffffff0000, - 0xfffffffffffcffff, 0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff, - 0x07fffffe00000000, 0xffffffc007fffffe, 0x000000001cfcfcfc + 0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xfffffffffffcffff, + 0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff, 0x07fffffe00000000, + 0xffffffc007fffffe, 0x000000001cfcfcfc ], r4: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 13, 14, @@ -249,45 +251,45 @@ pub mod derived_property { r5: &[ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2, 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32, - 32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 4, 2, 35, 36, 37, 32, 38, 2, 39, 40, 4, 41, 42, - 43, 44, 4, 4, 2, 45, 2, 46, 4, 4, 47, 48, 49, 50, 28, 4, 51, 4, 4, 4, 52, 4, 53, 54, 4, - 4, 4, 4, 55, 56, 57, 52, 4, 4, 4, 4, 58, 59, 60, 4, 61, 62, 63, 4, 4, 4, 4, 64, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 4, 2, 66, 2, 2, 2, 67, 4, 4, 4, 4, 4, + 32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 36, 2, 35, 37, 38, 32, 39, 2, 40, 41, 4, 42, 43, + 44, 45, 4, 4, 2, 46, 2, 47, 4, 4, 48, 49, 50, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, + 4, 57, 58, 59, 60, 61, 54, 4, 4, 4, 4, 62, 63, 64, 4, 65, 66, 67, 4, 4, 4, 4, 36, 4, 4, + 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 66, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 2, 2, 2, 2, 2, 2, 2, 2, 52, 20, 4, 69, 16, 70, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, - 4, 2, 72, 73, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 76, 2, 2, 2, 2, 2, - 77, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 2, 78, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 80, 81, 82, 83, 84, 2, 2, 2, 2, 85, 86, 87, 88, 89, - 90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 92, 2, 93, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 94, 95, 96, 4, 4, 4, 4, 4, 4, 4, 4, 4, 76, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 2, 2, 2, 2, 2, 2, 2, 2, 54, 20, 4, 72, 73, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, + 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2, 2, 2, 2, + 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90, 91, 92, + 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 95, 4, 4, 4, 96, 97, 4, 4, 4, 4, 4, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 99, 2, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 101, 102, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, + 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 102, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 + 2, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, + 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ], r6: &[ 0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff, @@ -299,22 +301,24 @@ pub mod derived_property { 0x003ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff, 0x0007ffffffffffff, 0x000000ffffffffff, 0xffff00801fffffff, 0x000000000000003f, - 0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070, 0x000000001400001e, - 0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff, 0xe3edfdfffff99fef, - 0x0000000fe081199f, 0x00000000000007bb, 0x00000000000000b3, 0x7f3fffffffffffff, - 0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011, 0x000007ffe7ffffff, - 0x01ffffffffffffff, 0xffffffff00000000, 0x80000000ffffffff, 0x7fe7ffffffffffff, - 0xffffffffffff0000, 0x0000000020ffffcf, 0x7f7ffffffffffdff, 0xfffc000000000001, + 0x007fffff00000000, 0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070, + 0x000000001400001e, 0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff, + 0xe3edfdfffff99fef, 0x0000000fe081199f, 0x00000000800007bb, 0x00000000000000b3, + 0x7f3fffffffffffff, 0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011, + 0x013fffffffffffff, 0x000007ffe7ffffff, 0x01ffffffffffffff, 0xffffffff00000000, + 0x80000000ffffffff, 0xfffffcff00000000, 0x0000001afcffffff, 0x7fe7ffffffffffff, + 0xffffffffffff0000, 0x0000000020ffffff, 0x7f7ffffffffffdff, 0xfffc000000000001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf000000cb, 0x00000000017b7fff, - 0x007fffff00000000, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, - 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f, 0x000000000000ffff, - 0x7fffffffffff001f, 0x00000000fff80000, 0x0000000300000000, 0x0003ffffffffffff, - 0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff, + 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f, + 0x00003fffffff0000, 0x0000ffffffffffff, 0xe0fffff80000000f, 0x000000000000ffff, + 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000, 0x00ffffffffffffff, + 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff, 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x000007dbf9ffff7f, - 0x000000000000001f, 0x000000000000008f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, - 0x0ffffbee0ffffbff, 0xffff03ffffff03ff, 0x00000000000003ff, 0x00000000007fffff, + 0x3f801fffffffffff, 0x0000000000004000, 0x00000fffffffffff, 0x000000000000001f, + 0x000000000000088f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, + 0xffff000000000000, 0xffff03ffffff03ff, 0x00000000000003ff, 0x00000000007fffff, 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff ], }; @@ -323,7 +327,7 @@ pub mod derived_property { Alphabetic_table.lookup(c) } - pub const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie { + const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -378,7 +382,7 @@ pub mod derived_property { 0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002, 0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000011, 0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x0000000c0000201e, - 0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1bf2000000000000, + 0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1ff2000000000000, 0x0000000000003f40, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, 0x1000000000000000, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, @@ -393,7 +397,7 @@ pub mod derived_property { 0x000000007e000000, 0x7000000000000000, 0x0000000000200000, 0x0000000000001000, 0xbff7800000000000, 0x00000000f0000000, 0x0003000000000000, 0x00000003ffffffff, 0x0001000000000000, 0x0000000000000700, 0x0300000000000000, 0x0000006000000844, - 0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x13c8000000000007, + 0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x33c8000000000007, 0x0000006000008000, 0x00667e0000000000, 0x1001000000001008, 0xc19d000000000000, 0x0058300020000002, 0x00000000f8000000, 0x0000212000000000, 0x0000000040000000, 0xfffc000000000000, 0x0000000000000003, 0x0000ffff0008ffff, 0x0000000000240000, @@ -401,38 +405,40 @@ pub mod derived_property { 0x0e00000800000000 ], r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 1, 2, 3, 2, 2, 4, 2, 2, 2, 2, 5, 2, 6, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ], r5: &[ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 17, 18, 19, 0, 0, 20, 21, 22, - 23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 0, 0, - 0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, + 0, 0, 0, 0, 35, 0, 36, 0, 37, 38, 39, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, + 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 52, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 0, 56, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 56, 57, 0, 0, 57, 57, 57, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 62, 62, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], r6: &[ 0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000, @@ -442,14 +448,15 @@ pub mod derived_property { 0x40d3800000000000, 0x000007f880000000, 0x1800000000000003, 0x001f1fc000000001, 0xff00000000000000, 0x000000004000005c, 0x85f8000000000000, 0x000000000000000d, 0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, - 0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x79f80000000007fe, - 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, - 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, - 0x001f000000000000, 0x007f000000000000, 0x000000000000000f, 0x00000000ffff8000, - 0x0000000300000000, 0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7, - 0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, - 0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xf800000000000000, - 0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff + 0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, + 0x79f80000000007fe, 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, + 0x006dfcfffffc0000, 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, + 0x0018000000000000, 0x01ff000000000000, 0x001f000000000000, 0x007f000000000000, + 0x000000000000000f, 0x0000000000008000, 0x00000000ffff8000, 0x0000000b00000000, + 0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7, 0x000000000000001c, + 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, + 0x3fff000000000000, 0x0000f00000000000, 0x00000000007f0000, 0x0000000000000ff0, + 0xf800000000000000, 0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff ], }; @@ -457,7 +464,7 @@ pub mod derived_property { Case_Ignorable_table.lookup(c) } - pub const Cased_table: &super::BoolTrie = &super::BoolTrie { + const Cased_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0, @@ -512,7 +519,7 @@ pub mod derived_property { 0xf21fbd503e2ffc84, 0xffffffff000043e0, 0x0000000000000018, 0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff, 0x000020bfffffffff, 0x00003fffffffffff, 0x000000003fffffff, 0xfffffffc00000000, - 0x03ffffffffff78ff, 0x0700000000000000, 0xffff000000000000, 0xffff003ff7ffffff, + 0xffffffffffff78ff, 0x070000000000007c, 0xffff000000000000, 0xffff00fff7ffffff, 0x0000000000f8007f, 0x07fffffe00000000, 0x0000000007fffffe ], r4: [ @@ -558,7 +565,7 @@ pub mod derived_property { Cased_table.lookup(c) } - pub const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie { + const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -613,17 +620,17 @@ pub mod derived_property { 0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000011, 0x0000000c00603dc1, 0x9000000000000002, 0x0000000c00603044, 0x5800000000000003, 0x0000000c0080201e, 0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80, - 0x1bf2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000, + 0x1ff2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, 0x3fb0000000000000, 0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060, 0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000, - 0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000, + 0x17f000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000, 0x00cff00000000000, 0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000, 0x0001ffffffff0000, 0x0003800000000000, 0x8000000000000000, 0xffffffff00000000, 0x0000fc0000000000, 0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000, 0x0003000000000000, 0x0000006000000844, 0x8003ffff00000030, 0x00003fc000000000, - 0x000000000003ff80, 0x13c8000000000007, 0x0000002000000000, 0x00667e0000000000, + 0x000000000003ff80, 0x33c8000000000007, 0x0000002000000000, 0x00667e0000000000, 0x1000000000001008, 0xc19d000000000000, 0x0040300000000002, 0x0000212000000000, 0x0000000040000000, 0x0000ffff0000ffff ], @@ -642,22 +649,22 @@ pub mod derived_property { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 0, 0, 16, 17, 18, 0, 0, 19, 20, 21, - 22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, - 0, 0, 0, 33, 0, 34, 0, 35, 36, 37, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 30, 31, 32, 33, 0, + 0, 0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, - 53, 53, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 41, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 0, + 0, 56, 56, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 ], r6: &[ 0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000, @@ -667,13 +674,14 @@ pub mod derived_property { 0x000007f880000000, 0x5800000000000003, 0x001f1fc000800001, 0xff00000000000000, 0x000000004000005c, 0xa5f9000000000000, 0x000000000000000d, 0xb03c800000000000, 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, 0x00bf280000000000, - 0x00000fbce0000000, 0x06ff800000000000, 0x79f80000000007fe, 0x000000000e7e0080, - 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, 0xb47e000000000000, - 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, 0x001f000000000000, - 0x007f000000000000, 0x0000000000078000, 0x0000000060000000, 0xf807c3a000000000, - 0x00003c0000000fe7, 0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, - 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, - 0xffffffff00000000, 0xffffffffffffffff, 0x0000ffffffffffff + 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, 0x79f80000000007fe, + 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, + 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, + 0x001f000000000000, 0x007f000000000000, 0x0000000000008000, 0x0000000000078000, + 0x0000000060000000, 0xf807c3a000000000, 0x00003c0000000fe7, 0x000000000000001c, + 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, + 0x0000f00000000000, 0x00000000007f0000, 0x00000000000007f0, 0xffffffff00000000, + 0xffffffffffffffff, 0x0000ffffffffffff ], }; @@ -681,7 +689,7 @@ pub mod derived_property { Grapheme_Extend_table.lookup(c) } - pub const Lowercase_table: &super::BoolTrie = &super::BoolTrie { + const Lowercase_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000, 0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240, @@ -736,7 +744,7 @@ pub mod derived_property { 0x000000001fff0000, 0x321080000008c400, 0xffff0000000043c0, 0x0000000000000010, 0x000003ffffff0000, 0xffff000000000000, 0x3fda15627fffffff, 0x0008501aaaaaaaaa, 0x000020bfffffffff, 0x00002aaaaaaaaaaa, 0x000000003aaaaaaa, 0xaaabaaa800000000, - 0x95ffaaaaaaaaaaaa, 0x02a082aaaaba50aa, 0x0700000000000000, 0xffff003ff7ffffff, + 0x95ffaaaaaaaaaaaa, 0xaaa082aaaaba50aa, 0x0700000000000008, 0xffff00fff7ffffff, 0x0000000000f8007f, 0x0000000007fffffe ], r4: [ @@ -781,7 +789,7 @@ pub mod derived_property { Lowercase_table.lookup(c) } - pub const Uppercase_table: &super::BoolTrie = &super::BoolTrie { + const Uppercase_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff, 0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490, @@ -815,7 +823,7 @@ pub mod derived_property { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, - 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -827,7 +835,7 @@ pub mod derived_property { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 24, 0, 0, 0 + 0, 0, 0, 0, 0, 25, 0, 0, 0 ], r3: &[ 0x0000000000000000, 0xffffffff00000000, 0x00000000000020bf, 0x003fffffffffffff, @@ -835,8 +843,8 @@ pub mod derived_property { 0x0000ff00aa003f00, 0x0f00000000000000, 0x0f001f000f000f00, 0xc00f3d503e273884, 0x0000ffff00000020, 0x0000000000000008, 0xffc0000000000000, 0x000000000000ffff, 0x00007fffffffffff, 0xc025ea9d00000000, 0x0004280555555555, 0x0000155555555555, - 0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x015f7d5555452855, - 0x07fffffe00000000 + 0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x555f7d5555452855, + 0x0000000000000074, 0x07fffffe00000000 ], r4: [ 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -882,7 +890,7 @@ pub mod derived_property { Uppercase_table.lookup(c) } - pub const XID_Continue_table: &super::BoolTrie = &super::BoolTrie { + const XID_Continue_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, @@ -941,7 +949,7 @@ pub mod derived_property { 0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7, 0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf, 0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f, - 0x07fffffffffffffe, 0x0000000003ff7fff, 0x3bffecaefef02596, 0x00000000f3ff3f5f, + 0x07fffffffffffffe, 0x0000000003ff7fff, 0x3fffffaffffff7d6, 0x00000000f3ff3f5f, 0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040, 0xffffffffffff03ff, 0xffffffff3fffffff, 0xf7ffffffffff20bf, 0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff, @@ -951,7 +959,7 @@ pub mod derived_property { 0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff, 0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff, 0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff, - 0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x03fffffffff70000, 0xfbffffffffffffff, + 0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x07fffffffff70000, 0xfbffffffffffffff, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000, 0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, @@ -959,10 +967,10 @@ pub mod derived_property { 0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff, 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff, - 0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, - 0xff80000000000000, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff, + 0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, + 0xff8000000000007c, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff, 0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff, - 0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff003ff7ffffff, 0x03ff37ffffffffff, + 0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff00fff7ffffff, 0x03ff37ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff, 0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff, @@ -983,45 +991,45 @@ pub mod derived_property { r5: &[ 0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2, 2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33, - 33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 4, 2, 37, 3, 38, 39, 40, 2, 41, 42, 4, 43, 44, - 45, 46, 4, 4, 2, 47, 2, 48, 4, 4, 49, 50, 2, 51, 52, 53, 54, 4, 4, 4, 3, 4, 55, 56, 4, - 4, 4, 4, 57, 58, 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4, 4, + 33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 37, 2, 38, 3, 39, 40, 41, 2, 42, 43, 4, 44, 45, + 46, 47, 4, 4, 2, 48, 2, 49, 4, 4, 50, 51, 2, 52, 53, 54, 55, 4, 4, 4, 3, 4, 56, 57, 4, + 4, 58, 59, 60, 61, 62, 53, 4, 4, 4, 4, 63, 64, 65, 4, 66, 67, 68, 4, 4, 4, 4, 37, 4, 4, + 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 2, 70, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 2, 2, 2, 2, 2, 2, 2, 2, 60, 72, 4, 73, 17, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, - 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 2, 2, 2, 2, 2, 2, 2, 2, 53, 73, 4, 74, 17, 75, 76, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, + 4, 4, 2, 77, 78, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 80, 2, 2, 2, 2, 2, - 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 84, 85, 4, 4, 86, 4, 4, 4, 4, 4, 4, 2, 87, 88, 89, 90, 91, 2, 2, 2, 2, 92, 93, 94, 95, - 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 98, 99, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 102, 2, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 81, 2, 2, 2, 2, + 2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 83, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 85, 86, 4, 4, 87, 4, 4, 4, 4, 4, 4, 2, 88, 89, 90, 91, 92, 2, 2, 2, 2, 93, 94, 95, + 96, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 103, 104, 4, 4, 4, 4, 4, 105, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 106, 2, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 110, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 109, 4, 4, 4, 4, 4, + 2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 110, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 111, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 114, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 115, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ], r6: &[ 0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff, @@ -1033,23 +1041,24 @@ pub mod derived_property { 0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff, - 0x000000000001ffff, 0x8000ffc00000007f, 0x03ff01ffffff0000, 0xffdfffffffffffff, - 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff, 0xffff01ffbfffbd7f, - 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f, 0x0000000043ff07ff, - 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001, 0x0000000003ff0011, - 0x00ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff, 0xffffffff00000000, - 0x800003ffffffffff, 0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffcf, - 0x01ffffffffffffff, 0xff7ffffffffffdff, 0xfffc000003ff0001, 0x007ffefffffcffff, - 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff, 0x000003ff01fb7fff, 0x007fffff00000000, - 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f, - 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f, 0x000000000000ffff, - 0x7fffffffffff001f, 0x00000000ffff8000, 0x0000000300000000, 0x0003ffffffffffff, - 0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000063ff01ff, - 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c, 0xffffffffffdfffff, - 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, - 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, 0xffff7fffffff7fff, - 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff, 0x00201fffffffffff, - 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f001f, 0x0000000003ff07ff, + 0x000000000001ffff, 0x007fffff00000000, 0x8000ffc00000007f, 0x03ff01ffffff0000, + 0xffdfffffffffffff, 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff, + 0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f, + 0x00000000c3ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001, + 0x0000000003ff0011, 0x01ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff, + 0xffffffff00000000, 0x800003ffffffffff, 0xfffffcff00000000, 0x0000001bfcffffff, + 0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffff, 0xff7ffffffffffdff, + 0xfffc000003ff0001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff, + 0x000003ff01fb7fff, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, + 0x000000000000007f, 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f, + 0x000000000000ffff, 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000, + 0x00ffffffffffffff, 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, + 0x0000000063ff01ff, 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c, + 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, + 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, + 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff, + 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x3fff1fffffffffff, + 0x00000000000043ff, 0x03ffffffffffffff, 0x00000000007f001f, 0x0000000003ff0fff, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff ], @@ -1059,7 +1068,7 @@ pub mod derived_property { XID_Continue_table.lookup(c) } - pub const XID_Start_table: &super::BoolTrie = &super::BoolTrie { + const XID_Start_table: &super::BoolTrie = &super::BoolTrie { r1: [ 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, @@ -1123,7 +1132,7 @@ pub mod derived_property { 0x23edfdfffff99fe0, 0x00020003b0000000, 0x03ffc718d63dc7e8, 0x0000000000010000, 0x23fffdfffffddfe0, 0x0000000307000000, 0x23effdfffffddfe1, 0x0006000340000000, 0x27fffffffffddfe0, 0xfc00000380704000, 0x2ffbfffffc7fffe0, 0x000000000000007f, - 0x0005fffffffffffe, 0x2005ecaefef02596, 0x00000000f000005f, 0x0000000000000001, + 0x0005fffffffffffe, 0x2005ffaffffff7d6, 0x00000000f000005f, 0x0000000000000001, 0x00001ffffffffeff, 0x0000000000001f00, 0x800007ffffffffff, 0xffe1c0623c3f0000, 0xffffffff00004003, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff, @@ -1134,18 +1143,18 @@ pub mod derived_property { 0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff, 0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8, 0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff, - 0x0063de0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, + 0x046fde0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff, 0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff, - 0xffffffff3fffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, 0xff80000000000000, + 0xffffffff3fffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, 0xff8000000000007c, 0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00, 0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff, 0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e, - 0xffff003ff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, + 0xffff00fff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, 0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffa0f8007f, 0xffffffffffffffdb, 0x0003ffffffffffff, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff, 0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0xaa8a000000000000, @@ -1166,43 +1175,43 @@ pub mod derived_property { r5: &[ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2, 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32, - 32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 4, 35, 4, 36, 37, 38, 39, 40, 41, 42, 4, 43, 20, - 44, 45, 4, 4, 5, 46, 47, 48, 4, 4, 49, 50, 47, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, - 4, 4, 4, 57, 58, 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 49, 2, 2, 2, 69, 4, 4, 4, 4, 4, + 32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 35, 36, 4, 37, 38, 39, 40, 41, 42, 43, 4, 44, + 20, 45, 46, 4, 4, 5, 47, 48, 49, 4, 4, 50, 51, 48, 52, 53, 4, 54, 4, 4, 4, 55, 4, 56, + 57, 4, 4, 58, 59, 60, 61, 62, 63, 4, 4, 4, 4, 64, 65, 66, 4, 67, 68, 69, 4, 4, 4, 4, 70, + 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 2, 50, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 2, 2, 2, 2, 2, 2, 2, 2, 60, 20, 4, 71, 47, 72, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, - 4, 2, 73, 74, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 63, 20, 4, 74, 48, 75, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 2, 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 77, 2, 2, 2, 2, 2, - 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 2, 79, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 81, 82, 83, 84, 85, 2, 2, 2, 2, 86, 87, 88, 89, 90, - 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 92, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 93, 94, 95, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2, + 2, 2, 2, 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90, + 91, 92, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 95, 96, 4, 4, 4, 4, 4, 55, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ], r6: &[ 0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff, @@ -1213,23 +1222,25 @@ pub mod derived_property { 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff, 0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff, - 0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x00fffffffffffff8, - 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8, 0x0047ffffffff0010, - 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff, 0xffff01ffbfffbd7f, - 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000000000780, 0x0000ffffffffffff, - 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000, 0x0000000000000010, - 0x000007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff, 0xffffffff00000000, - 0x80000000ffffffff, 0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003cf, - 0x01ffffffffffffff, 0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, - 0x0001fffffffffb7f, 0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, - 0x0000000003ffffff, 0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, - 0xe0fffff80000000f, 0x000000000001001f, 0x00000000fff80000, 0x0000000300000000, - 0x0003ffffffffffff, 0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, - 0x0000000003ff01ff, 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, - 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, - 0xffdfffffffdfffff, 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, - 0x000000000000001f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, - 0x00000000007fffff, 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff + 0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x007fffff00000000, + 0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8, + 0x0047ffffffff0010, 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff, + 0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000080000780, + 0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000, + 0x0000000000000010, 0x010007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff, + 0xffffffff00000000, 0x80000000ffffffff, 0xfffffcff00000000, 0x0000000a0001ffff, + 0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003ff, 0x01ffffffffffffff, + 0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, 0x0001fffffffffb7f, + 0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, 0x0000000003ffffff, + 0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f, + 0x00000000000107ff, 0x00000000fff80000, 0x0000000b00000000, 0x00ffffffffffffff, + 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff, + 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, + 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, + 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x3f801fffffffffff, + 0x0000000000004000, 0x000000000000001f, 0x000000000000080f, 0x0af7fe96ffffffef, + 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff, + 0x00000001ffffffff, 0x000000003fffffff ], }; @@ -1239,8 +1250,8 @@ pub mod derived_property { } -pub mod property { - pub const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie { +pub(crate) mod property { + const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie { r1: &[ 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1257,7 +1268,7 @@ pub mod property { Pattern_White_Space_table.lookup(c) } - pub const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie { + const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie { r1: &[ 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1279,7 +1290,7 @@ pub mod property { } -pub mod conversions { +pub(crate) mod conversions { pub fn to_lower(c: char) -> [char; 3] { match bsearch_case_table(c, to_lowercase_table) { None => [c, '\0', '\0'], @@ -1792,131 +1803,134 @@ pub mod conversions { ['\u{26c}', '\0', '\0']), ('\u{a7ae}', ['\u{26a}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}', '\0', '\0']), ('\u{a7b1}', ['\u{287}', '\0', '\0']), ('\u{a7b2}', ['\u{29d}', '\0', '\0']), ('\u{a7b3}', ['\u{ab53}', '\0', '\0']), ('\u{a7b4}', ['\u{a7b5}', '\0', '\0']), ('\u{a7b6}', - ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{ff21}', ['\u{ff41}', - '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', '\0', - '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', '\0']), - ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), ('\u{ff28}', - ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', ['\u{ff4a}', - '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', '\0', - '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', '\0']), - ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), ('\u{ff31}', - ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', ['\u{ff53}', - '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', '\0', - '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', '\0']), - ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), ('\u{ff3a}', - ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']), ('\u{10401}', - ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']), ('\u{10403}', - ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']), ('\u{10405}', - ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']), ('\u{10407}', - ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']), ('\u{10409}', - ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']), ('\u{1040b}', - ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']), ('\u{1040d}', - ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']), ('\u{1040f}', - ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']), ('\u{10411}', - ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']), ('\u{10413}', - ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']), ('\u{10415}', - ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']), ('\u{10417}', - ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']), ('\u{10419}', - ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']), ('\u{1041b}', - ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']), ('\u{1041d}', - ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']), ('\u{1041f}', - ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']), ('\u{10421}', - ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']), ('\u{10423}', - ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']), ('\u{10425}', - ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']), ('\u{10427}', - ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']), ('\u{104b1}', - ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']), ('\u{104b3}', - ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']), ('\u{104b5}', - ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']), ('\u{104b7}', - ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']), ('\u{104b9}', - ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']), ('\u{104bb}', - ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']), ('\u{104bd}', - ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']), ('\u{104bf}', - ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']), ('\u{104c1}', - ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']), ('\u{104c3}', - ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']), ('\u{104c5}', - ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']), ('\u{104c7}', - ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']), ('\u{104c9}', - ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']), ('\u{104cb}', - ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']), ('\u{104cd}', - ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']), ('\u{104cf}', - ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']), ('\u{104d1}', - ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']), ('\u{104d3}', - ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']), ('\u{10c81}', - ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']), ('\u{10c83}', - ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']), ('\u{10c85}', - ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']), ('\u{10c87}', - ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']), ('\u{10c89}', - ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']), ('\u{10c8b}', - ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']), ('\u{10c8d}', - ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']), ('\u{10c8f}', - ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']), ('\u{10c91}', - ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']), ('\u{10c93}', - ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']), ('\u{10c95}', - ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']), ('\u{10c97}', - ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']), ('\u{10c99}', - ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']), ('\u{10c9b}', - ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']), ('\u{10c9d}', - ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']), ('\u{10c9f}', - ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']), ('\u{10ca1}', - ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']), ('\u{10ca3}', - ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']), ('\u{10ca5}', - ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']), ('\u{10ca7}', - ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']), ('\u{10ca9}', - ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']), ('\u{10cab}', - ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']), ('\u{10cad}', - ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']), ('\u{10caf}', - ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']), ('\u{10cb1}', - ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']), ('\u{118a0}', - ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']), ('\u{118a2}', - ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']), ('\u{118a4}', - ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']), ('\u{118a6}', - ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']), ('\u{118a8}', - ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']), ('\u{118aa}', - ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']), ('\u{118ac}', - ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']), ('\u{118ae}', - ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']), ('\u{118b0}', - ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']), ('\u{118b2}', - ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']), ('\u{118b4}', - ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']), ('\u{118b6}', - ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']), ('\u{118b8}', - ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']), ('\u{118ba}', - ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']), ('\u{118bc}', - ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']), ('\u{118be}', - ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']), ('\u{16e40}', - ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']), ('\u{16e42}', - ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']), ('\u{16e44}', - ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']), ('\u{16e46}', - ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']), ('\u{16e48}', - ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']), ('\u{16e4a}', - ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']), ('\u{16e4c}', - ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']), ('\u{16e4e}', - ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']), ('\u{16e50}', - ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']), ('\u{16e52}', - ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']), ('\u{16e54}', - ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']), ('\u{16e56}', - ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']), ('\u{16e58}', - ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']), ('\u{16e5a}', - ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']), ('\u{16e5c}', - ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']), ('\u{16e5e}', - ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']), ('\u{1e900}', - ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']), ('\u{1e902}', - ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']), ('\u{1e904}', - ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']), ('\u{1e906}', - ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']), ('\u{1e908}', - ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']), ('\u{1e90a}', - ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']), ('\u{1e90c}', - ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']), ('\u{1e90e}', - ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']), ('\u{1e910}', - ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']), ('\u{1e912}', - ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']), ('\u{1e914}', - ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']), ('\u{1e916}', - ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']), ('\u{1e918}', - ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']), ('\u{1e91a}', - ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']), ('\u{1e91c}', - ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']), ('\u{1e91e}', - ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']), ('\u{1e920}', - ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0']) + ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{a7ba}', ['\u{a7bb}', + '\0', '\0']), ('\u{a7bc}', ['\u{a7bd}', '\0', '\0']), ('\u{a7be}', ['\u{a7bf}', '\0', + '\0']), ('\u{a7c2}', ['\u{a7c3}', '\0', '\0']), ('\u{a7c4}', ['\u{a794}', '\0', '\0']), + ('\u{a7c5}', ['\u{282}', '\0', '\0']), ('\u{a7c6}', ['\u{1d8e}', '\0', '\0']), ('\u{ff21}', + ['\u{ff41}', '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', + '\0', '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', + '\0']), ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), + ('\u{ff28}', ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', + ['\u{ff4a}', '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', + '\0', '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', + '\0']), ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), + ('\u{ff31}', ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', + ['\u{ff53}', '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', + '\0', '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', + '\0']), ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), + ('\u{ff3a}', ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']), + ('\u{10401}', ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']), + ('\u{10403}', ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']), + ('\u{10405}', ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']), + ('\u{10407}', ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']), + ('\u{10409}', ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']), + ('\u{1040b}', ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']), + ('\u{1040d}', ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']), + ('\u{1040f}', ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']), + ('\u{10411}', ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']), + ('\u{10413}', ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']), + ('\u{10415}', ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']), + ('\u{10417}', ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']), + ('\u{10419}', ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']), + ('\u{1041b}', ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']), + ('\u{1041d}', ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']), + ('\u{1041f}', ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']), + ('\u{10421}', ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']), + ('\u{10423}', ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']), + ('\u{10425}', ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']), + ('\u{10427}', ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']), + ('\u{104b1}', ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']), + ('\u{104b3}', ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']), + ('\u{104b5}', ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']), + ('\u{104b7}', ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']), + ('\u{104b9}', ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']), + ('\u{104bb}', ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']), + ('\u{104bd}', ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']), + ('\u{104bf}', ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']), + ('\u{104c1}', ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']), + ('\u{104c3}', ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']), + ('\u{104c5}', ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']), + ('\u{104c7}', ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']), + ('\u{104c9}', ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']), + ('\u{104cb}', ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']), + ('\u{104cd}', ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']), + ('\u{104cf}', ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']), + ('\u{104d1}', ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']), + ('\u{104d3}', ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']), + ('\u{10c81}', ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']), + ('\u{10c83}', ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']), + ('\u{10c85}', ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']), + ('\u{10c87}', ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']), + ('\u{10c89}', ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']), + ('\u{10c8b}', ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']), + ('\u{10c8d}', ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']), + ('\u{10c8f}', ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']), + ('\u{10c91}', ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']), + ('\u{10c93}', ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']), + ('\u{10c95}', ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']), + ('\u{10c97}', ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']), + ('\u{10c99}', ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']), + ('\u{10c9b}', ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']), + ('\u{10c9d}', ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']), + ('\u{10c9f}', ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']), + ('\u{10ca1}', ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']), + ('\u{10ca3}', ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']), + ('\u{10ca5}', ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']), + ('\u{10ca7}', ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']), + ('\u{10ca9}', ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']), + ('\u{10cab}', ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']), + ('\u{10cad}', ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']), + ('\u{10caf}', ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']), + ('\u{10cb1}', ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']), + ('\u{118a0}', ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']), + ('\u{118a2}', ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']), + ('\u{118a4}', ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']), + ('\u{118a6}', ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']), + ('\u{118a8}', ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']), + ('\u{118aa}', ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']), + ('\u{118ac}', ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']), + ('\u{118ae}', ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']), + ('\u{118b0}', ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']), + ('\u{118b2}', ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']), + ('\u{118b4}', ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']), + ('\u{118b6}', ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']), + ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']), + ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']), + ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']), + ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']), + ('\u{16e40}', ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']), + ('\u{16e42}', ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']), + ('\u{16e44}', ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']), + ('\u{16e46}', ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']), + ('\u{16e48}', ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']), + ('\u{16e4a}', ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']), + ('\u{16e4c}', ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']), + ('\u{16e4e}', ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']), + ('\u{16e50}', ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']), + ('\u{16e52}', ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']), + ('\u{16e54}', ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']), + ('\u{16e56}', ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']), + ('\u{16e58}', ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']), + ('\u{16e5a}', ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']), + ('\u{16e5c}', ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']), + ('\u{16e5e}', ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']), + ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']), + ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']), + ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']), + ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']), + ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']), + ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']), + ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']), + ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']), + ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']), + ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']), + ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']), + ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']), + ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']), + ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']), + ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']), + ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']), + ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0']) ]; const to_uppercase_table: &[(char, [char; 3])] = &[ @@ -2019,260 +2033,261 @@ pub mod conversions { ('\u{26a}', ['\u{a7ae}', '\0', '\0']), ('\u{26b}', ['\u{2c62}', '\0', '\0']), ('\u{26c}', ['\u{a7ad}', '\0', '\0']), ('\u{26f}', ['\u{19c}', '\0', '\0']), ('\u{271}', ['\u{2c6e}', '\0', '\0']), ('\u{272}', ['\u{19d}', '\0', '\0']), ('\u{275}', ['\u{19f}', '\0', '\0']), - ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{283}', - ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}', '\0', '\0']), ('\u{288}', ['\u{1ae}', - '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']), ('\u{28a}', ['\u{1b1}', '\0', '\0']), - ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}', ['\u{245}', '\0', '\0']), ('\u{292}', - ['\u{1b7}', '\0', '\0']), ('\u{29d}', ['\u{a7b2}', '\0', '\0']), ('\u{29e}', ['\u{a7b0}', - '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']), ('\u{371}', ['\u{370}', '\0', '\0']), - ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}', ['\u{376}', '\0', '\0']), ('\u{37b}', - ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}', '\0', '\0']), ('\u{37d}', ['\u{3ff}', - '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\0', - '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']), ('\u{3ae}', ['\u{389}', '\0', '\0']), - ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}', ['\u{392}', '\0', '\0']), ('\u{3b3}', - ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}', '\0', '\0']), ('\u{3b5}', ['\u{395}', - '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']), ('\u{3b7}', ['\u{397}', '\0', '\0']), - ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}', ['\u{399}', '\0', '\0']), ('\u{3ba}', - ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}', '\0', '\0']), ('\u{3bc}', ['\u{39c}', - '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']), ('\u{3be}', ['\u{39e}', '\0', '\0']), - ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}', ['\u{3a0}', '\0', '\0']), ('\u{3c1}', - ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}', '\0', '\0']), ('\u{3c3}', ['\u{3a3}', - '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']), ('\u{3c5}', ['\u{3a5}', '\0', '\0']), - ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}', ['\u{3a7}', '\0', '\0']), ('\u{3c8}', - ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}', '\0', '\0']), ('\u{3ca}', ['\u{3aa}', - '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']), ('\u{3cc}', ['\u{38c}', '\0', '\0']), - ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}', ['\u{38f}', '\0', '\0']), ('\u{3d0}', - ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}', '\0', '\0']), ('\u{3d5}', ['\u{3a6}', - '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']), ('\u{3d7}', ['\u{3cf}', '\0', '\0']), - ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}', ['\u{3da}', '\0', '\0']), ('\u{3dd}', - ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}', '\0', '\0']), ('\u{3e1}', ['\u{3e0}', - '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']), ('\u{3e5}', ['\u{3e4}', '\0', '\0']), - ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}', ['\u{3e8}', '\0', '\0']), ('\u{3eb}', - ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}', '\0', '\0']), ('\u{3ef}', ['\u{3ee}', - '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']), ('\u{3f1}', ['\u{3a1}', '\0', '\0']), - ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}', ['\u{37f}', '\0', '\0']), ('\u{3f5}', - ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}', '\0', '\0']), ('\u{3fb}', ['\u{3fa}', - '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']), ('\u{431}', ['\u{411}', '\0', '\0']), - ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}', ['\u{413}', '\0', '\0']), ('\u{434}', - ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}', '\0', '\0']), ('\u{436}', ['\u{416}', - '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']), ('\u{438}', ['\u{418}', '\0', '\0']), - ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}', ['\u{41a}', '\0', '\0']), ('\u{43b}', - ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}', '\0', '\0']), ('\u{43d}', ['\u{41d}', - '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']), ('\u{43f}', ['\u{41f}', '\0', '\0']), - ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}', ['\u{421}', '\0', '\0']), ('\u{442}', - ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}', '\0', '\0']), ('\u{444}', ['\u{424}', - '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']), ('\u{446}', ['\u{426}', '\0', '\0']), - ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}', ['\u{428}', '\0', '\0']), ('\u{449}', - ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}', '\0', '\0']), ('\u{44b}', ['\u{42b}', - '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']), ('\u{44d}', ['\u{42d}', '\0', '\0']), - ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}', ['\u{42f}', '\0', '\0']), ('\u{450}', - ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}', '\0', '\0']), ('\u{452}', ['\u{402}', - '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']), ('\u{454}', ['\u{404}', '\0', '\0']), - ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}', ['\u{406}', '\0', '\0']), ('\u{457}', - ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}', '\0', '\0']), ('\u{459}', ['\u{409}', - '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']), ('\u{45b}', ['\u{40b}', '\0', '\0']), - ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}', ['\u{40d}', '\0', '\0']), ('\u{45e}', - ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}', '\0', '\0']), ('\u{461}', ['\u{460}', - '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']), ('\u{465}', ['\u{464}', '\0', '\0']), - ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}', ['\u{468}', '\0', '\0']), ('\u{46b}', - ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}', '\0', '\0']), ('\u{46f}', ['\u{46e}', - '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']), ('\u{473}', ['\u{472}', '\0', '\0']), - ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}', ['\u{476}', '\0', '\0']), ('\u{479}', - ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}', '\0', '\0']), ('\u{47d}', ['\u{47c}', - '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']), ('\u{481}', ['\u{480}', '\0', '\0']), - ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}', ['\u{48c}', '\0', '\0']), ('\u{48f}', - ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}', '\0', '\0']), ('\u{493}', ['\u{492}', - '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']), ('\u{497}', ['\u{496}', '\0', '\0']), - ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}', ['\u{49a}', '\0', '\0']), ('\u{49d}', - ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}', '\0', '\0']), ('\u{4a1}', ['\u{4a0}', - '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']), ('\u{4a5}', ['\u{4a4}', '\0', '\0']), - ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}', ['\u{4a8}', '\0', '\0']), ('\u{4ab}', - ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}', '\0', '\0']), ('\u{4af}', ['\u{4ae}', - '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']), ('\u{4b3}', ['\u{4b2}', '\0', '\0']), - ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}', ['\u{4b6}', '\0', '\0']), ('\u{4b9}', - ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}', '\0', '\0']), ('\u{4bd}', ['\u{4bc}', - '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']), ('\u{4c2}', ['\u{4c1}', '\0', '\0']), - ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}', ['\u{4c5}', '\0', '\0']), ('\u{4c8}', - ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}', '\0', '\0']), ('\u{4cc}', ['\u{4cb}', - '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']), ('\u{4cf}', ['\u{4c0}', '\0', '\0']), - ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}', ['\u{4d2}', '\0', '\0']), ('\u{4d5}', - ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}', '\0', '\0']), ('\u{4d9}', ['\u{4d8}', - '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']), ('\u{4dd}', ['\u{4dc}', '\0', '\0']), - ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}', ['\u{4e0}', '\0', '\0']), ('\u{4e3}', - ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}', '\0', '\0']), ('\u{4e7}', ['\u{4e6}', - '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']), ('\u{4eb}', ['\u{4ea}', '\0', '\0']), - ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}', ['\u{4ee}', '\0', '\0']), ('\u{4f1}', - ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}', '\0', '\0']), ('\u{4f5}', ['\u{4f4}', - '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']), ('\u{4f9}', ['\u{4f8}', '\0', '\0']), - ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}', ['\u{4fc}', '\0', '\0']), ('\u{4ff}', - ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}', '\0', '\0']), ('\u{503}', ['\u{502}', - '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']), ('\u{507}', ['\u{506}', '\0', '\0']), - ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}', ['\u{50a}', '\0', '\0']), ('\u{50d}', - ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}', '\0', '\0']), ('\u{511}', ['\u{510}', - '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']), ('\u{515}', ['\u{514}', '\0', '\0']), - ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}', ['\u{518}', '\0', '\0']), ('\u{51b}', - ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}', '\0', '\0']), ('\u{51f}', ['\u{51e}', - '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']), ('\u{523}', ['\u{522}', '\0', '\0']), - ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}', ['\u{526}', '\0', '\0']), ('\u{529}', - ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}', '\0', '\0']), ('\u{52d}', ['\u{52c}', - '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']), ('\u{561}', ['\u{531}', '\0', '\0']), - ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}', ['\u{533}', '\0', '\0']), ('\u{564}', - ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}', '\0', '\0']), ('\u{566}', ['\u{536}', - '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']), ('\u{568}', ['\u{538}', '\0', '\0']), - ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}', ['\u{53a}', '\0', '\0']), ('\u{56b}', - ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}', '\0', '\0']), ('\u{56d}', ['\u{53d}', - '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']), ('\u{56f}', ['\u{53f}', '\0', '\0']), - ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}', ['\u{541}', '\0', '\0']), ('\u{572}', - ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}', '\0', '\0']), ('\u{574}', ['\u{544}', - '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']), ('\u{576}', ['\u{546}', '\0', '\0']), - ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}', ['\u{548}', '\0', '\0']), ('\u{579}', - ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}', '\0', '\0']), ('\u{57b}', ['\u{54b}', - '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']), ('\u{57d}', ['\u{54d}', '\0', '\0']), - ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}', ['\u{54f}', '\0', '\0']), ('\u{580}', - ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', '\0', '\0']), ('\u{582}', ['\u{552}', - '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), ('\u{584}', ['\u{554}', '\0', '\0']), - ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', ['\u{556}', '\0', '\0']), ('\u{587}', - ['\u{535}', '\u{552}', '\0']), ('\u{10d0}', ['\u{1c90}', '\0', '\0']), ('\u{10d1}', - ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}', '\0', '\0']), ('\u{10d3}', ['\u{1c93}', - '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0', '\0']), ('\u{10d5}', ['\u{1c95}', '\0', - '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']), ('\u{10d7}', ['\u{1c97}', '\0', '\0']), - ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}', ['\u{1c99}', '\0', '\0']), ('\u{10da}', - ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}', '\0', '\0']), ('\u{10dc}', ['\u{1c9c}', - '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0', '\0']), ('\u{10de}', ['\u{1c9e}', '\0', - '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']), ('\u{10e0}', ['\u{1ca0}', '\0', '\0']), - ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}', ['\u{1ca2}', '\0', '\0']), ('\u{10e3}', - ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}', '\0', '\0']), ('\u{10e5}', ['\u{1ca5}', - '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0', '\0']), ('\u{10e7}', ['\u{1ca7}', '\0', - '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']), ('\u{10e9}', ['\u{1ca9}', '\0', '\0']), - ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}', ['\u{1cab}', '\0', '\0']), ('\u{10ec}', - ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}', '\0', '\0']), ('\u{10ee}', ['\u{1cae}', - '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0', '\0']), ('\u{10f0}', ['\u{1cb0}', '\0', - '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']), ('\u{10f2}', ['\u{1cb2}', '\0', '\0']), - ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}', ['\u{1cb4}', '\0', '\0']), ('\u{10f5}', - ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}', '\0', '\0']), ('\u{10f7}', ['\u{1cb7}', - '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0', '\0']), ('\u{10f9}', ['\u{1cb9}', '\0', - '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']), ('\u{10fd}', ['\u{1cbd}', '\0', '\0']), - ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}', ['\u{1cbf}', '\0', '\0']), ('\u{13f8}', - ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}', '\0', '\0']), ('\u{13fa}', ['\u{13f2}', - '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0', '\0']), ('\u{13fc}', ['\u{13f4}', '\0', - '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']), ('\u{1c80}', ['\u{412}', '\0', '\0']), - ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}', ['\u{41e}', '\0', '\0']), ('\u{1c83}', - ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}', '\0', '\0']), ('\u{1c85}', ['\u{422}', - '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']), ('\u{1c87}', ['\u{462}', '\0', '\0']), - ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}', ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', - ['\u{2c63}', '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', - '\0', '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', - '\0']), ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), - ('\u{1e0d}', ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', - ['\u{1e10}', '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', - '\0', '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', - '\0']), ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), - ('\u{1e1f}', ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', - ['\u{1e22}', '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', - '\0', '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', - '\0']), ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), - ('\u{1e31}', ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', - ['\u{1e34}', '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', - '\0', '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', - '\0']), ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), - ('\u{1e43}', ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', - ['\u{1e46}', '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', - '\0', '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', - '\0']), ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), - ('\u{1e55}', ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', - ['\u{1e58}', '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', - '\0', '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', - '\0']), ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), - ('\u{1e67}', ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', - ['\u{1e6a}', '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', - '\0', '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', - '\0']), ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), - ('\u{1e79}', ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', - ['\u{1e7c}', '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', - '\0', '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', - '\0']), ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), - ('\u{1e8b}', ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', - ['\u{1e8e}', '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', - '\0', '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', - '\0']), ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', - '\0']), ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', - '\0']), ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), - ('\u{1ea3}', ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', - ['\u{1ea6}', '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', - '\0', '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', - '\0']), ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), - ('\u{1eb5}', ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', - ['\u{1eb8}', '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', - '\0', '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', - '\0']), ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), - ('\u{1ec7}', ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', - ['\u{1eca}', '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', - '\0', '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', - '\0']), ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), - ('\u{1ed9}', ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}', - ['\u{1edc}', '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', - '\0', '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', - '\0']), ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), - ('\u{1eeb}', ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}', - ['\u{1eee}', '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', - '\0', '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', - '\0']), ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']), - ('\u{1efd}', ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}', - ['\u{1f08}', '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', - '\0', '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', - '\0']), ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), - ('\u{1f07}', ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}', - ['\u{1f19}', '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', - '\0', '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', - '\0']), ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']), - ('\u{1f22}', ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', - ['\u{1f2c}', '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', - '\0', '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0', - '\0']), ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), - ('\u{1f33}', ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', - ['\u{1f3d}', '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', - '\0', '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0', - '\0']), ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), - ('\u{1f44}', ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', - ['\u{3a5}', '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}', - ['\u{3a5}', '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', - ['\u{3a5}', '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', - ['\u{3a5}', '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', - ['\u{1f68}', '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', - '\0', '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', - '\0']), ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), - ('\u{1f67}', ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}', - ['\u{1fbb}', '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', - '\0', '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', - '\0']), ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), - ('\u{1f78}', ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', - ['\u{1fea}', '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', - '\0', '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}', - '\0']), ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}', - '\0']), ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}', - '\0']), ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}', - '\0']), ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}', - '\0']), ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}', - '\0']), ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}', - '\0']), ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}', - '\0']), ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}', - '\0']), ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}', - '\0']), ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}', - '\0']), ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}', - '\0']), ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}', - '\0']), ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}', - '\0']), ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}', - '\0']), ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}', - '\0']), ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}', - '\0']), ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}', - '\0']), ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}', - '\0']), ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}', - '\0']), ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}', - '\0']), ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}', - '\0']), ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}', - '\0']), ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}', - '\0']), ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']), + ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{282}', + ['\u{a7c5}', '\0', '\0']), ('\u{283}', ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}', + '\0', '\0']), ('\u{288}', ['\u{1ae}', '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']), + ('\u{28a}', ['\u{1b1}', '\0', '\0']), ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}', + ['\u{245}', '\0', '\0']), ('\u{292}', ['\u{1b7}', '\0', '\0']), ('\u{29d}', ['\u{a7b2}', + '\0', '\0']), ('\u{29e}', ['\u{a7b0}', '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']), + ('\u{371}', ['\u{370}', '\0', '\0']), ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}', + ['\u{376}', '\0', '\0']), ('\u{37b}', ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}', + '\0', '\0']), ('\u{37d}', ['\u{3ff}', '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}', + '\u{301}']), ('\u{3ac}', ['\u{386}', '\0', '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']), + ('\u{3ae}', ['\u{389}', '\0', '\0']), ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}', + ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}', + ['\u{392}', '\0', '\0']), ('\u{3b3}', ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}', + '\0', '\0']), ('\u{3b5}', ['\u{395}', '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']), + ('\u{3b7}', ['\u{397}', '\0', '\0']), ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}', + ['\u{399}', '\0', '\0']), ('\u{3ba}', ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}', + '\0', '\0']), ('\u{3bc}', ['\u{39c}', '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']), + ('\u{3be}', ['\u{39e}', '\0', '\0']), ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}', + ['\u{3a0}', '\0', '\0']), ('\u{3c1}', ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}', + '\0', '\0']), ('\u{3c3}', ['\u{3a3}', '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']), + ('\u{3c5}', ['\u{3a5}', '\0', '\0']), ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}', + ['\u{3a7}', '\0', '\0']), ('\u{3c8}', ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}', + '\0', '\0']), ('\u{3ca}', ['\u{3aa}', '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']), + ('\u{3cc}', ['\u{38c}', '\0', '\0']), ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}', + ['\u{38f}', '\0', '\0']), ('\u{3d0}', ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}', + '\0', '\0']), ('\u{3d5}', ['\u{3a6}', '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']), + ('\u{3d7}', ['\u{3cf}', '\0', '\0']), ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}', + ['\u{3da}', '\0', '\0']), ('\u{3dd}', ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}', + '\0', '\0']), ('\u{3e1}', ['\u{3e0}', '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']), + ('\u{3e5}', ['\u{3e4}', '\0', '\0']), ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}', + ['\u{3e8}', '\0', '\0']), ('\u{3eb}', ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}', + '\0', '\0']), ('\u{3ef}', ['\u{3ee}', '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']), + ('\u{3f1}', ['\u{3a1}', '\0', '\0']), ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}', + ['\u{37f}', '\0', '\0']), ('\u{3f5}', ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}', + '\0', '\0']), ('\u{3fb}', ['\u{3fa}', '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']), + ('\u{431}', ['\u{411}', '\0', '\0']), ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}', + ['\u{413}', '\0', '\0']), ('\u{434}', ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}', + '\0', '\0']), ('\u{436}', ['\u{416}', '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']), + ('\u{438}', ['\u{418}', '\0', '\0']), ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}', + ['\u{41a}', '\0', '\0']), ('\u{43b}', ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}', + '\0', '\0']), ('\u{43d}', ['\u{41d}', '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']), + ('\u{43f}', ['\u{41f}', '\0', '\0']), ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}', + ['\u{421}', '\0', '\0']), ('\u{442}', ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}', + '\0', '\0']), ('\u{444}', ['\u{424}', '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']), + ('\u{446}', ['\u{426}', '\0', '\0']), ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}', + ['\u{428}', '\0', '\0']), ('\u{449}', ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}', + '\0', '\0']), ('\u{44b}', ['\u{42b}', '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']), + ('\u{44d}', ['\u{42d}', '\0', '\0']), ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}', + ['\u{42f}', '\0', '\0']), ('\u{450}', ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}', + '\0', '\0']), ('\u{452}', ['\u{402}', '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']), + ('\u{454}', ['\u{404}', '\0', '\0']), ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}', + ['\u{406}', '\0', '\0']), ('\u{457}', ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}', + '\0', '\0']), ('\u{459}', ['\u{409}', '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']), + ('\u{45b}', ['\u{40b}', '\0', '\0']), ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}', + ['\u{40d}', '\0', '\0']), ('\u{45e}', ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}', + '\0', '\0']), ('\u{461}', ['\u{460}', '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']), + ('\u{465}', ['\u{464}', '\0', '\0']), ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}', + ['\u{468}', '\0', '\0']), ('\u{46b}', ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}', + '\0', '\0']), ('\u{46f}', ['\u{46e}', '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']), + ('\u{473}', ['\u{472}', '\0', '\0']), ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}', + ['\u{476}', '\0', '\0']), ('\u{479}', ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}', + '\0', '\0']), ('\u{47d}', ['\u{47c}', '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']), + ('\u{481}', ['\u{480}', '\0', '\0']), ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}', + ['\u{48c}', '\0', '\0']), ('\u{48f}', ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}', + '\0', '\0']), ('\u{493}', ['\u{492}', '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']), + ('\u{497}', ['\u{496}', '\0', '\0']), ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}', + ['\u{49a}', '\0', '\0']), ('\u{49d}', ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}', + '\0', '\0']), ('\u{4a1}', ['\u{4a0}', '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']), + ('\u{4a5}', ['\u{4a4}', '\0', '\0']), ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}', + ['\u{4a8}', '\0', '\0']), ('\u{4ab}', ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}', + '\0', '\0']), ('\u{4af}', ['\u{4ae}', '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']), + ('\u{4b3}', ['\u{4b2}', '\0', '\0']), ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}', + ['\u{4b6}', '\0', '\0']), ('\u{4b9}', ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}', + '\0', '\0']), ('\u{4bd}', ['\u{4bc}', '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']), + ('\u{4c2}', ['\u{4c1}', '\0', '\0']), ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}', + ['\u{4c5}', '\0', '\0']), ('\u{4c8}', ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}', + '\0', '\0']), ('\u{4cc}', ['\u{4cb}', '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']), + ('\u{4cf}', ['\u{4c0}', '\0', '\0']), ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}', + ['\u{4d2}', '\0', '\0']), ('\u{4d5}', ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}', + '\0', '\0']), ('\u{4d9}', ['\u{4d8}', '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']), + ('\u{4dd}', ['\u{4dc}', '\0', '\0']), ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}', + ['\u{4e0}', '\0', '\0']), ('\u{4e3}', ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}', + '\0', '\0']), ('\u{4e7}', ['\u{4e6}', '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']), + ('\u{4eb}', ['\u{4ea}', '\0', '\0']), ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}', + ['\u{4ee}', '\0', '\0']), ('\u{4f1}', ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}', + '\0', '\0']), ('\u{4f5}', ['\u{4f4}', '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']), + ('\u{4f9}', ['\u{4f8}', '\0', '\0']), ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}', + ['\u{4fc}', '\0', '\0']), ('\u{4ff}', ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}', + '\0', '\0']), ('\u{503}', ['\u{502}', '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']), + ('\u{507}', ['\u{506}', '\0', '\0']), ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}', + ['\u{50a}', '\0', '\0']), ('\u{50d}', ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}', + '\0', '\0']), ('\u{511}', ['\u{510}', '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']), + ('\u{515}', ['\u{514}', '\0', '\0']), ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}', + ['\u{518}', '\0', '\0']), ('\u{51b}', ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}', + '\0', '\0']), ('\u{51f}', ['\u{51e}', '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']), + ('\u{523}', ['\u{522}', '\0', '\0']), ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}', + ['\u{526}', '\0', '\0']), ('\u{529}', ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}', + '\0', '\0']), ('\u{52d}', ['\u{52c}', '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']), + ('\u{561}', ['\u{531}', '\0', '\0']), ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}', + ['\u{533}', '\0', '\0']), ('\u{564}', ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}', + '\0', '\0']), ('\u{566}', ['\u{536}', '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']), + ('\u{568}', ['\u{538}', '\0', '\0']), ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}', + ['\u{53a}', '\0', '\0']), ('\u{56b}', ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}', + '\0', '\0']), ('\u{56d}', ['\u{53d}', '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']), + ('\u{56f}', ['\u{53f}', '\0', '\0']), ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}', + ['\u{541}', '\0', '\0']), ('\u{572}', ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}', + '\0', '\0']), ('\u{574}', ['\u{544}', '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']), + ('\u{576}', ['\u{546}', '\0', '\0']), ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}', + ['\u{548}', '\0', '\0']), ('\u{579}', ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}', + '\0', '\0']), ('\u{57b}', ['\u{54b}', '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']), + ('\u{57d}', ['\u{54d}', '\0', '\0']), ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}', + ['\u{54f}', '\0', '\0']), ('\u{580}', ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', + '\0', '\0']), ('\u{582}', ['\u{552}', '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), + ('\u{584}', ['\u{554}', '\0', '\0']), ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', + ['\u{556}', '\0', '\0']), ('\u{587}', ['\u{535}', '\u{552}', '\0']), ('\u{10d0}', + ['\u{1c90}', '\0', '\0']), ('\u{10d1}', ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}', + '\0', '\0']), ('\u{10d3}', ['\u{1c93}', '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0', + '\0']), ('\u{10d5}', ['\u{1c95}', '\0', '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']), + ('\u{10d7}', ['\u{1c97}', '\0', '\0']), ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}', + ['\u{1c99}', '\0', '\0']), ('\u{10da}', ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}', + '\0', '\0']), ('\u{10dc}', ['\u{1c9c}', '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0', + '\0']), ('\u{10de}', ['\u{1c9e}', '\0', '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']), + ('\u{10e0}', ['\u{1ca0}', '\0', '\0']), ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}', + ['\u{1ca2}', '\0', '\0']), ('\u{10e3}', ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}', + '\0', '\0']), ('\u{10e5}', ['\u{1ca5}', '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0', + '\0']), ('\u{10e7}', ['\u{1ca7}', '\0', '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']), + ('\u{10e9}', ['\u{1ca9}', '\0', '\0']), ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}', + ['\u{1cab}', '\0', '\0']), ('\u{10ec}', ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}', + '\0', '\0']), ('\u{10ee}', ['\u{1cae}', '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0', + '\0']), ('\u{10f0}', ['\u{1cb0}', '\0', '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']), + ('\u{10f2}', ['\u{1cb2}', '\0', '\0']), ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}', + ['\u{1cb4}', '\0', '\0']), ('\u{10f5}', ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}', + '\0', '\0']), ('\u{10f7}', ['\u{1cb7}', '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0', + '\0']), ('\u{10f9}', ['\u{1cb9}', '\0', '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']), + ('\u{10fd}', ['\u{1cbd}', '\0', '\0']), ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}', + ['\u{1cbf}', '\0', '\0']), ('\u{13f8}', ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}', + '\0', '\0']), ('\u{13fa}', ['\u{13f2}', '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0', + '\0']), ('\u{13fc}', ['\u{13f4}', '\0', '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']), + ('\u{1c80}', ['\u{412}', '\0', '\0']), ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}', + ['\u{41e}', '\0', '\0']), ('\u{1c83}', ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}', + '\0', '\0']), ('\u{1c85}', ['\u{422}', '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']), + ('\u{1c87}', ['\u{462}', '\0', '\0']), ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}', + ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', ['\u{2c63}', '\0', '\0']), ('\u{1d8e}', ['\u{a7c6}', + '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', '\0', + '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', '\0']), + ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), ('\u{1e0d}', + ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', ['\u{1e10}', + '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', '\0', + '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', '\0']), + ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), ('\u{1e1f}', + ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', ['\u{1e22}', + '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', '\0', + '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', '\0']), + ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), ('\u{1e31}', + ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', ['\u{1e34}', + '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', '\0', + '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', '\0']), + ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), ('\u{1e43}', + ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', ['\u{1e46}', + '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', '\0', + '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', '\0']), + ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), ('\u{1e55}', + ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', ['\u{1e58}', + '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', '\0', + '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', '\0']), + ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), ('\u{1e67}', + ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', ['\u{1e6a}', + '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', '\0', + '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', '\0']), + ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), ('\u{1e79}', + ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', ['\u{1e7c}', + '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', '\0', + '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', '\0']), + ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), ('\u{1e8b}', + ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', ['\u{1e8e}', + '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', '\0', + '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', '\0']), + ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\0']), + ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\0']), + ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), ('\u{1ea3}', + ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', ['\u{1ea6}', + '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', '\0', + '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', '\0']), + ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), ('\u{1eb5}', + ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', ['\u{1eb8}', + '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', '\0', + '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', '\0']), + ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), ('\u{1ec7}', + ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', ['\u{1eca}', + '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', '\0', + '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', '\0']), + ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), ('\u{1ed9}', + ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}', ['\u{1edc}', + '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', '\0', + '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', '\0']), + ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), ('\u{1eeb}', + ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}', ['\u{1eee}', + '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', '\0', + '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', '\0']), + ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']), ('\u{1efd}', + ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}', ['\u{1f08}', + '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', '\0', + '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', '\0']), + ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), ('\u{1f07}', + ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}', ['\u{1f19}', + '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', '\0', + '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', '\0']), + ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']), ('\u{1f22}', + ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', ['\u{1f2c}', + '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', '\0', + '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0', '\0']), + ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), ('\u{1f33}', + ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', ['\u{1f3d}', + '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', '\0', + '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0', '\0']), + ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), ('\u{1f44}', + ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', ['\u{3a5}', + '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}', ['\u{3a5}', + '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', ['\u{3a5}', + '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', ['\u{3a5}', + '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', ['\u{1f68}', + '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', '\0', + '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', '\0']), + ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), ('\u{1f67}', + ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}', ['\u{1fbb}', + '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', '\0', + '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', '\0']), + ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), ('\u{1f78}', + ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', ['\u{1fea}', + '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', '\0', + '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}', '\0']), + ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\0']), + ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\0']), + ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\0']), + ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}', '\0']), + ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\0']), + ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\0']), + ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\0']), + ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}', '\0']), + ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\0']), + ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\0']), + ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\0']), + ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}', '\0']), + ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\0']), + ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\0']), + ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\0']), + ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\0']), + ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\0']), + ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\0']), + ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\0']), + ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\0']), + ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\0']), + ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\0']), + ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\0']), + ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']), ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\0']), ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']), ('\u{1fb4}', ['\u{386}', '\u{399}', '\0']), ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), @@ -2413,66 +2428,68 @@ pub mod conversions { ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}', ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}', '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0', - '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), ('\u{a799}', ['\u{a798}', '\0', '\0']), - ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', ['\u{a79c}', '\0', '\0']), ('\u{a79f}', - ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}', - '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0', - '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']), - ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}', ['\u{a7b8}', '\0', '\0']), ('\u{ab53}', - ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']), ('\u{ab71}', ['\u{13a1}', - '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}', ['\u{13a3}', '\0', - '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}', '\0', '\0']), - ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0', '\0']), ('\u{ab78}', - ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']), ('\u{ab7a}', ['\u{13aa}', - '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}', ['\u{13ac}', '\0', - '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}', '\0', '\0']), - ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0', '\0']), ('\u{ab81}', - ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']), ('\u{ab83}', ['\u{13b3}', - '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}', ['\u{13b5}', '\0', - '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}', '\0', '\0']), - ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0', '\0']), ('\u{ab8a}', - ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']), ('\u{ab8c}', ['\u{13bc}', - '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}', ['\u{13be}', '\0', - '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}', '\0', '\0']), - ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0', '\0']), ('\u{ab93}', - ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']), ('\u{ab95}', ['\u{13c5}', - '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}', ['\u{13c7}', '\0', - '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}', '\0', '\0']), - ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0', '\0']), ('\u{ab9c}', - ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']), ('\u{ab9e}', ['\u{13ce}', - '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}', ['\u{13d0}', '\0', - '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}', '\0', '\0']), - ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0', '\0']), ('\u{aba5}', - ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']), ('\u{aba7}', ['\u{13d7}', - '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}', ['\u{13d9}', '\0', - '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}', '\0', '\0']), - ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0', '\0']), ('\u{abae}', - ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']), ('\u{abb0}', ['\u{13e0}', - '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}', ['\u{13e2}', '\0', - '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}', '\0', '\0']), - ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0', '\0']), ('\u{abb7}', - ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']), ('\u{abb9}', ['\u{13e9}', - '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}', ['\u{13eb}', '\0', - '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}', '\0', '\0']), - ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0', '\0']), ('\u{fb00}', - ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), ('\u{fb02}', - ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), ('\u{fb04}', - ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), ('\u{fb06}', - ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), ('\u{fb14}', - ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), ('\u{fb16}', - ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), ('\u{ff41}', - ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', ['\u{ff23}', - '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', '\0', - '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', '\0']), - ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), ('\u{ff4a}', - ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', ['\u{ff2c}', - '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', '\0', - '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', '\0']), - ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), ('\u{ff53}', - ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', ['\u{ff35}', - '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', '\0', - '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', '\0']), - ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']), + '\0']), ('\u{a794}', ['\u{a7c4}', '\0', '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), + ('\u{a799}', ['\u{a798}', '\0', '\0']), ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', + ['\u{a79c}', '\0', '\0']), ('\u{a79f}', ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', + '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}', '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', + '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0', '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), + ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']), ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}', + ['\u{a7b8}', '\0', '\0']), ('\u{a7bb}', ['\u{a7ba}', '\0', '\0']), ('\u{a7bd}', ['\u{a7bc}', + '\0', '\0']), ('\u{a7bf}', ['\u{a7be}', '\0', '\0']), ('\u{a7c3}', ['\u{a7c2}', '\0', + '\0']), ('\u{ab53}', ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']), + ('\u{ab71}', ['\u{13a1}', '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}', + ['\u{13a3}', '\0', '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}', + '\0', '\0']), ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0', + '\0']), ('\u{ab78}', ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']), + ('\u{ab7a}', ['\u{13aa}', '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}', + ['\u{13ac}', '\0', '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}', + '\0', '\0']), ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0', + '\0']), ('\u{ab81}', ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']), + ('\u{ab83}', ['\u{13b3}', '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}', + ['\u{13b5}', '\0', '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}', + '\0', '\0']), ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0', + '\0']), ('\u{ab8a}', ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']), + ('\u{ab8c}', ['\u{13bc}', '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}', + ['\u{13be}', '\0', '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}', + '\0', '\0']), ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0', + '\0']), ('\u{ab93}', ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']), + ('\u{ab95}', ['\u{13c5}', '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}', + ['\u{13c7}', '\0', '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}', + '\0', '\0']), ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0', + '\0']), ('\u{ab9c}', ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']), + ('\u{ab9e}', ['\u{13ce}', '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}', + ['\u{13d0}', '\0', '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}', + '\0', '\0']), ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0', + '\0']), ('\u{aba5}', ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']), + ('\u{aba7}', ['\u{13d7}', '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}', + ['\u{13d9}', '\0', '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}', + '\0', '\0']), ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0', + '\0']), ('\u{abae}', ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']), + ('\u{abb0}', ['\u{13e0}', '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}', + ['\u{13e2}', '\0', '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}', + '\0', '\0']), ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0', + '\0']), ('\u{abb7}', ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']), + ('\u{abb9}', ['\u{13e9}', '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}', + ['\u{13eb}', '\0', '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}', + '\0', '\0']), ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0', + '\0']), ('\u{fb00}', ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), + ('\u{fb02}', ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), + ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), + ('\u{fb06}', ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), + ('\u{fb14}', ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), + ('\u{fb16}', ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), + ('\u{ff41}', ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', + ['\u{ff23}', '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', + '\0', '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', + '\0']), ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), + ('\u{ff4a}', ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', + ['\u{ff2c}', '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', + '\0', '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', + '\0']), ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), + ('\u{ff53}', ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', + ['\u{ff35}', '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', + '\0', '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', + '\0']), ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']), ('\u{10429}', ['\u{10401}', '\0', '\0']), ('\u{1042a}', ['\u{10402}', '\0', '\0']), ('\u{1042b}', ['\u{10403}', '\0', '\0']), ('\u{1042c}', ['\u{10404}', '\0', '\0']), ('\u{1042d}', ['\u{10405}', '\0', '\0']), ('\u{1042e}', ['\u{10406}', '\0', '\0']), diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py index ae356c3ff4..6de5d9e033 100755 --- a/src/libcore/unicode/unicode.py +++ b/src/libcore/unicode/unicode.py @@ -1,147 +1,350 @@ #!/usr/bin/env python -# This script uses the following Unicode tables: -# - DerivedCoreProperties.txt -# - DerivedNormalizationProps.txt -# - EastAsianWidth.txt -# - auxiliary/GraphemeBreakProperty.txt -# - PropList.txt -# - ReadMe.txt -# - Scripts.txt -# - UnicodeData.txt -# -# Since this should not require frequent updates, we just store this -# out-of-line and check the tables.rs file into git. +""" +Regenerate Unicode tables (tables.rs). +""" -import fileinput, re, os, sys, operator, math, datetime +# This script uses the Unicode tables as defined +# in the UnicodeFiles class. -# The directory in which this file resides. -fdir = os.path.dirname(os.path.realpath(__file__)) + "/" +# Since this should not require frequent updates, we just store this +# out-of-line and check the tables.rs file into git. -preamble = ''' +# Note that the "curl" program is required for operation. +# This script is compatible with Python 2.7 and 3.x. + +import argparse +import datetime +import fileinput +import itertools +import os +import re +import textwrap +import subprocess + +from collections import defaultdict, namedtuple + +try: + # Python 3 + from itertools import zip_longest + from io import StringIO +except ImportError: + # Python 2 compatibility + zip_longest = itertools.izip_longest + from StringIO import StringIO + +try: + # Completely optional type hinting + # (Python 2 compatible using comments, + # see: https://mypy.readthedocs.io/en/latest/python2.html) + # This is very helpful in typing-aware IDE like PyCharm. + from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Tuple +except ImportError: + pass + + +# We don't use enum.Enum because of Python 2.7 compatibility. +class UnicodeFiles(object): + # ReadMe does not contain any Unicode data, we + # only use it to extract versions. + README = "ReadMe.txt" + + DERIVED_CORE_PROPERTIES = "DerivedCoreProperties.txt" + DERIVED_NORMALIZATION_PROPS = "DerivedNormalizationProps.txt" + PROPS = "PropList.txt" + SCRIPTS = "Scripts.txt" + SPECIAL_CASING = "SpecialCasing.txt" + UNICODE_DATA = "UnicodeData.txt" + + +# The order doesn't really matter (Python < 3.6 won't preserve it), +# we only want to aggregate all the file names. +ALL_UNICODE_FILES = tuple( + value for name, value in UnicodeFiles.__dict__.items() + if not name.startswith("_") +) + +assert len(ALL_UNICODE_FILES) == 7, "Unexpected number of unicode files" + +# The directory this file is located in. +THIS_DIR = os.path.dirname(os.path.realpath(__file__)) + +# Where to download the Unicode data. The downloaded files +# will be placed in sub-directories named after Unicode version. +FETCH_DIR = os.path.join(THIS_DIR, "downloaded") + +FETCH_URL_LATEST = "ftp://ftp.unicode.org/Public/UNIDATA/{filename}" +FETCH_URL_VERSION = "ftp://ftp.unicode.org/Public/{version}/ucd/{filename}" + +PREAMBLE = """\ // NOTE: The following code was generated by "./unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] -use unicode::version::UnicodeVersion; -use unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; -'''.format(year = datetime.datetime.now().year) +use crate::unicode::version::UnicodeVersion; +use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; +""".format(year=datetime.datetime.now().year) # Mapping taken from Table 12 from: # http://www.unicode.org/reports/tr44/#General_Category_Values -expanded_categories = { - 'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'], - 'Lm': ['L'], 'Lo': ['L'], - 'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'], - 'Nd': ['N'], 'Nl': ['N'], 'No': ['N'], - 'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'], - 'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'], - 'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'], - 'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'], - 'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'], +EXPANDED_CATEGORIES = { + "Lu": ["LC", "L"], "Ll": ["LC", "L"], "Lt": ["LC", "L"], + "Lm": ["L"], "Lo": ["L"], + "Mn": ["M"], "Mc": ["M"], "Me": ["M"], + "Nd": ["N"], "Nl": ["N"], "No": ["N"], + "Pc": ["P"], "Pd": ["P"], "Ps": ["P"], "Pe": ["P"], + "Pi": ["P"], "Pf": ["P"], "Po": ["P"], + "Sm": ["S"], "Sc": ["S"], "Sk": ["S"], "So": ["S"], + "Zs": ["Z"], "Zl": ["Z"], "Zp": ["Z"], + "Cc": ["C"], "Cf": ["C"], "Cs": ["C"], "Co": ["C"], "Cn": ["C"], } -# these are the surrogate codepoints, which are not valid rust characters -surrogate_codepoints = (0xd800, 0xdfff) +# This is the (inclusive) range of surrogate codepoints. +# These are not valid Rust characters. +SURROGATE_CODEPOINTS_RANGE = (0xd800, 0xdfff) + +UnicodeData = namedtuple( + "UnicodeData", ( + # Conversions: + "to_upper", "to_lower", "to_title", + + # Decompositions: canonical decompositions, compatibility decomp + "canon_decomp", "compat_decomp", + + # Grouped: general categories and combining characters + "general_categories", "combines", + ) +) + +UnicodeVersion = namedtuple( + "UnicodeVersion", ("major", "minor", "micro", "as_str") +) + + +def fetch_files(version=None): + # type: (str) -> UnicodeVersion + """ + Fetch all the Unicode files from unicode.org. + + This will use cached files (stored in `FETCH_DIR`) if they exist, + creating them if they don't. In any case, the Unicode version + is always returned. + + :param version: The desired Unicode version, as string. + (If None, defaults to latest final release available, + querying the unicode.org service). + """ + have_version = check_stored_version(version) + if have_version: + return have_version + + if version: + # Check if the desired version exists on the server. + get_fetch_url = lambda name: FETCH_URL_VERSION.format(version=version, filename=name) + else: + # Extract the latest version. + get_fetch_url = lambda name: FETCH_URL_LATEST.format(filename=name) + + readme_url = get_fetch_url(UnicodeFiles.README) + + print("Fetching: {}".format(readme_url)) + readme_content = subprocess.check_output(("curl", readme_url)) + + unicode_version = parse_readme_unicode_version( + readme_content.decode("utf8") + ) + + download_dir = get_unicode_dir(unicode_version) + if not os.path.exists(download_dir): + # For 2.7 compat, we don't use `exist_ok=True`. + os.makedirs(download_dir) + + for filename in ALL_UNICODE_FILES: + file_path = get_unicode_file_path(unicode_version, filename) + + if os.path.exists(file_path): + # Assume file on the server didn't change if it's been saved before. + continue + + if filename == UnicodeFiles.README: + with open(file_path, "wb") as fd: + fd.write(readme_content) + else: + url = get_fetch_url(filename) + print("Fetching: {}".format(url)) + subprocess.check_call(("curl", "-o", file_path, url)) + + return unicode_version + + +def check_stored_version(version): + # type: (Optional[str]) -> Optional[UnicodeVersion] + """ + Given desired Unicode version, return the version + if stored files are all present, and `None` otherwise. + """ + if not version: + # If no desired version specified, we should check what's the latest + # version, skipping stored version checks. + return None + + fetch_dir = os.path.join(FETCH_DIR, version) -def fetch(f): - path = fdir + os.path.basename(f) - if not os.path.exists(path): - os.system("curl -o {0}{1} ftp://ftp.unicode.org/Public/UNIDATA/{1}".format(fdir, f)) + for filename in ALL_UNICODE_FILES: + file_path = os.path.join(fetch_dir, filename) + + if not os.path.exists(file_path): + return None + + with open(os.path.join(fetch_dir, UnicodeFiles.README)) as fd: + return parse_readme_unicode_version(fd.read()) + + +def parse_readme_unicode_version(readme_content): + # type: (str) -> UnicodeVersion + """ + Parse the Unicode version contained in their `ReadMe.txt` file. + """ + # "Raw string" is necessary for \d not being treated as escape char + # (for the sake of compat with future Python versions). + # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior + pattern = r"for Version (\d+)\.(\d+)\.(\d+) of the Unicode" + groups = re.search(pattern, readme_content).groups() + + return UnicodeVersion(*map(int, groups), as_str=".".join(groups)) + + +def get_unicode_dir(unicode_version): + # type: (UnicodeVersion) -> str + """ + Indicate in which parent dir the Unicode data files should be stored. + + This returns a full, absolute path. + """ + return os.path.join(FETCH_DIR, unicode_version.as_str) + + +def get_unicode_file_path(unicode_version, filename): + # type: (UnicodeVersion, str) -> str + """ + Indicate where the Unicode data file should be stored. + """ + return os.path.join(get_unicode_dir(unicode_version), filename) - if not os.path.exists(path): - sys.stderr.write("cannot load %s" % f) - exit(1) def is_surrogate(n): - return surrogate_codepoints[0] <= n <= surrogate_codepoints[1] - -def load_unicode_data(f): - fetch(f) - gencats = {} - to_lower = {} - to_upper = {} - to_title = {} - combines = {} - canon_decomp = {} - compat_decomp = {} - - udict = {} + # type: (int) -> bool + """ + Tell if given codepoint is a surrogate (not a valid Rust character). + """ + return SURROGATE_CODEPOINTS_RANGE[0] <= n <= SURROGATE_CODEPOINTS_RANGE[1] + + +def load_unicode_data(file_path): + # type: (str) -> UnicodeData + """ + Load main Unicode data. + """ + # Conversions + to_lower = {} # type: Dict[int, Tuple[int, int, int]] + to_upper = {} # type: Dict[int, Tuple[int, int, int]] + to_title = {} # type: Dict[int, Tuple[int, int, int]] + + # Decompositions + compat_decomp = {} # type: Dict[int, List[int]] + canon_decomp = {} # type: Dict[int, List[int]] + + # Combining characters + # FIXME: combines are not used + combines = defaultdict(set) # type: Dict[str, Set[int]] + + # Categories + general_categories = defaultdict(set) # type: Dict[str, Set[int]] + category_assigned_codepoints = set() # type: Set[int] + + all_codepoints = {} + range_start = -1 - for line in fileinput.input(fdir + f): - data = line.split(';') + + for line in fileinput.input(file_path): + data = line.split(";") if len(data) != 15: continue - cp = int(data[0], 16) - if is_surrogate(cp): + codepoint = int(data[0], 16) + if is_surrogate(codepoint): continue if range_start >= 0: - for i in range(range_start, cp): - udict[i] = data + for i in range(range_start, codepoint): + all_codepoints[i] = data range_start = -1 if data[1].endswith(", First>"): - range_start = cp + range_start = codepoint continue - udict[cp] = data + all_codepoints[codepoint] = data - for code in udict: + for code, data in all_codepoints.items(): (code_org, name, gencat, combine, bidi, decomp, deci, digit, num, mirror, - old, iso, upcase, lowcase, titlecase) = udict[code] + old, iso, upcase, lowcase, titlecase) = data + + # Generate char to char direct common and simple conversions: - # generate char to char direct common and simple conversions - # uppercase to lowercase + # Uppercase to lowercase if lowcase != "" and code_org != lowcase: to_lower[code] = (int(lowcase, 16), 0, 0) - # lowercase to uppercase + # Lowercase to uppercase if upcase != "" and code_org != upcase: to_upper[code] = (int(upcase, 16), 0, 0) - # title case + # Title case if titlecase.strip() != "" and code_org != titlecase: to_title[code] = (int(titlecase, 16), 0, 0) - # store decomposition, if given - if decomp != "": - if decomp.startswith('<'): - seq = [] - for i in decomp.split()[1:]: - seq.append(int(i, 16)) - compat_decomp[code] = seq + # Store decomposition, if given + if decomp: + decompositions = decomp.split()[1:] + decomp_code_points = [int(i, 16) for i in decompositions] + + if decomp.startswith("<"): + # Compatibility decomposition + compat_decomp[code] = decomp_code_points else: - seq = [] - for i in decomp.split(): - seq.append(int(i, 16)) - canon_decomp[code] = seq - - # place letter in categories as appropriate - for cat in [gencat, "Assigned"] + expanded_categories.get(gencat, []): - if cat not in gencats: - gencats[cat] = [] - gencats[cat].append(code) - - # record combining class, if any + # Canonical decomposition + canon_decomp[code] = decomp_code_points + + # Place letter in categories as appropriate. + for cat in itertools.chain((gencat, ), EXPANDED_CATEGORIES.get(gencat, [])): + general_categories[cat].add(code) + category_assigned_codepoints.add(code) + + # Record combining class, if any. if combine != "0": - if combine not in combines: - combines[combine] = [] - combines[combine].append(code) - - # generate Not_Assigned from Assigned - gencats["Cn"] = gen_unassigned(gencats["Assigned"]) - # Assigned is not a real category - del(gencats["Assigned"]) + combines[combine].add(code) + + # Generate Not_Assigned from Assigned. + general_categories["Cn"] = get_unassigned_codepoints(category_assigned_codepoints) + # Other contains Not_Assigned - gencats["C"].extend(gencats["Cn"]) - gencats = group_cats(gencats) - combines = to_combines(group_cats(combines)) + general_categories["C"].update(general_categories["Cn"]) + + grouped_categories = group_categories(general_categories) - return (canon_decomp, compat_decomp, gencats, combines, to_upper, to_lower, to_title) + # FIXME: combines are not used + return UnicodeData( + to_lower=to_lower, to_upper=to_upper, to_title=to_title, + compat_decomp=compat_decomp, canon_decomp=canon_decomp, + general_categories=grouped_categories, combines=combines, + ) -def load_special_casing(f, to_upper, to_lower, to_title): - fetch(f) - for line in fileinput.input(fdir + f): - data = line.split('#')[0].split(';') + +def load_special_casing(file_path, unicode_data): + # type: (str, UnicodeData) -> None + """ + Load special casing data and enrich given Unicode data. + """ + for line in fileinput.input(file_path): + data = line.split("#")[0].split(";") if len(data) == 5: code, lower, title, upper, _comment = data elif len(data) == 6: @@ -155,243 +358,399 @@ def load_special_casing(f, to_upper, to_lower, to_title): title = title.strip() upper = upper.strip() key = int(code, 16) - for (map_, values) in [(to_lower, lower), (to_upper, upper), (to_title, title)]: + for (map_, values) in ((unicode_data.to_lower, lower), + (unicode_data.to_upper, upper), + (unicode_data.to_title, title)): if values != code: - values = [int(i, 16) for i in values.split()] - for _ in range(len(values), 3): - values.append(0) - assert len(values) == 3 - map_[key] = values - -def group_cats(cats): - cats_out = {} - for cat in cats: - cats_out[cat] = group_cat(cats[cat]) - return cats_out - -def group_cat(cat): - cat_out = [] - letters = sorted(set(cat)) - cur_start = letters.pop(0) - cur_end = cur_start - for letter in letters: - assert letter > cur_end, \ - "cur_end: %s, letter: %s" % (hex(cur_end), hex(letter)) - if letter == cur_end + 1: - cur_end = letter - else: - cat_out.append((cur_start, cur_end)) - cur_start = cur_end = letter - cat_out.append((cur_start, cur_end)) - return cat_out - -def ungroup_cat(cat): - cat_out = [] - for (lo, hi) in cat: - while lo <= hi: - cat_out.append(lo) - lo += 1 - return cat_out - -def gen_unassigned(assigned): - assigned = set(assigned) - return ([i for i in range(0, 0xd800) if i not in assigned] + - [i for i in range(0xe000, 0x110000) if i not in assigned]) - -def to_combines(combs): - combs_out = [] - for comb in combs: - for (lo, hi) in combs[comb]: - combs_out.append((lo, hi, comb)) - combs_out.sort(key=lambda comb: comb[0]) - return combs_out - -def format_table_content(f, content, indent): - line = " "*indent + split = values.split() + + codepoints = list(itertools.chain( + (int(i, 16) for i in split), + (0 for _ in range(len(split), 3)) + )) + + assert len(codepoints) == 3 + map_[key] = codepoints + + +def group_categories(mapping): + # type: (Dict[Any, Iterable[int]]) -> Dict[str, List[Tuple[int, int]]] + """ + Group codepoints mapped in "categories". + """ + return {category: group_codepoints(codepoints) + for category, codepoints in mapping.items()} + + +def group_codepoints(codepoints): + # type: (Iterable[int]) -> List[Tuple[int, int]] + """ + Group integral values into continuous, disjoint value ranges. + + Performs value deduplication. + + :return: sorted list of pairs denoting start and end of codepoint + group values, both ends inclusive. + + >>> group_codepoints([1, 2, 10, 11, 12, 3, 4]) + [(1, 4), (10, 12)] + >>> group_codepoints([1]) + [(1, 1)] + >>> group_codepoints([1, 5, 6]) + [(1, 1), (5, 6)] + >>> group_codepoints([]) + [] + """ + sorted_codes = sorted(set(codepoints)) + result = [] # type: List[Tuple[int, int]] + + if not sorted_codes: + return result + + next_codes = sorted_codes[1:] + start_code = sorted_codes[0] + + for code, next_code in zip_longest(sorted_codes, next_codes, fillvalue=None): + if next_code is None or next_code - code != 1: + result.append((start_code, code)) + start_code = next_code + + return result + + +def ungroup_codepoints(codepoint_pairs): + # type: (Iterable[Tuple[int, int]]) -> List[int] + """ + The inverse of group_codepoints -- produce a flat list of values + from value range pairs. + + >>> ungroup_codepoints([(1, 4), (10, 12)]) + [1, 2, 3, 4, 10, 11, 12] + >>> ungroup_codepoints([(1, 1), (5, 6)]) + [1, 5, 6] + >>> ungroup_codepoints(group_codepoints([1, 2, 7, 8])) + [1, 2, 7, 8] + >>> ungroup_codepoints([]) + [] + """ + return list(itertools.chain.from_iterable( + range(lo, hi + 1) for lo, hi in codepoint_pairs + )) + + +def get_unassigned_codepoints(assigned_codepoints): + # type: (Set[int]) -> Set[int] + """ + Given a set of "assigned" codepoints, return a set + of these that are not in assigned and not surrogate. + """ + return {i for i in range(0, 0x110000) + if i not in assigned_codepoints and not is_surrogate(i)} + + +def generate_table_lines(items, indent, wrap=98): + # type: (Iterable[str], int, int) -> Iterator[str] + """ + Given table items, generate wrapped lines of text with comma-separated items. + + This is a generator function. + + :param wrap: soft wrap limit (characters per line), integer. + """ + line = " " * indent first = True - for chunk in content.split(","): - if len(line) + len(chunk) < 98: + for item in items: + if len(line) + len(item) < wrap: if first: - line += chunk + line += item else: - line += ", " + chunk + line += ", " + item first = False else: - f.write(line + ",\n") - line = " "*indent + chunk - f.write(line) - -def load_properties(f, interestingprops): - fetch(f) - props = {} - re1 = re.compile("^ *([0-9A-F]+) *; *(\w+)") - re2 = re.compile("^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)") - - for line in fileinput.input(fdir + os.path.basename(f)): - prop = None - d_lo = 0 - d_hi = 0 - m = re1.match(line) - if m: - d_lo = m.group(1) - d_hi = m.group(1) - prop = m.group(2) - else: - m = re2.match(line) - if m: - d_lo = m.group(1) - d_hi = m.group(2) - prop = m.group(3) + yield line + ",\n" + line = " " * indent + item + + yield line + + +def load_properties(file_path, interesting_props): + # type: (str, Iterable[str]) -> Dict[str, List[Tuple[int, int]]] + """ + Load properties data and return in grouped form. + """ + props = defaultdict(list) # type: Dict[str, List[Tuple[int, int]]] + # "Raw string" is necessary for `\.` and `\w` not to be treated as escape chars + # (for the sake of compat with future Python versions). + # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior + re1 = re.compile(r"^ *([0-9A-F]+) *; *(\w+)") + re2 = re.compile(r"^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)") + + for line in fileinput.input(file_path): + match = re1.match(line) or re2.match(line) + if match: + groups = match.groups() + + if len(groups) == 2: + # `re1` matched (2 groups). + d_lo, prop = groups + d_hi = d_lo else: - continue - if interestingprops and prop not in interestingprops: + d_lo, d_hi, prop = groups + else: + continue + + if interesting_props and prop not in interesting_props: continue - d_lo = int(d_lo, 16) - d_hi = int(d_hi, 16) - if prop not in props: - props[prop] = [] - props[prop].append((d_lo, d_hi)) - # optimize if possible + lo_value = int(d_lo, 16) + hi_value = int(d_hi, 16) + + props[prop].append((lo_value, hi_value)) + + # Optimize if possible. for prop in props: - props[prop] = group_cat(ungroup_cat(props[prop])) + props[prop] = group_codepoints(ungroup_codepoints(props[prop])) return props -def escape_char(c): - return "'\\u{%x}'" % c if c != 0 else "'\\0'" -def emit_table(f, name, t_data, t_type = "&[(char, char)]", is_pub=True, - pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))): +def escape_char(c): + # type: (int) -> str + r""" + Escape a codepoint for use as Rust char literal. + + Outputs are OK to use as Rust source code as char literals + and they also include necessary quotes. + + >>> escape_char(97) + "'\\u{61}'" + >>> escape_char(0) + "'\\0'" + """ + return r"'\u{%x}'" % c if c != 0 else r"'\0'" + + +def format_char_pair(pair): + # type: (Tuple[int, int]) -> str + """ + Format a pair of two Rust chars. + """ + return "(%s,%s)" % (escape_char(pair[0]), escape_char(pair[1])) + + +def generate_table( + name, # type: str + items, # type: List[Tuple[int, int]] + decl_type="&[(char, char)]", # type: str + is_pub=True, # type: bool + format_item=format_char_pair, # type: Callable[[Tuple[int, int]], str] +): + # type: (...) -> Iterator[str] + """ + Generate a nicely formatted Rust constant "table" array. + + This generates actual Rust code. + """ pub_string = "" if is_pub: pub_string = "pub " - f.write(" %sconst %s: %s = &[\n" % (pub_string, name, t_type)) - data = "" + + yield " %sconst %s: %s = &[\n" % (pub_string, name, decl_type) + + data = [] first = True - for dat in t_data: + for item in items: if not first: - data += "," + data.append(",") first = False - data += pfun(dat) - format_table_content(f, data, 8) - f.write("\n ];\n\n") + data.extend(format_item(item)) -def compute_trie(rawdata, chunksize): + for table_line in generate_table_lines("".join(data).split(","), 8): + yield table_line + + yield "\n ];\n\n" + + +def compute_trie(raw_data, chunk_size): + # type: (List[int], int) -> Tuple[List[int], List[int]] + """ + Compute postfix-compressed trie. + + See: bool_trie.rs for more details. + + >>> compute_trie([1, 2, 3, 1, 2, 3, 4, 5, 6], 3) + ([0, 0, 1], [1, 2, 3, 4, 5, 6]) + >>> compute_trie([1, 2, 3, 1, 2, 4, 4, 5, 6], 3) + ([0, 1, 2], [1, 2, 3, 1, 2, 4, 4, 5, 6]) + """ root = [] - childmap = {} + childmap = {} # type: Dict[Tuple[int, ...], int] child_data = [] - for i in range(len(rawdata) // chunksize): - data = rawdata[i * chunksize: (i + 1) * chunksize] - child = '|'.join(map(str, data)) + + assert len(raw_data) % chunk_size == 0, "Chunks must be equally sized" + + for i in range(len(raw_data) // chunk_size): + data = raw_data[i * chunk_size : (i + 1) * chunk_size] + + # Postfix compression of child nodes (data chunks) + # (identical child nodes are shared). + + # Make a tuple out of the list so it's hashable. + child = tuple(data) if child not in childmap: childmap[child] = len(childmap) child_data.extend(data) + root.append(childmap[child]) - return (root, child_data) -def emit_bool_trie(f, name, t_data, is_pub=True): - CHUNK = 64 + return root, child_data + + +def generate_bool_trie(name, codepoint_ranges, is_pub=False): + # type: (str, List[Tuple[int, int]], bool) -> Iterator[str] + """ + Generate Rust code for BoolTrie struct. + + This yields string fragments that should be joined to produce + the final string. + + See: `bool_trie.rs`. + """ + chunk_size = 64 rawdata = [False] * 0x110000 - for (lo, hi) in t_data: + for (lo, hi) in codepoint_ranges: for cp in range(lo, hi + 1): rawdata[cp] = True - # convert to bitmap chunks of 64 bits each + # Convert to bitmap chunks of `chunk_size` bits each. chunks = [] - for i in range(0x110000 // CHUNK): + for i in range(0x110000 // chunk_size): chunk = 0 - for j in range(64): - if rawdata[i * 64 + j]: + for j in range(chunk_size): + if rawdata[i * chunk_size + j]: chunk |= 1 << j chunks.append(chunk) pub_string = "" if is_pub: pub_string = "pub " - f.write(" %sconst %s: &super::BoolTrie = &super::BoolTrie {\n" % (pub_string, name)) - f.write(" r1: [\n") - data = ','.join('0x%016x' % chunk for chunk in chunks[0:0x800 // CHUNK]) - format_table_content(f, data, 12) - f.write("\n ],\n") + yield " %sconst %s: &super::BoolTrie = &super::BoolTrie {\n" % (pub_string, name) + yield " r1: [\n" + data = ("0x%016x" % chunk for chunk in chunks[:0x800 // chunk_size]) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" # 0x800..0x10000 trie - (r2, r3) = compute_trie(chunks[0x800 // CHUNK : 0x10000 // CHUNK], 64 // CHUNK) - f.write(" r2: [\n") - data = ','.join(str(node) for node in r2) - format_table_content(f, data, 12) - f.write("\n ],\n") - f.write(" r3: &[\n") - data = ','.join('0x%016x' % chunk for chunk in r3) - format_table_content(f, data, 12) - f.write("\n ],\n") + (r2, r3) = compute_trie(chunks[0x800 // chunk_size : 0x10000 // chunk_size], 64 // chunk_size) + yield " r2: [\n" + data = map(str, r2) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" + + yield " r3: &[\n" + data = ("0x%016x" % node for node in r3) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" # 0x10000..0x110000 trie - (mid, r6) = compute_trie(chunks[0x10000 // CHUNK : 0x110000 // CHUNK], 64 // CHUNK) + (mid, r6) = compute_trie(chunks[0x10000 // chunk_size : 0x110000 // chunk_size], + 64 // chunk_size) (r4, r5) = compute_trie(mid, 64) - f.write(" r4: [\n") - data = ','.join(str(node) for node in r4) - format_table_content(f, data, 12) - f.write("\n ],\n") - f.write(" r5: &[\n") - data = ','.join(str(node) for node in r5) - format_table_content(f, data, 12) - f.write("\n ],\n") - f.write(" r6: &[\n") - data = ','.join('0x%016x' % chunk for chunk in r6) - format_table_content(f, data, 12) - f.write("\n ],\n") - - f.write(" };\n\n") - -def emit_small_bool_trie(f, name, t_data, is_pub=True): - last_chunk = max(hi // 64 for (lo, hi) in t_data) + + yield " r4: [\n" + data = map(str, r4) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" + + yield " r5: &[\n" + data = map(str, r5) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" + + yield " r6: &[\n" + data = ("0x%016x" % node for node in r6) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" + + yield " };\n\n" + + +def generate_small_bool_trie(name, codepoint_ranges, is_pub=False): + # type: (str, List[Tuple[int, int]], bool) -> Iterator[str] + """ + Generate Rust code for `SmallBoolTrie` struct. + + See: `bool_trie.rs`. + """ + last_chunk = max(hi // 64 for (lo, hi) in codepoint_ranges) n_chunks = last_chunk + 1 chunks = [0] * n_chunks - for (lo, hi) in t_data: + for (lo, hi) in codepoint_ranges: for cp in range(lo, hi + 1): - if cp // 64 >= len(chunks): - print(cp, cp // 64, len(chunks), lo, hi) + assert cp // 64 < len(chunks) chunks[cp // 64] |= 1 << (cp & 63) pub_string = "" if is_pub: pub_string = "pub " - f.write(" %sconst %s: &super::SmallBoolTrie = &super::SmallBoolTrie {\n" - % (pub_string, name)) + + yield (" %sconst %s: &super::SmallBoolTrie = &super::SmallBoolTrie {\n" + % (pub_string, name)) (r1, r2) = compute_trie(chunks, 1) - f.write(" r1: &[\n") - data = ','.join(str(node) for node in r1) - format_table_content(f, data, 12) - f.write("\n ],\n") - - f.write(" r2: &[\n") - data = ','.join('0x%016x' % node for node in r2) - format_table_content(f, data, 12) - f.write("\n ],\n") - - f.write(" };\n\n") - -def emit_property_module(f, mod, tbl, emit): - f.write("pub mod %s {\n" % mod) - for cat in sorted(emit): - if cat in ["Cc", "White_Space", "Pattern_White_Space"]: - emit_small_bool_trie(f, "%s_table" % cat, tbl[cat]) - f.write(" pub fn %s(c: char) -> bool {\n" % cat) - f.write(" %s_table.lookup(c)\n" % cat) - f.write(" }\n\n") + yield " r1: &[\n" + data = (str(node) for node in r1) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" + + yield " r2: &[\n" + data = ("0x%016x" % node for node in r2) + for fragment in generate_table_lines(data, 12): + yield fragment + yield "\n ],\n" + + yield " };\n\n" + + +def generate_property_module(mod, grouped_categories, category_subset): + # type: (str, Dict[str, List[Tuple[int, int]]], Iterable[str]) -> Iterator[str] + """ + Generate Rust code for module defining properties. + """ + + yield "pub(crate) mod %s {\n" % mod + for cat in sorted(category_subset): + if cat in ("Cc", "White_Space", "Pattern_White_Space"): + generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat]) else: - emit_bool_trie(f, "%s_table" % cat, tbl[cat]) - f.write(" pub fn %s(c: char) -> bool {\n" % cat) - f.write(" %s_table.lookup(c)\n" % cat) - f.write(" }\n\n") - f.write("}\n\n") - -def emit_conversions_module(f, to_upper, to_lower, to_title): - f.write("pub mod conversions {") - f.write(""" + generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat]) + + for fragment in generator: + yield fragment + + yield " pub fn %s(c: char) -> bool {\n" % cat + yield " %s_table.lookup(c)\n" % cat + yield " }\n\n" + + yield "}\n\n" + + +def generate_conversions_module(unicode_data): + # type: (UnicodeData) -> Iterator[str] + """ + Generate Rust code for module defining conversions. + """ + + yield "pub(crate) mod conversions {" + yield """ pub fn to_lower(c: char) -> [char; 3] { match bsearch_case_table(c, to_lowercase_table) { None => [c, '\\0', '\\0'], @@ -408,80 +767,109 @@ def emit_conversions_module(f, to_upper, to_lower, to_title): fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() - } + }\n\n""" + + decl_type = "&[(char, [char; 3])]" + format_conversion = lambda x: "({},[{},{},{}])".format(*( + escape_char(c) for c in (x[0], x[1][0], x[1][1], x[1][2]) + )) + + for fragment in generate_table( + name="to_lowercase_table", + items=sorted(unicode_data.to_lower.items(), key=lambda x: x[0]), + decl_type=decl_type, + is_pub=False, + format_item=format_conversion + ): + yield fragment + + for fragment in generate_table( + name="to_uppercase_table", + items=sorted(unicode_data.to_upper.items(), key=lambda x: x[0]), + decl_type=decl_type, + is_pub=False, + format_item=format_conversion + ): + yield fragment + + yield "}\n" + + +def parse_args(): + # type: () -> argparse.Namespace + """ + Parse command line arguments. + """ + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("-v", "--version", default=None, type=str, + help="Unicode version to use (if not specified," + " defaults to latest release).") + + return parser.parse_args() + + +def main(): + # type: () -> None + """ + Script entry point. + """ + args = parse_args() + + unicode_version = fetch_files(args.version) + print("Using Unicode version: {}".format(unicode_version.as_str)) + + # All the writing happens entirely in memory, we only write to file + # once we have generated the file content (it's not very large, <1 MB). + buf = StringIO() + buf.write(PREAMBLE) + + unicode_version_notice = textwrap.dedent(""" + /// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of + /// `char` and `str` methods are based on. + #[unstable(feature = "unicode_version", issue = "49726")] + pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {{ + major: {version.major}, + minor: {version.minor}, + micro: {version.micro}, + _priv: (), + }}; + """).format(version=unicode_version) + buf.write(unicode_version_notice) + + get_path = lambda f: get_unicode_file_path(unicode_version, f) + + unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA)) + load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data) + + want_derived = {"XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase", + "Cased", "Case_Ignorable", "Grapheme_Extend"} + derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived) + + props = load_properties(get_path(UnicodeFiles.PROPS), + {"White_Space", "Join_Control", "Noncharacter_Code_Point", + "Pattern_White_Space"}) + + # Category tables + for (name, categories, category_subset) in ( + ("general_category", unicode_data.general_categories, ["N", "Cc"]), + ("derived_property", derived, want_derived), + ("property", props, ["White_Space", "Pattern_White_Space"]) + ): + for fragment in generate_property_module(name, categories, category_subset): + buf.write(fragment) + + for fragment in generate_conversions_module(unicode_data): + buf.write(fragment) + + tables_rs_path = os.path.join(THIS_DIR, "tables.rs") + + # Actually write out the file content. + # Will overwrite the file if it exists. + with open(tables_rs_path, "w") as fd: + fd.write(buf.getvalue()) + + print("Regenerated tables.rs.") -""") - t_type = "&[(char, [char; 3])]" - pfun = lambda x: "(%s,[%s,%s,%s])" % ( - escape_char(x[0]), escape_char(x[1][0]), escape_char(x[1][1]), escape_char(x[1][2])) - emit_table(f, "to_lowercase_table", - sorted(to_lower.items(), key=operator.itemgetter(0)), - is_pub=False, t_type = t_type, pfun=pfun) - emit_table(f, "to_uppercase_table", - sorted(to_upper.items(), key=operator.itemgetter(0)), - is_pub=False, t_type = t_type, pfun=pfun) - f.write("}\n\n") - -def emit_norm_module(f, canon, compat, combine, norm_props): - canon_keys = sorted(canon.keys()) - - compat_keys = sorted(compat.keys()) - - canon_comp = {} - comp_exclusions = norm_props["Full_Composition_Exclusion"] - for char in canon_keys: - if any(lo <= char <= hi for lo, hi in comp_exclusions): - continue - decomp = canon[char] - if len(decomp) == 2: - if decomp[0] not in canon_comp: - canon_comp[decomp[0]] = [] - canon_comp[decomp[0]].append( (decomp[1], char) ) - canon_comp_keys = sorted(canon_comp.keys()) if __name__ == "__main__": - r = fdir + "tables.rs" - if os.path.exists(r): - os.remove(r) - with open(r, "w") as rf: - # write the file's preamble - rf.write(preamble) - - # download and parse all the data - fetch("ReadMe.txt") - with open(fdir + "ReadMe.txt") as readme: - pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode" - unicode_version = re.search(pattern, readme.read()).groups() - rf.write(""" -/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of -/// `char` and `str` methods are based on. -#[unstable(feature = "unicode_version", issue = "49726")] -pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion { - major: %s, - minor: %s, - micro: %s, - _priv: (), -}; -""" % unicode_version) - (canon_decomp, compat_decomp, gencats, combines, - to_upper, to_lower, to_title) = load_unicode_data("UnicodeData.txt") - load_special_casing("SpecialCasing.txt", to_upper, to_lower, to_title) - want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase", - "Cased", "Case_Ignorable", "Grapheme_Extend"] - derived = load_properties("DerivedCoreProperties.txt", want_derived) - scripts = load_properties("Scripts.txt", []) - props = load_properties("PropList.txt", - ["White_Space", "Join_Control", "Noncharacter_Code_Point", "Pattern_White_Space"]) - norm_props = load_properties("DerivedNormalizationProps.txt", - ["Full_Composition_Exclusion"]) - - # category tables - for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc"]), \ - ("derived_property", derived, want_derived), \ - ("property", props, ["White_Space", "Pattern_White_Space"]): - emit_property_module(rf, name, cat, pfuns) - - # normalizations and conversions module - emit_norm_module(rf, canon_decomp, compat_decomp, combines, norm_props) - emit_conversions_module(rf, to_upper, to_lower, to_title) - print("Regenerated tables.rs.") + main() diff --git a/src/libfmt_macros/Cargo.toml b/src/libfmt_macros/Cargo.toml index fc32f21ec4..82a9e34c06 100644 --- a/src/libfmt_macros/Cargo.toml +++ b/src/libfmt_macros/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [lib] name = "fmt_macros" path = "lib.rs" -crate-type = ["dylib"] [dependencies] syntax_pos = { path = "../libsyntax_pos" } + diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index f6e9143dd0..985abaf2c1 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -8,12 +8,9 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #![feature(nll)] #![feature(rustc_private)] +#![feature(unicode_internals)] pub use Piece::*; pub use Position::*; @@ -59,16 +56,20 @@ pub struct Argument<'a> { /// Specification for the formatting of an argument in the format string. #[derive(Copy, Clone, PartialEq)] pub struct FormatSpec<'a> { - /// Optionally specified character to fill alignment with + /// Optionally specified character to fill alignment with. pub fill: Option, - /// Optionally specified alignment + /// Optionally specified alignment. pub align: Alignment, - /// Packed version of various flags provided + /// Packed version of various flags provided. pub flags: u32, - /// The integer precision to use + /// The integer precision to use. pub precision: Count, - /// The string width requested for the resulting format + /// The span of the precision formatting flag (for diagnostics). + pub precision_span: Option, + /// The string width requested for the resulting format. pub width: Count, + /// The span of the width formatting flag (for diagnostics). + pub width_span: Option, /// The descriptor string representing the name of the format desired for /// this argument, this can be empty or any number of characters, although /// it is required to be one word. @@ -285,19 +286,24 @@ impl<'a> Parser<'a> { } /// Optionally consumes the specified character. If the character is not at - /// the current position, then the current iterator isn't moved and false is - /// returned, otherwise the character is consumed and true is returned. + /// the current position, then the current iterator isn't moved and `false` is + /// returned, otherwise the character is consumed and `true` is returned. fn consume(&mut self, c: char) -> bool { - if let Some(&(_, maybe)) = self.cur.peek() { + self.consume_pos(c).is_some() + } + + /// Optionally consumes the specified character. If the character is not at + /// the current position, then the current iterator isn't moved and `None` is + /// returned, otherwise the character is consumed and the current position is + /// returned. + fn consume_pos(&mut self, c: char) -> Option { + if let Some(&(pos, maybe)) = self.cur.peek() { if c == maybe { self.cur.next(); - true - } else { - false + return Some(pos); } - } else { - false } + None } fn to_span_index(&self, pos: usize) -> InnerOffset { @@ -465,7 +471,9 @@ impl<'a> Parser<'a> { align: AlignUnknown, flags: 0, precision: CountImplied, + precision_span: None, width: CountImplied, + width_span: None, ty: &self.input[..0], }; if !self.consume(':') { @@ -502,6 +510,7 @@ impl<'a> Parser<'a> { } // Width and precision let mut havewidth = false; + if self.consume('0') { // small ambiguity with '0$' as a format string. In theory this is a // '0' flag and then an ill-formatted format string with just a '$' @@ -515,17 +524,28 @@ impl<'a> Parser<'a> { } } if !havewidth { - spec.width = self.count(); + let width_span_start = if let Some((pos, _)) = self.cur.peek() { + *pos + } else { + 0 + }; + let (w, sp) = self.count(width_span_start); + spec.width = w; + spec.width_span = sp; } - if self.consume('.') { - if self.consume('*') { + if let Some(start) = self.consume_pos('.') { + if let Some(end) = self.consume_pos('*') { // Resolve `CountIsNextParam`. // We can do this immediately as `position` is resolved later. let i = self.curarg; self.curarg += 1; spec.precision = CountIsParam(i); + spec.precision_span = + Some(self.to_span_index(start).to(self.to_span_index(end + 1))); } else { - spec.precision = self.count(); + let (p, sp) = self.count(start); + spec.precision = p; + spec.precision_span = sp; } } // Optional radix followed by the actual format specifier @@ -554,24 +574,25 @@ impl<'a> Parser<'a> { /// Parses a Count parameter at the current position. This does not check /// for 'CountIsNextParam' because that is only used in precision, not /// width. - fn count(&mut self) -> Count { + fn count(&mut self, start: usize) -> (Count, Option) { if let Some(i) = self.integer() { - if self.consume('$') { - CountIsParam(i) + if let Some(end) = self.consume_pos('$') { + let span = self.to_span_index(start).to(self.to_span_index(end + 1)); + (CountIsParam(i), Some(span)) } else { - CountIs(i) + (CountIs(i), None) } } else { let tmp = self.cur.clone(); let word = self.word(); if word.is_empty() { self.cur = tmp; - CountImplied + (CountImplied, None) } else if self.consume('$') { - CountIsName(Symbol::intern(word)) + (CountIsName(Symbol::intern(word)), None) } else { self.cur = tmp; - CountImplied + (CountImplied, None) } } } diff --git a/src/libfmt_macros/tests.rs b/src/libfmt_macros/tests.rs index 7282d4a5f2..e2ddb8810e 100644 --- a/src/libfmt_macros/tests.rs +++ b/src/libfmt_macros/tests.rs @@ -12,6 +12,8 @@ fn fmtdflt() -> FormatSpec<'static> { flags: 0, precision: CountImplied, width: CountImplied, + precision_span: None, + width_span: None, ty: "", }; } @@ -79,165 +81,204 @@ fn format_position_nothing_else() { } #[test] fn format_type() { - same("{3:a}", - &[NextArgument(Argument { - position: ArgumentIs(3), - format: FormatSpec { - fill: None, - align: AlignUnknown, - flags: 0, - precision: CountImplied, - width: CountImplied, - ty: "a", - }, - })]); + same( + "{3:a}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: FormatSpec { + fill: None, + align: AlignUnknown, + flags: 0, + precision: CountImplied, + width: CountImplied, + precision_span: None, + width_span: None, + ty: "a", + }, + })]); } #[test] fn format_align_fill() { - same("{3:>}", - &[NextArgument(Argument { - position: ArgumentIs(3), - format: FormatSpec { - fill: None, - align: AlignRight, - flags: 0, - precision: CountImplied, - width: CountImplied, - ty: "", - }, - })]); - same("{3:0<}", - &[NextArgument(Argument { - position: ArgumentIs(3), - format: FormatSpec { - fill: Some('0'), - align: AlignLeft, - flags: 0, - precision: CountImplied, - width: CountImplied, - ty: "", - }, - })]); - same("{3:*}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: FormatSpec { + fill: None, + align: AlignRight, + flags: 0, + precision: CountImplied, + width: CountImplied, + precision_span: None, + width_span: None, + ty: "", + }, + })]); + same( + "{3:0<}", + &[NextArgument(Argument { + position: ArgumentIs(3), + format: FormatSpec { + fill: Some('0'), + align: AlignLeft, + flags: 0, + precision: CountImplied, + width: CountImplied, + precision_span: None, + width_span: None, + ty: "", + }, + })]); + same( + "{3:* u32 { libc::abort(); } - #[cfg(any(target_os = "redox", - windows, + #[cfg(any(windows, all(target_arch = "wasm32", not(target_os = "emscripten"))))] unsafe fn abort() -> ! { core::intrinsics::abort(); diff --git a/src/libpanic_unwind/dwarf/mod.rs b/src/libpanic_unwind/dwarf/mod.rs index 0360696426..34128e60d3 100644 --- a/src/libpanic_unwind/dwarf/mod.rs +++ b/src/libpanic_unwind/dwarf/mod.rs @@ -6,6 +6,9 @@ // are compiling it everywhere to avoid regressions. #![allow(unused)] +#[cfg(test)] +mod tests; + pub mod eh; use core::mem; @@ -68,21 +71,3 @@ impl DwarfReader { result as i64 } } - -#[test] -fn dwarf_reader() { - let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF]; - - let mut reader = DwarfReader::new(encoded.as_ptr()); - - unsafe { - assert!(reader.read::() == u8::to_be(1u8)); - assert!(reader.read::() == u16::to_be(0x0203)); - assert!(reader.read::() == u32::to_be(0x04050607)); - - assert!(reader.read_uleb128() == 624485); - assert!(reader.read_sleb128() == -624485); - - assert!(reader.read::() == i8::to_be(-1)); - } -} diff --git a/src/libpanic_unwind/dwarf/tests.rs b/src/libpanic_unwind/dwarf/tests.rs new file mode 100644 index 0000000000..1644f37083 --- /dev/null +++ b/src/libpanic_unwind/dwarf/tests.rs @@ -0,0 +1,19 @@ +use super::*; + +#[test] +fn dwarf_reader() { + let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF]; + + let mut reader = DwarfReader::new(encoded.as_ptr()); + + unsafe { + assert!(reader.read::() == u8::to_be(1u8)); + assert!(reader.read::() == u16::to_be(0x0203)); + assert!(reader.read::() == u32::to_be(0x04050607)); + + assert!(reader.read_uleb128() == 624485); + assert!(reader.read_sleb128() == -624485); + + assert!(reader.read::() == i8::to_be(-1)); + } +} diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index e2b743b379..236ed15050 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -126,6 +126,9 @@ const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7 #[cfg(target_arch = "sparc64")] const UNWIND_DATA_REG: (i32, i32) = (24, 25); // I0, I1 +#[cfg(target_arch = "hexagon")] +const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 + // The following code is based on GCC's C and C++ personality routines. For reference, see: // https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 2bb9ce6ab2..06e6e768f4 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -17,8 +17,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] -#![deny(rust_2018_idioms)] - #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(libc)] diff --git a/src/libproc_macro/bridge/buffer.rs b/src/libproc_macro/bridge/buffer.rs index 0d8cc552d6..a51e3a9a33 100644 --- a/src/libproc_macro/bridge/buffer.rs +++ b/src/libproc_macro/bridge/buffer.rs @@ -78,7 +78,7 @@ impl Buffer { } pub(super) fn take(&mut self) -> Self { - mem::replace(self, Self::default()) + mem::take(self) } pub(super) fn extend_from_slice(&mut self, xs: &[T]) { diff --git a/src/libproc_macro/bridge/scoped_cell.rs b/src/libproc_macro/bridge/scoped_cell.rs index 6f7965095b..2cde1f65ad 100644 --- a/src/libproc_macro/bridge/scoped_cell.rs +++ b/src/libproc_macro/bridge/scoped_cell.rs @@ -5,6 +5,7 @@ use std::mem; use std::ops::{Deref, DerefMut}; /// Type lambda application, with a lifetime. +#[allow(unused_lifetimes)] pub trait ApplyL<'a> { type Out; } @@ -74,7 +75,7 @@ impl ScopedCell { } /// Sets the value in `self` to `value` while running `f`. - pub fn set<'a, R>(&self, value: >::Out, f: impl FnOnce() -> R) -> R { + pub fn set(&self, value: >::Out, f: impl FnOnce() -> R) -> R { self.replace(value, |_| f()) } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 1e0f1ed578..c0f7714ca2 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -17,14 +17,13 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] -#![deny(rust_2018_idioms)] - #![feature(nll)] #![feature(staged_api)] #![feature(const_fn)] #![feature(extern_types)] #![feature(in_band_lifetimes)] #![feature(optin_builtin_traits)] +#![feature(mem_take)] #![feature(non_exhaustive)] #![feature(specialization)] diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 0b2bda577d..775f84535f 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -19,6 +19,7 @@ fn main() { "InstrProfilingPlatformDarwin.c", "InstrProfilingPlatformLinux.c", "InstrProfilingPlatformOther.c", + "InstrProfilingPlatformWindows.c", "InstrProfilingRuntime.cc", "InstrProfilingUtil.c", "InstrProfilingValue.c", diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index 2ce1a110b4..0d12ba01c8 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -7,4 +7,3 @@ #![allow(unused_features)] #![feature(nll)] #![feature(staged_api)] -#![deny(rust_2018_idioms)] diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 4d50e80d4c..0222a3dde7 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [lib] name = "rustc" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] arena = { path = "../libarena" } @@ -19,15 +19,15 @@ lazy_static = "1.0.0" num_cpus = "1.0" scoped-tls = "1.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } -polonius-engine = "0.7.0" rustc-rayon = "0.2.0" rustc-rayon-core = "0.2.0" +polonius-engine = "0.9.0" rustc_apfloat = { path = "../librustc_apfloat" } rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } backtrace = "0.3.3" @@ -37,33 +37,3 @@ chalk-engine = { version = "0.9.0", default-features=false } rustc_fs_util = { path = "../librustc_fs_util" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } measureme = "0.3" - -# Note that these dependencies are a lie, they're just here to get linkage to -# work. -# -# We're creating a bunch of dylibs for the compiler but we're also compiling a -# bunch of crates.io crates. Everything in the compiler is compiled as an -# rlib/dylib pair but all crates.io crates tend to just be rlibs. This means -# we've got a problem for dependency graphs that look like: -# -# foo - rustc_codegen_llvm -# / \ -# rustc ---- rustc_driver -# \ / -# foo - rustc_metadata -# -# Here the crate `foo` is linked into the `rustc_codegen_llvm` and the -# `rustc_metadata` dylibs, meaning we've got duplicate copies! When we then -# go to link `rustc_driver` the compiler notices this and gives us a compiler -# error. -# -# To work around this problem we just add these crates.io dependencies to the -# `rustc` crate which is a shared dependency above. That way the crate `foo` -# shows up in the dylib for the `rustc` crate, deduplicating it and allowing -# crates like `rustc_codegen_llvm` to use `foo` *through* the `rustc` crate. -# -# tl;dr; this is not needed to get `rustc` to compile, but if you remove it then -# later crate stop compiling. If you can remove this and everything -# compiles, then please feel free to do so! -flate2 = "1.0" -tempfile = "3.0" diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index a7750edbb6..ca852fe762 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -1,11 +1,11 @@ use crate::cfg::*; use crate::middle::region; use rustc_data_structures::graph::implementation as graph; -use syntax::ptr::P; use crate::ty::{self, TyCtxt}; use crate::hir::{self, PatKind}; use crate::hir::def_id::DefId; +use crate::hir::ptr::P; struct CFGBuilder<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -30,7 +30,7 @@ struct LoopScope { break_index: CFGIndex, // where to go on a `break` } -pub fn construct<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG { +pub fn construct(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG { let mut graph = graph::Graph::new(); let entry = graph.add_node(CFGNodeData::Entry); @@ -165,48 +165,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.add_ast_node(expr.hir_id.local_id, &[blk_exit]) } - hir::ExprKind::While(ref cond, ref body, _) => { - // - // [pred] - // | - // v 1 - // [loopback] <--+ 5 - // | | - // v 2 | - // +-----[cond] | - // | | | - // | v 4 | - // | [body] -----+ - // v 3 - // [expr] - // - // Note that `break` and `continue` statements - // may cause additional edges. - - let loopback = self.add_dummy_node(&[pred]); // 1 - - // Create expr_exit without pred (cond_exit) - let expr_exit = self.add_ast_node(expr.hir_id.local_id, &[]); // 3 - - // The LoopScope needs to be on the loop_scopes stack while evaluating the - // condition and the body of the loop (both can break out of the loop) - self.loop_scopes.push(LoopScope { - loop_id: expr.hir_id.local_id, - continue_index: loopback, - break_index: expr_exit - }); - - let cond_exit = self.expr(&cond, loopback); // 2 - - // Add pred (cond_exit) to expr_exit - self.add_contained_edge(cond_exit, expr_exit); - - let body_exit = self.block(&body, cond_exit); // 4 - self.add_contained_edge(body_exit, loopback); // 5 - self.loop_scopes.pop(); - expr_exit - } - hir::ExprKind::Loop(ref body, _, _) => { // // [pred] @@ -413,7 +371,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let expr_exit = self.add_ast_node(id, &[]); // Keep track of the previous guard expressions - let mut prev_guards = Vec::new(); + let mut prev_guard = None; + let match_scope = region::Scope { id, data: region::ScopeData::Node }; for arm in arms { // Add an exit node for when we've visited all the @@ -431,7 +390,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let guard_start = self.add_dummy_node(&[pat_exit]); // Visit the guard expression let guard_exit = match guard { - hir::Guard::If(ref e) => self.expr(e, guard_start), + hir::Guard::If(ref e) => (&**e, self.expr(e, guard_start)), }; // #47295: We used to have very special case code // here for when a pair of arms are both formed @@ -439,15 +398,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // edges. But this was not actually sound without // other constraints that we stopped enforcing at // some point. - while let Some(prev) = prev_guards.pop() { - self.add_contained_edge(prev, guard_start); + if let Some((prev_guard, prev_index)) = prev_guard.take() { + self.add_exiting_edge(prev_guard, prev_index, match_scope, guard_start); } // Push the guard onto the list of previous guards - prev_guards.push(guard_exit); + prev_guard = Some(guard_exit); // Update the exit node for the pattern - pat_exit = guard_exit; + pat_exit = guard_exit.1; } // Add an edge from the exit of this pattern to the diff --git a/src/librustc/cfg/mod.rs b/src/librustc/cfg/mod.rs index db168d99a0..88fc7fbfad 100644 --- a/src/librustc/cfg/mod.rs +++ b/src/librustc/cfg/mod.rs @@ -49,7 +49,7 @@ pub type CFGNode = graph::Node; pub type CFGEdge = graph::Edge; impl CFG { - pub fn new<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG { + pub fn new(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG { construct::construct(tcx, body) } diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs index 94b832bea6..ee22d0b755 100644 --- a/src/librustc/dep_graph/dep_tracking_map.rs +++ b/src/librustc/dep_graph/dep_tracking_map.rs @@ -55,7 +55,7 @@ impl MemoizationMap for RefCell> { /// /// ``` /// fn type_of_item(..., item: &hir::Item) -> Ty<'tcx> { - /// let item_def_id = ccx.tcx.hir().local_def_id(it.id); + /// let item_def_id = ccx.tcx.hir().local_def_id(it.hir_id); /// ccx.tcx.item_types.memoized(item_def_id, || { /// ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id)); // (*) /// compute_type_of_item(ccx, item) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 93c22c3e71..7eea336cbb 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -7,6 +7,7 @@ use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering}; use std::env; use std::hash::Hash; use std::collections::hash_map::Entry; +use std::mem; use crate::ty::{self, TyCtxt}; use crate::util::common::{ProfileQueriesMsg, profq_msg}; use parking_lot::{Mutex, Condvar}; @@ -61,11 +62,11 @@ struct DepGraphData { colors: DepNodeColorMap, - /// A set of loaded diagnostics that have been emitted. - emitted_diagnostics: Mutex>, + /// A set of loaded diagnostics that is in the progress of being emitted. + emitting_diagnostics: Mutex>, /// Used to wait for diagnostics to be emitted. - emitted_diagnostics_cond_var: Condvar, + emitting_diagnostics_cond_var: Condvar, /// When we load, there may be `.o` files, cached MIR, or other such /// things available to us. If we find that they are not dirty, we @@ -99,8 +100,8 @@ impl DepGraph { previous_work_products: prev_work_products, dep_node_debug: Default::default(), current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)), - emitted_diagnostics: Default::default(), - emitted_diagnostics_cond_var: Condvar::new(), + emitting_diagnostics: Default::default(), + emitting_diagnostics_cond_var: Condvar::new(), previous: prev_graph, colors: DepNodeColorMap::new(prev_graph_node_count), loaded_from_cache: Default::default(), @@ -744,7 +745,7 @@ impl DepGraph { // There may be multiple threads trying to mark the same dep node green concurrently - let (dep_node_index, did_allocation) = { + let dep_node_index = { let mut current = data.current.borrow_mut(); // Copy the fingerprint from the previous graph, @@ -758,34 +759,36 @@ impl DepGraph { // ... emitting any stored diagnostic ... + // FIXME: Store the fact that a node has diagnostics in a bit in the dep graph somewhere + // Maybe store a list on disk and encode this fact in the DepNodeState let diagnostics = tcx.queries.on_disk_cache - .load_diagnostics(tcx, prev_dep_node_index); + .load_diagnostics(tcx, prev_dep_node_index); + + #[cfg(not(parallel_compiler))] + debug_assert!(data.colors.get(prev_dep_node_index).is_none(), + "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ + insertion for {:?}", dep_node); if unlikely!(diagnostics.len() > 0) { self.emit_diagnostics( tcx, data, dep_node_index, - did_allocation, + prev_dep_node_index, diagnostics ); } // ... and finally storing a "Green" entry in the color map. // Multiple threads can all write the same color here - #[cfg(not(parallel_compiler))] - debug_assert!(data.colors.get(prev_dep_node_index).is_none(), - "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ - insertion for {:?}", dep_node); - data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); debug!("try_mark_previous_green({:?}) - END - successfully marked as green", dep_node); Some(dep_node_index) } - /// Atomically emits some loaded diagnotics, assuming that this only gets called with - /// `did_allocation` set to `true` on a single thread. + /// Atomically emits some loaded diagnostics. + /// This may be called concurrently on multiple threads for the same dep node. #[cold] #[inline(never)] fn emit_diagnostics<'tcx>( @@ -793,36 +796,49 @@ impl DepGraph { tcx: TyCtxt<'tcx>, data: &DepGraphData, dep_node_index: DepNodeIndex, - did_allocation: bool, + prev_dep_node_index: SerializedDepNodeIndex, diagnostics: Vec, ) { - if did_allocation || !cfg!(parallel_compiler) { - // Only the thread which did the allocation emits the error messages - let handle = tcx.sess.diagnostic(); + let mut emitting = data.emitting_diagnostics.lock(); + + if data.colors.get(prev_dep_node_index) == Some(DepNodeColor::Green(dep_node_index)) { + // The node is already green so diagnostics must have been emitted already + return; + } + + if emitting.insert(dep_node_index) { + // We were the first to insert the node in the set so this thread + // must emit the diagnostics and signal other potentially waiting + // threads after. + mem::drop(emitting); // Promote the previous diagnostics to the current session. tcx.queries.on_disk_cache - .store_diagnostics(dep_node_index, diagnostics.clone().into()); + .store_diagnostics(dep_node_index, diagnostics.clone().into()); + + let handle = tcx.sess.diagnostic(); for diagnostic in diagnostics { DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit(); } - #[cfg(parallel_compiler)] - { - // Mark the diagnostics and emitted and wake up waiters - data.emitted_diagnostics.lock().insert(dep_node_index); - data.emitted_diagnostics_cond_var.notify_all(); - } + // Mark the node as green now that diagnostics are emitted + data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); + + // Remove the node from the set + data.emitting_diagnostics.lock().remove(&dep_node_index); + + // Wake up waiters + data.emitting_diagnostics_cond_var.notify_all(); } else { - // The other threads will wait for the diagnostics to be emitted + // We must wait for the other thread to finish emitting the diagnostic - let mut emitted_diagnostics = data.emitted_diagnostics.lock(); loop { - if emitted_diagnostics.contains(&dep_node_index) { + data.emitting_diagnostics_cond_var.wait(&mut emitting); + if data.colors + .get(prev_dep_node_index) == Some(DepNodeColor::Green(dep_node_index)) { break; } - data.emitted_diagnostics_cond_var.wait(&mut emitted_diagnostics); } } } @@ -841,7 +857,7 @@ impl DepGraph { // // This method will only load queries that will end up in the disk cache. // Other queries will not be executed. - pub fn exec_cache_promotions<'tcx>(&self, tcx: TyCtxt<'tcx>) { + pub fn exec_cache_promotions(&self, tcx: TyCtxt<'_>) { let data = self.data.as_ref().unwrap(); for prev_index in data.colors.values.indices() { match data.colors.get(prev_index) { @@ -1027,7 +1043,7 @@ impl CurrentDepGraph { hash: self.anon_id_seed.combine(hasher.finish()), }; - self.intern_node(target_dep_node, task_deps.reads, Fingerprint::ZERO).0 + self.intern_node(target_dep_node, task_deps.reads, Fingerprint::ZERO) } fn alloc_node( @@ -1037,7 +1053,7 @@ impl CurrentDepGraph { fingerprint: Fingerprint ) -> DepNodeIndex { debug_assert!(!self.node_to_node_index.contains_key(&dep_node)); - self.intern_node(dep_node, edges, fingerprint).0 + self.intern_node(dep_node, edges, fingerprint) } fn intern_node( @@ -1045,11 +1061,11 @@ impl CurrentDepGraph { dep_node: DepNode, edges: SmallVec<[DepNodeIndex; 8]>, fingerprint: Fingerprint - ) -> (DepNodeIndex, bool) { + ) -> DepNodeIndex { debug_assert_eq!(self.node_to_node_index.len(), self.data.len()); match self.node_to_node_index.entry(dep_node) { - Entry::Occupied(entry) => (*entry.get(), false), + Entry::Occupied(entry) => *entry.get(), Entry::Vacant(entry) => { let dep_node_index = DepNodeIndex::new(self.data.len()); self.data.push(DepNodeData { @@ -1058,7 +1074,7 @@ impl CurrentDepGraph { fingerprint }); entry.insert(dep_node_index); - (dep_node_index, true) + dep_node_index } } } diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 65821d8dd8..b3eee7c346 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - // Error messages for EXXXX errors. // Each message should start and end with a new line, and be wrapped to 80 characters. // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. @@ -485,7 +483,7 @@ Erroneous code example: fn foo() {} #[main] -fn f() {} // error: multiple functions with a #[main] attribute +fn f() {} // error: multiple functions with a `#[main]` attribute ``` This error indicates that the compiler found multiple functions with the @@ -2090,11 +2088,11 @@ generator can be constructed. Erroneous code example: ```edition2018,compile-fail,E0698 -#![feature(futures_api, async_await, await_macro)] +#![feature(async_await)] async fn bar() -> () {} async fn foo() { - await!(bar()); // error: cannot infer type for `T` + bar().await; // error: cannot infer type for `T` } ``` @@ -2103,12 +2101,12 @@ To fix this you must bind `T` to a concrete type such as `String` so that a generator can then be constructed: ```edition2018 -#![feature(futures_api, async_await, await_macro)] +#![feature(async_await)] async fn bar() -> () {} async fn foo() { - await!(bar::()); - // ^^^^^^^^ specify type explicitly + bar::().await; + // ^^^^^^^^ specify type explicitly } ``` "##, diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 4b84d56858..22124d4ee4 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -26,8 +26,8 @@ pub(crate) enum Target { Mod, ForeignMod, GlobalAsm, - Ty, - Existential, + TyAlias, + OpaqueTy, Enum, Struct, Union, @@ -50,8 +50,8 @@ impl Display for Target { Target::Mod => "module", Target::ForeignMod => "foreign module", Target::GlobalAsm => "global asm", - Target::Ty => "type alias", - Target::Existential => "existential type", + Target::TyAlias => "type alias", + Target::OpaqueTy => "opaque type", Target::Enum => "enum", Target::Struct => "struct", Target::Union => "union", @@ -75,8 +75,8 @@ impl Target { hir::ItemKind::Mod(..) => Target::Mod, hir::ItemKind::ForeignMod(..) => Target::ForeignMod, hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm, - hir::ItemKind::Ty(..) => Target::Ty, - hir::ItemKind::Existential(..) => Target::Existential, + hir::ItemKind::TyAlias(..) => Target::TyAlias, + hir::ItemKind::OpaqueTy(..) => Target::OpaqueTy, hir::ItemKind::Enum(..) => Target::Enum, hir::ItemKind::Struct(..) => Target::Struct, hir::ItemKind::Union(..) => Target::Union, @@ -95,7 +95,7 @@ impl CheckAttrVisitor<'tcx> { /// Checks any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { if target == Target::Fn || target == Target::Const { - self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id)); + self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.hir_id)); } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) { self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function") .span_label(item.span, "not a function") @@ -347,7 +347,7 @@ fn is_c_like_enum(item: &hir::Item) -> bool { } } -fn check_mod_attrs<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor() diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 131a910beb..f83fbcdc26 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -1,4 +1,4 @@ -use crate::hir::def_id::DefId; +use crate::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::util::nodemap::DefIdMap; use syntax::ast; use syntax::ext::base::MacroKind; @@ -55,15 +55,15 @@ pub enum DefKind { /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists. Variant, Trait, - /// `existential type Foo: Bar;` - Existential, + /// `type Foo = impl Bar;` + OpaqueTy, /// `type Foo = Bar;` TyAlias, ForeignTy, TraitAlias, AssocTy, - /// `existential type Foo: Bar;` - AssocExistential, + /// `type Foo = impl Bar;` + AssocOpaqueTy, TyParam, // Value namespace @@ -81,9 +81,11 @@ pub enum DefKind { } impl DefKind { - pub fn descr(self) -> &'static str { + pub fn descr(self, def_id: DefId) -> &'static str { match self { DefKind::Fn => "function", + DefKind::Mod if def_id.index == CRATE_DEF_INDEX && def_id.krate != LOCAL_CRATE => + "crate", DefKind::Mod => "module", DefKind::Static => "static", DefKind::Enum => "enum", @@ -96,11 +98,11 @@ impl DefKind { DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => bug!("impossible struct constructor"), - DefKind::Existential => "existential type", + DefKind::OpaqueTy => "opaque type", DefKind::TyAlias => "type alias", DefKind::TraitAlias => "trait alias", DefKind::AssocTy => "associated type", - DefKind::AssocExistential => "associated existential type", + DefKind::AssocOpaqueTy => "associated opaque type", DefKind::Union => "union", DefKind::Trait => "trait", DefKind::ForeignTy => "foreign type", @@ -118,9 +120,9 @@ impl DefKind { match *self { DefKind::AssocTy | DefKind::AssocConst - | DefKind::AssocExistential + | DefKind::AssocOpaqueTy | DefKind::Enum - | DefKind::Existential => "an", + | DefKind::OpaqueTy => "an", DefKind::Macro(macro_kind) => macro_kind.article(), _ => "a", } @@ -366,7 +368,7 @@ impl Res { /// A human readable name for the res kind ("function", "module", etc.). pub fn descr(&self) -> &'static str { match *self { - Res::Def(kind, _) => kind.descr(), + Res::Def(kind, def_id) => kind.descr(def_id), Res::SelfCtor(..) => "self constructor", Res::PrimTy(..) => "builtin type", Res::Local(..) => "local variable", @@ -398,4 +400,12 @@ impl Res { Res::Err => Res::Err, } } + + pub fn macro_kind(self) -> Option { + match self { + Res::Def(DefKind::Macro(kind), _) => Some(kind), + Res::NonMacroAttr(..) => Some(MacroKind::Attr), + _ => None, + } + } } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index debed38361..c0a661908a 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -1,7 +1,6 @@ use crate::ty::{self, TyCtxt}; use crate::hir::map::definitions::FIRST_FREE_DEF_INDEX; use rustc_data_structures::indexed_vec::Idx; -use serialize; use std::fmt; use std::u32; @@ -13,10 +12,6 @@ newtype_index! { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum CrateNum { - /// Virtual crate for builtin macros - // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get - // `CrateNum`s. - BuiltinMacros, /// A special CrateNum that we use for the tcx.rcache when decoding from /// the incr. comp. cache. ReservedForIncrCompCache, @@ -27,7 +22,6 @@ impl ::std::fmt::Debug for CrateNum { fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { match self { CrateNum::Index(id) => write!(fmt, "crate{}", id.private), - CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"), CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"), } } @@ -69,14 +63,14 @@ impl CrateNum { pub fn as_usize(self) -> usize { match self { CrateNum::Index(id) => id.as_usize(), - _ => bug!("tried to get index of nonstandard crate {:?}", self), + _ => bug!("tried to get index of non-standard crate {:?}", self), } } pub fn as_u32(self) -> u32 { match self { CrateNum::Index(id) => id.as_u32(), - _ => bug!("tried to get index of nonstandard crate {:?}", self), + _ => bug!("tried to get index of non-standard crate {:?}", self), } } @@ -87,14 +81,13 @@ impl fmt::Display for CrateNum { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { CrateNum::Index(id) => fmt::Display::fmt(&id.private, f), - CrateNum::BuiltinMacros => write!(f, "builtin macros crate"), CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"), } } } -impl serialize::UseSpecializedEncodable for CrateNum {} -impl serialize::UseSpecializedDecodable for CrateNum {} +impl rustc_serialize::UseSpecializedEncodable for CrateNum {} +impl rustc_serialize::UseSpecializedDecodable for CrateNum {} newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a @@ -134,8 +127,8 @@ impl DefIndex { } } -impl serialize::UseSpecializedEncodable for DefIndex {} -impl serialize::UseSpecializedDecodable for DefIndex {} +impl rustc_serialize::UseSpecializedEncodable for DefIndex {} +impl rustc_serialize::UseSpecializedDecodable for DefIndex {} /// A `DefId` identifies a particular *definition*, by combining a crate /// index and a def index. @@ -186,8 +179,8 @@ impl DefId { } } -impl serialize::UseSpecializedEncodable for DefId {} -impl serialize::UseSpecializedDecodable for DefId {} +impl rustc_serialize::UseSpecializedEncodable for DefId {} +impl rustc_serialize::UseSpecializedDecodable for DefId {} /// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since /// we encode this information in the type, we can ensure at compile time that @@ -220,5 +213,5 @@ impl fmt::Debug for LocalDefId { } } -impl serialize::UseSpecializedEncodable for LocalDefId {} -impl serialize::UseSpecializedDecodable for LocalDefId {} +impl rustc_serialize::UseSpecializedEncodable for LocalDefId {} +impl rustc_serialize::UseSpecializedDecodable for LocalDefId {} diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 9c05f18762..b5c760bc9a 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -210,6 +210,10 @@ pub trait Visitor<'v> : Sized { } } + fn visit_arg(&mut self, arg: &'v Arg) { + walk_arg(self, arg) + } + /// Visits the top-level item and (optionally) nested items / impl items. See /// `visit_nested_item` for details. fn visit_item(&mut self, i: &'v Item) { @@ -396,10 +400,7 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id } pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) { - for argument in &body.arguments { - visitor.visit_id(argument.hir_id); - visitor.visit_pat(&argument.pat); - } + walk_list!(visitor, visit_arg, &body.arguments); visitor.visit_expr(&body.value); } @@ -452,6 +453,12 @@ pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id) } +pub fn walk_arg<'v, V: Visitor<'v>>(visitor: &mut V, arg: &'v Arg) { + visitor.visit_id(arg.hir_id); + visitor.visit_pat(&arg.pat); + walk_list!(visitor, visit_attribute, &arg.attrs); +} + pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); @@ -493,12 +500,12 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { ItemKind::GlobalAsm(_) => { visitor.visit_id(item.hir_id); } - ItemKind::Ty(ref ty, ref generics) => { + ItemKind::TyAlias(ref ty, ref generics) => { visitor.visit_id(item.hir_id); visitor.visit_ty(ty); visitor.visit_generics(generics) } - ItemKind::Existential(ExistTy { + ItemKind::OpaqueTy(OpaqueTy { ref generics, ref bounds, .. @@ -919,11 +926,11 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt impl_item.span, impl_item.hir_id); } - ImplItemKind::Type(ref ty) => { + ImplItemKind::TyAlias(ref ty) => { visitor.visit_id(impl_item.hir_id); visitor.visit_ty(ty); } - ImplItemKind::Existential(ref bounds) => { + ImplItemKind::OpaqueTy(ref bounds) => { visitor.visit_id(impl_item.hir_id); walk_list!(visitor, visit_param_bound, bounds); } @@ -1026,11 +1033,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { ExprKind::DropTemps(ref subexpression) => { visitor.visit_expr(subexpression); } - ExprKind::While(ref subexpression, ref block, ref opt_label) => { - walk_list!(visitor, visit_label, opt_label); - visitor.visit_expr(subexpression); - visitor.visit_block(block); - } ExprKind::Loop(ref block, ref opt_label, _) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 9c4a208f0f..fe69c9e634 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -32,13 +32,17 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. +mod expr; +mod item; + use crate::dep_graph::DepGraph; use crate::hir::{self, ParamName}; use crate::hir::HirVec; use crate::hir::map::{DefKey, DefPathData, Definitions}; use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; -use crate::hir::def::{Res, DefKind, PartialRes, PerNS}; +use crate::hir::def::{Namespace, Res, DefKind, PartialRes, PerNS}; use crate::hir::{GenericArg, ConstArg}; +use crate::hir::ptr::P; use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, ELIDED_LIFETIMES_IN_PATHS}; use crate::middle::cstore::CrateStore; @@ -52,19 +56,18 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::sync::Lrc; -use std::collections::{BTreeSet, BTreeMap}; +use std::collections::BTreeMap; use std::mem; use smallvec::SmallVec; use syntax::attr; use syntax::ast; +use syntax::ptr::P as AstP; use syntax::ast::*; use syntax::errors; -use syntax::ext::hygiene::{Mark, SyntaxContext}; +use syntax::ext::base::SpecialDerives; +use syntax::ext::hygiene::ExpnId; use syntax::print::pprust; -use syntax::ptr::P; -use syntax::source_map::{self, respan, ExpnInfo, CompilerDesugaringKind, Spanned}; -use syntax::source_map::CompilerDesugaringKind::IfTemporary; -use syntax::std_inject; +use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned}; use syntax::symbol::{kw, sym, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::parse::token::{self, Token}; @@ -90,6 +93,7 @@ pub struct LoweringContext<'a> { impl_items: BTreeMap, bodies: BTreeMap, exported_macros: Vec, + non_exported_macro_attrs: Vec, trait_impls: BTreeMap>, @@ -147,13 +151,6 @@ pub struct LoweringContext<'a> { } pub trait Resolver { - /// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc. - fn resolve_ast_path( - &mut self, - path: &ast::Path, - is_value: bool, - ) -> Res; - /// Obtain resolution for a `NodeId` with a single resolution. fn get_partial_res(&mut self, id: NodeId) -> Option; @@ -174,8 +171,10 @@ pub trait Resolver { span: Span, crate_root: Option, components: &[Symbol], - is_value: bool, + ns: Namespace, ) -> (ast::Path, Res); + + fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool; } /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, @@ -189,14 +188,14 @@ enum ImplTraitContext<'a> { /// Newly generated parameters should be inserted into the given `Vec`. Universal(&'a mut Vec), - /// Treat `impl Trait` as shorthand for a new existential parameter. + /// Treat `impl Trait` as shorthand for a new opaque type. /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually - /// equivalent to a fresh existential parameter like `existential type T; fn foo() -> T`. + /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`. /// /// We optionally store a `DefId` for the parent item here so we can look up necessary /// information later. It is `None` when no information about the context should be stored /// (e.g., for consts and statics). - Existential(Option /* fn def-ID */), + OpaqueTy(Option /* fn def-ID */), /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), @@ -222,7 +221,7 @@ impl<'a> ImplTraitContext<'a> { use self::ImplTraitContext::*; match self { Universal(params) => Universal(params), - Existential(fn_def_id) => Existential(*fn_def_id), + OpaqueTy(fn_def_id) => OpaqueTy(*fn_def_id), Disallowed(pos) => Disallowed(*pos), } } @@ -241,7 +240,7 @@ pub fn lower_crate( dep_graph.assert_ignored(); LoweringContext { - crate_root: std_inject::injected_crate_name().map(Symbol::intern), + crate_root: sess.parse_sess.injected_crate_name.try_get().copied(), sess, cstore, resolver, @@ -252,6 +251,7 @@ pub fn lower_crate( trait_impls: BTreeMap::new(), modules: BTreeMap::new(), exported_macros: Vec::new(), + non_exported_macro_attrs: Vec::new(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), is_in_loop_condition: false, @@ -436,7 +436,7 @@ impl<'a> LoweringContext<'a> { owner, id, DefPathData::Misc, - Mark::root(), + ExpnId::root(), tree.prefix.span, ); self.lctx.allocate_hir_id_counter(id); @@ -467,7 +467,7 @@ impl<'a> LoweringContext<'a> { fn visit_pat(&mut self, p: &'tcx Pat) { match p.node { // Doesn't generate a HIR node - PatKind::Paren(..) => {}, + PatKind::Paren(..) | PatKind::Rest => {}, _ => { if let Some(owner) = self.hir_id_owner { self.lctx.lower_node_id_with_owner(p.id, owner); @@ -485,8 +485,8 @@ impl<'a> LoweringContext<'a> { ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) | ItemKind::Enum(_, ref generics) - | ItemKind::Ty(_, ref generics) - | ItemKind::Existential(_, ref generics) + | ItemKind::TyAlias(_, ref generics) + | ItemKind::OpaqueTy(_, ref generics) | ItemKind::Trait(_, _, ref generics, ..) => { let def_id = self.lctx.resolver.definitions().local_def_id(item.id); let count = generics @@ -564,90 +564,11 @@ impl<'a> LoweringContext<'a> { } } - struct ItemLowerer<'tcx, 'interner> { - lctx: &'tcx mut LoweringContext<'interner>, - } - - impl<'tcx, 'interner> ItemLowerer<'tcx, 'interner> { - fn with_trait_impl_ref(&mut self, trait_impl_ref: &Option, f: F) - where - F: FnOnce(&mut Self), - { - let old = self.lctx.is_in_trait_impl; - self.lctx.is_in_trait_impl = if let &None = trait_impl_ref { - false - } else { - true - }; - f(self); - self.lctx.is_in_trait_impl = old; - } - } - - impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> { - fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) { - self.lctx.modules.insert(n, hir::ModuleItems { - items: BTreeSet::new(), - trait_items: BTreeSet::new(), - impl_items: BTreeSet::new(), - }); - - let old = self.lctx.current_module; - self.lctx.current_module = n; - visit::walk_mod(self, m); - self.lctx.current_module = old; - } - - fn visit_item(&mut self, item: &'tcx Item) { - let mut item_hir_id = None; - self.lctx.with_hir_id_owner(item.id, |lctx| { - if let Some(hir_item) = lctx.lower_item(item) { - item_hir_id = Some(hir_item.hir_id); - lctx.insert_item(hir_item); - } - }); - - if let Some(hir_id) = item_hir_id { - self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { - let this = &mut ItemLowerer { lctx: this }; - if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node { - this.with_trait_impl_ref(opt_trait_ref, |this| { - visit::walk_item(this, item) - }); - } else { - visit::walk_item(this, item); - } - }); - } - } - - fn visit_trait_item(&mut self, item: &'tcx TraitItem) { - self.lctx.with_hir_id_owner(item.id, |lctx| { - let hir_item = lctx.lower_trait_item(item); - let id = hir::TraitItemId { hir_id: hir_item.hir_id }; - lctx.trait_items.insert(id, hir_item); - lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id); - }); - - visit::walk_trait_item(self, item); - } - - fn visit_impl_item(&mut self, item: &'tcx ImplItem) { - self.lctx.with_hir_id_owner(item.id, |lctx| { - let hir_item = lctx.lower_impl_item(item); - let id = hir::ImplItemId { hir_id: hir_item.hir_id }; - lctx.impl_items.insert(id, hir_item); - lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id); - }); - visit::walk_impl_item(self, item); - } - } - self.lower_node_id(CRATE_NODE_ID); debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID); visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c); - visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c); + visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c); let module = self.lower_mod(&c.module); let attrs = self.lower_attrs(&c.attrs); @@ -662,6 +583,7 @@ impl<'a> LoweringContext<'a> { attrs, span: c.span, exported_macros: hir::HirVec::from(self.exported_macros), + non_exported_macro_attrs: hir::HirVec::from(self.non_exported_macro_attrs), items: self.items, trait_items: self.trait_items, impl_items: self.impl_items, @@ -785,57 +707,6 @@ impl<'a> LoweringContext<'a> { }) } - fn generator_movability_for_fn( - &mut self, - decl: &ast::FnDecl, - fn_decl_span: Span, - generator_kind: Option, - movability: Movability, - ) -> Option { - match generator_kind { - Some(hir::GeneratorKind::Gen) => { - if !decl.inputs.is_empty() { - span_err!( - self.sess, - fn_decl_span, - E0628, - "generators cannot have explicit arguments" - ); - self.sess.abort_if_errors(); - } - Some(match movability { - Movability::Movable => hir::GeneratorMovability::Movable, - Movability::Static => hir::GeneratorMovability::Static, - }) - }, - Some(hir::GeneratorKind::Async) => { - bug!("non-`async` closure body turned `async` during lowering"); - }, - None => { - if movability == Movability::Static { - span_err!( - self.sess, - fn_decl_span, - E0697, - "closures cannot be static" - ); - } - None - }, - } - } - - fn record_body(&mut self, arguments: HirVec, value: hir::Expr) -> hir::BodyId { - let body = hir::Body { - generator_kind: self.generator_kind, - arguments, - value, - }; - let id = body.id(); - self.bodies.insert(id, body); - id - } - fn next_id(&mut self) -> hir::HirId { self.lower_node_id(self.sess.next_node_id()) } @@ -869,17 +740,15 @@ impl<'a> LoweringContext<'a> { /// allowed inside this span. fn mark_span_with_reason( &self, - reason: CompilerDesugaringKind, + reason: DesugaringKind, span: Span, allow_internal_unstable: Option>, ) -> Span { - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo { - def_site: Some(span), + span.fresh_expansion(ExpnId::root(), ExpnInfo { + def_site: span, allow_internal_unstable, - ..ExpnInfo::default(source_map::CompilerDesugaring(reason), span, self.sess.edition()) - }); - span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) + ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) + }) } fn with_anonymous_lifetime_mode( @@ -968,7 +837,7 @@ impl<'a> LoweringContext<'a> { parent_index, node_id, DefPathData::LifetimeNs(str_name), - Mark::root(), + ExpnId::root(), span, ); @@ -1041,38 +910,6 @@ impl<'a> LoweringContext<'a> { res } - // Same as the method above, but accepts `hir::GenericParam`s - // instead of `ast::GenericParam`s. - // This should only be used with generics that have already had their - // in-band lifetimes added. In practice, this means that this function is - // only used when lowering a child item of a trait or impl. - fn with_parent_item_lifetime_defs(&mut self, - parent_hir_id: hir::HirId, - f: F - ) -> T where - F: FnOnce(&mut LoweringContext<'_>) -> T, - { - let old_len = self.in_scope_lifetimes.len(); - - let parent_generics = match self.items.get(&parent_hir_id).unwrap().node { - hir::ItemKind::Impl(_, _, _, ref generics, ..) - | hir::ItemKind::Trait(_, _, ref generics, ..) => { - &generics.params[..] - } - _ => &[], - }; - let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind { - hir::GenericParamKind::Lifetime { .. } => Some(param.name.ident().modern()), - _ => None, - }); - self.in_scope_lifetimes.extend(lt_def_names); - - let res = f(self); - - self.in_scope_lifetimes.truncate(old_len); - res - } - /// Appends in-band lifetime defs and argument-position `impl /// Trait` defs to the existing set of generics. /// @@ -1111,7 +948,7 @@ impl<'a> LoweringContext<'a> { }, ); - lowered_generics.params = lowered_generics + let mut lowered_params: Vec<_> = lowered_generics .params .into_iter() .chain(in_band_defs) @@ -1121,7 +958,7 @@ impl<'a> LoweringContext<'a> { // unsorted generic parameters at the moment, so we make sure // that they're ordered correctly here for now. (When we chain // the `in_band_defs`, we might make the order unsorted.) - lowered_generics.params.sort_by_key(|param| { + lowered_params.sort_by_key(|param| { match param.kind { hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime, hir::GenericParamKind::Type { .. } => ParamKindOrd::Type, @@ -1129,132 +966,9 @@ impl<'a> LoweringContext<'a> { } }); - (lowered_generics, res) - } - - fn with_catch_scope(&mut self, catch_id: NodeId, f: F) -> T - where - F: FnOnce(&mut LoweringContext<'_>) -> T, - { - let len = self.catch_scopes.len(); - self.catch_scopes.push(catch_id); - - let result = f(self); - assert_eq!( - len + 1, - self.catch_scopes.len(), - "catch scopes should be added and removed in stack order" - ); - - self.catch_scopes.pop().unwrap(); - - result - } - - fn make_async_expr( - &mut self, - capture_clause: CaptureBy, - closure_node_id: NodeId, - ret_ty: Option<&Ty>, - span: Span, - body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr, - ) -> hir::ExprKind { - let capture_clause = self.lower_capture_clause(capture_clause); - let output = match ret_ty { - Some(ty) => FunctionRetTy::Ty(P(ty.clone())), - None => FunctionRetTy::Default(span), - }; - let ast_decl = FnDecl { - inputs: vec![], - output, - c_variadic: false - }; - let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None); - let body_id = self.lower_fn_body(&ast_decl, |this| { - this.generator_kind = Some(hir::GeneratorKind::Async); - body(this) - }); - let generator = hir::Expr { - hir_id: self.lower_node_id(closure_node_id), - node: hir::ExprKind::Closure(capture_clause, decl, body_id, span, - Some(hir::GeneratorMovability::Static)), - span, - attrs: ThinVec::new(), - }; - - let unstable_span = self.mark_span_with_reason( - CompilerDesugaringKind::Async, - span, - self.allow_gen_future.clone(), - ); - let gen_future = self.expr_std_path( - unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new()); - hir::ExprKind::Call(P(gen_future), hir_vec![generator]) - } - - fn lower_body( - &mut self, - f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec, hir::Expr), - ) -> hir::BodyId { - let prev_gen_kind = self.generator_kind.take(); - let (arguments, result) = f(self); - let body_id = self.record_body(arguments, result); - self.generator_kind = prev_gen_kind; - body_id - } - - fn lower_fn_body( - &mut self, - decl: &FnDecl, - body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr, - ) -> hir::BodyId { - self.lower_body(|this| ( - decl.inputs.iter().map(|x| this.lower_arg(x)).collect(), - body(this), - )) - } - - fn lower_const_body(&mut self, expr: &Expr) -> hir::BodyId { - self.lower_body(|this| (hir_vec![], this.lower_expr(expr))) - } - - fn with_loop_scope(&mut self, loop_id: NodeId, f: F) -> T - where - F: FnOnce(&mut LoweringContext<'_>) -> T, - { - // We're no longer in the base loop's condition; we're in another loop. - let was_in_loop_condition = self.is_in_loop_condition; - self.is_in_loop_condition = false; - - let len = self.loop_scopes.len(); - self.loop_scopes.push(loop_id); - - let result = f(self); - assert_eq!( - len + 1, - self.loop_scopes.len(), - "loop scopes should be added and removed in stack order" - ); - - self.loop_scopes.pop().unwrap(); - - self.is_in_loop_condition = was_in_loop_condition; - - result - } - - fn with_loop_condition_scope(&mut self, f: F) -> T - where - F: FnOnce(&mut LoweringContext<'_>) -> T, - { - let was_in_loop_condition = self.is_in_loop_condition; - self.is_in_loop_condition = true; - - let result = f(self); - - self.is_in_loop_condition = was_in_loop_condition; + lowered_generics.params = lowered_params.into(); - result + (lowered_generics, res) } fn with_dyn_type_scope(&mut self, in_scope: bool, f: F) -> T @@ -1278,8 +992,8 @@ impl<'a> LoweringContext<'a> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new()); - let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new()); + let catch_scopes = mem::take(&mut self.catch_scopes); + let loop_scopes = mem::take(&mut self.loop_scopes); let ret = f(self); self.catch_scopes = catch_scopes; self.loop_scopes = loop_scopes; @@ -1297,43 +1011,17 @@ impl<'a> LoweringContext<'a> { } } - fn lower_label(&mut self, label: Option, D}` Enum(EnumDef, Generics), /// A struct definition, e.g., `struct Foo {x: A}` Struct(VariantData, Generics), /// A union definition, e.g., `union Foo {x: A, y: B}` Union(VariantData, Generics), - /// Represents a Trait Declaration + /// A trait definition Trait(IsAuto, Unsafety, Generics, GenericBounds, HirVec), - /// Represents a Trait Alias Declaration + /// A trait alias TraitAlias(Generics, GenericBounds), /// An implementation, eg `impl Trait for Foo { .. }` @@ -2439,8 +2455,8 @@ impl ItemKind { ItemKind::Mod(..) => "module", ItemKind::ForeignMod(..) => "foreign module", ItemKind::GlobalAsm(..) => "global asm", - ItemKind::Ty(..) => "type alias", - ItemKind::Existential(..) => "existential type", + ItemKind::TyAlias(..) => "type alias", + ItemKind::OpaqueTy(..) => "opaque type", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", ItemKind::Union(..) => "union", @@ -2462,8 +2478,8 @@ impl ItemKind { pub fn generics(&self) -> Option<&Generics> { Some(match *self { ItemKind::Fn(_, _, ref generics, _) | - ItemKind::Ty(_, ref generics) | - ItemKind::Existential(ExistTy { ref generics, impl_trait_fn: None, .. }) | + ItemKind::TyAlias(_, ref generics) | + ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) | ItemKind::Enum(_, ref generics) | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) | @@ -2512,7 +2528,7 @@ pub enum AssocItemKind { Const, Method { has_self: bool }, Type, - Existential, + OpaqueTy, } #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] @@ -2687,6 +2703,7 @@ impl CodegenFnAttrs { #[derive(Copy, Clone, Debug)] pub enum Node<'hir> { + Arg(&'hir Arg), Item(&'hir Item), ForeignItem(&'hir ForeignItem), TraitItem(&'hir TraitItem), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 8b1984e04f..11ba512053 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -2,11 +2,9 @@ use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::source_map::{SourceMap, Spanned}; use syntax::parse::ParseSess; -use syntax::parse::lexer::comments; use syntax::print::pp::{self, Breaks}; use syntax::print::pp::Breaks::{Consistent, Inconsistent}; -use syntax::print::pprust::{self, PrintState}; -use syntax::ptr::P; +use syntax::print::pprust::{self, Comments, PrintState}; use syntax::symbol::kw; use syntax::util::parser::{self, AssocOp, Fixity}; use syntax_pos::{self, BytePos, FileName}; @@ -14,10 +12,10 @@ use syntax_pos::{self, BytePos, FileName}; use crate::hir; use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; use crate::hir::{GenericParam, GenericParamKind, GenericArg}; +use crate::hir::ptr::P; use std::borrow::Cow; use std::cell::Cell; -use std::io::{self, Write, Read}; use std::vec; pub enum AnnNode<'a> { @@ -27,6 +25,7 @@ pub enum AnnNode<'a> { SubItem(hir::HirId), Expr(&'a hir::Expr), Pat(&'a hir::Pat), + Arm(&'a hir::Arm), } pub enum Nested { @@ -38,14 +37,11 @@ pub enum Nested { } pub trait PpAnn { - fn nested(&self, _state: &mut State<'_>, _nested: Nested) -> io::Result<()> { - Ok(()) + fn nested(&self, _state: &mut State<'_>, _nested: Nested) { } - fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> { - Ok(()) + fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { } - fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> { - Ok(()) + fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { } fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item> { None @@ -60,7 +56,7 @@ impl PpAnn for hir::Crate { fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item> { Some(self.item(item)) } - fn nested(&self, state: &mut State<'_>, nested: Nested) -> io::Result<()> { + fn nested(&self, state: &mut State<'_>, nested: Nested) { match nested { Nested::Item(id) => state.print_item(self.item(id.id)), Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)), @@ -72,38 +68,40 @@ impl PpAnn for hir::Crate { } pub struct State<'a> { - pub s: pp::Printer<'a>, - cm: Option<&'a SourceMap>, - comments: Option>, - cur_cmnt: usize, - boxes: Vec, + pub s: pp::Printer, + comments: Option>, ann: &'a (dyn PpAnn + 'a), } -impl<'a> PrintState<'a> for State<'a> { - fn writer(&mut self) -> &mut pp::Printer<'a> { - &mut self.s +impl std::ops::Deref for State<'_> { + type Target = pp::Printer; + fn deref(&self) -> &Self::Target { + &self.s } +} - fn boxes(&mut self) -> &mut Vec { - &mut self.boxes +impl std::ops::DerefMut for State<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.s } +} - fn comments(&mut self) -> &mut Option> { +impl<'a> PrintState<'a> for State<'a> { + fn comments(&mut self) -> &mut Option> { &mut self.comments } - fn cur_cmnt(&mut self) -> &mut usize { - &mut self.cur_cmnt + fn print_ident(&mut self, ident: ast::Ident) { + self.s.word(pprust::ast_ident_to_string(ident, ident.is_raw_guess())); + self.ann.post(self, AnnNode::Name(&ident.name)) + } + + fn print_generic_args(&mut self, args: &ast::GenericArgs, _colons_before_params: bool) { + span_bug!(args.span(), "AST generic args printed by HIR pretty-printer"); } } -#[allow(non_upper_case_globals)] -pub const indent_unit: usize = 4; - -#[allow(non_upper_case_globals)] -pub const default_columns: usize = 78; - +pub const INDENT_UNIT: usize = 4; /// Requires you to pass an input filename and reader so that /// it can scan the input text for comments to copy forward. @@ -111,17 +109,15 @@ pub fn print_crate<'a>(cm: &'a SourceMap, sess: &ParseSess, krate: &hir::Crate, filename: FileName, - input: &mut dyn Read, - out: Box, - ann: &'a dyn PpAnn) - -> io::Result<()> { - let mut s = State::new_from_input(cm, sess, filename, input, out, ann); + input: String, + ann: &'a dyn PpAnn) -> String { + let mut s = State::new_from_input(cm, sess, filename, input, ann); // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. - s.print_mod(&krate.module, &krate.attrs)?; - s.print_remaining_comments()?; + s.print_mod(&krate.module, &krate.attrs); + s.print_remaining_comments(); s.s.eof() } @@ -129,127 +125,91 @@ impl<'a> State<'a> { pub fn new_from_input(cm: &'a SourceMap, sess: &ParseSess, filename: FileName, - input: &mut dyn Read, - out: Box, + input: String, ann: &'a dyn PpAnn) -> State<'a> { - let comments = comments::gather_comments(sess, filename, input); - State::new(cm, out, ann, Some(comments)) - } - - pub fn new(cm: &'a SourceMap, - out: Box, - ann: &'a dyn PpAnn, - comments: Option>) - -> State<'a> { State { - s: pp::mk_printer(out, default_columns), - cm: Some(cm), - comments, - cur_cmnt: 0, - boxes: Vec::new(), + s: pp::mk_printer(), + comments: Some(Comments::new(cm, sess, filename, input)), ann, } } } pub fn to_string(ann: &dyn PpAnn, f: F) -> String - where F: FnOnce(&mut State<'_>) -> io::Result<()> + where F: FnOnce(&mut State<'_>) { - let mut wr = Vec::new(); - { - let mut printer = State { - s: pp::mk_printer(Box::new(&mut wr), default_columns), - cm: None, - comments: None, - cur_cmnt: 0, - boxes: Vec::new(), - ann, - }; - f(&mut printer).unwrap(); - printer.s.eof().unwrap(); - } - String::from_utf8(wr).unwrap() + let mut printer = State { + s: pp::mk_printer(), + comments: None, + ann, + }; + f(&mut printer); + printer.s.eof() } pub fn visibility_qualified>>(vis: &hir::Visibility, w: S) -> String { to_string(NO_ANN, |s| { - s.print_visibility(vis)?; + s.print_visibility(vis); s.s.word(w) }) } impl<'a> State<'a> { - pub fn cbox(&mut self, u: usize) -> io::Result<()> { - self.boxes.push(pp::Breaks::Consistent); - self.s.cbox(u) + pub fn cbox(&mut self, u: usize) { + self.s.cbox(u); } - pub fn nbsp(&mut self) -> io::Result<()> { + pub fn nbsp(&mut self) { self.s.word(" ") } - pub fn word_nbsp>>(&mut self, w: S) -> io::Result<()> { - self.s.word(w)?; + pub fn word_nbsp>>(&mut self, w: S) { + self.s.word(w); self.nbsp() } - pub fn head>>(&mut self, w: S) -> io::Result<()> { + pub fn head>>(&mut self, w: S) { let w = w.into(); // outer-box is consistent - self.cbox(indent_unit)?; + self.cbox(INDENT_UNIT); // head-box is inconsistent - self.ibox(w.len() + 1)?; + self.ibox(w.len() + 1); // keyword that starts the head if !w.is_empty() { - self.word_nbsp(w)?; + self.word_nbsp(w); } - Ok(()) } - pub fn bopen(&mut self) -> io::Result<()> { - self.s.word("{")?; - self.end() // close the head-box - } - - pub fn bclose_(&mut self, span: syntax_pos::Span, indented: usize) -> io::Result<()> { - self.bclose_maybe_open(span, indented, true) + pub fn bopen(&mut self) { + self.s.word("{"); + self.end(); // close the head-box } pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span, - indented: usize, close_box: bool) - -> io::Result<()> { - self.maybe_print_comment(span.hi())?; - self.break_offset_if_not_bol(1, -(indented as isize))?; - self.s.word("}")?; + { + self.maybe_print_comment(span.hi()); + self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize)); + self.s.word("}"); if close_box { - self.end()?; // close the outer-box + self.end(); // close the outer-box } - Ok(()) } - pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> { - self.bclose_(span, indent_unit) + pub fn bclose(&mut self, span: syntax_pos::Span) { + self.bclose_maybe_open(span, true) } - pub fn in_cbox(&self) -> bool { - match self.boxes.last() { - Some(&last_box) => last_box == pp::Breaks::Consistent, - None => false, + pub fn space_if_not_bol(&mut self) { + if !self.s.is_beginning_of_line() { + self.s.space(); } } - pub fn space_if_not_bol(&mut self) -> io::Result<()> { - if !self.is_bol() { - self.s.space()?; - } - Ok(()) - } - - pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()> { - if !self.is_bol() { + pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) { + if !self.s.is_beginning_of_line() { self.s.break_offset(n, off) } else { if off != 0 && self.s.last_token().is_hardbreak_tok() { @@ -258,17 +218,16 @@ impl<'a> State<'a> { // break into the previous hardbreak. self.s.replace_last_token(pp::Printer::hardbreak_tok_offset(off)); } - Ok(()) } } // Synthesizes a comment that was not textually present in the original source // file. - pub fn synth_comment(&mut self, text: String) -> io::Result<()> { - self.s.word("/*")?; - self.s.space()?; - self.s.word(text)?; - self.s.space()?; + pub fn synth_comment(&mut self, text: String) { + self.s.word("/*"); + self.s.space(); + self.s.word(text); + self.s.space(); self.s.word("*/") } @@ -277,97 +236,93 @@ impl<'a> State<'a> { elts: &[T], mut op: F, mut get_span: G) - -> io::Result<()> - where F: FnMut(&mut State<'_>, &T) -> io::Result<()>, + where F: FnMut(&mut State<'_>, &T), G: FnMut(&T) -> syntax_pos::Span { - self.rbox(0, b)?; + self.rbox(0, b); let len = elts.len(); let mut i = 0; for elt in elts { - self.maybe_print_comment(get_span(elt).hi())?; - op(self, elt)?; + self.maybe_print_comment(get_span(elt).hi()); + op(self, elt); i += 1; if i < len { - self.s.word(",")?; - self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi()))?; - self.space_if_not_bol()?; + self.s.word(","); + self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi())); + self.space_if_not_bol(); } } - self.end() + self.end(); } - pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) -> io::Result<()> { + pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span) } - pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { - self.print_inner_attributes(attrs)?; + pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) { + self.print_inner_attributes(attrs); for &item_id in &_mod.item_ids { - self.ann.nested(self, Nested::Item(item_id))?; + self.ann.nested(self, Nested::Item(item_id)); } - Ok(()) } pub fn print_foreign_mod(&mut self, nmod: &hir::ForeignMod, attrs: &[ast::Attribute]) - -> io::Result<()> { - self.print_inner_attributes(attrs)?; + { + self.print_inner_attributes(attrs); for item in &nmod.items { - self.print_foreign_item(item)?; + self.print_foreign_item(item); } - Ok(()) } - pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { + pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) { if !lifetime.is_elided() { - self.print_lifetime(lifetime)?; - self.nbsp()?; + self.print_lifetime(lifetime); + self.nbsp(); } - Ok(()) } - pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> { - self.maybe_print_comment(ty.span.lo())?; - self.ibox(0)?; + pub fn print_type(&mut self, ty: &hir::Ty) { + self.maybe_print_comment(ty.span.lo()); + self.ibox(0); match ty.node { hir::TyKind::Slice(ref ty) => { - self.s.word("[")?; - self.print_type(&ty)?; - self.s.word("]")?; + self.s.word("["); + self.print_type(&ty); + self.s.word("]"); } hir::TyKind::Ptr(ref mt) => { - self.s.word("*")?; + self.s.word("*"); match mt.mutbl { - hir::MutMutable => self.word_nbsp("mut")?, - hir::MutImmutable => self.word_nbsp("const")?, + hir::MutMutable => self.word_nbsp("mut"), + hir::MutImmutable => self.word_nbsp("const"), } - self.print_type(&mt.ty)?; + self.print_type(&mt.ty); } hir::TyKind::Rptr(ref lifetime, ref mt) => { - self.s.word("&")?; - self.print_opt_lifetime(lifetime)?; - self.print_mt(mt)?; + self.s.word("&"); + self.print_opt_lifetime(lifetime); + self.print_mt(mt); } hir::TyKind::Never => { - self.s.word("!")?; + self.s.word("!"); }, hir::TyKind::Tup(ref elts) => { - self.popen()?; - self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?; + self.popen(); + self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty)); if elts.len() == 1 { - self.s.word(",")?; + self.s.word(","); } - self.pclose()?; + self.pclose(); } hir::TyKind::BareFn(ref f) => { self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &f.generic_params, - &f.arg_names[..])?; + &f.arg_names[..]); } hir::TyKind::Def(..) => {}, hir::TyKind::Path(ref qpath) => { - self.print_qpath(qpath, false)? + self.print_qpath(qpath, false) } hir::TyKind::TraitObject(ref bounds, ref lifetime) => { let mut first = true; @@ -375,51 +330,51 @@ impl<'a> State<'a> { if first { first = false; } else { - self.nbsp()?; - self.word_space("+")?; + self.nbsp(); + self.word_space("+"); } - self.print_poly_trait_ref(bound)?; + self.print_poly_trait_ref(bound); } if !lifetime.is_elided() { - self.nbsp()?; - self.word_space("+")?; - self.print_lifetime(lifetime)?; + self.nbsp(); + self.word_space("+"); + self.print_lifetime(lifetime); } } hir::TyKind::Array(ref ty, ref length) => { - self.s.word("[")?; - self.print_type(&ty)?; - self.s.word("; ")?; - self.print_anon_const(length)?; - self.s.word("]")?; + self.s.word("["); + self.print_type(&ty); + self.s.word("; "); + self.print_anon_const(length); + self.s.word("]"); } hir::TyKind::Typeof(ref e) => { - self.s.word("typeof(")?; - self.print_anon_const(e)?; - self.s.word(")")?; + self.s.word("typeof("); + self.print_anon_const(e); + self.s.word(")"); } hir::TyKind::Infer => { - self.s.word("_")?; + self.s.word("_"); } hir::TyKind::Err => { - self.popen()?; - self.s.word("/*ERROR*/")?; - self.pclose()?; + self.popen(); + self.s.word("/*ERROR*/"); + self.pclose(); } hir::TyKind::CVarArgs(_) => { - self.s.word("...")?; + self.s.word("..."); } } self.end() } - pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(item.span.lo())?; - self.print_outer_attributes(&item.attrs)?; + pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) { + self.hardbreak_if_not_bol(); + self.maybe_print_comment(item.span.lo()); + self.print_outer_attributes(&item.attrs); match item.node { hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => { - self.head("")?; + self.head(""); self.print_fn(decl, hir::FnHeader { unsafety: hir::Unsafety::Normal, @@ -431,28 +386,28 @@ impl<'a> State<'a> { generics, &item.vis, arg_names, - None)?; - self.end()?; // end head-ibox - self.s.word(";")?; + None); + self.end(); // end head-ibox + self.s.word(";"); self.end() // end the outer fn box } hir::ForeignItemKind::Static(ref t, m) => { - self.head(visibility_qualified(&item.vis, "static"))?; + self.head(visibility_qualified(&item.vis, "static")); if m == hir::MutMutable { - self.word_space("mut")?; + self.word_space("mut"); } - self.print_ident(item.ident)?; - self.word_space(":")?; - self.print_type(&t)?; - self.s.word(";")?; - self.end()?; // end the head-ibox + self.print_ident(item.ident); + self.word_space(":"); + self.print_type(&t); + self.s.word(";"); + self.end(); // end the head-ibox self.end() // end the outer cbox } hir::ForeignItemKind::Type => { - self.head(visibility_qualified(&item.vis, "type"))?; - self.print_ident(item.ident)?; - self.s.word(";")?; - self.end()?; // end the head-ibox + self.head(visibility_qualified(&item.vis, "type")); + self.print_ident(item.ident); + self.s.word(";"); + self.end(); // end the head-ibox self.end() // end the outer cbox } } @@ -463,16 +418,16 @@ impl<'a> State<'a> { ty: &hir::Ty, default: Option, vis: &hir::Visibility) - -> io::Result<()> { - self.s.word(visibility_qualified(vis, ""))?; - self.word_space("const")?; - self.print_ident(ident)?; - self.word_space(":")?; - self.print_type(ty)?; + { + self.s.word(visibility_qualified(vis, "")); + self.word_space("const"); + self.print_ident(ident); + self.word_space(":"); + self.print_type(ty); if let Some(expr) = default { - self.s.space()?; - self.word_space("=")?; - self.ann.nested(self, Nested::Body(expr))?; + self.s.space(); + self.word_space("="); + self.ann.nested(self, Nested::Body(expr)); } self.s.word(";") } @@ -481,168 +436,171 @@ impl<'a> State<'a> { ident: ast::Ident, bounds: Option<&hir::GenericBounds>, ty: Option<&hir::Ty>) - -> io::Result<()> { - self.word_space("type")?; - self.print_ident(ident)?; + { + self.word_space("type"); + self.print_ident(ident); if let Some(bounds) = bounds { - self.print_bounds(":", bounds)?; + self.print_bounds(":", bounds); } if let Some(ty) = ty { - self.s.space()?; - self.word_space("=")?; - self.print_type(ty)?; + self.s.space(); + self.word_space("="); + self.print_type(ty); } self.s.word(";") } + fn print_item_type( + &mut self, + item: &hir::Item, + generics: &hir::Generics, + inner: impl Fn(&mut Self), + ) { + self.head(visibility_qualified(&item.vis, "type")); + self.print_ident(item.ident); + self.print_generic_params(&generics.params); + self.end(); // end the inner ibox + + self.print_where_clause(&generics.where_clause); + self.s.space(); + inner(self); + self.s.word(";"); + self.end(); // end the outer ibox + } + /// Pretty-print an item - pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(item.span.lo())?; - self.print_outer_attributes(&item.attrs)?; - self.ann.pre(self, AnnNode::Item(item))?; + pub fn print_item(&mut self, item: &hir::Item) { + self.hardbreak_if_not_bol(); + self.maybe_print_comment(item.span.lo()); + self.print_outer_attributes(&item.attrs); + self.ann.pre(self, AnnNode::Item(item)); match item.node { hir::ItemKind::ExternCrate(orig_name) => { - self.head(visibility_qualified(&item.vis, "extern crate"))?; + self.head(visibility_qualified(&item.vis, "extern crate")); if let Some(orig_name) = orig_name { - self.print_name(orig_name)?; - self.s.space()?; - self.s.word("as")?; - self.s.space()?; + self.print_name(orig_name); + self.s.space(); + self.s.word("as"); + self.s.space(); } - self.print_ident(item.ident)?; - self.s.word(";")?; - self.end()?; // end inner head-block - self.end()?; // end outer head-block + self.print_ident(item.ident); + self.s.word(";"); + self.end(); // end inner head-block + self.end(); // end outer head-block } hir::ItemKind::Use(ref path, kind) => { - self.head(visibility_qualified(&item.vis, "use"))?; - self.print_path(path, false)?; + self.head(visibility_qualified(&item.vis, "use")); + self.print_path(path, false); match kind { hir::UseKind::Single => { if path.segments.last().unwrap().ident != item.ident { - self.s.space()?; - self.word_space("as")?; - self.print_ident(item.ident)?; + self.s.space(); + self.word_space("as"); + self.print_ident(item.ident); } - self.s.word(";")?; + self.s.word(";"); } - hir::UseKind::Glob => self.s.word("::*;")?, - hir::UseKind::ListStem => self.s.word("::{};")? + hir::UseKind::Glob => self.s.word("::*;"), + hir::UseKind::ListStem => self.s.word("::{};") } - self.end()?; // end inner head-block - self.end()?; // end outer head-block + self.end(); // end inner head-block + self.end(); // end outer head-block } hir::ItemKind::Static(ref ty, m, expr) => { - self.head(visibility_qualified(&item.vis, "static"))?; + self.head(visibility_qualified(&item.vis, "static")); if m == hir::MutMutable { - self.word_space("mut")?; + self.word_space("mut"); } - self.print_ident(item.ident)?; - self.word_space(":")?; - self.print_type(&ty)?; - self.s.space()?; - self.end()?; // end the head-ibox + self.print_ident(item.ident); + self.word_space(":"); + self.print_type(&ty); + self.s.space(); + self.end(); // end the head-ibox - self.word_space("=")?; - self.ann.nested(self, Nested::Body(expr))?; - self.s.word(";")?; - self.end()?; // end the outer cbox + self.word_space("="); + self.ann.nested(self, Nested::Body(expr)); + self.s.word(";"); + self.end(); // end the outer cbox } hir::ItemKind::Const(ref ty, expr) => { - self.head(visibility_qualified(&item.vis, "const"))?; - self.print_ident(item.ident)?; - self.word_space(":")?; - self.print_type(&ty)?; - self.s.space()?; - self.end()?; // end the head-ibox - - self.word_space("=")?; - self.ann.nested(self, Nested::Body(expr))?; - self.s.word(";")?; - self.end()?; // end the outer cbox + self.head(visibility_qualified(&item.vis, "const")); + self.print_ident(item.ident); + self.word_space(":"); + self.print_type(&ty); + self.s.space(); + self.end(); // end the head-ibox + + self.word_space("="); + self.ann.nested(self, Nested::Body(expr)); + self.s.word(";"); + self.end(); // end the outer cbox } hir::ItemKind::Fn(ref decl, header, ref param_names, body) => { - self.head("")?; + self.head(""); self.print_fn(decl, header, Some(item.ident.name), param_names, &item.vis, &[], - Some(body))?; - self.s.word(" ")?; - self.end()?; // need to close a box - self.end()?; // need to close a box - self.ann.nested(self, Nested::Body(body))?; + Some(body)); + self.s.word(" "); + self.end(); // need to close a box + self.end(); // need to close a box + self.ann.nested(self, Nested::Body(body)); } hir::ItemKind::Mod(ref _mod) => { - self.head(visibility_qualified(&item.vis, "mod"))?; - self.print_ident(item.ident)?; - self.nbsp()?; - self.bopen()?; - self.print_mod(_mod, &item.attrs)?; - self.bclose(item.span)?; + self.head(visibility_qualified(&item.vis, "mod")); + self.print_ident(item.ident); + self.nbsp(); + self.bopen(); + self.print_mod(_mod, &item.attrs); + self.bclose(item.span); } hir::ItemKind::ForeignMod(ref nmod) => { - self.head("extern")?; - self.word_nbsp(nmod.abi.to_string())?; - self.bopen()?; - self.print_foreign_mod(nmod, &item.attrs)?; - self.bclose(item.span)?; + self.head("extern"); + self.word_nbsp(nmod.abi.to_string()); + self.bopen(); + self.print_foreign_mod(nmod, &item.attrs); + self.bclose(item.span); } hir::ItemKind::GlobalAsm(ref ga) => { - self.head(visibility_qualified(&item.vis, "global asm"))?; - self.s.word(ga.asm.as_str().to_string())?; - self.end()? - } - hir::ItemKind::Ty(ref ty, ref generics) => { - self.head(visibility_qualified(&item.vis, "type"))?; - self.print_ident(item.ident)?; - self.print_generic_params(&generics.params)?; - self.end()?; // end the inner ibox - - self.print_where_clause(&generics.where_clause)?; - self.s.space()?; - self.word_space("=")?; - self.print_type(&ty)?; - self.s.word(";")?; - self.end()?; // end the outer ibox - } - hir::ItemKind::Existential(ref exist) => { - self.head(visibility_qualified(&item.vis, "existential type"))?; - self.print_ident(item.ident)?; - self.print_generic_params(&exist.generics.params)?; - self.end()?; // end the inner ibox - - self.print_where_clause(&exist.generics.where_clause)?; - self.s.space()?; - let mut real_bounds = Vec::with_capacity(exist.bounds.len()); - for b in exist.bounds.iter() { - if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b { - self.s.space()?; - self.word_space("for ?")?; - self.print_trait_ref(&ptr.trait_ref)?; - } else { - real_bounds.push(b); + self.head(visibility_qualified(&item.vis, "global asm")); + self.s.word(ga.asm.as_str().to_string()); + self.end() + } + hir::ItemKind::TyAlias(ref ty, ref generics) => { + self.print_item_type(item, &generics, |state| { + state.word_space("="); + state.print_type(&ty); + }); + } + hir::ItemKind::OpaqueTy(ref opaque_ty) => { + self.print_item_type(item, &opaque_ty.generics, |state| { + let mut real_bounds = Vec::with_capacity(opaque_ty.bounds.len()); + for b in opaque_ty.bounds.iter() { + if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b { + state.s.space(); + state.word_space("for ?"); + state.print_trait_ref(&ptr.trait_ref); + } else { + real_bounds.push(b); + } } - } - self.print_bounds(":", real_bounds)?; - self.s.word(";")?; - self.end()?; // end the outer ibox + state.print_bounds("= impl", real_bounds); + }); } hir::ItemKind::Enum(ref enum_definition, ref params) => { - self.print_enum_def(enum_definition, params, item.ident.name, item.span, - &item.vis)?; + self.print_enum_def(enum_definition, params, item.ident.name, item.span, &item.vis); } hir::ItemKind::Struct(ref struct_def, ref generics) => { - self.head(visibility_qualified(&item.vis, "struct"))?; - self.print_struct(struct_def, generics, item.ident.name, item.span, true)?; + self.head(visibility_qualified(&item.vis, "struct")); + self.print_struct(struct_def, generics, item.ident.name, item.span, true); } hir::ItemKind::Union(ref struct_def, ref generics) => { - self.head(visibility_qualified(&item.vis, "union"))?; - self.print_struct(struct_def, generics, item.ident.name, item.span, true)?; + self.head(visibility_qualified(&item.vis, "union")); + self.print_struct(struct_def, generics, item.ident.name, item.span, true); } hir::ItemKind::Impl(unsafety, polarity, @@ -651,109 +609,108 @@ impl<'a> State<'a> { ref opt_trait, ref ty, ref impl_items) => { - self.head("")?; - self.print_visibility(&item.vis)?; - self.print_defaultness(defaultness)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("impl")?; + self.head(""); + self.print_visibility(&item.vis); + self.print_defaultness(defaultness); + self.print_unsafety(unsafety); + self.word_nbsp("impl"); if !generics.params.is_empty() { - self.print_generic_params(&generics.params)?; - self.s.space()?; + self.print_generic_params(&generics.params); + self.s.space(); } if let hir::ImplPolarity::Negative = polarity { - self.s.word("!")?; + self.s.word("!"); } if let Some(ref t) = opt_trait { - self.print_trait_ref(t)?; - self.s.space()?; - self.word_space("for")?; + self.print_trait_ref(t); + self.s.space(); + self.word_space("for"); } - self.print_type(&ty)?; - self.print_where_clause(&generics.where_clause)?; + self.print_type(&ty); + self.print_where_clause(&generics.where_clause); - self.s.space()?; - self.bopen()?; - self.print_inner_attributes(&item.attrs)?; + self.s.space(); + self.bopen(); + self.print_inner_attributes(&item.attrs); for impl_item in impl_items { - self.ann.nested(self, Nested::ImplItem(impl_item.id))?; + self.ann.nested(self, Nested::ImplItem(impl_item.id)); } - self.bclose(item.span)?; + self.bclose(item.span); } hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => { - self.head("")?; - self.print_visibility(&item.vis)?; - self.print_is_auto(is_auto)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("trait")?; - self.print_ident(item.ident)?; - self.print_generic_params(&generics.params)?; + self.head(""); + self.print_visibility(&item.vis); + self.print_is_auto(is_auto); + self.print_unsafety(unsafety); + self.word_nbsp("trait"); + self.print_ident(item.ident); + self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b { - self.s.space()?; - self.word_space("for ?")?; - self.print_trait_ref(&ptr.trait_ref)?; + self.s.space(); + self.word_space("for ?"); + self.print_trait_ref(&ptr.trait_ref); } else { real_bounds.push(b); } } - self.print_bounds(":", real_bounds)?; - self.print_where_clause(&generics.where_clause)?; - self.s.word(" ")?; - self.bopen()?; + self.print_bounds(":", real_bounds); + self.print_where_clause(&generics.where_clause); + self.s.word(" "); + self.bopen(); for trait_item in trait_items { - self.ann.nested(self, Nested::TraitItem(trait_item.id))?; + self.ann.nested(self, Nested::TraitItem(trait_item.id)); } - self.bclose(item.span)?; + self.bclose(item.span); } hir::ItemKind::TraitAlias(ref generics, ref bounds) => { - self.head("")?; - self.print_visibility(&item.vis)?; - self.word_nbsp("trait")?; - self.print_ident(item.ident)?; - self.print_generic_params(&generics.params)?; + self.head(""); + self.print_visibility(&item.vis); + self.word_nbsp("trait"); + self.print_ident(item.ident); + self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); // FIXME(durka) this seems to be some quite outdated syntax for b in bounds.iter() { if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b { - self.s.space()?; - self.word_space("for ?")?; - self.print_trait_ref(&ptr.trait_ref)?; + self.s.space(); + self.word_space("for ?"); + self.print_trait_ref(&ptr.trait_ref); } else { real_bounds.push(b); } } - self.nbsp()?; - self.print_bounds("=", real_bounds)?; - self.print_where_clause(&generics.where_clause)?; - self.s.word(";")?; + self.nbsp(); + self.print_bounds("=", real_bounds); + self.print_where_clause(&generics.where_clause); + self.s.word(";"); } } self.ann.post(self, AnnNode::Item(item)) } - pub fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> { + pub fn print_trait_ref(&mut self, t: &hir::TraitRef) { self.print_path(&t.path, false) } fn print_formal_generic_params( &mut self, generic_params: &[hir::GenericParam] - ) -> io::Result<()> { + ) { if !generic_params.is_empty() { - self.s.word("for")?; - self.print_generic_params(generic_params)?; - self.nbsp()?; + self.s.word("for"); + self.print_generic_params(generic_params); + self.nbsp(); } - Ok(()) } - fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> { - self.print_formal_generic_params(&t.bound_generic_params)?; + fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) { + self.print_formal_generic_params(&t.bound_generic_params); self.print_trait_ref(&t.trait_ref) } @@ -763,63 +720,60 @@ impl<'a> State<'a> { name: ast::Name, span: syntax_pos::Span, visibility: &hir::Visibility) - -> io::Result<()> { - self.head(visibility_qualified(visibility, "enum"))?; - self.print_name(name)?; - self.print_generic_params(&generics.params)?; - self.print_where_clause(&generics.where_clause)?; - self.s.space()?; + { + self.head(visibility_qualified(visibility, "enum")); + self.print_name(name); + self.print_generic_params(&generics.params); + self.print_where_clause(&generics.where_clause); + self.s.space(); self.print_variants(&enum_definition.variants, span) } pub fn print_variants(&mut self, variants: &[hir::Variant], span: syntax_pos::Span) - -> io::Result<()> { - self.bopen()?; + { + self.bopen(); for v in variants { - self.space_if_not_bol()?; - self.maybe_print_comment(v.span.lo())?; - self.print_outer_attributes(&v.node.attrs)?; - self.ibox(indent_unit)?; - self.print_variant(v)?; - self.s.word(",")?; - self.end()?; - self.maybe_print_trailing_comment(v.span, None)?; + self.space_if_not_bol(); + self.maybe_print_comment(v.span.lo()); + self.print_outer_attributes(&v.node.attrs); + self.ibox(INDENT_UNIT); + self.print_variant(v); + self.s.word(","); + self.end(); + self.maybe_print_trailing_comment(v.span, None); } self.bclose(span) } - pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> { + pub fn print_visibility(&mut self, vis: &hir::Visibility) { match vis.node { - hir::VisibilityKind::Public => self.word_nbsp("pub")?, - hir::VisibilityKind::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate")?, - hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)")?, + hir::VisibilityKind::Public => self.word_nbsp("pub"), + hir::VisibilityKind::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate"), + hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)"), hir::VisibilityKind::Restricted { ref path, .. } => { - self.s.word("pub(")?; + self.s.word("pub("); if path.segments.len() == 1 && path.segments[0].ident.name == kw::Super { // Special case: `super` can print like `pub(super)`. - self.s.word("super")?; + self.s.word("super"); } else { // Everything else requires `in` at present. - self.word_nbsp("in")?; - self.print_path(path, false)?; + self.word_nbsp("in"); + self.print_path(path, false); } - self.word_nbsp(")")?; + self.word_nbsp(")"); } hir::VisibilityKind::Inherited => () } - - Ok(()) } - pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> { + pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) { match defaultness { - hir::Defaultness::Default { .. } => self.word_nbsp("default")?, + hir::Defaultness::Default { .. } => self.word_nbsp("default"), hir::Defaultness::Final => (), } - Ok(()) } pub fn print_struct(&mut self, @@ -828,43 +782,43 @@ impl<'a> State<'a> { name: ast::Name, span: syntax_pos::Span, print_finalizer: bool) - -> io::Result<()> { - self.print_name(name)?; - self.print_generic_params(&generics.params)?; + { + self.print_name(name); + self.print_generic_params(&generics.params); match struct_def { hir::VariantData::Tuple(..) | hir::VariantData::Unit(..) => { if let hir::VariantData::Tuple(..) = struct_def { - self.popen()?; + self.popen(); self.commasep(Inconsistent, struct_def.fields(), |s, field| { - s.maybe_print_comment(field.span.lo())?; - s.print_outer_attributes(&field.attrs)?; - s.print_visibility(&field.vis)?; + s.maybe_print_comment(field.span.lo()); + s.print_outer_attributes(&field.attrs); + s.print_visibility(&field.vis); s.print_type(&field.ty) - })?; - self.pclose()?; + }); + self.pclose(); } - self.print_where_clause(&generics.where_clause)?; + self.print_where_clause(&generics.where_clause); if print_finalizer { - self.s.word(";")?; + self.s.word(";"); } - self.end()?; + self.end(); self.end() // close the outer-box } hir::VariantData::Struct(..) => { - self.print_where_clause(&generics.where_clause)?; - self.nbsp()?; - self.bopen()?; - self.hardbreak_if_not_bol()?; + self.print_where_clause(&generics.where_clause); + self.nbsp(); + self.bopen(); + self.hardbreak_if_not_bol(); for field in struct_def.fields() { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(field.span.lo())?; - self.print_outer_attributes(&field.attrs)?; - self.print_visibility(&field.vis)?; - self.print_ident(field.ident)?; - self.word_nbsp(":")?; - self.print_type(&field.ty)?; - self.s.word(",")?; + self.hardbreak_if_not_bol(); + self.maybe_print_comment(field.span.lo()); + self.print_outer_attributes(&field.attrs); + self.print_visibility(&field.vis); + self.print_ident(field.ident); + self.word_nbsp(":"); + self.print_type(&field.ty); + self.s.word(","); } self.bclose(span) @@ -872,16 +826,15 @@ impl<'a> State<'a> { } } - pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> { - self.head("")?; + pub fn print_variant(&mut self, v: &hir::Variant) { + self.head(""); let generics = hir::Generics::empty(); - self.print_struct(&v.node.data, &generics, v.node.ident.name, v.span, false)?; + self.print_struct(&v.node.data, &generics, v.node.ident.name, v.span, false); if let Some(ref d) = v.node.disr_expr { - self.s.space()?; - self.word_space("=")?; - self.print_anon_const(d)?; + self.s.space(); + self.word_space("="); + self.print_anon_const(d); } - Ok(()) } pub fn print_method_sig(&mut self, ident: ast::Ident, @@ -890,7 +843,7 @@ impl<'a> State<'a> { vis: &hir::Visibility, arg_names: &[ast::Ident], body_id: Option) - -> io::Result<()> { + { self.print_fn(&m.decl, m.header, Some(ident.name), @@ -900,67 +853,69 @@ impl<'a> State<'a> { body_id) } - pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> { - self.ann.pre(self, AnnNode::SubItem(ti.hir_id))?; - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(ti.span.lo())?; - self.print_outer_attributes(&ti.attrs)?; + pub fn print_trait_item(&mut self, ti: &hir::TraitItem) { + self.ann.pre(self, AnnNode::SubItem(ti.hir_id)); + self.hardbreak_if_not_bol(); + self.maybe_print_comment(ti.span.lo()); + self.print_outer_attributes(&ti.attrs); match ti.node { hir::TraitItemKind::Const(ref ty, default) => { let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }; - self.print_associated_const(ti.ident, &ty, default, &vis)?; + self.print_associated_const(ti.ident, &ty, default, &vis); } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => { let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }; - self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None)?; - self.s.word(";")?; + self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None); + self.s.word(";"); } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }; - self.head("")?; - self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body))?; - self.nbsp()?; - self.end()?; // need to close a box - self.end()?; // need to close a box - self.ann.nested(self, Nested::Body(body))?; + self.head(""); + self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body)); + self.nbsp(); + self.end(); // need to close a box + self.end(); // need to close a box + self.ann.nested(self, Nested::Body(body)); } hir::TraitItemKind::Type(ref bounds, ref default) => { self.print_associated_type(ti.ident, Some(bounds), - default.as_ref().map(|ty| &**ty))?; + default.as_ref().map(|ty| &**ty)); } } self.ann.post(self, AnnNode::SubItem(ti.hir_id)) } - pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> { - self.ann.pre(self, AnnNode::SubItem(ii.hir_id))?; - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(ii.span.lo())?; - self.print_outer_attributes(&ii.attrs)?; - self.print_defaultness(ii.defaultness)?; + pub fn print_impl_item(&mut self, ii: &hir::ImplItem) { + self.ann.pre(self, AnnNode::SubItem(ii.hir_id)); + self.hardbreak_if_not_bol(); + self.maybe_print_comment(ii.span.lo()); + self.print_outer_attributes(&ii.attrs); + self.print_defaultness(ii.defaultness); match ii.node { hir::ImplItemKind::Const(ref ty, expr) => { - self.print_associated_const(ii.ident, &ty, Some(expr), &ii.vis)?; + self.print_associated_const(ii.ident, &ty, Some(expr), &ii.vis); } hir::ImplItemKind::Method(ref sig, body) => { - self.head("")?; - self.print_method_sig(ii.ident, sig, &ii.generics, &ii.vis, &[], Some(body))?; - self.nbsp()?; - self.end()?; // need to close a box - self.end()?; // need to close a box - self.ann.nested(self, Nested::Body(body))?; + self.head(""); + self.print_method_sig(ii.ident, sig, &ii.generics, &ii.vis, &[], Some(body)); + self.nbsp(); + self.end(); // need to close a box + self.end(); // need to close a box + self.ann.nested(self, Nested::Body(body)); } - hir::ImplItemKind::Type(ref ty) => { - self.print_associated_type(ii.ident, None, Some(ty))?; + hir::ImplItemKind::TyAlias(ref ty) => { + self.print_associated_type(ii.ident, None, Some(ty)); } - hir::ImplItemKind::Existential(ref bounds) => { - self.word_space("existential")?; - self.print_associated_type(ii.ident, Some(bounds), None)?; + hir::ImplItemKind::OpaqueTy(ref bounds) => { + self.word_space("type"); + self.print_ident(ii.ident); + self.print_bounds("= impl", bounds); + self.s.word(";"); } } self.ann.post(self, AnnNode::SubItem(ii.hir_id)) @@ -969,126 +924,117 @@ impl<'a> State<'a> { pub fn print_local( &mut self, init: Option<&hir::Expr>, - decl: impl Fn(&mut Self) -> io::Result<()> - ) -> io::Result<()> { - self.space_if_not_bol()?; - self.ibox(indent_unit)?; - self.word_nbsp("let")?; + decl: impl Fn(&mut Self) + ) { + self.space_if_not_bol(); + self.ibox(INDENT_UNIT); + self.word_nbsp("let"); - self.ibox(indent_unit)?; - decl(self)?; - self.end()?; + self.ibox(INDENT_UNIT); + decl(self); + self.end(); if let Some(ref init) = init { - self.nbsp()?; - self.word_space("=")?; - self.print_expr(&init)?; + self.nbsp(); + self.word_space("="); + self.print_expr(&init); } self.end() } - pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> { - self.maybe_print_comment(st.span.lo())?; + pub fn print_stmt(&mut self, st: &hir::Stmt) { + self.maybe_print_comment(st.span.lo()); match st.node { hir::StmtKind::Local(ref loc) => { - self.print_local(loc.init.deref(), |this| this.print_local_decl(&loc))?; + self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc)); } hir::StmtKind::Item(item) => { - self.ann.nested(self, Nested::Item(item))? + self.ann.nested(self, Nested::Item(item)) } hir::StmtKind::Expr(ref expr) => { - self.space_if_not_bol()?; - self.print_expr(&expr)?; + self.space_if_not_bol(); + self.print_expr(&expr); } hir::StmtKind::Semi(ref expr) => { - self.space_if_not_bol()?; - self.print_expr(&expr)?; - self.s.word(";")?; + self.space_if_not_bol(); + self.print_expr(&expr); + self.s.word(";"); } } if stmt_ends_with_semi(&st.node) { - self.s.word(";")?; + self.s.word(";"); } self.maybe_print_trailing_comment(st.span, None) } - pub fn print_block(&mut self, blk: &hir::Block) -> io::Result<()> { + pub fn print_block(&mut self, blk: &hir::Block) { self.print_block_with_attrs(blk, &[]) } - pub fn print_block_unclosed(&mut self, blk: &hir::Block) -> io::Result<()> { - self.print_block_unclosed_indent(blk, indent_unit) - } - - pub fn print_block_unclosed_indent(&mut self, - blk: &hir::Block, - indented: usize) - -> io::Result<()> { - self.print_block_maybe_unclosed(blk, indented, &[], false) + pub fn print_block_unclosed(&mut self, blk: &hir::Block) { + self.print_block_maybe_unclosed(blk, &[], false) } pub fn print_block_with_attrs(&mut self, blk: &hir::Block, attrs: &[ast::Attribute]) - -> io::Result<()> { - self.print_block_maybe_unclosed(blk, indent_unit, attrs, true) + { + self.print_block_maybe_unclosed(blk, attrs, true) } pub fn print_block_maybe_unclosed(&mut self, blk: &hir::Block, - indented: usize, attrs: &[ast::Attribute], close_box: bool) - -> io::Result<()> { + { match blk.rules { - hir::UnsafeBlock(..) => self.word_space("unsafe")?, - hir::PushUnsafeBlock(..) => self.word_space("push_unsafe")?, - hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?, + hir::UnsafeBlock(..) => self.word_space("unsafe"), + hir::PushUnsafeBlock(..) => self.word_space("push_unsafe"), + hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe"), hir::DefaultBlock => (), } - self.maybe_print_comment(blk.span.lo())?; - self.ann.pre(self, AnnNode::Block(blk))?; - self.bopen()?; + self.maybe_print_comment(blk.span.lo()); + self.ann.pre(self, AnnNode::Block(blk)); + self.bopen(); - self.print_inner_attributes(attrs)?; + self.print_inner_attributes(attrs); for st in &blk.stmts { - self.print_stmt(st)?; + self.print_stmt(st); } if let Some(ref expr) = blk.expr { - self.space_if_not_bol()?; - self.print_expr(&expr)?; - self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()))?; + self.space_if_not_bol(); + self.print_expr(&expr); + self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi())); } - self.bclose_maybe_open(blk.span, indented, close_box)?; + self.bclose_maybe_open(blk.span, close_box); self.ann.post(self, AnnNode::Block(blk)) } - pub fn print_anon_const(&mut self, constant: &hir::AnonConst) -> io::Result<()> { + pub fn print_anon_const(&mut self, constant: &hir::AnonConst) { self.ann.nested(self, Nested::Body(constant.body)) } - fn print_call_post(&mut self, args: &[hir::Expr]) -> io::Result<()> { - self.popen()?; - self.commasep_exprs(Inconsistent, args)?; + fn print_call_post(&mut self, args: &[hir::Expr]) { + self.popen(); + self.commasep_exprs(Inconsistent, args); self.pclose() } - pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) -> io::Result<()> { + pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) { let needs_par = expr.precedence().order() < prec; if needs_par { - self.popen()?; + self.popen(); } - self.print_expr(expr)?; + self.print_expr(expr); if needs_par { - self.pclose()?; + self.pclose(); } - Ok(()) } /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in /// `if cond { ... }`. - pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) -> io::Result<()> { + pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) { let needs_par = match expr.node { // These cases need parens due to the parse error observed in #26461: `if return {}` // parses as the erroneous construct `if (return {})`, not `if (return) {}`. @@ -1100,30 +1046,29 @@ impl<'a> State<'a> { }; if needs_par { - self.popen()?; + self.popen(); } - self.print_expr(expr)?; + self.print_expr(expr); if needs_par { - self.pclose()?; + self.pclose(); } - Ok(()) } - fn print_expr_vec(&mut self, exprs: &[hir::Expr]) -> io::Result<()> { - self.ibox(indent_unit)?; - self.s.word("[")?; - self.commasep_exprs(Inconsistent, exprs)?; - self.s.word("]")?; + fn print_expr_vec(&mut self, exprs: &[hir::Expr]) { + self.ibox(INDENT_UNIT); + self.s.word("["); + self.commasep_exprs(Inconsistent, exprs); + self.s.word("]"); self.end() } - fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) -> io::Result<()> { - self.ibox(indent_unit)?; - self.s.word("[")?; - self.print_expr(element)?; - self.word_space(";")?; - self.print_anon_const(count)?; - self.s.word("]")?; + fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) { + self.ibox(INDENT_UNIT); + self.s.word("["); + self.print_expr(element); + self.word_space(";"); + self.print_anon_const(count); + self.s.word("]"); self.end() } @@ -1131,72 +1076,71 @@ impl<'a> State<'a> { qpath: &hir::QPath, fields: &[hir::Field], wth: &Option>) - -> io::Result<()> { - self.print_qpath(qpath, true)?; - self.s.word("{")?; + { + self.print_qpath(qpath, true); + self.s.word("{"); self.commasep_cmnt(Consistent, &fields[..], |s, field| { - s.ibox(indent_unit)?; + s.ibox(INDENT_UNIT); if !field.is_shorthand { - s.print_ident(field.ident)?; - s.word_space(":")?; + s.print_ident(field.ident); + s.word_space(":"); } - s.print_expr(&field.expr)?; + s.print_expr(&field.expr); s.end() }, - |f| f.span)?; + |f| f.span); match *wth { Some(ref expr) => { - self.ibox(indent_unit)?; + self.ibox(INDENT_UNIT); if !fields.is_empty() { - self.s.word(",")?; - self.s.space()?; + self.s.word(","); + self.s.space(); } - self.s.word("..")?; - self.print_expr(&expr)?; - self.end()?; + self.s.word(".."); + self.print_expr(&expr); + self.end(); } _ => if !fields.is_empty() { - self.s.word(",")? + self.s.word(",") }, } - self.s.word("}")?; - Ok(()) + self.s.word("}"); } - fn print_expr_tup(&mut self, exprs: &[hir::Expr]) -> io::Result<()> { - self.popen()?; - self.commasep_exprs(Inconsistent, exprs)?; + fn print_expr_tup(&mut self, exprs: &[hir::Expr]) { + self.popen(); + self.commasep_exprs(Inconsistent, exprs); if exprs.len() == 1 { - self.s.word(",")?; + self.s.word(","); } self.pclose() } - fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) -> io::Result<()> { + fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) { let prec = match func.node { hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, _ => parser::PREC_POSTFIX, }; - self.print_expr_maybe_paren(func, prec)?; + self.print_expr_maybe_paren(func, prec); self.print_call_post(args) } fn print_expr_method_call(&mut self, segment: &hir::PathSegment, args: &[hir::Expr]) - -> io::Result<()> { + { let base_args = &args[1..]; - self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX)?; - self.s.word(".")?; - self.print_ident(segment.ident)?; + self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX); + self.s.word("."); + self.print_ident(segment.ident); let generic_args = segment.generic_args(); if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { - self.print_generic_args(generic_args, segment.infer_args, true)?; + self.print_generic_args(generic_args, segment.infer_args, true); } self.print_call_post(base_args) @@ -1206,7 +1150,7 @@ impl<'a> State<'a> { op: hir::BinOp, lhs: &hir::Expr, rhs: &hir::Expr) - -> io::Result<()> { + { let assoc_op = bin_op_to_assoc_op(op.node); let prec = assoc_op.precedence() as i8; let fixity = assoc_op.fixity(); @@ -1226,220 +1170,210 @@ impl<'a> State<'a> { _ => left_prec, }; - self.print_expr_maybe_paren(lhs, left_prec)?; - self.s.space()?; - self.word_space(op.node.as_str())?; + self.print_expr_maybe_paren(lhs, left_prec); + self.s.space(); + self.word_space(op.node.as_str()); self.print_expr_maybe_paren(rhs, right_prec) } - fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> { - self.s.word(op.as_str())?; + fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) { + self.s.word(op.as_str()); self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) } fn print_expr_addr_of(&mut self, mutability: hir::Mutability, expr: &hir::Expr) - -> io::Result<()> { - self.s.word("&")?; - self.print_mutability(mutability)?; + { + self.s.word("&"); + self.print_mutability(mutability); self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) } - fn print_literal(&mut self, lit: &hir::Lit) -> io::Result<()> { - self.maybe_print_comment(lit.span.lo())?; - self.writer().word(pprust::literal_to_string(lit.node.to_lit_token())) + fn print_literal(&mut self, lit: &hir::Lit) { + self.maybe_print_comment(lit.span.lo()); + self.word(lit.node.to_lit_token().to_string()) } - pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> { - self.maybe_print_comment(expr.span.lo())?; - self.print_outer_attributes(&expr.attrs)?; - self.ibox(indent_unit)?; - self.ann.pre(self, AnnNode::Expr(expr))?; + pub fn print_expr(&mut self, expr: &hir::Expr) { + self.maybe_print_comment(expr.span.lo()); + self.print_outer_attributes(&expr.attrs); + self.ibox(INDENT_UNIT); + self.ann.pre(self, AnnNode::Expr(expr)); match expr.node { hir::ExprKind::Box(ref expr) => { - self.word_space("box")?; - self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?; + self.word_space("box"); + self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); } hir::ExprKind::Array(ref exprs) => { - self.print_expr_vec(exprs)?; + self.print_expr_vec(exprs); } hir::ExprKind::Repeat(ref element, ref count) => { - self.print_expr_repeat(&element, count)?; + self.print_expr_repeat(&element, count); } hir::ExprKind::Struct(ref qpath, ref fields, ref wth) => { - self.print_expr_struct(qpath, &fields[..], wth)?; + self.print_expr_struct(qpath, &fields[..], wth); } hir::ExprKind::Tup(ref exprs) => { - self.print_expr_tup(exprs)?; + self.print_expr_tup(exprs); } hir::ExprKind::Call(ref func, ref args) => { - self.print_expr_call(&func, args)?; + self.print_expr_call(&func, args); } hir::ExprKind::MethodCall(ref segment, _, ref args) => { - self.print_expr_method_call(segment, args)?; + self.print_expr_method_call(segment, args); } hir::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, &lhs, &rhs)?; + self.print_expr_binary(op, &lhs, &rhs); } hir::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, &expr)?; + self.print_expr_unary(op, &expr); } hir::ExprKind::AddrOf(m, ref expr) => { - self.print_expr_addr_of(m, &expr)?; + self.print_expr_addr_of(m, &expr); } hir::ExprKind::Lit(ref lit) => { - self.print_literal(&lit)?; + self.print_literal(&lit); } hir::ExprKind::Cast(ref expr, ref ty) => { let prec = AssocOp::As.precedence() as i8; - self.print_expr_maybe_paren(&expr, prec)?; - self.s.space()?; - self.word_space("as")?; - self.print_type(&ty)?; + self.print_expr_maybe_paren(&expr, prec); + self.s.space(); + self.word_space("as"); + self.print_type(&ty); } hir::ExprKind::Type(ref expr, ref ty) => { let prec = AssocOp::Colon.precedence() as i8; - self.print_expr_maybe_paren(&expr, prec)?; - self.word_space(":")?; - self.print_type(&ty)?; + self.print_expr_maybe_paren(&expr, prec); + self.word_space(":"); + self.print_type(&ty); } hir::ExprKind::DropTemps(ref init) => { // Print `{`: - self.cbox(indent_unit)?; - self.ibox(0)?; - self.bopen()?; + self.cbox(INDENT_UNIT); + self.ibox(0); + self.bopen(); // Print `let _t = $init;`: let temp = ast::Ident::from_str("_t"); - self.print_local(Some(init), |this| this.print_ident(temp))?; - self.s.word(";")?; + self.print_local(Some(init), |this| this.print_ident(temp)); + self.s.word(";"); // Print `_t`: - self.space_if_not_bol()?; - self.print_ident(temp)?; + self.space_if_not_bol(); + self.print_ident(temp); // Print `}`: - self.bclose_maybe_open(expr.span, indent_unit, true)?; - } - hir::ExprKind::While(ref test, ref blk, opt_label) => { - if let Some(label) = opt_label { - self.print_ident(label.ident)?; - self.word_space(":")?; - } - self.head("while")?; - self.print_expr_as_cond(&test)?; - self.s.space()?; - self.print_block(&blk)?; + self.bclose_maybe_open(expr.span, true); } hir::ExprKind::Loop(ref blk, opt_label, _) => { if let Some(label) = opt_label { - self.print_ident(label.ident)?; - self.word_space(":")?; + self.print_ident(label.ident); + self.word_space(":"); } - self.head("loop")?; - self.s.space()?; - self.print_block(&blk)?; + self.head("loop"); + self.s.space(); + self.print_block(&blk); } hir::ExprKind::Match(ref expr, ref arms, _) => { - self.cbox(indent_unit)?; - self.ibox(4)?; - self.word_nbsp("match")?; - self.print_expr_as_cond(&expr)?; - self.s.space()?; - self.bopen()?; + self.cbox(INDENT_UNIT); + self.ibox(INDENT_UNIT); + self.word_nbsp("match"); + self.print_expr_as_cond(&expr); + self.s.space(); + self.bopen(); for arm in arms { - self.print_arm(arm)?; + self.print_arm(arm); } - self.bclose_(expr.span, indent_unit)?; + self.bclose(expr.span); } hir::ExprKind::Closure(capture_clause, ref decl, body, _fn_decl_span, _gen) => { - self.print_capture_clause(capture_clause)?; + self.print_capture_clause(capture_clause); - self.print_closure_args(&decl, body)?; - self.s.space()?; + self.print_closure_args(&decl, body); + self.s.space(); // this is a bare expression - self.ann.nested(self, Nested::Body(body))?; - self.end()?; // need to close a box + self.ann.nested(self, Nested::Body(body)); + self.end(); // need to close a box // a box will be closed by print_expr, but we didn't want an overall // wrapper so we closed the corresponding opening. so create an // empty box to satisfy the close. - self.ibox(0)?; + self.ibox(0); } hir::ExprKind::Block(ref blk, opt_label) => { if let Some(label) = opt_label { - self.print_ident(label.ident)?; - self.word_space(":")?; + self.print_ident(label.ident); + self.word_space(":"); } // containing cbox, will be closed by print-block at } - self.cbox(indent_unit)?; + self.cbox(INDENT_UNIT); // head-box, will be closed by print-block after { - self.ibox(0)?; - self.print_block(&blk)?; + self.ibox(0); + self.print_block(&blk); } hir::ExprKind::Assign(ref lhs, ref rhs) => { let prec = AssocOp::Assign.precedence() as i8; - self.print_expr_maybe_paren(&lhs, prec + 1)?; - self.s.space()?; - self.word_space("=")?; - self.print_expr_maybe_paren(&rhs, prec)?; + self.print_expr_maybe_paren(&lhs, prec + 1); + self.s.space(); + self.word_space("="); + self.print_expr_maybe_paren(&rhs, prec); } hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => { let prec = AssocOp::Assign.precedence() as i8; - self.print_expr_maybe_paren(&lhs, prec + 1)?; - self.s.space()?; - self.s.word(op.node.as_str())?; - self.word_space("=")?; - self.print_expr_maybe_paren(&rhs, prec)?; + self.print_expr_maybe_paren(&lhs, prec + 1); + self.s.space(); + self.s.word(op.node.as_str()); + self.word_space("="); + self.print_expr_maybe_paren(&rhs, prec); } hir::ExprKind::Field(ref expr, ident) => { - self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?; - self.s.word(".")?; - self.print_ident(ident)?; + self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); + self.s.word("."); + self.print_ident(ident); } hir::ExprKind::Index(ref expr, ref index) => { - self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX)?; - self.s.word("[")?; - self.print_expr(&index)?; - self.s.word("]")?; + self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX); + self.s.word("["); + self.print_expr(&index); + self.s.word("]"); } hir::ExprKind::Path(ref qpath) => { - self.print_qpath(qpath, true)? + self.print_qpath(qpath, true) } hir::ExprKind::Break(destination, ref opt_expr) => { - self.s.word("break")?; - self.s.space()?; + self.s.word("break"); + self.s.space(); if let Some(label) = destination.label { - self.print_ident(label.ident)?; - self.s.space()?; + self.print_ident(label.ident); + self.s.space(); } if let Some(ref expr) = *opt_expr { - self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?; - self.s.space()?; + self.print_expr_maybe_paren(expr, parser::PREC_JUMP); + self.s.space(); } } hir::ExprKind::Continue(destination) => { - self.s.word("continue")?; - self.s.space()?; + self.s.word("continue"); + self.s.space(); if let Some(label) = destination.label { - self.print_ident(label.ident)?; - self.s.space()? + self.print_ident(label.ident); + self.s.space() } } hir::ExprKind::Ret(ref result) => { - self.s.word("return")?; + self.s.word("return"); if let Some(ref expr) = *result { - self.s.word(" ")?; - self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?; + self.s.word(" "); + self.print_expr_maybe_paren(&expr, parser::PREC_JUMP); } } hir::ExprKind::InlineAsm(ref a, ref outputs, ref inputs) => { - self.s.word("asm!")?; - self.popen()?; - self.print_string(&a.asm.as_str(), a.asm_str_style)?; - self.word_space(":")?; + self.s.word("asm!"); + self.popen(); + self.print_string(&a.asm.as_str(), a.asm_str_style); + self.word_space(":"); let mut out_idx = 0; self.commasep(Inconsistent, &a.outputs, |s, out| { @@ -1448,35 +1382,32 @@ impl<'a> State<'a> { match ch.next() { Some('=') if out.is_rw => { s.print_string(&format!("+{}", ch.as_str()), - ast::StrStyle::Cooked)? + ast::StrStyle::Cooked) } - _ => s.print_string(&constraint, ast::StrStyle::Cooked)?, + _ => s.print_string(&constraint, ast::StrStyle::Cooked), } - s.popen()?; - s.print_expr(&outputs[out_idx])?; - s.pclose()?; + s.popen(); + s.print_expr(&outputs[out_idx]); + s.pclose(); out_idx += 1; - Ok(()) - })?; - self.s.space()?; - self.word_space(":")?; + }); + self.s.space(); + self.word_space(":"); let mut in_idx = 0; self.commasep(Inconsistent, &a.inputs, |s, co| { - s.print_string(&co.as_str(), ast::StrStyle::Cooked)?; - s.popen()?; - s.print_expr(&inputs[in_idx])?; - s.pclose()?; + s.print_string(&co.as_str(), ast::StrStyle::Cooked); + s.popen(); + s.print_expr(&inputs[in_idx]); + s.pclose(); in_idx += 1; - Ok(()) - })?; - self.s.space()?; - self.word_space(":")?; + }); + self.s.space(); + self.word_space(":"); self.commasep(Inconsistent, &a.clobbers, |s, co| { - s.print_string(&co.as_str(), ast::StrStyle::Cooked)?; - Ok(()) - })?; + s.print_string(&co.as_str(), ast::StrStyle::Cooked); + }); let mut options = vec![]; if a.volatile { @@ -1490,131 +1421,117 @@ impl<'a> State<'a> { } if !options.is_empty() { - self.s.space()?; - self.word_space(":")?; + self.s.space(); + self.word_space(":"); self.commasep(Inconsistent, &options, |s, &co| { - s.print_string(co, ast::StrStyle::Cooked)?; - Ok(()) - })?; + s.print_string(co, ast::StrStyle::Cooked); + }); } - self.pclose()?; + self.pclose(); } hir::ExprKind::Yield(ref expr, _) => { - self.word_space("yield")?; - self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?; + self.word_space("yield"); + self.print_expr_maybe_paren(&expr, parser::PREC_JUMP); } hir::ExprKind::Err => { - self.popen()?; - self.s.word("/*ERROR*/")?; - self.pclose()?; + self.popen(); + self.s.word("/*ERROR*/"); + self.pclose(); } } - self.ann.post(self, AnnNode::Expr(expr))?; + self.ann.post(self, AnnNode::Expr(expr)); self.end() } - pub fn print_local_decl(&mut self, loc: &hir::Local) -> io::Result<()> { - self.print_pat(&loc.pat)?; + pub fn print_local_decl(&mut self, loc: &hir::Local) { + self.print_pat(&loc.pat); if let Some(ref ty) = loc.ty { - self.word_space(":")?; - self.print_type(&ty)?; + self.word_space(":"); + self.print_type(&ty); } - Ok(()) } - pub fn print_usize(&mut self, i: usize) -> io::Result<()> { + pub fn print_usize(&mut self, i: usize) { self.s.word(i.to_string()) } - pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> { - if ident.is_raw_guess() { - self.s.word(format!("r#{}", ident.name))?; - } else { - self.s.word(ident.as_str().to_string())?; - } - self.ann.post(self, AnnNode::Name(&ident.name)) - } - - pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { + pub fn print_name(&mut self, name: ast::Name) { self.print_ident(ast::Ident::with_empty_ctxt(name)) } - pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) -> io::Result<()> { - self.print_local_decl(loc)?; - self.s.space()?; - self.word_space("in")?; + pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) { + self.print_local_decl(loc); + self.s.space(); + self.word_space("in"); self.print_expr(coll) } pub fn print_path(&mut self, path: &hir::Path, colons_before_params: bool) - -> io::Result<()> { - self.maybe_print_comment(path.span.lo())?; + { + self.maybe_print_comment(path.span.lo()); for (i, segment) in path.segments.iter().enumerate() { if i > 0 { - self.s.word("::")? + self.s.word("::") } if segment.ident.name != kw::PathRoot { - self.print_ident(segment.ident)?; + self.print_ident(segment.ident); self.print_generic_args(segment.generic_args(), segment.infer_args, - colons_before_params)?; + colons_before_params); } } - - Ok(()) } - pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> { + pub fn print_path_segment(&mut self, segment: &hir::PathSegment) { if segment.ident.name != kw::PathRoot { - self.print_ident(segment.ident)?; - self.print_generic_args(segment.generic_args(), segment.infer_args, false)?; + self.print_ident(segment.ident); + self.print_generic_args(segment.generic_args(), segment.infer_args, false); } - Ok(()) } pub fn print_qpath(&mut self, qpath: &hir::QPath, colons_before_params: bool) - -> io::Result<()> { + { match *qpath { hir::QPath::Resolved(None, ref path) => { self.print_path(path, colons_before_params) } hir::QPath::Resolved(Some(ref qself), ref path) => { - self.s.word("<")?; - self.print_type(qself)?; - self.s.space()?; - self.word_space("as")?; + self.s.word("<"); + self.print_type(qself); + self.s.space(); + self.word_space("as"); for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() { if i > 0 { - self.s.word("::")? + self.s.word("::") } if segment.ident.name != kw::PathRoot { - self.print_ident(segment.ident)?; + self.print_ident(segment.ident); self.print_generic_args(segment.generic_args(), segment.infer_args, - colons_before_params)?; + colons_before_params); } } - self.s.word(">")?; - self.s.word("::")?; + self.s.word(">"); + self.s.word("::"); let item_segment = path.segments.last().unwrap(); - self.print_ident(item_segment.ident)?; + self.print_ident(item_segment.ident); self.print_generic_args(item_segment.generic_args(), item_segment.infer_args, colons_before_params) } hir::QPath::TypeRelative(ref qself, ref item_segment) => { - self.s.word("<")?; - self.print_type(qself)?; - self.s.word(">")?; - self.s.word("::")?; - self.print_ident(item_segment.ident)?; + self.s.word("<"); + self.print_type(qself); + self.s.word(">"); + self.s.word("::"); + self.print_ident(item_segment.ident); self.print_generic_args(item_segment.generic_args(), item_segment.infer_args, colons_before_params) @@ -1626,15 +1543,15 @@ impl<'a> State<'a> { generic_args: &hir::GenericArgs, infer_args: bool, colons_before_params: bool) - -> io::Result<()> { + { if generic_args.parenthesized { - self.s.word("(")?; - self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty))?; - self.s.word(")")?; + self.s.word("("); + self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty)); + self.s.word(")"); - self.space_if_not_bol()?; - self.word_space("->")?; - self.print_type(generic_args.bindings[0].ty())?; + self.space_if_not_bol(); + self.word_space("->"); + self.print_type(generic_args.bindings[0].ty()); } else { let start = if colons_before_params { "::<" } else { "<" }; let empty = Cell::new(true); @@ -1657,153 +1574,151 @@ impl<'a> State<'a> { }); if nonelided_generic_args { - start_or_comma(self)?; + start_or_comma(self); self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| { match generic_arg { GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), - GenericArg::Lifetime(_) => Ok(()), + GenericArg::Lifetime(_) => {}, GenericArg::Type(ty) => s.print_type(ty), GenericArg::Const(ct) => s.print_anon_const(&ct.value), } - })?; + }); } // FIXME(eddyb): this would leak into error messages (e.g., // "non-exhaustive patterns: `Some::<..>(_)` not covered"). if infer_args && false { - start_or_comma(self)?; - self.s.word("..")?; + start_or_comma(self); + self.s.word(".."); } for binding in generic_args.bindings.iter() { - start_or_comma(self)?; - self.print_ident(binding.ident)?; - self.s.space()?; + start_or_comma(self); + self.print_ident(binding.ident); + self.s.space(); match generic_args.bindings[0].kind { hir::TypeBindingKind::Equality { ref ty } => { - self.word_space("=")?; - self.print_type(ty)?; + self.word_space("="); + self.print_type(ty); } hir::TypeBindingKind::Constraint { ref bounds } => { - self.print_bounds(":", bounds)?; + self.print_bounds(":", bounds); } } } if !empty.get() { - self.s.word(">")? + self.s.word(">") } } - - Ok(()) } - pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> { - self.maybe_print_comment(pat.span.lo())?; - self.ann.pre(self, AnnNode::Pat(pat))?; + pub fn print_pat(&mut self, pat: &hir::Pat) { + self.maybe_print_comment(pat.span.lo()); + self.ann.pre(self, AnnNode::Pat(pat)); // Pat isn't normalized, but the beauty of it // is that it doesn't matter match pat.node { - PatKind::Wild => self.s.word("_")?, + PatKind::Wild => self.s.word("_"), PatKind::Binding(binding_mode, _, ident, ref sub) => { match binding_mode { hir::BindingAnnotation::Ref => { - self.word_nbsp("ref")?; - self.print_mutability(hir::MutImmutable)?; + self.word_nbsp("ref"); + self.print_mutability(hir::MutImmutable); } hir::BindingAnnotation::RefMut => { - self.word_nbsp("ref")?; - self.print_mutability(hir::MutMutable)?; + self.word_nbsp("ref"); + self.print_mutability(hir::MutMutable); } hir::BindingAnnotation::Unannotated => {} hir::BindingAnnotation::Mutable => { - self.word_nbsp("mut")?; + self.word_nbsp("mut"); } } - self.print_ident(ident)?; + self.print_ident(ident); if let Some(ref p) = *sub { - self.s.word("@")?; - self.print_pat(&p)?; + self.s.word("@"); + self.print_pat(&p); } } PatKind::TupleStruct(ref qpath, ref elts, ddpos) => { - self.print_qpath(qpath, true)?; - self.popen()?; + self.print_qpath(qpath, true); + self.popen(); if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p)); if ddpos != 0 { - self.word_space(",")?; + self.word_space(","); } - self.s.word("..")?; + self.s.word(".."); if ddpos != elts.len() { - self.s.word(",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + self.s.word(","); + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p)); } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p)); } - self.pclose()?; + self.pclose(); } PatKind::Path(ref qpath) => { - self.print_qpath(qpath, true)?; + self.print_qpath(qpath, true); } PatKind::Struct(ref qpath, ref fields, etc) => { - self.print_qpath(qpath, true)?; - self.nbsp()?; - self.word_space("{")?; + self.print_qpath(qpath, true); + self.nbsp(); + self.word_space("{"); self.commasep_cmnt(Consistent, &fields[..], |s, f| { - s.cbox(indent_unit)?; + s.cbox(INDENT_UNIT); if !f.node.is_shorthand { - s.print_ident(f.node.ident)?; - s.word_nbsp(":")?; + s.print_ident(f.node.ident); + s.word_nbsp(":"); } - s.print_pat(&f.node.pat)?; + s.print_pat(&f.node.pat); s.end() }, - |f| f.node.pat.span)?; + |f| f.node.pat.span); if etc { if !fields.is_empty() { - self.word_space(",")?; + self.word_space(","); } - self.s.word("..")?; + self.s.word(".."); } - self.s.space()?; - self.s.word("}")?; + self.s.space(); + self.s.word("}"); } PatKind::Tuple(ref elts, ddpos) => { - self.popen()?; + self.popen(); if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p)); if ddpos != 0 { - self.word_space(",")?; + self.word_space(","); } - self.s.word("..")?; + self.s.word(".."); if ddpos != elts.len() { - self.s.word(",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + self.s.word(","); + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p)); } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p)); if elts.len() == 1 { - self.s.word(",")?; + self.s.word(","); } } - self.pclose()?; + self.pclose(); } PatKind::Box(ref inner) => { let is_range_inner = match inner.node { PatKind::Range(..) => true, _ => false, }; - self.s.word("box ")?; + self.s.word("box "); if is_range_inner { - self.popen()?; + self.popen(); } - self.print_pat(&inner)?; + self.print_pat(&inner); if is_range_inner { - self.pclose()?; + self.pclose(); } } PatKind::Ref(ref inner, mutbl) => { @@ -1811,103 +1726,110 @@ impl<'a> State<'a> { PatKind::Range(..) => true, _ => false, }; - self.s.word("&")?; + self.s.word("&"); if mutbl == hir::MutMutable { - self.s.word("mut ")?; + self.s.word("mut "); } if is_range_inner { - self.popen()?; + self.popen(); } - self.print_pat(&inner)?; + self.print_pat(&inner); if is_range_inner { - self.pclose()?; + self.pclose(); } } - PatKind::Lit(ref e) => self.print_expr(&e)?, + PatKind::Lit(ref e) => self.print_expr(&e), PatKind::Range(ref begin, ref end, ref end_kind) => { - self.print_expr(&begin)?; - self.s.space()?; + self.print_expr(&begin); + self.s.space(); match *end_kind { - RangeEnd::Included => self.s.word("...")?, - RangeEnd::Excluded => self.s.word("..")?, + RangeEnd::Included => self.s.word("..."), + RangeEnd::Excluded => self.s.word(".."), } - self.print_expr(&end)?; + self.print_expr(&end); } PatKind::Slice(ref before, ref slice, ref after) => { - self.s.word("[")?; - self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?; + self.s.word("["); + self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p)); if let Some(ref p) = *slice { if !before.is_empty() { - self.word_space(",")?; + self.word_space(","); } if let PatKind::Wild = p.node { // Print nothing } else { - self.print_pat(&p)?; + self.print_pat(&p); } - self.s.word("..")?; + self.s.word(".."); if !after.is_empty() { - self.word_space(",")?; + self.word_space(","); } } - self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p))?; - self.s.word("]")?; + self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p)); + self.s.word("]"); } } self.ann.post(self, AnnNode::Pat(pat)) } - pub fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> { + pub fn print_arg(&mut self, arg: &hir::Arg) { + self.print_outer_attributes(&arg.attrs); + self.print_pat(&arg.pat); + } + + pub fn print_arm(&mut self, arm: &hir::Arm) { // I have no idea why this check is necessary, but here it // is :( if arm.attrs.is_empty() { - self.s.space()?; + self.s.space(); } - self.cbox(indent_unit)?; - self.ibox(0)?; - self.print_outer_attributes(&arm.attrs)?; + self.cbox(INDENT_UNIT); + self.ann.pre(self, AnnNode::Arm(arm)); + self.ibox(0); + self.print_outer_attributes(&arm.attrs); let mut first = true; for p in &arm.pats { if first { first = false; } else { - self.s.space()?; - self.word_space("|")?; + self.s.space(); + self.word_space("|"); } - self.print_pat(&p)?; + self.print_pat(&p); } - self.s.space()?; + self.s.space(); if let Some(ref g) = arm.guard { match g { hir::Guard::If(e) => { - self.word_space("if")?; - self.print_expr(&e)?; - self.s.space()?; + self.word_space("if"); + self.print_expr(&e); + self.s.space(); } } } - self.word_space("=>")?; + self.word_space("=>"); match arm.body.node { hir::ExprKind::Block(ref blk, opt_label) => { if let Some(label) = opt_label { - self.print_ident(label.ident)?; - self.word_space(":")?; + self.print_ident(label.ident); + self.word_space(":"); } // the block will close the pattern's ibox - self.print_block_unclosed_indent(&blk, indent_unit)?; + self.print_block_unclosed(&blk); // If it is a user-provided unsafe block, print a comma after it if let hir::UnsafeBlock(hir::UserProvided) = blk.rules { - self.s.word(",")?; + self.s.word(","); } } _ => { - self.end()?; // close the ibox for the pattern - self.print_expr(&arm.body)?; - self.s.word(",")?; + self.end(); // close the ibox for the pattern + self.print_expr(&arm.body); + self.s.word(","); } } + self.ann.post(self, AnnNode::Arm(arm)); self.end() // close enclosing cbox } @@ -1919,82 +1841,82 @@ impl<'a> State<'a> { vis: &hir::Visibility, arg_names: &[ast::Ident], body_id: Option) - -> io::Result<()> { - self.print_fn_header_info(header, vis)?; + { + self.print_fn_header_info(header, vis); if let Some(name) = name { - self.nbsp()?; - self.print_name(name)?; + self.nbsp(); + self.print_name(name); } - self.print_generic_params(&generics.params)?; + self.print_generic_params(&generics.params); - self.popen()?; + self.popen(); let mut i = 0; // Make sure we aren't supplied *both* `arg_names` and `body_id`. assert!(arg_names.is_empty() || body_id.is_none()); self.commasep(Inconsistent, &decl.inputs, |s, ty| { - s.ibox(indent_unit)?; + s.ibox(INDENT_UNIT); if let Some(arg_name) = arg_names.get(i) { - s.s.word(arg_name.as_str().to_string())?; - s.s.word(":")?; - s.s.space()?; + s.s.word(arg_name.as_str().to_string()); + s.s.word(":"); + s.s.space(); } else if let Some(body_id) = body_id { - s.ann.nested(s, Nested::BodyArgPat(body_id, i))?; - s.s.word(":")?; - s.s.space()?; + s.ann.nested(s, Nested::BodyArgPat(body_id, i)); + s.s.word(":"); + s.s.space(); } i += 1; - s.print_type(ty)?; + s.print_type(ty); s.end() - })?; + }); if decl.c_variadic { - self.s.word(", ...")?; + self.s.word(", ..."); } - self.pclose()?; + self.pclose(); - self.print_fn_output(decl)?; + self.print_fn_output(decl); self.print_where_clause(&generics.where_clause) } - fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) -> io::Result<()> { - self.s.word("|")?; + fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) { + self.s.word("|"); let mut i = 0; self.commasep(Inconsistent, &decl.inputs, |s, ty| { - s.ibox(indent_unit)?; + s.ibox(INDENT_UNIT); - s.ann.nested(s, Nested::BodyArgPat(body_id, i))?; + s.ann.nested(s, Nested::BodyArgPat(body_id, i)); i += 1; if let hir::TyKind::Infer = ty.node { // Print nothing } else { - s.s.word(":")?; - s.s.space()?; - s.print_type(ty)?; + s.s.word(":"); + s.s.space(); + s.print_type(ty); } - s.end() - })?; - self.s.word("|")?; + s.end(); + }); + self.s.word("|"); if let hir::DefaultReturn(..) = decl.output { - return Ok(()); + return; } - self.space_if_not_bol()?; - self.word_space("->")?; + self.space_if_not_bol(); + self.word_space("->"); match decl.output { hir::Return(ref ty) => { - self.print_type(&ty)?; + self.print_type(&ty); self.maybe_print_comment(ty.span.lo()) } hir::DefaultReturn(..) => unreachable!(), } } - pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io::Result<()> { + pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) { match capture_clause { hir::CaptureByValue => self.word_space("move"), - hir::CaptureByRef => Ok(()), + hir::CaptureByRef => {}, } } @@ -2002,55 +1924,53 @@ impl<'a> State<'a> { &mut self, prefix: &'static str, bounds: impl IntoIterator, - ) -> io::Result<()> { + ) { let mut first = true; for bound in bounds { if first { - self.s.word(prefix)?; + self.s.word(prefix); } if !(first && prefix.is_empty()) { - self.nbsp()?; + self.nbsp(); } if first { first = false; } else { - self.word_space("+")?; + self.word_space("+"); } match bound { GenericBound::Trait(tref, modifier) => { if modifier == &TraitBoundModifier::Maybe { - self.s.word("?")?; + self.s.word("?"); } - self.print_poly_trait_ref(tref)?; + self.print_poly_trait_ref(tref); } GenericBound::Outlives(lt) => { - self.print_lifetime(lt)?; + self.print_lifetime(lt); } } } - Ok(()) } - pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) -> io::Result<()> { + pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) { if !generic_params.is_empty() { - self.s.word("<")?; + self.s.word("<"); self.commasep(Inconsistent, generic_params, |s, param| { s.print_generic_param(param) - })?; + }); - self.s.word(">")?; + self.s.word(">"); } - Ok(()) } - pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> { + pub fn print_generic_param(&mut self, param: &GenericParam) { if let GenericParamKind::Const { .. } = param.kind { - self.word_space("const")?; + self.word_space("const"); } - self.print_ident(param.name.ident())?; + self.print_ident(param.name.ident()); match param.kind { GenericParamKind::Lifetime { .. } => { @@ -2058,48 +1978,47 @@ impl<'a> State<'a> { for bound in ¶m.bounds { match bound { GenericBound::Outlives(lt) => { - self.s.word(sep)?; - self.print_lifetime(lt)?; + self.s.word(sep); + self.print_lifetime(lt); sep = "+"; } _ => bug!(), } } - Ok(()) } GenericParamKind::Type { ref default, .. } => { - self.print_bounds(":", ¶m.bounds)?; + self.print_bounds(":", ¶m.bounds); match default { Some(default) => { - self.s.space()?; - self.word_space("=")?; + self.s.space(); + self.word_space("="); self.print_type(&default) } - _ => Ok(()), + _ => {} } } GenericParamKind::Const { ref ty } => { - self.word_space(":")?; + self.word_space(":"); self.print_type(ty) } } } - pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { + pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) { self.print_ident(lifetime.name.ident()) } - pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> { + pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) { if where_clause.predicates.is_empty() { - return Ok(()); + return; } - self.s.space()?; - self.word_space("where")?; + self.s.space(); + self.word_space("where"); for (i, predicate) in where_clause.predicates.iter().enumerate() { if i != 0 { - self.word_space(",")?; + self.word_space(","); } match predicate { @@ -2109,72 +2028,70 @@ impl<'a> State<'a> { ref bounds, .. }) => { - self.print_formal_generic_params(bound_generic_params)?; - self.print_type(&bounded_ty)?; - self.print_bounds(":", bounds)?; + self.print_formal_generic_params(bound_generic_params); + self.print_type(&bounded_ty); + self.print_bounds(":", bounds); } &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime, ref bounds, ..}) => { - self.print_lifetime(lifetime)?; - self.s.word(":")?; + self.print_lifetime(lifetime); + self.s.word(":"); for (i, bound) in bounds.iter().enumerate() { match bound { GenericBound::Outlives(lt) => { - self.print_lifetime(lt)?; + self.print_lifetime(lt); } _ => bug!(), } if i != 0 { - self.s.word(":")?; + self.s.word(":"); } } } &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty, ref rhs_ty, ..}) => { - self.print_type(lhs_ty)?; - self.s.space()?; - self.word_space("=")?; - self.print_type(rhs_ty)?; + self.print_type(lhs_ty); + self.s.space(); + self.word_space("="); + self.print_type(rhs_ty); } } } - - Ok(()) } - pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> { + pub fn print_mutability(&mut self, mutbl: hir::Mutability) { match mutbl { hir::MutMutable => self.word_nbsp("mut"), - hir::MutImmutable => Ok(()), + hir::MutImmutable => {}, } } - pub fn print_mt(&mut self, mt: &hir::MutTy) -> io::Result<()> { - self.print_mutability(mt.mutbl)?; + pub fn print_mt(&mut self, mt: &hir::MutTy) { + self.print_mutability(mt.mutbl); self.print_type(&mt.ty) } - pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> { + pub fn print_fn_output(&mut self, decl: &hir::FnDecl) { if let hir::DefaultReturn(..) = decl.output { - return Ok(()); + return; } - self.space_if_not_bol()?; - self.ibox(indent_unit)?; - self.word_space("->")?; + self.space_if_not_bol(); + self.ibox(INDENT_UNIT); + self.word_space("->"); match decl.output { hir::DefaultReturn(..) => unreachable!(), - hir::Return(ref ty) => self.print_type(&ty)?, + hir::Return(ref ty) => self.print_type(&ty), } - self.end()?; + self.end(); match decl.output { hir::Return(ref output) => self.maybe_print_comment(output.span.lo()), - _ => Ok(()), + _ => {}, } } @@ -2185,11 +2102,11 @@ impl<'a> State<'a> { name: Option, generic_params: &[hir::GenericParam], arg_names: &[ast::Ident]) - -> io::Result<()> { - self.ibox(indent_unit)?; + { + self.ibox(INDENT_UNIT); if !generic_params.is_empty() { - self.s.word("for")?; - self.print_generic_params(generic_params)?; + self.s.word("for"); + self.print_generic_params(generic_params); } let generics = hir::Generics { params: hir::HirVec::new(), @@ -2211,108 +2128,92 @@ impl<'a> State<'a> { &Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }, arg_names, - None)?; - self.end() + None); + self.end(); } pub fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span, next_pos: Option) - -> io::Result<()> { - let cm = match self.cm { - Some(cm) => cm, - _ => return Ok(()), - }; - if let Some(ref cmnt) = self.next_comment() { - if (*cmnt).style != comments::Trailing { - return Ok(()); - } - let span_line = cm.lookup_char_pos(span.hi()); - let comment_line = cm.lookup_char_pos((*cmnt).pos); - let mut next = (*cmnt).pos + BytePos(1); - if let Some(p) = next_pos { - next = p; - } - if span.hi() < (*cmnt).pos && (*cmnt).pos < next && - span_line.line == comment_line.line { - self.print_comment(cmnt)?; + { + if let Some(cmnts) = self.comments() { + if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) { + self.print_comment(&cmnt); } } - Ok(()) } - pub fn print_remaining_comments(&mut self) -> io::Result<()> { + pub fn print_remaining_comments(&mut self) { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. if self.next_comment().is_none() { - self.s.hardbreak()?; + self.s.hardbreak(); } while let Some(ref cmnt) = self.next_comment() { - self.print_comment(cmnt)? + self.print_comment(cmnt) } - Ok(()) } pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option) - -> io::Result<()> { + { match opt_abi { - Some(Abi::Rust) => Ok(()), + Some(Abi::Rust) => {}, Some(abi) => { - self.word_nbsp("extern")?; + self.word_nbsp("extern"); self.word_nbsp(abi.to_string()) } - None => Ok(()), + None => {}, } } - pub fn print_extern_opt_abi(&mut self, opt_abi: Option) -> io::Result<()> { + pub fn print_extern_opt_abi(&mut self, opt_abi: Option) { match opt_abi { Some(abi) => { - self.word_nbsp("extern")?; + self.word_nbsp("extern"); self.word_nbsp(abi.to_string()) } - None => Ok(()), + None => {}, } } pub fn print_fn_header_info(&mut self, header: hir::FnHeader, vis: &hir::Visibility) - -> io::Result<()> { - self.s.word(visibility_qualified(vis, ""))?; + { + self.s.word(visibility_qualified(vis, "")); match header.constness { hir::Constness::NotConst => {} - hir::Constness::Const => self.word_nbsp("const")?, + hir::Constness::Const => self.word_nbsp("const"), } match header.asyncness { hir::IsAsync::NotAsync => {} - hir::IsAsync::Async => self.word_nbsp("async")?, + hir::IsAsync::Async => self.word_nbsp("async"), } - self.print_unsafety(header.unsafety)?; + self.print_unsafety(header.unsafety); if header.abi != Abi::Rust { - self.word_nbsp("extern")?; - self.word_nbsp(header.abi.to_string())?; + self.word_nbsp("extern"); + self.word_nbsp(header.abi.to_string()); } self.s.word("fn") } - pub fn print_unsafety(&mut self, s: hir::Unsafety) -> io::Result<()> { + pub fn print_unsafety(&mut self, s: hir::Unsafety) { match s { - hir::Unsafety::Normal => Ok(()), + hir::Unsafety::Normal => {} hir::Unsafety::Unsafe => self.word_nbsp("unsafe"), } } - pub fn print_is_auto(&mut self, s: hir::IsAuto) -> io::Result<()> { + pub fn print_is_auto(&mut self, s: hir::IsAuto) { match s { hir::IsAuto::Yes => self.word_nbsp("auto"), - hir::IsAuto::No => Ok(()), + hir::IsAuto::No => {}, } } } @@ -2329,7 +2230,6 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { match e.node { hir::ExprKind::Match(..) | hir::ExprKind::Block(..) | - hir::ExprKind::While(..) | hir::ExprKind::Loop(..) => false, _ => true, } diff --git a/src/librustc/hir/ptr.rs b/src/librustc/hir/ptr.rs new file mode 100644 index 0000000000..1976b4c9e5 --- /dev/null +++ b/src/librustc/hir/ptr.rs @@ -0,0 +1,141 @@ +// HACK(eddyb) this is a copy of `syntax::ptr`, minus the mutation (the HIR is +// frozen anyway). The only reason for doing this instead of replacing `P` +// with `Box` in HIR, is that `&Box<[T]>` doesn't implement `IntoIterator`. + +use std::fmt::{self, Display, Debug}; +use std::iter::FromIterator; +use std::ops::Deref; +use std::{slice, vec}; + +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; + +use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, + HashStable}; +/// An owned smart pointer. +#[derive(Hash, PartialEq, Eq)] +pub struct P { + ptr: Box +} + +/// Construct a `P` from a `T` value. +#[allow(non_snake_case)] +pub fn P(value: T) -> P { + P { + ptr: box value + } +} + +impl P { + // HACK(eddyb) used by HIR lowering in a few places still. + // NOTE: do not make this more public than `pub(super)`. + pub(super) fn into_inner(self) -> T { + *self.ptr + } +} + +impl Deref for P { + type Target = T; + + fn deref(&self) -> &T { + &self.ptr + } +} + +impl Debug for P { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Debug::fmt(&self.ptr, f) + } +} + +impl Display for P { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Display::fmt(&**self, f) + } +} + +impl Decodable for P { + fn decode(d: &mut D) -> Result, D::Error> { + Decodable::decode(d).map(P) + } +} + +impl Encodable for P { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + (**self).encode(s) + } +} + +impl P<[T]> { + pub const fn new() -> P<[T]> { + // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>` + // (as trait methods, `default` in this case, can't be `const fn` yet). + P { + ptr: unsafe { + use std::ptr::NonNull; + std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>) + }, + } + } + + #[inline(never)] + pub fn from_vec(v: Vec) -> P<[T]> { + P { ptr: v.into_boxed_slice() } + } + + // HACK(eddyb) used by HIR lowering in a few places still. + // NOTE: do not make this more public than `pub(super)`, + // and do not make this into an `IntoIterator` impl. + pub(super) fn into_iter(self) -> vec::IntoIter { + self.ptr.into_vec().into_iter() + } +} + + +impl Default for P<[T]> { + /// Creates an empty `P<[T]>`. + fn default() -> P<[T]> { + P::new() + } +} + +impl From> for P<[T]> { + fn from(v: Vec) -> Self { + P::from_vec(v) + } +} + +impl FromIterator for P<[T]> { + fn from_iter>(iter: I) -> P<[T]> { + P::from_vec(iter.into_iter().collect()) + } +} + +impl<'a, T> IntoIterator for &'a P<[T]> { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.ptr.into_iter() + } +} + +impl Encodable for P<[T]> { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&**self, s) + } +} + +impl Decodable for P<[T]> { + fn decode(d: &mut D) -> Result, D::Error> { + Ok(P::from_vec(Decodable::decode(d)?)) + } +} + +impl HashStable for P + where T: ?Sized + HashStable +{ + fn hash_stable(&self, + hcx: &mut CTX, + hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); + } +} diff --git a/src/librustc/hir/upvars.rs b/src/librustc/hir/upvars.rs index 54b4435573..cc532cb064 100644 --- a/src/librustc/hir/upvars.rs +++ b/src/librustc/hir/upvars.rs @@ -83,7 +83,7 @@ impl Visitor<'tcx> for CaptureCollector<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if let hir::ExprKind::Closure(..) = expr.node { - let closure_def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id); + let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id); if let Some(upvars) = self.tcx.upvars(closure_def_id) { // Every capture of a closure expression is a local in scope, // that is moved/copied/borrowed into the closure value, and diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 4ef4d70ee1..ae7d82c202 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -359,21 +359,21 @@ impl<'a> HashStable> for Span { // times, we cache a stable hash of it and hash that instead of // recursing every time. thread_local! { - static CACHE: RefCell> = Default::default(); + static CACHE: RefCell> = Default::default(); } let sub_hash: u64 = CACHE.with(|cache| { - let mark = span.ctxt.outer(); + let expn_id = span.ctxt.outer_expn(); - if let Some(&sub_hash) = cache.borrow().get(&mark) { + if let Some(&sub_hash) = cache.borrow().get(&expn_id) { return sub_hash; } let mut hasher = StableHasher::new(); - mark.expn_info().hash_stable(hcx, &mut hasher); + expn_id.expn_info().hash_stable(hcx, &mut hasher); let sub_hash: Fingerprint = hasher.finish(); let sub_hash = sub_hash.to_smaller_hash(); - cache.borrow_mut().insert(mark, sub_hash); + cache.borrow_mut().insert(expn_id, sub_hash); sub_hash }); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 9430661f75..daa69efe28 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -89,7 +89,6 @@ impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind { Bang, Attr, Derive, - ProcMacroStub, }); @@ -137,9 +136,10 @@ for ::syntax::attr::StabilityLevel { hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => { + ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => { reason.hash_stable(hcx, hasher); issue.hash_stable(hcx, hasher); + is_soft.hash_stable(hcx, hasher); } ::syntax::attr::StabilityLevel::Stable { ref since } => { since.hash_stable(hcx, hasher); @@ -364,7 +364,8 @@ impl<'a> HashStable> for token::TokenKind { } token::DocComment(val) | - token::Shebang(val) => val.hash_stable(hcx, hasher), + token::Shebang(val) | + token::Unknown(val) => val.hash_stable(hcx, hasher), } } } @@ -399,7 +400,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { call_site, - format, + kind, def_site, default_transparency, allow_internal_unstable, @@ -408,18 +409,18 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { edition }); -impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat { - MacroAttribute(sym), - MacroBang(sym), - CompilerDesugaring(kind) +impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind { + Root, + Macro(kind, descr), + Desugaring(kind) }); -impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind { - IfTemporary, +impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind { + CondTemporary, Async, Await, QuestionMark, - ExistentialType, + OpaqueTy, ForLoop, TryBlock }); diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 3d57a89493..db724875b8 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -693,7 +693,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { const_var: &'tcx ty::Const<'tcx> ) -> &'tcx ty::Const<'tcx> { let infcx = self.infcx.expect("encountered const-var without infcx"); - let bound_to = infcx.resolve_const_var(const_var); + let bound_to = infcx.shallow_resolve(const_var); if bound_to != const_var { self.fold_const(bound_to) } else { diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index b508f91e01..6840611d4b 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -27,7 +27,7 @@ use crate::infer::region_constraints::MemberConstraint; use crate::mir::interpret::ConstValue; use rustc_data_structures::indexed_vec::IndexVec; use rustc_macros::HashStable; -use serialize::UseSpecializedDecodable; +use rustc_serialize::UseSpecializedDecodable; use smallvec::SmallVec; use std::ops::Index; use syntax::source_map::Span; diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index e20b53455f..4a9b68f243 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -340,6 +340,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { ambient_variance, needs_wf: false, root_ty: ty, + param_env: self.param_env, }; let ty = match generalize.relate(&ty, &ty) { @@ -379,6 +380,8 @@ struct Generalizer<'cx, 'tcx> { /// The root type that we are generalizing. Used when reporting cycles. root_ty: Ty<'tcx>, + + param_env: ty::ParamEnv<'tcx>, } /// Result from a generalization operation. This includes @@ -419,6 +422,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } fn tag(&self) -> &'static str { "Generalizer" diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 5eebe9e78d..5dfa0d29da 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -30,6 +30,8 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn a_is_expected(&self) -> bool { self.a_is_expected } fn relate_item_substs(&mut self, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index cbfb048c06..2ffcd2c4ac 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -269,8 +269,8 @@ impl<'tcx> TyCtxt<'tcx> { match item.node { hir::ImplItemKind::Method(..) => "method body", hir::ImplItemKind::Const(..) - | hir::ImplItemKind::Existential(..) - | hir::ImplItemKind::Type(..) => "associated item", + | hir::ImplItemKind::OpaqueTy(..) + | hir::ImplItemKind::TyAlias(..) => "associated item", } } @@ -662,19 +662,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } _ => { + // `last_ty` can be `!`, `expected` will have better info when present. + let t = self.resolve_vars_if_possible(&match exp_found { + Some(ty::error::ExpectedFound { expected, .. }) => expected, + _ => last_ty, + }); let msg = "`match` arms have incompatible types"; err.span_label(cause.span, msg); if prior_arms.len() <= 4 { for sp in prior_arms { - err.span_label(*sp, format!( - "this is found to be of type `{}`", - self.resolve_vars_if_possible(&last_ty), - )); + err.span_label( *sp, format!("this is found to be of type `{}`", t)); } } else if let Some(sp) = prior_arms.last() { - err.span_label(*sp, format!( - "this and all prior arms are found to be of type `{}`", last_ty, - )); + err.span_label( + *sp, + format!("this and all prior arms are found to be of type `{}`", t), + ); } } }, @@ -1143,27 +1146,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } (_, false, _) => { if let Some(exp_found) = exp_found { - let (def_id, ret_ty) = match exp_found.found.sty { - ty::FnDef(def, _) => { - (Some(def), Some(self.tcx.fn_sig(def).output())) - } - _ => (None, None), - }; - - let exp_is_struct = match exp_found.expected.sty { - ty::Adt(def, _) => def.is_struct(), - _ => false, - }; - - if let (Some(def_id), Some(ret_ty)) = (def_id, ret_ty) { - if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() { - let message = format!( - "did you mean `{}(/* fields */)`?", - self.tcx.def_path_str(def_id) - ); - diag.span_label(span, message); - } - } self.suggest_as_ref_where_appropriate(span, &exp_found, diag); } diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 4426b5c0e8..770d515577 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -5,7 +5,7 @@ use crate::infer::InferCtxt; use crate::infer::type_variable::TypeVariableOriginKind; use crate::ty::{self, Ty, Infer, TyVar}; use crate::ty::print::Print; -use syntax::source_map::CompilerDesugaringKind; +use syntax::source_map::DesugaringKind; use syntax_pos::Span; use errors::DiagnosticBuilder; @@ -194,12 +194,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { )); } else if let Some(pattern) = local_visitor.found_local_pattern { if let Some(simple_ident) = pattern.simple_ident() { - match pattern.span.compiler_desugaring_kind() { + match pattern.span.desugaring_kind() { None => labels.push(( pattern.span, format!("consider giving `{}` {}", simple_ident, suffix), )), - Some(CompilerDesugaringKind::ForLoop) => labels.push(( + Some(DesugaringKind::ForLoop) => labels.push(( pattern.span, "the element type for this iterator is not specified".to_owned(), )), diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs index 283af94b89..34f3b8a2c7 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -139,12 +139,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // error. We will then search the function parameters for a bound // region at the right depth with the same index (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => { - debug!( - "EarlyBound self.infcx.tcx.hir().local_def_id(id)={:?} \ - def_id={:?}", - id, - def_id - ); + debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { self.found_type = Some(arg); return; // we can stop visiting now @@ -162,8 +157,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { "FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index ); - debug!("self.infcx.tcx.hir().local_def_id(id)={:?}", id); - debug!("def_id={:?}", def_id); + debug!("LateBound id={:?} def_id={:?}", id, def_id); if debruijn_index == self.current_index && id == def_id { self.found_type = Some(arg); return; // we can stop visiting now @@ -231,12 +225,7 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> { } (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => { - debug!( - "EarlyBound self.infcx.tcx.hir().local_def_id(id)={:?} \ - def_id={:?}", - id, - def_id - ); + debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { self.found_it = true; return; // we can stop visiting now diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index 5502131674..2cef521176 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -27,6 +27,8 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn a_is_expected(&self) -> bool { self.a_is_expected } fn relate_with_variance>(&mut self, diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md index 56320636a6..7eb4da86ec 100644 --- a/src/librustc/infer/lexical_region_resolve/README.md +++ b/src/librustc/infer/lexical_region_resolve/README.md @@ -6,7 +6,7 @@ > As of edition 2018, region inference is done using Non-lexical lifetimes, > which is described in the guide and [this RFC]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check/region_inference.html [this RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md ## Terminology diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index d06c4434b3..6282fde59c 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -764,16 +764,17 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - span_bug!( + // Errors in earlier passes can yield error variables without + // resolution errors here; delay ICE in favor of those errors. + self.tcx().sess.delay_span_bug( self.var_infos[node_idx].origin.span(), - "collect_error_for_expanding_node() could not find \ - error for var {:?} in universe {:?}, lower_bounds={:#?}, \ - upper_bounds={:#?}", - node_idx, - node_universe, - lower_bounds, - upper_bounds - ); + &format!("collect_error_for_expanding_node() could not find \ + error for var {:?} in universe {:?}, lower_bounds={:#?}, \ + upper_bounds={:#?}", + node_idx, + node_universe, + lower_bounds, + upper_bounds)); } fn collect_concrete_regions( @@ -873,7 +874,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { constraints.retain(|constraint| { let (edge_changed, retain) = body(constraint); if edge_changed { - debug!("Updated due to constraint {:?}", constraint); + debug!("updated due to constraint {:?}", constraint); changed = true; } retain diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index 156288b9e6..e20372f151 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -27,6 +27,8 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn a_is_expected(&self) -> bool { self.a_is_expected } fn relate_with_variance>(&mut self, diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 663acd67dc..e1d77a97c1 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1351,23 +1351,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - pub fn resolve_const_var( - &self, - ct: &'tcx ty::Const<'tcx> - ) -> &'tcx ty::Const<'tcx> { - if let ty::Const { val: ConstValue::Infer(InferConst::Var(v)), .. } = ct { - self.const_unification_table - .borrow_mut() - .probe_value(*v) - .val - .known() - .map(|c| self.resolve_const_var(c)) - .unwrap_or(ct) - } else { - ct - } - } - pub fn fully_resolve>(&self, value: &T) -> FixupResult<'tcx, T> { /*! * Attempts to resolve all type/region/const variables in @@ -1586,7 +1569,7 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { // it can be resolved to an int/float variable, which // can then be recursively resolved, hence the // recursion. Note though that we prevent type - // variables from unifyxing to other type variables + // variables from unifying to other type variables // directly (though they may be embedded // structurally), and we prevent cycles in any case, // so this recursion should always be of very limited @@ -1626,17 +1609,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { } fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - match ct { - ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => { + if let ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } = ct { self.infcx.const_unification_table .borrow_mut() .probe_value(*vid) .val .known() - .map(|c| self.fold_const(c)) .unwrap_or(ct) - } - _ => ct, + } else { + ct } } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index a1a93eb552..5d521def65 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -364,7 +364,7 @@ where // been fully instantiated and hence the set of scopes we have // doesn't matter -- just to be sure, put an empty vector // in there. - let old_a_scopes = ::std::mem::replace(pair.vid_scopes(self), vec![]); + let old_a_scopes = ::std::mem::take(pair.vid_scopes(self)); // Relate the generalized kind to the original one. let result = pair.relate_generalized_ty(self, generalized_ty); @@ -502,6 +502,9 @@ where self.infcx.tcx } + // FIXME(oli-obk): not sure how to get the correct ParamEnv + fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() } + fn tag(&self) -> &'static str { "nll::subtype" } @@ -831,6 +834,9 @@ where self.infcx.tcx } + // FIXME(oli-obk): not sure how to get the correct ParamEnv + fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() } + fn tag(&self) -> &'static str { "nll::generalizer" } diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index f43e3fa0b7..5c62f76e3b 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -4,6 +4,7 @@ use crate::hir::Node; use crate::infer::outlives::free_region_map::FreeRegionRelations; use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind}; use crate::middle::region; +use crate::mir::interpret::ConstValue; use crate::traits::{self, PredicateObligation}; use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::subst::{InternalSubsts, Kind, SubstsRef, UnpackedKind}; @@ -17,19 +18,19 @@ use syntax_pos::Span; pub type OpaqueTypeMap<'tcx> = DefIdMap>; -/// Information about the opaque, abstract types whose values we +/// Information about the opaque types whose values we /// are inferring in this function (these are the `impl Trait` that /// appear in the return type). #[derive(Copy, Clone, Debug)] pub struct OpaqueTypeDecl<'tcx> { - /// The substitutions that we apply to the abstract that this + /// The substitutions that we apply to the opaque type that this /// `impl Trait` desugars to. e.g., if: /// /// fn foo<'a, 'b, T>() -> impl Trait<'a> /// /// winds up desugared to: /// - /// abstract type Foo<'x, X>: Trait<'x> + /// type Foo<'x, X> = impl Trait<'x> /// fn foo<'a, 'b, T>() -> Foo<'a, T> /// /// then `substs` would be `['a, T]`. @@ -39,7 +40,7 @@ pub struct OpaqueTypeDecl<'tcx> { /// for example: /// /// ``` - /// existential type Foo; + /// type Foo = impl Baz; /// fn bar() -> Foo { /// ^^^ This is the span we are looking for! /// ``` @@ -49,7 +50,7 @@ pub struct OpaqueTypeDecl<'tcx> { /// over-approximated, but better than nothing. pub definition_span: Span, - /// The type variable that represents the value of the abstract type + /// The type variable that represents the value of the opaque type /// that we require. In other words, after we compile this function, /// we will be created a constraint like: /// @@ -86,8 +87,8 @@ pub struct OpaqueTypeDecl<'tcx> { /// check.) pub has_required_region_bounds: bool, - /// The origin of the existential type - pub origin: hir::ExistTyOrigin, + /// The origin of the opaque type. + pub origin: hir::OpaqueTyOrigin, } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { @@ -142,8 +143,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { InferOk { value: (value, instantiator.opaque_types), obligations: instantiator.obligations } } - /// Given the map `opaque_types` containing the existential `impl - /// Trait` types whose underlying, hidden types are being + /// Given the map `opaque_types` containing the opaque + /// `impl Trait` types whose underlying, hidden types are being /// inferred, this method adds constraints to the regions /// appearing in those underlying hidden types to ensure that they /// at least do not refer to random scopes within the current @@ -163,12 +164,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Here, we have two `impl Trait` types whose values are being /// inferred (the `impl Bar<'a>` and the `impl /// Bar<'b>`). Conceptually, this is sugar for a setup where we - /// define underlying abstract types (`Foo1`, `Foo2`) and then, in + /// define underlying opaque types (`Foo1`, `Foo2`) and then, in /// the return type of `foo`, we *reference* those definitions: /// /// ```text - /// abstract type Foo1<'x>: Bar<'x>; - /// abstract type Foo2<'x>: Bar<'x>; + /// type Foo1<'x> = impl Bar<'x>; + /// type Foo2<'x> = impl Bar<'x>; /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. } /// // ^^^^ ^^ /// // | | @@ -227,7 +228,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// /// This is actually a bit of a tricky constraint in general. We /// want to say that each variable (e.g., `'0`) can only take on - /// values that were supplied as arguments to the abstract type + /// values that were supplied as arguments to the opaque type /// (e.g., `'a` for `Foo1<'a>`) or `'static`, which is always in /// scope. We don't have a constraint quite of this kind in the current /// region checker. @@ -264,24 +265,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// } /// /// // Equivalent to: - /// existential type FooReturn<'a, T>: Foo<'a>; + /// type FooReturn<'a, T> = impl Foo<'a>; /// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. } /// ``` /// /// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0` /// is an inference variable). If we generated a constraint that /// `Tc: 'a`, then this would incorrectly require that `T: 'a` -- - /// but this is not necessary, because the existential type we + /// but this is not necessary, because the opaque type we /// create will be allowed to reference `T`. So we only generate a /// constraint that `'0: 'a`. /// /// # The `free_region_relations` parameter /// /// The `free_region_relations` argument is used to find the - /// "minimum" of the regions supplied to a given abstract type. + /// "minimum" of the regions supplied to a given opaque type. /// It must be a relation that can answer whether `'a <= 'b`, /// where `'a` and `'b` are regions that appear in the "substs" - /// for the abstract type references (the `<'a>` in `Foo1<'a>`). + /// for the opaque type references (the `<'a>` in `Foo1<'a>`). /// /// Note that we do not impose the constraints based on the /// generic regions from the `Foo1` definition (e.g., `'x`). This @@ -297,7 +298,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// /// Here, the fact that `'b: 'a` is known only because of the /// implied bounds from the `&'a &'b u32` parameter, and is not - /// "inherent" to the abstract type definition. + /// "inherent" to the opaque type definition. /// /// # Parameters /// @@ -360,7 +361,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // There were no `required_region_bounds`, // so we have to search for a `least_region`. // Go through all the regions used as arguments to the - // abstract type. These are the parameters to the abstract + // opaque type. These are the parameters to the opaque // type; so in our example above, `substs` would contain // `['a]` for the first impl trait and `'b` for the // second. @@ -491,11 +492,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Without a feature-gate, we only generate member-constraints for async-await. let context_name = match opaque_defn.origin { // No feature-gate required for `async fn`. - hir::ExistTyOrigin::AsyncFn => return false, + hir::OpaqueTyOrigin::AsyncFn => return false, // Otherwise, generate the label we'll use in the error message. - hir::ExistTyOrigin::ExistentialType => "existential type", - hir::ExistTyOrigin::ReturnImplTrait => "impl Trait", + hir::OpaqueTyOrigin::TypeAlias => "impl Trait", + hir::OpaqueTyOrigin::FnReturn => "impl Trait", }; let msg = format!("ambiguous lifetime bound in `{}`", context_name); let mut err = self.tcx.sess.struct_span_err(span, &msg); @@ -527,12 +528,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Given the fully resolved, instantiated type for an opaque /// type, i.e., the value of an inference variable like C1 or C2 - /// (*), computes the "definition type" for an abstract type + /// (*), computes the "definition type" for an opaque type /// definition -- that is, the inferred value of `Foo1<'x>` or /// `Foo2<'x>` that we would conceptually use in its definition: /// - /// abstract type Foo1<'x>: Bar<'x> = AAA; <-- this type AAA - /// abstract type Foo2<'x>: Bar<'x> = BBB; <-- or this type BBB + /// type Foo1<'x> = impl Bar<'x> = AAA; <-- this type AAA + /// type Foo2<'x> = impl Bar<'x> = BBB; <-- or this type BBB /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. } /// /// Note that these values are defined in terms of a distinct set of @@ -553,6 +554,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { def_id: DefId, opaque_defn: &OpaqueTypeDecl<'tcx>, instantiated_ty: Ty<'tcx>, + span: Span, ) -> Ty<'tcx> { debug!( "infer_opaque_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})", @@ -584,6 +586,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { def_id, map, instantiated_ty, + span, )); debug!("infer_opaque_definition_from_instantiation: definition_ty={:?}", definition_ty); @@ -761,6 +764,9 @@ struct ReverseMapper<'tcx> { /// initially `Some`, set to `None` once error has been reported hidden_ty: Option>, + + /// Span of function being checked. + span: Span, } impl ReverseMapper<'tcx> { @@ -770,6 +776,7 @@ impl ReverseMapper<'tcx> { opaque_type_def_id: DefId, map: FxHashMap, Kind<'tcx>>, hidden_ty: Ty<'tcx>, + span: Span, ) -> Self { Self { tcx, @@ -778,6 +785,7 @@ impl ReverseMapper<'tcx> { map, map_missing_regions_to_empty: false, hidden_ty: Some(hidden_ty), + span, } } @@ -812,10 +820,11 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { _ => { } } + let generics = self.tcx().generics_of(self.opaque_type_def_id); match self.map.get(&r.into()).map(|k| k.unpack()) { Some(UnpackedKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), - None => { + None if generics.parent.is_some() => { if !self.map_missing_regions_to_empty && !self.tainted_by_errors { if let Some(hidden_ty) = self.hidden_ty.take() { unexpected_hidden_region_diagnostic( @@ -829,6 +838,21 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } self.tcx.lifetimes.re_empty } + None => { + self.tcx.sess + .struct_span_err( + self.span, + "non-defining opaque type use in defining scope" + ) + .span_label( + self.span, + format!("lifetime `{}` is part of concrete type but not used in \ + parameter list of the `impl Trait` type alias", r), + ) + .emit(); + + self.tcx().global_tcx().mk_region(ty::ReStatic) + }, } } @@ -839,7 +863,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { // we encounter a closure here, it is always a closure // from within the function that we are currently // type-checking -- one that is now being encapsulated - // in an existential abstract type. Ideally, we would + // in an opaque type. Ideally, we would // go through the types/lifetimes that it references // and treat them just like we would any other type, // which means we would error out if we find any @@ -890,9 +914,61 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability) } + ty::Param(..) => { + // Look it up in the substitution list. + match self.map.get(&ty.into()).map(|k| k.unpack()) { + // Found it in the substitution list; replace with the parameter from the + // opaque type. + Some(UnpackedKind::Type(t1)) => t1, + Some(u) => panic!("type mapped to unexpected kind: {:?}", u), + None => { + self.tcx.sess + .struct_span_err( + self.span, + &format!("type parameter `{}` is part of concrete type but not \ + used in parameter list for the `impl Trait` type alias", + ty), + ) + .emit(); + + self.tcx().types.err + } + } + } + _ => ty.super_fold_with(self), } } + + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + trace!("checking const {:?}", ct); + // Find a const parameter + match ct.val { + ConstValue::Param(..) => { + // Look it up in the substitution list. + match self.map.get(&ct.into()).map(|k| k.unpack()) { + // Found it in the substitution list, replace with the parameter from the + // opaque type. + Some(UnpackedKind::Const(c1)) => c1, + Some(u) => panic!("const mapped to unexpected kind: {:?}", u), + None => { + self.tcx.sess + .struct_span_err( + self.span, + &format!("const parameter `{}` is part of concrete type but not \ + used in parameter list for the `impl Trait` type alias", + ct) + ) + .emit(); + + self.tcx().consts.err + } + } + } + + _ => ct, + } + } } struct Instantiator<'a, 'tcx> { @@ -918,15 +994,15 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { // value we are inferring. At present, this is // always true during the first phase of // type-check, but not always true later on during - // NLL. Once we support named abstract types more fully, + // NLL. Once we support named opaque types more fully, // this same scenario will be able to arise during all phases. // - // Here is an example using `abstract type` that indicates - // the distinction we are checking for: + // Here is an example using type alias `impl Trait` + // that indicates the distinction we are checking for: // // ```rust // mod a { - // pub abstract type Foo: Iterator; + // pub type Foo = impl Iterator; // pub fn make_foo() -> Foo { .. } // } // @@ -951,42 +1027,46 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let parent_def_id = self.parent_def_id; let def_scope_default = || { let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); - parent_def_id - == tcx.hir().local_def_id_from_hir_id(opaque_parent_hir_id) + parent_def_id == tcx.hir() + .local_def_id(opaque_parent_hir_id) }; let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) { Some(Node::Item(item)) => match item.node { // Anonymous `impl Trait` - hir::ItemKind::Existential(hir::ExistTy { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(parent), origin, .. }) => (parent == self.parent_def_id, origin), - // Named `existential type` - hir::ItemKind::Existential(hir::ExistTy { + // Named `type Foo = impl Bar;` + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, origin, .. }) => ( - may_define_existential_type( + may_define_opaque_type( tcx, self.parent_def_id, opaque_hir_id, ), origin, ), - _ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType), + _ => { + (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias) + } }, Some(Node::ImplItem(item)) => match item.node { - hir::ImplItemKind::Existential(_) => ( - may_define_existential_type( + hir::ImplItemKind::OpaqueTy(_) => ( + may_define_opaque_type( tcx, self.parent_def_id, opaque_hir_id, ), - hir::ExistTyOrigin::ExistentialType, + hir::OpaqueTyOrigin::TypeAlias, ), - _ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType), + _ => { + (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias) + } }, _ => bug!( "expected (impl) item, found {}", @@ -1018,7 +1098,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { ty: Ty<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, - origin: hir::ExistTyOrigin, + origin: hir::OpaqueTyOrigin, ) -> Ty<'tcx> { let infcx = self.infcx; let tcx = infcx.tcx; @@ -1037,13 +1117,19 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let predicates_of = tcx.predicates_of(def_id); debug!("instantiate_opaque_types: predicates={:#?}", predicates_of,); let bounds = predicates_of.instantiate(tcx, substs); + + let param_env = tcx.param_env(def_id); + let InferOk { value: bounds, obligations } = + infcx.partially_normalize_associated_types_in(span, self.body_id, param_env, &bounds); + self.obligations.extend(obligations); + debug!("instantiate_opaque_types: bounds={:?}", bounds); let required_region_bounds = tcx.required_region_bounds(ty, bounds.predicates.clone()); debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds); // Make sure that we are in fact defining the *entire* type - // (e.g., `existential type Foo: Bar;` needs to be + // (e.g., `type Foo = impl Bar;` needs to be // defined by a function like `fn foo() -> Foo`). debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,); debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),); @@ -1091,7 +1177,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { /// ```rust /// pub mod foo { /// pub mod bar { -/// pub existential type Baz; +/// pub trait Bar { .. } +/// +/// pub type Baz = impl Bar; /// /// fn f1() -> Baz { .. } /// } @@ -1100,27 +1188,29 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { /// } /// ``` /// -/// Here, `def_id` is the `DefId` of the defining use of the existential type (e.g., `f1` or `f2`), -/// and `opaque_hir_id` is the `HirId` of the definition of the existential type `Baz`. +/// Here, `def_id` is the `DefId` of the defining use of the opaque type (e.g., `f1` or `f2`), +/// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`. /// For the above example, this function returns `true` for `f1` and `false` for `f2`. -pub fn may_define_existential_type( +pub fn may_define_opaque_type( tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir::HirId, ) -> bool { let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); - trace!( - "may_define_existential_type(def={:?}, opaque_node={:?})", - tcx.hir().get(hir_id), - tcx.hir().get(opaque_hir_id) - ); - // Named existential types can be defined by any siblings or children of siblings. + // Named opaque types can be defined by any siblings or children of siblings. let scope = tcx.hir().get_defining_scope(opaque_hir_id).expect("could not get defining scope"); // We walk up the node tree until we hit the root or the scope of the opaque type. while hir_id != scope && hir_id != hir::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id); } // Syntactically, we are allowed to define the concrete type if: - hir_id == scope + let res = hir_id == scope; + trace!( + "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}", + tcx.hir().get(hir_id), + tcx.hir().get(opaque_hir_id), + res + ); + res } diff --git a/src/librustc/infer/outlives/env.rs b/src/librustc/infer/outlives/env.rs index d555886128..e6155454d4 100644 --- a/src/librustc/infer/outlives/env.rs +++ b/src/librustc/infer/outlives/env.rs @@ -27,7 +27,7 @@ use crate::ty::{self, Ty}; /// interested in the `OutlivesEnvironment`. -nmatsakis #[derive(Clone)] pub struct OutlivesEnvironment<'tcx> { - param_env: ty::ParamEnv<'tcx>, + pub param_env: ty::ParamEnv<'tcx>, free_region_map: FreeRegionMap<'tcx>, // Contains, for each body B that we are checking (that is, the fn diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 0ae4446ee6..e1470e4ef0 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -112,7 +112,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Trait queries just want to pass back type obligations "as is" pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> { - ::std::mem::replace(&mut *self.region_obligations.borrow_mut(), vec![]) + ::std::mem::take(&mut *self.region_obligations.borrow_mut()) } /// Process the region obligations that must be proven (during diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs index 30f6137289..0c83bbc1e5 100644 --- a/src/librustc/infer/region_constraints/leak_check.rs +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -78,10 +78,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } return Err(if overly_polymorphic { - debug!("Overly polymorphic!"); + debug!("overly polymorphic!"); TypeError::RegionsOverlyPolymorphic(placeholder.name, tainted_region) } else { - debug!("Not as polymorphic!"); + debug!("not as polymorphic!"); TypeError::RegionsInsufficientlyPolymorphic(placeholder.name, tainted_region) }); } diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index fcb116fce5..21904edb30 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -455,7 +455,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { *any_unifications = false; } - mem::replace(data, RegionConstraintData::default()) + mem::take(data) } pub fn data(&self) -> &RegionConstraintData<'tcx> { diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index 1452a6dee5..cd1d206b5f 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -35,6 +35,9 @@ impl<'combine, 'infcx, 'tcx> Sub<'combine, 'infcx, 'tcx> { impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { fn tag(&self) -> &'static str { "Sub" } fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx } + + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn a_is_expected(&self) -> bool { self.a_is_expected } fn with_cause(&mut self, cause: Cause, f: F) -> R diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index dcafb0f397..e30e86998a 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -115,7 +115,7 @@ impl<'tcx> TypeVariableTable<'tcx> { /// /// Note that this function does not return care whether /// `vid` has been unified with something else or not. - pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool { + pub fn var_diverges(&self, vid: ty::TyVid) -> bool { self.values.get(vid.index as usize).diverging } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 257d5159f1..8d4cd51e46 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -28,13 +28,11 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(const_fn)] +#![feature(const_transmute)] #![feature(core_intrinsics)] #![feature(drain_filter)] #![feature(inner_deref)] @@ -45,11 +43,9 @@ #![feature(extern_types)] #![feature(nll)] #![feature(non_exhaustive)] -#![feature(proc_macro_internals)] #![feature(optin_builtin_traits)] #![feature(range_is_empty)] #![feature(rustc_diagnostic_macros)] -#![feature(rustc_attrs)] #![feature(slice_patterns)] #![feature(specialization)] #![feature(unboxed_closures)] @@ -57,7 +53,6 @@ #![feature(trace_macros)] #![feature(trusted_len)] #![feature(vec_remove_item)] -#![feature(step_trait)] #![feature(stmt_expr_attributes)] #![feature(integer_atomics)] #![feature(test)] @@ -65,6 +60,8 @@ #![feature(crate_visibility_modifier)] #![feature(proc_macro_hygiene)] #![feature(log_syntax)] +#![feature(mem_take)] +#![feature(associated_type_bounds)] #![recursion_limit="512"] @@ -76,24 +73,16 @@ extern crate getopts; extern crate libc; #[macro_use] extern crate rustc_macros; #[macro_use] extern crate rustc_data_structures; - #[macro_use] extern crate log; #[macro_use] extern crate syntax; - -// FIXME: This import is used by deriving `RustcDecodable` and `RustcEncodable`. Removing this -// results in a bunch of "failed to resolve" errors. Hopefully, the compiler moves to serde or -// something, and we can get rid of this. -#[allow(rust_2018_idioms)] -extern crate serialize as rustc_serialize; - #[macro_use] extern crate smallvec; -// Note that librustc doesn't actually depend on these crates, see the note in -// `Cargo.toml` for this crate about why these are here. -#[allow(unused_extern_crates)] -extern crate flate2; -#[allow(unused_extern_crates)] -extern crate test; +// Use the test crate here so we depend on getopts through it. This allow tools to link to both +// librustc_driver and libtest. +extern crate test as _; + +#[cfg(test)] +mod tests; #[macro_use] mod macros; @@ -115,7 +104,6 @@ pub mod infer; pub mod lint; pub mod middle { - pub mod allocator; pub mod borrowck; pub mod expr_use_visitor; pub mod cstore; @@ -154,18 +142,5 @@ pub mod util { // Allows macros to refer to this crate as `::rustc` extern crate self as rustc; -// FIXME(#27438): right now the unit tests of librustc don't refer to any actual -// functions generated in librustc_data_structures (all -// references are through generic functions), but statics are -// referenced from time to time. Due to this bug we won't -// actually correctly link in the statics unless we also -// reference a function, so be sure to reference a dummy -// function. -#[test] -fn noop() { - rustc_data_structures::__noop_fix_for_27438(); -} - - // Build the diagnostics array at the end so that the metadata includes error use sites. __build_diagnostic_array! { librustc, DIAGNOSTICS } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 45e598531b..dd290572d7 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -5,10 +5,12 @@ //! lints are all available in `rustc_lint::builtin`. use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::middle::stability; use crate::session::Session; use errors::{Applicability, DiagnosticBuilder}; use syntax::ast; use syntax::source_map::Span; +use syntax::symbol::Symbol; declare_lint! { pub EXCEEDING_BITSHIFTS, @@ -92,19 +94,19 @@ declare_lint! { declare_lint! { pub UNUSED_FEATURES, Warn, - "unused features found in crate-level #[feature] directives" + "unused features found in crate-level `#[feature]` directives" } declare_lint! { pub STABLE_FEATURES, Warn, - "stable features found in #[feature] directive" + "stable features found in `#[feature]` directive" } declare_lint! { pub UNKNOWN_CRATE_TYPES, Deny, - "unknown crate type found in #[crate_type] directive" + "unknown crate type found in `#[crate_type]` directive" } declare_lint! { @@ -346,6 +348,13 @@ declare_lint! { "outlives requirements can be inferred" } +declare_lint! { + pub INDIRECT_STRUCTURAL_MATCH, + // defaulting to allow until rust-lang/rust#62614 is fixed. + Allow, + "pattern with const indirectly referencing non-`#[structural_match]` type" +} + /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. pub mod parser { declare_lint! { @@ -353,6 +362,12 @@ pub mod parser { Warn, "ill-formed attribute inputs that were previously accepted and used in practice" } + + declare_lint! { + pub META_VARIABLE_MISUSE, + Allow, + "possible meta-variable misuse at macro definition" + } } declare_lint! { @@ -380,6 +395,12 @@ declare_lint! { "reservation of a two-phased borrow conflicts with other shared borrows" } +declare_lint! { + pub SOFT_UNSTABLE, + Deny, + "a feature gate that doesn't break dependent crates" +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -439,10 +460,13 @@ declare_lint_pass! { MACRO_USE_EXTERN_CRATE, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, parser::ILL_FORMED_ATTRIBUTE_INPUT, + parser::META_VARIABLE_MISUSE, DEPRECATED_IN_FUTURE, AMBIGUOUS_ASSOCIATED_ITEMS, NESTED_IMPL_TRAIT, MUTABLE_BORROW_RESERVATION_CONFLICT, + INDIRECT_STRUCTURAL_MATCH, + SOFT_UNSTABLE, ] } @@ -461,6 +485,7 @@ pub enum BuiltinLintDiagnostics { UnusedImports(String, Vec<(Span, String)>), NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span }, RedundantImport(Vec<(Span, bool)>, ast::Ident), + DeprecatedMacro(Option, Span), } pub(crate) fn add_elided_lifetime_in_path_suggestion( @@ -586,6 +611,8 @@ impl BuiltinLintDiagnostics { ); } } + BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => + stability::deprecation_suggestion(db, suggestion, span), } } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 7f09120bbd..de812410e8 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -23,7 +23,7 @@ use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; -use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; +use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use crate::session::{config, early_error, Session}; use crate::ty::{self, print::Printer, subst::Kind, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; @@ -926,7 +926,7 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> LateContextAndPass<'a, 'tcx, T> { { let old_param_env = self.context.param_env; self.context.param_env = self.context.tcx.param_env( - self.context.tcx.hir().local_def_id_from_hir_id(id) + self.context.tcx.hir().local_def_id(id) ); f(self); self.context.param_env = old_param_env; @@ -966,6 +966,13 @@ for LateContextAndPass<'a, 'tcx, T> { self.context.tables = old_tables; } + fn visit_arg(&mut self, arg: &'tcx hir::Arg) { + self.with_lint_attrs(arg.hir_id, &arg.attrs, |cx| { + lint_callback!(cx, check_arg, arg); + hir_visit::walk_arg(cx, arg); + }); + } + fn visit_body(&mut self, body: &'tcx hir::Body) { lint_callback!(self, check_body, body); hir_visit::walk_body(self, body); @@ -1156,6 +1163,13 @@ for LateContextAndPass<'a, 'tcx, T> { } impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> { + fn visit_arg(&mut self, arg: &'a ast::Arg) { + self.with_lint_attrs(arg.id, &arg.attrs, |cx| { + run_early_pass!(cx, check_arg, arg); + ast_visit::walk_arg(cx, arg); + }); + } + fn visit_item(&mut self, it: &'a ast::Item) { self.with_lint_attrs(it.id, &it.attrs, |cx| { run_early_pass!(cx, check_item, it); @@ -1341,6 +1355,7 @@ struct LateLintPassObjects<'a> { lints: &'a mut [LateLintPassObject], } +#[cfg_attr(not(bootstrap), allow(rustc::lint_pass_impl_without_macro))] impl LintPass for LateLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() @@ -1500,7 +1515,7 @@ pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( time(tcx.sess, "module lints", || { // Run per-module lints par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().lint_mod(tcx.hir().local_def_id(module)); + tcx.ensure().lint_mod(tcx.hir().local_def_id_from_node_id(module)); }); }); }); @@ -1510,6 +1525,7 @@ struct EarlyLintPassObjects<'a> { lints: &'a mut [EarlyLintPassObject], } +#[cfg_attr(not(bootstrap), allow(rustc::lint_pass_impl_without_macro))] impl LintPass for EarlyLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 86dae579ca..0b514f5927 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -7,11 +7,12 @@ use crate::lint::{ }; use errors::Applicability; use rustc_data_structures::fx::FxHashMap; -use syntax::ast::Ident; +use syntax::ast::{Ident, Item, ItemKind}; use syntax::symbol::{sym, Symbol}; +use syntax_pos::ExpnInfo; -declare_lint! { - pub DEFAULT_HASH_TYPES, +declare_tool_lint! { + pub rustc::DEFAULT_HASH_TYPES, Allow, "forbid HashMap and HashSet and suggest the FxHash* variants" } @@ -22,7 +23,7 @@ pub struct DefaultHashTypes { impl DefaultHashTypes { // we are allowed to use `HashMap` and `HashSet` as identifiers for implementing the lint itself - #[allow(internal)] + #[cfg_attr(not(bootstrap), allow(rustc::default_hash_types))] pub fn new() -> Self { let mut map = FxHashMap::default(); map.insert(sym::HashMap, sym::FxHashMap); @@ -36,10 +37,7 @@ impl_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]); impl EarlyLintPass for DefaultHashTypes { fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) { if let Some(replace) = self.map.get(&ident.name) { - let msg = format!( - "Prefer {} over {}, it has better performance", - replace, ident - ); + let msg = format!("Prefer {} over {}, it has better performance", replace, ident); let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg); db.span_suggestion( ident.span, @@ -47,29 +45,26 @@ impl EarlyLintPass for DefaultHashTypes { replace.to_string(), Applicability::MaybeIncorrect, // FxHashMap, ... needs another import ); - db.note(&format!( - "a `use rustc_data_structures::fx::{}` may be necessary", - replace - )) - .emit(); + db.note(&format!("a `use rustc_data_structures::fx::{}` may be necessary", replace)) + .emit(); } } } -declare_lint! { - pub USAGE_OF_TY_TYKIND, +declare_tool_lint! { + pub rustc::USAGE_OF_TY_TYKIND, Allow, "usage of `ty::TyKind` outside of the `ty::sty` module" } -declare_lint! { - pub TY_PASS_BY_REFERENCE, +declare_tool_lint! { + pub rustc::TY_PASS_BY_REFERENCE, Allow, "passing `Ty` or `TyCtxt` by reference" } -declare_lint! { - pub USAGE_OF_QUALIFIED_TY, +declare_tool_lint! { + pub rustc::USAGE_OF_QUALIFIED_TY, Allow, "using `ty::{Ty,TyCtxt}` instead of importing it" } @@ -137,13 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind { } } } - TyKind::Rptr( - _, - MutTy { - ty: inner_ty, - mutbl: Mutability::MutImmutable, - }, - ) => { + TyKind::Rptr(_, MutTy { ty: inner_ty, mutbl: Mutability::MutImmutable }) => { if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner_def_id()) { if cx.tcx.impl_trait_ref(impl_did).is_some() { return; @@ -225,3 +214,44 @@ fn gen_args(segment: &PathSegment) -> String { String::new() } + +declare_tool_lint! { + pub rustc::LINT_PASS_IMPL_WITHOUT_MACRO, + Allow, + "`impl LintPass` without the `declare_lint_pass!` or `impl_lint_pass!` macros" +} + +declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]); + +impl EarlyLintPass for LintPassImpl { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node { + if let Some(last) = lint_pass.path.segments.last() { + if last.ident.name == sym::LintPass { + match &lint_pass.path.span.ctxt().outer_expn_info() { + Some(info) if is_lint_pass_expansion(info) => {} + _ => { + cx.struct_span_lint( + LINT_PASS_IMPL_WITHOUT_MACRO, + lint_pass.path.span, + "implementing `LintPass` by hand", + ) + .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead") + .emit(); + } + } + } + } + } + } +} + +fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool { + if expn_info.kind.descr() == sym::impl_lint_pass { + true + } else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() { + info.kind.descr() == sym::declare_lint_pass + } else { + false + } +} diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 309af4b72c..8ddf460349 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -27,7 +27,7 @@ use crate::hir::def_id::{CrateNum, LOCAL_CRATE}; use crate::hir::intravisit; use crate::hir; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::lint::builtin::parser::ILL_FORMED_ATTRIBUTE_INPUT; +use crate::lint::builtin::parser::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; use crate::session::{Session, DiagnosticMessageId}; use crate::ty::TyCtxt; use crate::ty::query::Providers; @@ -35,9 +35,10 @@ use crate::util::nodemap::NodeMap; use errors::{DiagnosticBuilder, DiagnosticId}; use std::{hash, ptr}; use syntax::ast; -use syntax::source_map::{MultiSpan, ExpnFormat, CompilerDesugaringKind}; +use syntax::source_map::{MultiSpan, ExpnKind, DesugaringKind}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; +use syntax::ext::base::MacroKind; use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; @@ -81,6 +82,7 @@ impl Lint { pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self { match lint_id { BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT, + BufferedEarlyLintId::MetaVariableMisuse => META_VARIABLE_MISUSE, } } @@ -204,6 +206,7 @@ macro_rules! declare_lint_pass { macro_rules! late_lint_methods { ($macro:path, $args:tt, [$hir:tt]) => ( $macro!($args, [$hir], [ + fn check_arg(a: &$hir hir::Arg); fn check_body(a: &$hir hir::Body); fn check_body_post(a: &$hir hir::Body); fn check_name(a: Span, b: ast::Name); @@ -356,6 +359,7 @@ macro_rules! declare_combined_late_lint_pass { macro_rules! early_lint_methods { ($macro:path, $args:tt) => ( $macro!($args, [ + fn check_arg(a: &ast::Arg); fn check_ident(a: ast::Ident); fn check_crate(a: &ast::Crate); fn check_crate_post(a: &ast::Crate); @@ -493,8 +497,6 @@ pub type EarlyLintPassObject = Box LateLintPass<'a, 'tcx> + sync::Send + sync::Sync + 'static>; - - /// Identifies a lint known to the compiler. #[derive(Clone, Copy, Debug)] pub struct LintId { @@ -670,7 +672,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, sess.diag_note_once( &mut err, DiagnosticMessageId::from(lint), - &format!("#[{}({})] on by default", level.as_str(), name)); + &format!("`#[{}({})]` on by default", level.as_str(), name)); } LintSource::CommandLine(lint_flag_val) => { let flag = match level { @@ -705,7 +707,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, if lint_attr_name.as_str() != name { let level_str = level.as_str(); sess.diag_note_once(&mut err, DiagnosticMessageId::from(lint), - &format!("#[{}({})] implied by #[{}({})]", + &format!("`#[{}({})]` implied by `#[{}({})]`", level_str, name, level_str, lint_attr_name)); } } @@ -765,7 +767,7 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) } -fn lint_levels<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx LintLevelMap { +fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); let mut builder = LintLevelMapBuilder { levels: LintLevelSets::builder(tcx.sess), @@ -810,6 +812,12 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { intravisit::NestedVisitorMap::All(&self.tcx.hir()) } + fn visit_arg(&mut self, arg: &'tcx hir::Arg) { + self.with_lint_attrs(arg.hir_id, &arg.attrs, |builder| { + intravisit::walk_arg(builder, arg); + }); + } + fn visit_item(&mut self, it: &'tcx hir::Item) { self.with_lint_attrs(it.hir_id, &it.attrs, |builder| { intravisit::walk_item(builder, it); @@ -883,36 +891,30 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { None => return false, }; - match info.format { - ExpnFormat::MacroAttribute(..) => true, // definitely a plugin - ExpnFormat::CompilerDesugaring(CompilerDesugaringKind::ForLoop) => false, - ExpnFormat::CompilerDesugaring(_) => true, // well, it's "external" - ExpnFormat::MacroBang(..) => { - let def_site = match info.def_site { - Some(span) => span, - // no span for the def_site means it's an external macro - None => return true, - }; - - match sess.source_map().span_to_snippet(def_site) { + match info.kind { + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, + ExpnKind::Desugaring(_) => true, // well, it's "external" + ExpnKind::Macro(MacroKind::Bang, _) => { + if info.def_site.is_dummy() { + // dummy span for the def_site means it's an external macro + return true; + } + match sess.source_map().span_to_snippet(info.def_site) { Ok(code) => !code.starts_with("macro_rules"), // no snippet = external macro or compiler-builtin expansion Err(_) => true, } } + ExpnKind::Macro(..) => true, // definitely a plugin } } /// Returns whether `span` originates in a derive macro's expansion pub fn in_derive_expansion(span: Span) -> bool { - let info = match span.ctxt().outer_expn_info() { - Some(info) => info, - // no ExpnInfo means this span doesn't come from a macro - None => return false, - }; - - match info.format { - ExpnFormat::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("), - _ => false, + if let Some(info) = span.ctxt().outer_expn_info() { + if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind { + return true; + } } + false } diff --git a/src/librustc/middle/allocator.rs b/src/librustc/middle/allocator.rs deleted file mode 100644 index bb2e3b4ec1..0000000000 --- a/src/librustc/middle/allocator.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[derive(Clone, Copy)] -pub enum AllocatorKind { - Global, - DefaultLib, - DefaultExe, -} - -impl AllocatorKind { - pub fn fn_name(&self, base: &str) -> String { - match *self { - AllocatorKind::Global => format!("__rg_{}", base), - AllocatorKind::DefaultLib => format!("__rdl_{}", base), - AllocatorKind::DefaultExe => format!("__rde_{}", base), - } - } -} diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index 2799f9424d..60c24eeae7 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -1,6 +1,4 @@ use crate::ich::StableHashingContext; -use crate::hir::HirId; -use crate::util::nodemap::FxHashSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; @@ -18,7 +16,6 @@ impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen }); #[derive(Debug, Default, RustcEncodable, RustcDecodable)] pub struct BorrowCheckResult { - pub used_mut_nodes: FxHashSet, pub signalled_any_error: SignalledError, } @@ -27,10 +24,8 @@ impl<'a> HashStable> for BorrowCheckResult { hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let BorrowCheckResult { - ref used_mut_nodes, ref signalled_any_error, } = *self; - used_mut_nodes.hash_stable(hcx, hasher); signalled_any_error.hash_stable(hcx, hasher); } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 2e9e1ac582..d37b2367ae 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -87,7 +87,7 @@ pub enum LinkagePreference { RequireStatic, } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] pub enum NativeLibraryKind { /// native static library (.a archive) @@ -100,7 +100,7 @@ pub enum NativeLibraryKind { NativeUnknown, } -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] pub struct NativeLibrary { pub kind: NativeLibraryKind, pub name: Option, @@ -211,7 +211,7 @@ pub trait CrateStore { fn crates_untracked(&self) -> Vec; // utility functions - fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata; + fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata; fn metadata_encoding_version(&self) -> &[u8]; } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index e02ee89436..55fa261f1e 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -26,7 +26,7 @@ use syntax_pos; // explored. For example, if it's a live Node::Item that is a // function, then we should explore its block to check for codes that // may need to be marked as live. -fn should_explore<'tcx>(tcx: TyCtxt<'tcx>, hir_id: hir::HirId) -> bool { +fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { match tcx.hir().find(hir_id) { Some(Node::Item(..)) | Some(Node::ImplItem(..)) | @@ -161,7 +161,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { Node::Item(item) => { match item.node { hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let def = self.tcx.adt_def(def_id); self.repr_has_repr_c = def.repr.c(); @@ -269,8 +269,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { fn visit_pat(&mut self, pat: &'tcx hir::Pat) { match pat.node { - PatKind::Struct(hir::QPath::Resolved(_, ref path), ref fields, _) => { - self.handle_field_pattern_match(pat, path.res, fields); + PatKind::Struct(ref path, ref fields, _) => { + let res = self.tables.qpath_res(path, pat.hir_id); + self.handle_field_pattern_match(pat, res, fields); } PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => { let res = self.tables.qpath_res(qpath, pat.hir_id); @@ -320,12 +321,7 @@ fn has_allow_dead_code_or_lang_attr( return true; } - // Don't lint about global allocators - if attr::contains_name(attrs, sym::global_allocator) { - return true; - } - - let def_id = tcx.hir().local_def_id_from_hir_id(id); + let def_id = tcx.hir().local_def_id(id); let cg_attrs = tcx.codegen_fn_attrs(def_id); // #[used], #[no_mangle], #[export_name], etc also keeps the item alive @@ -484,7 +480,7 @@ impl DeadVisitor<'tcx> { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::Fn(..) - | hir::ItemKind::Ty(..) + | hir::ItemKind::TyAlias(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => true, @@ -494,7 +490,7 @@ impl DeadVisitor<'tcx> { } fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool { - let field_type = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id)); + let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id)); !field.is_positional() && !self.symbol_is_live(field.hir_id) && !field_type.is_phantom_data() @@ -525,7 +521,7 @@ impl DeadVisitor<'tcx> { // This is done to handle the case where, for example, the static // method of a private type is used, but the type itself is never // called directly. - let def_id = self.tcx.hir().local_def_id_from_hir_id(id); + let def_id = self.tcx.hir().local_def_id(id); let inherent_impls = self.tcx.inherent_impls(def_id); for &impl_did in inherent_impls.iter() { for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] { @@ -643,8 +639,8 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } self.visit_nested_body(body_id) } - hir::ImplItemKind::Existential(..) | - hir::ImplItemKind::Type(..) => {} + hir::ImplItemKind::OpaqueTy(..) | + hir::ImplItemKind::TyAlias(..) => {} } } @@ -662,7 +658,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } } -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_crate(tcx: TyCtxt<'_>) { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); let krate = tcx.hir().krate(); let live_symbols = find_live(tcx, access_levels, krate); diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 879da6413e..96b99fe4cd 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -81,7 +81,7 @@ pub enum Linkage { Dynamic, } -pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn calculate(tcx: TyCtxt<'_>) { let sess = &tcx.sess; let fmts = sess.crate_types.borrow().iter().map(|&ty| { let linkage = calculate_type(tcx, ty); @@ -92,7 +92,7 @@ pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) { sess.dependency_formats.set(fmts); } -fn calculate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: config::CrateType) -> DependencyList { +fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { let sess = &tcx.sess; if !sess.opts.output_types.should_codegen() { @@ -267,7 +267,7 @@ fn add_library( } } -fn attempt_static<'tcx>(tcx: TyCtxt<'tcx>) -> Option { +fn attempt_static(tcx: TyCtxt<'_>) -> Option { let sess = &tcx.sess; let crates = cstore::used_crates(tcx, RequireStatic); if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) { @@ -324,7 +324,7 @@ fn activate_injected_dep(injected: Option, // After the linkage for a crate has been determined we need to verify that // there's only going to be one allocator in the output. -fn verify_ok<'tcx>(tcx: TyCtxt<'tcx>, list: &[Linkage]) { +fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { let sess = &tcx.sess; if list.len() == 0 { return diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index d1867e8fa3..53c099c0b4 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -32,7 +32,7 @@ struct EntryContext<'a, 'tcx> { impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx Item) { - let def_id = self.map.local_def_id_from_hir_id(item.hir_id); + let def_id = self.map.local_def_id(item.hir_id); let def_key = self.map.def_key(def_id); let at_root = def_key.parent == Some(CRATE_DEF_INDEX); find_item(item, self, at_root); @@ -120,9 +120,9 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { ctxt.attr_main_fn = Some((item.hir_id, item.span)); } else { struct_span_err!(ctxt.session, item.span, E0137, - "multiple functions with a #[main] attribute") - .span_label(item.span, "additional #[main] function") - .span_label(ctxt.attr_main_fn.unwrap().1, "first #[main] function") + "multiple functions with a `#[main]` attribute") + .span_label(item.span, "additional `#[main]` function") + .span_label(ctxt.attr_main_fn.unwrap().1, "first `#[main]` function") .emit(); } }, @@ -142,11 +142,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> { if let Some((hir_id, _)) = visitor.start_fn { - Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Start)) + Some((tcx.hir().local_def_id(hir_id), EntryFnType::Start)) } else if let Some((hir_id, _)) = visitor.attr_main_fn { - Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Main)) + Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main)) } else if let Some((hir_id, _)) = visitor.main_fn { - Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Main)) + Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main)) } else { // No main function let mut err = struct_err!(tcx.sess, E0601, diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 086ddfd7e3..a274d7bbee 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -11,6 +11,7 @@ use self::OverloadedCallType::*; use crate::hir::def::{CtorOf, Res, DefKind}; use crate::hir::def_id::DefId; +use crate::hir::ptr::P; use crate::infer::InferCtxt; use crate::middle::mem_categorization as mc; use crate::middle::region; @@ -18,7 +19,6 @@ use crate::ty::{self, DefIdTree, TyCtxt, adjustment}; use crate::hir::{self, PatKind}; use std::rc::Rc; -use syntax::ptr::P; use syntax_pos::Span; use crate::util::nodemap::ItemLocalSet; @@ -277,6 +277,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { ) -> Self { ExprUseVisitor { mc: mc::MemCategorizationContext::new(tcx, + param_env, body_owner, region_scope_tree, tables, @@ -299,6 +300,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { ExprUseVisitor { mc: mc::MemCategorizationContext::with_infer( infcx, + param_env, body_owner, region_scope_tree, tables, @@ -487,11 +489,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.walk_block(&blk); } - hir::ExprKind::While(ref cond_expr, ref blk, _) => { - self.consume_expr(&cond_expr); - self.walk_block(&blk); - } - hir::ExprKind::Unary(_, ref lhs) => { self.consume_expr(&lhs); } @@ -930,7 +927,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) { debug!("walk_captures({:?})", closure_expr); - let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id); + let closure_def_id = self.tcx().hir().local_def_id(closure_expr.hir_id); if let Some(upvars) = self.tcx().upvars(closure_def_id) { for (&var_id, upvar) in upvars.iter() { let upvar_id = ty::UpvarId { diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index e8d68e0b7a..1cc96c549e 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -10,7 +10,7 @@ use syntax_pos::{Span, sym}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::hir; -fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut ItemVisitor { tcx }.as_deep_visitor() diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index a6e5bd275a..c5c8639324 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -118,7 +118,7 @@ impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> { match self.item_refs.get(&*value.as_str()).cloned() { // Known lang item with attribute on correct target. Some((item_index, expected_target)) if actual_target == expected_target => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); self.collect_item(item_index, def_id); }, // Known lang item with attribute on incorrect target. @@ -326,6 +326,7 @@ language_item_table! { UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait; PinTypeLangItem, "pin", pin_type, Target::Struct; + // Don't be fooled by the naming here: this lang item denotes `PartialEq`, not `Eq`. EqTraitLangItem, "eq", eq_trait, Target::Trait; PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait; OrdTraitLangItem, "ord", ord_trait, Target::Trait; @@ -364,35 +365,9 @@ language_item_table! { ManuallyDropItem, "manually_drop", manually_drop, Target::Struct; - DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; + MaybeUninitLangItem, "maybe_uninit", maybe_uninit, Target::Union; - // A lang item for each of the 128-bit operators we can optionally lower. - I128AddFnLangItem, "i128_add", i128_add_fn, Target::Fn; - U128AddFnLangItem, "u128_add", u128_add_fn, Target::Fn; - I128SubFnLangItem, "i128_sub", i128_sub_fn, Target::Fn; - U128SubFnLangItem, "u128_sub", u128_sub_fn, Target::Fn; - I128MulFnLangItem, "i128_mul", i128_mul_fn, Target::Fn; - U128MulFnLangItem, "u128_mul", u128_mul_fn, Target::Fn; - I128DivFnLangItem, "i128_div", i128_div_fn, Target::Fn; - U128DivFnLangItem, "u128_div", u128_div_fn, Target::Fn; - I128RemFnLangItem, "i128_rem", i128_rem_fn, Target::Fn; - U128RemFnLangItem, "u128_rem", u128_rem_fn, Target::Fn; - I128ShlFnLangItem, "i128_shl", i128_shl_fn, Target::Fn; - U128ShlFnLangItem, "u128_shl", u128_shl_fn, Target::Fn; - I128ShrFnLangItem, "i128_shr", i128_shr_fn, Target::Fn; - U128ShrFnLangItem, "u128_shr", u128_shr_fn, Target::Fn; - // And overflow versions for the operators that are checkable. - // While MIR calls these Checked*, they return (T,bool), not Option. - I128AddoFnLangItem, "i128_addo", i128_addo_fn, Target::Fn; - U128AddoFnLangItem, "u128_addo", u128_addo_fn, Target::Fn; - I128SuboFnLangItem, "i128_subo", i128_subo_fn, Target::Fn; - U128SuboFnLangItem, "u128_subo", u128_subo_fn, Target::Fn; - I128MuloFnLangItem, "i128_mulo", i128_mulo_fn, Target::Fn; - U128MuloFnLangItem, "u128_mulo", u128_mulo_fn, Target::Fn; - I128ShloFnLangItem, "i128_shlo", i128_shlo_fn, Target::Fn; - U128ShloFnLangItem, "u128_shlo", u128_shlo_fn, Target::Fn; - I128ShroFnLangItem, "i128_shro", i128_shro_fn, Target::Fn; - U128ShroFnLangItem, "u128_shro", u128_shro_fn, Target::Fn; + DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; // Align offset for stride != 1, must not panic. AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 9c131ce634..0d6d016e50 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -142,8 +142,12 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> { } } -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LibFeatures { +pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures { let mut collector = LibFeatureCollector::new(tcx); - intravisit::walk_crate(&mut collector, tcx.hir().krate()); + let krate = tcx.hir().krate(); + for attr in &krate.non_exported_macro_attrs { + collector.visit_attribute(attr); + } + intravisit::walk_crate(&mut collector, krate); collector.lib_features } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 7b69fe394f..daf0d8103a 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -93,12 +93,12 @@ //! It is the responsibility of typeck to ensure that there are no //! `return` expressions in a function declared as diverging. -use self::LoopKind::*; use self::LiveNodeKind::*; use self::VarKind::*; use crate::hir::def::*; use crate::hir::Node; +use crate::hir::ptr::P; use crate::ty::{self, TyCtxt}; use crate::ty::query::Providers; use crate::lint; @@ -111,7 +111,6 @@ use std::io::prelude::*; use std::io; use std::rc::Rc; use syntax::ast; -use syntax::ptr::P; use syntax::symbol::{kw, sym}; use syntax_pos::Span; @@ -120,14 +119,6 @@ use crate::hir::{Expr, HirId}; use crate::hir::def_id::DefId; use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; -/// For use with `propagate_through_loop`. -enum LoopKind<'a> { - /// An endless `loop` loop. - LoopLoop, - /// A `while` loop, with the given expression as condition. - WhileLoop(&'a Expr), -} - #[derive(Copy, Clone, PartialEq)] struct Variable(u32); @@ -181,7 +172,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); } } -fn check_mod_liveness<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut IrMaps::new(tcx, module_def_id).as_deep_visitor(), @@ -363,7 +354,7 @@ fn visit_fn<'tcx>( debug!("visit_fn"); // swap in a new set of IR maps for this function body: - let def_id = ir.tcx.hir().local_def_id_from_hir_id(id); + let def_id = ir.tcx.hir().local_def_id(id); let mut fn_maps = IrMaps::new(ir.tcx, def_id); // Don't run unused pass for #[derive()] @@ -494,7 +485,7 @@ fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr) { // in better error messages than just pointing at the closure // construction site. let mut call_caps = Vec::new(); - let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id); + let closure_def_id = ir.tcx.hir().local_def_id(expr.hir_id); if let Some(upvars) = ir.tcx.upvars(closure_def_id) { let parent_upvars = ir.tcx.upvars(ir.body_owner); call_caps.extend(upvars.iter().filter_map(|(&var_id, upvar)| { @@ -517,7 +508,6 @@ fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr) { // live nodes required for interesting control flow: hir::ExprKind::Match(..) | - hir::ExprKind::While(..) | hir::ExprKind::Loop(..) => { ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span)); intravisit::walk_expr(ir, expr); @@ -1055,14 +1045,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { }) } - hir::ExprKind::While(ref cond, ref blk, _) => { - self.propagate_through_loop(expr, WhileLoop(&cond), &blk, succ) - } - // Note that labels have been resolved, so we don't need to look // at the label ident hir::ExprKind::Loop(ref blk, _, _) => { - self.propagate_through_loop(expr, LoopLoop, &blk, succ) + self.propagate_through_loop(expr, &blk, succ) } hir::ExprKind::Match(ref e, ref arms, _) => { @@ -1353,74 +1339,44 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn propagate_through_loop(&mut self, - expr: &Expr, - kind: LoopKind<'_>, - body: &hir::Block, - succ: LiveNode) - -> LiveNode { + fn propagate_through_loop( + &mut self, + expr: &Expr, + body: &hir::Block, + succ: LiveNode + ) -> LiveNode { /* - We model control flow like this: - (cond) <--+ - | | - v | - +-- (expr) | - | | | - | v | - | (body) ---+ - | - | - v - (succ) + (expr) <-+ + | | + v | + (body) --+ + Note that a `continue` expression targeting the `loop` will have a successor of `expr`. + Meanwhile, a `break` expression will have a successor of `succ`. */ - // first iteration: let mut first_merge = true; let ln = self.live_node(expr.hir_id, expr.span); self.init_empty(ln, succ); - match kind { - LoopLoop => {} - _ => { - // If this is not a `loop` loop, then it's possible we bypass - // the body altogether. Otherwise, the only way is via a `break` - // in the loop body. - self.merge_from_succ(ln, succ, first_merge); - first_merge = false; - } - } debug!("propagate_through_loop: using id for loop body {} {}", expr.hir_id, self.ir.tcx.hir().hir_to_pretty_string(body.hir_id)); self.break_ln.insert(expr.hir_id, succ); - let cond_ln = match kind { - LoopLoop => ln, - WhileLoop(ref cond) => self.propagate_through_expr(&cond, ln), - }; - - self.cont_ln.insert(expr.hir_id, cond_ln); + self.cont_ln.insert(expr.hir_id, ln); - let body_ln = self.propagate_through_block(body, cond_ln); + let body_ln = self.propagate_through_block(body, ln); // repeat until fixed point is reached: while self.merge_from_succ(ln, body_ln, first_merge) { first_merge = false; - - let new_cond_ln = match kind { - LoopLoop => ln, - WhileLoop(ref cond) => { - self.propagate_through_expr(&cond, ln) - } - }; - assert_eq!(cond_ln, new_cond_ln); - assert_eq!(body_ln, self.propagate_through_block(body, cond_ln)); + assert_eq!(body_ln, self.propagate_through_block(body, ln)); } - cond_ln + ln } } @@ -1520,7 +1476,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { // no correctness conditions related to liveness hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) | - hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) | + hir::ExprKind::Match(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Index(..) | hir::ExprKind::Field(..) | hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) | hir::ExprKind::Unary(..) | diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 088c862dcb..77d6f39324 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -66,7 +66,6 @@ use crate::hir::def::{CtorOf, Res, DefKind, CtorKind}; use crate::ty::adjustment; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::fold::TypeFoldable; -use crate::ty::layout::VariantIdx; use crate::hir::{MutImmutable, MutMutable, PatKind}; use crate::hir::pat_util::EnumerateAndAdjustIterator; @@ -79,7 +78,6 @@ use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::indexed_vec::Idx; use std::rc::Rc; use crate::util::nodemap::ItemLocalSet; @@ -198,79 +196,6 @@ pub struct cmt_<'tcx> { pub type cmt<'tcx> = Rc>; -pub enum ImmutabilityBlame<'tcx> { - ImmLocal(hir::HirId), - ClosureEnv(LocalDefId), - LocalDeref(hir::HirId), - AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef) -} - -impl<'tcx> cmt_<'tcx> { - fn resolve_field(&self, field_index: usize) -> Option<(&'tcx ty::AdtDef, &'tcx ty::FieldDef)> - { - let adt_def = match self.ty.sty { - ty::Adt(def, _) => def, - ty::Tuple(..) => return None, - // closures get `Categorization::Upvar` rather than `Categorization::Interior` - _ => bug!("interior cmt {:?} is not an ADT", self) - }; - let variant_def = match self.cat { - Categorization::Downcast(_, variant_did) => { - adt_def.variant_with_id(variant_did) - } - _ => { - assert_eq!(adt_def.variants.len(), 1); - &adt_def.variants[VariantIdx::new(0)] - } - }; - Some((adt_def, &variant_def.fields[field_index])) - } - - pub fn immutability_blame(&self) -> Option> { - match self.cat { - Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) => { - // try to figure out where the immutable reference came from - match base_cmt.cat { - Categorization::Local(hir_id) => - Some(ImmutabilityBlame::LocalDeref(hir_id)), - Categorization::Interior(ref base_cmt, InteriorField(field_index)) => { - base_cmt.resolve_field(field_index.0).map(|(adt_def, field_def)| { - ImmutabilityBlame::AdtFieldDeref(adt_def, field_def) - }) - } - Categorization::Upvar(Upvar { id, .. }) => { - if let NoteClosureEnv(..) = self.note { - Some(ImmutabilityBlame::ClosureEnv(id.closure_expr_id)) - } else { - None - } - } - _ => None - } - } - Categorization::Local(hir_id) => { - Some(ImmutabilityBlame::ImmLocal(hir_id)) - } - Categorization::Rvalue(..) | - Categorization::Upvar(..) | - Categorization::Deref(_, UnsafePtr(..)) => { - // This should not be reachable up to inference limitations. - None - } - Categorization::Interior(ref base_cmt, _) | - Categorization::Downcast(ref base_cmt, _) | - Categorization::Deref(ref base_cmt, _) => { - base_cmt.immutability_blame() - } - Categorization::ThreadLocal(..) | - Categorization::StaticItem => { - // Do we want to do something here? - None - } - } - } -} - pub trait HirNode { fn hir_id(&self) -> hir::HirId; fn span(&self) -> Span; @@ -289,6 +214,7 @@ impl HirNode for hir::Pat { #[derive(Clone)] pub struct MemCategorizationContext<'a, 'tcx> { pub tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, pub body_owner: DefId, pub upvars: Option<&'tcx FxIndexMap>, pub region_scope_tree: &'a region::ScopeTree, @@ -405,6 +331,7 @@ impl MutabilityCategory { impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, body_owner: DefId, region_scope_tree: &'a region::ScopeTree, tables: &'a ty::TypeckTables<'tcx>, @@ -417,7 +344,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { region_scope_tree, tables, rvalue_promotable_map, - infcx: None + infcx: None, + param_env, } } } @@ -434,6 +362,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// known, the results around upvar accesses may be incorrect. pub fn with_infer( infcx: &'a InferCtxt<'a, 'tcx>, + param_env: ty::ParamEnv<'tcx>, body_owner: DefId, region_scope_tree: &'a region::ScopeTree, tables: &'a ty::TypeckTables<'tcx>, @@ -454,6 +383,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { tables, rvalue_promotable_map, infcx: Some(infcx), + param_env, } } @@ -696,7 +626,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) | hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | - hir::ExprKind::Binary(..) | hir::ExprKind::While(..) | + hir::ExprKind::Binary(..) | hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) | hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) | hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | @@ -971,7 +901,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { // Always promote `[T; 0]` (even when e.g., borrowed mutably). let promotable = match expr_ty.sty { - ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true, + ty::Array(_, len) if len.try_eval_usize(self.tcx, self.param_env) == Some(0) => true, _ => promotable, }; @@ -1069,7 +999,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { let deref_ty = match base_cmt_ty.builtin_deref(true) { Some(mt) => mt.ty, None => { - debug!("Explicit deref of non-derefable type: {:?}", base_cmt_ty); + debug!("explicit deref of non-derefable type: {:?}", base_cmt_ty); return Err(()); } }; @@ -1392,7 +1322,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { let element_ty = match cmt.ty.builtin_index() { Some(ty) => ty, None => { - debug!("Explicit index of non-indexable type {:?}", cmt); + debug!("explicit index of non-indexable type {:?}", cmt); return Err(()); } }; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index d607c35f87..76d8a6738f 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -35,20 +35,20 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item, attrs: CodegenFnAt match item.node { hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => { - let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id)); + let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id)); generics.requires_monomorphization(tcx) } _ => false, } } -fn method_might_be_inlined<'tcx>( - tcx: TyCtxt<'tcx>, +fn method_might_be_inlined( + tcx: TyCtxt<'_>, impl_item: &hir::ImplItem, impl_src: DefId, ) -> bool { let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner_def_id()); - let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(impl_item.hir_id)); + let generics = tcx.generics_of(tcx.hir().local_def_id(impl_item.hir_id)); if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) { return true } @@ -188,8 +188,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } } - hir::ImplItemKind::Existential(..) | - hir::ImplItemKind::Type(_) => false, + hir::ImplItemKind::OpaqueTy(..) | + hir::ImplItemKind::TyAlias(_) => false, } } Some(_) => false, @@ -222,7 +222,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } else { false }; - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let codegen_attrs = self.tcx.codegen_fn_attrs(def_id); let is_extern = codegen_attrs.contains_extern_indicator(); let std_internal = codegen_attrs.flags.contains( @@ -243,7 +243,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { Node::Item(item) => { match item.node { hir::ItemKind::Fn(.., body) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); if item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)) { @@ -263,8 +263,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // worklist, as determined by the privacy pass hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) | - hir::ItemKind::Existential(..) | - hir::ItemKind::Ty(..) | + hir::ItemKind::OpaqueTy(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Static(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod(..) | @@ -301,8 +301,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { self.visit_nested_body(body) } } - hir::ImplItemKind::Existential(..) | - hir::ImplItemKind::Type(_) => {} + hir::ImplItemKind::OpaqueTy(..) | + hir::ImplItemKind::TyAlias(_) => {} } } Node::Expr(&hir::Expr { node: hir::ExprKind::Closure(.., body, _, _), .. }) => { @@ -345,7 +345,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx // Anything which has custom linkage gets thrown on the worklist no // matter where it is in the crate, along with "special std symbols" // which are currently akin to allocator symbols. - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let codegen_attrs = self.tcx.codegen_fn_attrs(def_id); if codegen_attrs.contains_extern_indicator() || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { @@ -391,7 +391,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx #[derive(Clone, HashStable)] pub struct ReachableSet(pub Lrc); -fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> ReachableSet { +fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { debug_assert!(crate_num == LOCAL_CRATE); let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 114684b152..88c1971581 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -675,7 +675,7 @@ impl<'tcx> ScopeTree { &format!("free_scope: {:?} not recognized by the \ region scope tree for {:?} / {:?}", param_owner, - self.root_parent.map(|id| tcx.hir().local_def_id_from_hir_id(id)), + self.root_parent.map(|id| tcx.hir().local_def_id(id)), self.root_body.map(|hir_id| DefId::local(hir_id.owner)))); } @@ -915,11 +915,6 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h terminating(body.hir_id.local_id); } - hir::ExprKind::While(ref expr, ref body, _) => { - terminating(expr.hir_id.local_id); - terminating(body.hir_id.local_id); - } - hir::ExprKind::DropTemps(ref expr) => { // `DropTemps(expr)` does not denote a conditional scope. // Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`. @@ -1375,7 +1370,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0); let outer_cx = self.cx; - let outer_ts = mem::replace(&mut self.terminating_scopes, FxHashSet::default()); + let outer_ts = mem::take(&mut self.terminating_scopes); self.terminating_scopes.insert(body.value.hir_id.local_id); if let Some(root_id) = self.cx.root_id { @@ -1446,7 +1441,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { } } -fn region_scope_tree<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ScopeTree { +fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { let closure_base_def_id = tcx.closure_base_def_id(def_id); if closure_base_def_id != def_id { return tcx.region_scope_tree(closure_base_def_id); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 3d80fb28c7..f8f01f79e1 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -8,7 +8,8 @@ use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use crate::hir::map::Map; -use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName}; +use crate::hir::ptr::P; +use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName, QPath}; use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use crate::rustc::lint; @@ -18,10 +19,9 @@ use errors::{Applicability, DiagnosticBuilder}; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; -use std::mem::replace; +use std::mem::{replace, take}; use syntax::ast; use syntax::attr; -use syntax::ptr::P; use syntax::symbol::{kw, sym}; use syntax_pos::Span; @@ -83,7 +83,7 @@ impl Region { fn early(hir_map: &Map<'_>, index: &mut u32, param: &GenericParam) -> (ParamName, Region) { let i = *index; *index += 1; - let def_id = hir_map.local_def_id_from_hir_id(param.hir_id); + let def_id = hir_map.local_def_id(param.hir_id); let origin = LifetimeDefOrigin::from_param(param); debug!("Region::early: index={} def_id={:?}", i, def_id); (param.name.modern(), Region::EarlyBound(i, def_id, origin)) @@ -91,7 +91,7 @@ impl Region { fn late(hir_map: &Map<'_>, param: &GenericParam) -> (ParamName, Region) { let depth = ty::INNERMOST; - let def_id = hir_map.local_def_id_from_hir_id(param.hir_id); + let def_id = hir_map.local_def_id(param.hir_id); let origin = LifetimeDefOrigin::from_param(param); debug!( "Region::late: param={:?} depth={:?} def_id={:?} origin={:?}", @@ -268,17 +268,17 @@ enum Scope<'a> { track_lifetime_uses: bool, /// Whether or not this binder would serve as the parent - /// binder for abstract types introduced within. For example: + /// binder for opaque types introduced within. For example: /// /// fn foo<'a>() -> impl for<'b> Trait> /// - /// Here, the abstract types we create for the `impl Trait` + /// Here, the opaque types we create for the `impl Trait` /// and `impl Trait2` references will both have the `foo` item /// as their parent. When we get to `impl Trait2`, we find /// that it is nested within the `for<>` binder -- this flag /// allows us to skip that when looking for the parent binder - /// of the resulting abstract type. - abstract_type_parent: bool, + /// of the resulting opaque type. + opaque_type_parent: bool, s: ScopeRef<'a>, }, @@ -368,7 +368,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// entire crate. You should not read the result of this query /// directly, but rather use `named_region_map`, `is_late_bound_map`, /// etc. -fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx ResolveLifetimes { +fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> &ResolveLifetimes { assert_eq!(for_krate, LOCAL_CRATE); let named_region_map = krate(tcx); @@ -395,7 +395,7 @@ fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx Reso tcx.arena.alloc(rl) } -fn krate<'tcx>(tcx: TyCtxt<'tcx>) -> NamedRegionMap { +fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap { let krate = tcx.hir().krate(); let mut map = NamedRegionMap { defs: Default::default(), @@ -441,7 +441,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { // Each body has their own set of labels, save labels. - let saved = replace(&mut self.labels_in_fn, vec![]); + let saved = take(&mut self.labels_in_fn); let body = self.tcx.hir().body(body); extract_labels(self, body); self.with( @@ -480,16 +480,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.with(scope, |_, this| intravisit::walk_item(this, item)); } - hir::ItemKind::Existential(hir::ExistTy { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => { - // currently existential type declarations are just generated from impl Trait - // items. doing anything on this node is irrelevant, as we currently don't need + // Currently opaque type declarations are just generated from `impl Trait` + // items. Doing anything on this node is irrelevant, as we currently don't need // it. } - hir::ItemKind::Ty(_, ref generics) - | hir::ItemKind::Existential(hir::ExistTy { + hir::ItemKind::TyAlias(_, ref generics) + | hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, ref generics, .. @@ -526,7 +526,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let scope = Scope::Binder { lifetimes, next_early_index: index + non_lifetime_count, - abstract_type_parent: true, + opaque_type_parent: true, track_lifetime_uses, s: ROOT_SCOPE, }; @@ -574,7 +574,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, next_early_index, track_lifetime_uses: true, - abstract_type_parent: false, + opaque_type_parent: false, }; self.with(scope, |old_scope, this| { // a bare fn has no bounds, so everything @@ -622,14 +622,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir::TyKind::Def(item_id, ref lifetimes) => { // Resolve the lifetimes in the bounds to the lifetime defs in the generics. // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to - // `abstract type MyAnonTy<'b>: MyTrait<'b>;` - // ^ ^ this gets resolved in the scope of - // the exist_ty generics + // `type MyAnonTy<'b> = impl MyTrait<'b>;` + // ^ ^ this gets resolved in the scope of + // the opaque_ty generics let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node { - // named existential types are reached via TyKind::Path - // this arm is for `impl Trait` in the types of statics, constants and locals - hir::ItemKind::Existential(hir::ExistTy { + // Named opaque `impl Trait` types are reached via `TyKind::Path`. + // This arm is for `impl Trait` in the types of statics, constants and locals. + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { @@ -637,15 +637,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { return; } // RPIT (return position impl trait) - hir::ItemKind::Existential(hir::ExistTy { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, ref bounds, .. }) => (generics, bounds), - ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i), + ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), }; - // Resolve the lifetimes that are applied to the existential type. + // Resolve the lifetimes that are applied to the opaque type. // These are resolved in the current scope. // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to // `fn foo<'a>() -> MyAnonTy<'a> { ... }` @@ -687,7 +687,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // We want to start our early-bound indices at the end of the parent scope, // not including any parent `impl Trait`s. - let mut index = self.next_early_index_for_abstract_type(); + let mut index = self.next_early_index_for_opaque_type(); debug!("visit_ty: index = {}", index); let mut elision = None; @@ -728,7 +728,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, s: this.scope, track_lifetime_uses: true, - abstract_type_parent: false, + opaque_type_parent: false, }; this.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -743,7 +743,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, s: self.scope, track_lifetime_uses: true, - abstract_type_parent: false, + opaque_type_parent: false, }; self.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -796,7 +796,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: index + non_lifetime_count, s: self.scope, track_lifetime_uses: true, - abstract_type_parent: true, + opaque_type_parent: true, }; self.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -828,7 +828,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { |this| intravisit::walk_impl_item(this, impl_item), ) } - Type(ref ty) => { + TyAlias(ref ty) => { let generics = &impl_item.generics; let mut index = self.next_early_index(); let mut non_lifetime_count = 0; @@ -848,14 +848,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: index + non_lifetime_count, s: self.scope, track_lifetime_uses: true, - abstract_type_parent: true, + opaque_type_parent: true, }; self.with(scope, |_old_scope, this| { this.visit_generics(generics); this.visit_ty(ty); }); } - Existential(ref bounds) => { + OpaqueTy(ref bounds) => { let generics = &impl_item.generics; let mut index = self.next_early_index(); let mut next_early_index = index; @@ -879,7 +879,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, s: self.scope, track_lifetime_uses: true, - abstract_type_parent: true, + opaque_type_parent: true, }; self.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -967,7 +967,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, next_early_index, track_lifetime_uses: true, - abstract_type_parent: false, + opaque_type_parent: false, }; let result = self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &bound_generic_params); @@ -1037,7 +1037,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, next_early_index, track_lifetime_uses: true, - abstract_type_parent: false, + opaque_type_parent: false, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params); @@ -1201,11 +1201,10 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) { } fn expression_label(ex: &hir::Expr) -> Option { - match ex.node { - hir::ExprKind::While(.., Some(label)) | hir::ExprKind::Loop(_, Some(label), _) => { - Some(label.ident) - } - _ => None, + if let hir::ExprKind::Loop(_, Some(label), _) = ex.node { + Some(label.ident) + } else { + None } } @@ -1255,12 +1254,12 @@ fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap { let result = object_lifetime_defaults_for_item(tcx, generics); @@ -1326,7 +1325,7 @@ fn object_lifetime_defaults_for_item( add_bounds(&mut set, ¶m.bounds); - let param_def_id = tcx.hir().local_def_id_from_hir_id(param.hir_id); + let param_def_id = tcx.hir().local_def_id(param.hir_id); for predicate in &generics.where_clause.predicates { // Look for `type: ...` where clauses. let data = match *predicate { @@ -1370,7 +1369,7 @@ fn object_lifetime_defaults_for_item( .enumerate() .find(|&(_, (_, lt_name, _))| lt_name == name) .map_or(Set1::Many, |(i, (id, _, origin))| { - let def_id = tcx.hir().local_def_id_from_hir_id(id); + let def_id = tcx.hir().local_def_id(id); Set1::One(Region::EarlyBound(i as u32, def_id, origin)) }) } @@ -1405,9 +1404,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_uses, .. } = self; - let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); - let xcrate_object_lifetime_defaults = - replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default()); + let labels_in_fn = take(&mut self.labels_in_fn); + let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let mut this = LifetimeContext { tcx: *tcx, map: map, @@ -1460,10 +1458,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } // helper method to issue suggestions from `fn rah<'a>(&'a T)` to `fn rah(&T)` + // or from `fn rah<'a>(T<'a>)` to `fn rah(T<'_>)` fn suggest_eliding_single_use_lifetime( &self, err: &mut DiagnosticBuilder<'_>, def_id: DefId, lifetime: &hir::Lifetime ) { - // FIXME: future work: also suggest `impl Foo<'_>` for `impl<'a> Foo<'a>` let name = lifetime.name.ident(); let mut remove_decl = None; if let Some(parent_def_id) = self.tcx.parent(def_id) { @@ -1473,18 +1471,38 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } let mut remove_use = None; + let mut elide_use = None; let mut find_arg_use_span = |inputs: &hir::HirVec| { for input in inputs { - if let hir::TyKind::Rptr(lt, _) = input.node { - if lt.name.ident() == name { - // include the trailing whitespace between the ampersand and the type name - let lt_through_ty_span = lifetime.span.to(input.span.shrink_to_hi()); - remove_use = Some( - self.tcx.sess.source_map() - .span_until_non_whitespace(lt_through_ty_span) - ); - break; + match input.node { + hir::TyKind::Rptr(lt, _) => { + if lt.name.ident() == name { + // include the trailing whitespace between the lifetime and type names + let lt_through_ty_span = lifetime.span.to(input.span.shrink_to_hi()); + remove_use = Some( + self.tcx.sess.source_map() + .span_until_non_whitespace(lt_through_ty_span) + ); + break; + } } + hir::TyKind::Path(ref qpath) => { + if let QPath::Resolved(_, path) = qpath { + + let last_segment = &path.segments[path.segments.len()-1]; + let generics = last_segment.generic_args(); + for arg in generics.args.iter() { + if let GenericArg::Lifetime(lt) = arg { + if lt.name.ident() == name { + elide_use = Some(lt.span); + break; + } + } + } + break; + } + }, + _ => {} } } }; @@ -1508,24 +1526,35 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - if let (Some(decl_span), Some(use_span)) = (remove_decl, remove_use) { - // if both declaration and use deletion spans start at the same - // place ("start at" because the latter includes trailing - // whitespace), then this is an in-band lifetime - if decl_span.shrink_to_lo() == use_span.shrink_to_lo() { - err.span_suggestion( - use_span, - "elide the single-use lifetime", - String::new(), - Applicability::MachineApplicable, - ); - } else { + let msg = "elide the single-use lifetime"; + match (remove_decl, remove_use, elide_use) { + (Some(decl_span), Some(use_span), None) => { + // if both declaration and use deletion spans start at the same + // place ("start at" because the latter includes trailing + // whitespace), then this is an in-band lifetime + if decl_span.shrink_to_lo() == use_span.shrink_to_lo() { + err.span_suggestion( + use_span, + msg, + String::new(), + Applicability::MachineApplicable, + ); + } else { + err.multipart_suggestion( + msg, + vec![(decl_span, String::new()), (use_span, String::new())], + Applicability::MachineApplicable, + ); + } + } + (Some(decl_span), None, Some(use_span)) => { err.multipart_suggestion( - "elide the single-use lifetime", - vec![(decl_span, String::new()), (use_span, String::new())], + msg, + vec![(decl_span, String::new()), (use_span, "'_".to_owned())], Applicability::MachineApplicable, ); } + _ => {} } } @@ -1616,7 +1645,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } Some(LifetimeUseSet::Many) => { - debug!("Not one use lifetime"); + debug!("not one use lifetime"); } None => { let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -1724,7 +1753,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetimes, next_early_index, s: self.scope, - abstract_type_parent: true, + opaque_type_parent: true, track_lifetime_uses: false, }; self.with(scope, move |old_scope, this| { @@ -1733,7 +1762,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }); } - fn next_early_index_helper(&self, only_abstract_type_parent: bool) -> u32 { + fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 { let mut scope = self.scope; loop { match *scope { @@ -1741,9 +1770,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { next_early_index, - abstract_type_parent, + opaque_type_parent, .. - } if (!only_abstract_type_parent || abstract_type_parent) => + } if (!only_opaque_type_parent || opaque_type_parent) => { return next_early_index } @@ -1763,10 +1792,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } /// Returns the next index one would use for an `impl Trait` that - /// is being converted into an `abstract type`. This will be the + /// is being converted into an opaque type alias `impl Trait`. This will be the /// next early index from the enclosing item, for the most - /// part. See the `abstract_type_parent` field for more info. - fn next_early_index_for_abstract_type(&self) -> u32 { + /// part. See the `opaque_type_parent` field for more info. + fn next_early_index_for_opaque_type(&self) -> u32 { self.next_early_index_helper(false) } @@ -1836,7 +1865,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { node: hir::ImplItemKind::Method(..), .. }) => { - let scope = self.tcx.hir().local_def_id_from_hir_id(fn_id); + let scope = self.tcx.hir().local_def_id(fn_id); def = Region::Free(scope, def.id().unwrap()); } _ => {} @@ -2539,7 +2568,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let lifetimes: Vec<_> = params .iter() .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => Some((param, param.name)), + GenericParamKind::Lifetime { .. } => Some((param, param.name.modern())), _ => None, }) .collect(); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 38df406065..0d22c37cd6 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -4,6 +4,7 @@ pub use self::StabilityLevel::*; use crate::lint::{self, Lint, in_derive_expansion}; +use crate::lint::builtin::BuiltinLintDiagnostics; use crate::hir::{self, Item, Generics, StructField, Variant, HirId}; use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; @@ -11,12 +12,13 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::ty::query::Providers; use crate::middle::privacy::AccessLevels; use crate::session::{DiagnosticMessageId, Session}; +use errors::DiagnosticBuilder; use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, MultiSpan}; -use syntax::ast::Attribute; +use syntax::ast::{Attribute, CRATE_NODE_ID}; use syntax::errors::Applicability; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax::attr::{self, Stability, Deprecation}; +use syntax::attr::{self, Stability, Deprecation, RustcDeprecation}; use crate::ty::{self, TyCtxt}; use crate::util::nodemap::{FxHashSet, FxHashMap}; @@ -361,7 +363,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { - let impl_def_id = self.tcx.hir().local_def_id_from_hir_id( + let impl_def_id = self.tcx.hir().local_def_id( self.tcx.hir().get_parent_item(ii.hir_id)); if self.tcx.impl_trait_ref(impl_def_id).is_none() { self.check_missing_stability(ii.hir_id, ii.span, "item"); @@ -436,6 +438,7 @@ impl<'tcx> Index<'tcx> { level: attr::StabilityLevel::Unstable { reason: Some(Symbol::intern(reason)), issue: 27812, + is_soft: false, }, feature: sym::rustc_private, rustc_depr: None, @@ -466,7 +469,7 @@ impl<'tcx> Index<'tcx> { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. -fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }.as_deep_visitor()); } @@ -477,6 +480,42 @@ pub fn provide(providers: &mut Providers<'_>) { }; } +pub fn report_unstable( + sess: &Session, feature: Symbol, reason: Option, issue: u32, is_soft: bool, span: Span +) { + let msg = match reason { + Some(r) => format!("use of unstable library feature '{}': {}", feature, r), + None => format!("use of unstable library feature '{}'", &feature) + }; + + let msp: MultiSpan = span.into(); + let cm = &sess.parse_sess.source_map(); + let span_key = msp.primary_span().and_then(|sp: Span| + if !sp.is_dummy() { + let file = cm.lookup_char_pos(sp.lo()).file; + if file.name.is_macros() { + None + } else { + Some(span) + } + } else { + None + } + ); + + let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); + let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); + if fresh { + if is_soft { + sess.buffer_lint(lint::builtin::SOFT_UNSTABLE, CRATE_NODE_ID, span, &msg); + } else { + emit_feature_err( + &sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg + ); + } + } +} + /// Checks whether an item marked with `deprecated(since="X")` is currently /// deprecated (i.e., whether X is not greater than the current rustc version). pub fn deprecation_in_effect(since: &str) -> bool { @@ -501,6 +540,79 @@ pub fn deprecation_in_effect(since: &str) -> bool { } } +pub fn deprecation_suggestion( + diag: &mut DiagnosticBuilder<'_>, suggestion: Option, span: Span +) { + if let Some(suggestion) = suggestion { + diag.span_suggestion( + span, + "replace the use of the deprecated item", + suggestion.to_string(), + Applicability::MachineApplicable, + ); + } +} + +fn deprecation_message_common(message: String, reason: Option) -> String { + match reason { + Some(reason) => format!("{}: {}", message, reason), + None => message, + } +} + +pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) { + let message = format!("use of deprecated item '{}'", path); + (deprecation_message_common(message, depr.note), lint::builtin::DEPRECATED) +} + +pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) { + let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) { + (format!("use of deprecated item '{}'", path), lint::builtin::DEPRECATED) + } else { + (format!("use of item '{}' that will be deprecated in future version {}", path, depr.since), + lint::builtin::DEPRECATED_IN_FUTURE) + }; + (deprecation_message_common(message, Some(depr.reason)), lint) +} + +pub fn early_report_deprecation( + sess: &Session, + message: &str, + suggestion: Option, + lint: &'static Lint, + span: Span, +) { + if in_derive_expansion(span) { + return; + } + + let diag = BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span); + sess.buffer_lint_with_diagnostic(lint, CRATE_NODE_ID, span, message, diag); +} + +fn late_report_deprecation( + tcx: TyCtxt<'_>, + message: &str, + suggestion: Option, + lint: &'static Lint, + span: Span, + def_id: DefId, + hir_id: HirId, +) { + if in_derive_expansion(span) { + return; + } + + let mut diag = tcx.struct_span_lint_hir(lint, hir_id, span, message); + if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { + deprecation_suggestion(&mut diag, suggestion, span); + } + diag.emit(); + if hir_id == hir::DUMMY_HIR_ID { + span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); + } +} + struct Checker<'tcx> { tcx: TyCtxt<'tcx>, } @@ -516,6 +628,7 @@ pub enum EvalResult { feature: Symbol, reason: Option, issue: u32, + is_soft: bool, }, /// The item does not have the `#[stable]` or `#[unstable]` marker assigned. Unmarked, @@ -563,55 +676,18 @@ impl<'tcx> TyCtxt<'tcx> { /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to /// `id`. pub fn eval_stability(self, def_id: DefId, id: Option, span: Span) -> EvalResult { - let lint_deprecated = |def_id: DefId, - id: HirId, - note: Option, - suggestion: Option, - message: &str, - lint: &'static Lint| { - if in_derive_expansion(span) { - return; - } - let msg = if let Some(note) = note { - format!("{}: {}", message, note) - } else { - format!("{}", message) - }; - - let mut diag = self.struct_span_lint_hir(lint, id, span, &msg); - if let Some(suggestion) = suggestion { - if let hir::Node::Expr(_) = self.hir().get(id) { - diag.span_suggestion( - span, - "replace the use of the deprecated item", - suggestion.to_string(), - Applicability::MachineApplicable, - ); - } - } - diag.emit(); - if id == hir::DUMMY_HIR_ID { - span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); - } - }; - // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { - let parent_def_id = self.hir().local_def_id_from_hir_id( + let parent_def_id = self.hir().local_def_id( self.hir().get_parent_item(id)); let skip = self.lookup_deprecation_entry(parent_def_id) .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { - let path = self.def_path_str(def_id); - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - depr_entry.attr.note, - None, - &message, - lint::builtin::DEPRECATED); + let (message, lint) = + deprecation_message(&depr_entry.attr, &self.def_path_str(def_id)); + late_report_deprecation(self, &message, None, lint, span, def_id, id); } }; } @@ -631,27 +707,11 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(id) = id { if let Some(stability) = stability { if let Some(depr) = &stability.rustc_depr { - let path = self.def_path_str(def_id); - if deprecation_in_effect(&depr.since.as_str()) { - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - Some(depr.reason), - depr.suggestion, - &message, - lint::builtin::DEPRECATED); - } else { - let message = format!("use of item '{}' \ - that will be deprecated in future version {}", - path, - depr.since); - lint_deprecated(def_id, - id, - Some(depr.reason), - depr.suggestion, - &message, - lint::builtin::DEPRECATED_IN_FUTURE); - } + let (message, lint) = + rustc_deprecation_message(depr, &self.def_path_str(def_id)); + late_report_deprecation( + self, &message, depr.suggestion, lint, span, def_id, id + ); } } } @@ -668,7 +728,9 @@ impl<'tcx> TyCtxt<'tcx> { } match stability { - Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => { + Some(&Stability { + level: attr::Unstable { reason, issue, is_soft }, feature, .. + }) => { if span.allows_unstable(feature) { debug!("stability: skipping span={:?} since it is internal", span); return EvalResult::Allow; @@ -692,7 +754,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - EvalResult::Deny { feature, reason, issue } + EvalResult::Deny { feature, reason, issue, is_soft } } Some(_) => { // Stable APIs are always ok to call and deprecated APIs are @@ -715,34 +777,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn check_stability(self, def_id: DefId, id: Option, span: Span) { match self.eval_stability(def_id, id, span) { EvalResult::Allow => {} - EvalResult::Deny { feature, reason, issue } => { - let msg = match reason { - Some(r) => format!("use of unstable library feature '{}': {}", feature, r), - None => format!("use of unstable library feature '{}'", &feature) - }; - - let msp: MultiSpan = span.into(); - let cm = &self.sess.parse_sess.source_map(); - let span_key = msp.primary_span().and_then(|sp: Span| - if !sp.is_dummy() { - let file = cm.lookup_char_pos(sp.lo()).file; - if file.name.is_macros() { - None - } else { - Some(span) - } - } else { - None - } - ); - - let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); - let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - emit_feature_err(&self.sess.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &msg); - } - } + EvalResult::Deny { feature, reason, issue, is_soft } => + report_unstable(self.sess, feature, reason, issue, is_soft, span), EvalResult::Unmarked => { // The API could be uncallable for other reasons, for example when a private module // was referenced. @@ -766,7 +802,7 @@ impl Visitor<'tcx> for Checker<'tcx> { // compiler-generated `extern crate` items have a dummy span. if item.span.is_dummy() { return } - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) { Some(cnum) => cnum, None => return, @@ -796,7 +832,7 @@ impl Visitor<'tcx> for Checker<'tcx> { // There's no good place to insert stability check for non-Copy unions, // so semi-randomly perform it here in stability.rs hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let adt_def = self.tcx.adt_def(def_id); let ty = self.tcx.type_of(def_id); @@ -836,7 +872,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the list of enabled features that were not language features (i.e., that /// were expected to be library features), and the list of features used from /// libraries, identify activated features that don't exist and error about them. -pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); if tcx.stability().staged_api[&LOCAL_CRATE] { @@ -920,8 +956,8 @@ pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) { // don't lint about unused features. We should reenable this one day! } -fn unnecessary_stable_feature_lint<'tcx>( - tcx: TyCtxt<'tcx>, +fn unnecessary_stable_feature_lint( + tcx: TyCtxt<'_>, span: Span, feature: Symbol, since: Symbol, diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index d2cabb7e10..3d33e24953 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -1,27 +1,25 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::{RwLock, MappedReadGuard, ReadGuard}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use crate::ich::StableHashingContext; use crate::mir::{Body, BasicBlock}; -use crate::rustc_serialize as serialize; - #[derive(Clone, Debug)] pub struct Cache { predecessors: RwLock>>> } -impl serialize::Encodable for Cache { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - serialize::Encodable::encode(&(), s) +impl rustc_serialize::Encodable for Cache { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&(), s) } } -impl serialize::Decodable for Cache { - fn decode(d: &mut D) -> Result { - serialize::Decodable::decode(d).map(|_v: ()| Self::new()) +impl rustc_serialize::Decodable for Cache { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|_v: ()| Self::new()) } } diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index c8bf250d02..ce04cca96e 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -113,7 +113,7 @@ impl Allocation { } } -impl<'tcx> ::serialize::UseSpecializedDecodable for &'tcx Allocation {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {} /// Byte accessors impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { @@ -235,17 +235,17 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { { assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); let offset = ptr.offset.bytes() as usize; - match self.bytes[offset..].iter().position(|&c| c == 0) { + Ok(match self.bytes[offset..].iter().position(|&c| c == 0) { Some(size) => { let size_with_null = Size::from_bytes((size + 1) as u64); // Go through `get_bytes` for checks and AllocationExtra hooks. // We read the null, so we include it in the request, but we want it removed // from the result, so we do subslicing. - Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) + &self.get_bytes(cx, ptr, size_with_null)?[..size] } // This includes the case where `offset` is out-of-bounds to begin with. - None => err!(UnterminatedCString(ptr.erase_tag())), - } + None => throw_unsup!(UnterminatedCString(ptr.erase_tag())), + }) } /// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a @@ -446,7 +446,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation { if self.relocations(cx, ptr, size).is_empty() { Ok(()) } else { - err!(ReadPointerAsBytes) + throw_unsup!(ReadPointerAsBytes) } } @@ -516,7 +516,7 @@ impl<'tcx, Tag, Extra> Allocation { self.undef_mask.is_range_defined( ptr.offset, ptr.offset + size, - ).or_else(|idx| err!(ReadUndefBytes(idx))) + ).or_else(|idx| throw_unsup!(ReadUndefBytes(idx))) } pub fn mark_definedness( diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 7be4a2206f..ef0e205184 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -47,7 +47,7 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>; #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub error: crate::mir::interpret::InterpError<'tcx, u64>, + pub error: crate::mir::interpret::InterpError<'tcx>, pub stacktrace: Vec>, } @@ -137,15 +137,17 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> Result, ErrorHandled> { - match self.error { - InterpError::Layout(LayoutError::Unknown(_)) | - InterpError::TooGeneric => return Err(ErrorHandled::TooGeneric), - InterpError::Layout(LayoutError::SizeOverflow(_)) | - InterpError::TypeckError => return Err(ErrorHandled::Reported), - _ => {}, - } + let must_error = match self.error { + err_inval!(Layout(LayoutError::Unknown(_))) | + err_inval!(TooGeneric) => + return Err(ErrorHandled::TooGeneric), + err_inval!(TypeckError) => + return Err(ErrorHandled::Reported), + err_inval!(Layout(LayoutError::SizeOverflow(_))) => true, + _ => false, + }; trace!("reporting const eval failure at {:?}", self.span); - let mut err = if let Some(lint_root) = lint_root { + let mut err = if let (Some(lint_root), false) = (lint_root, must_error) { let hir_id = self.stacktrace .iter() .rev() @@ -158,10 +160,14 @@ impl<'tcx> ConstEvalErr<'tcx> { tcx.span, message, ) + } else if must_error { + struct_error(tcx, &self.error.to_string()) } else { struct_error(tcx, message) }; - err.span_label(self.span, self.error.to_string()); + if !must_error { + err.span_label(self.span, self.error.to_string()); + } // Skip the last, which is just the environment of the constant. The stacktrace // is sometimes empty because we create "fake" eval contexts in CTFE to do work // on constant values. @@ -181,15 +187,22 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<' /// Packages the kind of error we got from the const code interpreter /// up with a Rust-level backtrace of where the error occured. /// Thsese should always be constructed by calling `.into()` on -/// a `InterpError`. In `librustc_mir::interpret`, we have the `err!` -/// macro for this +/// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*` +/// macros for this. #[derive(Debug, Clone)] pub struct InterpErrorInfo<'tcx> { - pub kind: InterpError<'tcx, u64>, + pub kind: InterpError<'tcx>, backtrace: Option>, } -impl<'tcx> InterpErrorInfo<'tcx> { + +impl fmt::Display for InterpErrorInfo<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.kind) + } +} + +impl InterpErrorInfo<'_> { pub fn print_backtrace(&mut self) { if let Some(ref mut backtrace) = self.backtrace { print_backtrace(&mut *backtrace); @@ -202,9 +215,9 @@ fn print_backtrace(backtrace: &mut Backtrace) { eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace); } -impl<'tcx> From> for InterpErrorInfo<'tcx> { - fn from(kind: InterpError<'tcx, u64>) -> Self { - let backtrace = match env::var("RUST_CTFE_BACKTRACE") { +impl<'tcx> From> for InterpErrorInfo<'tcx> { + fn from(kind: InterpError<'tcx>) -> Self { + let backtrace = match env::var("RUSTC_CTFE_BACKTRACE") { // Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present". Ok(ref val) if val != "0" => { let mut backtrace = Backtrace::new_unresolved(); @@ -226,23 +239,143 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { } } -pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>; +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum PanicInfo { + Panic { + msg: Symbol, + line: u32, + col: u32, + file: Symbol, + }, + BoundsCheck { + len: O, + index: O, + }, + Overflow(mir::BinOp), + OverflowNeg, + DivisionByZero, + RemainderByZero, + GeneratorResumedAfterReturn, + GeneratorResumedAfterPanic, +} + +/// Type for MIR `Assert` terminator error messages. +pub type AssertMessage<'tcx> = PanicInfo>; + +impl PanicInfo { + /// Getting a description does not require `O` to be printable, and does not + /// require allocation. + /// The caller is expected to handle `Panic` and `BoundsCheck` separately. + pub fn description(&self) -> &'static str { + use PanicInfo::*; + match self { + 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", + Panic { .. } | BoundsCheck { .. } => + bug!("Unexpected PanicInfo"), + } + } +} + +impl fmt::Debug for PanicInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use PanicInfo::*; + match self { + Panic { ref msg, line, col, ref file } => + write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), + BoundsCheck { ref len, ref index } => + write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index), + _ => + write!(f, "{}", self.description()), + } + } +} #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum InterpError<'tcx, O> { - /// This variant is used by machines to signal their own errors that do not - /// match an existing variant. - MachineError(String), +pub enum InvalidProgramInfo<'tcx> { + /// Resolution can fail if we are in a too generic context. + TooGeneric, + /// Cannot compute this constant because it depends on another one + /// which already produced an error. + ReferencedConstant, + /// Abort in case type errors are reached. + TypeckError, + /// An error occurred during layout computation. + Layout(layout::LayoutError<'tcx>), +} - /// Not actually an interpreter error -- used to signal that execution has exited - /// with the given status code. Used by Miri, but not by CTFE. - Exit(i32), +impl fmt::Debug for InvalidProgramInfo<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InvalidProgramInfo::*; + match self { + TooGeneric => + write!(f, "encountered overly generic constant"), + ReferencedConstant => + write!(f, "referenced constant has errors"), + TypeckError => + write!(f, "encountered constants with type errors, stopping evaluation"), + Layout(ref err) => + write!(f, "{}", err), + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum UndefinedBehaviorInfo { + /// Free-form case. Only for errors that are never caught! + Ub(String), + /// Free-form case for experimental UB. Only for errors that are never caught! + UbExperimental(String), + /// Unreachable code was executed. + Unreachable, +} +impl fmt::Debug for UndefinedBehaviorInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use UndefinedBehaviorInfo::*; + match self { + Ub(msg) | UbExperimental(msg) => + write!(f, "{}", msg), + Unreachable => + write!(f, "entered unreachable code"), + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum UnsupportedOpInfo<'tcx> { + /// Free-form case. Only for errors that are never caught! + Unsupported(String), + + // -- Everything below is not classified yet -- FunctionAbiMismatch(Abi, Abi), FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>), FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>), FunctionArgCountMismatch, - NoMirFor(String), UnterminatedCString(Pointer), DanglingPointerDeref, DoubleFree, @@ -263,214 +396,38 @@ pub enum InterpError<'tcx, O> { ReadUndefBytes(Size), DeadLocal, InvalidBoolOp(mir::BinOp), - Unimplemented(String), + UnimplementedTraitSelection, + CalledClosureAsFunction, + NoMirFor(String), DerefFunctionPointer, ExecuteMemory, - BoundsCheck { len: O, index: O }, - Overflow(mir::BinOp), - OverflowNeg, - DivisionByZero, - RemainderByZero, - Intrinsic(String), InvalidChar(u128), - StackFrameLimitReached, OutOfTls, TlsOutOfBounds, - AbiViolation(String), AlignmentCheckFailed { required: Align, has: Align, }, ValidationFailure(String), - CalledClosureAsFunction, VtableForArgumentlessMethod, ModifiedConstantMemory, ModifiedStatic, - AssumptionNotHeld, - InlineAsm, TypeNotPrimitive(Ty<'tcx>), ReallocatedWrongMemoryKind(String, String), DeallocatedWrongMemoryKind(String, String), ReallocateNonBasePtr, DeallocateNonBasePtr, IncorrectAllocationInformation(Size, Size, Align, Align), - Layout(layout::LayoutError<'tcx>), HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), - Unreachable, - Panic { - msg: Symbol, - line: u32, - col: u32, - file: Symbol, - }, ReadFromReturnPointer, PathNotFound(Vec), - UnimplementedTraitSelection, - /// Abort in case type errors are reached - TypeckError, - /// Resolution can fail if we are in a too generic context - TooGeneric, - /// Cannot compute this constant because it depends on another one - /// which already produced an error - ReferencedConstant, - GeneratorResumedAfterReturn, - GeneratorResumedAfterPanic, - InfiniteLoop, } -pub type InterpResult<'tcx, T = ()> = Result>; - -impl<'tcx, O> InterpError<'tcx, O> { - pub fn description(&self) -> &str { - use self::InterpError::*; - match *self { - MachineError(ref inner) => inner, - Exit(..) => - "exited", - FunctionAbiMismatch(..) | FunctionArgMismatch(..) | FunctionRetMismatch(..) - | FunctionArgCountMismatch => - "tried to call a function through a function pointer of incompatible type", - InvalidMemoryAccess => - "tried to access memory through an invalid pointer", - DanglingPointerDeref => - "dangling pointer was dereferenced", - DoubleFree => - "tried to deallocate dangling pointer", - InvalidFunctionPointer => - "tried to use a function pointer after offsetting it", - InvalidBool => - "invalid boolean value read", - InvalidDiscriminant(..) => - "invalid enum discriminant value read", - PointerOutOfBounds { .. } => - "pointer offset outside bounds of allocation", - InvalidNullPointerUsage => - "invalid use of NULL pointer", - ValidationFailure(..) => - "type validation failed", - ReadPointerAsBytes => - "a raw memory access tried to access part of a pointer value as raw bytes", - ReadBytesAsPointer => - "a memory access tried to interpret some bytes as a pointer", - ReadForeignStatic => - "tried to read from foreign (extern) static", - InvalidPointerMath => - "attempted to do invalid arithmetic on pointers that would leak base addresses, \ - e.g., comparing pointers into different allocations", - ReadUndefBytes(_) => - "attempted to read undefined bytes", - DeadLocal => - "tried to access a dead local variable", - InvalidBoolOp(_) => - "invalid boolean operation", - Unimplemented(ref msg) => msg, - DerefFunctionPointer => - "tried to dereference a function pointer", - ExecuteMemory => - "tried to treat a memory pointer as a function pointer", - BoundsCheck{..} => - "array index out of bounds", - Intrinsic(..) => - "intrinsic failed", - NoMirFor(..) => - "mir not found", - InvalidChar(..) => - "tried to interpret an invalid 32-bit value as a char", - StackFrameLimitReached => - "reached the configured maximum number of stack frames", - OutOfTls => - "reached the maximum number of representable TLS keys", - TlsOutOfBounds => - "accessed an invalid (unallocated) TLS key", - AbiViolation(ref msg) => msg, - AlignmentCheckFailed{..} => - "tried to execute a misaligned read or write", - CalledClosureAsFunction => - "tried to call a closure through a function pointer", - VtableForArgumentlessMethod => - "tried to call a vtable function without arguments", - ModifiedConstantMemory => - "tried to modify constant memory", - ModifiedStatic => - "tried to modify a static's initial value from another static's initializer", - AssumptionNotHeld => - "`assume` argument was false", - InlineAsm => - "miri does not support inline assembly", - TypeNotPrimitive(_) => - "expected primitive type, got nonprimitive", - ReallocatedWrongMemoryKind(_, _) => - "tried to reallocate memory from one kind to another", - DeallocatedWrongMemoryKind(_, _) => - "tried to deallocate memory of the wrong kind", - ReallocateNonBasePtr => - "tried to reallocate with a pointer not to the beginning of an existing object", - DeallocateNonBasePtr => - "tried to deallocate with a pointer not to the beginning of an existing object", - IncorrectAllocationInformation(..) => - "tried to deallocate or reallocate using incorrect alignment or size", - Layout(_) => - "rustc layout computation failed", - UnterminatedCString(_) => - "attempted to get length of a null terminated string, but no null found before end \ - of allocation", - HeapAllocZeroBytes => - "tried to re-, de- or allocate zero bytes on the heap", - HeapAllocNonPowerOfTwoAlignment(_) => - "tried to re-, de-, or allocate heap memory with alignment that is not a power of \ - two", - Unreachable => - "entered unreachable code", - Panic { .. } => - "the evaluated program panicked", - ReadFromReturnPointer => - "tried to read from the return pointer", - PathNotFound(_) => - "a path could not be resolved, maybe the crate is not loaded", - UnimplementedTraitSelection => - "there were unresolved type arguments during trait selection", - TypeckError => - "encountered constants with type errors, stopping evaluation", - TooGeneric => - "encountered overly generic constant", - 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", - InfiniteLoop => - "duplicate interpreter state observed here, const evaluation will never terminate", - } - } -} - -impl<'tcx> fmt::Display for InterpErrorInfo<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.kind) - } -} - -impl<'tcx> fmt::Display for InterpError<'tcx, u64> { +impl fmt::Debug for UnsupportedOpInfo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use self::InterpError::*; - match *self { + use UnsupportedOpInfo::*; + match self { PointerOutOfBounds { ptr, msg, allocation_size } => { write!(f, "{} failed: pointer must be in-bounds at offset {}, \ but is outside bounds of allocation {} which has size {}", @@ -493,14 +450,10 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> { callee_ty, caller_ty), FunctionArgCountMismatch => write!(f, "tried to call a function with incorrect number of arguments"), - 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), - Intrinsic(ref err) => - write!(f, "{}", err), InvalidChar(c) => write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), AlignmentCheckFailed { required, has } => @@ -508,23 +461,148 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> { has.bytes(), required.bytes()), TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty), - Layout(ref err) => - write!(f, "rustc layout computation failed: {:?}", err), PathNotFound(ref path) => write!(f, "Cannot find path {:?}", path), - MachineError(ref inner) => - write!(f, "{}", inner), IncorrectAllocationInformation(size, size2, align, align2) => write!(f, "incorrect alloc info: expected size {} and align {}, \ got size {} and align {}", size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), - Panic { ref msg, line, col, ref file } => - write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), InvalidDiscriminant(val) => write!(f, "encountered invalid enum discriminant {}", val), + InvalidMemoryAccess => + write!(f, "tried to access memory through an invalid pointer"), + DanglingPointerDeref => + write!(f, "dangling pointer was dereferenced"), + DoubleFree => + write!(f, "tried to deallocate dangling pointer"), + InvalidFunctionPointer => + write!(f, "tried to use a function pointer after offsetting it"), + InvalidBool => + write!(f, "invalid boolean value read"), + InvalidNullPointerUsage => + write!(f, "invalid use of NULL pointer"), + ReadPointerAsBytes => + write!(f, "a raw memory access tried to access part of a pointer value as raw \ + bytes"), + ReadBytesAsPointer => + write!(f, "a memory access tried to interpret some bytes as a pointer"), + ReadForeignStatic => + write!(f, "tried to read from foreign (extern) static"), + InvalidPointerMath => + write!(f, "attempted to do invalid arithmetic on pointers that would leak base \ + addresses, e.g., comparing pointers into different allocations"), + DeadLocal => + write!(f, "tried to access a dead local variable"), + DerefFunctionPointer => + write!(f, "tried to dereference a function pointer"), + ExecuteMemory => + write!(f, "tried to treat a memory pointer as a function pointer"), + OutOfTls => + write!(f, "reached the maximum number of representable TLS keys"), + TlsOutOfBounds => + write!(f, "accessed an invalid (unallocated) TLS key"), + CalledClosureAsFunction => + write!(f, "tried to call a closure through a function pointer"), + VtableForArgumentlessMethod => + write!(f, "tried to call a vtable function without arguments"), + ModifiedConstantMemory => + write!(f, "tried to modify constant memory"), + ModifiedStatic => + write!(f, "tried to modify a static's initial value from another static's \ + initializer"), + ReallocateNonBasePtr => + write!(f, "tried to reallocate with a pointer not to the beginning of an \ + existing object"), + DeallocateNonBasePtr => + write!(f, "tried to deallocate with a pointer not to the beginning of an \ + existing object"), + HeapAllocZeroBytes => + write!(f, "tried to re-, de- or allocate zero bytes on the heap"), + ReadFromReturnPointer => + write!(f, "tried to read from the return pointer"), + UnimplementedTraitSelection => + write!(f, "there were unresolved type arguments during trait selection"), + InvalidBoolOp(_) => + write!(f, "invalid boolean operation"), + UnterminatedCString(_) => + write!(f, "attempted to get length of a null terminated string, but no null \ + found before end of allocation"), + ReadUndefBytes(_) => + write!(f, "attempted to read undefined bytes"), + HeapAllocNonPowerOfTwoAlignment(_) => + write!(f, "tried to re-, de-, or allocate heap memory with alignment that is \ + not a power of two"), + Unsupported(ref msg) => + write!(f, "{}", msg), + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum ResourceExhaustionInfo { + /// The stack grew too big. + StackFrameLimitReached, + /// The program ran into an infinite loop. + InfiniteLoop, +} + +impl fmt::Debug for ResourceExhaustionInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use ResourceExhaustionInfo::*; + match self { + StackFrameLimitReached => + write!(f, "reached the configured maximum number of stack frames"), + InfiniteLoop => + write!(f, "duplicate interpreter state observed here, const evaluation will never \ + terminate"), + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum InterpError<'tcx> { + /// The program panicked. + Panic(PanicInfo), + /// The program caused undefined behavior. + UndefinedBehavior(UndefinedBehaviorInfo), + /// The program did something the interpreter does not support (some of these *might* be UB + /// but the interpreter is not sure). + Unsupported(UnsupportedOpInfo<'tcx>), + /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). + InvalidProgram(InvalidProgramInfo<'tcx>), + /// The program exhausted the interpreter's resources (stack/heap too big, + /// execution takes too long, ..). + ResourceExhaustion(ResourceExhaustionInfo), + /// Not actually an interpreter error -- used to signal that execution has exited + /// with the given status code. Used by Miri, but not by CTFE. + Exit(i32), +} + +pub type InterpResult<'tcx, T = ()> = Result>; + +impl fmt::Display for InterpError<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Forward `Display` to `Debug` + write!(f, "{:?}", self) + } +} + +impl fmt::Debug for InterpError<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InterpError::*; + match *self { + Unsupported(ref msg) => + write!(f, "{:?}", msg), + InvalidProgram(ref msg) => + write!(f, "{:?}", msg), + UndefinedBehavior(ref msg) => + write!(f, "{:?}", msg), + ResourceExhaustion(ref msg) => + write!(f, "{:?}", msg), + Panic(ref msg) => + write!(f, "{:?}", msg), Exit(code) => write!(f, "exited with status code {}", code), - _ => write!(f, "{}", self.description()), } } } diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 1b294250aa..1ec95c29a4 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -1,8 +1,93 @@ //! An interpreter for MIR used in CTFE and by miri #[macro_export] -macro_rules! err { - ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::$($tt)*.into()) }; +macro_rules! err_unsup { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_unsup_format { + ($($tt:tt)*) => { err_unsup!(Unsupported(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! err_inval { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InvalidProgramInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_ub { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::UndefinedBehavior( + $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_ub_format { + ($($tt:tt)*) => { err_ub!(Ub(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! err_panic { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Panic( + $crate::mir::interpret::PanicInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_exhaust { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::ResourceExhaustion( + $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! throw_unsup { + ($($tt:tt)*) => { return Err(err_unsup!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_unsup_format { + ($($tt:tt)*) => { throw_unsup!(Unsupported(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! throw_inval { + ($($tt:tt)*) => { return Err(err_inval!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_ub { + ($($tt:tt)*) => { return Err(err_ub!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_ub_format { + ($($tt:tt)*) => { throw_ub!(Ub(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! throw_panic { + ($($tt:tt)*) => { return Err(err_panic!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_exhaust { + ($($tt:tt)*) => { return Err(err_exhaust!($($tt)*).into()) }; } mod error; @@ -12,7 +97,8 @@ mod pointer; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedOpInfo, + InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo, }; pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue}; @@ -27,7 +113,7 @@ use crate::hir::def_id::DefId; use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind}; use crate::ty::layout::{self, Size}; use std::io; -use crate::rustc_serialize::{Encoder, Decodable, Encodable}; +use rustc_serialize::{Encoder, Decodable, Encodable}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{Lock as Mutex, HashMapExt}; use rustc_data_structures::tiny_list::TinyList; @@ -51,8 +137,8 @@ pub struct GlobalId<'tcx> { #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] pub struct AllocId(pub u64); -impl crate::rustc_serialize::UseSpecializedEncodable for AllocId {} -impl crate::rustc_serialize::UseSpecializedDecodable for AllocId {} +impl rustc_serialize::UseSpecializedEncodable for AllocId {} +impl rustc_serialize::UseSpecializedDecodable for AllocId {} #[derive(RustcDecodable, RustcEncodable)] enum AllocDiscriminant { diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index a17bc1f672..0a99851337 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -4,9 +4,7 @@ use crate::mir; use crate::ty::layout::{self, HasDataLayout, Size}; use rustc_macros::HashStable; -use super::{ - AllocId, InterpResult, -}; +use super::{AllocId, InterpResult}; /// Used by `check_in_alloc` to indicate context of check #[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] @@ -76,13 +74,13 @@ pub trait PointerArithmetic: layout::HasDataLayout { #[inline] fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_offset(val, i); - if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { throw_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } #[inline] fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_signed_offset(val, i128::from(i)); - if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { throw_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } } @@ -198,11 +196,7 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - err!(PointerOutOfBounds { - ptr: self.erase_tag(), - msg, - allocation_size, - }) + throw_unsup!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) } else { Ok(()) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 388c549324..5381d46972 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -2,7 +2,7 @@ use std::fmt; use rustc_macros::HashStable; use rustc_apfloat::{Float, ieee::{Double, Single}}; -use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size, Align}, subst::SubstsRef}; +use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}, subst::SubstsRef}; use crate::ty::PlaceholderConst; use crate::hir::def_id::DefId; @@ -45,18 +45,11 @@ pub enum ConstValue<'tcx> { /// A value not represented/representable by `Scalar` or `Slice` ByRef { - /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive - /// fields of `repr(packed)` structs. The alignment may be lower than the type of this - /// constant. This permits reads with lower alignment than what the type would normally - /// require. - /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't - /// really need them. Disabling them may be too hard though. - align: Align, - /// Offset into `alloc` - offset: Size, /// The backing memory of the value, may contain more memory than needed for just the value /// in order to share `Allocation`s between values alloc: &'tcx Allocation, + /// Offset into `alloc` + offset: Size, }, /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other @@ -262,30 +255,6 @@ impl<'tcx, Tag> Scalar { } } - /// Returns this pointer's offset from the allocation base, or from NULL (for - /// integer pointers). - #[inline] - pub fn get_ptr_offset(self, cx: &impl HasDataLayout) -> Size { - match self { - Scalar::Raw { data, size } => { - assert_eq!(size as u64, cx.pointer_size().bytes()); - Size::from_bytes(data as u64) - } - Scalar::Ptr(ptr) => ptr.offset, - } - } - - #[inline] - pub fn is_null_ptr(self, cx: &impl HasDataLayout) -> bool { - match self { - Scalar::Raw { data, size } => { - assert_eq!(size as u64, cx.data_layout().pointer_size.bytes()); - data == 0 - }, - Scalar::Ptr(_) => false, - } - } - #[inline] pub fn from_bool(b: bool) -> Self { Scalar::Raw { data: b as u128, size: 1 } @@ -350,6 +319,10 @@ impl<'tcx, Tag> Scalar { Scalar::Raw { data: f.to_bits(), size: 8 } } + /// This is very rarely the method you want! You should dispatch on the type + /// and use `force_bits`/`assert_bits`/`force_ptr`/`assert_ptr`. + /// This method only exists for the benefit of low-level memory operations + /// as well as the implementation of the `force_*` methods. #[inline] pub fn to_bits_or_ptr( self, @@ -370,6 +343,7 @@ impl<'tcx, Tag> Scalar { } } + /// Do not call this method! Use either `assert_bits` or `force_bits`. #[inline] pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> { match self { @@ -379,19 +353,31 @@ impl<'tcx, Tag> Scalar { Scalar::check_data(data, size); Ok(data) } - Scalar::Ptr(_) => err!(ReadPointerAsBytes), + Scalar::Ptr(_) => throw_unsup!(ReadPointerAsBytes), } } + #[inline(always)] + pub fn assert_bits(self, target_size: Size) -> u128 { + self.to_bits(target_size).expect("Expected Raw bits but got a Pointer") + } + + /// Do not call this method! Use either `assert_ptr` or `force_ptr`. #[inline] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { - Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage), - Scalar::Raw { .. } => err!(ReadBytesAsPointer), + Scalar::Raw { data: 0, .. } => throw_unsup!(InvalidNullPointerUsage), + Scalar::Raw { .. } => throw_unsup!(ReadBytesAsPointer), Scalar::Ptr(p) => Ok(p), } } + #[inline(always)] + pub fn assert_ptr(self) -> Pointer { + self.to_ptr().expect("Expected a Pointer but got Raw bits") + } + + /// Do not call this method! Dispatch based on the type instead. #[inline] pub fn is_bits(self) -> bool { match self { @@ -400,6 +386,7 @@ impl<'tcx, Tag> Scalar { } } + /// Do not call this method! Dispatch based on the type instead. #[inline] pub fn is_ptr(self) -> bool { match self { @@ -412,7 +399,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), - _ => err!(InvalidBool), + _ => throw_unsup!(InvalidBool), } } @@ -420,7 +407,7 @@ impl<'tcx, Tag> Scalar { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), - None => err!(InvalidChar(val as u128)), + None => throw_unsup!(InvalidChar(val as u128)), } } @@ -543,15 +530,17 @@ impl<'tcx, Tag> ScalarMaybeUndef { pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), - ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))), + ScalarMaybeUndef::Undef => throw_unsup!(ReadUndefBytes(Size::from_bytes(0))), } } + /// Do not call this method! Use either `assert_ptr` or `force_ptr`. #[inline(always)] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { self.not_undef()?.to_ptr() } + /// Do not call this method! Use either `assert_bits` or `force_bits`. #[inline(always)] pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> { self.not_undef()?.to_bits(target_size) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9b1808c585..1e2ec08301 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -7,8 +7,18 @@ use crate::hir::def::{CtorKind, Namespace}; use crate::hir::def_id::DefId; use crate::hir::{self, InlineAsm as HirInlineAsm}; -use crate::mir::interpret::{ConstValue, InterpError, Scalar}; +use crate::mir::interpret::{ConstValue, PanicInfo, Scalar}; use crate::mir::visit::MirVisitable; +use crate::ty::adjustment::PointerCast; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::layout::VariantIdx; +use crate::ty::print::{FmtPrinter, Printer}; +use crate::ty::subst::{Subst, SubstsRef}; +use crate::ty::{ + self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, + UserTypeAnnotationIndex, +}; +use polonius_engine::Atom; use rustc_data_structures::bit_set::BitMatrix; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::{dominators, Dominators}; @@ -17,10 +27,10 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::MappedReadGuard; use rustc_macros::HashStable; -use crate::rustc_serialize::{self as serialize}; +use rustc_serialize::{Encodable, Decodable}; use smallvec::SmallVec; use std::borrow::Cow; -use std::fmt::{self, Debug, Formatter, Write, Display}; +use std::fmt::{self, Debug, Display, Formatter, Write}; use std::iter::FusedIterator; use std::ops::{Index, IndexMut}; use std::slice; @@ -29,15 +39,6 @@ use std::{iter, mem, option, u32}; use syntax::ast::Name; use syntax::symbol::{InternedString, Symbol}; use syntax_pos::{Span, DUMMY_SP}; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use crate::ty::subst::{Subst, SubstsRef}; -use crate::ty::layout::VariantIdx; -use crate::ty::{ - self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, - UserTypeAnnotationIndex, -}; -use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::adjustment::{PointerCast}; pub use crate::mir::interpret::AssertMessage; @@ -224,10 +225,7 @@ impl<'tcx> Body<'tcx> { #[inline] pub fn basic_blocks_and_local_decls_mut( &mut self, - ) -> ( - &mut IndexVec>, - &mut LocalDecls<'tcx>, - ) { + ) -> (&mut IndexVec>, &mut LocalDecls<'tcx>) { self.cache.invalidate(); (&mut self.basic_blocks, &mut self.local_decls) } @@ -259,16 +257,10 @@ impl<'tcx> Body<'tcx> { let if_not_zero_locations = if loc.statement_index == 0 { None } else { - Some(Location { - block: loc.block, - statement_index: loc.statement_index - 1, - }) + Some(Location { block: loc.block, statement_index: loc.statement_index - 1 }) }; - if_zero_locations - .into_iter() - .flatten() - .chain(if_not_zero_locations) + if_zero_locations.into_iter().flatten().chain(if_not_zero_locations) } #[inline] @@ -406,10 +398,7 @@ impl<'tcx> Body<'tcx> { /// Gets the location of the terminator for the given block pub fn terminator_loc(&self, bb: BasicBlock) -> Location { - Location { - block: bb, - statement_index: self[bb].statements.len(), - } + Location { block: bb, statement_index: self[bb].statements.len() } } } @@ -474,8 +463,8 @@ impl ClearCrossCrate { } } -impl serialize::UseSpecializedEncodable for ClearCrossCrate {} -impl serialize::UseSpecializedDecodable for ClearCrossCrate {} +impl rustc_serialize::UseSpecializedEncodable for ClearCrossCrate {} +impl rustc_serialize::UseSpecializedDecodable for ClearCrossCrate {} /// Grouped information about the source code origin of a MIR entity. /// Intended to be inspected by diagnostics and debuginfo. @@ -508,8 +497,9 @@ impl From for hir::Mutability { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, - Ord, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, HashStable, +)] pub enum BorrowKind { /// Data must be immutable and is aliasable. Shared, @@ -600,6 +590,12 @@ newtype_index! { } } +impl Atom for Local { + fn index(self) -> usize { + Idx::index(self) + } +} + /// Classifies locals into categories. See `Body::local_kind`. #[derive(PartialEq, Eq, Debug, HashStable)] pub enum LocalKind { @@ -658,7 +654,7 @@ pub enum ImplicitSelfKind { MutRef, /// Represents when a function does not have a self argument or /// when a function has a `self: X` argument. - None + None, } CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, } @@ -889,8 +885,7 @@ impl<'tcx> LocalDecl<'tcx> { pat_span: _, }))) => true, - Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm))) - => true, + Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm))) => true, _ => false, } @@ -928,7 +923,7 @@ impl<'tcx> LocalDecl<'tcx> { /// `__next` from a `for` loop. #[inline] pub fn from_compiler_desugaring(&self) -> bool { - self.source_info.span.compiler_desugaring_kind().is_some() + self.source_info.span.desugaring_kind().is_some() } /// Creates a new `LocalDecl` for a temporary. @@ -959,21 +954,13 @@ impl<'tcx> LocalDecl<'tcx> { } #[inline] - fn new_local( - ty: Ty<'tcx>, - mutability: Mutability, - internal: bool, - span: Span, - ) -> Self { + fn new_local(ty: Ty<'tcx>, mutability: Mutability, internal: bool, span: Span) -> Self { LocalDecl { mutability, ty, user_ty: UserTypeProjections::none(), name: None, - source_info: SourceInfo { - span, - scope: OUTERMOST_SOURCE_SCOPE, - }, + source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, visibility_scope: OUTERMOST_SOURCE_SCOPE, internal, is_user_variable: None, @@ -990,10 +977,7 @@ impl<'tcx> LocalDecl<'tcx> { mutability: Mutability::Mut, ty: return_ty, user_ty: UserTypeProjections::none(), - source_info: SourceInfo { - span, - scope: OUTERMOST_SOURCE_SCOPE, - }, + source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, visibility_scope: OUTERMOST_SOURCE_SCOPE, internal: false, is_block_tail: None, @@ -1025,10 +1009,7 @@ newtype_index! { impl BasicBlock { pub fn start_location(self) -> Location { - Location { - block: self, - statement_index: 0, - } + Location { block: self, statement_index: 0 } } } @@ -1111,11 +1092,7 @@ pub enum TerminatorKind<'tcx> { Unreachable, /// Drop the Place - Drop { - location: Place<'tcx>, - target: BasicBlock, - unwind: Option, - }, + Drop { location: Place<'tcx>, target: BasicBlock, unwind: Option }, /// Drop the Place and assign the new value over it. This ensures /// that the assignment to `P` occurs *even if* the destructor for @@ -1263,80 +1240,27 @@ impl<'tcx> TerminatorKind<'tcx> { | GeneratorDrop | Return | Unreachable - | Call { - destination: None, - cleanup: None, - .. - } => None.into_iter().chain(&[]), + | 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(&[]), - 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), - .. + | 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(&[]), + 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)) } - | 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[..]), - FalseEdges { - ref real_target, - ref imaginary_target, - } => Some(real_target).into_iter().chain(slice::from_ref(imaginary_target)), + FalseEdges { ref real_target, ref imaginary_target } => { + Some(real_target).into_iter().chain(slice::from_ref(imaginary_target)) + } } } @@ -1348,84 +1272,29 @@ impl<'tcx> TerminatorKind<'tcx> { | GeneratorDrop | Return | Unreachable - | Call { - destination: None, - cleanup: None, - .. - } => None.into_iter().chain(&mut []), + | 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), - .. + | 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 []) } - | DropAndReplace { - target: ref mut t, - unwind: Some(ref mut u), - .. + 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_mut(u)) } - | Drop { - target: ref mut t, - unwind: Some(ref mut u), - .. + SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets[..]), + FalseEdges { ref mut real_target, ref mut imaginary_target } => { + Some(real_target).into_iter().chain(slice::from_mut(imaginary_target)) } - | 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_mut(u)), - SwitchInt { - ref mut targets, .. - } => None.into_iter().chain(&mut targets[..]), - FalseEdges { - ref mut real_target, - ref mut imaginary_target, - } => Some(real_target) - .into_iter() - .chain(slice::from_mut(imaginary_target)), } } @@ -1440,14 +1309,8 @@ impl<'tcx> TerminatorKind<'tcx> { | TerminatorKind::Yield { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdges { .. } => None, - TerminatorKind::Call { - cleanup: ref unwind, - .. - } - | TerminatorKind::Assert { - cleanup: ref unwind, - .. - } + TerminatorKind::Call { cleanup: ref unwind, .. } + | TerminatorKind::Assert { cleanup: ref unwind, .. } | TerminatorKind::DropAndReplace { ref unwind, .. } | TerminatorKind::Drop { ref unwind, .. } | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind), @@ -1465,14 +1328,8 @@ impl<'tcx> TerminatorKind<'tcx> { | TerminatorKind::Yield { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::FalseEdges { .. } => None, - TerminatorKind::Call { - cleanup: ref mut unwind, - .. - } - | TerminatorKind::Assert { - cleanup: ref mut unwind, - .. - } + TerminatorKind::Call { cleanup: ref mut unwind, .. } + | TerminatorKind::Assert { cleanup: ref mut unwind, .. } | TerminatorKind::DropAndReplace { ref mut unwind, .. } | TerminatorKind::Drop { ref mut unwind, .. } | TerminatorKind::FalseUnwind { ref mut unwind, .. } => Some(unwind), @@ -1482,11 +1339,7 @@ impl<'tcx> TerminatorKind<'tcx> { impl<'tcx> BasicBlockData<'tcx> { pub fn new(terminator: Option>) -> BasicBlockData<'tcx> { - BasicBlockData { - statements: vec![], - terminator, - is_cleanup: false, - } + BasicBlockData { statements: vec![], terminator, is_cleanup: false } } /// Accessor for terminator. @@ -1548,10 +1401,7 @@ impl<'tcx> BasicBlockData<'tcx> { self.statements.resize( gap.end, Statement { - source_info: SourceInfo { - span: DUMMY_SP, - scope: OUTERMOST_SOURCE_SCOPE, - }, + source_info: SourceInfo { span: DUMMY_SP, scope: OUTERMOST_SOURCE_SCOPE }, kind: StatementKind::Nop, }, ); @@ -1610,9 +1460,7 @@ impl<'tcx> TerminatorKind<'tcx> { use self::TerminatorKind::*; match *self { Goto { .. } => write!(fmt, "goto"), - SwitchInt { - discr: ref place, .. - } => write!(fmt, "switchInt({:?})", place), + SwitchInt { discr: ref place, .. } => write!(fmt, "switchInt({:?})", place), Return => write!(fmt, "return"), GeneratorDrop => write!(fmt, "generator_drop"), Resume => write!(fmt, "resume"), @@ -1620,17 +1468,10 @@ impl<'tcx> TerminatorKind<'tcx> { Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value), Unreachable => write!(fmt, "unreachable"), Drop { ref location, .. } => write!(fmt, "drop({:?})", location), - DropAndReplace { - ref location, - ref value, - .. - } => write!(fmt, "replace({:?} <- {:?})", location, value), - Call { - ref func, - ref args, - ref destination, - .. - } => { + DropAndReplace { ref location, ref value, .. } => { + write!(fmt, "replace({:?} <- {:?})", location, value) + } + Call { ref func, ref args, ref destination, .. } => { if let Some((ref destination, _)) = *destination { write!(fmt, "{:?} = ", destination)?; } @@ -1643,12 +1484,7 @@ impl<'tcx> TerminatorKind<'tcx> { } write!(fmt, ")") } - Assert { - ref cond, - expected, - ref msg, - .. - } => { + Assert { ref cond, expected, ref msg, .. } => { write!(fmt, "assert(")?; if !expected { write!(fmt, "!")?; @@ -1666,69 +1502,41 @@ impl<'tcx> TerminatorKind<'tcx> { match *self { Return | Resume | Abort | Unreachable | GeneratorDrop => vec![], Goto { .. } => vec!["".into()], - SwitchInt { - ref values, - switch_ty, - .. - } => { - ty::tls::with(|tcx| { - let param_env = ty::ParamEnv::empty(); - let switch_ty = tcx.lift_to_global(&switch_ty).unwrap(); - let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size; - values - .iter() - .map(|&u| { - tcx.mk_const(ty::Const { - val: ConstValue::Scalar( - Scalar::from_uint(u, size).into(), - ), - ty: switch_ty, - }).to_string().into() - }).chain(iter::once("otherwise".into())) - .collect() - }) + SwitchInt { ref values, switch_ty, .. } => ty::tls::with(|tcx| { + let param_env = ty::ParamEnv::empty(); + let switch_ty = tcx.lift_to_global(&switch_ty).unwrap(); + let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size; + values + .iter() + .map(|&u| { + tcx.mk_const(ty::Const { + val: ConstValue::Scalar(Scalar::from_uint(u, size).into()), + ty: switch_ty, + }) + .to_string() + .into() + }) + .chain(iter::once("otherwise".into())) + .collect() + }), + Call { destination: Some(_), cleanup: Some(_), .. } => { + vec!["return".into(), "unwind".into()] } - Call { - destination: Some(_), - cleanup: Some(_), - .. - } => vec!["return".into(), "unwind".into()], - Call { - destination: Some(_), - cleanup: None, - .. - } => vec!["return".into()], - Call { - destination: None, - cleanup: Some(_), - .. - } => vec!["unwind".into()], - Call { - destination: None, - cleanup: None, - .. - } => vec![], + Call { destination: Some(_), cleanup: None, .. } => vec!["return".into()], + Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()], + Call { destination: None, cleanup: None, .. } => vec![], Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()], Yield { drop: None, .. } => vec!["resume".into()], DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => { vec!["return".into()] } - DropAndReplace { - unwind: Some(_), .. + DropAndReplace { unwind: Some(_), .. } | Drop { unwind: Some(_), .. } => { + vec!["return".into(), "unwind".into()] } - | Drop { - unwind: Some(_), .. - } => vec!["return".into(), "unwind".into()], Assert { cleanup: None, .. } => vec!["".into()], Assert { .. } => vec!["success".into(), "unwind".into()], - FalseEdges { - .. - } => { - vec!["real".into(), "imaginary".into()] - } - FalseUnwind { - unwind: Some(_), .. - } => vec!["real".into(), "cleanup".into()], + FalseEdges { .. } => vec!["real".into(), "imaginary".into()], + FalseUnwind { unwind: Some(_), .. } => vec!["real".into(), "cleanup".into()], FalseUnwind { unwind: None, .. } => vec!["real".into()], } } @@ -1778,10 +1586,7 @@ pub enum StatementKind<'tcx> { FakeRead(FakeReadCause, Place<'tcx>), /// Write the discriminant for a variant to the enum Place. - SetDiscriminant { - place: Place<'tcx>, - variant_index: VariantIdx, - }, + SetDiscriminant { place: Place<'tcx>, variant_index: VariantIdx }, /// Start a live range for the storage of the local. StorageLive(Local), @@ -1878,24 +1683,25 @@ impl<'tcx> Debug for Statement<'tcx> { match self.kind { Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv), FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place), - Retag(ref kind, ref place) => - write!(fmt, "Retag({}{:?})", - match kind { - RetagKind::FnEntry => "[fn entry] ", - RetagKind::TwoPhase => "[2phase] ", - RetagKind::Raw => "[raw] ", - RetagKind::Default => "", - }, - place, - ), + Retag(ref kind, ref place) => write!( + fmt, + "Retag({}{:?})", + match kind { + RetagKind::FnEntry => "[fn entry] ", + RetagKind::TwoPhase => "[2phase] ", + RetagKind::Raw => "[raw] ", + RetagKind::Default => "", + }, + place, + ), StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place), StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place), - SetDiscriminant { - ref place, - variant_index, - } => write!(fmt, "discriminant({:?}) = {:?}", place, variant_index), - InlineAsm(ref asm) => - write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs), + SetDiscriminant { ref place, variant_index } => { + write!(fmt, "discriminant({:?}) = {:?}", place, variant_index) + } + InlineAsm(ref asm) => { + write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs) + } AscribeUserType(ref place, ref variance, ref c_ty) => { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } @@ -1909,15 +1715,19 @@ impl<'tcx> Debug for Statement<'tcx> { /// A path to a value; something that can be evaluated without /// changing or disturbing program state. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] -pub enum Place<'tcx> { - Base(PlaceBase<'tcx>), +#[derive( + Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, +)] +pub struct Place<'tcx> { + pub base: PlaceBase<'tcx>, /// projection out of a place (access a field, deref a pointer, etc) - Projection(Box>), + pub projection: Option>>, } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, +)] pub enum PlaceBase<'tcx> { /// local variable Local(Local), @@ -1933,7 +1743,9 @@ pub struct Static<'tcx> { pub kind: StaticKind, } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable)] +#[derive( + Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable, +)] pub enum StaticKind { Promoted(Promoted), Static(DefId), @@ -1945,15 +1757,17 @@ impl_stable_hash_for!(struct Static<'tcx> { }); /// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, - Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, +)] pub struct Projection<'tcx> { - pub base: Place<'tcx>, + pub base: Option>>, pub elem: PlaceElem<'tcx>, - } +} -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, - Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, +)] pub enum ProjectionElem { Deref, Field(Field, T), @@ -2012,8 +1826,17 @@ newtype_index! { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PlaceRef<'a, 'tcx> { + pub base: &'a PlaceBase<'tcx>, + pub projection: &'a Option>>, +} + impl<'tcx> Place<'tcx> { - pub const RETURN_PLACE: Place<'tcx> = Place::Base(PlaceBase::Local(RETURN_PLACE)); + pub const RETURN_PLACE: Place<'tcx> = Place { + base: PlaceBase::Local(RETURN_PLACE), + projection: None, + }; pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { self.elem(ProjectionElem::Field(f, ty)) @@ -2026,7 +1849,8 @@ impl<'tcx> Place<'tcx> { pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Place<'tcx> { self.elem(ProjectionElem::Downcast( Some(adt_def.variants[variant_index].ident.name), - variant_index)) + variant_index, + )) } pub fn downcast_unnamed(self, variant_index: VariantIdx) -> Place<'tcx> { @@ -2038,7 +1862,10 @@ impl<'tcx> Place<'tcx> { } pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> { - Place::Projection(Box::new(Projection { base: self, elem })) + Place { + base: self.base, + projection: Some(Box::new(Projection { base: self.projection, elem })), + } } /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or @@ -2047,58 +1874,77 @@ impl<'tcx> Place<'tcx> { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self { - Place::Base(PlaceBase::Local(local)) | - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(local)), - elem: ProjectionElem::Deref, - }) => Some(*local), + Place { + base: PlaceBase::Local(local), + projection: None, + } | + Place { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + } => Some(*local), _ => None, } } - /// Finds the innermost `Local` from this `Place`. - pub fn base_local(&self) -> Option { - let mut place = self; - loop { - match place { - Place::Projection(proj) => place = &proj.base, - Place::Base(PlaceBase::Static(_)) => return None, - Place::Base(PlaceBase::Local(local)) => return Some(*local), - } - } - } - /// Recursively "iterates" over place components, generating a `PlaceBase` and /// `Projections` list and invoking `op` with a `ProjectionsIter`. pub fn iterate( &self, op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R, ) -> R { - self.iterate2(&Projections::Empty, op) + Place::iterate_over(&self.base, &self.projection, op) } - fn iterate2( - &self, - next: &Projections<'_, 'tcx>, + pub fn iterate_over( + place_base: &PlaceBase<'tcx>, + place_projection: &Option>>, op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R, ) -> R { - match self { - Place::Projection(interior) => interior.base.iterate2( - &Projections::List { - projection: interior, - next, - }, - op, - ), + fn iterate_over2<'tcx, R>( + place_base: &PlaceBase<'tcx>, + place_projection: &Option>>, + next: &Projections<'_, 'tcx>, + op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R, + ) -> R { + match place_projection { + None => { + op(place_base, next.iter()) + } + + Some(interior) => { + iterate_over2( + place_base, + &interior.base, + &Projections::List { + projection: interior, + next, + }, + op, + ) + } + } + } - Place::Base(base) => op(base, next.iter()), + iterate_over2(place_base, place_projection, &Projections::Empty, op) + } + + pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> { + PlaceRef { + base: &self.base, + projection: &self.projection, } } } impl From for Place<'_> { fn from(local: Local) -> Self { - Place::Base(local.into()) + Place { + base: local.into(), + projection: None, + } } } @@ -2108,6 +1954,36 @@ impl From for PlaceBase<'_> { } } +impl<'a, 'tcx> PlaceRef<'a, 'tcx> { + pub fn iterate( + &self, + op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R, + ) -> R { + Place::iterate_over(self.base, self.projection, op) + } + + /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or + /// a single deref of a local. + // + // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? + pub fn local_or_deref_local(&self) -> Option { + match self { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } | + PlaceRef { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + } => Some(*local), + _ => None, + } + } +} + /// A linked list of projections running up the stack; begins with the /// innermost projection and extends to the outermost (e.g., `a.b.c` /// would have the place `b` with a "next" pointer to `b.c`). @@ -2119,10 +1995,7 @@ impl From for PlaceBase<'_> { pub enum Projections<'p, 'tcx> { Empty, - List { - projection: &'p Projection<'tcx>, - next: &'p Projections<'p, 'tcx>, - } + List { projection: &'p Projection<'tcx>, next: &'p Projections<'p, 'tcx> }, } impl<'p, 'tcx> Projections<'p, 'tcx> { @@ -2181,16 +2054,15 @@ impl<'tcx> Debug for Place<'tcx> { let projs_vec: Vec<_> = place_projections.collect(); for projection in projs_vec.iter().rev() { match projection.elem { - ProjectionElem::Downcast(_, _) | - ProjectionElem::Field(_, _) => { + ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => { write!(fmt, "(").unwrap(); } ProjectionElem::Deref => { write!(fmt, "(*").unwrap(); } - ProjectionElem::Index(_) | - ProjectionElem::ConstantIndex { .. } | - ProjectionElem::Subslice { .. } => {} + ProjectionElem::Index(_) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } => {} } } }); @@ -2215,18 +2087,10 @@ impl<'tcx> Debug for Place<'tcx> { ProjectionElem::Index(ref index) => { write!(fmt, "[{:?}]", index)?; } - ProjectionElem::ConstantIndex { - offset, - min_length, - from_end: false, - } => { + ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => { write!(fmt, "[{:?} of {:?}]", offset, min_length)?; } - ProjectionElem::ConstantIndex { - offset, - min_length, - from_end: true, - } => { + ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => { write!(fmt, "[-{:?} of {:?}]", offset, min_length)?; } ProjectionElem::Subslice { from, to } if to == 0 => { @@ -2251,21 +2115,11 @@ impl Debug for PlaceBase<'_> { match *self { PlaceBase::Local(id) => write!(fmt, "{:?}", id), PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) }) => { - write!( - fmt, - "({}: {:?})", - ty::tls::with(|tcx| tcx.def_path_str(def_id)), - ty - ) - }, + write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty) + } PlaceBase::Static(box self::Static { ty, kind: StaticKind::Promoted(promoted) }) => { - write!( - fmt, - "({:?}: {:?})", - promoted, - ty - ) - }, + write!(fmt, "({:?}: {:?})", promoted, ty) + } } } } @@ -2396,7 +2250,6 @@ pub enum Rvalue<'tcx> { Aggregate(Box>, Vec>), } - #[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] pub enum CastKind { Misc, @@ -2414,13 +2267,7 @@ pub enum AggregateKind<'tcx> { /// active field number and is present only for union expressions /// -- e.g., for a union expression `SomeUnion { c: .. }`, the /// active field index would identity the field `c` - Adt( - &'tcx AdtDef, - VariantIdx, - SubstsRef<'tcx>, - Option, - Option, - ), + Adt(&'tcx AdtDef, VariantIdx, SubstsRef<'tcx>, Option, Option), Closure(DefId, ClosureSubsts<'tcx>), Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability), @@ -2598,8 +2445,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { - let name = format!("[generator@{:?}]", - tcx.hir().span(hir_id)); + let name = format!("[generator@{:?}]", tcx.hir().span(hir_id)); let mut struct_fmt = fmt.debug_struct(&name); if let Some(upvars) = tcx.upvars(def_id) { @@ -2690,30 +2536,26 @@ impl<'tcx> UserTypeProjections { UserTypeProjections { contents: vec![] } } - pub fn from_projections(projs: impl Iterator) -> Self { + pub fn from_projections(projs: impl Iterator) -> Self { UserTypeProjections { contents: projs.collect() } } - pub fn projections_and_spans(&self) -> impl Iterator { + pub fn projections_and_spans(&self) -> impl Iterator { self.contents.iter() } - pub fn projections(&self) -> impl Iterator { + pub fn projections(&self) -> impl Iterator { self.contents.iter().map(|&(ref user_type, _span)| user_type) } - pub fn push_projection( - mut self, - user_ty: &UserTypeProjection, - span: Span, - ) -> Self { + pub fn push_projection(mut self, user_ty: &UserTypeProjection, span: Span) -> Self { self.contents.push((user_ty.clone(), span)); self } fn map_projections( mut self, - mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection + mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection, ) -> Self { self.contents = self.contents.drain(..).map(|(proj, span)| (f(proj), span)).collect(); self @@ -2735,12 +2577,7 @@ impl<'tcx> UserTypeProjections { self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field)) } - pub fn variant( - self, - adt_def: &'tcx AdtDef, - variant_index: VariantIdx, - field: Field, - ) -> Self { + pub fn variant(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx, field: Field) -> Self { self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field)) } } @@ -2766,7 +2603,7 @@ pub struct UserTypeProjection { pub projs: Vec, } -impl Copy for ProjectionKind { } +impl Copy for ProjectionKind {} impl UserTypeProjection { pub(crate) fn index(mut self) -> Self { @@ -2797,7 +2634,8 @@ impl UserTypeProjection { ) -> Self { self.projs.push(ProjectionElem::Downcast( Some(adt_def.variants[variant_index].ident.name), - variant_index)); + variant_index, + )); self.projs.push(ProjectionElem::Field(field, ())); self } @@ -2810,15 +2648,15 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { use crate::mir::ProjectionElem::*; let base = self.base.fold_with(folder); - let projs: Vec<_> = self.projs + let projs: Vec<_> = self + .projs .iter() - .map(|elem| { - match elem { - Deref => Deref, - Field(f, ()) => Field(f.clone(), ()), - Index(()) => Index(()), - elem => elem.clone(), - }}) + .map(|elem| match elem { + Deref => Deref, + Field(f, ()) => Field(f.clone(), ()), + Index(()) => Index(()), + elem => elem.clone(), + }) .collect(); UserTypeProjection { base, projs } @@ -2867,19 +2705,19 @@ impl<'tcx> graph::WithStartNode for Body<'tcx> { } impl<'tcx> graph::WithPredecessors for Body<'tcx> { - fn predecessors<'graph>( - &'graph self, + fn predecessors( + &self, node: Self::Node, - ) -> >::Iter { + ) -> >::Iter { self.predecessors_for(node).clone().into_iter() } } impl<'tcx> graph::WithSuccessors for Body<'tcx> { - fn successors<'graph>( - &'graph self, + fn successors( + &self, node: Self::Node, - ) -> >::Iter { + ) -> >::Iter { self.basic_blocks[node].terminator().successors().cloned() } } @@ -2911,20 +2749,14 @@ impl fmt::Debug for Location { } impl Location { - pub const START: Location = Location { - block: START_BLOCK, - statement_index: 0, - }; + pub const START: Location = Location { block: START_BLOCK, statement_index: 0 }; /// Returns the location immediately after this one within the enclosing block. /// /// Note that if this location represents a terminator, then the /// resulting location would be out of bounds and invalid. pub fn successor_within_block(&self) -> Location { - Location { - block: self.block, - statement_index: self.statement_index + 1, - } + Location { block: self.block, statement_index: self.statement_index + 1 } } /// Returns `true` if `other` is earlier in the control flow graph than `self`. @@ -3114,8 +2946,19 @@ pub struct ClosureOutlivesRequirement<'tcx> { /// order of the category, thereby influencing diagnostic output. /// /// See also [rustc_mir::borrow_check::nll::constraints] -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, - Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Copy, + Clone, + Debug, + Eq, + PartialEq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable, +)] pub enum ConstraintCategory { Return, Yield, @@ -3278,56 +3121,27 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { let kind = match self.kind { Goto { target } => Goto { target }, - SwitchInt { - ref discr, - switch_ty, - ref values, - ref targets, - } => SwitchInt { + SwitchInt { ref discr, switch_ty, ref values, ref targets } => SwitchInt { discr: discr.fold_with(folder), switch_ty: switch_ty.fold_with(folder), values: values.clone(), targets: targets.clone(), }, - Drop { - ref location, - target, - unwind, - } => Drop { - location: location.fold_with(folder), - target, - unwind, - }, - DropAndReplace { - ref location, - ref value, - target, - unwind, - } => DropAndReplace { + Drop { ref location, target, unwind } => { + Drop { location: location.fold_with(folder), target, unwind } + } + DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace { location: location.fold_with(folder), value: value.fold_with(folder), target, unwind, }, - Yield { - ref value, - resume, - drop, - } => Yield { - value: value.fold_with(folder), - resume: resume, - drop: drop, - }, - Call { - ref func, - ref args, - ref destination, - cleanup, - from_hir_call, - } => { - let dest = destination - .as_ref() - .map(|&(ref loc, dest)| (loc.fold_with(folder), dest)); + Yield { ref value, resume, drop } => { + Yield { value: value.fold_with(folder), resume: resume, drop: drop } + } + Call { ref func, ref args, ref destination, cleanup, from_hir_call } => { + let dest = + destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest)); Call { func: func.fold_with(folder), @@ -3337,77 +3151,46 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { from_hir_call, } } - Assert { - ref cond, - expected, - ref msg, - target, - cleanup, - } => { - let msg = if let InterpError::BoundsCheck { ref len, ref index } = *msg { - InterpError::BoundsCheck { - len: len.fold_with(folder), - index: index.fold_with(folder), - } - } else { - msg.clone() + Assert { ref cond, expected, ref msg, target, cleanup } => { + use PanicInfo::*; + let msg = match msg { + BoundsCheck { ref len, ref index } => + BoundsCheck { + len: len.fold_with(folder), + index: index.fold_with(folder), + }, + Panic { .. } | Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero | + GeneratorResumedAfterReturn | GeneratorResumedAfterPanic => + msg.clone(), }; - Assert { - cond: cond.fold_with(folder), - expected, - msg, - target, - cleanup, - } + Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup } } GeneratorDrop => GeneratorDrop, Resume => Resume, Abort => Abort, Return => Return, Unreachable => Unreachable, - FalseEdges { - real_target, - imaginary_target, - } => FalseEdges { - real_target, - imaginary_target, - }, - FalseUnwind { - real_target, - unwind, - } => FalseUnwind { - real_target, - unwind, - }, + FalseEdges { real_target, imaginary_target } => { + FalseEdges { real_target, imaginary_target } + } + FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind }, }; - Terminator { - source_info: self.source_info, - kind, - } + Terminator { source_info: self.source_info, kind } } fn super_visit_with>(&self, visitor: &mut V) -> bool { use crate::mir::TerminatorKind::*; match self.kind { - SwitchInt { - ref discr, - switch_ty, - .. - } => discr.visit_with(visitor) || switch_ty.visit_with(visitor), + SwitchInt { ref discr, switch_ty, .. } => { + discr.visit_with(visitor) || switch_ty.visit_with(visitor) + } Drop { ref location, .. } => location.visit_with(visitor), - DropAndReplace { - ref location, - ref value, - .. - } => location.visit_with(visitor) || value.visit_with(visitor), + DropAndReplace { ref location, ref value, .. } => { + location.visit_with(visitor) || value.visit_with(visitor) + } Yield { ref value, .. } => value.visit_with(visitor), - Call { - ref func, - ref args, - ref destination, - .. - } => { + Call { ref func, ref args, ref destination, .. } => { let dest = if let Some((ref loc, _)) = *destination { loc.visit_with(visitor) } else { @@ -3415,14 +3198,16 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { }; dest || func.visit_with(visitor) || args.visit_with(visitor) } - Assert { - ref cond, ref msg, .. - } => { + Assert { ref cond, ref msg, .. } => { if cond.visit_with(visitor) { - if let InterpError::BoundsCheck { ref len, ref index } = *msg { - len.visit_with(visitor) || index.visit_with(visitor) - } else { - false + use PanicInfo::*; + match msg { + BoundsCheck { ref len, ref index } => + len.visit_with(visitor) || index.visit_with(visitor), + Panic { .. } | Overflow(_) | OverflowNeg | + DivisionByZero | RemainderByZero | + GeneratorResumedAfterReturn | GeneratorResumedAfterPanic => + false } } else { false @@ -3442,18 +3227,14 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - match self { - &Place::Projection(ref p) => Place::Projection(p.fold_with(folder)), - _ => self.clone(), + Place { + base: self.base.clone(), + projection: self.projection.fold_with(folder), } } fn super_visit_with>(&self, visitor: &mut V) -> bool { - if let &Place::Projection(ref p) = self { - p.visit_with(visitor) - } else { - false - } + self.projection.visit_with(visitor) } } @@ -3564,11 +3345,12 @@ impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> { fn super_visit_with>(&self, visitor: &mut Vs) -> bool { use crate::mir::ProjectionElem::*; - self.base.visit_with(visitor) || match self.elem { - Field(_, ref ty) => ty.visit_with(visitor), - Index(ref v) => v.visit_with(visitor), - _ => false, - } + self.base.visit_with(visitor) + || match self.elem { + Field(_, ref ty) => ty.visit_with(visitor), + Index(ref v) => v.visit_with(visitor), + _ => false, + } } } diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 432a61de6c..a061e6f48f 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -79,7 +79,7 @@ impl<'tcx> MonoItem<'tcx> { tcx.symbol_name(Instance::mono(tcx, def_id)) } MonoItem::GlobalAsm(hir_id) => { - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); SymbolName { name: InternedString::intern(&format!("global_asm_{:?}", def_id)) } diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 2079a2a34e..f8889380b2 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -57,7 +57,7 @@ impl<'tcx> PlaceTy<'tcx> { /// `PlaceElem`, where we can just use the `Ty` that is already /// stored inline on field projection elems. pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> { - self.projection_ty_core(tcx, elem, |_, _, ty| ty) + self.projection_ty_core(tcx, ty::ParamEnv::empty(), elem, |_, _, ty| ty) } /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` @@ -68,6 +68,7 @@ impl<'tcx> PlaceTy<'tcx> { pub fn projection_ty_core( self, tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, elem: &ProjectionElem, mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>, ) -> PlaceTy<'tcx> @@ -90,7 +91,7 @@ impl<'tcx> PlaceTy<'tcx> { ProjectionElem::Subslice { from, to } => { PlaceTy::from_ty(match self.ty.sty { ty::Array(inner, size) => { - let size = size.unwrap_usize(tcx); + let size = size.eval_usize(tcx, param_env); let len = size - (from as u64) - (to as u64); tcx.mk_array(inner, len) } @@ -118,11 +119,15 @@ BraceStructTypeFoldableImpl! { } impl<'tcx> Place<'tcx> { - pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> - where - D: HasLocalDecls<'tcx>, + pub fn ty_from( + base: &PlaceBase<'tcx>, + projection: &Option>>, + local_decls: &D, + tcx: TyCtxt<'tcx> + ) -> PlaceTy<'tcx> + where D: HasLocalDecls<'tcx> { - self.iterate(|place_base, place_projections| { + Place::iterate_over(base, projection, |place_base, place_projections| { let mut place_ty = place_base.ty(local_decls); for proj in place_projections { @@ -132,6 +137,13 @@ impl<'tcx> Place<'tcx> { place_ty }) } + + pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> + where + D: HasLocalDecls<'tcx>, + { + Place::ty_from(&self.base, &self.projection, local_decls, tcx) + } } impl<'tcx> PlaceBase<'tcx> { diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index babce812d4..ee4ecb6762 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -159,10 +159,11 @@ macro_rules! make_mir_visitor { } fn visit_projection(&mut self, + place_base: & $($mutability)? PlaceBase<'tcx>, place: & $($mutability)? Projection<'tcx>, context: PlaceContext, location: Location) { - self.super_projection(place, context, location); + self.super_projection(place_base, place, context, location); } fn visit_constant(&mut self, @@ -513,10 +514,16 @@ macro_rules! make_mir_visitor { fn super_assert_message(&mut self, msg: & $($mutability)? AssertMessage<'tcx>, location: Location) { - use crate::mir::interpret::InterpError::*; - if let BoundsCheck { len, index } = msg { - self.visit_operand(len, location); - self.visit_operand(index, location); + use crate::mir::interpret::PanicInfo::*; + match msg { + BoundsCheck { len, index } => { + self.visit_operand(len, location); + self.visit_operand(index, location); + } + Panic { .. } | Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero | + GeneratorResumedAfterReturn | GeneratorResumedAfterPanic => { + // Nothing to visit + } } } @@ -676,19 +683,20 @@ macro_rules! make_mir_visitor { place: & $($mutability)? Place<'tcx>, context: PlaceContext, location: Location) { - match place { - Place::Base(place_base) => { - self.visit_place_base(place_base, context, location); - } - Place::Projection(proj) => { - let context = if context.is_mutating_use() { - PlaceContext::MutatingUse(MutatingUseContext::Projection) - } else { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) - }; + let mut context = context; + + if place.projection.is_some() { + context = if context.is_mutating_use() { + PlaceContext::MutatingUse(MutatingUseContext::Projection) + } else { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) + }; + } - self.visit_projection(proj, context, location); - } + self.visit_place_base(& $($mutability)? place.base, context, location); + + if let Some(box proj) = & $($mutability)? place.projection { + self.visit_projection(& $($mutability)? place.base, proj, context, location); } } @@ -707,13 +715,14 @@ macro_rules! make_mir_visitor { } fn super_projection(&mut self, + place_base: & $($mutability)? PlaceBase<'tcx>, proj: & $($mutability)? Projection<'tcx>, context: PlaceContext, location: Location) { - // this is calling `super_place` in preparation for changing `Place` to be - // a struct with a base and a slice of projections. `visit_place` should only ever - // be called for the outermost place now. - self.super_place(& $($mutability)? proj.base, context, location); + if let Some(box proj_base) = & $($mutability)? proj.base { + self.visit_projection(place_base, proj_base, context, location); + } + match & $($mutability)? proj.elem { ProjectionElem::Deref => { } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index d2082ab87e..5ab1b90642 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -124,6 +124,8 @@ rustc_queries! { mir.map(|x| &*tcx.arena.alloc(x)) } } + + query promoted_mir(key: DefId) -> &'tcx IndexVec> { } } TypeChecking { @@ -422,11 +424,6 @@ rustc_queries! { "const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id()) } - cache_on_disk_if(_, opt_result) { - // Only store results without errors - // FIXME: We never store these - opt_result.map_or(true, |r| r.is_ok()) - } } /// Results of evaluating const items or constants embedded in @@ -464,7 +461,7 @@ rustc_queries! { } TypeChecking { - query check_match(key: DefId) -> () { + query check_match(key: DefId) -> SignalledError { cache_on_disk_if { key.is_local() } } @@ -646,11 +643,11 @@ rustc_queries! { } query is_sanitizer_runtime(_: CrateNum) -> bool { fatal_cycle - desc { "query a crate is #![sanitizer_runtime]" } + desc { "query a crate is `#![sanitizer_runtime]`" } } query is_profiler_runtime(_: CrateNum) -> bool { fatal_cycle - desc { "query a crate is #![profiler_runtime]" } + desc { "query a crate is `#![profiler_runtime]`" } } query panic_strategy(_: CrateNum) -> PanicStrategy { fatal_cycle @@ -658,7 +655,7 @@ rustc_queries! { } query is_no_builtins(_: CrateNum) -> bool { fatal_cycle - desc { "test whether a crate has #![no_builtins]" } + desc { "test whether a crate has `#![no_builtins]`" } } query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion { fatal_cycle diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 9f03326285..3536b2aa8f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -269,11 +269,11 @@ impl OutputTypes { self.0.contains_key(key) } - pub fn keys<'a>(&'a self) -> BTreeMapKeysIter<'a, OutputType, Option> { + pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option> { self.0.keys() } - pub fn values<'a>(&'a self) -> BTreeMapValuesIter<'a, OutputType, Option> { + pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option> { self.0.values() } @@ -316,7 +316,7 @@ impl Externs { self.0.get(key) } - pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, ExternEntry> { + pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> { self.0.iter() } } @@ -438,6 +438,10 @@ top_level_options!( remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], edition: Edition [TRACKED], + + // Whether or not we're emitting JSON blobs about each artifact produced + // by the compiler. + json_artifact_notifications: bool [TRACKED], } ); @@ -625,6 +629,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, + json_artifact_notifications: false, } } } @@ -1144,13 +1149,13 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED], "perform LLVM link-time optimizations"), target_cpu: Option = (None, parse_opt_string, [TRACKED], - "select target processor (rustc --print target-cpus for details)"), + "select target processor (`rustc --print target-cpus` for details)"), target_feature: String = (String::new(), parse_string, [TRACKED], - "target specific attributes (rustc --print target-features for details)"), + "target specific attributes (`rustc --print target-features` for details)"), passes: Vec = (Vec::new(), parse_list, [TRACKED], "a list of extra LLVM passes to run (space separated)"), llvm_args: Vec = (Vec::new(), parse_list, [TRACKED], - "a list of arguments to pass to llvm (space separated)"), + "a list of arguments to pass to LLVM (space separated)"), save_temps: bool = (false, parse_bool, [UNTRACKED], "save all temporary output files during compilation"), rpath: bool = (false, parse_bool, [UNTRACKED], @@ -1172,9 +1177,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, no_redzone: Option = (None, parse_opt_bool, [TRACKED], "disable the use of the redzone"), relocation_model: Option = (None, parse_opt_string, [TRACKED], - "choose the relocation model to use (rustc --print relocation-models for details)"), + "choose the relocation model to use (`rustc --print relocation-models` for details)"), code_model: Option = (None, parse_opt_string, [TRACKED], - "choose the code model to use (rustc --print code-models for details)"), + "choose the code model to use (`rustc --print code-models` for details)"), metadata: Vec = (Vec::new(), parse_list, [TRACKED], "metadata to mangle symbol names with"), extra_filename: String = (String::new(), parse_string, [UNTRACKED], @@ -1184,7 +1189,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED], "print remarks for these optimization passes (space separated, or \"all\")"), no_stack_check: bool = (false, parse_bool, [UNTRACKED], - "the --no-stack-check flag is deprecated and does nothing"), + "the `--no-stack-check` flag is deprecated and does nothing"), debuginfo: Option = (None, parse_opt_uint, [TRACKED], "debug info emission level, 0 = no debug info, 1 = line tables only, \ 2 = full debug info with variable and type information"), @@ -1203,7 +1208,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, default_linker_libraries: Option = (None, parse_opt_bool, [UNTRACKED], "allow the linker to link its default libraries"), linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], - "Linker flavor"), + "linker flavor"), linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, parse_linker_plugin_lto, [TRACKED], "generate build artifacts that are compatible with linker-based LTO."), @@ -1250,7 +1255,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, print_link_args: bool = (false, parse_bool, [UNTRACKED], "print the arguments passed to the linker"), print_llvm_passes: bool = (false, parse_bool, [UNTRACKED], - "prints the llvm optimization passes being run"), + "prints the LLVM optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), threads: Option = (None, parse_opt_uint, [UNTRACKED], @@ -1370,11 +1375,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], "pass `-install_name @rpath/...` to the macOS linker"), sanitizer: Option = (None, parse_sanitizer, [TRACKED], - "Use a sanitizer"), + "use a sanitizer"), fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], "set the optimization fuel quota for a crate"), print_fuel: Option = (None, parse_opt_string, [TRACKED], - "make Rustc print the total optimization fuel used by a crate"), + "make rustc print the total optimization fuel used by a crate"), force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], "force all crates to be `rustc_private` unstable"), pre_link_arg: Vec = (vec![], parse_string_push, [UNTRACKED], @@ -1400,23 +1405,19 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, thinlto: Option = (None, parse_opt_bool, [TRACKED], "enable ThinLTO when possible"), inline_in_all_cgus: Option = (None, parse_opt_bool, [TRACKED], - "control whether #[inline] functions are in all cgus"), + "control whether `#[inline]` functions are in all CGUs"), tls_model: Option = (None, parse_opt_string, [TRACKED], - "choose the TLS model to use (rustc --print tls-models for details)"), + "choose the TLS model to use (`rustc --print tls-models` for details)"), saturating_float_casts: bool = (false, parse_bool, [TRACKED], "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ the max/min integer respectively, and NaN is mapped to 0"), - lower_128bit_ops: Option = (None, parse_opt_bool, [TRACKED], - "rewrite operators on i128 and u128 into lang item calls (typically provided \ - by compiler-builtins) so codegen doesn't need to support them, - overriding the default for the current target"), human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], "generate human-readable, predictable names for codegen units"), dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], "in dep-info output, omit targets for tracking dependencies of the dep-info files \ themselves"), unpretty: Option = (None, parse_unpretty, [UNTRACKED], - "Present the input source, unstable (and less-pretty) variants; + "present the input source, unstable (and less-pretty) variants; valid types are any of the types for `--pretty`, as well as: `expanded`, `expanded,identified`, `expanded,hygiene` (with internal representations), @@ -1463,11 +1464,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, the same values as the target option of the same name"), allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], "only allow the listed language features to be enabled in code (space separated)"), - emit_artifact_notifications: bool = (false, parse_bool, [UNTRACKED], - "emit notifications after each artifact has been output (only in the JSON format)"), symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy, parse_symbol_mangling_version, [TRACKED], "which mangling version to use for symbol names"), + binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], + "include artifacts (sysroot, crate dependencies) used during compilation in dep-info"), } pub fn default_lib_output() -> CrateType { @@ -1630,7 +1631,7 @@ impl RustcOptGroup { // *unstable* options, i.e., options that are only enabled when the // user also passes the `-Z unstable-options` debugging flag. mod opt { - // The `fn opt_u` etc below are written so that we can use them + // The `fn flag*` etc below are written so that we can use them // in the future; do not warn about them not being used right now. #![allow(dead_code)] @@ -1707,7 +1708,7 @@ pub fn rustc_short_optgroups() -> Vec { "", "Add a directory to the library search path. The optional KIND can be one of dependency, crate, native, - framework or all (the default).", + framework, or all (the default).", "[KIND=]PATH", ), opt::multi_s( @@ -1715,8 +1716,7 @@ pub fn rustc_short_optgroups() -> Vec { "", "Link the generated crate(s) to the specified native library NAME. The optional KIND can be one of - static, dylib, or framework. If omitted, dylib is - assumed.", + static, framework, or dylib (the default).", "[KIND=]NAME", ), opt::multi_s( @@ -1821,11 +1821,11 @@ pub fn rustc_optgroups() -> Vec { "How errors and other messages are produced", "human|json|short", ), - opt::opt( + opt::multi_s( "", - "json-rendered", - "Choose `rendered` field of json diagnostics render scheme", - "plain|termcolor", + "json", + "Configure the JSON output of the compiler", + "CONFIG", ), opt::opt_s( "", @@ -1921,10 +1921,9 @@ pub fn get_cmd_lint_options(matches: &getopts::Matches, (lint_opts, describe_lints, lint_cap) } -pub fn build_session_options_and_crate_config( - matches: &getopts::Matches, -) -> (Options, FxHashSet<(String, Option)>) { - let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) { +/// Parse the `--color` flag +pub fn parse_color(matches: &getopts::Matches) -> ColorConfig { + match matches.opt_str("color").as_ref().map(|s| &s[..]) { Some("auto") => ColorConfig::Auto, Some("always") => ColorConfig::Always, Some("never") => ColorConfig::Never, @@ -1939,46 +1938,52 @@ pub fn build_session_options_and_crate_config( arg ), ), - }; + } +} - let edition = match matches.opt_str("edition") { - Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| +/// Parse the `--json` flag. +/// +/// The first value returned is how to render JSON diagnostics, and the second +/// is whether or not artifact notifications are enabled. +pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool) { + let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType = + HumanReadableErrorType::Default; + let mut json_color = ColorConfig::Never; + let mut json_artifact_notifications = false; + for option in matches.opt_strs("json") { + // For now conservatively forbid `--color` with `--json` since `--json` + // won't actually be emitting any colors and anything colorized is + // embedded in a diagnostic message anyway. + if matches.opt_str("color").is_some() { early_error( ErrorOutputType::default(), - &format!( - "argument for --edition must be one of: \ - {}. (instead was `{}`)", - EDITION_NAME_LIST, - arg - ), - ), - ), - None => DEFAULT_EDITION, - }; + "cannot specify the `--color` option with `--json`", + ); + } - if !edition.is_stable() && !nightly_options::is_nightly_build() { - early_error( - ErrorOutputType::default(), - &format!( - "Edition {} is unstable and only \ - available for nightly builds of rustc.", - edition, - ) - ) + for sub_option in option.split(',') { + match sub_option { + "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, + "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, + "artifacts" => json_artifact_notifications = true, + s => { + early_error( + ErrorOutputType::default(), + &format!("unknown `--json` option `{}`", s), + ) + } + } + } } + (json_rendered(json_color), json_artifact_notifications) +} - let json_rendered = matches.opt_str("json-rendered").and_then(|s| match s.as_str() { - "plain" => None, - "termcolor" => Some(HumanReadableErrorType::Default(ColorConfig::Always)), - _ => early_error( - ErrorOutputType::default(), - &format!( - "argument for --json-rendered must be `plain` or `termcolor` (instead was `{}`)", - s, - ), - ), - }).unwrap_or(HumanReadableErrorType::Default(ColorConfig::Never)); - +/// Parse the `--error-format` flag +pub fn parse_error_format( + matches: &getopts::Matches, + color: ColorConfig, + json_rendered: HumanReadableErrorType, +) -> ErrorOutputType { // We need the opts_present check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use opts_present not @@ -2007,6 +2012,60 @@ pub fn build_session_options_and_crate_config( ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)) }; + match error_format { + ErrorOutputType::Json { .. } => {} + + // Conservatively require that the `--json` argument is coupled with + // `--error-format=json`. This means that `--json` is specified we + // should actually be emitting JSON blobs. + _ if matches.opt_strs("json").len() > 0 => { + early_error( + ErrorOutputType::default(), + "using `--json` requires also using `--error-format=json`", + ); + } + + _ => {} + } + + return error_format; +} + +pub fn build_session_options_and_crate_config( + matches: &getopts::Matches, +) -> (Options, FxHashSet<(String, Option)>) { + let color = parse_color(matches); + + let edition = match matches.opt_str("edition") { + Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| + early_error( + ErrorOutputType::default(), + &format!( + "argument for --edition must be one of: \ + {}. (instead was `{}`)", + EDITION_NAME_LIST, + arg + ), + ), + ), + None => DEFAULT_EDITION, + }; + + if !edition.is_stable() && !nightly_options::is_nightly_build() { + early_error( + ErrorOutputType::default(), + &format!( + "Edition {} is unstable and only \ + available for nightly builds of rustc.", + edition, + ) + ) + } + + let (json_rendered, json_artifact_notifications) = parse_json(matches); + + let error_format = parse_error_format(matches, color, json_rendered); + let unparsed_crate_types = matches.opt_strs("crate-type"); let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); @@ -2017,9 +2076,6 @@ pub fn build_session_options_and_crate_config( let mut debugging_opts = build_debugging_options(matches, error_format); if !debugging_opts.unstable_options { - if matches.opt_str("json-rendered").is_some() { - early_error(error_format, "`--json-rendered=x` is unstable"); - } if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format { early_error( ErrorOutputType::Json { pretty: false, json_rendered }, @@ -2444,6 +2500,7 @@ pub fn build_session_options_and_crate_config( cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, edition, + json_artifact_notifications, }, cfg, ) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index c1736a0554..61dac67891 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fingerprint::Fingerprint; use crate::lint; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::middle::allocator::AllocatorKind; use crate::middle::dependency_format; use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath}; use crate::session::search_paths::{PathKind, SearchPath}; @@ -27,6 +26,7 @@ use errors::emitter::HumanReadableErrorType; use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter}; use syntax::ast::{self, NodeId}; use syntax::edition::Edition; +use syntax::ext::allocator::AllocatorKind; use syntax::feature_gate::{self, AttributeType}; use syntax::json::JsonEmitter; use syntax::source_map; @@ -215,66 +215,66 @@ impl Session { *self.crate_disambiguator.get() } - pub fn struct_span_warn<'a, S: Into>( - &'a self, + pub fn struct_span_warn>( + &self, sp: S, msg: &str, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn(sp, msg) } - pub fn struct_span_warn_with_code<'a, S: Into>( - &'a self, + pub fn struct_span_warn_with_code>( + &self, sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } - pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_warn(msg) } - pub fn struct_span_err<'a, S: Into>( - &'a self, + pub fn struct_span_err>( + &self, sp: S, msg: &str, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_err(sp, msg) } - pub fn struct_span_err_with_code<'a, S: Into>( - &'a self, + pub fn struct_span_err_with_code>( + &self, sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_err_with_code(sp, msg, code) } // FIXME: This method should be removed (every error should have an associated error code). - pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_err(msg) } - pub fn struct_err_with_code<'a>( - &'a self, + pub fn struct_err_with_code( + &self, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_err_with_code(msg, code) } - pub fn struct_span_fatal<'a, S: Into>( - &'a self, + pub fn struct_span_fatal>( + &self, sp: S, msg: &str, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_fatal(sp, msg) } - pub fn struct_span_fatal_with_code<'a, S: Into>( - &'a self, + pub fn struct_span_fatal_with_code>( + &self, sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } - pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_fatal(msg) } @@ -416,7 +416,7 @@ impl Session { pub fn next_node_id(&self) -> NodeId { self.reserve_node_ids(1) } - pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler { + pub fn diagnostic(&self) -> &errors::Handler { &self.parse_sess.span_diagnostic } @@ -504,7 +504,7 @@ impl Session { ); } - pub fn source_map<'a>(&'a self) -> &'a source_map::SourceMap { + pub fn source_map(&self) -> &source_map::SourceMap { self.parse_sess.source_map() } pub fn verbose(&self) -> bool { @@ -545,6 +545,9 @@ impl Session { pub fn print_llvm_passes(&self) -> bool { self.opts.debugging_opts.print_llvm_passes } + pub fn binary_dep_depinfo(&self) -> bool { + self.opts.debugging_opts.binary_dep_depinfo + } /// Gets the features enabled for the current compilation session. /// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents diff --git a/src/librustc/tests.rs b/src/librustc/tests.rs new file mode 100644 index 0000000000..cf3ea2ffa9 --- /dev/null +++ b/src/librustc/tests.rs @@ -0,0 +1,13 @@ +use super::*; + +// FIXME(#27438): right now the unit tests of librustc don't refer to any actual +// functions generated in librustc_data_structures (all +// references are through generic functions), but statics are +// referenced from time to time. Due to this bug we won't +// actually correctly link in the statics unless we also +// reference a function, so be sure to reference a dummy +// function. +#[test] +fn noop() { + rustc_data_structures::__noop_fix_for_27438(); +} diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index d8087af60a..b6f0addd77 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -48,8 +48,8 @@ pub fn add_placeholder_note(err: &mut errors::DiagnosticBuilder<'_>) { /// If there are types that satisfy both impls, invokes `on_overlap` /// with a suitably-freshened `ImplHeader` with those types /// substituted. Otherwise, invokes `no_overlap`. -pub fn overlapping_impls<'tcx, F1, F2, R>( - tcx: TyCtxt<'tcx>, +pub fn overlapping_impls( + tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId, intercrate_mode: IntercrateMode, @@ -247,10 +247,10 @@ pub enum OrphanCheckErr<'tcx> { /// /// 1. All type parameters in `Self` must be "covered" by some local type constructor. /// 2. Some local type must appear in `Self`. -pub fn orphan_check<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn orphan_check( + tcx: TyCtxt<'_>, impl_def_id: DefId, -) -> Result<(), OrphanCheckErr<'tcx>> { +) -> Result<(), OrphanCheckErr<'_>> { debug!("orphan_check({:?})", impl_def_id); // We only except this routine to be invoked on implementations diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f54575ff8f..83bd5c5604 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -36,7 +36,7 @@ use errors::{Applicability, DiagnosticBuilder}; use std::fmt; use syntax::ast; use syntax::symbol::sym; -use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat}; +use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnKind}; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_fulfillment_errors(&self, @@ -61,12 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. let mut span = error.obligation.cause.span; - if let Some(ExpnInfo { - format: ExpnFormat::CompilerDesugaring(_), - def_site: Some(def_span), - .. - }) = span.ctxt().outer_expn_info() { - span = def_span; + if let Some(ExpnInfo { kind: ExpnKind::Desugaring(_), def_site, .. }) + = span.ctxt().outer_expn_info() { + span = def_site; } error_map.entry(span).or_default().push( @@ -247,7 +244,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { /// returns the fuzzy category of a given type, or None /// if the type can be equated to any type. - fn type_category<'tcx>(t: Ty<'tcx>) -> Option { + fn type_category(t: Ty<'_>) -> Option { match t.sty { ty::Bool => Some(0), ty::Char => Some(1), @@ -373,9 +370,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { flags.push((sym::parent_trait, Some(t))); } - if let Some(k) = obligation.cause.span.compiler_desugaring_kind() { + if let Some(k) = obligation.cause.span.desugaring_kind() { flags.push((sym::from_desugaring, None)); - flags.push((sym::from_desugaring, Some(k.name().to_string()))); + flags.push((sym::from_desugaring, Some(format!("{:?}", k)))); } let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); @@ -420,7 +417,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), )); let tcx = self.tcx; - if let Some(len) = len.assert_usize(tcx) { + if let Some(len) = len.try_eval_usize(tcx, ty::ParamEnv::empty()) { flags.push(( sym::_Self, Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), @@ -1659,7 +1656,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::TrivialBound => { err.help("see issue #48214"); if tcx.sess.opts.unstable_features.is_nightly_build() { - err.help("add #![feature(trivial_bounds)] to the \ + err.help("add `#![feature(trivial_bounds)]` to the \ crate attributes to enable", ); } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index cfd5cfa897..37eff852ab 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -702,6 +702,6 @@ impl<'tcx> TyCtxt<'tcx> { } } -pub(super) fn is_object_safe_provider<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> bool { +pub(super) fn is_object_safe_provider(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { tcx.object_safety_violations(trait_def_id).is_empty() } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 8bd8f941fb..38263f26a5 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1492,7 +1492,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( }; } let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node); - let ty = if let ty::AssocKind::Existential = assoc_ty.item.kind { + let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind { let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); tcx.mk_opaque(assoc_ty.item.def_id, item_substs) } else { @@ -1509,8 +1509,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( /// /// Based on the "projection mode", this lookup may in fact only examine the /// topmost impl. See the comments for `Reveal` for more details. -fn assoc_ty_def<'cx, 'tcx>( - selcx: &SelectionContext<'cx, 'tcx>, +fn assoc_ty_def( + selcx: &SelectionContext<'_, '_>, impl_def_id: DefId, assoc_ty_def_id: DefId, ) -> specialization_graph::NodeItem { diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 55e622e46b..2ffcd0fd4d 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -34,7 +34,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { { debug!( "normalize::<{}>(value={:?}, param_env={:?})", - unsafe { ::std::intrinsics::type_name::() }, + ::std::any::type_name::(), value, self.param_env, ); diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs index 3218ff062c..d09288461d 100644 --- a/src/librustc/traits/query/normalize_erasing_regions.rs +++ b/src/librustc/traits/query/normalize_erasing_regions.rs @@ -22,7 +22,7 @@ impl<'tcx> TyCtxt<'tcx> { { debug!( "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", - unsafe { ::std::intrinsics::type_name::() }, + ::std::any::type_name::(), value, param_env, ); diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 798a25fe7b..d4ae366262 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -167,7 +167,7 @@ struct TraitObligationStack<'prev, 'tcx> { /// ok on the premise that if `A: AutoTrait` held, but we indeed /// encountered a problem (later on) with `A: AutoTrait. So we /// currently set a flag on the stack node for `B: AutoTrait` (as - /// well as the second instance of `A: AutoTrait`) to supress + /// well as the second instance of `A: AutoTrait`) to suppress /// caching. /// /// This is a simple, targeted fix. A more-performant fix requires @@ -1082,7 +1082,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if unbound_input_types && stack.iter().skip(1).any(|prev| { stack.obligation.param_env == prev.obligation.param_env - && self.match_fresh_trait_refs(&stack.fresh_trait_ref, &prev.fresh_trait_ref) + && self.match_fresh_trait_refs( + &stack.fresh_trait_ref, &prev.fresh_trait_ref, prev.obligation.param_env) }) { debug!( "evaluate_stack({:?}) --> unbound argument, recursive --> giving up", @@ -1105,7 +1106,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// /// - is a defaulted trait, /// - it also appears in the backtrace at some position `X`, - /// - all the predicates at positions `X..` between `X` an the top are + /// - all the predicates at positions `X..` between `X` and the top are /// also defaulted traits. pub fn coinductive_match(&mut self, cycle: I) -> bool where @@ -3798,8 +3799,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &self, previous: &ty::PolyTraitRef<'tcx>, current: &ty::PolyTraitRef<'tcx>, + param_env: ty::ParamEnv<'tcx>, ) -> bool { - let mut matcher = ty::_match::Match::new(self.tcx()); + let mut matcher = ty::_match::Match::new(self.tcx(), param_env); matcher.relate(previous, current).is_ok() } @@ -3899,7 +3901,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // each predicate must be preceded by the obligations required // to normalize it. // for example, if we have: - // impl> Foo for V where U::Item: Copy + // impl, V: Iterator> Foo for V // the impl will have the following predicates: // ::Item = U, // U: Iterator, U: Sized, diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 43bb4edd9b..f0389bb037 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -145,8 +145,8 @@ pub fn find_associated_item<'tcx>( /// Specialization is determined by the sets of types to which the impls apply; /// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies /// to. -pub(super) fn specializes<'tcx>( - tcx: TyCtxt<'tcx>, +pub(super) fn specializes( + tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId), ) -> bool { debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id); @@ -282,10 +282,10 @@ fn fulfill_implication<'a, 'tcx>( } // Query provider for `specialization_graph_of`. -pub(super) fn specialization_graph_provider<'tcx>( - tcx: TyCtxt<'tcx>, +pub(super) fn specialization_graph_provider( + tcx: TyCtxt<'_>, trait_id: DefId, -) -> &'tcx specialization_graph::Graph { +) -> &specialization_graph::Graph { let mut sg = specialization_graph::Graph::new(); let mut trait_impls = tcx.all_impls(trait_id); diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index f736c5ef9b..b43881defd 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -484,13 +484,13 @@ impl<'tcx> Ancestors<'tcx> { | (Const, Const) | (Method, Method) | (Type, Type) - | (Type, Existential) + | (Type, OpaqueTy) => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), | (Const, _) | (Method, _) | (Type, _) - | (Existential, _) + | (OpaqueTy, _) => false, }).map(move |item| NodeItem { node: node, item: item }) }) diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 129a400d28..05b698eb4c 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -980,8 +980,7 @@ EnumTypeFoldableImpl! { (chalk_engine::DelayedLiteral::Negative)(a), (chalk_engine::DelayedLiteral::Positive)(a, b), } where - C: chalk_engine::context::Context + Clone, - C::CanonicalConstrainedSubst: TypeFoldable<'tcx>, + C: chalk_engine::context::Context> + Clone, } EnumTypeFoldableImpl! { @@ -989,8 +988,7 @@ EnumTypeFoldableImpl! { (chalk_engine::Literal::Negative)(a), (chalk_engine::Literal::Positive)(a), } where - C: chalk_engine::context::Context + Clone, - C::GoalInEnvironment: Clone + TypeFoldable<'tcx>, + C: chalk_engine::context::Context> + Clone, } CloneTypeFoldableAndLiftImpls! { diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 2d295679be..07d6f63314 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -417,7 +417,7 @@ pub struct SupertraitDefIds<'tcx> { visited: FxHashSet, } -pub fn supertrait_def_ids<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> SupertraitDefIds<'tcx> { +pub fn supertrait_def_ids(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SupertraitDefIds<'_> { SupertraitDefIds { tcx, stack: vec![trait_def_id], diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs index 6e10dc03a2..f800a70e0b 100644 --- a/src/librustc/ty/_match.rs +++ b/src/librustc/ty/_match.rs @@ -21,17 +21,19 @@ use crate::mir::interpret::ConstValue; /// affects any type variables or unification state. pub struct Match<'tcx> { tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, } impl Match<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>) -> Match<'tcx> { - Match { tcx } + pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> { + Match { tcx, param_env } } } impl TypeRelation<'tcx> for Match<'tcx> { fn tag(&self) -> &'static str { "Match" } fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } fn a_is_expected(&self) -> bool { true } // irrelevant fn relate_with_variance>(&mut self, diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 224f7d5f28..e3c6eca02d 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -10,7 +10,7 @@ use crate::arena::ArenaAllocatable; use crate::hir::def_id::{DefId, CrateNum}; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use rustc_data_structures::fx::FxHashMap; -use crate::rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; +use rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; use std::hash::Hash; use std::intrinsics; use crate::ty::{self, Ty, TyCtxt}; @@ -27,6 +27,7 @@ pub trait EncodableWithShorthand: Clone + Eq + Hash { fn variant(&self) -> &Self::Variant; } +#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] impl<'tcx> EncodableWithShorthand for Ty<'tcx> { type Variant = ty::TyKind<'tcx>; fn variant(&self) -> &Self::Variant { @@ -159,6 +160,7 @@ where Ok(decoder.map_encoded_cnum_to_current(cnum)) } +#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] #[inline] pub fn decode_ty(decoder: &mut D) -> Result, D::Error> where @@ -331,7 +333,7 @@ macro_rules! implement_ty_decoder { use $crate::ty::codec::*; use $crate::ty::subst::SubstsRef; use $crate::hir::def_id::{CrateNum}; - use crate::rustc_serialize::{Decoder, SpecializedDecoder}; + use rustc_serialize::{Decoder, SpecializedDecoder}; use std::borrow::Cow; impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4710d611d9..ef74d9e5b2 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! Type context book-keeping. use crate::arena::Arena; @@ -23,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata; use crate::middle::lang_items; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::stability; -use crate::mir::{self, Body, interpret, ProjectionKind}; +use crate::mir::{Body, interpret, ProjectionKind}; use crate::mir::interpret::{ConstValue, Allocation, Scalar}; use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; @@ -48,7 +46,6 @@ use crate::util::common::ErrorReported; use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet}; use crate::util::nodemap::{FxHashMap, FxHashSet}; use errors::DiagnosticBuilder; -use rustc_data_structures::interner::HashInterner; use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, StableHasher, StableHasherResult, @@ -56,6 +53,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, use arena::SyncDroplessArena; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal}; +use rustc_data_structures::sharded::ShardedHashMap; use std::any::Any; use std::borrow::Borrow; use std::cmp::Ordering; @@ -67,7 +65,6 @@ use std::ops::{Deref, Bound}; use std::iter; use std::sync::mpsc; use std::sync::Arc; -use std::marker::PhantomData; use rustc_target::spec::abi; use rustc_macros::HashStable; use syntax::ast; @@ -81,19 +78,17 @@ use crate::hir; pub struct AllArenas { pub interner: SyncDroplessArena, - pub local_interner: SyncDroplessArena, } impl AllArenas { pub fn new() -> Self { AllArenas { interner: SyncDroplessArena::default(), - local_interner: SyncDroplessArena::default(), } } } -type InternedSet<'tcx, T> = Lock, ()>>; +type InternedSet<'tcx, T> = ShardedHashMap, ()>; pub struct CtxtInterners<'tcx> { /// The arena that types, regions, etc are allocated from @@ -135,58 +130,23 @@ impl<'tcx> CtxtInterners<'tcx> { } /// Intern a type + #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] #[inline(never)] - fn intern_ty( - local: &CtxtInterners<'tcx>, - global: &CtxtInterners<'tcx>, - st: TyKind<'tcx>, + fn intern_ty(&self, + st: TyKind<'tcx> ) -> Ty<'tcx> { - let flags = super::flags::FlagComputation::for_sty(&st); - - // 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 flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) { - local.type_.borrow_mut().intern(st, |st| { - let ty_struct = TyS { - sty: st, - flags: flags.flags, - outer_exclusive_binder: flags.outer_exclusive_binder, - }; - - // Make sure we don't end up with inference - // types/regions in the global interner - if ptr_eq(local, global) { - bug!("Attempted to intern `{:?}` which contains \ - inference types/regions in the global type context", - &ty_struct); - } - - // This is safe because all the types the ty_struct can point to - // already is in the local arena or the global arena - let ty_struct: TyS<'tcx> = unsafe { - mem::transmute(ty_struct) - }; + self.type_.intern(st, |st| { + let flags = super::flags::FlagComputation::for_sty(&st); - Interned(local.arena.alloc(ty_struct)) - }).0 - } else { - global.type_.borrow_mut().intern(st, |st| { - let ty_struct = TyS { - sty: st, - flags: flags.flags, - outer_exclusive_binder: flags.outer_exclusive_binder, - }; + let ty_struct = TyS { + sty: st, + flags: flags.flags, + outer_exclusive_binder: flags.outer_exclusive_binder, + }; - // This is safe because all the types the ty_struct can point to - // already is in the global arena - let ty_struct: TyS<'tcx> = unsafe { - mem::transmute(ty_struct) - }; - Interned(global.arena.alloc(ty_struct)) - }).0 - } + Interned(self.arena.alloc(ty_struct)) + }).0 } } @@ -321,14 +281,14 @@ impl<'a, V> LocalTableInContextMut<'a, V> { } } -/// All information necessary to validate and reveal an `impl Trait` or `existential Type` +/// All information necessary to validate and reveal an `impl Trait`. #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct ResolvedOpaqueTy<'tcx> { /// The revealed type as seen by this function. pub concrete_type: Ty<'tcx>, /// Generic parameters on the opaque type as passed by this function. - /// For `existential type Foo; fn foo() -> Foo { .. }` this is `[T, U]`, not - /// `[A, B]` + /// For `type Foo = impl Bar; fn foo() -> Foo { .. }` + /// this is `[T, U]`, not `[A, B]`. pub substs: SubstsRef<'tcx>, } @@ -432,9 +392,9 @@ pub struct TypeckTables<'tcx> { /// read-again by borrowck. pub free_region_map: FreeRegionMap<'tcx>, - /// All the existential types that are restricted to concrete types - /// by this function - pub concrete_existential_types: FxHashMap>, + /// All the opaque types that are restricted to concrete types + /// by this function. + pub concrete_opaque_types: FxHashMap>, /// Given the closure ID this map provides the list of UpvarIDs used by it. /// The upvarID contains the HIR node ID and it also contains the full path @@ -464,7 +424,7 @@ impl<'tcx> TypeckTables<'tcx> { used_trait_imports: Lrc::new(Default::default()), tainted_by_errors: false, free_region_map: Default::default(), - concrete_existential_types: Default::default(), + concrete_opaque_types: Default::default(), upvar_list: Default::default(), } } @@ -773,7 +733,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { ref used_trait_imports, tainted_by_errors, ref free_region_map, - ref concrete_existential_types, + ref concrete_opaque_types, ref upvar_list, } = *self; @@ -817,7 +777,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { used_trait_imports.hash_stable(hcx, hasher); tainted_by_errors.hash_stable(hcx, hasher); free_region_map.hash_stable(hcx, hasher); - concrete_existential_types.hash_stable(hcx, hasher); + concrete_opaque_types.hash_stable(hcx, hasher); upvar_list.hash_stable(hcx, hasher); }) } @@ -933,7 +893,7 @@ EnumLiftImpl! { impl<'tcx> CommonTypes<'tcx> { fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> { - let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty); + let mk = |sty| interners.intern_ty(sty); CommonTypes { unit: mk(Tuple(List::empty())), @@ -964,7 +924,7 @@ impl<'tcx> CommonTypes<'tcx> { impl<'tcx> CommonLifetimes<'tcx> { fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> { let mk = |r| { - interners.region.borrow_mut().intern(r, |r| { + interners.region.intern(r, |r| { Interned(interners.arena.alloc(r)) }).0 }; @@ -980,7 +940,7 @@ impl<'tcx> CommonLifetimes<'tcx> { impl<'tcx> CommonConsts<'tcx> { fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> { let mk_const = |c| { - interners.const_.borrow_mut().intern(c, |c| { + interners.const_.intern(c, |c| { Interned(interners.arena.alloc(c)) }).0 }; @@ -1015,8 +975,6 @@ pub struct FreeRegionInfo { #[derive(Copy, Clone)] pub struct TyCtxt<'tcx> { gcx: &'tcx GlobalCtxt<'tcx>, - interners: &'tcx CtxtInterners<'tcx>, - dummy: PhantomData<&'tcx ()>, } impl<'tcx> Deref for TyCtxt<'tcx> { @@ -1030,8 +988,7 @@ impl<'tcx> Deref for TyCtxt<'tcx> { pub struct GlobalCtxt<'tcx> { pub arena: WorkerLocal>, - global_interners: CtxtInterners<'tcx>, - local_interners: CtxtInterners<'tcx>, + interners: CtxtInterners<'tcx>, cstore: &'tcx CrateStoreDyn, @@ -1096,14 +1053,14 @@ pub struct GlobalCtxt<'tcx> { /// Data layout specification for the current target. pub data_layout: TargetDataLayout, - stability_interner: Lock>, + stability_interner: ShardedHashMap<&'tcx attr::Stability, ()>, /// Stores the value of constants (and deduplicates the actual memory) - allocation_interner: Lock>, + allocation_interner: ShardedHashMap<&'tcx Allocation, ()>, pub alloc_map: Lock>, - layout_interner: Lock>, + layout_interner: ShardedHashMap<&'tcx LayoutDetails, ()>, /// A general purpose channel to throw data out the back towards LLVM worker /// threads. @@ -1122,8 +1079,6 @@ impl<'tcx> TyCtxt<'tcx> { pub fn global_tcx(self) -> TyCtxt<'tcx> { TyCtxt { gcx: self.gcx, - interners: &self.gcx.global_interners, - dummy: PhantomData, } } @@ -1148,7 +1103,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn intern_const_alloc(self, alloc: Allocation) -> &'tcx Allocation { - self.allocation_interner.borrow_mut().intern(alloc, |alloc| { + self.allocation_interner.intern(alloc, |alloc| { self.arena.alloc(alloc) }) } @@ -1162,13 +1117,13 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability { - self.stability_interner.borrow_mut().intern(stab, |stab| { + self.stability_interner.intern(stab, |stab| { self.arena.alloc(stab) }) } pub fn intern_layout(self, layout: LayoutDetails) -> &'tcx LayoutDetails { - self.layout_interner.borrow_mut().intern(layout, |layout| { + self.layout_interner.intern(layout, |layout| { self.arena.alloc(layout) }) } @@ -1203,11 +1158,6 @@ impl<'tcx> TyCtxt<'tcx> { value.lift_to_tcx(self.global_tcx()) } - /// Returns `true` if self is the same as self.global_tcx(). - fn is_global(self) -> bool { - ptr_eq(self.interners, &self.global_interners) - } - /// Creates a type context and call the closure with a `TyCtxt` reference /// to the context. The closure enforces that the type context and any interned /// value (types, substs, etc.) can only be used while `ty::tls` has a valid @@ -1229,7 +1179,6 @@ impl<'tcx> TyCtxt<'tcx> { s.fatal(&err); }); let interners = CtxtInterners::new(&arenas.interner); - let local_interners = CtxtInterners::new(&arenas.local_interner); let common = Common { empty_predicates: ty::GenericPredicates { parent: None, @@ -1287,8 +1236,7 @@ impl<'tcx> TyCtxt<'tcx> { sess: s, cstore, arena: WorkerLocal::new(|_| Arena::default()), - global_interners: interners, - local_interners: local_interners, + interners, dep_graph, common, types: common_types, @@ -1304,15 +1252,15 @@ impl<'tcx> TyCtxt<'tcx> { maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports .into_iter() - .map(|id| hir.local_def_id(id)) + .map(|id| hir.local_def_id_from_node_id(id)) .collect(), maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates .into_iter() - .map(|(id, sp)| (hir.local_def_id(id), sp)) + .map(|(id, sp)| (hir.local_def_id_from_node_id(id), sp)) .collect(), glob_map: resolutions.glob_map.into_iter().map(|(id, names)| { - (hir.local_def_id(id), names) + (hir.local_def_id_from_node_id(id), names) }).collect(), extern_prelude: resolutions.extern_prelude, hir_map: hir, @@ -1349,40 +1297,6 @@ impl<'tcx> TyCtxt<'tcx> { self.get_lang_items(LOCAL_CRATE) } - /// Due to missing llvm support for lowering 128 bit math to software emulation - /// (on some targets), the lowering can be done in MIR. - /// - /// This function only exists until said support is implemented. - pub fn is_binop_lang_item(&self, def_id: DefId) -> Option<(mir::BinOp, bool)> { - let items = self.lang_items(); - let def_id = Some(def_id); - if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.u128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.i128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.u128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.i128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.u128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.i128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.u128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.i128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.u128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.i128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.u128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.i128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.u128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.i128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.u128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.i128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.u128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.i128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.u128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.i128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.u128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.i128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else if items.u128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else { None } - } - pub fn stability(self) -> &'tcx stability::Index<'tcx> { self.stability_index(LOCAL_CRATE) } @@ -1682,8 +1596,6 @@ impl<'tcx> GlobalCtxt<'tcx> { { let tcx = TyCtxt { gcx: self, - interners: &self.local_interners, - dummy: PhantomData, }; ty::tls::with_related_context(tcx.global_tcx(), |icx| { let new_icx = ty::tls::ImplicitCtxt { @@ -1729,11 +1641,7 @@ macro_rules! nop_lift { type Lifted = $lifted; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { if tcx.interners.arena.in_arena(*self as *const _) { - return Some(unsafe { mem::transmute(*self) }); - } - // Also try in the global tcx if we're not that. - if !tcx.is_global() { - self.lift_to_tcx(tcx.global_tcx()) + Some(unsafe { mem::transmute(*self) }) } else { None } @@ -1751,11 +1659,7 @@ macro_rules! nop_list_lift { return Some(List::empty()); } if tcx.interners.arena.in_arena(*self as *const _) { - return Some(unsafe { mem::transmute(*self) }); - } - // Also try in the global tcx if we're not that. - if !tcx.is_global() { - self.lift_to_tcx(tcx.global_tcx()) + Some(unsafe { mem::transmute(*self) }) } else { None } @@ -1785,7 +1689,6 @@ pub mod tls { use std::fmt; use std::mem; - use std::marker::PhantomData; use syntax_pos; use crate::ty::query; use errors::{Diagnostic, TRACK_DIAGNOSTICS}; @@ -1949,8 +1852,6 @@ pub mod tls { let tcx = TyCtxt { gcx, - interners: &gcx.global_interners, - dummy: PhantomData, }; let icx = ImplicitCtxt { tcx, @@ -1981,8 +1882,6 @@ pub mod tls { let gcx = &*(gcx as *const GlobalCtxt<'_>); let tcx = TyCtxt { gcx, - interners: &gcx.global_interners, - dummy: PhantomData, }; let icx = ImplicitCtxt { query: None, @@ -2041,26 +1940,6 @@ pub mod tls { }) } - /// Allows access to the current ImplicitCtxt whose tcx field has the same global - /// interner and local interner as the tcx argument passed in. This means the closure - /// is given an ImplicitCtxt with the same 'tcx and 'tcx lifetimes as the TyCtxt passed in. - /// This will panic if you pass it a TyCtxt which has a different global interner or - /// a different local interner from the current ImplicitCtxt's tcx field. - #[inline] - pub fn with_fully_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R - where - F: for<'b> FnOnce(&ImplicitCtxt<'b, 'tcx>) -> R, - { - with_context(|context| { - unsafe { - assert!(ptr_eq(context.tcx.gcx, tcx.gcx)); - assert!(ptr_eq(context.tcx.interners, tcx.interners)); - let context: &ImplicitCtxt<'_, '_> = mem::transmute(context); - f(context) - } - }) - } - /// Allows access to the TyCtxt in the current ImplicitCtxt. /// Panics if there is no ImplicitCtxt available #[inline] @@ -2110,7 +1989,9 @@ macro_rules! sty_debug_print { }; $(let mut $variant = total;)* - for &Interned(t) in tcx.interners.type_.borrow().keys() { + let shards = tcx.interners.type_.lock_shards(); + let types = shards.iter().flat_map(|shard| shard.keys()); + for &Interned(t) in types { let variant = match t.sty { ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Str | ty::Never => continue, @@ -2161,11 +2042,11 @@ impl<'tcx> TyCtxt<'tcx> { Generator, GeneratorWitness, Dynamic, Closure, Tuple, Bound, Param, Infer, UnnormalizedProjection, Projection, Opaque, Foreign); - println!("InternalSubsts interner: #{}", self.interners.substs.borrow().len()); - println!("Region interner: #{}", self.interners.region.borrow().len()); - println!("Stability interner: #{}", self.stability_interner.borrow().len()); - println!("Allocation interner: #{}", self.allocation_interner.borrow().len()); - println!("Layout interner: #{}", self.layout_interner.borrow().len()); + println!("InternalSubsts interner: #{}", self.interners.substs.len()); + println!("Region interner: #{}", self.interners.region.len()); + println!("Stability interner: #{}", self.stability_interner.len()); + println!("Allocation interner: #{}", self.allocation_interner.len()); + println!("Layout interner: #{}", self.layout_interner.len()); } } @@ -2195,6 +2076,7 @@ impl<'tcx> Hash for Interned<'tcx, TyS<'tcx>> { } } +#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] impl<'tcx> Borrow> for Interned<'tcx, TyS<'tcx>> { fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> { &self.0.sty @@ -2288,39 +2170,22 @@ impl<'tcx> Borrow<[Goal<'tcx>]> for Interned<'tcx, List>> { macro_rules! intern_method { ($lt_tcx:tt, $name:ident: $method:ident($alloc:ty, $alloc_method:expr, - $alloc_to_key:expr, - $keep_in_local_tcx:expr) -> $ty:ty) => { + $alloc_to_key:expr) -> $ty:ty) => { impl<$lt_tcx> TyCtxt<$lt_tcx> { pub fn $method(self, v: $alloc) -> &$lt_tcx $ty { let key = ($alloc_to_key)(&v); - // 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 ($keep_in_local_tcx)(&v) { - self.interners.$name.borrow_mut().intern_ref(key, || { - // Make sure we don't end up with inference - // types/regions in the global tcx. - if self.is_global() { - bug!("Attempted to intern `{:?}` which contains \ - inference types/regions in the global type context", - v); - } + self.interners.$name.intern_ref(key, || { + Interned($alloc_method(&self.interners.arena, v)) - Interned($alloc_method(&self.interners.arena, v)) - }).0 - } else { - self.global_interners.$name.borrow_mut().intern_ref(key, || { - Interned($alloc_method(&self.global_interners.arena, v)) - }).0 - } + }).0 } } } } macro_rules! direct_interners { - ($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => { + ($lt_tcx:tt, $($name:ident: $method:ident($ty:ty)),+) => { $(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> { fn eq(&self, other: &Self) -> bool { self.0 == other.0 @@ -2339,8 +2204,7 @@ macro_rules! direct_interners { $lt_tcx, $name: $method($ty, |a: &$lt_tcx SyncDroplessArena, v| -> &$lt_tcx $ty { a.alloc(v) }, - |x| x, - $keep_in_local_tcx) -> $ty);)+ + |x| x) -> $ty);)+ } } @@ -2349,9 +2213,9 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool { } direct_interners!('tcx, - region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind, - goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>, - const_: mk_const(|c: &Const<'_>| keep_local(&c)) -> Const<'tcx> + region: mk_region(RegionKind), + goal: mk_goal(GoalKind<'tcx>), + const_: mk_const(Const<'tcx>) ); macro_rules! slice_interners { @@ -2359,8 +2223,7 @@ macro_rules! slice_interners { $(intern_method!( 'tcx, $field: $method( &[$ty], |a, v| List::from_arena(a, v), - Deref::deref, - |xs: &[$ty]| xs.iter().any(keep_local)) -> List<$ty>);)+ + Deref::deref) -> List<$ty>);)+ ); } @@ -2384,8 +2247,7 @@ intern_method! { canonical_var_infos: _intern_canonical_var_infos( &[CanonicalVarInfo], |a, v| List::from_arena(a, v), - Deref::deref, - |_xs: &[CanonicalVarInfo]| -> bool { false } + Deref::deref ) -> List } @@ -2429,9 +2291,10 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_fn_ptr(converted_sig) } + #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] #[inline] pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> { - CtxtInterners::intern_ty(&self.interners, &self.global_interners, st) + self.interners.intern_ty(st) } pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> { @@ -2484,10 +2347,9 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Foreign(def_id)) } - pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem); - let adt_def = self.adt_def(def_id); - let substs = InternalSubsts::for_item(self, def_id, |param, substs| { + fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> { + let adt_def = self.adt_def(wrapper_def_id); + let substs = InternalSubsts::for_item(self, wrapper_def_id, |param, substs| { match param.kind { GenericParamDefKind::Lifetime | GenericParamDefKind::Const => { @@ -2495,7 +2357,7 @@ impl<'tcx> TyCtxt<'tcx> { } GenericParamDefKind::Type { has_default, .. } => { if param.index == 0 { - ty.into() + ty_param.into() } else { assert!(has_default); self.type_of(param.def_id).subst(self, substs).into() @@ -2506,6 +2368,18 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Adt(adt_def, substs)) } + #[inline] + pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> { + let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem); + self.mk_generic_adt(def_id, ty) + } + + #[inline] + pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> { + let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem); + self.mk_generic_adt(def_id, ty) + } + #[inline] pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { self.mk_ty(RawPtr(tm)) @@ -2789,8 +2663,8 @@ impl<'tcx> TyCtxt<'tcx> { unsafety: hir::Unsafety, abi: abi::Abi) -> , ty::FnSig<'tcx>>>::Output - where I: Iterator, - I::Item: InternIteratorElement, ty::FnSig<'tcx>> + where + I: Iterator, ty::FnSig<'tcx>>>, { inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig { inputs_and_output: self.intern_type_list(xs), diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index b8bdde4a78..4a72794b61 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -194,7 +194,7 @@ impl<'tcx> ty::TyS<'tcx> { ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(), ty::Array(_, n) => { let n = tcx.lift_to_global(&n).unwrap(); - match n.assert_usize(tcx) { + match n.try_eval_usize(tcx, ty::ParamEnv::empty()) { Some(n) => format!("array of {} elements", n).into(), None => "array".into(), } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 8d7e7e16e8..411b18e043 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -18,6 +18,7 @@ impl FlagComputation { } } + #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] pub fn for_sty(st: &ty::TyKind<'_>) -> FlagComputation { let mut result = FlagComputation::new(); result.add_sty(st); @@ -61,6 +62,7 @@ impl FlagComputation { } // otherwise, this binder captures nothing } + #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] fn add_sty(&mut self, st: &ty::TyKind<'_>) { match st { &ty::Bool | diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs index af8dedfc88..4453624fa4 100644 --- a/src/librustc/ty/inhabitedness/def_id_forest.rs +++ b/src/librustc/ty/inhabitedness/def_id_forest.rs @@ -33,7 +33,7 @@ impl<'tcx> DefIdForest { /// crate. #[inline] pub fn full(tcx: TyCtxt<'tcx>) -> DefIdForest { - let crate_id = tcx.hir().local_def_id_from_hir_id(CRATE_HIR_ID); + let crate_id = tcx.hir().local_def_id(CRATE_HIR_ID); DefIdForest::from_id(crate_id) } diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 0d96e5ea62..2b32916566 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -3,6 +3,7 @@ use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS}; use crate::ty::{DefId, SubstsRef}; use crate::ty::{AdtKind, Visibility}; use crate::ty::TyKind::*; +use crate::ty; pub use self::def_id_forest::DefIdForest; @@ -190,7 +191,7 @@ impl<'tcx> TyS<'tcx> { })) } - Array(ty, len) => match len.assert_usize(tcx) { + Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) { // If the array is definitely non-empty, it's uninhabited if // the type of its elements is uninhabited. Some(n) if n != 0 => ty.uninhabited_from(tcx), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 4af26e19b3..19c753bc30 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -246,6 +246,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let align = a.value.align(dl).max(b_align).max(dl.aggregate_align); let b_offset = a.value.size(dl).align_to(b_align.abi); let size = (b_offset + b.value.size(dl)).align_to(align.abi); + + // HACK(nox): We iter on `b` and then `a` because `max_by_key` + // returns the last maximum. + let largest_niche = Niche::from_scalar(dl, b_offset, b.clone()) + .into_iter() + .chain(Niche::from_scalar(dl, Size::ZERO, a.clone())) + .max_by_key(|niche| niche.available(dl)); + LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { @@ -253,6 +261,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { memory_index: vec![0, 1] }, abi: Abi::ScalarPair(a, b), + largest_niche, align, size } @@ -321,6 +330,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut offset = Size::ZERO; + let mut largest_niche = None; + let mut largest_niche_available = 0; if let StructKind::Prefixed(prefix_size, prefix_align) = kind { let prefix_align = if packed { @@ -355,6 +366,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i as usize] = offset; + if let Some(mut niche) = field.largest_niche.clone() { + let available = niche.available(dl); + if available > largest_niche_available { + largest_niche_available = available; + niche.offset += offset; + largest_niche = Some(niche); + } + } + offset = offset.checked_add(field.size, dl) .ok_or(LayoutError::SizeOverflow(ty))?; } @@ -466,6 +486,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { memory_index }, abi, + largest_niche, align, size }) @@ -525,6 +546,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Union(0), abi: Abi::Uninhabited, + largest_niche: None, align: dl.i8_align, size: Size::ZERO }) @@ -543,7 +565,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr))); } - let unsized_part = tcx.struct_tail(pointee); + let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); let metadata = match unsized_part.sty { ty::Foreign(..) => { return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr))); @@ -572,7 +594,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } } - let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?; + let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; let element = self.layout_of(element)?; let size = element.size.checked_mul(count, dl) .ok_or(LayoutError::SizeOverflow(ty))?; @@ -583,6 +605,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Abi::Aggregate { sized: true } }; + let largest_niche = if count != 0 { + element.largest_niche.clone() + } else { + None + }; + tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Array { @@ -590,6 +618,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { count }, abi, + largest_niche, align: element.align, size }) @@ -603,6 +632,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { count: 0 }, abi: Abi::Aggregate { sized: false }, + largest_niche: None, align: element.align, size: Size::ZERO }) @@ -615,6 +645,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { count: 0 }, abi: Abi::Aggregate { sized: false }, + largest_niche: None, align: dl.i8_align, size: Size::ZERO }) @@ -683,6 +714,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { element: scalar, count }, + largest_niche: element.largest_niche.clone(), size, align, }) @@ -768,6 +800,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { variants: Variants::Single { index }, fields: FieldPlacement::Union(variants[index].len()), abi, + largest_niche: None, align, size: size.align_to(align.abi) })); @@ -829,14 +862,38 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // `#[rustc_layout_scalar_valid_range(n)]` // attribute to widen the range of anything as that would probably // result in UB somewhere + // FIXME(eddyb) the asserts are probably not needed, + // as larger validity ranges would result in missed + // optimizations, *not* wrongly assuming the inner + // value is valid. e.g. unions enlarge validity ranges, + // because the values may be uninitialized. if let Bound::Included(start) = start { + // FIXME(eddyb) this might be incorrect - it doesn't + // account for wrap-around (end < start) ranges. assert!(*scalar.valid_range.start() <= start); scalar.valid_range = start..=*scalar.valid_range.end(); } if let Bound::Included(end) = end { + // FIXME(eddyb) this might be incorrect - it doesn't + // account for wrap-around (end < start) ranges. assert!(*scalar.valid_range.end() >= end); scalar.valid_range = *scalar.valid_range.start()..=end; } + + // Update `largest_niche` if we have introduced a larger niche. + let niche = Niche::from_scalar(dl, Size::ZERO, scalar.clone()); + if let Some(niche) = niche { + match &st.largest_niche { + Some(largest_niche) => { + // Replace the existing niche even if they're equal, + // because this one is at a lower offset. + if largest_niche.available(dl) <= niche.available(dl) { + st.largest_niche = Some(niche); + } + } + None => st.largest_niche = Some(niche), + } + } } _ => assert!( start == Bound::Unbounded && end == Bound::Unbounded, @@ -845,6 +902,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { st, ), } + return Ok(tcx.intern_layout(st)); } @@ -886,8 +944,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let count = ( niche_variants.end().as_u32() - niche_variants.start().as_u32() + 1 ) as u128; + // FIXME(#62691) use the largest niche across all fields, + // not just the first one. for (field_index, &field) in variants[i].iter().enumerate() { - let niche = match self.find_niche(field)? { + let niche = match &field.largest_niche { Some(niche) => niche, _ => continue, }; @@ -937,6 +997,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { abi = Abi::Uninhabited; } + + let largest_niche = + Niche::from_scalar(dl, offset, niche_scalar.clone()); + return Ok(tcx.intern_layout(LayoutDetails { variants: Variants::Multiple { discr: niche_scalar, @@ -953,6 +1017,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { memory_index: vec![0] }, abi, + largest_niche, size, align, })); @@ -1164,6 +1229,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { abi = Abi::Uninhabited; } + let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone()); + tcx.intern_layout(LayoutDetails { variants: Variants::Multiple { discr: tag, @@ -1175,6 +1242,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { offsets: vec![Size::ZERO], memory_index: vec![0] }, + largest_niche, abi, align, size @@ -1300,6 +1368,27 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } } + // Count the number of variants in use. If only one of them, then it is + // impossible to overlap any locals in our layout. In this case it's + // always better to make the remaining locals ineligible, so we can + // lay them out with the other locals in the prefix and eliminate + // unnecessary padding bytes. + { + let mut used_variants = BitSet::new_empty(info.variant_fields.len()); + for assignment in &assignments { + match assignment { + Assigned(idx) => { used_variants.insert(*idx); } + _ => {} + } + } + if used_variants.count() < 2 { + for assignment in assignments.iter_mut() { + *assignment = Ineligible(None); + } + ineligible_locals.insert_all(); + } + } + // Write down the order of our locals that will be promoted to the prefix. { let mut idx = 0u32; @@ -1332,16 +1421,28 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. let discr_index = substs.prefix_tys(def_id, tcx).count(); - let promoted_tys = - ineligible_locals.iter().map(|local| subst_field(info.field_tys[local])); - let prefix_tys = substs.prefix_tys(def_id, tcx) - .chain(iter::once(substs.discr_ty(tcx))) - .chain(promoted_tys); + // FIXME(eddyb) set the correct vaidity range for the discriminant. + let discr_layout = self.layout_of(substs.discr_ty(tcx))?; + let discr = match &discr_layout.abi { + Abi::Scalar(s) => s.clone(), + _ => bug!(), + }; + let promoted_layouts = ineligible_locals.iter() + .map(|local| subst_field(info.field_tys[local])) + .map(|ty| tcx.mk_maybe_uninit(ty)) + .map(|ty| self.layout_of(ty)); + let prefix_layouts = substs.prefix_tys(def_id, tcx) + .map(|ty| self.layout_of(ty)) + .chain(iter::once(Ok(discr_layout))) + .chain(promoted_layouts) + .collect::, _>>()?; let prefix = self.univariant_uninterned( ty, - &prefix_tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, + &prefix_layouts, &ReprOptions::default(), - StructKind::AlwaysSized)?; + StructKind::AlwaysSized, + )?; + let (prefix_size, prefix_align) = (prefix.size, prefix.align); // Split the prefix layout into the "outer" fields (upvars and @@ -1457,16 +1558,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Ok(variant) }).collect::, _>>()?; + size = size.align_to(align.abi); + let abi = if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi.is_uninhabited()) { Abi::Uninhabited } else { Abi::Aggregate { sized: true } }; - let discr = match &self.layout_of(substs.discr_ty(tcx))?.abi { - Abi::Scalar(s) => s.clone(), - _ => bug!(), - }; let layout = tcx.intern_layout(LayoutDetails { variants: Variants::Multiple { @@ -1477,6 +1576,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }, fields: outer_fields, abi, + largest_niche: prefix.largest_niche, size, align, }); @@ -1664,7 +1764,7 @@ impl<'tcx> SizeSkeleton<'tcx> { ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let non_zero = !ty.is_unsafe_ptr(); - let tail = tcx.struct_tail(pointee); + let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); match tail.sty { ty::Param(_) | ty::Projection(_) => { debug_assert!(tail.has_param_types() || tail.has_self_ty()); @@ -1927,9 +2027,9 @@ impl ty::query::TyCtxtAt<'tcx> { impl<'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> where - C: LayoutOf> + HasTyCtxt<'tcx>, - C::TyLayout: MaybeResult>, - C: HasParamEnv<'tcx>, + C: LayoutOf, TyLayout: MaybeResult>> + + HasTyCtxt<'tcx> + + HasParamEnv<'tcx>, { fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLayout<'tcx> { let details = match this.variants { @@ -1950,6 +2050,7 @@ where variants: Variants::Single { index: variant_index }, fields: FieldPlacement::Union(fields), abi: Abi::Uninhabited, + largest_niche: None, align: tcx.data_layout.i8_align, size: Size::ZERO }) @@ -2015,7 +2116,7 @@ where })); } - match tcx.struct_tail(pointee).sty { + match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).sty { ty::Slice(_) | ty::Str => tcx.types.usize, ty::Dynamic(_, _) => { @@ -2222,120 +2323,6 @@ where } } -struct Niche { - offset: Size, - scalar: Scalar, - available: u128, -} - -impl Niche { - fn reserve<'tcx>( - &self, - cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, - count: u128, - ) -> Option<(u128, Scalar)> { - if count > self.available { - return None; - } - let Scalar { value, valid_range: ref v } = self.scalar; - let bits = value.size(cx).bits(); - assert!(bits <= 128); - let max_value = !0u128 >> (128 - bits); - let start = v.end().wrapping_add(1) & max_value; - let end = v.end().wrapping_add(count) & max_value; - Some((start, Scalar { value, valid_range: *v.start()..=end })) - } -} - -impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { - /// Find the offset of a niche leaf field, starting from - /// the given type and recursing through aggregates. - // FIXME(eddyb) traverse already optimized enums. - fn find_niche(&self, layout: TyLayout<'tcx>) -> Result, LayoutError<'tcx>> { - let scalar_niche = |scalar: &Scalar, offset| { - let Scalar { value, valid_range: ref v } = *scalar; - - let bits = value.size(self).bits(); - assert!(bits <= 128); - let max_value = !0u128 >> (128 - bits); - - // Find out how many values are outside the valid range. - let available = if v.start() <= v.end() { - v.start() + (max_value - v.end()) - } else { - v.start() - v.end() - 1 - }; - - // Give up if there is no niche value available. - if available == 0 { - return None; - } - - Some(Niche { offset, scalar: scalar.clone(), available }) - }; - - // Locals variables which live across yields are stored - // in the generator type as fields. These may be uninitialized - // so we don't look for niches there. - if let ty::Generator(..) = layout.ty.sty { - return Ok(None); - } - - match layout.abi { - Abi::Scalar(ref scalar) => { - return Ok(scalar_niche(scalar, Size::ZERO)); - } - Abi::ScalarPair(ref a, ref b) => { - // HACK(nox): We iter on `b` and then `a` because `max_by_key` - // returns the last maximum. - let niche = iter::once( - (b, a.value.size(self).align_to(b.value.align(self).abi)) - ) - .chain(iter::once((a, Size::ZERO))) - .filter_map(|(scalar, offset)| scalar_niche(scalar, offset)) - .max_by_key(|niche| niche.available); - return Ok(niche); - } - Abi::Vector { ref element, .. } => { - return Ok(scalar_niche(element, Size::ZERO)); - } - _ => {} - } - - // Perhaps one of the fields is non-zero, let's recurse and find out. - if let FieldPlacement::Union(_) = layout.fields { - // Only Rust enums have safe-to-inspect fields - // (a discriminant), other unions are unsafe. - if let Variants::Single { .. } = layout.variants { - return Ok(None); - } - } - if let FieldPlacement::Array { count: original_64_bit_count, .. } = layout.fields { - // rust-lang/rust#57038: avoid ICE within FieldPlacement::count when count too big - if original_64_bit_count > usize::max_value() as u64 { - return Err(LayoutError::SizeOverflow(layout.ty)); - } - if layout.fields.count() > 0 { - return self.find_niche(layout.field(self, 0)?); - } else { - return Ok(None); - } - } - let mut niche = None; - let mut available = 0; - for i in 0..layout.fields.count() { - if let Some(mut c) = self.find_niche(layout.field(self, i)?)? { - if c.available > available { - available = c.available; - c.offset += layout.fields.offset(i); - niche = Some(c); - } - } - } - Ok(niche) - } -} - impl<'a> HashStable> for Variants { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, @@ -2456,10 +2443,16 @@ impl<'a> HashStable> for Scalar { } } +impl_stable_hash_for!(struct crate::ty::layout::Niche { + offset, + scalar +}); + impl_stable_hash_for!(struct crate::ty::layout::LayoutDetails { variants, fields, abi, + largest_niche, size, align }); @@ -2525,7 +2518,7 @@ where + HasTyCtxt<'tcx> + HasParamEnv<'tcx>, { - fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self; + fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self; fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self; fn new_internal( @@ -2545,7 +2538,7 @@ where + HasTyCtxt<'tcx> + HasParamEnv<'tcx>, { - fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self { + fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self { let sig = instance.fn_sig(cx.tcx()); let sig = cx .tcx() diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ad98807251..9d563e290d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1,7 +1,5 @@ // ignore-tidy-filelength -#![allow(usage_of_ty_tykind)] - pub use self::Variance::*; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; @@ -34,7 +32,7 @@ use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use arena::SyncDroplessArena; use crate::session::DataTypeKind; -use serialize::{self, Encodable, Encoder}; +use rustc_serialize::{self, Encodable, Encoder}; use std::cell::RefCell; use std::cmp::{self, Ordering}; use std::fmt; @@ -46,7 +44,7 @@ use std::{mem, ptr}; use std::ops::Range; use syntax::ast::{self, Name, Ident, NodeId}; use syntax::attr; -use syntax::ext::hygiene::Mark; +use syntax::ext::hygiene::ExpnId; use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString}; use syntax_pos::Span; @@ -187,7 +185,7 @@ pub struct AssocItem { pub enum AssocKind { Const, Method, - Existential, + OpaqueTy, Type } @@ -197,7 +195,7 @@ impl AssocItem { AssocKind::Const => DefKind::AssocConst, AssocKind::Method => DefKind::Method, AssocKind::Type => DefKind::AssocTy, - AssocKind::Existential => DefKind::AssocExistential, + AssocKind::OpaqueTy => DefKind::AssocOpaqueTy, } } @@ -205,7 +203,7 @@ impl AssocItem { /// for ! pub fn relevant_for_never(&self) -> bool { match self.kind { - AssocKind::Existential | + AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true, // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. @@ -223,7 +221,8 @@ impl AssocItem { tcx.fn_sig(self.def_id).skip_binder().to_string() } ty::AssocKind::Type => format!("type {};", self.ident), - ty::AssocKind::Existential => format!("existential type {};", self.ident), + // FIXME(type_alias_impl_trait): we should print bounds here too. + ty::AssocKind::OpaqueTy => format!("type {};", self.ident), ty::AssocKind::Const => { format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id)) } @@ -484,6 +483,7 @@ bitflags! { } } +#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] pub struct TyS<'tcx> { pub sty: TyKind<'tcx>, pub flags: TypeFlags, @@ -541,29 +541,29 @@ impl<'tcx> Hash for TyS<'tcx> { impl<'tcx> TyS<'tcx> { pub fn is_primitive_ty(&self) -> bool { match self.sty { - TyKind::Bool | - TyKind::Char | - TyKind::Int(_) | - TyKind::Uint(_) | - TyKind::Float(_) | - TyKind::Infer(InferTy::IntVar(_)) | - TyKind::Infer(InferTy::FloatVar(_)) | - TyKind::Infer(InferTy::FreshIntTy(_)) | - TyKind::Infer(InferTy::FreshFloatTy(_)) => true, - TyKind::Ref(_, x, _) => x.is_primitive_ty(), + Bool | + Char | + Int(_) | + Uint(_) | + Float(_) | + Infer(InferTy::IntVar(_)) | + Infer(InferTy::FloatVar(_)) | + Infer(InferTy::FreshIntTy(_)) | + Infer(InferTy::FreshFloatTy(_)) => true, + Ref(_, x, _) => x.is_primitive_ty(), _ => false, } } pub fn is_suggestable(&self) -> bool { match self.sty { - TyKind::Opaque(..) | - TyKind::FnDef(..) | - TyKind::FnPtr(..) | - TyKind::Dynamic(..) | - TyKind::Closure(..) | - TyKind::Infer(..) | - TyKind::Projection(..) => false, + Opaque(..) | + FnDef(..) | + FnPtr(..) | + Dynamic(..) | + Closure(..) | + Infer(..) | + Projection(..) => false, _ => true, } } @@ -589,8 +589,8 @@ impl<'a, 'tcx> HashStable> for ty::TyS<'tcx> { pub type Ty<'tcx> = &'tcx TyS<'tcx>; -impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {} -impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {} pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>; @@ -709,7 +709,7 @@ impl<'a, T> IntoIterator for &'a List { } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List> {} impl List { #[inline(always)] @@ -904,7 +904,7 @@ pub struct Generics { pub parent_count: usize, pub params: Vec, - /// Reverse map to the `index` field of each `GenericParamDef` + /// Reverse map to the `index` field of each `GenericParamDef`. #[stable_hasher(ignore)] pub param_def_id_to_index: FxHashMap, @@ -1010,8 +1010,8 @@ pub struct GenericPredicates<'tcx> { pub predicates: Vec<(Predicate<'tcx>, Span)>, } -impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {} -impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {} impl<'tcx> GenericPredicates<'tcx> { pub fn instantiate( @@ -1252,7 +1252,7 @@ impl<'tcx> TraitPredicate<'tcx> { impl<'tcx> PolyTraitPredicate<'tcx> { pub fn def_id(&self) -> DefId { - // Ok to skip binder since trait def-ID does not care about regions. + // Ok to skip binder since trait `DefId` does not care about regions. self.skip_binder().def_id() } } @@ -1319,7 +1319,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { /// Note that this is not the `DefId` of the `TraitRef` containing this /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. pub fn projection_def_id(&self) -> DefId { - // Ok to skip binder since trait def-ID does not care about regions. + // Ok to skip binder since trait `DefId` does not care about regions. self.skip_binder().projection_ty.item_def_id } } @@ -1646,9 +1646,9 @@ pub type PlaceholderConst = Placeholder; /// particular point. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] pub struct ParamEnv<'tcx> { - /// Obligations that the caller must satisfy. This is basically + /// `Obligation`s that the caller must satisfy. This is basically /// the set of bounds on the in-scope type parameters, translated - /// into Obligations, and elaborated and normalized. + /// into `Obligation`s, and elaborated and normalized. pub caller_bounds: &'tcx List>, /// Typically, this is `Reveal::UserFacing`, but during codegen we @@ -1842,7 +1842,8 @@ pub struct VariantDef { pub ctor_kind: CtorKind, /// Flags of the variant (e.g. is field list non-exhaustive)? flags: VariantFlags, - /// Recovered? + /// Variant is obtained as part of recovering from a syntactic error. + /// May be incomplete or bogus. pub recovered: bool, } @@ -1949,7 +1950,7 @@ pub struct FieldDef { pub struct AdtDef { /// `DefId` of the struct, enum or union item. pub did: DefId, - /// Variants of the ADT. If this is a struct or enum, then there will be a single variant. + /// Variants of the ADT. If this is a struct or union, then there will be a single variant. pub variants: IndexVec, /// Flags of the ADT (e.g. is this a struct? is this non-exhaustive?) flags: AdtFlags, @@ -1986,13 +1987,13 @@ impl Hash for AdtDef { } } -impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef { +impl<'tcx> rustc_serialize::UseSpecializedEncodable for &'tcx AdtDef { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { self.did.encode(s) } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx AdtDef {} impl<'a> HashStable> for AdtDef { @@ -2357,7 +2358,7 @@ impl<'tcx> AdtDef { #[inline] pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option> { - let param_env = ParamEnv::empty(); + let param_env = tcx.param_env(expr_did); let repr_type = self.repr.discr_type(); let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), expr_did); let instance = ty::Instance::new(expr_did, substs); @@ -2368,7 +2369,7 @@ impl<'tcx> AdtDef { match tcx.const_eval(param_env.and(cid)) { Ok(val) => { // FIXME: Find the right type and use it instead of `val.ty` here - if let Some(b) = val.assert_bits(tcx.global_tcx(), param_env.and(val.ty)) { + if let Some(b) = val.try_eval_bits(tcx.global_tcx(), param_env, val.ty) { trace!("discriminants: {} ({:?})", b, repr_type); Some(Discr { val: b, @@ -2565,6 +2566,8 @@ impl<'tcx> AdtDef { } impl<'tcx> FieldDef { + /// Returns the type of this field. The `subst` is typically obtained + /// via the second field of `TyKind::AdtDef`. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { tcx.type_of(self.did).subst(tcx, subst) } @@ -2796,7 +2799,7 @@ impl<'tcx> TyCtxt<'tcx> { _ => false, } } else { - match self.def_kind(def_id).expect("no def for def-id") { + match self.def_kind(def_id).expect("no def for `DefId`") { DefKind::AssocConst | DefKind::Method | DefKind::AssocTy => true, @@ -2816,14 +2819,14 @@ impl<'tcx> TyCtxt<'tcx> { parent_vis: &hir::Visibility, trait_item_ref: &hir::TraitItemRef) -> AssocItem { - let def_id = self.hir().local_def_id_from_hir_id(trait_item_ref.id.hir_id); + let def_id = self.hir().local_def_id(trait_item_ref.id.hir_id); let (kind, has_self) = match trait_item_ref.kind { hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Method { has_self } => { (ty::AssocKind::Method, has_self) } hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::Existential => bug!("only impls can have existentials"), + hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), }; AssocItem { @@ -2842,14 +2845,14 @@ impl<'tcx> TyCtxt<'tcx> { parent_def_id: DefId, impl_item_ref: &hir::ImplItemRef) -> AssocItem { - let def_id = self.hir().local_def_id_from_hir_id(impl_item_ref.id.hir_id); + let def_id = self.hir().local_def_id(impl_item_ref.id.hir_id); let (kind, has_self) = match impl_item_ref.kind { hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Method { has_self } => { (ty::AssocKind::Method, has_self) } hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::Existential => (ty::AssocKind::Existential, false), + hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), }; AssocItem { @@ -3072,10 +3075,10 @@ impl<'tcx> TyCtxt<'tcx> { self.expansion_that_defined(def_parent_def_id)) } - fn expansion_that_defined(self, scope: DefId) -> Mark { + fn expansion_that_defined(self, scope: DefId) -> ExpnId { match scope.krate { LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index), - _ => Mark::root(), + _ => ExpnId::root(), } } @@ -3114,7 +3117,7 @@ impl Iterator for AssocItemsIterator<'_> { fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> AssocItem { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); let parent_id = tcx.hir().get_parent_item(id); - let parent_def_id = tcx.hir().local_def_id_from_hir_id(parent_id); + let parent_def_id = tcx.hir().local_def_id(parent_id); let parent_item = tcx.hir().expect_item(parent_id); match parent_item.node { hir::ItemKind::Impl(.., ref impl_item_refs) => { @@ -3178,14 +3181,14 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { tcx.arena.alloc_from_iter( trait_item_refs.iter() .map(|trait_item_ref| trait_item_ref.id) - .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) + .map(|id| tcx.hir().local_def_id(id.hir_id)) ) } hir::ItemKind::Impl(.., ref impl_item_refs) => { tcx.arena.alloc_from_iter( impl_item_refs.iter() .map(|impl_item_ref| impl_item_ref.id) - .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) + .map(|id| tcx.hir().local_def_id(id.hir_id)) ) } hir::ItemKind::TraitAlias(..) => &[], @@ -3214,8 +3217,8 @@ fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { if let Node::Item(item) = tcx.hir().get(hir_id) { - if let hir::ItemKind::Existential(ref exist_ty) = item.node { - return exist_ty.impl_trait_fn; + if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.node { + return opaque_ty.impl_trait_fn; } } } diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs index c12402a57c..b68e6a7448 100644 --- a/src/librustc/ty/print/obsolete.rs +++ b/src/librustc/ty/print/obsolete.rs @@ -89,7 +89,8 @@ impl DefPathBasedNames<'tcx> { ty::Array(inner_type, len) => { output.push('['); self.push_type_name(inner_type, output, debug); - write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap(); + let len = len.eval_usize(self.tcx, ty::ParamEnv::reveal_all()); + write!(output, "; {}", len).unwrap(); output.push(']'); } ty::Slice(inner_type) => { diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index cb0ac0f07f..bf6741dde4 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -6,12 +6,13 @@ use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use crate::middle::region; use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; use crate::ty::subst::{Kind, Subst, UnpackedKind}; -use crate::ty::layout::Size; -use crate::mir::interpret::{ConstValue, sign_extend, Scalar}; +use crate::ty::layout::{Integer, IntegerExt, Size}; +use crate::mir::interpret::{ConstValue, sign_extend, Scalar, truncate}; use syntax::ast; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_target::spec::abi::Abi; +use syntax::attr::{SignedInt, UnsignedInt}; use syntax::symbol::{kw, InternedString}; use std::cell::Cell; @@ -228,8 +229,27 @@ pub trait PrettyPrinter<'tcx>: /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. fn try_print_visible_def_path( + self, + def_id: DefId, + ) -> Result<(Self, bool), Self::Error> { + let mut callers = Vec::new(); + self.try_print_visible_def_path_recur(def_id, &mut callers) + } + + /// Does the work of `try_print_visible_def_path`, building the + /// full definition path recursively before attempting to + /// post-process it into the valid and visible version that + /// accounts for re-exports. + /// + /// This method should only be callled by itself or + /// `try_print_visible_def_path`. + /// + /// `callers` is a chain of visible_parent's leading to `def_id`, + /// to support cycle detection during recursion. + fn try_print_visible_def_path_recur( mut self, def_id: DefId, + callers: &mut Vec, ) -> Result<(Self, bool), Self::Error> { define_scoped_cx!(self); @@ -302,14 +322,19 @@ pub trait PrettyPrinter<'tcx>: Some(parent) => parent, None => return Ok((self, false)), }; + if callers.contains(&visible_parent) { + return Ok((self, false)); + } + callers.push(visible_parent); // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid // knowing ahead of time whether the entire path will succeed or not. // To support printers that do not implement `PrettyPrinter`, a `Vec` or // linked list on the stack would need to be built, before any printing. - match self.try_print_visible_def_path(visible_parent)? { + match self.try_print_visible_def_path_recur(visible_parent, callers)? { (cx, false) => return Ok((cx, false)), (cx, true) => self = cx, } + callers.pop(); let actual_parent = self.tcx().parent(def_id); debug!( "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}", @@ -672,7 +697,12 @@ pub trait PrettyPrinter<'tcx>: }, ty::Array(ty, sz) => { p!(write("["), print(ty), write("; ")); - if let Some(n) = sz.assert_usize(self.tcx()) { + if let ConstValue::Unevaluated(..) = sz.val { + // do not try to evalute unevaluated constants. If we are const evaluating an + // array length anon const, rustc will (with debug assertions) print the + // constant's path. Which will end up here again. + p!(write("_")); + } else if let Some(n) = sz.try_eval_usize(self.tcx(), ty::ParamEnv::empty()) { p!(write("{}", n)); } else { p!(write("_")); @@ -870,15 +900,31 @@ pub trait PrettyPrinter<'tcx>: return Ok(self); }, ty::Uint(ui) => { - p!(write("{}{}", data, ui)); + let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(ui)).size(); + let max = truncate(u128::max_value(), bit_size); + + if data == max { + p!(write("std::{}::MAX", ui)) + } else { + p!(write("{}{}", data, ui)) + }; return Ok(self); }, ty::Int(i) =>{ + let bit_size = Integer::from_attr(&self.tcx(), SignedInt(i)) + .size().bits() as u128; + let min = 1u128 << (bit_size - 1); + let max = min - 1; + let ty = self.tcx().lift_to_global(&ct.ty).unwrap(); let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty)) .unwrap() .size; - p!(write("{}{}", sign_extend(data, size) as i128, i)); + match data { + d if d == min => p!(write("std::{}::MIN", i)), + d if d == max => p!(write("std::{}::MAX", i)), + _ => p!(write("{}{}", sign_extend(data, size) as i128, i)) + } return Ok(self); }, ty::Char => { @@ -891,7 +937,7 @@ pub trait PrettyPrinter<'tcx>: if let ty::Ref(_, ref_ty, _) = ct.ty.sty { let byte_str = match (ct.val, &ref_ty.sty) { (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => { - let n = n.unwrap_usize(self.tcx()); + let n = n.eval_usize(self.tcx(), ty::ParamEnv::empty()); Some(self.tcx() .alloc_map.lock() .unwrap_memory(ptr.alloc_id) diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index b921272856..91082c59ba 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -11,7 +11,7 @@ use crate::util::profiling::ProfileCategory; use std::borrow::Cow; use std::hash::Hash; use std::fmt::Debug; -use rustc_data_structures::sync::Lock; +use rustc_data_structures::sharded::Sharded; use rustc_data_structures::fingerprint::Fingerprint; use crate::ich::StableHashingContext; @@ -34,7 +34,7 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { fn query(key: Self::Key) -> Query<'tcx>; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Lock>; + fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Sharded>; fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode; @@ -69,7 +69,7 @@ impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M { if !tcx.sess.verbose() { format!("processing `{}`", tcx.def_path_str(def_id)).into() } else { - let name = unsafe { ::std::intrinsics::type_name::() }; + let name = ::std::any::type_name::(); format!("processing {:?} with query `{}`", def_id, name).into() } } diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index dcc467a61b..a25560ff76 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -1,35 +1,25 @@ -#![allow(warnings)] - -use std::mem; -use std::process; -use std::{fmt, ptr}; +use crate::ty::context::TyCtxt; +use crate::ty::query::plumbing::CycleError; +use crate::ty::query::Query; +use crate::ty::tls; -use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak}; -use rustc_data_structures::OnDrop; -use rustc_data_structures::jobserver; +use rustc_data_structures::sync::Lrc; use syntax_pos::Span; -use crate::ty::tls; -use crate::ty::query::Query; -use crate::ty::query::plumbing::CycleError; #[cfg(not(parallel_compiler))] -use crate::ty::query::{ - plumbing::TryGetJob, - config::QueryDescription, -}; -use crate::ty::context::TyCtxt; +use std::ptr; #[cfg(parallel_compiler)] use { - rustc_rayon_core as rayon_core, parking_lot::{Mutex, Condvar}, - std::sync::atomic::Ordering, - std::thread, - std::iter, - std::iter::FromIterator, + rustc_data_structures::{jobserver, OnDrop}, + rustc_data_structures::fx::FxHashSet, + rustc_data_structures::stable_hasher::{StableHasher, HashStable}, + rustc_data_structures::sync::Lock, + rustc_rayon_core as rayon_core, syntax_pos::DUMMY_SP, - rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable}, + std::{mem, process, thread}, + std::iter::FromIterator, }; /// Indicates the state of a query for a given key in a query map. @@ -81,7 +71,7 @@ impl<'tcx> QueryJob<'tcx> { span: Span, ) -> Result<(), CycleError<'tcx>> { tls::with_related_context(tcx, move |icx| { - let mut waiter = Lrc::new(QueryWaiter { + let waiter = Lrc::new(QueryWaiter { query: icx.query.clone(), span, cycle: Lock::new(None), @@ -138,6 +128,7 @@ impl<'tcx> QueryJob<'tcx> { self.latch.set(); } + #[cfg(parallel_compiler)] fn as_ptr(&self) -> *const QueryJob<'tcx> { self as *const _ } @@ -431,7 +422,7 @@ fn remove_cycle<'tcx>( let usage = usage.as_ref().map(|(span, query)| (*span, query.info.query.clone())); // Create the cycle error - let mut error = CycleError { + let error = CycleError { usage, cycle: stack.iter().map(|&(s, ref q)| QueryInfo { span: s, @@ -463,9 +454,6 @@ fn remove_cycle<'tcx>( /// Must only be called when a deadlock is about to happen. #[cfg(parallel_compiler)] pub unsafe fn handle_deadlock() { - use syntax; - use syntax_pos; - let registry = rayon_core::Registry::current(); let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| { @@ -473,11 +461,6 @@ pub unsafe fn handle_deadlock() { }); let gcx_ptr = &*gcx_ptr; - let syntax_globals = syntax::GLOBALS.with(|syntax_globals| { - syntax_globals as *const _ - }); - let syntax_globals = &*syntax_globals; - let syntax_pos_globals = syntax_pos::GLOBALS.with(|syntax_pos_globals| { syntax_pos_globals as *const _ }); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index e788628bc5..fb2ad2aa54 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -4,7 +4,7 @@ use crate::hir::def::{DefKind, Export}; use crate::hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs}; use crate::infer::canonical::{self, Canonical}; use crate::lint; -use crate::middle::borrowck::BorrowCheckResult; +use crate::middle::borrowck::{BorrowCheckResult, SignalledError}; use crate::middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, ForeignModule}; use crate::middle::cstore::{NativeLibraryKind, DepKind, CrateSource}; use crate::middle::privacy::AccessLevels; @@ -54,7 +54,7 @@ use rustc_target::spec::PanicStrategy; use std::borrow::Cow; use std::ops::Deref; use std::sync::Arc; -use std::intrinsics::type_name; +use std::any::type_name; use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::symbol::InternedString; use syntax::attr; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 8b2183c42e..00871a1cbf 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -5,7 +5,7 @@ use crate::hir::map::definitions::DefPathHash; use crate::ich::{CachingSourceMapView, Fingerprint}; use crate::mir::{self, interpret}; use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; -use crate::rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque, SpecializedDecoder, SpecializedEncoder, UseSpecializedDecodable, UseSpecializedEncodable}; use crate::session::{CrateDisambiguator, Session}; @@ -23,7 +23,7 @@ use std::mem; use syntax::ast::NodeId; use syntax::source_map::{SourceMap, StableSourceFileId}; use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile}; -use syntax_pos::hygiene::{Mark, SyntaxContext, ExpnInfo}; +use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnInfo}; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; @@ -201,28 +201,22 @@ impl<'sess> OnDiskCache<'sess> { let mut query_result_index = EncodedQueryResultIndex::new(); time(tcx.sess, "encode query results", || { - use crate::ty::query::queries::*; let enc = &mut encoder; let qri = &mut query_result_index; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; - // FIXME: Include const_eval_raw? + macro_rules! encode_queries { + ($($query:ident,)*) => { + $( + encode_query_results::, _>( + tcx, + enc, + qri + )?; + )* + } + } + + rustc_cached_queries!(encode_queries!); Ok(()) })?; @@ -306,9 +300,9 @@ impl<'sess> OnDiskCache<'sess> { } /// Loads a diagnostic emitted during the previous compilation session. - pub fn load_diagnostics<'tcx>( + pub fn load_diagnostics( &self, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, ) -> Vec { let diagnostics: Option = self.load_indexed( @@ -335,9 +329,9 @@ impl<'sess> OnDiskCache<'sess> { /// Returns the cached query result if there is something in the cache for /// the given `SerializedDepNodeIndex`; otherwise returns `None`. - pub fn try_load_query_result<'tcx, T>( + pub fn try_load_query_result( &self, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, ) -> Option where @@ -594,41 +588,41 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { let expn_info_tag = u8::decode(self)?; - let ctxt = match expn_info_tag { + // FIXME(mw): This method does not restore `InternalExpnData::parent` or + // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things + // don't seem to be used after HIR lowering, so everything should be fine + // as long as incremental compilation does not kick in before that. + let location = || Span::new(lo, hi, SyntaxContext::empty()); + let recover_from_expn_info = |this: &Self, expn_info, pos| { + let span = location().fresh_expansion(ExpnId::root(), expn_info); + this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt()); + span + }; + Ok(match expn_info_tag { TAG_NO_EXPANSION_INFO => { - SyntaxContext::empty() + location() } TAG_EXPANSION_INFO_INLINE => { - let pos = AbsoluteBytePos::new(self.opaque.position()); - let expn_info: ExpnInfo = Decodable::decode(self)?; - let ctxt = SyntaxContext::allocate_directly(expn_info); - self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt); - ctxt + let expn_info = Decodable::decode(self)?; + recover_from_expn_info( + self, expn_info, AbsoluteBytePos::new(self.opaque.position()) + ) } TAG_EXPANSION_INFO_SHORTHAND => { let pos = AbsoluteBytePos::decode(self)?; - let cached_ctxt = self.synthetic_expansion_infos - .borrow() - .get(&pos) - .cloned(); - + let cached_ctxt = self.synthetic_expansion_infos.borrow().get(&pos).cloned(); if let Some(ctxt) = cached_ctxt { - ctxt + Span::new(lo, hi, ctxt) } else { - let expn_info = self.with_position(pos.to_usize(), |this| { - ExpnInfo::decode(this) - })?; - let ctxt = SyntaxContext::allocate_directly(expn_info); - self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt); - ctxt + let expn_info = + self.with_position(pos.to_usize(), |this| ExpnInfo::decode(this))?; + recover_from_expn_info(self, expn_info, pos) } } _ => { unreachable!() } - }; - - Ok(Span::new(lo, hi, ctxt)) + }) } } @@ -731,7 +725,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> { encoder: &'a mut E, type_shorthands: FxHashMap, usize>, predicate_shorthands: FxHashMap, usize>, - expn_info_shorthands: FxHashMap, + expn_info_shorthands: FxHashMap, interpret_allocs: FxHashMap, interpret_allocs_inverse: Vec, source_map: CachingSourceMapView<'tcx>, @@ -825,15 +819,15 @@ where if span_data.ctxt == SyntaxContext::empty() { TAG_NO_EXPANSION_INFO.encode(self) } else { - let (mark, expn_info) = span_data.ctxt.outer_and_expn_info(); + let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info(); if let Some(expn_info) = expn_info { - if let Some(pos) = self.expn_info_shorthands.get(&mark).cloned() { + if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() { TAG_EXPANSION_INFO_SHORTHAND.encode(self)?; pos.encode(self) } else { TAG_EXPANSION_INFO_INLINE.encode(self)?; let pos = AbsoluteBytePos::new(self.position()); - self.expn_info_shorthands.insert(mark, pos); + self.expn_info_shorthands.insert(expn_id, pos); expn_info.encode(self) } } else { @@ -1061,17 +1055,16 @@ fn encode_query_results<'a, 'tcx, Q, E>( query_result_index: &mut EncodedQueryResultIndex, ) -> Result<(), E::Error> where - Q: super::config::QueryDescription<'tcx>, + Q: super::config::QueryDescription<'tcx, Value: Encodable>, E: 'a + TyEncoder, - Q::Value: Encodable, { let desc = &format!("encode_query_results for {}", - unsafe { ::std::intrinsics::type_name::() }); + ::std::any::type_name::()); time_ext(tcx.sess.time_extended(), Some(tcx.sess), desc, || { - let map = Q::query_cache(tcx).borrow(); - assert!(map.active.is_empty()); - for (key, entry) in map.results.iter() { + let shards = Q::query_cache(tcx).lock_shards(); + assert!(shards.iter().all(|shard| shard.active.is_empty())); + for (key, entry) in shards.iter().flat_map(|shard| shard.results.iter()) { if Q::cache_on_disk(tcx, key.clone(), Some(&entry.value)) { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 5a7d106700..4dce55f589 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -17,6 +17,7 @@ use errors::Diagnostic; use errors::FatalError; use rustc_data_structures::fx::{FxHashMap}; use rustc_data_structures::sync::{Lrc, Lock}; +use rustc_data_structures::sharded::Sharded; use rustc_data_structures::thin_vec::ThinVec; #[cfg(not(parallel_compiler))] use rustc_data_structures::cold_path; @@ -90,7 +91,7 @@ macro_rules! profq_query_msg { /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx>> { - cache: &'a Lock>, + cache: &'a Sharded>, key: Q::Key, job: Lrc>, } @@ -107,7 +108,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { pub(super) fn try_get(tcx: TyCtxt<'tcx>, span: Span, key: &Q::Key) -> TryGetJob<'a, 'tcx, Q> { let cache = Q::query_cache(tcx); loop { - let mut lock = cache.borrow_mut(); + let mut lock = cache.get_shard_by_value(key).lock(); if let Some(value) = lock.results.get(key) { profq_msg!(tcx, ProfileQueriesMsg::CacheHit); tcx.sess.profiler(|p| p.record_query_hit(Q::NAME)); @@ -191,7 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { let value = QueryValue::new(result.clone(), dep_node_index); { - let mut lock = cache.borrow_mut(); + let mut lock = cache.get_shard_by_value(&key).lock(); lock.active.remove(&key); lock.results.insert(key, value); } @@ -215,7 +216,8 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> { #[cold] fn drop(&mut self) { // Poison the query so jobs waiting on it panic - self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned); + let shard = self.cache.get_shard_by_value(&self.key); + shard.lock().active.insert(self.key.clone(), QueryResult::Poisoned); // Also signal the completion of the job, so waiters // will continue execution self.job.signal_complete(); @@ -708,7 +710,7 @@ macro_rules! define_queries_inner { use std::mem; #[cfg(parallel_compiler)] use ty::query::job::QueryResult; - use rustc_data_structures::sync::Lock; + use rustc_data_structures::sharded::Sharded; use crate::{ rustc_data_structures::stable_hasher::HashStable, rustc_data_structures::stable_hasher::StableHasherResult, @@ -740,18 +742,17 @@ macro_rules! define_queries_inner { pub fn collect_active_jobs(&self) -> Vec>> { let mut jobs = Vec::new(); - // We use try_lock here since we are only called from the + // We use try_lock_shards here since we are only called from the // deadlock handler, and this shouldn't be locked. $( - jobs.extend( - self.$name.try_lock().unwrap().active.values().filter_map(|v| - if let QueryResult::Started(ref job) = *v { - Some(job.clone()) - } else { - None - } - ) - ); + let shards = self.$name.try_lock_shards().unwrap(); + jobs.extend(shards.iter().flat_map(|shard| shard.active.values().filter_map(|v| + if let QueryResult::Started(ref job) = *v { + Some(job.clone()) + } else { + None + } + ))); )* jobs @@ -773,26 +774,27 @@ macro_rules! define_queries_inner { fn stats<'tcx, Q: QueryConfig<'tcx>>( name: &'static str, - map: &QueryCache<'tcx, Q> + map: &Sharded>, ) -> QueryStats { + let map = map.lock_shards(); QueryStats { name, #[cfg(debug_assertions)] - cache_hits: map.cache_hits, + cache_hits: map.iter().map(|shard| shard.cache_hits).sum(), #[cfg(not(debug_assertions))] cache_hits: 0, key_size: mem::size_of::(), - key_type: unsafe { type_name::() }, + key_type: type_name::(), value_size: mem::size_of::(), - value_type: unsafe { type_name::() }, - entry_count: map.results.len(), + value_type: type_name::(), + entry_count: map.iter().map(|shard| shard.results.len()).sum(), } } $( queries.push(stats::>( stringify!($name), - &*self.$name.lock() + &self.$name, )); )* @@ -967,7 +969,7 @@ macro_rules! define_queries_inner { } #[inline(always)] - fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Lock> { + fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Sharded> { &tcx.queries.$name } @@ -1099,7 +1101,7 @@ macro_rules! define_queries_struct { providers: IndexVec>, fallback_extern_providers: Box>, - $($(#[$attr])* $name: Lock>>,)* + $($(#[$attr])* $name: Sharded>>,)* } }; } @@ -1166,7 +1168,7 @@ macro_rules! define_provider_struct { /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just /// add it to the "We don't have enough information to reconstruct..." group in /// the match below. -pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool { +pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { use crate::dep_graph::RecoverKey; // We must avoid ever having to call force_from_dep_node() for a diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index a6bfc2dee6..945e3e158e 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -25,6 +25,8 @@ pub enum Cause { pub trait TypeRelation<'tcx>: Sized { fn tcx(&self) -> TyCtxt<'tcx>; + fn param_env(&self) -> ty::ParamEnv<'tcx>; + /// Returns a static string we can use for printouts. fn tag(&self) -> &'static str; @@ -466,7 +468,9 @@ pub fn super_relate_tys>( Err(err) => { // Check whether the lengths are both concrete/known values, // but are unequal, for better diagnostics. - match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) { + let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); + let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); + match (sz_a, sz_b) { (Some(sz_a_val), Some(sz_b_val)) => { Err(TypeError::FixedArraySize( expected_found(relation, &sz_a_val, &sz_b_val) @@ -594,13 +598,11 @@ pub fn super_relate_consts>( ty: a.ty, })) } - (ConstValue::ByRef { .. }, _) => { - bug!( - "non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}", - a, - b, - ); - } + + // FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment + // saying that we're not handling it intentionally. + + // FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`. // FIXME(const_generics): this is wrong, as it is a projection (ConstValue::Unevaluated(a_def_id, a_substs), diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 28b52dcea8..649a524472 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1367,8 +1367,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { - ConstValue::ByRef { offset, align, alloc } => - ConstValue::ByRef { offset, align, alloc }, + ConstValue::ByRef { alloc, offset } => + ConstValue::ByRef { alloc, offset }, ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)), ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)), ConstValue::Placeholder(p) => ConstValue::Placeholder(p), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 8bfbd8b854..129ea9b5b6 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1,5 +1,7 @@ //! This module contains `TyKind` and its major components. +#![cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))] + use crate::hir; use crate::hir::def_id::DefId; use crate::infer::canonical::Canonical; @@ -13,7 +15,7 @@ use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFolda use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv}; use crate::ty::layout::VariantIdx; use crate::util::captures::Captures; -use crate::mir::interpret::{Scalar, Pointer}; +use crate::mir::interpret::{Scalar, GlobalId}; use smallvec::SmallVec; use std::borrow::Cow; @@ -24,7 +26,6 @@ use rustc_target::spec::abi; use syntax::ast::{self, Ident}; use syntax::symbol::{kw, InternedString}; -use serialize; use self::InferTy::*; use self::TyKind::*; @@ -170,6 +171,7 @@ pub enum TyKind<'tcx> { Never, /// A tuple type. For example, `(i32, bool)`. + /// Use `TyS::tuple_fields` to iterate over the field types. Tuple(SubstsRef<'tcx>), /// The projection of an associated type. For example, @@ -184,7 +186,7 @@ pub enum TyKind<'tcx> { /// Opaque (`impl Trait`) type found in a return type. /// The `DefId` comes either from /// * the `impl Trait` ast::Ty node, - /// * or the `existential type` declaration + /// * or the `type Foo = impl Trait` declaration /// The substitutions are for the generics of the function in question. /// After typeck, the concrete type can be found in the `types` map. Opaque(DefId, SubstsRef<'tcx>), @@ -638,14 +640,14 @@ impl<'tcx> Binder> { } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List> {} impl<'tcx> List> { /// Returns the "principal def id" of this set of existential predicates. /// /// A Rust trait object type consists (in addition to a lifetime bound) /// of a set of trait bounds, which are separated into any number - /// of auto-trait bounds, and at most 1 non-auto-trait bound. The + /// of auto-trait bounds, and at most one non-auto-trait bound. The /// non-auto-trait bound is called the "principal" of the trait /// object. /// @@ -679,7 +681,8 @@ impl<'tcx> List> { #[inline] pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + 'a { + impl Iterator> + 'a + { self.iter().filter_map(|predicate| { match *predicate { ExistentialPredicate::Projection(p) => Some(p), @@ -689,7 +692,7 @@ impl<'tcx> List> { } #[inline] - pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { + pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { self.iter().filter_map(|predicate| { match *predicate { ExistentialPredicate::AutoTrait(d) => Some(d), @@ -710,17 +713,17 @@ impl<'tcx> Binder<&'tcx List>> { #[inline] pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + 'a { + impl Iterator> + 'a { self.skip_binder().projection_bounds().map(Binder::bind) } #[inline] - pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { + pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { self.skip_binder().auto_traits() } pub fn iter<'a>(&'a self) - -> impl DoubleEndedIterator>> + 'tcx { + -> impl DoubleEndedIterator>> + 'tcx { self.skip_binder().iter().cloned().map(Binder::bind) } } @@ -1322,7 +1325,7 @@ pub enum RegionKind { ReClosureBound(RegionVid), } -impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {} #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, PartialOrd, Ord)] pub struct EarlyBoundRegion { @@ -1721,11 +1724,11 @@ impl<'tcx> TyS<'tcx> { }) }) } - ty::Tuple(tys) => tys.iter().any(|ty| { - ty.expect_ty().conservative_is_privately_uninhabited(tcx) + ty::Tuple(..) => self.tuple_fields().any(|ty| { + ty.conservative_is_privately_uninhabited(tcx) }), ty::Array(ty, len) => { - match len.assert_usize(tcx) { + match len.try_eval_usize(tcx, ParamEnv::empty()) { // If the array is definitely non-empty, it's uninhabited if // the type of its elements is uninhabited. Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx), @@ -1846,7 +1849,7 @@ impl<'tcx> TyS<'tcx> { } #[inline] - pub fn is_mutable_pointer(&self) -> bool { + pub fn is_mutable_ptr(&self) -> bool { match self.sty { RawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) | Ref(_, _, hir::Mutability::MutMutable) => true, @@ -1862,6 +1865,12 @@ impl<'tcx> TyS<'tcx> { } } + /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer). + #[inline] + pub fn is_any_ptr(&self) -> bool { + self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr() + } + /// Returns `true` if this type is an `Arc`. #[inline] pub fn is_arc(&self) -> bool { @@ -2001,7 +2010,7 @@ impl<'tcx> TyS<'tcx> { } #[inline] - pub fn is_pointer_sized(&self) -> bool { + pub fn is_ptr_sized_integral(&self) -> bool { match self.sty { Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true, _ => false, @@ -2095,6 +2104,15 @@ impl<'tcx> TyS<'tcx> { } } + /// Iterates over tuple fields. + /// Panics when called on anything but a tuple. + pub fn tuple_fields(&self) -> impl DoubleEndedIterator> { + match self.sty { + Tuple(substs) => substs.iter().map(|field| field.expect_ty()), + _ => bug!("tuple_fields called on non-tuple"), + } + } + /// If the type contains variants, returns the valid range of variant indices. /// FIXME This requires the optimized MIR in the case of generators. #[inline] @@ -2284,29 +2302,38 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn to_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option { - if self.ty != ty.value { - return None; + pub fn try_eval_bits( + &self, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ty: Ty<'tcx>, + ) -> Option { + assert_eq!(self.ty, ty); + // if `ty` does not depend on generic parameters, use an empty param_env + let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size; + match self.val { + // FIXME(const_generics): this doesn't work right now, + // because it tries to relate an `Infer` to a `Param`. + ConstValue::Unevaluated(did, substs) => { + // if `substs` has no unresolved components, use and empty param_env + let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts(); + // try to resolve e.g. associated constants to their definition on an impl + let instance = ty::Instance::resolve(tcx, param_env, did, substs)?; + let gid = GlobalId { + instance, + promoted: None, + }; + let evaluated = tcx.const_eval(param_env.and(gid)).ok()?; + evaluated.val.try_to_bits(size) + }, + // otherwise just extract a `ConstValue`'s bits if possible + _ => self.val.try_to_bits(size), } - let size = tcx.layout_of(ty).ok()?.size; - self.val.try_to_bits(size) - } - - #[inline] - pub fn to_ptr(&self) -> Option { - self.val.try_to_ptr() - } - - #[inline] - pub fn assert_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option { - assert_eq!(self.ty, ty.value); - let size = tcx.layout_of(ty).ok()?.size; - self.val.try_to_bits(size) } #[inline] - pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option { - self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v { + pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option { + self.try_eval_bits(tcx, param_env, tcx.types.bool).and_then(|v| match v { 0 => Some(false), 1 => Some(true), _ => None, @@ -2314,24 +2341,23 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn assert_usize(&self, tcx: TyCtxt<'tcx>) -> Option { - self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64) + pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option { + self.try_eval_bits(tcx, param_env, tcx.types.usize).map(|v| v as u64) } #[inline] - pub fn unwrap_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 { - self.assert_bits(tcx, ty).unwrap_or_else(|| - bug!("expected bits of {}, got {:#?}", ty.value, self)) + pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 { + self.try_eval_bits(tcx, param_env, ty).unwrap_or_else(|| + bug!("expected bits of {:#?}, got {:#?}", ty, self)) } #[inline] - pub fn unwrap_usize(&self, tcx: TyCtxt<'tcx>) -> u64 { - self.assert_usize(tcx).unwrap_or_else(|| - bug!("expected constant usize, got {:#?}", self)) + pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 { + self.eval_bits(tcx, param_env, tcx.types.usize) as u64 } } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {} /// An inference variable for a const, for use in const generics. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 79dcd327f5..ea829da783 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -6,7 +6,7 @@ use crate::ty::{self, Lift, List, Ty, TyCtxt, InferConst, ParamConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::mir::interpret::ConstValue; -use serialize::{self, Encodable, Encoder, Decodable, Decoder}; +use rustc_serialize::{self, Encodable, Encoder, Decodable, Decoder}; use syntax_pos::{Span, DUMMY_SP}; use smallvec::SmallVec; use rustc_macros::HashStable; @@ -399,7 +399,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { } } -impl<'tcx> serialize::UseSpecializedDecodable for SubstsRef<'tcx> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for SubstsRef<'tcx> {} /////////////////////////////////////////////////////////////////////////// // Public trait `Subst` diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index a7ade875bf..2bb9c258f8 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -186,7 +186,7 @@ pub(super) fn trait_impls_of_provider( } for &hir_id in tcx.hir().trait_impls(trait_id) { - add_impl(tcx.hir().local_def_id_from_hir_id(hir_id)); + add_impl(tcx.hir().local_def_id(hir_id)); } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index a3b99f143d..96e16efd13 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -22,7 +22,6 @@ use rustc_macros::HashStable; use std::{cmp, fmt}; use syntax::ast; use syntax::attr::{self, SignedInt, UnsignedInt}; -use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug)] @@ -258,10 +257,46 @@ impl<'tcx> TyCtxt<'tcx> { false } - /// Returns the deeply last field of nested structures, or the same type, - /// if not a structure at all. Corresponds to the only possible unsized - /// field, and its type can be used to determine unsizing strategy. - pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> { + /// Attempts to returns the deeply last field of nested structures, but + /// does not apply any normalization in its search. Returns the same type + /// if input `ty` is not a structure at all. + pub fn struct_tail_without_normalization(self, ty: Ty<'tcx>) -> Ty<'tcx> + { + let tcx = self; + tcx.struct_tail_with_normalize(ty, |ty| ty) + } + + /// Returns the deeply last field of nested structures, or the same type if + /// not a structure at all. Corresponds to the only possible unsized field, + /// and its type can be used to determine unsizing strategy. + /// + /// Should only be called if `ty` has no inference variables and does not + /// need its lifetimes preserved (e.g. as part of codegen); otherwise + /// normalization attempt may cause compiler bugs. + pub fn struct_tail_erasing_lifetimes(self, + ty: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>) + -> Ty<'tcx> + { + let tcx = self; + tcx.struct_tail_with_normalize(ty, |ty| tcx.normalize_erasing_regions(param_env, ty)) + } + + /// Returns the deeply last field of nested structures, or the same type if + /// not a structure at all. Corresponds to the only possible unsized field, + /// and its type can be used to determine unsizing strategy. + /// + /// This is parameterized over the normalization strategy (i.e. how to + /// handle `::Assoc` and `impl Trait`); pass the identity + /// function to indicate no normalization should take place. + /// + /// See also `struct_tail_erasing_lifetimes`, which is suitable for use + /// during codegen. + pub fn struct_tail_with_normalize(self, + mut ty: Ty<'tcx>, + normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>) + -> Ty<'tcx> + { loop { match ty.sty { ty::Adt(def, substs) => { @@ -282,6 +317,15 @@ impl<'tcx> TyCtxt<'tcx> { } } + ty::Projection(_) | ty::Opaque(..) => { + let normalized = normalize(ty); + if ty == normalized { + return ty; + } else { + ty = normalized; + } + } + _ => { break; } @@ -295,10 +339,35 @@ impl<'tcx> TyCtxt<'tcx> { /// structure definitions. /// For `(Foo>, Foo)`, the result will be `(Foo, Trait)`, /// whereas struct_tail produces `T`, and `Trait`, respectively. - pub fn struct_lockstep_tails(self, - source: Ty<'tcx>, - target: Ty<'tcx>) - -> (Ty<'tcx>, Ty<'tcx>) { + /// + /// Should only be called if the types have no inference variables and do + /// not need their lifetimes preserved (e.g. as part of codegen); otherwise + /// normalization attempt may cause compiler bugs. + pub fn struct_lockstep_tails_erasing_lifetimes(self, + source: Ty<'tcx>, + target: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>) + -> (Ty<'tcx>, Ty<'tcx>) + { + let tcx = self; + tcx.struct_lockstep_tails_with_normalize( + source, target, |ty| tcx.normalize_erasing_regions(param_env, ty)) + } + + /// Same as applying struct_tail on `source` and `target`, but only + /// keeps going as long as the two types are instances of the same + /// structure definitions. + /// For `(Foo>, Foo)`, the result will be `(Foo, Trait)`, + /// whereas struct_tail produces `T`, and `Trait`, respectively. + /// + /// See also `struct_lockstep_tails_erasing_lifetimes`, which is suitable for use + /// during codegen. + pub fn struct_lockstep_tails_with_normalize(self, + source: Ty<'tcx>, + target: Ty<'tcx>, + normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>) + -> (Ty<'tcx>, Ty<'tcx>) + { let (mut a, mut b) = (source, target); loop { match (&a.sty, &b.sty) { @@ -320,6 +389,22 @@ impl<'tcx> TyCtxt<'tcx> { break; } }, + (ty::Projection(_), _) | (ty::Opaque(..), _) | + (_, ty::Projection(_)) | (_, ty::Opaque(..)) => { + // If either side is a projection, attempt to + // progress via normalization. (Should be safe to + // apply to both sides as normalization is + // idempotent.) + let a_norm = normalize(a); + let b_norm = normalize(b); + if a == a_norm && b == b_norm { + break; + } else { + a = a_norm; + b = b_norm; + } + } + _ => break, } } @@ -435,20 +520,6 @@ impl<'tcx> TyCtxt<'tcx> { Some(dtor) => dtor.did }; - // RFC 1238: if the destructor method is tagged with the - // attribute `unsafe_destructor_blind_to_params`, then the - // compiler is being instructed to *assume* that the - // destructor will not access borrowed data, - // even if such data is otherwise reachable. - // - // Such access can be in plain sight (e.g., dereferencing - // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden - // (e.g., calling `foo.0.clone()` of `Foo`). - if self.has_attr(dtor, sym::unsafe_destructor_blind_to_params) { - debug!("destructor_constraint({:?}) - blind", def.did); - return vec![]; - } - let impl_def_id = self.associated_item(dtor).container.id(); let impl_generics = self.generics_of(impl_def_id); @@ -774,15 +845,15 @@ impl<'tcx> ty::TyS<'tcx> { ty: Ty<'tcx>, ) -> Representability { match ty.sty { - Tuple(ref ts) => { + Tuple(..) => { // Find non representable - fold_repr(ts.iter().map(|ty| { + fold_repr(ty.tuple_fields().map(|ty| { is_type_structurally_recursive( tcx, sp, seen, representable_cache, - ty.expect_ty(), + ty, ) })) } @@ -1024,7 +1095,7 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx> // state transformation pass ty::Generator(..) => true, - ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).any(needs_drop), + ty::Tuple(..) => ty.tuple_fields().any(needs_drop), // unions don't have destructors because of the child types, // only if they manually implement `Drop` (handled above). diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index c74511cf0f..8c3110792a 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -119,8 +119,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::GeneratorWitness(ts) => { stack.extend(ts.skip_binder().iter().cloned().rev()); } - ty::Tuple(ts) => { - stack.extend(ts.iter().map(|k| k.expect_ty()).rev()); + ty::Tuple(..) => { + stack.extend(parent_ty.tuple_fields().rev()); } ty::FnDef(_, substs) => { stack.extend(substs.types().rev()); diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 1979b4317a..d32c32af29 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -362,7 +362,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // should've been checked by the instantiation // of whatever returned this exact `impl Trait`. - // for named existential types we still need to check them + // for named opaque `impl Trait` types we still need to check them if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() { let obligations = self.nominal_obligations(did, substs); self.out.extend(obligations); diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 2140018223..7118d05204 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -18,6 +18,9 @@ use crate::dep_graph::{DepNode}; use lazy_static; use crate::session::Session; +#[cfg(test)] +mod tests; + // The name of the associated type for `Fn` return types. pub const FN_OUTPUT_NAME: Symbol = sym::Output; @@ -170,7 +173,7 @@ pub fn time_ext(do_it: bool, sess: Option<&Session>, what: &str, f: F) -> } } - print_time_passes_entry_internal(what, dur); + print_time_passes_entry(true, what, dur); TIME_DEPTH.with(|slot| slot.set(old)); @@ -182,18 +185,6 @@ pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) { return } - let old = TIME_DEPTH.with(|slot| { - let r = slot.get(); - slot.set(r + 1); - r - }); - - print_time_passes_entry_internal(what, dur); - - TIME_DEPTH.with(|slot| slot.set(old)); -} - -fn print_time_passes_entry_internal(what: &str, dur: Duration) { let indentation = TIME_DEPTH.with(|slot| slot.get()); let mem_string = match get_resident() { @@ -361,16 +352,3 @@ impl MemoizationMap for RefCell> } } } - -#[test] -fn test_to_readable_str() { - assert_eq!("0", to_readable_str(0)); - assert_eq!("1", to_readable_str(1)); - assert_eq!("99", to_readable_str(99)); - assert_eq!("999", to_readable_str(999)); - assert_eq!("1_000", to_readable_str(1_000)); - assert_eq!("1_001", to_readable_str(1_001)); - assert_eq!("999_999", to_readable_str(999_999)); - assert_eq!("1_000_000", to_readable_str(1_000_000)); - assert_eq!("1_234_567", to_readable_str(1_234_567)); -} diff --git a/src/librustc/util/common/tests.rs b/src/librustc/util/common/tests.rs new file mode 100644 index 0000000000..9a9fb203c6 --- /dev/null +++ b/src/librustc/util/common/tests.rs @@ -0,0 +1,14 @@ +use super::*; + +#[test] +fn test_to_readable_str() { + assert_eq!("0", to_readable_str(0)); + assert_eq!("1", to_readable_str(1)); + assert_eq!("99", to_readable_str(99)); + assert_eq!("999", to_readable_str(999)); + assert_eq!("1_000", to_readable_str(1_000)); + assert_eq!("1_001", to_readable_str(1_001)); + assert_eq!("999_999", to_readable_str(999_999)); + assert_eq!("1_000_000", to_readable_str(1_000_000)); + assert_eq!("1_234_567", to_readable_str(1_234_567)); +} diff --git a/src/librustc_allocator/Cargo.toml b/src/librustc_allocator/Cargo.toml deleted file mode 100644 index cf6c598bfb..0000000000 --- a/src/librustc_allocator/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_allocator" -version = "0.0.0" -edition = "2018" - -[lib] -path = "lib.rs" -crate-type = ["dylib"] -test = false - -[dependencies] -rustc = { path = "../librustc" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_target = { path = "../librustc_target" } -syntax = { path = "../libsyntax" } -syntax_pos = { path = "../libsyntax_pos" } -log = "0.4" -smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs deleted file mode 100644 index d402b0ddf6..0000000000 --- a/src/librustc_allocator/expand.rs +++ /dev/null @@ -1,301 +0,0 @@ -use log::debug; -use rustc::middle::allocator::AllocatorKind; -use smallvec::{smallvec, SmallVec}; -use syntax::{ - ast::{ - self, Arg, Attribute, Crate, Expr, FnHeader, Generics, Ident, Item, ItemKind, - Mac, Mod, Mutability, Ty, TyKind, Unsafety, VisibilityKind, - }, - attr, - source_map::{ - respan, ExpnInfo, MacroAttribute, - }, - ext::{ - base::{ExtCtxt, Resolver}, - build::AstBuilder, - expand::ExpansionConfig, - hygiene::{Mark, SyntaxContext}, - }, - mut_visit::{self, MutVisitor}, - parse::ParseSess, - ptr::P, - symbol::{kw, sym} -}; -use syntax_pos::Span; - -use crate::{AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; - -pub fn modify( - sess: &ParseSess, - resolver: &mut dyn Resolver, - krate: &mut Crate, - crate_name: String, - handler: &rustc_errors::Handler, -) { - ExpandAllocatorDirectives { - handler, - sess, - resolver, - found: false, - crate_name: Some(crate_name), - in_submod: -1, // -1 to account for the "root" module - }.visit_crate(krate); -} - -struct ExpandAllocatorDirectives<'a> { - found: bool, - handler: &'a rustc_errors::Handler, - sess: &'a ParseSess, - resolver: &'a mut dyn Resolver, - crate_name: Option, - - // For now, we disallow `global_allocator` in submodules because hygiene is hard. Keep track of - // whether we are in a submodule or not. If `in_submod > 0` we are in a submodule. - in_submod: isize, -} - -impl MutVisitor for ExpandAllocatorDirectives<'_> { - fn flat_map_item(&mut self, item: P) -> SmallVec<[P; 1]> { - debug!("in submodule {}", self.in_submod); - - if !attr::contains_name(&item.attrs, sym::global_allocator) { - return mut_visit::noop_flat_map_item(item, self); - } - - match item.node { - ItemKind::Static(..) => {} - _ => { - self.handler - .span_err(item.span, "allocators must be statics"); - return smallvec![item]; - } - } - - if self.in_submod > 0 { - self.handler - .span_err(item.span, "`global_allocator` cannot be used in submodules"); - return smallvec![item]; - } - - if self.found { - self.handler - .span_err(item.span, "cannot define more than one #[global_allocator]"); - return smallvec![item]; - } - self.found = true; - - // Create a fresh Mark for the new macro expansion we are about to do - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(sym::global_allocator), item.span, self.sess.edition, &[sym::rustc_attrs] - )); - - // Tie the span to the macro expansion info we just created - let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - - // Create an expansion config - let ecfg = ExpansionConfig::default(self.crate_name.take().unwrap()); - - // Generate a bunch of new items using the AllocFnFactory - let mut f = AllocFnFactory { - span, - kind: AllocatorKind::Global, - global: item.ident, - core: Ident::with_empty_ctxt(sym::core), - cx: ExtCtxt::new(self.sess, ecfg, self.resolver), - }; - - // We will generate a new submodule. To `use` the static from that module, we need to get - // the `super::...` path. - let super_path = f.cx.path(f.span, vec![Ident::with_empty_ctxt(kw::Super), f.global]); - - // Generate the items in the submodule - let mut items = vec![ - // import `core` to use allocators - f.cx.item_extern_crate(f.span, f.core), - // `use` the `global_allocator` in `super` - f.cx.item_use_simple( - f.span, - respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), - super_path, - ), - ]; - - // Add the allocator methods to the submodule - items.extend( - ALLOCATOR_METHODS - .iter() - .map(|method| f.allocator_fn(method)), - ); - - // Generate the submodule itself - let name = f.kind.fn_name("allocator_abi"); - let allocator_abi = Ident::from_str(&name).gensym(); - let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); - let module = f.cx.monotonic_expander().flat_map_item(module).pop().unwrap(); - - // Return the item and new submodule - smallvec![item, module] - } - - // If we enter a submodule, take note. - fn visit_mod(&mut self, m: &mut Mod) { - debug!("enter submodule"); - self.in_submod += 1; - mut_visit::noop_visit_mod(m, self); - self.in_submod -= 1; - debug!("exit submodule"); - } - - // `visit_mac` is disabled by default. Enable it here. - fn visit_mac(&mut self, mac: &mut Mac) { - mut_visit::noop_visit_mac(mac, self) - } -} - -struct AllocFnFactory<'a> { - span: Span, - kind: AllocatorKind, - global: Ident, - core: Ident, - cx: ExtCtxt<'a>, -} - -impl AllocFnFactory<'_> { - fn allocator_fn(&self, method: &AllocatorMethod) -> P { - let mut abi_args = Vec::new(); - let mut i = 0; - let ref mut mk = || { - let name = Ident::from_str(&format!("arg{}", i)); - i += 1; - name - }; - let args = method - .inputs - .iter() - .map(|ty| self.arg_ty(ty, &mut abi_args, mk)) - .collect(); - let result = self.call_allocator(method.name, args); - let (output_ty, output_expr) = self.ret_ty(&method.output, result); - let kind = ItemKind::Fn( - self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)), - FnHeader { - unsafety: Unsafety::Unsafe, - ..FnHeader::default() - }, - Generics::default(), - self.cx.block_expr(output_expr), - ); - self.cx.item( - self.span, - Ident::from_str(&self.kind.fn_name(method.name)), - self.attrs(), - kind, - ) - } - - fn call_allocator(&self, method: &str, mut args: Vec>) -> P { - let method = self.cx.path( - self.span, - vec![ - self.core, - Ident::from_str("alloc"), - Ident::from_str("GlobalAlloc"), - Ident::from_str(method), - ], - ); - let method = self.cx.expr_path(method); - let allocator = self.cx.path_ident(self.span, self.global); - let allocator = self.cx.expr_path(allocator); - let allocator = self.cx.expr_addr_of(self.span, allocator); - args.insert(0, allocator); - - self.cx.expr_call(self.span, method, args) - } - - fn attrs(&self) -> Vec { - let special = sym::rustc_std_internal_symbol; - let special = self.cx.meta_word(self.span, special); - vec![self.cx.attribute(self.span, special)] - } - - fn arg_ty( - &self, - ty: &AllocatorTy, - args: &mut Vec, - ident: &mut dyn FnMut() -> Ident, - ) -> P { - match *ty { - AllocatorTy::Layout => { - let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize)); - let ty_usize = self.cx.ty_path(usize); - let size = ident(); - let align = ident(); - args.push(self.cx.arg(self.span, size, ty_usize.clone())); - args.push(self.cx.arg(self.span, align, ty_usize)); - - let layout_new = self.cx.path( - self.span, - vec![ - self.core, - Ident::from_str("alloc"), - Ident::from_str("Layout"), - Ident::from_str("from_size_align_unchecked"), - ], - ); - let layout_new = self.cx.expr_path(layout_new); - let size = self.cx.expr_ident(self.span, size); - let align = self.cx.expr_ident(self.span, align); - let layout = self.cx.expr_call(self.span, layout_new, vec![size, align]); - layout - } - - AllocatorTy::Ptr => { - let ident = ident(); - args.push(self.cx.arg(self.span, ident, self.ptr_u8())); - let arg = self.cx.expr_ident(self.span, ident); - self.cx.expr_cast(self.span, arg, self.ptr_u8()) - } - - AllocatorTy::Usize => { - let ident = ident(); - args.push(self.cx.arg(self.span, ident, self.usize())); - self.cx.expr_ident(self.span, ident) - } - - AllocatorTy::ResultPtr | AllocatorTy::Unit => { - panic!("can't convert AllocatorTy to an argument") - } - } - } - - fn ret_ty(&self, ty: &AllocatorTy, expr: P) -> (P, P) { - match *ty { - AllocatorTy::ResultPtr => { - // We're creating: - // - // #expr as *mut u8 - - let expr = self.cx.expr_cast(self.span, expr, self.ptr_u8()); - (self.ptr_u8(), expr) - } - - AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr), - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("can't convert AllocatorTy to an output") - } - } - } - - fn usize(&self) -> P { - let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize)); - self.cx.ty_path(usize) - } - - fn ptr_u8(&self) -> P { - let u8 = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::u8)); - let ty_u8 = self.cx.ty_path(u8); - self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable) - } -} diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs deleted file mode 100644 index e7a70895a3..0000000000 --- a/src/librustc_allocator/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![feature(nll)] -#![feature(rustc_private)] - -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - -pub mod expand; - -pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ - AllocatorMethod { - name: "alloc", - inputs: &[AllocatorTy::Layout], - output: AllocatorTy::ResultPtr, - }, - AllocatorMethod { - name: "dealloc", - inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout], - output: AllocatorTy::Unit, - }, - AllocatorMethod { - name: "realloc", - inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize], - output: AllocatorTy::ResultPtr, - }, - AllocatorMethod { - name: "alloc_zeroed", - inputs: &[AllocatorTy::Layout], - output: AllocatorTy::ResultPtr, - }, -]; - -pub struct AllocatorMethod { - pub name: &'static str, - pub inputs: &'static [AllocatorTy], - pub output: AllocatorTy, -} - -pub enum AllocatorTy { - Layout, - Ptr, - ResultPtr, - Unit, - Usize, -} diff --git a/src/librustc_apfloat/Cargo.toml b/src/librustc_apfloat/Cargo.toml index c7496a9547..af6c2feed0 100644 --- a/src/librustc_apfloat/Cargo.toml +++ b/src/librustc_apfloat/Cargo.toml @@ -10,5 +10,4 @@ path = "lib.rs" [dependencies] bitflags = "1.0" -rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 1b0bcdd0b5..9e6d5a6f62 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -32,12 +32,8 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![forbid(unsafe_code)] -#![deny(rust_2018_idioms)] #![feature(nll)] -// See librustc_cratesio_shim/Cargo.toml for a comment explaining this. -#[allow(unused_extern_crates)] -extern crate rustc_cratesio_shim; use std::cmp::Ordering; use std::fmt; diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 3bdb86d313..d6c8e54c18 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_borrowck/Cargo.toml b/src/librustc_ast_borrowck/Cargo.toml similarity index 83% rename from src/librustc_borrowck/Cargo.toml rename to src/librustc_ast_borrowck/Cargo.toml index f293739dec..024b2640e1 100644 --- a/src/librustc_borrowck/Cargo.toml +++ b/src/librustc_ast_borrowck/Cargo.toml @@ -1,14 +1,14 @@ [package] authors = ["The Rust Project Developers"] -name = "rustc_borrowck" +name = "rustc_ast_borrowck" version = "0.0.0" edition = "2018" [lib] -name = "rustc_borrowck" +name = "rustc_ast_borrowck" path = "lib.rs" -crate-type = ["dylib"] test = false +doctest = false [dependencies] log = "0.4" @@ -18,6 +18,5 @@ syntax_pos = { path = "../libsyntax_pos" } # refers to the borrowck-specific graphviz adapter traits. dot = { path = "../libgraphviz", package = "graphviz" } rustc = { path = "../librustc" } -rustc_mir = { path = "../librustc_mir" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_ast_borrowck/borrowck/README.md similarity index 99% rename from src/librustc_borrowck/borrowck/README.md rename to src/librustc_ast_borrowck/borrowck/README.md index 6c47e8784e..3f2175921d 100644 --- a/src/librustc_borrowck/borrowck/README.md +++ b/src/librustc_ast_borrowck/borrowck/README.md @@ -747,7 +747,7 @@ However, it is not always unsafe to freeze the base pointer. In particular, if the referent is frozen, there is no harm in it: ```rust -// src/test/run-pass/borrowck-borrow-of-mut-base-ptr-safe.rs +// src/test/ui/borrowck-borrow-of-mut-base-ptr-safe.rs fn foo<'a>(mut t0: &'a mut i32, mut t1: &'a mut i32) { let p: &i32 = &*t0; // Freezes `*t0` @@ -763,7 +763,7 @@ already frozen. In particular, we cannot assign to `*t0` through the new alias `t2`, as demonstrated in this test case: ```rust -// src/test/run-pass/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs +// src/test/ui/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs fn foo(t0: & &mut i32) { let t1 = t0; let p: &i32 = &**t0; diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_ast_borrowck/borrowck/check_loans.rs similarity index 60% rename from src/librustc_borrowck/borrowck/check_loans.rs rename to src/librustc_ast_borrowck/borrowck/check_loans.rs index 714b7c2720..3d824ee6ce 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_ast_borrowck/borrowck/check_loans.rs @@ -7,8 +7,6 @@ // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -use UseError::*; - use crate::borrowck::*; use crate::borrowck::InteriorKind::{InteriorElement, InteriorField}; use rustc::middle::expr_use_visitor as euv; @@ -20,7 +18,6 @@ use rustc::ty::{self, TyCtxt, RegionKind}; use syntax_pos::Span; use rustc::hir; use rustc::hir::Node; -use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; use log::debug; use std::rc::Rc; @@ -89,13 +86,12 @@ struct CheckLoanCtxt<'a, 'tcx> { impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn consume(&mut self, consume_id: hir::HirId, - consume_span: Span, + _: Span, cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { - debug!("consume(consume_id={}, cmt={:?}, mode={:?})", - consume_id, cmt, mode); + debug!("consume(consume_id={}, cmt={:?})", consume_id, cmt); - self.consume_common(consume_id.local_id, consume_span, cmt, mode); + self.consume_common(consume_id.local_id, cmt, mode); } fn matched_pat(&mut self, @@ -107,12 +103,9 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { consume_pat: &hir::Pat, cmt: &mc::cmt_<'tcx>, mode: euv::ConsumeMode) { - debug!("consume_pat(consume_pat={:?}, cmt={:?}, mode={:?})", - consume_pat, - cmt, - mode); + debug!("consume_pat(consume_pat={:?}, cmt={:?})", consume_pat, cmt); - self.consume_common(consume_pat.hir_id.local_id, consume_pat.span, cmt, mode); + self.consume_common(consume_pat.hir_id.local_id, cmt, mode); } fn borrow(&mut self, @@ -129,11 +122,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { bk, loan_cause); if let Some(lp) = opt_loan_path(cmt) { - let moved_value_use_kind = match loan_cause { - euv::ClosureCapture(_) => MovedInCapture, - _ => MovedInUse, - }; - self.check_if_path_is_moved(borrow_id.local_id, borrow_span, moved_value_use_kind, &lp); + self.check_if_path_is_moved(borrow_id.local_id, &lp); } self.check_for_conflicting_loans(borrow_id.local_id); @@ -143,7 +132,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { fn mutate(&mut self, assignment_id: hir::HirId, - assignment_span: Span, + _: Span, assignee_cmt: &mc::cmt_<'tcx>, mode: euv::MutateMode) { @@ -157,23 +146,18 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { // have to be *FULLY* initialized, but we still // must be careful lest it contains derefs of // pointers. - self.check_if_assigned_path_is_moved(assignee_cmt.hir_id.local_id, - assignment_span, - MovedInUse, - &lp); + self.check_if_assigned_path_is_moved(assignee_cmt.hir_id.local_id, &lp); } MutateMode::WriteAndRead => { // In a case like `path += 1`, then path must be // fully initialized, since we will read it before // we write it. self.check_if_path_is_moved(assignee_cmt.hir_id.local_id, - assignment_span, - MovedInUse, &lp); } } } - self.check_assignment(assignment_id.local_id, assignment_span, assignee_cmt); + self.check_assignment(assignment_id.local_id, assignee_cmt); } fn decl_without_init(&mut self, _id: hir::HirId, _span: Span) { } @@ -218,12 +202,6 @@ pub fn check_loans<'a, 'tcx>( .consume_body(body); } -#[derive(PartialEq)] -enum UseError<'tcx> { - UseOk, - UseWhileBorrowed(/*loan*/Rc>, /*loan*/Span) -} - fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind, borrow_kind2: ty::BorrowKind) -> bool { @@ -354,7 +332,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, borrow_span: Span) { - pub fn borrow_of_local_data<'tcx>(cmt: &mc::cmt_<'tcx>) -> bool { + pub fn borrow_of_local_data(cmt: &mc::cmt_<'_>) -> bool { match cmt.cat { // Borrows of static items is allowed Categorization::StaticItem => false, @@ -433,15 +411,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { return; } - if let Some(yield_span) = self.bccx - .region_scope_tree - .yield_in_scope_for_expr(scope, - cmt.hir_id, - self.bccx.body) + if let Some(_) = self.bccx.region_scope_tree + .yield_in_scope_for_expr(scope, cmt.hir_id, self.bccx.body) { - self.bccx.cannot_borrow_across_generator_yield(borrow_span, - yield_span, - Origin::Ast).emit(); self.bccx.signal_error(); } } @@ -478,10 +450,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } } - pub fn report_error_if_loans_conflict(&self, - old_loan: &Loan<'tcx>, - new_loan: &Loan<'tcx>) - -> bool { + pub fn report_error_if_loans_conflict( + &self, + old_loan: &Loan<'tcx>, + new_loan: &Loan<'tcx>, + ) -> bool { //! Checks whether `old_loan` and `new_loan` can safely be issued //! simultaneously. @@ -493,266 +466,87 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { assert!(self.bccx.region_scope_tree.scopes_intersect(old_loan.kill_scope, new_loan.kill_scope)); - let err_old_new = self.report_error_if_loan_conflicts_with_restriction( - old_loan, new_loan, old_loan, new_loan).err(); - let err_new_old = self.report_error_if_loan_conflicts_with_restriction( - new_loan, old_loan, old_loan, new_loan).err(); - - match (err_old_new, err_new_old) { - (Some(mut err), None) | (None, Some(mut err)) => { - err.emit(); - self.bccx.signal_error(); - } - (Some(mut err_old), Some(mut err_new)) => { - err_old.emit(); - self.bccx.signal_error(); - err_new.cancel(); - } - (None, None) => return true, - } - - false + self.report_error_if_loan_conflicts_with_restriction( + old_loan, new_loan) + && self.report_error_if_loan_conflicts_with_restriction( + new_loan, old_loan) } - pub fn report_error_if_loan_conflicts_with_restriction(&self, - loan1: &Loan<'tcx>, - loan2: &Loan<'tcx>, - old_loan: &Loan<'tcx>, - new_loan: &Loan<'tcx>) - -> Result<(), DiagnosticBuilder<'a>> { + pub fn report_error_if_loan_conflicts_with_restriction( + &self, + loan1: &Loan<'tcx>, + loan2: &Loan<'tcx>, + ) -> bool { //! Checks whether the restrictions introduced by `loan1` would - //! prohibit `loan2`. Returns false if an error is reported. - + //! prohibit `loan2`. debug!("report_error_if_loan_conflicts_with_restriction(\ loan1={:?}, loan2={:?})", loan1, loan2); if compatible_borrow_kinds(loan1.kind, loan2.kind) { - return Ok(()); + return true; } let loan2_base_path = owned_ptr_base_path_rc(&loan2.loan_path); for restr_path in &loan1.restricted_paths { if *restr_path != loan2_base_path { continue; } - // If new_loan is something like `x.a`, and old_loan is something like `x.b`, we would - // normally generate a rather confusing message (in this case, for multiple mutable - // borrows): - // - // error: cannot borrow `x.b` as mutable more than once at a time - // note: previous borrow of `x.a` occurs here; the mutable borrow prevents - // subsequent moves, borrows, or modification of `x.a` until the borrow ends - // - // What we want to do instead is get the 'common ancestor' of the two borrow paths and - // use that for most of the message instead, giving is something like this: - // - // error: cannot borrow `x` as mutable more than once at a time - // note: previous borrow of `x` occurs here (through borrowing `x.a`); the mutable - // borrow prevents subsequent moves, borrows, or modification of `x` until the - // borrow ends - - let common = new_loan.loan_path.common(&old_loan.loan_path); - let (nl, ol, new_loan_msg, old_loan_msg) = { - if new_loan.loan_path.has_fork(&old_loan.loan_path) && common.is_some() { - let nl = self.bccx.loan_path_to_string(&common.unwrap()); - let ol = nl.clone(); - let new_loan_msg = self.bccx.loan_path_to_string(&new_loan.loan_path); - let old_loan_msg = self.bccx.loan_path_to_string(&old_loan.loan_path); - (nl, ol, new_loan_msg, old_loan_msg) - } else { - (self.bccx.loan_path_to_string(&new_loan.loan_path), - self.bccx.loan_path_to_string(&old_loan.loan_path), - String::new(), - String::new()) - } - }; - - let ol_pronoun = if new_loan.loan_path == old_loan.loan_path { - "it".to_string() - } else { - format!("`{}`", ol) - }; - - // We want to assemble all the relevant locations for the error. - // - // 1. Where did the new loan occur. - // - if due to closure creation, where was the variable used in closure? - // 2. Where did old loan occur. - // 3. Where does old loan expire. - - let previous_end_span = - Some(self.tcx().sess.source_map().end_point( - old_loan.kill_scope.span(self.tcx(), &self.bccx.region_scope_tree))); - - let mut err = match (new_loan.kind, old_loan.kind) { - (ty::MutBorrow, ty::MutBorrow) => - self.bccx.cannot_mutably_borrow_multiply( - new_loan.span, &nl, &new_loan_msg, old_loan.span, &old_loan_msg, - previous_end_span, Origin::Ast), - (ty::UniqueImmBorrow, ty::UniqueImmBorrow) => - self.bccx.cannot_uniquely_borrow_by_two_closures( - new_loan.span, &nl, old_loan.span, previous_end_span, Origin::Ast), - (ty::UniqueImmBorrow, _) => - self.bccx.cannot_uniquely_borrow_by_one_closure( - new_loan.span, "closure", &nl, &new_loan_msg, - old_loan.span, &ol_pronoun, &old_loan_msg, previous_end_span, Origin::Ast), - (_, ty::UniqueImmBorrow) => { - let new_loan_str = &new_loan.kind.to_user_str(); - self.bccx.cannot_reborrow_already_uniquely_borrowed( - new_loan.span, "closure", &nl, &new_loan_msg, new_loan_str, - old_loan.span, &old_loan_msg, previous_end_span, "", Origin::Ast) - } - (..) => - self.bccx.cannot_reborrow_already_borrowed( - new_loan.span, - &nl, &new_loan_msg, &new_loan.kind.to_user_str(), - old_loan.span, &ol_pronoun, &old_loan.kind.to_user_str(), &old_loan_msg, - previous_end_span, Origin::Ast) - }; - - match new_loan.cause { - euv::ClosureCapture(span) => { - err.span_label( - span, - format!("borrow occurs due to use of `{}` in closure", nl)); - } - _ => { } - } - - match old_loan.cause { - euv::ClosureCapture(span) => { - err.span_label( - span, - format!("previous borrow occurs due to use of `{}` in closure", - ol)); - } - _ => { } - } - - return Err(err); + self.bccx.signal_error(); + return false; } - Ok(()) + true } - fn consume_common(&self, - id: hir::ItemLocalId, - span: Span, - cmt: &mc::cmt_<'tcx>, - mode: euv::ConsumeMode) { + fn consume_common( + &self, + id: hir::ItemLocalId, + cmt: &mc::cmt_<'tcx>, + mode: euv::ConsumeMode, + ) { if let Some(lp) = opt_loan_path(cmt) { - let moved_value_use_kind = match mode { + match mode { euv::Copy => { - self.check_for_copy_of_frozen_path(id, span, &lp); - MovedInUse + self.check_for_copy_of_frozen_path(id, &lp); } euv::Move(_) => { - match self.move_data.kind_of_move_of_path(id, &lp) { - None => { - // Sometimes moves don't have a move kind; - // this either means that the original move - // was from something illegal to move, - // or was moved from referent of an unsafe - // pointer or something like that. - MovedInUse - } - Some(move_kind) => { - self.check_for_move_of_borrowed_path(id, span, - &lp, move_kind); - if move_kind == move_data::Captured { - MovedInCapture - } else { - MovedInUse - } - } + // Sometimes moves aren't from a move path; + // this either means that the original move + // was from something illegal to move, + // or was moved from referent of an unsafe + // pointer or something like that. + if self.move_data.is_move_path(id, &lp) { + self.check_for_move_of_borrowed_path(id, &lp); } } - }; - - self.check_if_path_is_moved(id, span, moved_value_use_kind, &lp); + } + self.check_if_path_is_moved(id, &lp); } } fn check_for_copy_of_frozen_path(&self, id: hir::ItemLocalId, - span: Span, copy_path: &LoanPath<'tcx>) { - match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) { - UseOk => { } - UseWhileBorrowed(loan_path, loan_span) => { - let desc = self.bccx.loan_path_to_string(copy_path); - self.bccx.cannot_use_when_mutably_borrowed( - span, &desc, - loan_span, &self.bccx.loan_path_to_string(&loan_path), - Origin::Ast) - .emit(); - self.bccx.signal_error(); - } - } + self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow); } fn check_for_move_of_borrowed_path(&self, id: hir::ItemLocalId, - span: Span, - move_path: &LoanPath<'tcx>, - move_kind: move_data::MoveKind) { + move_path: &LoanPath<'tcx>) { // We want to detect if there are any loans at all, so we search for // any loans incompatible with MutBorrrow, since all other kinds of // loans are incompatible with that. - match self.analyze_restrictions_on_use(id, move_path, ty::MutBorrow) { - UseOk => { } - UseWhileBorrowed(loan_path, loan_span) => { - let mut err = match move_kind { - move_data::Captured => { - let mut err = self.bccx.cannot_move_into_closure( - span, &self.bccx.loan_path_to_string(move_path), Origin::Ast); - err.span_label( - loan_span, - format!("borrow of `{}` occurs here", - &self.bccx.loan_path_to_string(&loan_path)) - ); - err.span_label( - span, - "move into closure occurs here" - ); - err - } - move_data::Declared | - move_data::MoveExpr | - move_data::MovePat => { - let desc = self.bccx.loan_path_to_string(move_path); - let mut err = self.bccx.cannot_move_when_borrowed(span, &desc, Origin::Ast); - err.span_label( - loan_span, - format!("borrow of `{}` occurs here", - &self.bccx.loan_path_to_string(&loan_path)) - ); - err.span_label( - span, - format!("move out of `{}` occurs here", - &self.bccx.loan_path_to_string(move_path)) - ); - err - } - }; - - err.emit(); - self.bccx.signal_error(); - } - } + self.analyze_restrictions_on_use(id, move_path, ty::MutBorrow); } - pub fn analyze_restrictions_on_use(&self, + fn analyze_restrictions_on_use(&self, expr_id: hir::ItemLocalId, use_path: &LoanPath<'tcx>, - borrow_kind: ty::BorrowKind) - -> UseError<'tcx> { + borrow_kind: ty::BorrowKind) { debug!("analyze_restrictions_on_use(expr_id={:?}, use_path={:?})", expr_id, use_path); - let mut ret = UseOk; - let scope = region::Scope { id: expr_id, data: region::ScopeData::Node @@ -760,38 +554,28 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { self.each_in_scope_loan_affecting_path( scope, use_path, |loan| { if !compatible_borrow_kinds(loan.kind, borrow_kind) { - ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); + self.bccx.signal_error(); false } else { true } }); - - return ret; } /// Reports an error if `expr` (which should be a path) /// is using a moved/uninitialized value fn check_if_path_is_moved(&self, id: hir::ItemLocalId, - span: Span, - use_kind: MovedValueUseKind, lp: &Rc>) { - debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={:?})", - id, use_kind, lp); + debug!("check_if_path_is_moved(id={:?}, lp={:?})", id, lp); // FIXME: if you find yourself tempted to cut and paste // the body below and then specializing the error reporting, // consider refactoring this instead! let base_lp = owned_ptr_base_path_rc(lp); - self.move_data.each_move_of(id, &base_lp, |the_move, moved_lp| { - self.bccx.report_use_of_moved_value( - span, - use_kind, - &lp, - the_move, - moved_lp); + self.move_data.each_move_of(id, &base_lp, |_, _| { + self.bccx.signal_error(); false }); } @@ -820,8 +604,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { /// ``` fn check_if_assigned_path_is_moved(&self, id: hir::ItemLocalId, - span: Span, - use_kind: MovedValueUseKind, lp: &Rc>) { match lp.kind { @@ -830,8 +612,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } LpDowncast(ref lp_base, _) => { // assigning to `(P->Variant).f` is ok if assigning to `P` is ok - self.check_if_assigned_path_is_moved(id, span, - use_kind, lp_base); + self.check_if_assigned_path_is_moved(id, lp_base); } LpExtend(ref lp_base, _, LpInterior(_, InteriorField(_))) => { match lp_base.to_type().sty { @@ -845,9 +626,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { let loan_path = owned_ptr_base_path_rc(lp_base); self.move_data.each_move_of(id, &loan_path, |_, _| { self.bccx - .report_partial_reinitialization_of_uninitialized_structure( - span, - &loan_path); + .signal_error(); false }); return; @@ -856,21 +635,19 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } // assigning to `P.f` is ok if assigning to `P` is ok - self.check_if_assigned_path_is_moved(id, span, - use_kind, lp_base); + self.check_if_assigned_path_is_moved(id, lp_base); } LpExtend(ref lp_base, _, LpInterior(_, InteriorElement)) | LpExtend(ref lp_base, _, LpDeref(_)) => { // assigning to `P[i]` requires `P` is initialized // assigning to `(*P)` requires `P` is initialized - self.check_if_path_is_moved(id, span, use_kind, lp_base); + self.check_if_path_is_moved(id, lp_base); } } } fn check_assignment(&self, assignment_id: hir::ItemLocalId, - assignment_span: Span, assignee_cmt: &mc::cmt_<'tcx>) { debug!("check_assignment(assignee_cmt={:?})", assignee_cmt); @@ -880,8 +657,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { id: assignment_id, data: region::ScopeData::Node }; - self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| { - self.report_illegal_mutation(assignment_span, &loan_path, loan); + self.each_in_scope_loan_affecting_path(scope, &loan_path, |_| { + self.bccx.signal_error(); false }); } @@ -889,30 +666,15 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // Check for reassignments to (immutable) local variables. This // needs to be done here instead of in check_loans because we // depend on move data. - if let Categorization::Local(hir_id) = assignee_cmt.cat { + if let Categorization::Local(_) = assignee_cmt.cat { let lp = opt_loan_path(assignee_cmt).unwrap(); - self.move_data.each_assignment_of(assignment_id, &lp, |assign| { - if assignee_cmt.mutbl.is_mutable() { - self.bccx.used_mut_nodes.borrow_mut().insert(hir_id); - } else { - self.bccx.report_reassigned_immutable_variable( - assignment_span, - &lp, - assign); + self.move_data.each_assignment_of(assignment_id, &lp, |_| { + if !assignee_cmt.mutbl.is_mutable() { + self.bccx.signal_error(); } false }); return } } - - pub fn report_illegal_mutation(&self, - span: Span, - loan_path: &LoanPath<'tcx>, - loan: &Loan<'_>) { - self.bccx.cannot_assign_to_borrowed( - span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast) - .emit(); - self.bccx.signal_error(); - } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_ast_borrowck/borrowck/gather_loans/gather_moves.rs similarity index 54% rename from src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs rename to src/librustc_ast_borrowck/borrowck/gather_loans/gather_moves.rs index 658e430734..617161109b 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_ast_borrowck/borrowck/gather_loans/gather_moves.rs @@ -1,10 +1,7 @@ //! Computes moves. use crate::borrowck::*; -use crate::borrowck::gather_loans::move_error::MovePlace; -use crate::borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector}; use crate::borrowck::move_data::*; -use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::middle::mem_categorization::InteriorOffsetKind as Kind; @@ -12,56 +9,11 @@ use rustc::ty::{self, Ty}; use std::rc::Rc; use syntax_pos::Span; -use rustc::hir::*; -use rustc::hir::Node; use log::debug; struct GatherMoveInfo<'c, 'tcx> { id: hir::ItemLocalId, - kind: MoveKind, cmt: &'c mc::cmt_<'tcx>, - span_path_opt: Option>, -} - -/// Represents the kind of pattern -#[derive(Debug, Clone, Copy)] -pub enum PatternSource<'tcx> { - MatchExpr(&'tcx Expr), - LetDecl(&'tcx Local), - Other, -} - -/// Analyzes the context where the pattern appears to determine the -/// kind of hint we want to give. In particular, if the pattern is in a `match` -/// or nested within other patterns, we want to suggest a `ref` binding: -/// -/// let (a, b) = v[0]; // like the `a` and `b` patterns here -/// match v[0] { a => ... } // or the `a` pattern here -/// -/// But if the pattern is the outermost pattern in a `let`, we would rather -/// suggest that the author add a `&` to the initializer: -/// -/// let x = v[0]; // suggest `&v[0]` here -/// -/// In this latter case, this function will return `PatternSource::LetDecl` -/// with a reference to the let -fn get_pattern_source<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat) -> PatternSource<'tcx> { - - let parent = tcx.hir().get_parent_node(pat.hir_id); - - match tcx.hir().get(parent) { - Node::Expr(ref e) => { - // the enclosing expression must be a `match` or something else - assert!(match e.node { - ExprKind::Match(..) => true, - _ => return PatternSource::Other, - }); - PatternSource::MatchExpr(e) - } - Node::Local(local) => PatternSource::LetDecl(local), - _ => return PatternSource::Other, - - } } pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, @@ -69,82 +21,54 @@ pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, var_id: hir::HirId, var_ty: Ty<'tcx>) { let loan_path = Rc::new(LoanPath::new(LpVar(var_id), var_ty)); - move_data.add_move(bccx.tcx, loan_path, var_id.local_id, Declared); + move_data.add_move(bccx.tcx, loan_path, var_id.local_id); } pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - move_error_collector: &mut MoveErrorCollector<'tcx>, move_expr_id: hir::ItemLocalId, - cmt: &mc::cmt_<'tcx>, - move_reason: euv::MoveReason) { - let kind = match move_reason { - euv::DirectRefMove | euv::PatBindingMove => MoveExpr, - euv::CaptureMove => Captured - }; + cmt: &mc::cmt_<'tcx>) { let move_info = GatherMoveInfo { id: move_expr_id, - kind, cmt, - span_path_opt: None, }; - gather_move(bccx, move_data, move_error_collector, move_info); + gather_move(bccx, move_data, move_info); } pub fn gather_move_from_pat<'a, 'c, 'tcx>( bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - move_error_collector: &mut MoveErrorCollector<'tcx>, move_pat: &hir::Pat, cmt: &'c mc::cmt_<'tcx>, ) { - let source = get_pattern_source(bccx.tcx,move_pat); - let pat_span_path_opt = match move_pat.node { - PatKind::Binding(_, _, ident, _) => { - Some(MovePlace { - span: move_pat.span, - name: ident.name, - pat_source: source, - }) - } - _ => None, - }; let move_info = GatherMoveInfo { id: move_pat.hir_id.local_id, - kind: MovePat, cmt, - span_path_opt: pat_span_path_opt, }; - debug!("gather_move_from_pat: move_pat={:?} source={:?}", - move_pat, - source); + debug!("gather_move_from_pat: move_pat={:?}", move_pat); - gather_move(bccx, move_data, move_error_collector, move_info); + gather_move(bccx, move_data, move_info); } fn gather_move<'a, 'c, 'tcx>( bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - move_error_collector: &mut MoveErrorCollector<'tcx>, move_info: GatherMoveInfo<'c, 'tcx>, ) { debug!("gather_move(move_id={:?}, cmt={:?})", move_info.id, move_info.cmt); let potentially_illegal_move = check_and_get_illegal_move_origin(bccx, move_info.cmt); - if let Some(illegal_move_origin) = potentially_illegal_move { - debug!("illegal_move_origin={:?}", illegal_move_origin); - let error = MoveError::with_move_info(Rc::new(illegal_move_origin), - move_info.span_path_opt); - move_error_collector.add_error(error); + if let Some(_) = potentially_illegal_move { + bccx.signal_error(); return; } match opt_loan_path(&move_info.cmt) { Some(loan_path) => { move_data.add_move(bccx.tcx, loan_path, - move_info.id, move_info.kind); + move_info.id); } None => { // move from rvalue or raw pointer, hence ok diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_ast_borrowck/borrowck/gather_loans/lifetime.rs similarity index 80% rename from src/librustc_borrowck/borrowck/gather_loans/lifetime.rs rename to src/librustc_ast_borrowck/borrowck/gather_loans/lifetime.rs index 3122a6060f..ff7dd66793 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_ast_borrowck/borrowck/gather_loans/lifetime.rs @@ -3,21 +3,17 @@ use crate::borrowck::*; use rustc::hir::HirId; -use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::middle::region; use rustc::ty; -use syntax_pos::Span; use log::debug; type R = Result<(),()>; pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, item_scope: region::Scope, - span: Span, - cause: euv::LoanCause, cmt: &'a mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>) -> Result<(),()> { @@ -26,12 +22,7 @@ pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, //! and is scope of `cmt` otherwise. debug!("guarantee_lifetime(cmt={:?}, loan_region={:?})", cmt, loan_region); - let ctxt = GuaranteeLifetimeContext {bccx: bccx, - item_scope, - span, - cause, - loan_region, - cmt_original: cmt}; + let ctxt = GuaranteeLifetimeContext { bccx, item_scope, loan_region }; ctxt.check(cmt, None) } @@ -44,10 +35,7 @@ struct GuaranteeLifetimeContext<'a, 'tcx> { // the scope of the function body for the enclosing item item_scope: region::Scope, - span: Span, - cause: euv::LoanCause, loan_region: ty::Region<'tcx>, - cmt_original: &'a mc::cmt_<'tcx> } impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { @@ -85,7 +73,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { //! Reports an error if `loan_region` is larger than `max_scope` if !self.bccx.is_subregion_of(self.loan_region, max_scope) { - Err(self.report_error(err_out_of_scope(max_scope, self.loan_region, self.cause))) + Err(self.bccx.signal_error()) } else { Ok(()) } @@ -122,11 +110,4 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } } - - fn report_error(&self, code: bckerr_code<'tcx>) { - self.bccx.report(BckError { cmt: self.cmt_original, - span: self.span, - cause: BorrowViolation(self.cause), - code: code }); - } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_ast_borrowck/borrowck/gather_loans/mod.rs similarity index 73% rename from src/librustc_borrowck/borrowck/gather_loans/mod.rs rename to src/librustc_ast_borrowck/borrowck/gather_loans/mod.rs index 887011d347..16fef705ec 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_ast_borrowck/borrowck/gather_loans/mod.rs @@ -23,7 +23,6 @@ use restrictions::RestrictionResult; mod lifetime; mod restrictions; mod gather_moves; -mod move_error; pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, body: hir::BodyId) @@ -38,7 +37,6 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, data: region::ScopeData::Node }, move_data: MoveData::default(), - move_error_collector: move_error::MoveErrorCollector::new(), }; let rvalue_promotable_map = bccx.tcx.rvalue_promotable_map(def_id); @@ -51,7 +49,6 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, Some(rvalue_promotable_map)) .consume_body(bccx.body); - glcx.report_potential_errors(); let GatherLoanCtxt { all_loans, move_data, .. } = glcx; (all_loans, move_data) } @@ -59,7 +56,6 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, struct GatherLoanCtxt<'a, 'tcx> { bccx: &'a BorrowckCtxt<'a, 'tcx>, move_data: move_data::MoveData<'tcx>, - move_error_collector: move_error::MoveErrorCollector<'tcx>, all_loans: Vec>, /// `item_ub` is used as an upper-bound on the lifetime whenever we /// ask for the scope of an expression categorized as an upvar. @@ -76,10 +72,10 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { consume_id, cmt, mode); match mode { - euv::Move(move_reason) => { + euv::Move(_) => { gather_moves::gather_move_from_expr( - self.bccx, &self.move_data, &mut self.move_error_collector, - consume_id.local_id, cmt, move_reason); + self.bccx, &self.move_data, + consume_id.local_id, cmt); } euv::Copy => { } } @@ -110,13 +106,13 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { } gather_moves::gather_move_from_pat( - self.bccx, &self.move_data, &mut self.move_error_collector, + self.bccx, &self.move_data, consume_pat, cmt); } fn borrow(&mut self, borrow_id: hir::HirId, - borrow_span: Span, + _: Span, cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, @@ -128,11 +124,9 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { bk, loan_cause); self.guarantee_valid(borrow_id.local_id, - borrow_span, cmt, bk, - loan_region, - loan_cause); + loan_region); } fn mutate(&mut self, @@ -174,8 +168,6 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { /// Implements the A-* rules in README.md. fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - borrow_span: Span, - loan_cause: AliasableViolationKind, cmt: &mc::cmt_<'tcx>, req_kind: ty::BorrowKind) -> Result<(),()> { @@ -198,13 +190,9 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, // user knows what they're doing in these cases. Ok(()) } - (mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) | - (mc::Aliasability::FreelyAliasable(alias_cause), ty::MutBorrow) => { - bccx.report_aliasability_violation( - borrow_span, - loan_cause, - alias_cause, - cmt); + (mc::Aliasability::FreelyAliasable(_), ty::UniqueImmBorrow) | + (mc::Aliasability::FreelyAliasable(_), ty::MutBorrow) => { + bccx.signal_error(); Err(()) } (..) => { @@ -215,13 +203,10 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, /// Implements the M-* rules in README.md. fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - borrow_span: Span, - cause: AliasableViolationKind, cmt: &mc::cmt_<'tcx>, req_kind: ty::BorrowKind) -> Result<(),()> { - debug!("check_mutability(cause={:?} cmt={:?} req_kind={:?}", - cause, cmt, req_kind); + debug!("check_mutability(cmt={:?} req_kind={:?}", cmt, req_kind); match req_kind { ty::UniqueImmBorrow | ty::ImmBorrow => { match cmt.mutbl { @@ -239,10 +224,7 @@ fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, ty::MutBorrow => { // Only mutable data can be lent as mutable. if !cmt.mutbl.is_mutable() { - Err(bccx.report(BckError { span: borrow_span, - cause, - cmt, - code: err_mutbl })) + Err(bccx.signal_error()) } else { Ok(()) } @@ -268,26 +250,18 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // mutable - this is checked in check_loans. } else { // Check that we don't allow assignments to non-mutable data. - if check_mutability(self.bccx, assignment_span, MutabilityViolation, - cmt, ty::MutBorrow).is_err() { + if check_mutability(self.bccx, cmt, ty::MutBorrow).is_err() { return; // reported an error, no sense in reporting more. } } // Check that we don't allow assignments to aliasable data - if check_aliasability(self.bccx, assignment_span, MutabilityViolation, - cmt, ty::MutBorrow).is_err() { + if check_aliasability(self.bccx, cmt, ty::MutBorrow).is_err() { return; // reported an error, no sense in reporting more. } match opt_lp { Some(lp) => { - if let Categorization::Local(..) = cmt.cat { - // Only re-assignments to locals require it to be - // mutable - this is checked in check_loans. - } else { - self.mark_loan_path_as_mutated(&lp); - } gather_moves::gather_assignment(self.bccx, &self.move_data, assignment_id.local_id, assignment_span, @@ -306,11 +280,9 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { /// `req_loan_map`. fn guarantee_valid(&mut self, borrow_id: hir::ItemLocalId, - borrow_span: Span, cmt: &mc::cmt_<'tcx>, req_kind: ty::BorrowKind, - loan_region: ty::Region<'tcx>, - cause: euv::LoanCause) { + loan_region: ty::Region<'tcx>) { debug!("guarantee_valid(borrow_id={:?}, cmt={:?}, \ req_mutbl={:?}, loan_region={:?})", borrow_id, @@ -326,27 +298,23 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // Check that the lifetime of the borrow does not exceed // the lifetime of the data being borrowed. - if lifetime::guarantee_lifetime(self.bccx, self.item_ub, - borrow_span, cause, cmt, loan_region).is_err() { + if lifetime::guarantee_lifetime(self.bccx, self.item_ub, cmt, loan_region).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of non-mutable data. - if check_mutability(self.bccx, borrow_span, BorrowViolation(cause), - cmt, req_kind).is_err() { + if check_mutability(self.bccx, cmt, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of aliasable data. - if check_aliasability(self.bccx, borrow_span, BorrowViolation(cause), - cmt, req_kind).is_err() { + if check_aliasability(self.bccx, cmt, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Compute the restrictions that are required to enforce the // loan is safe. - let restr = restrictions::compute_restrictions( - self.bccx, borrow_span, cause, &cmt, loan_region); + let restr = restrictions::compute_restrictions(self.bccx, &cmt, loan_region); debug!("guarantee_valid(): restrictions={:?}", restr); @@ -395,19 +363,13 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { let kill_scope = self.compute_kill_scope(loan_scope, &loan_path); debug!("kill_scope = {:?}", kill_scope); - if req_kind == ty::MutBorrow { - self.mark_loan_path_as_mutated(&loan_path); - } - Loan { index: self.all_loans.len(), loan_path, kind: req_kind, gen_scope, kill_scope, - span: borrow_span, restricted_paths, - cause, } } }; @@ -419,70 +381,6 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // let loan_gen_scope = loan.gen_scope; // let loan_kill_scope = loan.kill_scope; self.all_loans.push(loan); - - // if loan_gen_scope != borrow_id { - // FIXME(https://github.com/rust-lang/rfcs/issues/811) Nested method calls - // - // Typically, the scope of the loan includes the point at - // which the loan is originated. This - // This is a subtle case. See the test case - // - // to see what we are guarding against. - - //let restr = restrictions::compute_restrictions( - // self.bccx, borrow_span, cmt, RESTR_EMPTY); - //let loan = { - // Loan { - // index: self.all_loans.len(), - // loan_path, - // cmt, - // mutbl: ConstMutability, - // gen_scope: borrow_id, - // kill_scope, - // span: borrow_span, - // restrictions, - // } - // } - } - - pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath<'_>) { - //! For mutable loans of content whose mutability derives - //! from a local variable, mark the mutability decl as necessary. - - let mut wrapped_path = Some(loan_path); - let mut through_borrow = false; - - while let Some(current_path) = wrapped_path { - wrapped_path = match current_path.kind { - LpVar(hir_id) => { - if !through_borrow { - self.bccx.used_mut_nodes.borrow_mut().insert(hir_id); - } - None - } - LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => { - self.bccx.used_mut_nodes.borrow_mut().insert(hir_id); - None - } - LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) | - LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => { - if pointer_kind != mc::Unique { - through_borrow = true; - } - Some(base) - } - LpDowncast(ref base, _) | - LpExtend(ref base, mc::McInherited, _) | - LpExtend(ref base, mc::McDeclared, _) => { - Some(base) - } - LpExtend(_, mc::McImmutable, _) => { - // Nothing to do. - None - } - } - } - } pub fn compute_gen_scope(&self, @@ -532,8 +430,4 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { loan_scope } } - - pub fn report_potential_errors(&self) { - self.move_error_collector.report_potential_errors(self.bccx); - } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_ast_borrowck/borrowck/gather_loans/restrictions.rs similarity index 91% rename from src/librustc_borrowck/borrowck/gather_loans/restrictions.rs rename to src/librustc_ast_borrowck/borrowck/gather_loans/restrictions.rs index 371e6c55a7..545c27b17b 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_ast_borrowck/borrowck/gather_loans/restrictions.rs @@ -1,11 +1,9 @@ //! Computes the restrictions that result from a borrow. use crate::borrowck::*; -use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::ty; -use syntax_pos::Span; use log::debug; use crate::borrowck::ToInteriorKind; @@ -19,17 +17,10 @@ pub enum RestrictionResult<'tcx> { } pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - span: Span, - cause: euv::LoanCause, cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>) -> RestrictionResult<'tcx> { - let ctxt = RestrictionsContext { - bccx, - span, - cause, - loan_region, - }; + let ctxt = RestrictionsContext { bccx, loan_region }; ctxt.restrict(cmt) } @@ -39,9 +30,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, struct RestrictionsContext<'a, 'tcx> { bccx: &'a BorrowckCtxt<'a, 'tcx>, - span: Span, loan_region: ty::Region<'tcx>, - cause: euv::LoanCause, } impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { @@ -149,13 +138,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { mc::BorrowedPtr(bk, lt) => { // R-Deref-[Mut-]Borrowed if !self.bccx.is_subregion_of(self.loan_region, lt) { - self.bccx.report( - BckError { - span: self.span, - cause: BorrowViolation(self.cause), - cmt: &cmt_base, - code: err_borrowed_pointer_too_short( - self.loan_region, lt)}); + self.bccx.signal_error(); return RestrictionResult::Safe; } diff --git a/src/librustc_ast_borrowck/borrowck/mod.rs b/src/librustc_ast_borrowck/borrowck/mod.rs new file mode 100644 index 0000000000..3bbd7ae5c3 --- /dev/null +++ b/src/librustc_ast_borrowck/borrowck/mod.rs @@ -0,0 +1,621 @@ +//! See The Book chapter on the borrow checker for more details. + +#![allow(non_camel_case_types)] + +pub use LoanPathKind::*; +pub use LoanPathElem::*; + +use InteriorKind::*; + +use rustc::hir::HirId; +use rustc::hir::Node; +use rustc::cfg; +use rustc::middle::borrowck::{BorrowCheckResult, SignalledError}; +use rustc::hir::def_id::{DefId, LocalDefId}; +use rustc::middle::mem_categorization as mc; +use rustc::middle::mem_categorization::Categorization; +use rustc::middle::region; +use rustc::middle::free_region::RegionRelations; +use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::query::Providers; + +use std::borrow::Cow; +use std::cell::{Cell}; +use std::fmt; +use std::rc::Rc; +use std::hash::{Hash, Hasher}; +use log::debug; + +use rustc::hir; + +use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; + +pub mod check_loans; + +pub mod gather_loans; + +pub mod move_data; + +#[derive(Clone, Copy)] +pub struct LoanDataFlowOperator; + +pub type LoanDataFlow<'tcx> = DataFlowContext<'tcx, LoanDataFlowOperator>; + +pub fn check_crate(tcx: TyCtxt<'_>) { + tcx.par_body_owners(|body_owner_def_id| { + tcx.ensure().borrowck(body_owner_def_id); + }); +} + +pub fn provide(providers: &mut Providers<'_>) { + *providers = Providers { + borrowck, + ..*providers + }; +} + +/// Collection of conclusions determined via borrow checker analyses. +pub struct AnalysisData<'tcx> { + pub all_loans: Vec>, + pub loans: DataFlowContext<'tcx, LoanDataFlowOperator>, + pub move_data: move_data::FlowedMoveData<'tcx>, +} + +fn borrowck(tcx: TyCtxt<'_>, owner_def_id: DefId) -> &BorrowCheckResult { + assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck()); + + debug!("borrowck(body_owner_def_id={:?})", owner_def_id); + + let signalled_error = tcx.check_match(owner_def_id); + if let SignalledError::SawSomeError = signalled_error { + return tcx.arena.alloc(BorrowCheckResult { + signalled_any_error: SignalledError::SawSomeError, + }) + } + + let owner_id = tcx.hir().as_local_hir_id(owner_def_id).unwrap(); + + match tcx.hir().get(owner_id) { + Node::Ctor(..) => { + // We get invoked with anything that has MIR, but some of + // those things (notably the synthesized constructors from + // tuple structs/variants) do not have an associated body + // and do not need borrowchecking. + return tcx.arena.alloc(BorrowCheckResult { + signalled_any_error: SignalledError::NoErrorsSeen, + }) + } + _ => { } + } + + let body_id = tcx.hir().body_owned_by(owner_id); + let tables = tcx.typeck_tables_of(owner_def_id); + let region_scope_tree = tcx.region_scope_tree(owner_def_id); + let body = tcx.hir().body(body_id); + let mut bccx = BorrowckCtxt { + tcx, + tables, + region_scope_tree, + owner_def_id, + body, + signalled_any_error: Cell::new(SignalledError::NoErrorsSeen), + }; + + // Eventually, borrowck will always read the MIR, but at the + // moment we do not. So, for now, we always force MIR to be + // constructed for a given fn, since this may result in errors + // being reported and we want that to happen. + // + // Note that `mir_validated` is a "stealable" result; the + // thief, `optimized_mir()`, forces borrowck, so we know that + // is not yet stolen. + tcx.ensure().mir_validated(owner_def_id); + + // option dance because you can't capture an uninitialized variable + // by mut-ref. + let mut cfg = None; + if let Some(AnalysisData { all_loans, + loans: loan_dfcx, + move_data: flowed_moves }) = + build_borrowck_dataflow_data(&mut bccx, false, body_id, + |bccx| { + cfg = Some(cfg::CFG::new(bccx.tcx, &body)); + cfg.as_mut().unwrap() + }) + { + check_loans::check_loans(&mut bccx, &loan_dfcx, &flowed_moves, &all_loans, body); + } + + tcx.arena.alloc(BorrowCheckResult { + signalled_any_error: bccx.signalled_any_error.into_inner(), + }) +} + +fn build_borrowck_dataflow_data<'a, 'c, 'tcx, F>(this: &mut BorrowckCtxt<'a, 'tcx>, + force_analysis: bool, + body_id: hir::BodyId, + get_cfg: F) + -> Option> + where F: FnOnce(&mut BorrowckCtxt<'a, 'tcx>) -> &'c cfg::CFG +{ + // Check the body of fn items. + let (all_loans, move_data) = + gather_loans::gather_loans_in_fn(this, body_id); + + if !force_analysis && move_data.is_empty() && all_loans.is_empty() { + // large arrays of data inserted as constants can take a lot of + // time and memory to borrow-check - see issue #36799. However, + // they don't have places, so no borrow-check is actually needed. + // Recognize that case and skip borrow-checking. + debug!("skipping loan propagation for {:?} because of no loans", body_id); + return None; + } else { + debug!("propagating loans in {:?}", body_id); + } + + let cfg = get_cfg(this); + let mut loan_dfcx = + DataFlowContext::new(this.tcx, + "borrowck", + Some(this.body), + cfg, + LoanDataFlowOperator, + all_loans.len()); + for (loan_idx, loan) in all_loans.iter().enumerate() { + loan_dfcx.add_gen(loan.gen_scope.item_local_id(), loan_idx); + loan_dfcx.add_kill(KillFrom::ScopeEnd, + loan.kill_scope.item_local_id(), + loan_idx); + } + loan_dfcx.add_kills_from_flow_exits(cfg); + loan_dfcx.propagate(cfg, this.body); + + let flowed_moves = move_data::FlowedMoveData::new(move_data, + this, + cfg, + this.body); + + Some(AnalysisData { all_loans, + loans: loan_dfcx, + move_data:flowed_moves }) +} + +/// Accessor for introspective clients inspecting `AnalysisData` and +/// the `BorrowckCtxt` itself , e.g., the flowgraph visualizer. +pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( + tcx: TyCtxt<'tcx>, + body_id: hir::BodyId, + cfg: &cfg::CFG) + -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'tcx>) +{ + let owner_id = tcx.hir().body_owner(body_id); + let owner_def_id = tcx.hir().local_def_id(owner_id); + let tables = tcx.typeck_tables_of(owner_def_id); + let region_scope_tree = tcx.region_scope_tree(owner_def_id); + let body = tcx.hir().body(body_id); + let mut bccx = BorrowckCtxt { + tcx, + tables, + region_scope_tree, + owner_def_id, + body, + signalled_any_error: Cell::new(SignalledError::NoErrorsSeen), + }; + + let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg); + (bccx, dataflow_data.unwrap()) +} + +// ---------------------------------------------------------------------- +// Type definitions + +pub struct BorrowckCtxt<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + + // tables for the current thing we are checking; set to + // Some in `borrowck_fn` and cleared later + tables: &'a ty::TypeckTables<'tcx>, + + region_scope_tree: &'tcx region::ScopeTree, + + owner_def_id: DefId, + + body: &'tcx hir::Body, + + signalled_any_error: Cell, +} + + +impl<'a, 'tcx: 'a> BorrowckCtxt<'a, 'tcx> { + fn signal_error(&self) { + self.signalled_any_error.set(SignalledError::SawSomeError); + } +} + +/////////////////////////////////////////////////////////////////////////// +// Loans and loan paths + +/// Record of a loan that was issued. +pub struct Loan<'tcx> { + index: usize, + loan_path: Rc>, + kind: ty::BorrowKind, + restricted_paths: Vec>>, + + /// gen_scope indicates where loan is introduced. Typically the + /// loan is introduced at the point of the borrow, but in some + /// cases, notably method arguments, the loan may be introduced + /// only later, once it comes into scope. See also + /// `GatherLoanCtxt::compute_gen_scope`. + gen_scope: region::Scope, + + /// kill_scope indicates when the loan goes out of scope. This is + /// either when the lifetime expires or when the local variable + /// which roots the loan-path goes out of scope, whichever happens + /// faster. See also `GatherLoanCtxt::compute_kill_scope`. + kill_scope: region::Scope, +} + +impl<'tcx> Loan<'tcx> { + pub fn loan_path(&self) -> Rc> { + self.loan_path.clone() + } +} + +#[derive(Eq)] +pub struct LoanPath<'tcx> { + kind: LoanPathKind<'tcx>, + ty: Ty<'tcx>, +} + +impl<'tcx> PartialEq for LoanPath<'tcx> { + fn eq(&self, that: &LoanPath<'tcx>) -> bool { + self.kind == that.kind + } +} + +impl<'tcx> Hash for LoanPath<'tcx> { + fn hash(&self, state: &mut H) { + self.kind.hash(state); + } +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub enum LoanPathKind<'tcx> { + LpVar(hir::HirId), // `x` in README.md + LpUpvar(ty::UpvarId), // `x` captured by-value into closure + LpDowncast(Rc>, DefId), // `x` downcast to particular enum variant + LpExtend(Rc>, mc::MutabilityCategory, LoanPathElem<'tcx>) +} + +impl<'tcx> LoanPath<'tcx> { + fn new(kind: LoanPathKind<'tcx>, ty: Ty<'tcx>) -> LoanPath<'tcx> { + LoanPath { kind: kind, ty: ty } + } + + fn to_type(&self) -> Ty<'tcx> { self.ty } +} + +// FIXME (pnkfelix): See discussion here +// https://github.com/pnkfelix/rust/commit/ +// b2b39e8700e37ad32b486b9a8409b50a8a53aa51#commitcomment-7892003 +const DOWNCAST_PRINTED_OPERATOR: &'static str = " as "; + +// A local, "cleaned" version of `mc::InteriorKind` that drops +// information that is not relevant to loan-path analysis. (In +// particular, the distinction between how precisely an array-element +// is tracked is irrelevant here.) +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub enum InteriorKind { + InteriorField(mc::FieldIndex), + InteriorElement, +} + +trait ToInteriorKind { fn cleaned(self) -> InteriorKind; } +impl ToInteriorKind for mc::InteriorKind { + fn cleaned(self) -> InteriorKind { + match self { + mc::InteriorField(name) => InteriorField(name), + mc::InteriorElement(_) => InteriorElement, + } + } +} + +// This can be: +// - a pointer dereference (`*P` in README.md) +// - a field reference, with an optional definition of the containing +// enum variant (`P.f` in README.md) +// `DefId` is present when the field is part of struct that is in +// a variant of an enum. For instance in: +// `enum E { X { foo: u32 }, Y { foo: u32 }}` +// each `foo` is qualified by the definitition id of the variant (`X` or `Y`). +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum LoanPathElem<'tcx> { + LpDeref(mc::PointerKind<'tcx>), + LpInterior(Option, InteriorKind), +} + +fn closure_to_block(closure_id: LocalDefId, tcx: TyCtxt<'_>) -> HirId { + let closure_id = tcx.hir().local_def_id_to_hir_id(closure_id); + match tcx.hir().get(closure_id) { + Node::Expr(expr) => match expr.node { + hir::ExprKind::Closure(.., body_id, _, _) => { + body_id.hir_id + } + _ => { + bug!("encountered non-closure id: {}", closure_id) + } + }, + _ => bug!("encountered non-expr id: {}", closure_id) + } +} + +impl<'a, 'tcx> LoanPath<'tcx> { + pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::Scope { + match self.kind { + LpVar(hir_id) => { + bccx.region_scope_tree.var_scope(hir_id.local_id) + } + LpUpvar(upvar_id) => { + let block_id = closure_to_block(upvar_id.closure_expr_id, bccx.tcx); + region::Scope { id: block_id.local_id, data: region::ScopeData::Node } + } + LpDowncast(ref base, _) | + LpExtend(ref base, ..) => base.kill_scope(bccx), + } + } +} + +// Avoid "cannot borrow immutable field `self.x` as mutable" as that implies that a field *can* be +// mutable independently of the struct it belongs to. (#35937) +pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt_<'tcx>) -> (Option>>, bool) { + let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty)); + + match cmt.cat { + Categorization::Rvalue(..) | + Categorization::ThreadLocal(..) | + Categorization::StaticItem => { + (None, false) + } + + Categorization::Local(id) => { + (Some(new_lp(LpVar(id))), false) + } + + Categorization::Upvar(mc::Upvar { id, .. }) => { + (Some(new_lp(LpUpvar(id))), false) + } + + Categorization::Deref(ref cmt_base, pk) => { + let lp = opt_loan_path_is_field(cmt_base); + (lp.0.map(|lp| { + new_lp(LpExtend(lp, cmt.mutbl, LpDeref(pk))) + }), lp.1) + } + + Categorization::Interior(ref cmt_base, ik) => { + (opt_loan_path(cmt_base).map(|lp| { + let opt_variant_id = match cmt_base.cat { + Categorization::Downcast(_, did) => Some(did), + _ => None + }; + new_lp(LpExtend(lp, cmt.mutbl, LpInterior(opt_variant_id, ik.cleaned()))) + }), true) + } + + Categorization::Downcast(ref cmt_base, variant_def_id) => { + let lp = opt_loan_path_is_field(cmt_base); + (lp.0.map(|lp| { + new_lp(LpDowncast(lp, variant_def_id)) + }), lp.1) + } + } +} + +/// Computes the `LoanPath` (if any) for a `cmt`. +/// Note that this logic is somewhat duplicated in +/// the method `compute()` found in `gather_loans::restrictions`, +/// which allows it to share common loan path pieces as it +/// traverses the CMT. +pub fn opt_loan_path<'tcx>(cmt: &mc::cmt_<'tcx>) -> Option>> { + opt_loan_path_is_field(cmt).0 +} + +/////////////////////////////////////////////////////////////////////////// +// Misc + +impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { + pub fn is_subregion_of(&self, + r_sub: ty::Region<'tcx>, + r_sup: ty::Region<'tcx>) + -> bool + { + let region_rels = RegionRelations::new(self.tcx, + self.owner_def_id, + &self.region_scope_tree, + &self.tables.free_region_map); + region_rels.is_subregion_of(r_sub, r_sup) + } + + pub fn append_loan_path_to_string(&self, + loan_path: &LoanPath<'tcx>, + out: &mut String) { + match loan_path.kind { + LpUpvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id: id }, closure_expr_id: _ }) => { + out.push_str(&self.tcx.hir().name(id).as_str()); + } + LpVar(id) => { + out.push_str(&self.tcx.hir().name(id).as_str()); + } + + LpDowncast(ref lp_base, variant_def_id) => { + out.push('('); + self.append_loan_path_to_string(&lp_base, out); + out.push_str(DOWNCAST_PRINTED_OPERATOR); + out.push_str(&self.tcx.def_path_str(variant_def_id)); + out.push(')'); + } + + LpExtend(ref lp_base, _, LpInterior(_, InteriorField(mc::FieldIndex(_, info)))) => { + self.append_autoderefd_loan_path_to_string(&lp_base, out); + out.push('.'); + out.push_str(&info.as_str()); + } + + LpExtend(ref lp_base, _, LpInterior(_, InteriorElement)) => { + self.append_autoderefd_loan_path_to_string(&lp_base, out); + out.push_str("[..]"); + } + + LpExtend(ref lp_base, _, LpDeref(_)) => { + out.push('*'); + self.append_loan_path_to_string(&lp_base, out); + } + } + } + + pub fn append_autoderefd_loan_path_to_string(&self, + loan_path: &LoanPath<'tcx>, + out: &mut String) { + match loan_path.kind { + LpExtend(ref lp_base, _, LpDeref(_)) => { + // For a path like `(*x).f` or `(*x)[3]`, autoderef + // rules would normally allow users to omit the `*x`. + // So just serialize such paths to `x.f` or x[3]` respectively. + self.append_autoderefd_loan_path_to_string(&lp_base, out) + } + + LpDowncast(ref lp_base, variant_def_id) => { + out.push('('); + self.append_autoderefd_loan_path_to_string(&lp_base, out); + out.push_str(DOWNCAST_PRINTED_OPERATOR); + out.push_str(&self.tcx.def_path_str(variant_def_id)); + out.push(')'); + } + + LpVar(..) | LpUpvar(..) | LpExtend(.., LpInterior(..)) => { + self.append_loan_path_to_string(loan_path, out) + } + } + } + + pub fn loan_path_to_string(&self, loan_path: &LoanPath<'tcx>) -> String { + let mut result = String::new(); + self.append_loan_path_to_string(loan_path, &mut result); + result + } + + pub fn cmt_to_cow_str(&self, cmt: &mc::cmt_<'tcx>) -> Cow<'static, str> { + cmt.descriptive_string(self.tcx) + } + + pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt_<'tcx>) -> String { + match opt_loan_path(cmt) { + Some(lp) => format!("`{}`", self.loan_path_to_string(&lp)), + None => self.cmt_to_cow_str(cmt).into_owned(), + } + } +} + +impl BitwiseOperator for LoanDataFlowOperator { + #[inline] + fn join(&self, succ: usize, pred: usize) -> usize { + succ | pred // loans from both preds are in scope + } +} + +impl DataFlowOperator for LoanDataFlowOperator { + #[inline] + fn initial_value(&self) -> bool { + false // no loans in scope by default + } +} + +impl fmt::Debug for InteriorKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + InteriorField(mc::FieldIndex(_, info)) => write!(f, "{}", info), + InteriorElement => write!(f, "[]"), + } + } +} + +impl<'tcx> fmt::Debug for Loan<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Loan_{}({:?}, {:?}, {:?}-{:?}, {:?})", + self.index, + self.loan_path, + self.kind, + self.gen_scope, + self.kill_scope, + self.restricted_paths) + } +} + +impl<'tcx> fmt::Debug for LoanPath<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.kind { + LpVar(id) => { + write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_string(id))) + } + + LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath {hir_id: var_id}, closure_expr_id }) => { + let s = ty::tls::with(|tcx| { + tcx.hir().node_to_string(var_id) + }); + write!(f, "$({} captured by id={:?})", s, closure_expr_id) + } + + LpDowncast(ref lp, variant_def_id) => { + let variant_str = if variant_def_id.is_local() { + ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) + } else { + format!("{:?}", variant_def_id) + }; + write!(f, "({:?}{}{})", lp, DOWNCAST_PRINTED_OPERATOR, variant_str) + } + + LpExtend(ref lp, _, LpDeref(_)) => { + write!(f, "{:?}.*", lp) + } + + LpExtend(ref lp, _, LpInterior(_, ref interior)) => { + write!(f, "{:?}.{:?}", lp, interior) + } + } + } +} + +impl<'tcx> fmt::Display for LoanPath<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.kind { + LpVar(id) => { + write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().hir_to_user_string(id))) + } + + LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => { + let s = ty::tls::with(|tcx| { + tcx.hir().node_to_string(hir_id) + }); + write!(f, "$({} captured by closure)", s) + } + + LpDowncast(ref lp, variant_def_id) => { + let variant_str = if variant_def_id.is_local() { + ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) + } else { + format!("{:?}", variant_def_id) + }; + write!(f, "({}{}{})", lp, DOWNCAST_PRINTED_OPERATOR, variant_str) + } + + LpExtend(ref lp, _, LpDeref(_)) => { + write!(f, "{}.*", lp) + } + + LpExtend(ref lp, _, LpInterior(_, ref interior)) => { + write!(f, "{}.{:?}", lp, interior) + } + } + } +} diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_ast_borrowck/borrowck/move_data.rs similarity index 96% rename from src/librustc_borrowck/borrowck/move_data.rs rename to src/librustc_ast_borrowck/borrowck/move_data.rs index 9feea64f18..887a0e2f20 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_ast_borrowck/borrowck/move_data.rs @@ -1,8 +1,6 @@ //! Data structures used for tracking moves. Please see the extensive //! comments in the section "Moves and initialization" in `README.md`. -pub use MoveKind::*; - use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; use crate::borrowck::*; @@ -101,13 +99,6 @@ pub struct MovePath<'tcx> { pub next_sibling: MovePathIndex, } -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum MoveKind { - Declared, // When declared, variables start out "moved". - MoveExpr, // Expression or binding that moves a variable - MovePat, // By-move binding - Captured // Closure creation that moves a value -} #[derive(Copy, Clone)] pub struct Move { @@ -117,9 +108,6 @@ pub struct Move { /// ID of node that is doing the move. pub id: hir::ItemLocalId, - /// Kind of move, for error messages. - pub kind: MoveKind, - /// Next node in linked list of moves from `path`, or `InvalidMoveIndex` pub next_move: MoveIndex } @@ -315,7 +303,6 @@ impl MoveData<'tcx> { tcx: TyCtxt<'tcx>, orig_lp: Rc>, id: hir::ItemLocalId, - kind: MoveKind, ) { // Moving one union field automatically moves all its fields. Also move siblings of // all parent union fields, moves do not propagate upwards automatically. @@ -331,7 +318,7 @@ impl MoveData<'tcx> { let sibling_lp_kind = LpExtend(base_lp.clone(), mutbl, LpInterior(opt_variant_id, field)); let sibling_lp = Rc::new(LoanPath::new(sibling_lp_kind, tcx.types.err)); - self.add_move_helper(tcx, sibling_lp, id, kind); + self.add_move_helper(tcx, sibling_lp, id); } } } @@ -339,7 +326,7 @@ impl MoveData<'tcx> { lp = base_lp.clone(); } - self.add_move_helper(tcx, orig_lp, id, kind); + self.add_move_helper(tcx, orig_lp, id); } fn add_move_helper( @@ -347,12 +334,8 @@ impl MoveData<'tcx> { tcx: TyCtxt<'tcx>, lp: Rc>, id: hir::ItemLocalId, - kind: MoveKind, ) { - debug!("add_move(lp={:?}, id={:?}, kind={:?})", - lp, - id, - kind); + debug!("add_move(lp={:?}, id={:?})", lp, id); let path_index = self.move_path(tcx, lp); let move_index = MoveIndex(self.moves.borrow().len()); @@ -363,7 +346,6 @@ impl MoveData<'tcx> { self.moves.borrow_mut().push(Move { path: path_index, id, - kind, next_move, }); } @@ -611,19 +593,16 @@ impl<'tcx> FlowedMoveData<'tcx> { } } - pub fn kind_of_move_of_path(&self, - id: hir::ItemLocalId, - loan_path: &Rc>) - -> Option { + pub fn is_move_path(&self, id: hir::ItemLocalId, loan_path: &Rc>) -> bool { //! Returns the kind of a move of `loan_path` by `id`, if one exists. - let mut ret = None; + let mut ret = false; if let Some(loan_path_index) = self.move_data.path_map.borrow().get(&*loan_path) { self.dfcx_moves.each_gen_bit(id, |move_index| { let the_move = self.move_data.moves.borrow(); let the_move = (*the_move)[move_index]; if the_move.path == *loan_path_index { - ret = Some(the_move.kind); + ret = true; false } else { true diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_ast_borrowck/dataflow.rs similarity index 97% rename from src/librustc_borrowck/dataflow.rs rename to src/librustc_ast_borrowck/dataflow.rs index f5d311b35d..94849728a9 100644 --- a/src/librustc_borrowck/dataflow.rs +++ b/src/librustc_ast_borrowck/dataflow.rs @@ -6,10 +6,8 @@ use rustc::cfg; use rustc::cfg::CFGIndex; use rustc::ty::TyCtxt; -use std::io; use std::mem; use std::usize; -use syntax::print::pprust::PrintState; use log::debug; use rustc_data_structures::graph::implementation::OUTGOING; @@ -84,9 +82,9 @@ struct PropagationContext<'a, 'tcx, O> { changed: bool, } -fn get_cfg_indices<'a>(id: hir::ItemLocalId, - index: &'a FxHashMap>) - -> &'a [CFGIndex] { +fn get_cfg_indices(id: hir::ItemLocalId, + index: &FxHashMap>) + -> &[CFGIndex] { index.get(&id).map_or(&[], |v| &v[..]) } @@ -98,23 +96,24 @@ impl<'tcx, O: DataFlowOperator> DataFlowContext<'tcx, O> { } impl<'tcx, O: DataFlowOperator> pprust::PpAnn for DataFlowContext<'tcx, O> { - fn nested(&self, state: &mut pprust::State<'_>, nested: pprust::Nested) -> io::Result<()> { + fn nested(&self, state: &mut pprust::State<'_>, nested: pprust::Nested) { pprust::PpAnn::nested(self.tcx.hir(), state, nested) } fn pre(&self, ps: &mut pprust::State<'_>, - node: pprust::AnnNode<'_>) -> io::Result<()> { + node: pprust::AnnNode<'_>) { let id = match node { - pprust::AnnNode::Name(_) => return Ok(()), + pprust::AnnNode::Name(_) => return, pprust::AnnNode::Expr(expr) => expr.hir_id.local_id, pprust::AnnNode::Block(blk) => blk.hir_id.local_id, pprust::AnnNode::Item(_) | - pprust::AnnNode::SubItem(_) => return Ok(()), - pprust::AnnNode::Pat(pat) => pat.hir_id.local_id + pprust::AnnNode::SubItem(_) => return, + pprust::AnnNode::Pat(pat) => pat.hir_id.local_id, + pprust::AnnNode::Arm(arm) => arm.hir_id.local_id, }; if !self.has_bitset_for_local_id(id) { - return Ok(()); + return; } assert!(self.bits_per_id > 0); @@ -147,10 +146,9 @@ impl<'tcx, O: DataFlowOperator> pprust::PpAnn for DataFlowContext<'tcx, O> { ps.synth_comment( format!("id {}: {}{}{}{}", id.as_usize(), entry_str, - gens_str, action_kills_str, scope_kills_str))?; - ps.s.space()?; + gens_str, action_kills_str, scope_kills_str)); + ps.s.space(); } - Ok(()) } } @@ -531,8 +529,8 @@ impl<'tcx, O: DataFlowOperator + Clone + 'static> DataFlowContext<'tcx, O> { debug!("Dataflow result for {}:", self.analysis_name); debug!("{}", pprust::to_string(self, |s| { - s.cbox(pprust::indent_unit)?; - s.ibox(0)?; + s.cbox(pprust::INDENT_UNIT); + s.ibox(0); s.print_expr(&body.value) })); } diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_ast_borrowck/graphviz.rs similarity index 100% rename from src/librustc_borrowck/graphviz.rs rename to src/librustc_ast_borrowck/graphviz.rs diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_ast_borrowck/lib.rs similarity index 83% rename from src/librustc_borrowck/lib.rs rename to src/librustc_ast_borrowck/lib.rs index 98e629ce04..dc818278a4 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_ast_borrowck/lib.rs @@ -1,9 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs deleted file mode 100644 index 58be2cf76c..0000000000 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ /dev/null @@ -1,186 +0,0 @@ -use crate::borrowck::BorrowckCtxt; -use rustc::middle::mem_categorization as mc; -use rustc::middle::mem_categorization::Categorization; -use rustc::middle::mem_categorization::NoteClosureEnv; -use rustc::middle::mem_categorization::InteriorOffsetKind as Kind; -use rustc::ty; -use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; -use syntax::ast; -use syntax_pos; -use errors::{DiagnosticBuilder, Applicability}; -use crate::borrowck::gather_loans::gather_moves::PatternSource; -use log::debug; - -pub struct MoveErrorCollector<'tcx> { - errors: Vec> -} - -impl<'tcx> MoveErrorCollector<'tcx> { - pub fn new() -> MoveErrorCollector<'tcx> { - MoveErrorCollector { - errors: Vec::new() - } - } - - pub fn add_error(&mut self, error: MoveError<'tcx>) { - self.errors.push(error); - } - - pub fn report_potential_errors<'a>(&self, bccx: &BorrowckCtxt<'a, 'tcx>) { - report_move_errors(bccx, &self.errors) - } -} - -pub struct MoveError<'tcx> { - move_from: mc::cmt<'tcx>, - move_to: Option> -} - -impl<'tcx> MoveError<'tcx> { - pub fn with_move_info(move_from: mc::cmt<'tcx>, - move_to: Option>) - -> MoveError<'tcx> { - MoveError { - move_from, - move_to, - } - } -} - -#[derive(Clone)] -pub struct MovePlace<'tcx> { - pub span: syntax_pos::Span, - pub name: ast::Name, - pub pat_source: PatternSource<'tcx>, -} - -pub struct GroupedMoveErrors<'tcx> { - move_from: mc::cmt<'tcx>, - move_to_places: Vec> -} - -fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &[MoveError<'tcx>]) { - let grouped_errors = group_errors_with_same_origin(errors); - for error in &grouped_errors { - let mut err = report_cannot_move_out_of(bccx, error.move_from.clone()); - let mut is_first_note = true; - match error.move_to_places.get(0) { - Some(&MovePlace { pat_source: PatternSource::LetDecl(ref e), .. }) => { - // ignore patterns that are found at the top-level of a `let`; - // see `get_pattern_source()` for details - let initializer = - e.init.as_ref().expect("should have an initializer to get an error"); - if let Ok(snippet) = bccx.tcx.sess.source_map().span_to_snippet(initializer.span) { - err.span_suggestion( - initializer.span, - "consider using a reference instead", - format!("&{}", snippet), - Applicability::MaybeIncorrect // using a reference may not be the right fix - ); - } - } - _ => { - for move_to in &error.move_to_places { - - err = note_move_destination(err, move_to.span, move_to.name, is_first_note); - is_first_note = false; - } - } - } - if let NoteClosureEnv(upvar_id) = error.move_from.note { - err.span_label(bccx.tcx.hir().span(upvar_id.var_path.hir_id), - "captured outer variable"); - } - err.emit(); - bccx.signal_error(); - } -} - -fn group_errors_with_same_origin<'tcx>(errors: &[MoveError<'tcx>]) - -> Vec> { - let mut grouped_errors = Vec::new(); - for error in errors { - append_to_grouped_errors(&mut grouped_errors, error) - } - return grouped_errors; - - fn append_to_grouped_errors<'tcx>(grouped_errors: &mut Vec>, - error: &MoveError<'tcx>) { - let move_from_id = error.move_from.hir_id; - debug!("append_to_grouped_errors(move_from_id={:?})", move_from_id); - let move_to = if error.move_to.is_some() { - vec![error.move_to.clone().unwrap()] - } else { - Vec::new() - }; - for ge in &mut *grouped_errors { - if move_from_id == ge.move_from.hir_id && error.move_to.is_some() { - debug!("appending move_to to list"); - ge.move_to_places.extend(move_to); - return - } - } - debug!("found a new move from location"); - grouped_errors.push(GroupedMoveErrors { - move_from: error.move_from.clone(), - move_to_places: move_to - }) - } -} - -// (keep in sync with gather_moves::check_and_get_illegal_move_origin ) -fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>, - move_from: mc::cmt<'tcx>) - -> DiagnosticBuilder<'a> { - match move_from.cat { - Categorization::Deref(_, mc::BorrowedPtr(..)) | - Categorization::Deref(_, mc::UnsafePtr(..)) | - Categorization::Deref(_, mc::Unique) | - Categorization::ThreadLocal(..) | - Categorization::StaticItem => { - bccx.cannot_move_out_of( - move_from.span, &move_from.descriptive_string(bccx.tcx), Origin::Ast) - } - Categorization::Interior(ref b, mc::InteriorElement(ik)) => { - bccx.cannot_move_out_of_interior_noncopy( - move_from.span, b.ty, Some(ik == Kind::Index), Origin::Ast) - } - - Categorization::Downcast(ref b, _) | - Categorization::Interior(ref b, mc::InteriorField(_)) => { - match b.ty.sty { - ty::Adt(def, _) if def.has_dtor(bccx.tcx) => { - bccx.cannot_move_out_of_interior_of_drop( - move_from.span, b.ty, Origin::Ast) - } - _ => { - span_bug!(move_from.span, "this path should not cause illegal move"); - } - } - } - - Categorization::Rvalue(..) | - Categorization::Local(..) | - Categorization::Upvar(..) => { - span_bug!(move_from.span, "this path should not cause illegal move"); - } - } -} - -fn note_move_destination(mut err: DiagnosticBuilder<'_>, - move_to_span: syntax_pos::Span, - pat_name: ast::Name, - is_first_note: bool) -> DiagnosticBuilder<'_> { - if is_first_note { - err.span_label( - move_to_span, - format!("hint: to prevent move, use `ref {0}` or `ref mut {0}`", - pat_name)); - err - } else { - err.span_label(move_to_span, - format!("...and here (use `ref {0}` or `ref mut {0}`)", - pat_name)); - err - } -} diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs deleted file mode 100644 index 3c7f19f7fb..0000000000 --- a/src/librustc_borrowck/borrowck/mod.rs +++ /dev/null @@ -1,1573 +0,0 @@ -//! See The Book chapter on the borrow checker for more details. - -#![allow(non_camel_case_types)] - -pub use LoanPathKind::*; -pub use LoanPathElem::*; -pub use bckerr_code::*; -pub use AliasableViolationKind::*; -pub use MovedValueUseKind::*; - -use InteriorKind::*; - -use rustc::hir::HirId; -use rustc::hir::Node; -use rustc::hir::map::blocks::FnLikeNode; -use rustc::cfg; -use rustc::middle::borrowck::{BorrowCheckResult, SignalledError}; -use rustc::hir::def_id::{DefId, LocalDefId}; -use rustc::middle::expr_use_visitor as euv; -use rustc::middle::mem_categorization as mc; -use rustc::middle::mem_categorization::Categorization; -use rustc::middle::mem_categorization::ImmutabilityBlame; -use rustc::middle::region; -use rustc::middle::free_region::RegionRelations; -use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::query::Providers; -use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; -use rustc_mir::util::suggest_ref_mut; -use rustc::util::nodemap::FxHashSet; - -use std::borrow::Cow; -use std::cell::{Cell, RefCell}; -use std::fmt; -use std::rc::Rc; -use std::hash::{Hash, Hasher}; -use syntax::source_map::CompilerDesugaringKind; -use syntax_pos::{MultiSpan, Span}; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; -use log::debug; - -use rustc::hir; - -use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom}; - -pub mod check_loans; - -pub mod gather_loans; - -pub mod move_data; - -#[derive(Clone, Copy)] -pub struct LoanDataFlowOperator; - -pub type LoanDataFlow<'tcx> = DataFlowContext<'tcx, LoanDataFlowOperator>; - -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { - tcx.par_body_owners(|body_owner_def_id| { - tcx.ensure().borrowck(body_owner_def_id); - }); -} - -pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - borrowck, - ..*providers - }; -} - -/// Collection of conclusions determined via borrow checker analyses. -pub struct AnalysisData<'tcx> { - pub all_loans: Vec>, - pub loans: DataFlowContext<'tcx, LoanDataFlowOperator>, - pub move_data: move_data::FlowedMoveData<'tcx>, -} - -fn borrowck<'tcx>(tcx: TyCtxt<'tcx>, owner_def_id: DefId) -> &'tcx BorrowCheckResult { - assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck()); - - debug!("borrowck(body_owner_def_id={:?})", owner_def_id); - - let owner_id = tcx.hir().as_local_hir_id(owner_def_id).unwrap(); - - match tcx.hir().get(owner_id) { - Node::Ctor(..) => { - // We get invoked with anything that has MIR, but some of - // those things (notably the synthesized constructors from - // tuple structs/variants) do not have an associated body - // and do not need borrowchecking. - return tcx.arena.alloc(BorrowCheckResult { - used_mut_nodes: Default::default(), - signalled_any_error: SignalledError::NoErrorsSeen, - }) - } - _ => { } - } - - let body_id = tcx.hir().body_owned_by(owner_id); - let tables = tcx.typeck_tables_of(owner_def_id); - let region_scope_tree = tcx.region_scope_tree(owner_def_id); - let body = tcx.hir().body(body_id); - let mut bccx = BorrowckCtxt { - tcx, - tables, - region_scope_tree, - owner_def_id, - body, - used_mut_nodes: Default::default(), - signalled_any_error: Cell::new(SignalledError::NoErrorsSeen), - }; - - // Eventually, borrowck will always read the MIR, but at the - // moment we do not. So, for now, we always force MIR to be - // constructed for a given fn, since this may result in errors - // being reported and we want that to happen. - // - // Note that `mir_validated` is a "stealable" result; the - // thief, `optimized_mir()`, forces borrowck, so we know that - // is not yet stolen. - tcx.ensure().mir_validated(owner_def_id); - - // option dance because you can't capture an uninitialized variable - // by mut-ref. - let mut cfg = None; - if let Some(AnalysisData { all_loans, - loans: loan_dfcx, - move_data: flowed_moves }) = - build_borrowck_dataflow_data(&mut bccx, false, body_id, - |bccx| { - cfg = Some(cfg::CFG::new(bccx.tcx, &body)); - cfg.as_mut().unwrap() - }) - { - check_loans::check_loans(&mut bccx, &loan_dfcx, &flowed_moves, &all_loans, body); - } - - tcx.arena.alloc(BorrowCheckResult { - used_mut_nodes: bccx.used_mut_nodes.into_inner(), - signalled_any_error: bccx.signalled_any_error.into_inner(), - }) -} - -fn build_borrowck_dataflow_data<'a, 'c, 'tcx, F>( - this: &mut BorrowckCtxt<'a, 'tcx>, - force_analysis: bool, - body_id: hir::BodyId, - get_cfg: F, -) -> Option> -where - F: FnOnce(&mut BorrowckCtxt<'a, 'tcx>) -> &'c cfg::CFG, -{ - // Check the body of fn items. - let (all_loans, move_data) = - gather_loans::gather_loans_in_fn(this, body_id); - - if !force_analysis && move_data.is_empty() && all_loans.is_empty() { - // large arrays of data inserted as constants can take a lot of - // time and memory to borrow-check - see issue #36799. However, - // they don't have places, so no borrow-check is actually needed. - // Recognize that case and skip borrow-checking. - debug!("skipping loan propagation for {:?} because of no loans", body_id); - return None; - } else { - debug!("propagating loans in {:?}", body_id); - } - - let cfg = get_cfg(this); - let mut loan_dfcx = - DataFlowContext::new(this.tcx, - "borrowck", - Some(this.body), - cfg, - LoanDataFlowOperator, - all_loans.len()); - for (loan_idx, loan) in all_loans.iter().enumerate() { - loan_dfcx.add_gen(loan.gen_scope.item_local_id(), loan_idx); - loan_dfcx.add_kill(KillFrom::ScopeEnd, - loan.kill_scope.item_local_id(), - loan_idx); - } - loan_dfcx.add_kills_from_flow_exits(cfg); - loan_dfcx.propagate(cfg, this.body); - - let flowed_moves = move_data::FlowedMoveData::new(move_data, - this, - cfg, - this.body); - - Some(AnalysisData { all_loans, - loans: loan_dfcx, - move_data:flowed_moves }) -} - -/// Accessor for introspective clients inspecting `AnalysisData` and -/// the `BorrowckCtxt` itself , e.g., the flowgraph visualizer. -pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( - tcx: TyCtxt<'tcx>, - body_id: hir::BodyId, - cfg: &cfg::CFG, -) -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'tcx>) { - let owner_id = tcx.hir().body_owner(body_id); - let owner_def_id = tcx.hir().local_def_id_from_hir_id(owner_id); - let tables = tcx.typeck_tables_of(owner_def_id); - let region_scope_tree = tcx.region_scope_tree(owner_def_id); - let body = tcx.hir().body(body_id); - let mut bccx = BorrowckCtxt { - tcx, - tables, - region_scope_tree, - owner_def_id, - body, - used_mut_nodes: Default::default(), - signalled_any_error: Cell::new(SignalledError::NoErrorsSeen), - }; - - let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg); - (bccx, dataflow_data.unwrap()) -} - -// ---------------------------------------------------------------------- -// Type definitions - -pub struct BorrowckCtxt<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - - // tables for the current thing we are checking; set to - // Some in `borrowck_fn` and cleared later - tables: &'a ty::TypeckTables<'tcx>, - - region_scope_tree: &'tcx region::ScopeTree, - - owner_def_id: DefId, - - body: &'tcx hir::Body, - - used_mut_nodes: RefCell>, - - signalled_any_error: Cell, -} - -impl BorrowckCtxt<'_, 'tcx> { - fn signal_error(&self) { - self.signalled_any_error.set(SignalledError::SawSomeError); - } -} - -impl BorrowckErrors<'a> for &'a BorrowckCtxt<'_, 'tcx> { - fn struct_span_err_with_code>(self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> - { - self.tcx.sess.struct_span_err_with_code(sp, msg, code) - } - - fn struct_span_err>(self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> - { - self.tcx.sess.struct_span_err(sp, msg) - } - - fn cancel_if_wrong_origin(self, - mut diag: DiagnosticBuilder<'a>, - o: Origin) - -> DiagnosticBuilder<'a> - { - if !o.should_emit_errors(self.tcx.borrowck_mode()) { - self.tcx.sess.diagnostic().cancel(&mut diag); - } - diag - } -} - -/////////////////////////////////////////////////////////////////////////// -// Loans and loan paths - -/// Record of a loan that was issued. -pub struct Loan<'tcx> { - index: usize, - loan_path: Rc>, - kind: ty::BorrowKind, - restricted_paths: Vec>>, - - /// gen_scope indicates where loan is introduced. Typically the - /// loan is introduced at the point of the borrow, but in some - /// cases, notably method arguments, the loan may be introduced - /// only later, once it comes into scope. See also - /// `GatherLoanCtxt::compute_gen_scope`. - gen_scope: region::Scope, - - /// kill_scope indicates when the loan goes out of scope. This is - /// either when the lifetime expires or when the local variable - /// which roots the loan-path goes out of scope, whichever happens - /// faster. See also `GatherLoanCtxt::compute_kill_scope`. - kill_scope: region::Scope, - span: Span, - cause: euv::LoanCause, -} - -impl<'tcx> Loan<'tcx> { - pub fn loan_path(&self) -> Rc> { - self.loan_path.clone() - } -} - -#[derive(Eq)] -pub struct LoanPath<'tcx> { - kind: LoanPathKind<'tcx>, - ty: Ty<'tcx>, -} - -impl<'tcx> PartialEq for LoanPath<'tcx> { - fn eq(&self, that: &LoanPath<'tcx>) -> bool { - self.kind == that.kind - } -} - -impl<'tcx> Hash for LoanPath<'tcx> { - fn hash(&self, state: &mut H) { - self.kind.hash(state); - } -} - -#[derive(PartialEq, Eq, Hash, Debug)] -pub enum LoanPathKind<'tcx> { - LpVar(hir::HirId), // `x` in README.md - LpUpvar(ty::UpvarId), // `x` captured by-value into closure - LpDowncast(Rc>, DefId), // `x` downcast to particular enum variant - LpExtend(Rc>, mc::MutabilityCategory, LoanPathElem<'tcx>) -} - -impl<'tcx> LoanPath<'tcx> { - fn new(kind: LoanPathKind<'tcx>, ty: Ty<'tcx>) -> LoanPath<'tcx> { - LoanPath { kind: kind, ty: ty } - } - - fn to_type(&self) -> Ty<'tcx> { self.ty } - - fn has_downcast(&self) -> bool { - match self.kind { - LpDowncast(_, _) => true, - LpExtend(ref lp, _, LpInterior(_, _)) => { - lp.has_downcast() - } - _ => false, - } - } -} - -// FIXME (pnkfelix): See discussion here -// https://github.com/pnkfelix/rust/commit/ -// b2b39e8700e37ad32b486b9a8409b50a8a53aa51#commitcomment-7892003 -const DOWNCAST_PRINTED_OPERATOR: &'static str = " as "; - -// A local, "cleaned" version of `mc::InteriorKind` that drops -// information that is not relevant to loan-path analysis. (In -// particular, the distinction between how precisely an array-element -// is tracked is irrelevant here.) -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub enum InteriorKind { - InteriorField(mc::FieldIndex), - InteriorElement, -} - -trait ToInteriorKind { fn cleaned(self) -> InteriorKind; } -impl ToInteriorKind for mc::InteriorKind { - fn cleaned(self) -> InteriorKind { - match self { - mc::InteriorField(name) => InteriorField(name), - mc::InteriorElement(_) => InteriorElement, - } - } -} - -// This can be: -// - a pointer dereference (`*P` in README.md) -// - a field reference, with an optional definition of the containing -// enum variant (`P.f` in README.md) -// `DefId` is present when the field is part of struct that is in -// a variant of an enum. For instance in: -// `enum E { X { foo: u32 }, Y { foo: u32 }}` -// each `foo` is qualified by the definitition id of the variant (`X` or `Y`). -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub enum LoanPathElem<'tcx> { - LpDeref(mc::PointerKind<'tcx>), - LpInterior(Option, InteriorKind), -} - -fn closure_to_block(closure_id: LocalDefId, tcx: TyCtxt<'_>) -> HirId { - let closure_id = tcx.hir().local_def_id_to_hir_id(closure_id); - match tcx.hir().get(closure_id) { - Node::Expr(expr) => match expr.node { - hir::ExprKind::Closure(.., body_id, _, _) => { - body_id.hir_id - } - _ => { - bug!("encountered non-closure id: {}", closure_id) - } - }, - _ => bug!("encountered non-expr id: {}", closure_id) - } -} - -impl LoanPath<'tcx> { - pub fn kill_scope(&self, bccx: &BorrowckCtxt<'_, 'tcx>) -> region::Scope { - match self.kind { - LpVar(hir_id) => { - bccx.region_scope_tree.var_scope(hir_id.local_id) - } - LpUpvar(upvar_id) => { - let block_id = closure_to_block(upvar_id.closure_expr_id, bccx.tcx); - region::Scope { id: block_id.local_id, data: region::ScopeData::Node } - } - LpDowncast(ref base, _) | - LpExtend(ref base, ..) => base.kill_scope(bccx), - } - } - - fn has_fork(&self, other: &LoanPath<'tcx>) -> bool { - match (&self.kind, &other.kind) { - (&LpExtend(ref base, _, LpInterior(opt_variant_id, id)), - &LpExtend(ref base2, _, LpInterior(opt_variant_id2, id2))) => - if id == id2 && opt_variant_id == opt_variant_id2 { - base.has_fork(&base2) - } else { - true - }, - (&LpExtend(ref base, _, LpDeref(_)), _) => base.has_fork(other), - (_, &LpExtend(ref base, _, LpDeref(_))) => self.has_fork(&base), - _ => false, - } - } - - fn depth(&self) -> usize { - match self.kind { - LpExtend(ref base, _, LpDeref(_)) => base.depth(), - LpExtend(ref base, _, LpInterior(..)) => base.depth() + 1, - _ => 0, - } - } - - fn common(&self, other: &LoanPath<'tcx>) -> Option> { - match (&self.kind, &other.kind) { - (&LpExtend(ref base, a, LpInterior(opt_variant_id, id)), - &LpExtend(ref base2, _, LpInterior(opt_variant_id2, id2))) => { - if id == id2 && opt_variant_id == opt_variant_id2 { - base.common(&base2).map(|x| { - let xd = x.depth(); - if base.depth() == xd && base2.depth() == xd { - LoanPath { - kind: LpExtend(Rc::new(x), a, LpInterior(opt_variant_id, id)), - ty: self.ty, - } - } else { - x - } - }) - } else { - base.common(&base2) - } - } - (&LpExtend(ref base, _, LpDeref(_)), _) => base.common(other), - (_, &LpExtend(ref other, _, LpDeref(_))) => self.common(&other), - (&LpVar(id), &LpVar(id2)) => { - if id == id2 { - Some(LoanPath { kind: LpVar(id), ty: self.ty }) - } else { - None - } - } - (&LpUpvar(id), &LpUpvar(id2)) => { - if id == id2 { - Some(LoanPath { kind: LpUpvar(id), ty: self.ty }) - } else { - None - } - } - _ => None, - } - } -} - -// Avoid "cannot borrow immutable field `self.x` as mutable" as that implies that a field *can* be -// mutable independently of the struct it belongs to. (#35937) -pub fn opt_loan_path_is_field<'tcx>(cmt: &mc::cmt_<'tcx>) -> (Option>>, bool) { - let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty)); - - match cmt.cat { - Categorization::Rvalue(..) | - Categorization::ThreadLocal(..) | - Categorization::StaticItem => { - (None, false) - } - - Categorization::Local(id) => { - (Some(new_lp(LpVar(id))), false) - } - - Categorization::Upvar(mc::Upvar { id, .. }) => { - (Some(new_lp(LpUpvar(id))), false) - } - - Categorization::Deref(ref cmt_base, pk) => { - let lp = opt_loan_path_is_field(cmt_base); - (lp.0.map(|lp| { - new_lp(LpExtend(lp, cmt.mutbl, LpDeref(pk))) - }), lp.1) - } - - Categorization::Interior(ref cmt_base, ik) => { - (opt_loan_path(cmt_base).map(|lp| { - let opt_variant_id = match cmt_base.cat { - Categorization::Downcast(_, did) => Some(did), - _ => None - }; - new_lp(LpExtend(lp, cmt.mutbl, LpInterior(opt_variant_id, ik.cleaned()))) - }), true) - } - - Categorization::Downcast(ref cmt_base, variant_def_id) => { - let lp = opt_loan_path_is_field(cmt_base); - (lp.0.map(|lp| { - new_lp(LpDowncast(lp, variant_def_id)) - }), lp.1) - } - } -} - -/// Computes the `LoanPath` (if any) for a `cmt`. -/// Note that this logic is somewhat duplicated in -/// the method `compute()` found in `gather_loans::restrictions`, -/// which allows it to share common loan path pieces as it -/// traverses the CMT. -pub fn opt_loan_path<'tcx>(cmt: &mc::cmt_<'tcx>) -> Option>> { - opt_loan_path_is_field(cmt).0 -} - -/////////////////////////////////////////////////////////////////////////// -// Errors - -// Errors that can occur -#[derive(Debug, PartialEq)] -pub enum bckerr_code<'tcx> { - err_mutbl, - /// superscope, subscope, loan cause - err_out_of_scope(ty::Region<'tcx>, ty::Region<'tcx>, euv::LoanCause), - err_borrowed_pointer_too_short(ty::Region<'tcx>, ty::Region<'tcx>), // loan, ptr -} - -// Combination of an error code and the categorization of the expression -// that caused it -#[derive(Debug, PartialEq)] -pub struct BckError<'c, 'tcx> { - span: Span, - cause: AliasableViolationKind, - cmt: &'c mc::cmt_<'tcx>, - code: bckerr_code<'tcx> -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum AliasableViolationKind { - MutabilityViolation, - BorrowViolation(euv::LoanCause) -} - -#[derive(Copy, Clone, Debug)] -pub enum MovedValueUseKind { - MovedInUse, - MovedInCapture, -} - -/////////////////////////////////////////////////////////////////////////// -// Misc - -impl BorrowckCtxt<'_, 'tcx> { - pub fn is_subregion_of(&self, - r_sub: ty::Region<'tcx>, - r_sup: ty::Region<'tcx>) - -> bool - { - let region_rels = RegionRelations::new(self.tcx, - self.owner_def_id, - &self.region_scope_tree, - &self.tables.free_region_map); - region_rels.is_subregion_of(r_sub, r_sup) - } - - pub fn report(&self, err: BckError<'a, 'tcx>) { - // Catch and handle some particular cases. - match (&err.code, &err.cause) { - (&err_out_of_scope(&ty::ReScope(_), &ty::ReStatic, _), - &BorrowViolation(euv::ClosureCapture(span))) | - (&err_out_of_scope(&ty::ReScope(_), &ty::ReEarlyBound(..), _), - &BorrowViolation(euv::ClosureCapture(span))) | - (&err_out_of_scope(&ty::ReScope(_), &ty::ReFree(..), _), - &BorrowViolation(euv::ClosureCapture(span))) => { - return self.report_out_of_scope_escaping_closure_capture(&err, span); - } - _ => { } - } - - self.report_bckerr(&err); - } - - pub fn report_use_of_moved_value(&self, - use_span: Span, - use_kind: MovedValueUseKind, - lp: &LoanPath<'tcx>, - the_move: &move_data::Move, - moved_lp: &LoanPath<'tcx>) { - let (verb, verb_participle) = match use_kind { - MovedInUse => ("use", "used"), - MovedInCapture => ("capture", "captured"), - }; - - let (_ol, _moved_lp_msg, mut err, need_note) = match the_move.kind { - move_data::Declared => { - // If this is an uninitialized variable, just emit a simple warning - // and return. - self.cannot_act_on_uninitialized_variable(use_span, - verb, - &self.loan_path_to_string(lp), - Origin::Ast) - .span_label(use_span, format!("use of possibly uninitialized `{}`", - self.loan_path_to_string(lp))) - .emit(); - self.signal_error(); - return; - } - _ => { - // If moved_lp is something like `x.a`, and lp is something like `x.b`, we would - // normally generate a rather confusing message: - // - // error: use of moved value: `x.b` - // note: `x.a` moved here... - // - // What we want to do instead is get the 'common ancestor' of the two moves and - // use that for most of the message instead, giving is something like this: - // - // error: use of moved value: `x` - // note: `x` moved here (through moving `x.a`)... - - let common = moved_lp.common(lp); - let has_common = common.is_some(); - let has_fork = moved_lp.has_fork(lp); - let (nl, ol, moved_lp_msg) = - if has_fork && has_common { - let nl = self.loan_path_to_string(&common.unwrap()); - let ol = nl.clone(); - let moved_lp_msg = format!(" (through moving `{}`)", - self.loan_path_to_string(moved_lp)); - (nl, ol, moved_lp_msg) - } else { - (self.loan_path_to_string(lp), - self.loan_path_to_string(moved_lp), - String::new()) - }; - - let partial = moved_lp.depth() > lp.depth(); - let msg = if !has_fork && partial { "partially " } - else if has_fork && !has_common { "collaterally "} - else { "" }; - let mut err = self.cannot_act_on_moved_value(use_span, - verb, - msg, - Some(nl), - Origin::Ast); - let need_note = match lp.ty.sty { - ty::Closure(id, _) => { - let hir_id = self.tcx.hir().as_local_hir_id(id).unwrap(); - if let Some((span, name)) = self.tables.closure_kind_origins().get(hir_id) { - err.span_note(*span, &format!( - "closure cannot be invoked more than once because \ - it moves the variable `{}` out of its environment", - name - )); - false - } else { - true - } - } - _ => true, - }; - (ol, moved_lp_msg, err, need_note) - } - }; - - // Get type of value and span where it was previously - // moved. - let hir_id = hir::HirId { - owner: self.body.value.hir_id.owner, - local_id: the_move.id - }; - let (move_span, move_note) = match the_move.kind { - move_data::Declared => { - unreachable!(); - } - - move_data::MoveExpr | - move_data::MovePat => (self.tcx.hir().span(hir_id), ""), - - move_data::Captured => - (match self.tcx.hir().expect_expr(hir_id).node { - hir::ExprKind::Closure(.., fn_decl_span, _) => fn_decl_span, - ref r => bug!("Captured({:?}) maps to non-closure: {:?}", - the_move.id, r), - }, " (into closure)"), - }; - - // Annotate the use and the move in the span. Watch out for - // the case where the use and the move are the same. This - // means the use is in a loop. - err = if use_span == move_span { - err.span_label( - use_span, - format!("value moved{} here in previous iteration of loop", - move_note)); - err - } else { - err.span_label(use_span, format!("value {} here after move", verb_participle)); - err.span_label(move_span, format!("value moved{} here", move_note)); - err - }; - - if need_note { - err.note(&format!( - "move occurs because {} has type `{}`, which does not implement the `Copy` trait", - if moved_lp.has_downcast() { - "the value".to_string() - } else { - format!("`{}`", self.loan_path_to_string(moved_lp)) - }, - moved_lp.ty)); - } - if let (Some(CompilerDesugaringKind::ForLoop), Ok(snippet)) = ( - move_span.compiler_desugaring_kind(), - self.tcx.sess.source_map().span_to_snippet(move_span), - ) { - if !snippet.starts_with("&") { - err.span_suggestion( - move_span, - "consider borrowing this to avoid moving it into the for loop", - format!("&{}", snippet), - Applicability::MaybeIncorrect, - ); - } - } - - // Note: we used to suggest adding a `ref binding` or calling - // `clone` but those suggestions have been removed because - // they are often not what you actually want to do, and were - // not considered particularly helpful. - - err.emit(); - self.signal_error(); - } - - pub fn report_partial_reinitialization_of_uninitialized_structure( - &self, - span: Span, - lp: &LoanPath<'tcx>) { - self.cannot_partially_reinit_an_uninit_struct(span, - &self.loan_path_to_string(lp), - Origin::Ast) - .emit(); - self.signal_error(); - } - - pub fn report_reassigned_immutable_variable(&self, - span: Span, - lp: &LoanPath<'tcx>, - assign: - &move_data::Assignment) { - let mut err = self.cannot_reassign_immutable(span, - &self.loan_path_to_string(lp), - false, - Origin::Ast); - err.span_label(span, "cannot assign twice to immutable variable"); - if span != assign.span { - err.span_label(assign.span, format!("first assignment to `{}`", - self.loan_path_to_string(lp))); - } - err.emit(); - self.signal_error(); - } - - fn report_bckerr(&self, err: &BckError<'a, 'tcx>) { - let error_span = err.span.clone(); - - match err.code { - err_mutbl => { - let descr: Cow<'static, str> = match err.cmt.note { - mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => { - self.cmt_to_cow_str(&err.cmt) - } - _ => match opt_loan_path_is_field(&err.cmt) { - (None, true) => { - format!("{} of {} binding", - self.cmt_to_cow_str(&err.cmt), - err.cmt.mutbl.to_user_str()).into() - - } - (None, false) => { - format!("{} {}", - err.cmt.mutbl.to_user_str(), - self.cmt_to_cow_str(&err.cmt)).into() - - } - (Some(lp), true) => { - format!("{} `{}` of {} binding", - self.cmt_to_cow_str(&err.cmt), - self.loan_path_to_string(&lp), - err.cmt.mutbl.to_user_str()).into() - } - (Some(lp), false) => { - format!("{} {} `{}`", - err.cmt.mutbl.to_user_str(), - self.cmt_to_cow_str(&err.cmt), - self.loan_path_to_string(&lp)).into() - } - } - }; - - let mut db = match err.cause { - MutabilityViolation => { - let mut db = self.cannot_assign(error_span, &descr, Origin::Ast); - if let mc::NoteClosureEnv(upvar_id) = err.cmt.note { - let hir_id = upvar_id.var_path.hir_id; - let sp = self.tcx.hir().span(hir_id); - let fn_closure_msg = "`Fn` closures cannot capture their enclosing \ - environment for modifications"; - match (self.tcx.sess.source_map().span_to_snippet(sp), &err.cmt.cat) { - (_, &Categorization::Upvar(mc::Upvar { - kind: ty::ClosureKind::Fn, .. - })) => { - db.note(fn_closure_msg); - // we should point at the cause for this closure being - // identified as `Fn` (like in signature of method this - // closure was passed into) - } - (Ok(ref snippet), ref cat) => { - let msg = &format!("consider making `{}` mutable", snippet); - let suggestion = format!("mut {}", snippet); - - if let &Categorization::Deref(ref cmt, _) = cat { - if let Categorization::Upvar(mc::Upvar { - kind: ty::ClosureKind::Fn, .. - }) = cmt.cat { - db.note(fn_closure_msg); - } else { - db.span_suggestion( - sp, - msg, - suggestion, - Applicability::Unspecified, - ); - } - } else { - db.span_suggestion( - sp, - msg, - suggestion, - Applicability::Unspecified, - ); - } - } - _ => { - db.span_help(sp, "consider making this binding mutable"); - } - } - } - - db - } - BorrowViolation(euv::ClosureCapture(_)) => { - self.closure_cannot_assign_to_borrowed(error_span, &descr, Origin::Ast) - } - BorrowViolation(euv::OverloadedOperator) | - BorrowViolation(euv::AddrOf) | - BorrowViolation(euv::RefBinding) | - BorrowViolation(euv::AutoRef) | - BorrowViolation(euv::AutoUnsafe) | - BorrowViolation(euv::ForLoop) | - BorrowViolation(euv::MatchDiscriminant) => { - self.cannot_borrow_path_as_mutable(error_span, &descr, Origin::Ast) - } - BorrowViolation(euv::ClosureInvocation) => { - span_bug!(err.span, "err_mutbl with a closure invocation"); - } - }; - - // We add a special note about `IndexMut`, if the source of this error - // is the fact that `Index` is implemented, but `IndexMut` is not. Needing - // to implement two traits for "one operator" is not very intuitive for - // many programmers. - if err.cmt.note == mc::NoteIndex { - let node = self.tcx.hir().get(err.cmt.hir_id); - - // This pattern probably always matches. - if let Node::Expr( - hir::Expr { node: hir::ExprKind::Index(lhs, _), ..} - ) = node { - let ty = self.tables.expr_ty(lhs); - - db.help(&format!( - "trait `IndexMut` is required to modify indexed content, but \ - it is not implemented for `{}`", - ty - )); - } - } - - self.note_and_explain_mutbl_error(&mut db, &err, &error_span); - self.note_immutability_blame( - &mut db, - err.cmt.immutability_blame(), - err.cmt.hir_id - ); - db.emit(); - self.signal_error(); - } - err_out_of_scope(super_scope, sub_scope, cause) => { - let msg = match opt_loan_path(&err.cmt) { - None => "borrowed value".to_string(), - Some(lp) => { - format!("`{}`", self.loan_path_to_string(&lp)) - } - }; - - let mut db = self.path_does_not_live_long_enough(error_span, &msg, Origin::Ast); - let value_kind = match err.cmt.cat { - mc::Categorization::Rvalue(..) => "temporary value", - _ => "borrowed value", - }; - - let is_closure = match cause { - euv::ClosureCapture(s) => { - // The primary span starts out as the closure creation point. - // Change the primary span here to highlight the use of the variable - // in the closure, because it seems more natural. Highlight - // closure creation point as a secondary span. - match db.span.primary_span() { - Some(primary) => { - db.span = MultiSpan::from_span(s); - db.span_label(primary, "capture occurs here"); - db.span_label(s, format!("{} does not live long enough", - value_kind)); - true - } - None => false - } - } - _ => { - db.span_label(error_span, format!("{} does not live long enough", - value_kind)); - false - } - }; - - let sub_span = self.region_end_span(sub_scope); - let super_span = self.region_end_span(super_scope); - - match (sub_span, super_span) { - (Some(s1), Some(s2)) if s1 == s2 => { - if !is_closure { - let msg = match opt_loan_path(&err.cmt) { - None => value_kind.to_string(), - Some(lp) => { - format!("`{}`", self.loan_path_to_string(&lp)) - } - }; - db.span_label(s1, - format!("{} dropped here while still borrowed", msg)); - } else { - db.span_label(s1, format!("{} dropped before borrower", value_kind)); - } - db.note("values in a scope are dropped in the opposite order \ - they are created"); - } - (Some(s1), Some(s2)) if !is_closure => { - let msg = match opt_loan_path(&err.cmt) { - None => value_kind.to_string(), - Some(lp) => { - format!("`{}`", self.loan_path_to_string(&lp)) - } - }; - db.span_label(s2, format!("{} dropped here while still borrowed", msg)); - db.span_label(s1, format!("{} needs to live until here", value_kind)); - } - _ => { - match sub_span { - Some(s) => { - db.span_label(s, format!("{} needs to live until here", - value_kind)); - } - None => { - self.tcx.note_and_explain_region( - &self.region_scope_tree, - &mut db, - "borrowed value must be valid for ", - sub_scope, - "..."); - } - } - match super_span { - Some(s) => { - db.span_label(s, format!("{} only lives until here", value_kind)); - } - None => { - self.tcx.note_and_explain_region( - &self.region_scope_tree, - &mut db, - "...but borrowed value is only valid for ", - super_scope, - ""); - } - } - } - } - - if let ty::ReScope(scope) = *super_scope { - let hir_id = scope.hir_id(&self.region_scope_tree); - match self.tcx.hir().find(hir_id) { - Some(Node::Stmt(_)) => { - if *sub_scope != ty::ReStatic { - db.note("consider using a `let` binding to increase its lifetime"); - } - - } - _ => {} - } - } - - db.emit(); - self.signal_error(); - } - err_borrowed_pointer_too_short(loan_scope, ptr_scope) => { - let descr = self.cmt_to_path_or_string(err.cmt); - let mut db = self.lifetime_too_short_for_reborrow(error_span, &descr, Origin::Ast); - let descr: Cow<'static, str> = match opt_loan_path(&err.cmt) { - Some(lp) => { - format!("`{}`", self.loan_path_to_string(&lp)).into() - } - None => self.cmt_to_cow_str(&err.cmt) - }; - self.tcx.note_and_explain_region( - &self.region_scope_tree, - &mut db, - &format!("{} would have to be valid for ", - descr), - loan_scope, - "..."); - self.tcx.note_and_explain_region( - &self.region_scope_tree, - &mut db, - &format!("...but {} is only valid for ", descr), - ptr_scope, - ""); - - db.emit(); - self.signal_error(); - } - } - } - - pub fn report_aliasability_violation(&self, - span: Span, - kind: AliasableViolationKind, - cause: mc::AliasableReason, - cmt: &mc::cmt_<'tcx>) { - let mut is_closure = false; - let prefix = match kind { - MutabilityViolation => { - "cannot assign to data" - } - BorrowViolation(euv::ClosureCapture(_)) | - BorrowViolation(euv::OverloadedOperator) | - BorrowViolation(euv::AddrOf) | - BorrowViolation(euv::AutoRef) | - BorrowViolation(euv::AutoUnsafe) | - BorrowViolation(euv::RefBinding) | - BorrowViolation(euv::MatchDiscriminant) => { - "cannot borrow data mutably" - } - BorrowViolation(euv::ClosureInvocation) => { - is_closure = true; - "closure invocation" - } - - BorrowViolation(euv::ForLoop) => { - "`for` loop" - } - }; - - match cause { - mc::AliasableStaticMut => { - // This path cannot occur. `static mut X` is not checked - // for aliasability violations. - span_bug!(span, "aliasability violation for static mut `{}`", prefix) - } - mc::AliasableStatic | mc::AliasableBorrowed => {} - }; - let blame = cmt.immutability_blame(); - let mut err = match blame { - Some(ImmutabilityBlame::ClosureEnv(id)) => { - // FIXME: the distinction between these 2 messages looks wrong. - let help_msg = if let BorrowViolation(euv::ClosureCapture(_)) = kind { - // The aliasability violation with closure captures can - // happen for nested closures, so we know the enclosing - // closure incorrectly accepts an `Fn` while it needs to - // be `FnMut`. - "consider changing this to accept closures that implement `FnMut`" - - } else { - "consider changing this closure to take self by mutable reference" - }; - let hir_id = self.tcx.hir().local_def_id_to_hir_id(id); - let help_span = self.tcx.hir().span(hir_id); - self.cannot_act_on_capture_in_sharable_fn(span, - prefix, - (help_span, help_msg), - Origin::Ast) - } - _ => { - self.cannot_assign_into_immutable_reference(span, prefix, - Origin::Ast) - } - }; - self.note_immutability_blame( - &mut err, - blame, - cmt.hir_id - ); - - if is_closure { - err.help("closures behind references must be called via `&mut`"); - } - err.emit(); - self.signal_error(); - } - - /// Given a type, if it is an immutable reference, return a suggestion to make it mutable - fn suggest_mut_for_immutable(&self, pty: &hir::Ty, is_implicit_self: bool) -> Option { - // Check whether the argument is an immutable reference - debug!("suggest_mut_for_immutable({:?}, {:?})", pty, is_implicit_self); - if let hir::TyKind::Rptr(lifetime, hir::MutTy { - mutbl: hir::Mutability::MutImmutable, - ref ty - }) = pty.node { - // Account for existing lifetimes when generating the message - let pointee_snippet = match self.tcx.sess.source_map().span_to_snippet(ty.span) { - Ok(snippet) => snippet, - _ => return None - }; - - let lifetime_snippet = if !lifetime.is_elided() { - format!("{} ", match self.tcx.sess.source_map().span_to_snippet(lifetime.span) { - Ok(lifetime_snippet) => lifetime_snippet, - _ => return None - }) - } else { - String::new() - }; - Some(format!("use `&{}mut {}` here to make mutable", - lifetime_snippet, - if is_implicit_self { "self" } else { &*pointee_snippet })) - } else { - None - } - } - - fn local_binding_mode(&self, hir_id: hir::HirId) -> ty::BindingMode { - let pat = match self.tcx.hir().get(hir_id) { - Node::Binding(pat) => pat, - node => bug!("bad node for local: {:?}", node) - }; - - match pat.node { - hir::PatKind::Binding(..) => { - *self.tables - .pat_binding_modes() - .get(pat.hir_id) - .expect("missing binding mode") - } - _ => bug!("local is not a binding: {:?}", pat) - } - } - - fn local_ty(&self, hir_id: hir::HirId) -> (Option<&hir::Ty>, bool) { - let parent = self.tcx.hir().get_parent_node(hir_id); - let parent_node = self.tcx.hir().get(parent); - - // The parent node is like a fn - if let Some(fn_like) = FnLikeNode::from_node(parent_node) { - // `nid`'s parent's `Body` - let fn_body = self.tcx.hir().body(fn_like.body()); - // Get the position of `node_id` in the arguments list - let arg_pos = fn_body.arguments.iter().position(|arg| arg.pat.hir_id == hir_id); - if let Some(i) = arg_pos { - // The argument's `Ty` - (Some(&fn_like.decl().inputs[i]), - i == 0 && fn_like.decl().implicit_self.has_implicit_self()) - } else { - (None, false) - } - } else { - (None, false) - } - } - - fn note_immutability_blame(&self, - db: &mut DiagnosticBuilder<'_>, - blame: Option>, - error_hir_id: hir::HirId) { - match blame { - None => {} - Some(ImmutabilityBlame::ClosureEnv(_)) => {} - Some(ImmutabilityBlame::ImmLocal(hir_id)) => { - self.note_immutable_local(db, error_hir_id, hir_id) - } - Some(ImmutabilityBlame::LocalDeref(hir_id)) => { - match self.local_binding_mode(hir_id) { - ty::BindByReference(..) => { - let let_span = self.tcx.hir().span(hir_id); - let suggestion = suggest_ref_mut(self.tcx, let_span); - if let Some(replace_str) = suggestion { - db.span_suggestion( - let_span, - "use a mutable reference instead", - replace_str, - // I believe this can be machine applicable, - // but if there are multiple attempted uses of an immutable - // reference, I don't know how rustfix handles it, it might - // attempt fixing them multiple times. - // @estebank - Applicability::Unspecified, - ); - } - } - ty::BindByValue(..) => { - if let (Some(local_ty), is_implicit_self) = self.local_ty(hir_id) { - if let Some(msg) = - self.suggest_mut_for_immutable(local_ty, is_implicit_self) { - db.span_label(local_ty.span, msg); - } - } - } - } - } - Some(ImmutabilityBlame::AdtFieldDeref(_, field)) => { - let hir_id = match self.tcx.hir().as_local_hir_id(field.did) { - Some(hir_id) => hir_id, - None => return - }; - - if let Node::Field(ref field) = self.tcx.hir().get(hir_id) { - if let Some(msg) = self.suggest_mut_for_immutable(&field.ty, false) { - db.span_label(field.ty.span, msg); - } - } - } - } - } - - // Suggest a fix when trying to mutably borrow an immutable local - // binding: either to make the binding mutable (if its type is - // not a mutable reference) or to avoid borrowing altogether - fn note_immutable_local(&self, - db: &mut DiagnosticBuilder<'_>, - borrowed_hir_id: hir::HirId, - binding_hir_id: hir::HirId) { - let let_span = self.tcx.hir().span(binding_hir_id); - if let ty::BindByValue(..) = self.local_binding_mode(binding_hir_id) { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(let_span) { - let (ty, is_implicit_self) = self.local_ty(binding_hir_id); - if is_implicit_self && snippet != "self" { - // avoid suggesting `mut &self`. - return - } - if let Some(&hir::TyKind::Rptr( - _, - hir::MutTy { - mutbl: hir::MutMutable, - .. - }, - )) = ty.map(|t| &t.node) - { - let borrow_expr_id = self.tcx.hir().get_parent_node(borrowed_hir_id); - db.span_suggestion( - self.tcx.hir().span(borrow_expr_id), - "consider removing the `&mut`, as it is an \ - immutable binding to a mutable reference", - snippet, - Applicability::MachineApplicable, - ); - } else { - db.span_suggestion( - let_span, - "make this binding mutable", - format!("mut {}", snippet), - Applicability::MachineApplicable, - ); - } - } - } - } - - fn report_out_of_scope_escaping_closure_capture(&self, - err: &BckError<'a, 'tcx>, - capture_span: Span) - { - let cmt_path_or_string = self.cmt_to_path_or_string(&err.cmt); - - let suggestion = - match self.tcx.sess.source_map().span_to_snippet(err.span) { - Ok(string) => format!("move {}", string), - Err(_) => "move || ".to_string() - }; - - self.cannot_capture_in_long_lived_closure(err.span, - &cmt_path_or_string, - capture_span, - Origin::Ast) - .span_suggestion( - err.span, - &format!("to force the closure to take ownership of {} \ - (and any other referenced variables), \ - use the `move` keyword", - cmt_path_or_string), - suggestion, - Applicability::MachineApplicable, - ) - .emit(); - self.signal_error(); - } - - fn region_end_span(&self, region: ty::Region<'tcx>) -> Option { - match *region { - ty::ReScope(scope) => { - Some(self.tcx.sess.source_map().end_point( - scope.span(self.tcx, &self.region_scope_tree))) - } - _ => None - } - } - - fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder<'_>, err: &BckError<'a, 'tcx>, - error_span: &Span) { - match err.cmt.note { - mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => { - // If this is an `Fn` closure, it simply can't mutate upvars. - // If it's an `FnMut` closure, the original variable was declared immutable. - // We need to determine which is the case here. - let kind = match err.cmt.upvar_cat().unwrap() { - Categorization::Upvar(mc::Upvar { kind, .. }) => kind, - _ => bug!() - }; - if *kind == ty::ClosureKind::Fn { - let closure_hir_id = - self.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id); - db.span_help(self.tcx.hir().span(closure_hir_id), - "consider changing this closure to take \ - self by mutable reference"); - } - } - _ => { - if let Categorization::Deref(..) = err.cmt.cat { - db.span_label(*error_span, "cannot borrow as mutable"); - } else if let Categorization::Local(local_id) = err.cmt.cat { - let span = self.tcx.hir().span(local_id); - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - if snippet.starts_with("ref mut ") || snippet.starts_with("&mut ") { - db.span_label(*error_span, "cannot reborrow mutably"); - db.span_label(*error_span, "try removing `&mut` here"); - } else { - db.span_label(*error_span, "cannot borrow mutably"); - } - } else { - db.span_label(*error_span, "cannot borrow mutably"); - } - } else if let Categorization::Interior(ref cmt, _) = err.cmt.cat { - if let mc::MutabilityCategory::McImmutable = cmt.mutbl { - db.span_label(*error_span, - "cannot mutably borrow field of immutable binding"); - } - } - } - } - } - pub fn append_loan_path_to_string(&self, - loan_path: &LoanPath<'tcx>, - out: &mut String) { - match loan_path.kind { - LpUpvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id: id }, closure_expr_id: _ }) => { - out.push_str(&self.tcx.hir().name(id).as_str()); - } - LpVar(id) => { - out.push_str(&self.tcx.hir().name(id).as_str()); - } - - LpDowncast(ref lp_base, variant_def_id) => { - out.push('('); - self.append_loan_path_to_string(&lp_base, out); - out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&self.tcx.def_path_str(variant_def_id)); - out.push(')'); - } - - LpExtend(ref lp_base, _, LpInterior(_, InteriorField(mc::FieldIndex(_, info)))) => { - self.append_autoderefd_loan_path_to_string(&lp_base, out); - out.push('.'); - out.push_str(&info.as_str()); - } - - LpExtend(ref lp_base, _, LpInterior(_, InteriorElement)) => { - self.append_autoderefd_loan_path_to_string(&lp_base, out); - out.push_str("[..]"); - } - - LpExtend(ref lp_base, _, LpDeref(_)) => { - out.push('*'); - self.append_loan_path_to_string(&lp_base, out); - } - } - } - - pub fn append_autoderefd_loan_path_to_string(&self, - loan_path: &LoanPath<'tcx>, - out: &mut String) { - match loan_path.kind { - LpExtend(ref lp_base, _, LpDeref(_)) => { - // For a path like `(*x).f` or `(*x)[3]`, autoderef - // rules would normally allow users to omit the `*x`. - // So just serialize such paths to `x.f` or x[3]` respectively. - self.append_autoderefd_loan_path_to_string(&lp_base, out) - } - - LpDowncast(ref lp_base, variant_def_id) => { - out.push('('); - self.append_autoderefd_loan_path_to_string(&lp_base, out); - out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&self.tcx.def_path_str(variant_def_id)); - out.push(')'); - } - - LpVar(..) | LpUpvar(..) | LpExtend(.., LpInterior(..)) => { - self.append_loan_path_to_string(loan_path, out) - } - } - } - - pub fn loan_path_to_string(&self, loan_path: &LoanPath<'tcx>) -> String { - let mut result = String::new(); - self.append_loan_path_to_string(loan_path, &mut result); - result - } - - pub fn cmt_to_cow_str(&self, cmt: &mc::cmt_<'tcx>) -> Cow<'static, str> { - cmt.descriptive_string(self.tcx) - } - - pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt_<'tcx>) -> String { - match opt_loan_path(cmt) { - Some(lp) => format!("`{}`", self.loan_path_to_string(&lp)), - None => self.cmt_to_cow_str(cmt).into_owned(), - } - } -} - -impl BitwiseOperator for LoanDataFlowOperator { - #[inline] - fn join(&self, succ: usize, pred: usize) -> usize { - succ | pred // loans from both preds are in scope - } -} - -impl DataFlowOperator for LoanDataFlowOperator { - #[inline] - fn initial_value(&self) -> bool { - false // no loans in scope by default - } -} - -impl fmt::Debug for InteriorKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - InteriorField(mc::FieldIndex(_, info)) => write!(f, "{}", info), - InteriorElement => write!(f, "[]"), - } - } -} - -impl<'tcx> fmt::Debug for Loan<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Loan_{}({:?}, {:?}, {:?}-{:?}, {:?})", - self.index, - self.loan_path, - self.kind, - self.gen_scope, - self.kill_scope, - self.restricted_paths) - } -} - -impl<'tcx> fmt::Debug for LoanPath<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - LpVar(id) => { - write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_string(id))) - } - - LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath {hir_id: var_id}, closure_expr_id }) => { - let s = ty::tls::with(|tcx| { - tcx.hir().node_to_string(var_id) - }); - write!(f, "$({} captured by id={:?})", s, closure_expr_id) - } - - LpDowncast(ref lp, variant_def_id) => { - let variant_str = if variant_def_id.is_local() { - ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) - } else { - format!("{:?}", variant_def_id) - }; - write!(f, "({:?}{}{})", lp, DOWNCAST_PRINTED_OPERATOR, variant_str) - } - - LpExtend(ref lp, _, LpDeref(_)) => { - write!(f, "{:?}.*", lp) - } - - LpExtend(ref lp, _, LpInterior(_, ref interior)) => { - write!(f, "{:?}.{:?}", lp, interior) - } - } - } -} - -impl<'tcx> fmt::Display for LoanPath<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - LpVar(id) => { - write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().hir_to_user_string(id))) - } - - LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => { - let s = ty::tls::with(|tcx| { - tcx.hir().node_to_string(hir_id) - }); - write!(f, "$({} captured by closure)", s) - } - - LpDowncast(ref lp, variant_def_id) => { - let variant_str = if variant_def_id.is_local() { - ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) - } else { - format!("{:?}", variant_def_id) - }; - write!(f, "({}{}{})", lp, DOWNCAST_PRINTED_OPERATOR, variant_str) - } - - LpExtend(ref lp, _, LpDeref(_)) => { - write!(f, "{}.*", lp) - } - - LpExtend(ref lp, _, LpInterior(_, ref interior)) => { - write!(f, "{}.{:?}", lp, interior) - } - } - } -} diff --git a/src/librustc_borrowck/error_codes.rs b/src/librustc_borrowck/error_codes.rs deleted file mode 100644 index 44d8a23fcb..0000000000 --- a/src/librustc_borrowck/error_codes.rs +++ /dev/null @@ -1 +0,0 @@ -#![allow(non_snake_case)] diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 4ae8303c76..5e1b0eafde 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -13,7 +13,7 @@ test = false [dependencies] cc = "1.0.1" # Used to locate MSVC num_cpus = "1.0" -rustc-demangle = "0.1.15" +tempfile = "3.0" rustc_llvm = { path = "../librustc_llvm" } memmap = "0.6" diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 38d4b7e3f9..ff87afe0c4 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -34,17 +34,17 @@ trait ArgAttributeExt { impl ArgAttributeExt for ArgAttribute { fn for_each_kind(&self, mut f: F) where F: FnMut(llvm::Attribute) { for_each_kind!(self, f, - ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) + NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) } } pub trait ArgAttributesExt { - fn apply_llfn(&self, idx: AttributePlace, llfn: &Value); - fn apply_callsite(&self, idx: AttributePlace, callsite: &Value); + fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>); + fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>); } impl ArgAttributesExt for ArgAttributes { - fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) { + fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -65,11 +65,14 @@ impl ArgAttributesExt for ArgAttributes { idx.as_uint(), align.bytes() as u32); } + if regular.contains(ArgAttribute::ByVal) { + llvm::LLVMRustAddByValAttr(llfn, idx.as_uint(), ty.unwrap()); + } regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn)); } } - fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) { + fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -90,6 +93,9 @@ impl ArgAttributesExt for ArgAttributes { idx.as_uint(), align.bytes() as u32); } + if regular.contains(ArgAttribute::ByVal) { + llvm::LLVMRustAddByValCallSiteAttr(callsite, idx.as_uint(), ty.unwrap()); + } regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite)); } } @@ -298,7 +304,7 @@ pub trait FnTypeLlvmExt<'tcx> { fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_cconv(&self) -> llvm::CallConv; - fn apply_attrs_llfn(&self, llfn: &'ll Value); + fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value); fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value); } @@ -384,51 +390,51 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn apply_attrs_llfn(&self, llfn: &'ll Value) { + fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) { let mut i = 0; - let mut apply = |attrs: &ArgAttributes| { - attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn); + let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| { + attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty); i += 1; }; match self.ret.mode { PassMode::Direct(ref attrs) => { - attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); + attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn, None); } - PassMode::Indirect(ref attrs, _) => apply(attrs), + PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(cx))), _ => {} } for arg in &self.args { if arg.pad.is_some() { - apply(&ArgAttributes::new()); + apply(&ArgAttributes::new(), None); } match arg.mode { PassMode::Ignore(_) => {} PassMode::Direct(ref attrs) | - PassMode::Indirect(ref attrs, None) => apply(attrs), + PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(cx))), PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { - apply(attrs); - apply(extra_attrs); + apply(attrs, None); + apply(extra_attrs, None); } PassMode::Pair(ref a, ref b) => { - apply(a); - apply(b); + apply(a, None); + apply(b, None); } - PassMode::Cast(_) => apply(&ArgAttributes::new()), + PassMode::Cast(_) => apply(&ArgAttributes::new(), None), } } } fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) { let mut i = 0; - let mut apply = |attrs: &ArgAttributes| { - attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); + let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| { + attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty); i += 1; }; match self.ret.mode { PassMode::Direct(ref attrs) => { - attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite); + attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite, None); } - PassMode::Indirect(ref attrs, _) => apply(attrs), + PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(bx))), _ => {} } if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi { @@ -446,21 +452,21 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } for arg in &self.args { if arg.pad.is_some() { - apply(&ArgAttributes::new()); + apply(&ArgAttributes::new(), None); } match arg.mode { PassMode::Ignore(_) => {} PassMode::Direct(ref attrs) | - PassMode::Indirect(ref attrs, None) => apply(attrs), + PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(bx))), PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { - apply(attrs); - apply(extra_attrs); + apply(attrs, None); + apply(extra_attrs, None); } PassMode::Pair(ref a, ref b) => { - apply(a); - apply(b); + apply(a, None); + apply(b, None); } - PassMode::Cast(_) => apply(&ArgAttributes::new()), + PassMode::Cast(_) => apply(&ArgAttributes::new(), None), } } diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs index 02a05fd110..5d43bf6ae2 100644 --- a/src/librustc_codegen_llvm/allocator.rs +++ b/src/librustc_codegen_llvm/allocator.rs @@ -2,9 +2,8 @@ use std::ffi::CString; use crate::attributes; use libc::c_uint; -use rustc::middle::allocator::AllocatorKind; use rustc::ty::TyCtxt; -use rustc_allocator::{ALLOCATOR_METHODS, AllocatorTy}; +use syntax::ext::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use crate::ModuleLlvm; use crate::llvm::{self, False, True}; diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index 81acc16b7a..9763d523a2 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -102,7 +102,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { let kind = llvm::LLVMGetMDKindIDInContext(self.llcx, key.as_ptr() as *const c_char, key.len() as c_uint); - let val: &'ll Value = self.const_i32(ia.ctxt.outer().as_u32() as i32); + let val: &'ll Value = self.const_i32(ia.ctxt.outer_expn().as_u32() as i32); llvm::LLVMSetMetadata(r, kind, llvm::LLVMMDNodeInContext(self.llcx, &val, 1)); @@ -146,7 +146,7 @@ fn inline_asm_call( unsafe { // Ask LLVM to verify that the constraints are well-formed. let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr()); - debug!("Constraint verification result: {:?}", constraints_ok); + debug!("constraint verification result: {:?}", constraints_ok); if constraints_ok { let v = llvm::LLVMRustInlineAsm( fty, diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 94abf1796d..33b50401b2 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -119,6 +119,29 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { const_cstr!("probe-stack"), const_cstr!("__rust_probestack")); } +fn translate_obsolete_target_features(feature: &str) -> &str { + const LLVM9_FEATURE_CHANGES: &[(&str, &str)] = &[ + ("+fp-only-sp", "-fp64"), + ("-fp-only-sp", "+fp64"), + ("+d16", "-d32"), + ("-d16", "+d32"), + ]; + if llvm_util::get_major_version() >= 9 { + for &(old, new) in LLVM9_FEATURE_CHANGES { + if feature == old { + return new; + } + } + } else { + for &(old, new) in LLVM9_FEATURE_CHANGES { + if feature == new { + return old; + } + } + } + feature +} + pub fn llvm_target_features(sess: &Session) -> impl Iterator { const RUSTC_SPECIFIC_FEATURES: &[&str] = &[ "crt-static", @@ -129,6 +152,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { sess.target.target.options.features.split(',') .chain(cmdline) .filter(|l| !l.is_empty()) + .map(translate_obsolete_target_features) } pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index e0e26e9af2..e3b7cb235c 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -36,11 +36,20 @@ enum Addition { name_in_archive: String, }, Archive { + path: PathBuf, archive: ArchiveRO, skip: Box bool>, }, } +impl Addition { + fn path(&self) -> &Path { + match self { + Addition::File { path, .. } | Addition::Archive { path, .. } => path, + } + } +} + fn is_relevant_child(c: &Child<'_>) -> bool { match c.name() { Some(name) => !name.contains("SYMDEF"), @@ -188,12 +197,16 @@ impl<'a> LlvmArchiveBuilder<'a> { -> io::Result<()> where F: FnMut(&str) -> bool + 'static { - let archive = match ArchiveRO::open(archive) { + let archive_ro = match ArchiveRO::open(archive) { Ok(ar) => ar, Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)), }; + if self.additions.iter().any(|ar| ar.path() == archive) { + return Ok(()) + } self.additions.push(Addition::Archive { - archive, + path: archive.to_path_buf(), + archive: archive_ro, skip: Box::new(skip), }); Ok(()) @@ -205,8 +218,8 @@ impl<'a> LlvmArchiveBuilder<'a> { } fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> { - let removals = mem::replace(&mut self.removals, Vec::new()); - let mut additions = mem::replace(&mut self.additions, Vec::new()); + let removals = mem::take(&mut self.removals); + let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); let mut members = Vec::new(); @@ -243,7 +256,7 @@ impl<'a> LlvmArchiveBuilder<'a> { strings.push(path); strings.push(name); } - Addition::Archive { archive, skip } => { + Addition::Archive { archive, skip, .. } => { for child in archive.iter() { let child = child.map_err(string_to_io_error)?; if !is_relevant_child(&child) { diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 5d3cc0c0a2..5ed08943fe 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -265,7 +265,7 @@ fn fat_lto(cgcx: &CodegenContext, // and we want to move everything to the same LLVM context. Currently the // way we know of to do that is to serialize them to a string and them parse // them later. Not great but hey, that's why it's "fat" LTO, right? - serialized_modules.extend(modules.into_iter().map(|module| { + let mut new_modules = modules.into_iter().map(|module| { match module { FatLTOInput::InMemory(module) => { let buffer = ModuleBuffer::new(module.module_llvm.llmod()); @@ -277,7 +277,10 @@ fn fat_lto(cgcx: &CodegenContext, (SerializedModule::Local(buffer), llmod_id) } } - })); + }).collect::>(); + // Sort the modules to ensure we produce deterministic results. + new_modules.sort_by(|module1, module2| module1.1.partial_cmp(&module2.1).unwrap()); + serialized_modules.extend(new_modules); serialized_modules.extend(cached_modules.into_iter().map(|(buffer, wp)| { (buffer, CString::new(wp.cgu_name).unwrap()) })); diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 3638730707..253110dcb3 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -239,9 +239,9 @@ impl<'a> Drop for DiagnosticHandlers<'a> { } } -unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext, - msg: &'b str, - cookie: c_uint) { +unsafe extern "C" fn report_inline_asm(cgcx: &CodegenContext, + msg: &str, + cookie: c_uint) { cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned()); } @@ -329,33 +329,55 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, let mpm = llvm::LLVMCreatePassManager(); { - // If we're verifying or linting, add them to the function pass - // manager. - let addpass = |pass_name: &str| { + let find_pass = |pass_name: &str| { let pass_name = SmallCStr::new(pass_name); - let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) { - Some(pass) => pass, - None => return false, - }; - let pass_manager = match llvm::LLVMRustPassKind(pass) { - llvm::PassKind::Function => &*fpm, - llvm::PassKind::Module => &*mpm, - llvm::PassKind::Other => { - diag_handler.err("Encountered LLVM pass kind we can't handle"); - return true - }, - }; - llvm::LLVMRustAddPass(pass_manager, pass); - true + llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) }; - if config.verify_llvm_ir { assert!(addpass("verify")); } + if config.verify_llvm_ir { + // Verification should run as the very first pass. + llvm::LLVMRustAddPass(fpm, find_pass("verify").unwrap()); + } + + let mut extra_passes = Vec::new(); + let mut have_name_anon_globals_pass = false; + + for pass_name in &config.passes { + if pass_name == "lint" { + // Linting should also be performed early, directly on the generated IR. + llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap()); + continue; + } + + if let Some(pass) = find_pass(pass_name) { + extra_passes.push(pass); + } else { + diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass_name)); + } + + if pass_name == "name-anon-globals" { + have_name_anon_globals_pass = true; + } + } + + for pass_name in &cgcx.plugin_passes { + if let Some(pass) = find_pass(pass_name) { + extra_passes.push(pass); + } else { + diag_handler.err(&format!("a plugin asked for LLVM pass \ + `{}` but LLVM does not \ + recognize it", pass_name)); + } + + if pass_name == "name-anon-globals" { + have_name_anon_globals_pass = true; + } + } // Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need // to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise // we'll get errors in LLVM. let using_thin_buffers = config.bitcode_needed(); - let mut have_name_anon_globals_pass = false; if !config.no_prepopulate_passes { llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod); llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod); @@ -364,34 +386,22 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal || (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled()); with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| { + llvm::LLVMRustAddLastExtensionPasses( + b, extra_passes.as_ptr(), extra_passes.len() as size_t); llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm); llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm); }); have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto; if using_thin_buffers && !prepare_for_thin_lto { - assert!(addpass("name-anon-globals")); - have_name_anon_globals_pass = true; - } - } - - for pass in &config.passes { - if !addpass(pass) { - diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass)); - } - if pass == "name-anon-globals" { + llvm::LLVMRustAddPass(mpm, find_pass("name-anon-globals").unwrap()); have_name_anon_globals_pass = true; } - } - - for pass in &cgcx.plugin_passes { - if !addpass(pass) { - diag_handler.err(&format!("a plugin asked for LLVM pass \ - `{}` but LLVM does not \ - recognize it", pass)); - } - if pass == "name-anon-globals" { - have_name_anon_globals_pass = true; + } else { + // If we don't use the standard pipeline, directly populate the MPM + // with the extra passes. + for pass in extra_passes { + llvm::LLVMRustAddPass(mpm, pass); } } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 04645dacfe..21c19e167c 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -123,8 +123,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'tcx>, cgu_name: InternedString) { submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tcx, module, cost); - fn module_codegen<'tcx>( - tcx: TyCtxt<'tcx>, + fn module_codegen( + tcx: TyCtxt<'_>, cgu_name: InternedString, ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 0709368ad8..894e5c2fd3 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -144,7 +144,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn build_sibling_block<'b>(&self, name: &'b str) -> Self { + fn build_sibling_block(&self, name: &str) -> Self { Builder::new_block(self.cx, self.llfn(), name) } @@ -215,7 +215,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { funclet: Option<&Funclet<'ll>>, ) -> &'ll Value { - debug!("Invoke {:?} with args ({:?})", + debug!("invoke {:?} with args ({:?})", llfn, args); @@ -1035,7 +1035,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { funclet: Option<&Funclet<'ll>>, ) -> &'ll Value { - debug!("Call {:?} with args ({:?})", + debug!("call {:?} with args ({:?})", llfn, args); @@ -1153,11 +1153,14 @@ impl Builder<'a, 'll, 'tcx> { } } + pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) } + } + pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) } + } pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { unsafe { - // FIXME: add a non-fast math version once - // https://bugs.llvm.org/show_bug.cgi?id=36732 - // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -1165,9 +1168,6 @@ impl Builder<'a, 'll, 'tcx> { } pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { unsafe { - // FIXME: add a non-fast math version once - // https://bugs.llvm.org/show_bug.cgi?id=36732 - // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -1238,7 +1238,7 @@ impl Builder<'a, 'll, 'tcx> { if dest_ptr_ty == stored_ptr_ty { ptr } else { - debug!("Type mismatch in store. \ + debug!("type mismatch in store. \ Expected {:?}, got {:?}; inserting bitcast", dest_ptr_ty, stored_ptr_ty); self.bitcast(ptr, stored_ptr_ty) @@ -1274,7 +1274,7 @@ impl Builder<'a, 'll, 'tcx> { .map(|(i, (expected_ty, &actual_val))| { let actual_ty = self.val_ty(actual_val); if expected_ty != actual_ty { - debug!("Type mismatch in function call of {:?}. \ + debug!("type mismatch in function call of {:?}. \ Expected {:?} for param {}, got {:?}; injecting bitcast", llfn, expected_ty, i, actual_ty); self.bitcast(actual_val, expected_ty) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index f21f203fcc..b0c94a139b 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -11,7 +11,7 @@ use crate::value::Value; use rustc_codegen_ssa::traits::*; use crate::consts::const_alloc_to_llvm; -use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size, Align}; +use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size}; use rustc::mir::interpret::{Scalar, GlobalAlloc, Allocation}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -166,25 +166,6 @@ impl CodegenCx<'ll, 'tcx> { r } } - - pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> { - unsafe { - if self.is_const_real(v) { - let mut loses_info: llvm::Bool = ::std::mem::uninitialized(); - let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info); - let loses_info = if loses_info == 1 { true } else { false }; - Some((r, loses_info)) - } else { - None - } - } - } - - fn is_const_real(&self, v: &'ll Value) -> bool { - unsafe { - llvm::LLVMIsAConstantFP(v).is_some() - } - } } impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -249,6 +230,10 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.const_uint(self.type_i8(), i as u64) } + fn const_real(&self, t: &'ll Type, val: f64) -> &'ll Value { + unsafe { llvm::LLVMConstReal(t, val) } + } + fn const_struct( &self, elts: &[&'ll Value], @@ -344,12 +329,12 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn from_const_alloc( &self, layout: TyLayout<'tcx>, - align: Align, alloc: &Allocation, offset: Size, ) -> PlaceRef<'tcx, &'ll Value> { + assert_eq!(alloc.align, layout.align.abi); let init = const_alloc_to_llvm(self, alloc); - let base_addr = self.static_addr_of(init, align, None); + let base_addr = self.static_addr_of(init, alloc.align, None); let llval = unsafe { llvm::LLVMConstInBoundsGEP( self.const_bitcast(base_addr, self.type_i8p()), @@ -357,7 +342,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { 1, )}; let llval = self.const_bitcast(llval, self.type_ptr_to(layout.llvm_type(self))); - PlaceRef::new_sized(llval, layout, align) + PlaceRef::new_sized(llval, layout, alloc.align) } fn const_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index e02d14a151..0077df3cf5 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -72,8 +72,8 @@ pub fn codegen_static_initializer( let alloc = match static_.val { ConstValue::ByRef { - offset, align, alloc, - } if offset.bytes() == 0 && align == alloc.align => { + alloc, offset, + } if offset.bytes() == 0 => { alloc }, _ => bug!("static const eval returned {:#?}", static_), diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 6a61b180de..a2aaaddf09 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -1,5 +1,6 @@ use crate::attributes; use crate::llvm; +use crate::llvm_util; use crate::debuginfo; use crate::value::Value; use rustc::dep_graph::DepGraphSafe; @@ -29,6 +30,7 @@ use std::iter; use std::str; use std::sync::Arc; use syntax::symbol::LocalInternedString; +use syntax::source_map::{DUMMY_SP, Span}; use crate::abi::Abi; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM @@ -140,6 +142,11 @@ pub fn is_pie_binary(sess: &Session) -> bool { !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC } +fn strip_function_ptr_alignment(data_layout: String) -> String { + // FIXME: Make this more general. + data_layout.replace("-Fi8-", "-") +} + pub unsafe fn create_module( tcx: TyCtxt<'_>, llcx: &'ll llvm::Context, @@ -149,14 +156,19 @@ pub unsafe fn create_module( let mod_name = SmallCStr::new(mod_name); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); + let mut target_data_layout = sess.target.target.data_layout.clone(); + if llvm_util::get_major_version() < 9 { + target_data_layout = strip_function_ptr_alignment(target_data_layout); + } + // Ensure the data-layout values hardcoded remain the defaults. if sess.target.target.options.is_builtin { let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false); llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm); llvm::LLVMRustDisposeTargetMachine(tm); - let data_layout = llvm::LLVMGetDataLayout(llmod); - let data_layout = str::from_utf8(CStr::from_ptr(data_layout).to_bytes()) + let llvm_data_layout = llvm::LLVMGetDataLayout(llmod); + let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes()) .ok().expect("got a non-UTF8 data-layout from LLVM"); // Unfortunately LLVM target specs change over time, and right now we @@ -177,16 +189,16 @@ pub unsafe fn create_module( let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or(""); let custom_llvm_used = cfg_llvm_root.trim() != ""; - if !custom_llvm_used && sess.target.target.data_layout != data_layout { + if !custom_llvm_used && target_data_layout != llvm_data_layout { bug!("data-layout for builtin `{}` target, `{}`, \ differs from LLVM default, `{}`", sess.target.target.llvm_target, - sess.target.target.data_layout, - data_layout); + target_data_layout, + llvm_data_layout); } } - let data_layout = SmallCStr::new(&sess.target.target.data_layout); + let data_layout = SmallCStr::new(&target_data_layout); llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); let llvm_target = SmallCStr::new(&sess.target.target.llvm_target); @@ -849,9 +861,13 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> { type TyLayout = TyLayout<'tcx>; fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { + self.spanned_layout_of(ty, DUMMY_SP) + } + + fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyLayout { self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) .unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e { - self.sess().fatal(&e.to_string()) + self.sess().span_fatal(span, &e.to_string()) } else { bug!("failed to get layout for `{}`: {}", ty, e) }) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index fbeda43af4..928532a1f4 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -341,7 +341,7 @@ fn fixed_vec_metadata( let (size, align) = cx.size_and_align_of(array_or_slice_type); let upper_bound = match array_or_slice_type.sty { - ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong, + ty::Array(_, len) => len.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong, _ => -1 }; @@ -450,11 +450,11 @@ fn subroutine_type_metadata( false); } -// FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill- -// defined concept. For the case of an actual trait pointer (i.e., Box, -// &Trait), trait_object_type should be the whole thing (e.g, Box) and -// trait_type should be the actual trait (e.g., Trait). Where the trait is part -// of a DST struct, there is no trait_object_type and the results of this +// FIXME(1563): This is all a bit of a hack because 'trait pointer' is an ill- +// defined concept. For the case of an actual trait pointer (i.e., `Box`, +// `&Trait`), `trait_object_type` should be the whole thing (e.g, `Box`) and +// `trait_type` should be the actual trait (e.g., `Trait`). Where the trait is part +// of a DST struct, there is no `trait_object_type` and the results of this // function will be a little bit weird. fn trait_pointer_metadata( cx: &CodegenCx<'ll, 'tcx>, @@ -464,13 +464,13 @@ fn trait_pointer_metadata( ) -> &'ll DIType { // The implementation provided here is a stub. It makes sure that the trait // type is assigned the correct name, size, namespace, and source location. - // But it does not describe the trait's methods. + // However, it does not describe the trait's methods. let containing_scope = match trait_type.sty { ty::Dynamic(ref data, ..) => data.principal_def_id().map(|did| get_namespace_for_item(cx, did)), _ => { - bug!("debuginfo: Unexpected trait-object type in \ + bug!("debuginfo: unexpected trait-object type in \ trait_pointer_metadata(): {:?}", trait_type); } @@ -683,11 +683,13 @@ pub fn type_metadata( } ty::Closure(def_id, substs) => { let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect(); + let containing_scope = get_namespace_for_item(cx, def_id); prepare_tuple_metadata(cx, t, &upvar_tys, unique_type_id, - usage_site_span).finalize(cx) + usage_site_span, + Some(containing_scope)).finalize(cx) } ty::Generator(def_id, substs, _) => { let upvar_tys : Vec<_> = substs.prefix_tys(def_id, cx.tcx).map(|t| { @@ -728,7 +730,8 @@ pub fn type_metadata( t, &tys, unique_type_id, - usage_site_span).finalize(cx) + usage_site_span, + NO_SCOPE_METADATA).finalize(cx) } _ => { bug!("debuginfo: unexpected type in type_metadata: {:?}", t) @@ -913,9 +916,12 @@ pub fn compile_unit_metadata( } debug!("compile_unit_metadata: {:?}", name_in_debuginfo); + let rustc_producer = format!( + "rustc version {}", + option_env!("CFG_VERSION").expect("CFG_VERSION"), + ); // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice. - let producer = format!("clang LLVM (rustc version {})", - (option_env!("CFG_VERSION")).expect("CFG_VERSION")); + let producer = format!("clang LLVM ({})", rustc_producer); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo); @@ -980,6 +986,21 @@ pub fn compile_unit_metadata( gcov_metadata); } + // Insert `llvm.ident` metadata on the wasm32 targets since that will + // get hooked up to the "producer" sections `processed-by` information. + if tcx.sess.opts.target_triple.triple().starts_with("wasm32") { + let name_metadata = llvm::LLVMMDStringInContext( + debug_context.llcontext, + rustc_producer.as_ptr() as *const _, + rustc_producer.as_bytes().len() as c_uint, + ); + llvm::LLVMAddNamedMetadataOperand( + debug_context.llmod, + const_cstr!("llvm.ident").as_ptr(), + llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1), + ); + } + return unit_metadata; }; @@ -1187,6 +1208,7 @@ fn prepare_tuple_metadata( component_types: &[Ty<'tcx>], unique_type_id: UniqueTypeId, span: Span, + containing_scope: Option<&'ll DIScope>, ) -> RecursiveTypeDescription<'ll, 'tcx> { let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false); @@ -1194,7 +1216,7 @@ fn prepare_tuple_metadata( tuple_type, &tuple_name[..], unique_type_id, - NO_SCOPE_METADATA); + containing_scope); create_and_register_recursive_type_forward_declaration( cx, diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index bcb14b8899..62eab0f3d4 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -107,7 +107,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { llvm::Attribute::NoReturn.apply_llfn(Function, llfn); } - fty.apply_attrs_llfn(llfn); + fty.apply_attrs_llfn(self, llfn); llfn } diff --git a/src/librustc_codegen_llvm/error_codes.rs b/src/librustc_codegen_llvm/error_codes.rs index 872fa424e4..c6b5dc03a6 100644 --- a/src/librustc_codegen_llvm/error_codes.rs +++ b/src/librustc_codegen_llvm/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { E0511: r##" diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 7831c20011..a9b8962f45 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1,5 +1,3 @@ -#![allow(non_upper_case_globals)] - use crate::attributes; use crate::llvm; use crate::llvm_util; @@ -1640,32 +1638,15 @@ fn generic_simd_intrinsic( } }, ty::Float(f) => { - // ordered arithmetic reductions take an accumulator let acc = if $ordered { - let acc = args[1].immediate(); - // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36734 - // * if the accumulator of the fadd isn't 0, incorrect - // code is generated - // * if the accumulator of the fmul isn't 1, incorrect - // code is generated - match bx.const_get_real(acc) { - None => return_error!("accumulator of {} is not a constant", $name), - Some((v, loses_info)) => { - if $name.contains("mul") && v != 1.0_f64 { - return_error!("accumulator of {} is not 1.0", $name); - } else if $name.contains("add") && v != 0.0_f64 { - return_error!("accumulator of {} is not 0.0", $name); - } else if loses_info { - return_error!("accumulator of {} loses information", $name); - } - } - } - acc + // ordered arithmetic reductions take an accumulator + args[1].immediate() } else { - // unordered arithmetic reductions do not: + // unordered arithmetic reductions use the identity accumulator + let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 }; match f.bit_width() { - 32 => bx.const_undef(bx.type_f32()), - 64 => bx.const_undef(bx.type_f64()), + 32 => bx.const_real(bx.type_f32(), identity_acc), + 64 => bx.const_real(bx.type_f64(), identity_acc), v => { return_error!(r#" unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, @@ -1687,8 +1668,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, } } - arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd_fast, true); - arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul_fast, true); + arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd, true); + arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul, true); arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false); arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7283aa95b3..653dd8868f 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -12,7 +12,6 @@ #![feature(crate_visibility_modifier)] #![feature(extern_types)] #![feature(in_band_lifetimes)] -#![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] @@ -21,24 +20,23 @@ #![feature(link_args)] #![feature(static_nobundle)] #![feature(trusted_len)] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] +#![feature(mem_take)] use back::write::{create_target_machine, create_informational_target_machine}; use syntax_pos::symbol::Symbol; +extern crate rustc_demangle; extern crate flate2; #[macro_use] extern crate bitflags; extern crate libc; #[macro_use] extern crate rustc; -extern crate rustc_allocator; extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; extern crate rustc_incremental; extern crate rustc_codegen_utils; extern crate rustc_codegen_ssa; extern crate rustc_fs_util; +extern crate rustc_driver as _; #[macro_use] extern crate log; #[macro_use] extern crate syntax; @@ -51,13 +49,13 @@ use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModul use rustc_codegen_ssa::CompiledModule; use errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; +use syntax::ext::allocator::AllocatorKind; use syntax_pos::symbol::InternedString; pub use llvm_util::target_features; use std::any::Any; use std::sync::{mpsc, Arc}; use rustc::dep_graph::DepGraph; -use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; @@ -124,7 +122,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend { ) { unsafe { allocator::codegen(tcx, mods, kind) } } - fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: InternedString) { + fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: InternedString) { base::compile_codegen_unit(tcx, cgu_name); } fn target_machine_factory( diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index a5c295cd45..9f9410560e 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1,3 +1,6 @@ +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + use super::debuginfo::{ DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, @@ -566,7 +569,7 @@ pub mod debuginfo { bitflags! { #[repr(transparent)] #[derive(Default)] - pub struct DIFlags: ::libc::uint32_t { + pub struct DIFlags: u32 { const FlagZero = 0; const FlagPrivate = 1; const FlagProtected = 2; @@ -595,7 +598,7 @@ pub mod debuginfo { bitflags! { #[repr(transparent)] #[derive(Default)] - pub struct DISPFlags: ::libc::uint32_t { + pub struct DISPFlags: u32 { const SPFlagZero = 0; const SPFlagVirtual = 1; const SPFlagPureVirtual = 2; @@ -715,10 +718,10 @@ extern "C" { // Operations on scalar constants pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; + pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: &mut u64, low: &mut u64) -> bool; - pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: &mut Bool) -> f64; // Operations on composite constants @@ -794,6 +797,7 @@ extern "C" { pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32); pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64); pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type); pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute); pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value, index: c_uint, @@ -824,6 +828,7 @@ extern "C" { pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type); // Operations on load/store instructions (only) pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool); @@ -1660,11 +1665,13 @@ extern "C" { pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; - pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind; pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass); + pub fn LLVMRustAddLastExtensionPasses(PMB: &PassManagerBuilder, + Passes: *const &'static mut Pass, + NumPasses: size_t); pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; @@ -1736,7 +1743,9 @@ extern "C" { pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); - pub fn LLVMRustGetSectionName(SI: &SectionIterator<'_>, data: &mut *const c_char) -> size_t; + #[allow(improper_ctypes)] + pub fn LLVMRustGetSectionName(SI: &SectionIterator<'_>, + data: &mut Option>) -> size_t; #[allow(improper_ctypes)] pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 543cc91293..57815933af 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -1,7 +1,4 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] #![allow(non_snake_case)] -#![deny(bare_trait_objects)] pub use self::IntPredicate::*; pub use self::RealPredicate::*; diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index 274c896596..541d3d98b7 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -174,7 +174,7 @@ const X86_WHITELIST: &[(&str, Option)] = &[ const HEXAGON_WHITELIST: &[(&str, Option)] = &[ ("hvx", Some(sym::hexagon_target_feature)), - ("hvx-double", Some(sym::hexagon_target_feature)), + ("hvx-length128b", Some(sym::hexagon_target_feature)), ]; const POWERPC_WHITELIST: &[(&str, Option)] = &[ diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index 7cf497cb5d..cd72558881 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -8,7 +8,6 @@ use rustc_data_structures::owning_ref::OwningRef; use rustc_codegen_ssa::METADATA_FILENAME; use std::path::Path; -use std::ptr; use std::slice; use rustc_fs_util::path_to_c_string; @@ -67,10 +66,16 @@ fn search_meta_section<'a>(of: &'a ObjectFile, unsafe { let si = mk_section_iter(of.llof); while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { - let mut name_buf = ptr::null(); + let mut name_buf = None; let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); - let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); - let name = String::from_utf8(name).unwrap(); + let name = name_buf.map_or( + String::new(), // We got a NULL ptr, ignore `name_len`. + |buf| String::from_utf8( + slice::from_raw_parts(buf.as_ptr() as *const u8, + name_len as usize) + .to_vec() + ).unwrap() + ); debug!("get_metadata_section: name {}", name); if read_metadata_section_name(target) == name { let cbuf = llvm::LLVMGetSectionContents(si.llsi); diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 2c167256ad..8d6cd0bcf4 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -1,5 +1,3 @@ -#![allow(non_upper_case_globals)] - pub use crate::llvm::Type; use crate::llvm; diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index a4cb517faf..89a6ec27fe 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -7,14 +7,12 @@ edition = "2018" [lib] name = "rustc_codegen_ssa" path = "lib.rs" -crate-type = ["dylib"] test = false [dependencies] bitflags = "1.0.4" cc = "1.0.1" num_cpus = "1.0" -rustc-demangle = "0.1.15" memmap = "0.6" log = "0.4.5" libc = "0.2.44" @@ -22,11 +20,10 @@ jobserver = "0.1.11" parking_lot = "0.7" tempfile = "3.0.5" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } -rustc_allocator = { path = "../librustc_allocator" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_data_structures = { path = "../librustc_data_structures"} diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs index 78570cce57..340cc772e5 100644 --- a/src/librustc_codegen_ssa/back/command.rs +++ b/src/librustc_codegen_ssa/back/command.rs @@ -50,8 +50,8 @@ impl Command { } pub fn args(&mut self, args: I) -> &mut Command - where I: IntoIterator, - I::Item: AsRef, + where + I: IntoIterator>, { for arg in args { self._arg(arg.as_ref()); @@ -110,7 +110,7 @@ impl Command { } pub fn take_args(&mut self) -> Vec { - mem::replace(&mut self.args, Vec::new()) + mem::take(&mut self.args) } /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits, diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index e3d297e786..8fb0828285 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -95,7 +95,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, ); } } - if sess.opts.debugging_opts.emit_artifact_notifications { + if sess.opts.json_artifact_notifications { sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename, "link"); } } @@ -653,10 +653,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, linker_error.emit(); if sess.target.target.options.is_like_msvc && linker_not_found { - sess.note_without_error("the msvc targets depend on the msvc linker \ - but `link.exe` was not found"); - sess.note_without_error("please ensure that VS 2013, VS 2015 or VS 2017 \ - was installed with the Visual C++ option"); + sess.note_without_error( + "the msvc targets depend on the msvc linker \ + but `link.exe` was not found", + ); + sess.note_without_error( + "please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 \ + was installed with the Visual C++ option", + ); } sess.abort_if_errors(); } @@ -674,14 +678,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, sess.fatal(&format!("failed to run dsymutil: {}", e)) } } - - if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" { - super::wasm::add_producer_section( - &out_filename, - &sess.edition().to_string(), - option_env!("CFG_VERSION").unwrap_or("unknown"), - ); - } } /// Returns a boolean indicating whether the specified crate should be ignored diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 32696d46cd..26091005f2 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -16,7 +16,7 @@ use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, LinkerPluginLto, Lto}; use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; -use serialize::{json, Encoder}; +use rustc_serialize::{json, Encoder}; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. @@ -368,6 +368,26 @@ impl<'a> Linker for GccLinker<'a> { } } else { self.cmd.arg("-shared"); + if self.sess.target.target.options.is_like_windows { + // The output filename already contains `dll_suffix` so + // the resulting import library will have a name in the + // form of libfoo.dll.a + let implib_name = out_filename + .file_name() + .and_then(|file| file.to_str()) + .map(|file| format!("{}{}{}", + self.sess.target.target.options.staticlib_prefix, + file, + self.sess.target.target.options.staticlib_suffix)); + if let Some(implib_name) = implib_name { + let implib = out_filename + .parent() + .map(|dir| dir.join(&implib_name)); + if let Some(implib) = implib { + self.linker_arg(&format!("--out-implib,{}", (*implib).to_str().unwrap())); + } + } + } } } @@ -881,7 +901,45 @@ pub struct WasmLd<'a> { } impl<'a> WasmLd<'a> { - fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { + fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { + // If the atomics feature is enabled for wasm then we need a whole bunch + // of flags: + // + // * `--shared-memory` - the link won't even succeed without this, flags + // the one linear memory as `shared` + // + // * `--max-memory=1G` - when specifying a shared memory this must also + // be specified. We conservatively choose 1GB but users should be able + // to override this with `-C link-arg`. + // + // * `--import-memory` - it doesn't make much sense for memory to be + // exported in a threaded module because typically you're + // sharing memory and instantiating the module multiple times. As a + // result if it were exported then we'd just have no sharing. + // + // * `--passive-segments` - all memory segments should be passive to + // prevent each module instantiation from reinitializing memory. + // + // * `--export=__wasm_init_memory` - when using `--passive-segments` the + // linker will synthesize this function, and so we need to make sure + // that our usage of `--export` below won't accidentally cause this + // function to get deleted. + // + // * `--export=*tls*` - when `#[thread_local]` symbols are used these + // symbols are how the TLS segments are initialized and configured. + let atomics = sess.opts.cg.target_feature.contains("+atomics") || + sess.target.target.options.features.contains("+atomics"); + if atomics { + cmd.arg("--shared-memory"); + cmd.arg("--max-memory=1073741824"); + cmd.arg("--import-memory"); + cmd.arg("--passive-segments"); + cmd.arg("--export=__wasm_init_memory"); + cmd.arg("--export=__wasm_init_tls"); + cmd.arg("--export=__tls_size"); + cmd.arg("--export=__tls_align"); + cmd.arg("--export=__tls_base"); + } WasmLd { cmd, sess, info } } } @@ -984,6 +1042,13 @@ impl<'a> Linker for WasmLd<'a> { for sym in self.info.exports[&crate_type].iter() { self.cmd.arg("--export").arg(&sym); } + + // LLD will hide these otherwise-internal symbols since our `--export` + // list above is a whitelist of what to export. Various bits and pieces + // of tooling use this, so be sure these symbols make their way out of + // the linker as well. + self.cmd.arg("--export=__heap_base"); + self.cmd.arg("--export=__data_end"); } fn subsystem(&mut self, _subsystem: &str) { diff --git a/src/librustc_codegen_ssa/back/mod.rs b/src/librustc_codegen_ssa/back/mod.rs index a16d099ee3..901891d85a 100644 --- a/src/librustc_codegen_ssa/back/mod.rs +++ b/src/librustc_codegen_ssa/back/mod.rs @@ -6,4 +6,3 @@ pub mod command; pub mod symbol_export; pub mod archive; pub mod rpath; -pub mod wasm; diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 3e0f030527..2d9220f897 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -1,3 +1,4 @@ +use std::collections::hash_map::Entry::*; use std::sync::Arc; use rustc::ty::Instance; @@ -12,9 +13,8 @@ use rustc::ty::{TyCtxt, SymbolName}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::util::nodemap::{FxHashMap, DefIdMap}; -use rustc_allocator::ALLOCATOR_METHODS; use rustc_data_structures::indexed_vec::IndexVec; -use std::collections::hash_map::Entry::*; +use syntax::ext::allocator::ALLOCATOR_METHODS; pub type ExportedSymbols = FxHashMap< CrateNum, @@ -46,10 +46,10 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExpor } } -fn reachable_non_generics_provider<'tcx>( - tcx: TyCtxt<'tcx>, +fn reachable_non_generics_provider( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> &'tcx DefIdMap { +) -> &DefIdMap { assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { @@ -84,7 +84,7 @@ fn reachable_non_generics_provider<'tcx>( // let it through if it's included statically. match tcx.hir().get(hir_id) { Node::ForeignItem(..) => { - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); if tcx.is_statically_included_foreign_item(def_id) { Some(def_id) } else { @@ -104,7 +104,7 @@ fn reachable_non_generics_provider<'tcx>( node: hir::ImplItemKind::Method(..), .. }) => { - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); let generics = tcx.generics_of(def_id); if !generics.requires_monomorphization(tcx) && // Functions marked with #[inline] are only ever codegened @@ -157,7 +157,7 @@ fn reachable_non_generics_provider<'tcx>( tcx.arena.alloc(reachable_non_generics) } -fn is_reachable_non_generic_provider_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_reachable_non_generic_provider_local(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let export_threshold = threshold(tcx); if let Some(&level) = tcx.reachable_non_generics(def_id.krate).get(&def_id) { @@ -167,14 +167,14 @@ fn is_reachable_non_generic_provider_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefI } } -fn is_reachable_non_generic_provider_extern<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.reachable_non_generics(def_id.krate).contains_key(&def_id) } -fn exported_symbols_provider_local<'tcx>( - tcx: TyCtxt<'tcx>, +fn exported_symbols_provider_local( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> Arc, SymbolExportLevel)>> { +) -> Arc, SymbolExportLevel)>> { assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { @@ -273,10 +273,10 @@ fn exported_symbols_provider_local<'tcx>( Arc::new(symbols) } -fn upstream_monomorphizations_provider<'tcx>( - tcx: TyCtxt<'tcx>, +fn upstream_monomorphizations_provider( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> &'tcx DefIdMap, CrateNum>> { +) -> &DefIdMap, CrateNum>> { debug_assert!(cnum == LOCAL_CRATE); let cnums = tcx.all_crate_nums(LOCAL_CRATE); @@ -322,10 +322,10 @@ fn upstream_monomorphizations_provider<'tcx>( tcx.arena.alloc(instances) } -fn upstream_monomorphizations_for_provider<'tcx>( - tcx: TyCtxt<'tcx>, +fn upstream_monomorphizations_for_provider( + tcx: TyCtxt<'_>, def_id: DefId, -) -> Option<&'tcx FxHashMap, CrateNum>> { +) -> Option<&FxHashMap, CrateNum>> { debug_assert!(!def_id.is_local()); tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id) } diff --git a/src/librustc_codegen_ssa/back/wasm.rs b/src/librustc_codegen_ssa/back/wasm.rs deleted file mode 100644 index f90bb89fbe..0000000000 --- a/src/librustc_codegen_ssa/back/wasm.rs +++ /dev/null @@ -1,191 +0,0 @@ -use std::fs; -use std::path::Path; -use std::str; - -use serialize::leb128; - -// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec -const WASM_CUSTOM_SECTION_ID: u8 = 0; - -/// Adds or augment the existing `producers` section to encode information about -/// the Rust compiler used to produce the wasm file. -pub fn add_producer_section( - path: &Path, - rust_version: &str, - rustc_version: &str, -) { - struct Field<'a> { - name: &'a str, - values: Vec>, - } - - #[derive(Copy, Clone)] - struct FieldValue<'a> { - name: &'a str, - version: &'a str, - } - - let wasm = fs::read(path).expect("failed to read wasm output"); - let mut ret = WasmEncoder::new(); - ret.data.extend(&wasm[..8]); - - // skip the 8 byte wasm/version header - let rustc_value = FieldValue { - name: "rustc", - version: rustc_version, - }; - let rust_value = FieldValue { - name: "Rust", - version: rust_version, - }; - let mut fields = Vec::new(); - let mut wrote_rustc = false; - let mut wrote_rust = false; - - // Move all sections from the original wasm file to our output, skipping - // everything except the producers section - for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) { - if id != WASM_CUSTOM_SECTION_ID { - ret.byte(id); - ret.bytes(raw); - continue - } - let mut decoder = WasmDecoder::new(raw); - if decoder.str() != "producers" { - ret.byte(id); - ret.bytes(raw); - continue - } - - // Read off the producers section into our fields outside the loop, - // we'll re-encode the producers section when we're done (to handle an - // entirely missing producers section as well). - info!("rewriting existing producers section"); - - for _ in 0..decoder.u32() { - let name = decoder.str(); - let mut values = Vec::new(); - for _ in 0..decoder.u32() { - let name = decoder.str(); - let version = decoder.str(); - values.push(FieldValue { name, version }); - } - - if name == "language" { - values.push(rust_value); - wrote_rust = true; - } else if name == "processed-by" { - values.push(rustc_value); - wrote_rustc = true; - } - fields.push(Field { name, values }); - } - } - - if !wrote_rust { - fields.push(Field { - name: "language", - values: vec![rust_value], - }); - } - if !wrote_rustc { - fields.push(Field { - name: "processed-by", - values: vec![rustc_value], - }); - } - - // Append the producers section to the end of the wasm file. - let mut section = WasmEncoder::new(); - section.str("producers"); - section.u32(fields.len() as u32); - for field in fields { - section.str(field.name); - section.u32(field.values.len() as u32); - for value in field.values { - section.str(value.name); - section.str(value.version); - } - } - ret.byte(WASM_CUSTOM_SECTION_ID); - ret.bytes(§ion.data); - - fs::write(path, &ret.data).expect("failed to write wasm output"); -} - -struct WasmSections<'a>(WasmDecoder<'a>); - -impl<'a> Iterator for WasmSections<'a> { - type Item = (u8, &'a [u8]); - - fn next(&mut self) -> Option<(u8, &'a [u8])> { - if self.0.data.is_empty() { - return None - } - - // see https://webassembly.github.io/spec/core/binary/modules.html#sections - let id = self.0.byte(); - let section_len = self.0.u32(); - info!("new section {} / {} bytes", id, section_len); - let section = self.0.skip(section_len as usize); - Some((id, section)) - } -} - -struct WasmDecoder<'a> { - data: &'a [u8], -} - -impl<'a> WasmDecoder<'a> { - fn new(data: &'a [u8]) -> WasmDecoder<'a> { - WasmDecoder { data } - } - - fn byte(&mut self) -> u8 { - self.skip(1)[0] - } - - fn u32(&mut self) -> u32 { - let (n, l1) = leb128::read_u32_leb128(self.data); - self.data = &self.data[l1..]; - return n - } - - fn skip(&mut self, amt: usize) -> &'a [u8] { - let (data, rest) = self.data.split_at(amt); - self.data = rest; - data - } - - fn str(&mut self) -> &'a str { - let len = self.u32(); - str::from_utf8(self.skip(len as usize)).unwrap() - } -} - -struct WasmEncoder { - data: Vec, -} - -impl WasmEncoder { - fn new() -> WasmEncoder { - WasmEncoder { data: Vec::new() } - } - - fn u32(&mut self, val: u32) { - leb128::write_u32_leb128(&mut self.data, val); - } - - fn byte(&mut self, val: u8) { - self.data.push(val); - } - - fn bytes(&mut self, val: &[u8]) { - self.u32(val.len() as u32); - self.data.extend_from_slice(val); - } - - fn str(&mut self, val: &str) { - self.bytes(val.as_bytes()) - } -} diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 6364843d77..c9e4663fdb 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -26,7 +26,7 @@ use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; use rustc_errors::emitter::{Emitter}; use rustc_target::spec::MergeFunctions; use syntax::attr; -use syntax::ext::hygiene::Mark; +use syntax::ext::hygiene::ExpnId; use syntax_pos::MultiSpan; use syntax_pos::symbol::{Symbol, sym}; use jobserver::{Client, Acquired}; @@ -1345,12 +1345,9 @@ fn start_executing_work( assert!(!started_lto); started_lto = true; - let needs_fat_lto = - mem::replace(&mut needs_fat_lto, Vec::new()); - let needs_thin_lto = - mem::replace(&mut needs_thin_lto, Vec::new()); - let import_only_modules = - mem::replace(&mut lto_import_only_modules, Vec::new()); + let needs_fat_lto = mem::take(&mut needs_fat_lto); + let needs_thin_lto = mem::take(&mut needs_thin_lto); + let import_only_modules = mem::take(&mut lto_import_only_modules); for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) { @@ -1557,7 +1554,7 @@ fn start_executing_work( let total_llvm_time = Instant::now().duration_since(llvm_start_time); // This is the top-level timing for all of LLVM, set the time-depth // to zero. - set_time_depth(0); + set_time_depth(1); print_time_passes_entry(cgcx.time_passes, "LLVM passes", total_llvm_time); @@ -1778,7 +1775,7 @@ impl SharedEmitterMain { } } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => { - match Mark::from_u32(cookie).expn_info() { + match ExpnId::from_u32(cookie).expn_info() { Some(ei) => sess.span_err(ei.call_site, &msg), None => sess.err(&msg), } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 47b383fddb..cdc54bb179 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -25,7 +25,7 @@ use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; use rustc::middle::cstore::{self, LinkagePreference}; -use rustc::util::common::{time, print_time_passes_entry}; +use rustc::util::common::{time, print_time_passes_entry, set_time_depth, time_depth}; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; @@ -128,10 +128,11 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>( target: Ty<'tcx>, old_info: Option, ) -> Cx::Value { - let (source, target) = cx.tcx().struct_lockstep_tails(source, target); + let (source, target) = + cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, cx.param_env()); match (&source.sty, &target.sty) { (&ty::Array(_, len), &ty::Slice(_)) => { - cx.const_usize(len.unwrap_usize(cx.tcx())) + cx.const_usize(len.eval_usize(cx.tcx(), ty::ParamEnv::reveal_all())) } (&ty::Dynamic(..), &ty::Dynamic(..)) => { // For now, upcasts are limited to changes in marker @@ -433,7 +434,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' if cx.get_defined_value("main").is_some() { // FIXME: We should be smart and show a better diagnostic here. cx.sess().struct_span_err(sp, "entry symbol `main` defined multiple times") - .help("did you use #[no_mangle] on `fn main`? Use #[start] instead") + .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead") .emit(); cx.sess().abort_if_errors(); bug!(); @@ -639,9 +640,12 @@ pub fn codegen_crate( // Since the main thread is sometimes blocked during codegen, we keep track // -Ztime-passes output manually. + let time_depth = time_depth(); + set_time_depth(time_depth + 1); print_time_passes_entry(tcx.sess.time_passes(), "codegen to LLVM IR", total_codegen_time); + set_time_depth(time_depth); ::rustc_incremental::assert_module_sources::assert_module_sources(tcx); @@ -700,7 +704,7 @@ impl Drop for AbortCodegenOnDrop { } } -fn assert_and_save_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) { +fn assert_and_save_dep_graph(tcx: TyCtxt<'_>) { time(tcx.sess, "assert dep graph", || ::rustc_incremental::assert_dep_graph(tcx)); @@ -777,12 +781,6 @@ impl CrateInfo { } } -fn is_codegened_item(tcx: TyCtxt<'_>, id: DefId) -> bool { - let (all_mono_items, _) = - tcx.collect_and_partition_mono_items(LOCAL_CRATE); - all_mono_items.contains(&id) -} - pub fn provide_both(providers: &mut Providers<'_>) { providers.backend_optimization_level = |tcx, cratenum| { let for_speed = match tcx.sess.opts.optimize { diff --git a/src/librustc_codegen_ssa/debuginfo/mod.rs b/src/librustc_codegen_ssa/debuginfo/mod.rs index d60a2e0cb1..c9b1c0260e 100644 --- a/src/librustc_codegen_ssa/debuginfo/mod.rs +++ b/src/librustc_codegen_ssa/debuginfo/mod.rs @@ -10,7 +10,7 @@ pub enum FunctionDebugContext { } impl FunctionDebugContext { - pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData { + pub fn get_ref(&self, span: Span) -> &FunctionDebugContextData { match *self { FunctionDebugContext::RegularContext(ref data) => data, FunctionDebugContext::DebugInfoDisabled => { diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index 8f0bb6ee19..9b5ad94ecd 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -89,7 +89,7 @@ pub fn push_debuginfo_type_name<'tcx>( ty::Array(inner_type, len) => { output.push('['); push_debuginfo_type_name(tcx, inner_type, true, output, visited); - output.push_str(&format!("; {}", len.unwrap_usize(tcx))); + output.push_str(&format!("; {}", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))); output.push(']'); }, ty::Slice(inner_type) => { @@ -190,11 +190,17 @@ pub fn push_debuginfo_type_name<'tcx>( // processing visited.remove(t); }, - ty::Closure(..) => { - output.push_str("closure"); + ty::Closure(def_id, ..) => { + output.push_str(&format!( + "closure-{}", + tcx.def_key(def_id).disambiguated_data.disambiguator + )); } - ty::Generator(..) => { - output.push_str("generator"); + ty::Generator(def_id, ..) => { + output.push_str(&format!( + "generator-{}", + tcx.def_key(def_id).disambiguated_data.disambiguator + )); } ty::Error | ty::Infer(_) | diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs index e7ef178cfa..8d46dcb7c0 100644 --- a/src/librustc_codegen_ssa/error_codes.rs +++ b/src/librustc_codegen_ssa/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { E0668: r##" diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index b76f098773..68640abb04 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -10,11 +10,8 @@ #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(trusted_len)] -#![allow(unused_attributes)] -#![allow(dead_code)] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] +#![feature(mem_take)] +#![feature(associated_type_bounds)] #![recursion_limit="256"] @@ -131,6 +128,7 @@ bitflags::bitflags! { } /// Misc info we load from metadata to persist beyond the tcx. +#[derive(Debug)] pub struct CrateInfo { pub panic_runtime: Option, pub compiler_builtins: Option, diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 0289150a5e..cc0c733c22 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -9,6 +9,7 @@ use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUs use rustc::mir::traversal; use rustc::ty; use rustc::ty::layout::{LayoutOf, HasTyCtxt}; +use syntax_pos::DUMMY_SP; use super::FunctionCx; use crate::traits::*; @@ -20,10 +21,13 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( analyzer.visit_body(mir); - for (index, ty) in mir.local_decls.iter().map(|l| l.ty).enumerate() { + for (index, (ty, span)) in mir.local_decls.iter() + .map(|l| (l.ty, l.source_info.span)) + .enumerate() + { let ty = fx.monomorphize(&ty); debug!("local {} has type {:?}", index, ty); - let layout = fx.cx.layout_of(ty); + let layout = fx.cx.spanned_layout_of(ty, span); if fx.cx.is_backend_immediate(layout) { // These sorts of types are immediates that we can store // in an Value without an alloca. @@ -92,6 +96,93 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { self.first_assignment[local] = location; } } + + fn process_place( + &mut self, + place_ref: &mir::PlaceRef<'_, 'tcx>, + context: PlaceContext, + location: Location, + ) { + let cx = self.fx.cx; + + if let Some(proj) = place_ref.projection { + // Allow uses of projections that are ZSTs or from scalar fields. + let is_consume = match context { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, + _ => false + }; + if is_consume { + let base_ty = + mir::Place::ty_from(place_ref.base, &proj.base, self.fx.mir, cx.tcx()); + let base_ty = self.fx.monomorphize(&base_ty); + + // ZSTs don't require any actual memory access. + let elem_ty = base_ty + .projection_ty(cx.tcx(), &proj.elem) + .ty; + let elem_ty = self.fx.monomorphize(&elem_ty); + let span = if let mir::PlaceBase::Local(index) = place_ref.base { + self.fx.mir.local_decls[*index].source_info.span + } else { + DUMMY_SP + }; + if cx.spanned_layout_of(elem_ty, span).is_zst() { + return; + } + + if let mir::ProjectionElem::Field(..) = proj.elem { + let layout = cx.spanned_layout_of(base_ty.ty, span); + if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { + // Recurse with the same context, instead of `Projection`, + // potentially stopping at non-operand projections, + // which would trigger `not_ssa` on locals. + self.process_place( + &mir::PlaceRef { + base: place_ref.base, + projection: &proj.base, + }, + context, + location, + ); + return; + } + } + } + + // A deref projection only reads the pointer, never needs the place. + if let mir::ProjectionElem::Deref = proj.elem { + self.process_place( + &mir::PlaceRef { + base: place_ref.base, + projection: &proj.base, + }, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), + location + ); + return; + } + } + + // FIXME this is super_place code, is repeated here to avoid cloning place or changing + // visit_place API + let mut context = context; + + if place_ref.projection.is_some() { + context = if context.is_mutating_use() { + PlaceContext::MutatingUse(MutatingUseContext::Projection) + } else { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) + }; + } + + self.visit_place_base(place_ref.base, context, location); + + if let Some(box proj) = place_ref.projection { + self.visit_projection(place_ref.base, proj, context, location); + } + } + } impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> @@ -103,9 +194,13 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> location: Location) { debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue); - if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place { + if let mir::Place { + base: mir::PlaceBase::Local(index), + projection: None, + } = *place { self.assign(index, location); - if !self.fx.rvalue_creates_operand(rvalue) { + let decl_span = self.fx.mir.local_decls[index].source_info.span; + if !self.fx.rvalue_creates_operand(rvalue, decl_span) { self.not_ssa(index); } } else { @@ -155,51 +250,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> context: PlaceContext, location: Location) { debug!("visit_place(place={:?}, context={:?})", place, context); - let cx = self.fx.cx; - - if let mir::Place::Projection(ref proj) = *place { - // Allow uses of projections that are ZSTs or from scalar fields. - let is_consume = match context { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, - _ => false - }; - if is_consume { - let base_ty = proj.base.ty(self.fx.mir, cx.tcx()); - let base_ty = self.fx.monomorphize(&base_ty); - - // ZSTs don't require any actual memory access. - let elem_ty = base_ty - .projection_ty(cx.tcx(), &proj.elem) - .ty; - let elem_ty = self.fx.monomorphize(&elem_ty); - if cx.layout_of(elem_ty).is_zst() { - return; - } - - if let mir::ProjectionElem::Field(..) = proj.elem { - let layout = cx.layout_of(base_ty.ty); - if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { - // Recurse with the same context, instead of `Projection`, - // potentially stopping at non-operand projections, - // which would trigger `not_ssa` on locals. - self.visit_place(&proj.base, context, location); - return; - } - } - } - - // A deref projection only reads the pointer, never needs the place. - if let mir::ProjectionElem::Deref = proj.elem { - return self.visit_place( - &proj.base, - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), - location - ); - } - } - - self.super_place(place, context, location); + self.process_place(&place.as_ref(), context, location); } fn visit_local(&mut self, @@ -273,7 +324,7 @@ impl CleanupKind { } } -pub fn cleanup_kinds<'tcx>(mir: &mir::Body<'tcx>) -> IndexVec { +pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec { fn discover_masters<'tcx>(result: &mut IndexVec, mir: &mir::Body<'tcx>) { for (bb, data) in mir.basic_blocks().iter_enumerated() { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 941166ccfa..ce98979cc0 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -2,7 +2,7 @@ use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; -use rustc::mir::interpret::InterpError; +use rustc::mir::interpret::PanicInfo; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::spec::abi::Abi; use crate::base; @@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { PassMode::Direct(_) | PassMode::Pair(..) => { let op = - self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE); + self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_ref()); if let Ref(llval, _, align) = op.val { bx.load(llval, align) } else { @@ -314,7 +314,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return } - let place = self.codegen_place(&mut bx, location); + let place = self.codegen_place(&mut bx, &location.as_ref()); let (args1, args2); let mut args = if let Some(llextra) = place.llextra { args2 = [place.llval, llextra]; @@ -337,7 +337,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => { (bx.get_fn(drop_fn), - FnType::of_instance(&bx, &drop_fn)) + FnType::of_instance(&bx, drop_fn)) } }; helper.do_call(self, &mut bx, fn_ty, drop_fn, args, @@ -368,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checked operation, just a comparison with the minimum // value, so we have to check for the assert message. if !bx.check_overflow() { - if let mir::interpret::InterpError::OverflowNeg = *msg { + if let PanicInfo::OverflowNeg = *msg { const_cond = Some(expected); } } @@ -402,8 +402,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let col = bx.const_u32(loc.col.to_usize() as u32 + 1); // Put together the arguments to the panic entry point. - let (lang_item, args) = match *msg { - InterpError::BoundsCheck { ref len, ref index } => { + let (lang_item, args) = match msg { + PanicInfo::BoundsCheck { ref len, ref index } => { let len = self.codegen_operand(&mut bx, len).immediate(); let index = self.codegen_operand(&mut bx, index).immediate(); @@ -435,7 +435,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Obtain the panic entry point. let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item); let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = FnType::of_instance(&bx, &instance); + let fn_ty = FnType::of_instance(&bx, instance); let llfn = bx.get_fn(instance); // Codegen the actual panic invoke/call. @@ -552,7 +552,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let def_id = common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = FnType::of_instance(&bx, &instance); + let fn_ty = FnType::of_instance(&bx, instance); let llfn = bx.get_fn(instance); // Codegen the actual panic invoke/call. @@ -607,18 +607,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // but specified directly in the code. This means it gets promoted // and we can then extract the value by evaluating the promoted. mir::Operand::Copy( - Place::Base( - PlaceBase::Static( - box Static { kind: StaticKind::Promoted(promoted), ty } - ) - ) + Place { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(promoted), + ty, + }), + projection: None, + } ) | mir::Operand::Move( - Place::Base( - PlaceBase::Static( - box Static { kind: StaticKind::Promoted(promoted), ty } - ) - ) + Place { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(promoted), + ty, + }), + projection: None, + } ) => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { @@ -1098,7 +1102,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if fn_ret.is_ignore() { return ReturnDest::Nothing; } - let dest = if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dest { + let dest = if let mir::Place { + base: mir::PlaceBase::Local(index), + projection: None, + } = *dest { match self.locals[index] { LocalRef::Place(dest) => dest, LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), @@ -1128,7 +1135,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } else { - self.codegen_place(bx, dest) + self.codegen_place(bx, &mir::PlaceRef { + base: &dest.base, + projection: &dest.projection, + }) }; if fn_ret.is_indirect() { if dest.align < dest.layout.align.abi { @@ -1153,12 +1163,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx> ) { - if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dst { + if let mir::Place { + base: mir::PlaceBase::Local(index), + projection: None, + } = *dst { match self.locals[index] { LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"), LocalRef::Operand(None) => { - let dst_layout = bx.layout_of(self.monomorphized_place_ty(dst)); + let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_ref())); assert!(!dst_layout.ty.has_erasable_regions()); let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp"); place.storage_live(bx); @@ -1173,7 +1186,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } else { - let dst = self.codegen_place(bx, dst); + let dst = self.codegen_place(bx, &dst.as_ref()); self.codegen_transmute_into(bx, src, dst); } } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index d6951b923b..216e5a4645 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -41,7 +41,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .map(|c| { let field_ty = c.ty.builtin_index().unwrap(); let fields = match c.ty.sty { - ty::Array(_, n) => n.unwrap_usize(bx.tcx()), + ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()), _ => bug!("invalid simd shuffle type: {}", c.ty), }; let values: Vec<_> = (0..fields).map(|field| { diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 4a6752fec3..5e5804b726 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -109,8 +109,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) }, - ConstValue::ByRef { offset, align, alloc } => { - return bx.load_operand(bx.from_const_alloc(layout, align, alloc, offset)); + ConstValue::ByRef { alloc, offset } => { + return bx.load_operand(bx.from_const_alloc(layout, alloc, offset)); }, }; @@ -380,11 +380,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn maybe_codegen_consume_direct( &mut self, bx: &mut Bx, - place: &mir::Place<'tcx> + place_ref: &mir::PlaceRef<'_, 'tcx> ) -> Option> { - debug!("maybe_codegen_consume_direct(place={:?})", place); + debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); - place.iterate(|place_base, place_projection| { + place_ref.iterate(|place_base, place_projection| { if let mir::PlaceBase::Local(index) = place_base { match self.locals[*index] { LocalRef::Operand(Some(mut o)) => { @@ -413,7 +413,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(o) } LocalRef::Operand(None) => { - bug!("use of {:?} before def", place); + bug!("use of {:?} before def", place_ref); } LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { // watch out for locals that do not have an @@ -430,11 +430,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_consume( &mut self, bx: &mut Bx, - place: &mir::Place<'tcx> + place_ref: &mir::PlaceRef<'_, 'tcx> ) -> OperandRef<'tcx, Bx::Value> { - debug!("codegen_consume(place={:?})", place); + debug!("codegen_consume(place_ref={:?})", place_ref); - let ty = self.monomorphized_place_ty(place); + let ty = self.monomorphized_place_ty(place_ref); let layout = bx.cx().layout_of(ty); // ZSTs don't require any actual memory access. @@ -442,13 +442,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return OperandRef::new_zst(bx, layout); } - if let Some(o) = self.maybe_codegen_consume_direct(bx, place) { + if let Some(o) = self.maybe_codegen_consume_direct(bx, place_ref) { return o; } // for most places, to consume them we just load them // out from their home - let place = self.codegen_place(bx, place); + let place = self.codegen_place(bx, place_ref); bx.load_operand(place) } @@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match *operand { mir::Operand::Copy(ref place) | mir::Operand::Move(ref place) => { - self.codegen_consume(bx, place) + self.codegen_consume(bx, &place.as_ref()) } mir::Operand::Constant(ref constant) => { diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index be5d7b0996..a632838ba2 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -138,7 +138,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { // * packed struct - there is no alignment padding match field.ty.sty { _ if self.llextra.is_none() => { - debug!("Unsized field `{}`, of `{:?}` has no metadata for adjustment", + debug!("unsized field `{}`, of `{:?}` has no metadata for adjustment", ix, self.llval); return simple(); } @@ -228,8 +228,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { } }; - let discr = self.project_field(bx, discr_index); - let lldiscr = bx.load_operand(discr).immediate(); + // Read the tag/niche-encoded discriminant from memory. + let encoded_discr = self.project_field(bx, discr_index); + let encoded_discr = bx.load_operand(encoded_discr); + + // Decode the discriminant (specifically if it's niche-encoded). match *discr_kind { layout::DiscriminantKind::Tag => { let signed = match discr_scalar.value { @@ -240,38 +243,73 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout::Int(_, signed) => !discr_scalar.is_bool() && signed, _ => false }; - bx.intcast(lldiscr, cast_to, signed) + bx.intcast(encoded_discr.immediate(), cast_to, signed) } layout::DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start, } => { - let niche_llty = bx.cx().immediate_backend_type(discr.layout); - 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. + // Rebase from niche values to discriminants, and check + // whether the result is in range for the niche variants. + let niche_llty = bx.cx().immediate_backend_type(encoded_discr.layout); + let encoded_discr = encoded_discr.immediate(); + + // We first compute the "relative discriminant" (wrt `niche_variants`), + // that is, if `n = niche_variants.end() - niche_variants.start()`, + // we remap `niche_start..=niche_start + n` (which may wrap around) + // to (non-wrap-around) `0..=n`, to be able to check whether the + // discriminant corresponds to a niche variant with one comparison. + // We also can't go directly to the (variant index) discriminant + // and check that it is in the range `niche_variants`, because + // that might not fit in the same type, on top of needing an extra + // comparison (see also the comment on `let niche_discr`). + let relative_discr = if niche_start == 0 { + // Avoid subtracting `0`, which wouldn't work for pointers. + // FIXME(eddyb) check the actual primitive type here. + encoded_discr + } else { + bx.sub(encoded_discr, bx.cx().const_uint_big(niche_llty, niche_start)) + }; + let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32(); + let is_niche = { + let relative_max = if relative_max == 0 { + // Avoid calling `const_uint`, which wouldn't work for pointers. + // FIXME(eddyb) check the actual primitive type here. bx.cx().const_null(niche_llty) } else { - bx.cx().const_uint_big(niche_llty, niche_start) + bx.cx().const_uint(niche_llty, relative_max as u64) }; - let select_arg = bx.icmp(IntPredicate::IntEQ, lldiscr, niche_llval); - bx.select(select_arg, + bx.icmp(IntPredicate::IntULE, relative_discr, relative_max) + }; + + // NOTE(eddyb) this addition needs to be performed on the final + // type, in case the niche itself can't represent all variant + // indices (e.g. `u8` niche with more than `256` variants, + // but enough uninhabited variants so that the remaining variants + // fit in the niche). + // In other words, `niche_variants.end - niche_variants.start` + // is representable in the niche, but `niche_variants.end` + // might not be, in extreme cases. + let niche_discr = { + let relative_discr = if relative_max == 0 { + // HACK(eddyb) since we have only one niche, we know which + // one it is, and we can avoid having a dynamic value here. + bx.cx().const_uint(cast_to, 0) + } else { + bx.intcast(relative_discr, cast_to, false) + }; + bx.add( + relative_discr, bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64), - bx.cx().const_uint(cast_to, dataful_variant.as_u32() as u64)) - } else { - // Rebase from niche values to discriminant values. - let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128); - let lldiscr = bx.sub(lldiscr, bx.cx().const_uint_big(niche_llty, delta)); - let lldiscr_max = - bx.cx().const_uint(niche_llty, niche_variants.end().as_u32() as u64); - let select_arg = bx.icmp(IntPredicate::IntULE, lldiscr, lldiscr_max); - let cast = bx.intcast(lldiscr, cast_to, false); - bx.select(select_arg, - cast, - bx.cx().const_uint(cast_to, dataful_variant.as_u32() as u64)) - } + ) + }; + + bx.select( + is_niche, + niche_discr, + bx.cx().const_uint(cast_to, dataful_variant.as_u32() as u64), + ) } } } @@ -390,16 +428,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_place( &mut self, bx: &mut Bx, - place: &mir::Place<'tcx> + place_ref: &mir::PlaceRef<'_, 'tcx> ) -> PlaceRef<'tcx, Bx::Value> { - debug!("codegen_place(place={:?})", place); - + debug!("codegen_place(place_ref={:?})", place_ref); let cx = self.cx; let tcx = self.cx.tcx(); - let result = match *place { - mir::Place::Base(mir::PlaceBase::Local(index)) => { - match self.locals[index] { + let result = match &place_ref { + mir::PlaceRef { + base: mir::PlaceBase::Local(index), + projection: None, + } => { + match self.locals[*index] { LocalRef::Place(place) => { return place; } @@ -407,25 +447,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return bx.load_operand(place).deref(cx); } LocalRef::Operand(..) => { - bug!("using operand local {:?} as place", place); + bug!("using operand local {:?} as place", place_ref); } } } - mir::Place::Base( - mir::PlaceBase::Static( - box mir::Static { ty, kind: mir::StaticKind::Promoted(promoted) } - ) - ) => { + mir::PlaceRef { + base: mir::PlaceBase::Static(box mir::Static { + ty, + kind: mir::StaticKind::Promoted(promoted), + }), + projection: None, + } => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { instance: self.instance, - promoted: Some(promoted), + promoted: Some(*promoted), }; let layout = cx.layout_of(self.monomorphize(&ty)); match bx.tcx().const_eval(param_env.and(cid)) { Ok(val) => match val.val { - mir::interpret::ConstValue::ByRef { offset, align, alloc } => { - bx.cx().from_const_alloc(layout, align, alloc, offset) + mir::interpret::ConstValue::ByRef { alloc, offset } => { + bx.cx().from_const_alloc(layout, alloc, offset) } _ => bug!("promoteds should have an allocation: {:?}", val), }, @@ -442,26 +484,41 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } - mir::Place::Base( - mir::PlaceBase::Static( - box mir::Static { ty, kind: mir::StaticKind::Static(def_id) } - ) - ) => { + mir::PlaceRef { + base: mir::PlaceBase::Static(box mir::Static { + ty, + kind: mir::StaticKind::Static(def_id), + }), + projection: None, + } => { // NB: The layout of a static may be unsized as is the case when working // with a static that is an extern_type. let layout = cx.layout_of(self.monomorphize(&ty)); - let static_ = bx.get_static(def_id); + let static_ = bx.get_static(*def_id); PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi) }, - mir::Place::Projection(box mir::Projection { - ref base, - elem: mir::ProjectionElem::Deref - }) => { + mir::PlaceRef { + base, + projection: Some(box mir::Projection { + base: proj_base, + elem: mir::ProjectionElem::Deref, + }), + } => { // Load the pointer from its location. - self.codegen_consume(bx, base).deref(bx.cx()) + self.codegen_consume(bx, &mir::PlaceRef { + base, + projection: proj_base, + }).deref(bx.cx()) } - mir::Place::Projection(ref projection) => { - let cg_base = self.codegen_place(bx, &projection.base); + mir::PlaceRef { + base, + projection: Some(projection), + } => { + // FIXME turn this recursion into iteration + let cg_base = self.codegen_place(bx, &mir::PlaceRef { + base, + projection: &projection.base, + }); match projection.elem { mir::ProjectionElem::Deref => bug!(), @@ -515,13 +572,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } }; - debug!("codegen_place(place={:?}) => {:?}", place, result); + debug!("codegen_place(place={:?}) => {:?}", place_ref, result); result } - pub fn monomorphized_place_ty(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> { + pub fn monomorphized_place_ty(&self, place_ref: &mir::PlaceRef<'_, 'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); - let place_ty = place.ty(self.mir, tcx); + let place_ty = mir::Place::ty_from(place_ref.base, place_ref.projection, self.mir, tcx); self.monomorphize(&place_ty.ty) } } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 4a1971e3e2..9da1e5024b 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -6,6 +6,7 @@ use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc_apfloat::{ieee, Float, Status, Round}; use std::{u128, i128}; use syntax::symbol::sym; +use syntax::source_map::{DUMMY_SP, Span}; use crate::base; use crate::MemFlags; @@ -136,7 +137,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => { - assert!(self.rvalue_creates_operand(rvalue)); + assert!(self.rvalue_creates_operand(rvalue, DUMMY_SP)); let (mut bx, temp) = self.codegen_rvalue_operand(bx, rvalue); temp.val.store(&mut bx, dest); bx @@ -169,7 +170,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mut bx: Bx, rvalue: &mir::Rvalue<'tcx> ) -> (Bx, OperandRef<'tcx, Bx::Value>) { - assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue); + assert!( + self.rvalue_creates_operand(rvalue, DUMMY_SP), + "cannot codegen {:?} to operand", + rvalue, + ); match *rvalue { mir::Rvalue::Cast(ref kind, ref source, mir_cast_ty) => { @@ -355,7 +360,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::Ref(_, bk, ref place) => { - let cg_place = self.codegen_place(&mut bx, place); + let cg_place = self.codegen_place(&mut bx, &place.as_ref()); let ty = cg_place.layout.ty; @@ -446,7 +451,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Discriminant(ref place) => { let discr_ty = rvalue.ty(&*self.mir, bx.tcx()); - let discr = self.codegen_place(&mut bx, place) + let discr = self.codegen_place(&mut bx, &place.as_ref()) .codegen_get_discr(&mut bx, discr_ty); (bx, OperandRef { val: OperandValue::Immediate(discr), @@ -515,17 +520,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) -> Bx::Value { // ZST are passed as operands and require special handling // because codegen_place() panics if Local is operand. - if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place { + if let mir::Place { + base: mir::PlaceBase::Local(index), + projection: None, + } = *place { if let LocalRef::Operand(Some(op)) = self.locals[index] { if let ty::Array(_, n) = op.layout.ty.sty { - let n = n.unwrap_usize(bx.cx().tcx()); + let n = n.eval_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all()); return bx.cx().const_usize(n); } } } // use common size calculation for non zero-sized types - let cg_value = self.codegen_place(bx, place); - return cg_value.len(bx.cx()); + let cg_value = self.codegen_place(bx, &place.as_ref()); + cg_value.len(bx.cx()) } pub fn codegen_scalar_binop( @@ -688,7 +696,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>) -> bool { + pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { match *rvalue { mir::Rvalue::Ref(..) | mir::Rvalue::Len(..) | @@ -704,7 +712,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Aggregate(..) => { let ty = rvalue.ty(self.mir, self.cx.tcx()); let ty = self.monomorphize(&ty); - self.cx.layout_of(ty).is_zst() + self.cx.spanned_layout_of(ty, span).is_zst() } } diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 750b2f5b1a..3717be4b41 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -17,7 +17,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(&mut bx, statement.source_info); match statement.kind { mir::StatementKind::Assign(ref place, ref rvalue) => { - if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place { + if let mir::Place { + base: mir::PlaceBase::Local(index), + projection: None, + } = *place { match self.locals[index] { LocalRef::Place(cg_dest) => { self.codegen_rvalue(bx, cg_dest, rvalue) @@ -43,12 +46,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } else { - let cg_dest = self.codegen_place(&mut bx, place); + let cg_dest = self.codegen_place(&mut bx, &place.as_ref()); self.codegen_rvalue(bx, cg_dest, rvalue) } } mir::StatementKind::SetDiscriminant{ref place, variant_index} => { - self.codegen_place(&mut bx, place) + self.codegen_place(&mut bx, &place.as_ref()) .codegen_set_discr(&mut bx, variant_index); bx } @@ -70,7 +73,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::StatementKind::InlineAsm(ref asm) => { let outputs = asm.outputs.iter().map(|output| { - self.codegen_place(&mut bx, output) + self.codegen_place(&mut bx, &output.as_ref()) }).collect(); let input_vals = asm.inputs.iter() diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 414871be61..9fbb44dcc9 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -3,12 +3,12 @@ use rustc::ty::Ty; use super::write::WriteBackendMethods; use super::CodegenObject; -use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::EncodedMetadata; use rustc::session::{Session, config}; use rustc::ty::TyCtxt; use rustc_codegen_utils::codegen_backend::CodegenBackend; use std::sync::Arc; +use syntax::ext::allocator::AllocatorKind; use syntax_pos::symbol::InternedString; pub trait BackendTypes { @@ -44,7 +44,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se mods: &mut Self::Module, kind: AllocatorKind, ); - fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: InternedString); + fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: InternedString); // If find_features is true this won't access `sess.crate_types` by assuming // that `is_pie_binary` is false. When we discover LLVM target features // `sess.crate_types` is uninitialized so we cannot access it. diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 1c80e614db..3a144f0b0e 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -36,7 +36,7 @@ pub trait BuilderMethods<'a, 'tcx>: { fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self; - fn build_sibling_block<'b>(&self, name: &'b str) -> Self; + fn build_sibling_block(&self, name: &str) -> Self; fn cx(&self) -> &Self::CodegenCx; fn llbb(&self) -> Self::BasicBlock; diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 46286b5329..e7ce03f183 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -17,6 +17,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_u64(&self, i: u64) -> Self::Value; fn const_usize(&self, i: u64) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value; + fn const_real(&self, t: Self::Type, val: f64) -> Self::Value; fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; @@ -34,7 +35,6 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn from_const_alloc( &self, layout: layout::TyLayout<'tcx>, - align: layout::Align, alloc: &Allocation, offset: layout::Size, ) -> PlaceRef<'tcx, Self::Value>; diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index aa38d8d518..13f72e2381 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -77,11 +77,12 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { } fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) { + let param_env = ty::ParamEnv::reveal_all(); + if ty.is_sized(self.tcx().at(DUMMY_SP), param_env) { return false; } - let tail = self.tcx().struct_tail(ty); + let tail = self.tcx().struct_tail_erasing_lifetimes(ty, param_env); match tail.sty { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml index b218d18a06..d93589ea84 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_codegen_utils/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [lib] name = "rustc_codegen_utils" path = "lib.rs" -crate-type = ["dylib"] test = false [dependencies] diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 7a7a50a25f..262cfb1658 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -5,8 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(warnings)] -#![feature(box_syntax)] use std::any::Any; use std::sync::mpsc; diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 942c2d13fa..4ea375b59b 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -10,16 +10,11 @@ #![feature(core_intrinsics)] #![feature(never_type)] #![feature(nll)] -#![allow(unused_attributes)] #![feature(rustc_diagnostic_macros)] #![feature(in_band_lifetimes)] #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index a2ac64fa7e..6b9258c32e 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -57,7 +57,7 @@ pub fn find_crate_name(sess: Option<&Session>, if let Some(ref s) = sess.opts.crate_name { if let Some((attr, name)) = attr_crate_name { if name.as_str() != *s { - let msg = format!("--crate-name and #[crate_name] are \ + let msg = format!("`--crate-name` and `#[crate_name]` are \ required to match, but `{}` != `{}`", s, name); sess.span_err(attr.span, &msg); diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs index 8a54fb6bbc..47601da8b7 100644 --- a/src/librustc_codegen_utils/symbol_names/v0.rs +++ b/src/librustc_codegen_utils/symbol_names/v0.rs @@ -512,7 +512,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { } self = ct.ty.print(self)?; - if let Some(bits) = ct.assert_bits(self.tcx, ty::ParamEnv::empty().and(ct.ty)) { + if let Some(bits) = ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty) { let _ = write!(self.out, "{:x}_", bits); } else { // NOTE(eddyb) despite having the path, we need to diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index f48d1f2853..f562744dbe 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -11,7 +11,7 @@ use syntax::symbol::{Symbol, sym}; const SYMBOL_NAME: Symbol = sym::rustc_symbol_name; const DEF_PATH: Symbol = sym::rustc_def_path; -pub fn report_symbol_names<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn report_symbol_names(tcx: TyCtxt<'_>) { // if the `rustc_attrs` feature is not enabled, then the // attributes we are interested in cannot be present anyway, so // skip the walk. @@ -33,7 +33,7 @@ impl SymbolNamesTest<'tcx> { fn process_attrs(&mut self, hir_id: hir::HirId) { let tcx = self.tcx; - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); for attr in tcx.get_attrs(def_id).iter() { if attr.check_name(SYMBOL_NAME) { // for now, can only use on monomorphic names diff --git a/src/librustc_cratesio_shim/Cargo.toml b/src/librustc_cratesio_shim/Cargo.toml deleted file mode 100644 index 6bdfbe0935..0000000000 --- a/src/librustc_cratesio_shim/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -# This crate exists to allow rustc to link certain crates from crates.io into -# the distribution. This doesn't work normally because: -# -# - Cargo always builds dependencies as rlibs: -# https://github.com/rust-lang/cargo/issues/629 -# - rustc wants to avoid multiple definitions of the same symbol, so it refuses -# to link multiple dylibs containing the same rlib -# - multiple dylibs depend on the same crates.io crates -# -# This solution works by including all the conflicting rlibs in a single dylib, -# which is then linked into all dylibs that depend on these crates.io crates. -# The result is that each rlib only appears once, and things work! - -[package] -authors = ["The Rust Project Developers"] -name = "rustc_cratesio_shim" -version = "0.0.0" -edition = "2018" - -[lib] -crate-type = ["dylib"] - -[dependencies] -bitflags = "1.0" -log = "0.4" -unicode-width = "0.1.4" diff --git a/src/librustc_cratesio_shim/src/lib.rs b/src/librustc_cratesio_shim/src/lib.rs deleted file mode 100644 index 4c170f4f5f..0000000000 --- a/src/librustc_cratesio_shim/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![deny(rust_2018_idioms)] - -// See Cargo.toml for a comment explaining this crate. -#![allow(unused_extern_crates)] - -#![feature(nll)] - -extern crate bitflags; -extern crate log; -extern crate proc_macro; -extern crate unicode_width; diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index cd792d3118..288676ce3f 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [lib] name = "rustc_data_structures" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] ena = "0.13" @@ -15,10 +15,10 @@ indexmap = "1" log = "0.4" jobserver_crate = { version = "0.1.13", package = "jobserver" } lazy_static = "1" -rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } graphviz = { path = "../libgraphviz" } cfg-if = "0.1.2" +crossbeam-utils = { version = "0.6.5", features = ["nightly"] } stable_deref_trait = "1.0.0" rayon = { version = "0.2.0", package = "rustc-rayon" } rayon-core = { version = "0.2.0", package = "rustc-rayon-core" } diff --git a/src/librustc_data_structures/base_n.rs b/src/librustc_data_structures/base_n.rs index f1bd3f03ae..9b63a892b8 100644 --- a/src/librustc_data_structures/base_n.rs +++ b/src/librustc_data_structures/base_n.rs @@ -3,6 +3,9 @@ use std::str; +#[cfg(test)] +mod tests; + pub const MAX_BASE: usize = 64; pub const ALPHANUMERIC_ONLY: usize = 62; pub const CASE_INSENSITIVE: usize = 36; @@ -38,24 +41,3 @@ pub fn encode(n: u128, base: usize) -> String { push_str(n, base, &mut s); s } - -#[test] -fn test_encode() { - fn test(n: u128, base: usize) { - assert_eq!(Ok(n), u128::from_str_radix(&encode(n, base), base as u32)); - } - - for base in 2..37 { - test(0, base); - test(1, base); - test(35, base); - test(36, base); - test(37, base); - test(u64::max_value() as u128, base); - test(u128::max_value(), base); - - for i in 0 .. 1_000 { - test(i * 983, base); - } - } -} diff --git a/src/librustc_data_structures/base_n/tests.rs b/src/librustc_data_structures/base_n/tests.rs new file mode 100644 index 0000000000..0b0a8c5e25 --- /dev/null +++ b/src/librustc_data_structures/base_n/tests.rs @@ -0,0 +1,22 @@ +use super::*; + +#[test] +fn test_encode() { + fn test(n: u128, base: usize) { + assert_eq!(Ok(n), u128::from_str_radix(&encode(n, base), base as u32)); + } + + for base in 2..37 { + test(0, base); + test(1, base); + test(35, base); + test(36, base); + test(37, base); + test(u64::max_value() as u128, base); + test(u128::max_value(), base); + + for i in 0 .. 1_000 { + test(i * 983, base); + } + } +} diff --git a/src/librustc_data_structures/binary_search_util/mod.rs b/src/librustc_data_structures/binary_search_util/mod.rs index 32aa1cb6b1..6d1e1abbce 100644 --- a/src/librustc_data_structures/binary_search_util/mod.rs +++ b/src/librustc_data_structures/binary_search_util/mod.rs @@ -1,5 +1,5 @@ #[cfg(test)] -mod test; +mod tests; /// Uses a sorted slice `data: &[E]` as a kind of "multi-map". The /// `key_fn` extracts a key of type `K` from the data, and this diff --git a/src/librustc_data_structures/binary_search_util/test.rs b/src/librustc_data_structures/binary_search_util/tests.rs similarity index 100% rename from src/librustc_data_structures/binary_search_util/test.rs rename to src/librustc_data_structures/binary_search_util/tests.rs diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index 5d8388d89f..fe8ef64243 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -5,10 +5,9 @@ use std::iter; use std::marker::PhantomData; use std::mem; use std::slice; + #[cfg(test)] -extern crate test; -#[cfg(test)] -use test::Bencher; +mod tests; pub type Word = u64; pub const WORD_BYTES: usize = mem::size_of::(); @@ -168,7 +167,7 @@ impl BitSet { /// Iterates over the indices of set bits in a sorted order. #[inline] - pub fn iter<'a>(&'a self) -> BitIter<'a, T> { + pub fn iter(&self) -> BitIter<'_, T> { BitIter { cur: None, iter: self.words.iter().enumerate(), @@ -849,7 +848,7 @@ impl BitMatrix { /// Iterates through all the columns set to true in a given row of /// the matrix. - pub fn iter<'a>(&'a self, row: R) -> BitIter<'a, C> { + pub fn iter(&self, row: R) -> BitIter<'_, C> { assert!(row.index() < self.num_rows); let (start, end) = self.range(row); BitIter { @@ -983,368 +982,3 @@ fn word_index_and_mask(elem: T) -> (usize, Word) { let mask = 1 << (elem % WORD_BITS); (word_index, mask) } - -#[test] -fn test_new_filled() { - for i in 0..128 { - let idx_buf = BitSet::new_filled(i); - let elems: Vec = idx_buf.iter().collect(); - let expected: Vec = (0..i).collect(); - assert_eq!(elems, expected); - } -} - -#[test] -fn bitset_iter_works() { - let mut bitset: BitSet = BitSet::new_empty(100); - bitset.insert(1); - bitset.insert(10); - bitset.insert(19); - bitset.insert(62); - bitset.insert(63); - bitset.insert(64); - bitset.insert(65); - bitset.insert(66); - bitset.insert(99); - assert_eq!( - bitset.iter().collect::>(), - [1, 10, 19, 62, 63, 64, 65, 66, 99] - ); -} - -#[test] -fn bitset_iter_works_2() { - let mut bitset: BitSet = BitSet::new_empty(320); - bitset.insert(0); - bitset.insert(127); - bitset.insert(191); - bitset.insert(255); - bitset.insert(319); - assert_eq!(bitset.iter().collect::>(), [0, 127, 191, 255, 319]); -} - -#[test] -fn union_two_sets() { - let mut set1: BitSet = BitSet::new_empty(65); - let mut set2: BitSet = BitSet::new_empty(65); - assert!(set1.insert(3)); - assert!(!set1.insert(3)); - assert!(set2.insert(5)); - assert!(set2.insert(64)); - assert!(set1.union(&set2)); - assert!(!set1.union(&set2)); - assert!(set1.contains(3)); - assert!(!set1.contains(4)); - assert!(set1.contains(5)); - assert!(!set1.contains(63)); - assert!(set1.contains(64)); -} - -#[test] -fn hybrid_bitset() { - let mut sparse038: HybridBitSet = HybridBitSet::new_empty(256); - assert!(sparse038.is_empty()); - assert!(sparse038.insert(0)); - assert!(sparse038.insert(1)); - assert!(sparse038.insert(8)); - assert!(sparse038.insert(3)); - assert!(!sparse038.insert(3)); - assert!(sparse038.remove(1)); - assert!(!sparse038.is_empty()); - assert_eq!(sparse038.iter().collect::>(), [0, 3, 8]); - - for i in 0..256 { - if i == 0 || i == 3 || i == 8 { - assert!(sparse038.contains(i)); - } else { - assert!(!sparse038.contains(i)); - } - } - - let mut sparse01358 = sparse038.clone(); - assert!(sparse01358.insert(1)); - assert!(sparse01358.insert(5)); - assert_eq!(sparse01358.iter().collect::>(), [0, 1, 3, 5, 8]); - - let mut dense10 = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(dense10.insert(i)); - } - assert!(!dense10.is_empty()); - assert_eq!(dense10.iter().collect::>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - - let mut dense256 = HybridBitSet::new_empty(256); - assert!(dense256.is_empty()); - dense256.insert_all(); - assert!(!dense256.is_empty()); - for i in 0..256 { - assert!(dense256.contains(i)); - } - - assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) - assert!(sparse01358.superset(&sparse038)); // sparse + sparse - assert!(dense10.superset(&sparse038)); // dense + sparse - assert!(dense10.superset(&dense10)); // dense + dense (self) - assert!(dense256.superset(&dense10)); // dense + dense - - let mut hybrid = sparse038; - assert!(!sparse01358.union(&hybrid)); // no change - assert!(hybrid.union(&sparse01358)); - assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); - assert!(!dense10.union(&sparse01358)); - assert!(!dense256.union(&dense10)); - let mut dense = dense10; - assert!(dense.union(&dense256)); - assert!(dense.superset(&dense256) && dense256.superset(&dense)); - assert!(hybrid.union(&dense256)); - assert!(hybrid.superset(&dense256) && dense256.superset(&hybrid)); - - assert_eq!(dense256.iter().count(), 256); - let mut dense0 = dense256; - for i in 0..256 { - assert!(dense0.remove(i)); - } - assert!(!dense0.remove(0)); - assert!(dense0.is_empty()); -} - -#[test] -fn grow() { - let mut set: GrowableBitSet = GrowableBitSet::with_capacity(65); - for index in 0..65 { - assert!(set.insert(index)); - assert!(!set.insert(index)); - } - set.ensure(128); - - // Check if the bits set before growing are still set - for index in 0..65 { - assert!(set.contains(index)); - } - - // Check if the new bits are all un-set - for index in 65..128 { - assert!(!set.contains(index)); - } - - // Check that we can set all new bits without running out of bounds - for index in 65..128 { - assert!(set.insert(index)); - assert!(!set.insert(index)); - } -} - -#[test] -fn matrix_intersection() { - let mut matrix: BitMatrix = BitMatrix::new(200, 200); - - // (*) Elements reachable from both 2 and 65. - - matrix.insert(2, 3); - matrix.insert(2, 6); - matrix.insert(2, 10); // (*) - matrix.insert(2, 64); // (*) - matrix.insert(2, 65); - matrix.insert(2, 130); - matrix.insert(2, 160); // (*) - - matrix.insert(64, 133); - - matrix.insert(65, 2); - matrix.insert(65, 8); - matrix.insert(65, 10); // (*) - matrix.insert(65, 64); // (*) - matrix.insert(65, 68); - matrix.insert(65, 133); - matrix.insert(65, 160); // (*) - - let intersection = matrix.intersect_rows(2, 64); - assert!(intersection.is_empty()); - - let intersection = matrix.intersect_rows(2, 65); - assert_eq!(intersection, &[10, 64, 160]); -} - -#[test] -fn matrix_iter() { - let mut matrix: BitMatrix = BitMatrix::new(64, 100); - matrix.insert(3, 22); - matrix.insert(3, 75); - matrix.insert(2, 99); - matrix.insert(4, 0); - matrix.union_rows(3, 5); - matrix.insert_all_into_row(6); - - let expected = [99]; - let mut iter = expected.iter(); - for i in matrix.iter(2) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - assert_eq!(matrix.count(3), expected.len()); - for i in matrix.iter(3) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [0]; - let mut iter = expected.iter(); - assert_eq!(matrix.count(4), expected.len()); - for i in matrix.iter(4) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - assert_eq!(matrix.count(5), expected.len()); - for i in matrix.iter(5) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - assert_eq!(matrix.count(6), 100); - let mut count = 0; - for (idx, i) in matrix.iter(6).enumerate() { - assert_eq!(idx, i); - count += 1; - } - assert_eq!(count, 100); - - if let Some(i) = matrix.iter(7).next() { - panic!("expected no elements in row, but contains element {:?}", i); - } -} - -#[test] -fn sparse_matrix_iter() { - let mut matrix: SparseBitMatrix = SparseBitMatrix::new(100); - matrix.insert(3, 22); - matrix.insert(3, 75); - matrix.insert(2, 99); - matrix.insert(4, 0); - matrix.union_rows(3, 5); - - let expected = [99]; - let mut iter = expected.iter(); - for i in matrix.iter(2) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - for i in matrix.iter(3) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [0]; - let mut iter = expected.iter(); - for i in matrix.iter(4) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - for i in matrix.iter(5) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); -} - -/// Merge dense hybrid set into empty sparse hybrid set. -#[bench] -fn union_hybrid_sparse_empty_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set with same indices. -#[bench] -fn union_hybrid_sparse_full_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set with indices over the whole domain. -#[bench] -fn union_hybrid_sparse_domain_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i*64)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into empty hybrid set where the domain is very small. -#[bench] -fn union_hybrid_sparse_empty_small_domain(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_dense.insert(i)); - } - let pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set where the domain is very small. -#[bench] -fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} diff --git a/src/librustc_data_structures/bit_set/tests.rs b/src/librustc_data_structures/bit_set/tests.rs new file mode 100644 index 0000000000..ac7913815f --- /dev/null +++ b/src/librustc_data_structures/bit_set/tests.rs @@ -0,0 +1,369 @@ +use super::*; + +extern crate test; +use test::Bencher; + +#[test] +fn test_new_filled() { + for i in 0..128 { + let idx_buf = BitSet::new_filled(i); + let elems: Vec = idx_buf.iter().collect(); + let expected: Vec = (0..i).collect(); + assert_eq!(elems, expected); + } +} + +#[test] +fn bitset_iter_works() { + let mut bitset: BitSet = BitSet::new_empty(100); + bitset.insert(1); + bitset.insert(10); + bitset.insert(19); + bitset.insert(62); + bitset.insert(63); + bitset.insert(64); + bitset.insert(65); + bitset.insert(66); + bitset.insert(99); + assert_eq!( + bitset.iter().collect::>(), + [1, 10, 19, 62, 63, 64, 65, 66, 99] + ); +} + +#[test] +fn bitset_iter_works_2() { + let mut bitset: BitSet = BitSet::new_empty(320); + bitset.insert(0); + bitset.insert(127); + bitset.insert(191); + bitset.insert(255); + bitset.insert(319); + assert_eq!(bitset.iter().collect::>(), [0, 127, 191, 255, 319]); +} + +#[test] +fn union_two_sets() { + let mut set1: BitSet = BitSet::new_empty(65); + let mut set2: BitSet = BitSet::new_empty(65); + assert!(set1.insert(3)); + assert!(!set1.insert(3)); + assert!(set2.insert(5)); + assert!(set2.insert(64)); + assert!(set1.union(&set2)); + assert!(!set1.union(&set2)); + assert!(set1.contains(3)); + assert!(!set1.contains(4)); + assert!(set1.contains(5)); + assert!(!set1.contains(63)); + assert!(set1.contains(64)); +} + +#[test] +fn hybrid_bitset() { + let mut sparse038: HybridBitSet = HybridBitSet::new_empty(256); + assert!(sparse038.is_empty()); + assert!(sparse038.insert(0)); + assert!(sparse038.insert(1)); + assert!(sparse038.insert(8)); + assert!(sparse038.insert(3)); + assert!(!sparse038.insert(3)); + assert!(sparse038.remove(1)); + assert!(!sparse038.is_empty()); + assert_eq!(sparse038.iter().collect::>(), [0, 3, 8]); + + for i in 0..256 { + if i == 0 || i == 3 || i == 8 { + assert!(sparse038.contains(i)); + } else { + assert!(!sparse038.contains(i)); + } + } + + let mut sparse01358 = sparse038.clone(); + assert!(sparse01358.insert(1)); + assert!(sparse01358.insert(5)); + assert_eq!(sparse01358.iter().collect::>(), [0, 1, 3, 5, 8]); + + let mut dense10 = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(dense10.insert(i)); + } + assert!(!dense10.is_empty()); + assert_eq!(dense10.iter().collect::>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + + let mut dense256 = HybridBitSet::new_empty(256); + assert!(dense256.is_empty()); + dense256.insert_all(); + assert!(!dense256.is_empty()); + for i in 0..256 { + assert!(dense256.contains(i)); + } + + assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) + assert!(sparse01358.superset(&sparse038)); // sparse + sparse + assert!(dense10.superset(&sparse038)); // dense + sparse + assert!(dense10.superset(&dense10)); // dense + dense (self) + assert!(dense256.superset(&dense10)); // dense + dense + + let mut hybrid = sparse038; + assert!(!sparse01358.union(&hybrid)); // no change + assert!(hybrid.union(&sparse01358)); + assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); + assert!(!dense10.union(&sparse01358)); + assert!(!dense256.union(&dense10)); + let mut dense = dense10; + assert!(dense.union(&dense256)); + assert!(dense.superset(&dense256) && dense256.superset(&dense)); + assert!(hybrid.union(&dense256)); + assert!(hybrid.superset(&dense256) && dense256.superset(&hybrid)); + + assert_eq!(dense256.iter().count(), 256); + let mut dense0 = dense256; + for i in 0..256 { + assert!(dense0.remove(i)); + } + assert!(!dense0.remove(0)); + assert!(dense0.is_empty()); +} + +#[test] +fn grow() { + let mut set: GrowableBitSet = GrowableBitSet::with_capacity(65); + for index in 0..65 { + assert!(set.insert(index)); + assert!(!set.insert(index)); + } + set.ensure(128); + + // Check if the bits set before growing are still set + for index in 0..65 { + assert!(set.contains(index)); + } + + // Check if the new bits are all un-set + for index in 65..128 { + assert!(!set.contains(index)); + } + + // Check that we can set all new bits without running out of bounds + for index in 65..128 { + assert!(set.insert(index)); + assert!(!set.insert(index)); + } +} + +#[test] +fn matrix_intersection() { + let mut matrix: BitMatrix = BitMatrix::new(200, 200); + + // (*) Elements reachable from both 2 and 65. + + matrix.insert(2, 3); + matrix.insert(2, 6); + matrix.insert(2, 10); // (*) + matrix.insert(2, 64); // (*) + matrix.insert(2, 65); + matrix.insert(2, 130); + matrix.insert(2, 160); // (*) + + matrix.insert(64, 133); + + matrix.insert(65, 2); + matrix.insert(65, 8); + matrix.insert(65, 10); // (*) + matrix.insert(65, 64); // (*) + matrix.insert(65, 68); + matrix.insert(65, 133); + matrix.insert(65, 160); // (*) + + let intersection = matrix.intersect_rows(2, 64); + assert!(intersection.is_empty()); + + let intersection = matrix.intersect_rows(2, 65); + assert_eq!(intersection, &[10, 64, 160]); +} + +#[test] +fn matrix_iter() { + let mut matrix: BitMatrix = BitMatrix::new(64, 100); + matrix.insert(3, 22); + matrix.insert(3, 75); + matrix.insert(2, 99); + matrix.insert(4, 0); + matrix.union_rows(3, 5); + matrix.insert_all_into_row(6); + + let expected = [99]; + let mut iter = expected.iter(); + for i in matrix.iter(2) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + assert_eq!(matrix.count(3), expected.len()); + for i in matrix.iter(3) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [0]; + let mut iter = expected.iter(); + assert_eq!(matrix.count(4), expected.len()); + for i in matrix.iter(4) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + assert_eq!(matrix.count(5), expected.len()); + for i in matrix.iter(5) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + assert_eq!(matrix.count(6), 100); + let mut count = 0; + for (idx, i) in matrix.iter(6).enumerate() { + assert_eq!(idx, i); + count += 1; + } + assert_eq!(count, 100); + + if let Some(i) = matrix.iter(7).next() { + panic!("expected no elements in row, but contains element {:?}", i); + } +} + +#[test] +fn sparse_matrix_iter() { + let mut matrix: SparseBitMatrix = SparseBitMatrix::new(100); + matrix.insert(3, 22); + matrix.insert(3, 75); + matrix.insert(2, 99); + matrix.insert(4, 0); + matrix.union_rows(3, 5); + + let expected = [99]; + let mut iter = expected.iter(); + for i in matrix.iter(2) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + for i in matrix.iter(3) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [0]; + let mut iter = expected.iter(); + for i in matrix.iter(4) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + for i in matrix.iter(5) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); +} + +/// Merge dense hybrid set into empty sparse hybrid set. +#[bench] +fn union_hybrid_sparse_empty_to_dense(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(pre_dense.insert(i)); + } + let pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into full hybrid set with same indices. +#[bench] +fn union_hybrid_sparse_full_to_dense(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(pre_dense.insert(i)); + } + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); + for i in 0..SPARSE_MAX { + assert!(pre_sparse.insert(i)); + } + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into full hybrid set with indices over the whole domain. +#[bench] +fn union_hybrid_sparse_domain_to_dense(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); + for i in 0..10 { + assert!(pre_dense.insert(i)); + } + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); + for i in 0..SPARSE_MAX { + assert!(pre_sparse.insert(i*64)); + } + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into empty hybrid set where the domain is very small. +#[bench] +fn union_hybrid_sparse_empty_small_domain(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + for i in 0..SPARSE_MAX { + assert!(pre_dense.insert(i)); + } + let pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into full hybrid set where the domain is very small. +#[bench] +fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + for i in 0..SPARSE_MAX { + assert!(pre_dense.insert(i)); + } + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + for i in 0..SPARSE_MAX { + assert!(pre_sparse.insert(i)); + } + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index 7975c62b90..c8012bb942 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -1,7 +1,6 @@ use crate::stable_hasher; use std::mem; -use serialize; -use serialize::opaque::{EncodeResult, Encoder, Decoder}; +use rustc_serialize::opaque::{EncodeResult, Encoder, Decoder}; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] pub struct Fingerprint(u64, u64); @@ -58,7 +57,7 @@ impl Fingerprint { Ok(()) } - pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result { + pub fn decode_opaque(decoder: &mut Decoder<'_>) -> Result { let mut bytes = [0; 16]; decoder.read_raw_bytes(&mut bytes)?; @@ -85,17 +84,17 @@ impl stable_hasher::StableHasherResult for Fingerprint { impl_stable_hash_via_hash!(Fingerprint); -impl serialize::UseSpecializedEncodable for Fingerprint { } +impl rustc_serialize::UseSpecializedEncodable for Fingerprint { } -impl serialize::UseSpecializedDecodable for Fingerprint { } +impl rustc_serialize::UseSpecializedDecodable for Fingerprint { } -impl serialize::SpecializedEncoder for serialize::opaque::Encoder { +impl rustc_serialize::SpecializedEncoder for Encoder { fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { f.encode_opaque(self) } } -impl<'a> serialize::SpecializedDecoder for serialize::opaque::Decoder<'a> { +impl<'a> rustc_serialize::SpecializedDecoder for Decoder<'a> { fn specialized_decode(&mut self) -> Result { Fingerprint::decode_opaque(self) } diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs index b63701dbc0..b0bd137f2c 100644 --- a/src/librustc_data_structures/flock.rs +++ b/src/librustc_data_structures/flock.rs @@ -238,14 +238,14 @@ cfg_if! { .write(true); } - debug!("Attempting to open lock file `{}`", p.display()); + debug!("attempting to open lock file `{}`", p.display()); let file = match open_options.open(p) { Ok(file) => { - debug!("Lock file opened successfully"); + debug!("lock file opened successfully"); file } Err(err) => { - debug!("Error opening lock file: {}", err); + debug!("error opening lock file: {}", err); return Err(err) } }; @@ -262,7 +262,7 @@ cfg_if! { dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; } - debug!("Attempting to acquire lock on lock file `{}`", + debug!("attempting to acquire lock on lock file `{}`", p.display()); LockFileEx(file.as_raw_handle(), dwFlags, @@ -273,10 +273,10 @@ cfg_if! { }; if ret == 0 { let err = io::Error::last_os_error(); - debug!("Failed acquiring file lock: {}", err); + debug!("failed acquiring file lock: {}", err); Err(err) } else { - debug!("Successfully acquired lock."); + debug!("successfully acquired lock"); Ok(Lock { _file: file }) } } diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 93a2a261c6..41e6b72953 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -9,7 +9,7 @@ use super::iterate::reverse_post_order; use super::ControlFlowGraph; #[cfg(test)] -mod test; +mod tests; pub fn dominators(graph: &G) -> Dominators { let start_node = graph.start_node(); @@ -127,11 +127,6 @@ impl Dominators { // FIXME -- could be optimized by using post-order-rank self.dominators(node).any(|n| n == dom) } - - #[cfg(test)] - fn all_immediate_dominators(&self) -> &IndexVec> { - &self.immediate_dominators - } } pub struct Iter<'dom, Node: Idx> { diff --git a/src/librustc_data_structures/graph/dominators/test.rs b/src/librustc_data_structures/graph/dominators/tests.rs similarity index 85% rename from src/librustc_data_structures/graph/dominators/test.rs rename to src/librustc_data_structures/graph/dominators/tests.rs index 5d17ce9e90..92301ff652 100644 --- a/src/librustc_data_structures/graph/dominators/test.rs +++ b/src/librustc_data_structures/graph/dominators/tests.rs @@ -1,13 +1,13 @@ -use super::super::test::TestGraph; - use super::*; +use super::super::tests::TestGraph; + #[test] fn diamond() { let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]); let dominators = dominators(&graph); - let immediate_dominators = dominators.all_immediate_dominators(); + let immediate_dominators = &dominators.immediate_dominators; assert_eq!(immediate_dominators[0], Some(0)); assert_eq!(immediate_dominators[1], Some(0)); assert_eq!(immediate_dominators[2], Some(0)); @@ -22,7 +22,7 @@ fn paper() { (2, 1)]); let dominators = dominators(&graph); - let immediate_dominators = dominators.all_immediate_dominators(); + let immediate_dominators = &dominators.immediate_dominators; assert_eq!(immediate_dominators[0], None); // <-- note that 0 is not in graph assert_eq!(immediate_dominators[1], Some(6)); assert_eq!(immediate_dominators[2], Some(6)); diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/src/librustc_data_structures/graph/implementation/mod.rs index de4b1bcd0c..d2699004c8 100644 --- a/src/librustc_data_structures/graph/implementation/mod.rs +++ b/src/librustc_data_structures/graph/implementation/mod.rs @@ -247,11 +247,11 @@ impl Graph { self.incoming_edges(target).sources() } - pub fn depth_traverse<'a>( - &'a self, + pub fn depth_traverse( + &self, start: NodeIndex, direction: Direction, - ) -> DepthFirstTraversal<'a, N, E> { + ) -> DepthFirstTraversal<'_, N, E> { DepthFirstTraversal::with_start_node(self, start, direction) } diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs index 5612778ce0..c4185fc7cd 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/src/librustc_data_structures/graph/iterate/mod.rs @@ -3,7 +3,7 @@ use super::{DirectedGraph, WithNumNodes, WithSuccessors}; use crate::bit_set::BitSet; #[cfg(test)] -mod test; +mod tests; pub fn post_order_from( graph: &G, diff --git a/src/librustc_data_structures/graph/iterate/test.rs b/src/librustc_data_structures/graph/iterate/tests.rs similarity index 85% rename from src/librustc_data_structures/graph/iterate/test.rs rename to src/librustc_data_structures/graph/iterate/tests.rs index 62e48aaec5..6c7cfd6d8a 100644 --- a/src/librustc_data_structures/graph/iterate/test.rs +++ b/src/librustc_data_structures/graph/iterate/tests.rs @@ -1,4 +1,4 @@ -use super::super::test::TestGraph; +use super::super::tests::TestGraph; use super::*; diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 2787fa3c6b..662581ca1e 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -8,7 +8,7 @@ pub mod scc; pub mod vec_graph; #[cfg(test)] -mod test; +mod tests; pub trait DirectedGraph { type Node: Idx; @@ -26,10 +26,10 @@ pub trait WithSuccessors: DirectedGraph where Self: for<'graph> GraphSuccessors<'graph, Item = ::Node>, { - fn successors<'graph>( - &'graph self, + fn successors( + &self, node: Self::Node, - ) -> >::Iter; + ) -> >::Iter; fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_, Self> where @@ -39,6 +39,7 @@ where } } +#[allow(unused_lifetimes)] pub trait GraphSuccessors<'graph> { type Item; type Iter: Iterator; @@ -48,12 +49,13 @@ pub trait WithPredecessors: DirectedGraph where Self: for<'graph> GraphPredecessors<'graph, Item = ::Node>, { - fn predecessors<'graph>( - &'graph self, + fn predecessors( + &self, node: Self::Node, - ) -> >::Iter; + ) -> >::Iter; } +#[allow(unused_lifetimes)] pub trait GraphPredecessors<'graph> { type Item; type Iter: Iterator; diff --git a/src/librustc_data_structures/graph/reference.rs b/src/librustc_data_structures/graph/reference.rs index 5ad2a71e1d..9442bb3cde 100644 --- a/src/librustc_data_structures/graph/reference.rs +++ b/src/librustc_data_structures/graph/reference.rs @@ -17,15 +17,15 @@ impl<'graph, G: WithStartNode> WithStartNode for &'graph G { } impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G { - fn successors<'iter>(&'iter self, node: Self::Node) -> >::Iter { + fn successors(&self, node: Self::Node) -> >::Iter { (**self).successors(node) } } impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G { - fn predecessors<'iter>(&'iter self, - node: Self::Node) - -> >::Iter { + fn predecessors(&self, + node: Self::Node) + -> >::Iter { (**self).predecessors(node) } } diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs index 78554cda77..23a1a2a90a 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/src/librustc_data_structures/graph/scc/mod.rs @@ -9,7 +9,8 @@ use crate::graph::vec_graph::VecGraph; use crate::indexed_vec::{Idx, IndexVec}; use std::ops::Range; -mod test; +#[cfg(test)] +mod tests; /// Strongly connected components (SCC) of a graph. The type `N` is /// the index type for the graph nodes and `S` is the index type for diff --git a/src/librustc_data_structures/graph/scc/test.rs b/src/librustc_data_structures/graph/scc/tests.rs similarity index 98% rename from src/librustc_data_structures/graph/scc/test.rs rename to src/librustc_data_structures/graph/scc/tests.rs index da3a1ceefe..6da3ac0ecb 100644 --- a/src/librustc_data_structures/graph/scc/test.rs +++ b/src/librustc_data_structures/graph/scc/tests.rs @@ -1,6 +1,4 @@ -#![cfg(test)] - -use crate::graph::test::TestGraph; +use crate::graph::tests::TestGraph; use super::*; #[test] diff --git a/src/librustc_data_structures/graph/test.rs b/src/librustc_data_structures/graph/tests.rs similarity index 87% rename from src/librustc_data_structures/graph/test.rs rename to src/librustc_data_structures/graph/tests.rs index b390c41957..bc142144e9 100644 --- a/src/librustc_data_structures/graph/test.rs +++ b/src/librustc_data_structures/graph/tests.rs @@ -51,15 +51,15 @@ impl WithNumNodes for TestGraph { } impl WithPredecessors for TestGraph { - fn predecessors<'graph>(&'graph self, - node: usize) - -> >::Iter { + fn predecessors(&self, + node: usize) + -> >::Iter { self.predecessors[&node].iter().cloned() } } impl WithSuccessors for TestGraph { - fn successors<'graph>(&'graph self, node: usize) -> >::Iter { + fn successors(&self, node: usize) -> >::Iter { self.successors[&node].iter().cloned() } } diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/src/librustc_data_structures/graph/vec_graph/mod.rs index 6fb1bb42d2..19c61f2680 100644 --- a/src/librustc_data_structures/graph/vec_graph/mod.rs +++ b/src/librustc_data_structures/graph/vec_graph/mod.rs @@ -2,7 +2,7 @@ use crate::indexed_vec::{Idx, IndexVec}; use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; #[cfg(test)] -mod test; +mod tests; pub struct VecGraph { /// Maps from a given node to an index where the set of successors diff --git a/src/librustc_data_structures/graph/vec_graph/test.rs b/src/librustc_data_structures/graph/vec_graph/tests.rs similarity index 100% rename from src/librustc_data_structures/graph/vec_graph/test.rs rename to src/librustc_data_structures/graph/vec_graph/tests.rs diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index b3a810a622..6f40d059be 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -1,3 +1,5 @@ +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; + use std::fmt::Debug; use std::iter::{self, FromIterator}; use std::slice; @@ -8,8 +10,6 @@ use std::hash::Hash; use std::vec; use std::u32; -use rustc_serialize as serialize; - /// Represents some newtyped `usize` wrapper. /// /// Purpose: avoid mixing indexes for different bitvector domains. @@ -57,12 +57,13 @@ impl Idx for u32 { /// `u32::MAX`. You can also customize things like the `Debug` impl, /// what traits are derived, and so forth via the macro. #[macro_export] +#[allow_internal_unstable(step_trait, rustc_attrs)] macro_rules! newtype_index { // ---- public rules ---- // Use default constants ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( - newtype_index!( + $crate::newtype_index!( // Leave out derives marker so we can use its absence to ensure it comes first @attrs [$(#[$attrs])*] @type [$name] @@ -74,7 +75,7 @@ macro_rules! newtype_index { // Define any constants ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( - newtype_index!( + $crate::newtype_index!( // Leave out derives marker so we can use its absence to ensure it comes first @attrs [$(#[$attrs])*] @type [$name] @@ -258,7 +259,7 @@ macro_rules! newtype_index { } } - newtype_index!( + $crate::newtype_index!( @handle_debug @derives [$($derives,)*] @type [$type] @@ -294,7 +295,7 @@ macro_rules! newtype_index { @derives [$_derive:ident, $($derives:ident,)*] @type [$type:ident] @debug_format [$debug_format:tt]) => ( - newtype_index!( + $crate::newtype_index!( @handle_debug @derives [$($derives,)*] @type [$type] @@ -309,7 +310,7 @@ macro_rules! newtype_index { @debug_format [$debug_format:tt] derive [$($derives:ident),*] $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @attrs [$(#[$attrs])*] @type [$type] @max [$max] @@ -329,7 +330,7 @@ macro_rules! newtype_index { derive [$($derives:ident,)+] ENCODABLE = custom $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @attrs [$(#[$attrs])*] @derives [$($derives,)+] @type [$type] @@ -348,7 +349,7 @@ macro_rules! newtype_index { @debug_format [$debug_format:tt] derive [$($derives:ident,)+] $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @derives [$($derives,)+ RustcEncodable,] @attrs [$(#[$attrs])*] @type [$type] @@ -356,7 +357,7 @@ macro_rules! newtype_index { @vis [$v] @debug_format [$debug_format] $($tokens)*); - newtype_index!(@decodable $type); + $crate::newtype_index!(@decodable $type); ); // The case where no derives are added, but encodable is overridden. Don't @@ -368,7 +369,7 @@ macro_rules! newtype_index { @debug_format [$debug_format:tt] ENCODABLE = custom $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @derives [] @attrs [$(#[$attrs])*] @type [$type] @@ -385,7 +386,7 @@ macro_rules! newtype_index { @vis [$v:vis] @debug_format [$debug_format:tt] $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @derives [RustcEncodable,] @attrs [$(#[$attrs])*] @type [$type] @@ -393,21 +394,13 @@ macro_rules! newtype_index { @vis [$v] @debug_format [$debug_format] $($tokens)*); - newtype_index!(@decodable $type); + $crate::newtype_index!(@decodable $type); ); (@decodable $type:ident) => ( - impl $type { - fn __decodable__impl__hack() { - mod __more_hacks_because__self_doesnt_work_in_functions { - extern crate serialize; - use self::serialize::{Decodable, Decoder}; - impl Decodable for super::$type { - fn decode(d: &mut D) -> Result { - d.read_u32().map(Self::from) - } - } - } + impl ::rustc_serialize::Decodable for $type { + fn decode(d: &mut D) -> Result { + d.read_u32().map(Self::from) } } ); @@ -420,7 +413,7 @@ macro_rules! newtype_index { @vis [$v:vis] @debug_format [$debug_format:tt] $name:ident = $constant:expr) => ( - newtype_index!( + $crate::newtype_index!( @derives [$($derives,)*] @attrs [$(#[$attrs])*] @type [$type] @@ -439,7 +432,7 @@ macro_rules! newtype_index { @debug_format [$debug_format:tt] $(#[doc = $doc:expr])* const $name:ident = $constant:expr) => ( - newtype_index!( + $crate::newtype_index!( @derives [$($derives,)*] @attrs [$(#[$attrs])*] @type [$type] @@ -458,7 +451,7 @@ macro_rules! newtype_index { @debug_format [$debug_format:tt] MAX = $max:expr, $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @derives [$($derives,)*] @attrs [$(#[$attrs])*] @type [$type] @@ -477,7 +470,7 @@ macro_rules! newtype_index { @debug_format [$_debug_format:tt] DEBUG_FORMAT = $debug_format:tt, $($tokens:tt)*) => ( - newtype_index!( + $crate::newtype_index!( @derives [$($derives,)*] @attrs [$(#[$attrs])*] @type [$type] @@ -499,7 +492,7 @@ macro_rules! newtype_index { $($tokens:tt)*) => ( $(#[doc = $doc])* pub const $name: $type = $type::from_u32_const($constant); - newtype_index!( + $crate::newtype_index!( @derives [$($derives,)*] @attrs [$(#[$attrs])*] @type [$type] @@ -520,15 +513,15 @@ pub struct IndexVec { // not the phantom data. unsafe impl Send for IndexVec where T: Send {} -impl serialize::Encodable for IndexVec { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - serialize::Encodable::encode(&self.raw, s) +impl Encodable for IndexVec { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&self.raw, s) } } -impl serialize::Decodable for IndexVec { - fn decode(d: &mut D) -> Result { - serialize::Decodable::decode(d).map(|v| { +impl Decodable for IndexVec { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|v| { IndexVec { raw: v, _marker: PhantomData } }) } diff --git a/src/librustc_data_structures/interner.rs b/src/librustc_data_structures/interner.rs deleted file mode 100644 index 36ccbb704a..0000000000 --- a/src/librustc_data_structures/interner.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::hash::Hash; -use std::hash::BuildHasher; -use std::hash::Hasher; -use std::collections::HashMap; -use std::collections::hash_map::RawEntryMut; -use std::borrow::Borrow; - -pub trait HashInterner { - fn intern_ref K>(&mut self, value: &Q, make: F) -> K - where K: Borrow, - Q: Hash + Eq; - - fn intern K>(&mut self, value: Q, make: F) -> K - where K: Borrow, - Q: Hash + Eq; -} - -impl HashInterner for HashMap { - #[inline] - fn intern_ref K>(&mut self, value: &Q, make: F) -> K - where K: Borrow, - Q: Hash + Eq - { - let mut hasher = self.hasher().build_hasher(); - value.hash(&mut hasher); - let hash = hasher.finish(); - let entry = self.raw_entry_mut().from_key_hashed_nocheck(hash, value); - - match entry { - RawEntryMut::Occupied(e) => *e.key(), - RawEntryMut::Vacant(e) => { - let v = make(); - e.insert_hashed_nocheck(hash, v, ()); - v - } - } - } - - #[inline] - fn intern K>(&mut self, value: Q, make: F) -> K - where K: Borrow, - Q: Hash + Eq - { - let mut hasher = self.hasher().build_hasher(); - value.hash(&mut hasher); - let hash = hasher.finish(); - let entry = self.raw_entry_mut().from_key_hashed_nocheck(hash, &value); - - match entry { - RawEntryMut::Occupied(e) => *e.key(), - RawEntryMut::Vacant(e) => { - let v = make(value); - e.insert_hashed_nocheck(hash, v, ()); - v - } - } - } -} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 98c809f7e2..9f103437d3 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -22,25 +22,20 @@ #![feature(stmt_expr_attributes)] #![feature(core_intrinsics)] #![feature(integer_atomics)] +#![feature(test)] +#![feature(associated_type_bounds)] #![cfg_attr(unix, feature(libc))] -#![cfg_attr(test, feature(test))] -#![deny(rust_2018_idioms)] +#![cfg_attr(not(bootstrap), allow(rustc::default_hash_types))] #[macro_use] extern crate log; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving #[cfg(unix)] extern crate libc; #[macro_use] extern crate cfg_if; -// See librustc_cratesio_shim/Cargo.toml for a comment explaining this. -#[allow(unused_extern_crates)] -extern crate rustc_cratesio_shim; - pub use rustc_serialize::hex::ToHex; #[inline(never)] @@ -80,7 +75,6 @@ pub mod flock; pub mod fx; pub mod graph; pub mod indexed_vec; -pub mod interner; pub mod jobserver; pub mod obligation_forest; pub mod owning_ref; @@ -92,6 +86,7 @@ pub use ena::snapshot_vec; pub mod sorted_map; #[macro_use] pub mod stable_hasher; pub mod sync; +pub mod sharded; pub mod tiny_list; pub mod thin_vec; pub mod transitive_relation; diff --git a/src/librustc_data_structures/macros.rs b/src/librustc_data_structures/macros.rs index 6e7a8e9885..3f75523a81 100644 --- a/src/librustc_data_structures/macros.rs +++ b/src/librustc_data_structures/macros.rs @@ -1,7 +1,6 @@ /// A simple static assertion macro. #[macro_export] -#[cfg_attr(bootstrap, allow_internal_unstable(type_ascription, underscore_const_names))] -#[cfg_attr(not(bootstrap), allow_internal_unstable(type_ascription))] +#[allow_internal_unstable(type_ascription)] macro_rules! static_assert { ($test:expr) => { // Use the bool to access an array such that if the bool is false, the access @@ -13,7 +12,6 @@ macro_rules! static_assert { /// Type size assertion. The first argument is a type and the second argument is its expected size. #[macro_export] -#[cfg_attr(bootstrap, allow_internal_unstable(underscore_const_names))] macro_rules! static_assert_size { ($ty:ty, $size:expr) => { const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 557e5e2186..04d2b23ab1 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -94,7 +94,7 @@ use self::node_index::NodeIndex; mod graphviz; #[cfg(test)] -mod test; +mod tests; pub trait ForestObligation : Clone + Debug { type Predicate : Clone + hash::Hash + Eq + Debug; diff --git a/src/librustc_data_structures/obligation_forest/test.rs b/src/librustc_data_structures/obligation_forest/tests.rs similarity index 99% rename from src/librustc_data_structures/obligation_forest/test.rs rename to src/librustc_data_structures/obligation_forest/tests.rs index 27d4bf4959..e20466572a 100644 --- a/src/librustc_data_structures/obligation_forest/test.rs +++ b/src/librustc_data_structures/obligation_forest/tests.rs @@ -1,6 +1,4 @@ -#![cfg(test)] - -use super::{Error, DoCompleted, ObligationForest, ObligationProcessor, Outcome, ProcessResult}; +use super::*; use std::fmt; use std::marker::PhantomData; diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index a7af615fa5..b835b1706b 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -10,7 +10,7 @@ This allows moving and dropping of a `OwningRef` without needing to recreate the This can sometimes be useful because Rust borrowing rules normally prevent moving a type that has been moved from. For example, this kind of code gets rejected: -```rust,ignore +```compile_fail,E0515 fn return_owned_and_referenced<'a>() -> (Vec, &'a [u8]) { let v = vec![1, 2, 3, 4]; let s = &v[1..3]; @@ -43,7 +43,8 @@ and preventing mutable access to root containers, which in practice requires hea as provided by `Box`, `Rc`, etc. Also provided are typedefs for common owner type combinations, -which allow for less verbose type signatures. For example, `BoxRef` instead of `OwningRef, T>`. +which allow for less verbose type signatures. +For example, `BoxRef` instead of `OwningRef, T>`. The crate also provides the more advanced `OwningHandle` type, which allows more freedom in bundling a dependent handle object @@ -283,6 +284,7 @@ impl Erased for T {} /// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box -> Box`. This would be unneeded with /// higher kinded types support in the language. +#[allow(unused_lifetimes)] pub unsafe trait IntoErased<'a> { /// Owner with the dereference type substituted to `Erased`. type Erased; @@ -293,6 +295,7 @@ pub unsafe trait IntoErased<'a> { /// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box -> Box`. This would be unneeded with /// higher kinded types support in the language. +#[allow(unused_lifetimes)] pub unsafe trait IntoErasedSend<'a> { /// Owner with the dereference type substituted to `Erased + Send`. type Erased: Send; @@ -303,6 +306,7 @@ pub unsafe trait IntoErasedSend<'a> { /// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box -> Box`. This would be unneeded with /// higher kinded types support in the language. +#[allow(unused_lifetimes)] pub unsafe trait IntoErasedSendSync<'a> { /// Owner with the dereference type substituted to `Erased + Send + Sync`. type Erased: Send + Sync; @@ -495,7 +499,8 @@ impl OwningRef { } } - /// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`. + /// Erases the concrete base type of the owner with a trait object + /// which implements `Send` and `Sync`. /// /// This allows mixing of owned references with different owner base types. pub fn erase_send_sync_owner<'a>(self) -> OwningRef @@ -507,7 +512,7 @@ impl OwningRef { } } - // TODO: wrap_owner + // UNIMPLEMENTED: wrap_owner // FIXME: Naming convention? /// A getter for the underlying owner. @@ -753,7 +758,7 @@ impl OwningRefMut { } } - // TODO: wrap_owner + // UNIMPLEMENTED: wrap_owner // FIXME: Naming convention? /// A getter for the underlying owner. @@ -842,7 +847,9 @@ pub trait ToHandleMut { } impl OwningHandle - where O: StableAddress, O::Target: ToHandle, H: Deref, +where + O: StableAddress>, + H: Deref, { /// Creates a new `OwningHandle` for a type that implements `ToHandle`. For types /// that don't implement `ToHandle`, callers may invoke `new_with_fn`, which accepts @@ -853,7 +860,9 @@ impl OwningHandle } impl OwningHandle - where O: StableAddress, O::Target: ToHandleMut, H: DerefMut, +where + O: StableAddress>, + H: DerefMut, { /// Creates a new mutable `OwningHandle` for a type that implements `ToHandleMut`. pub fn new_mut(o: O) -> Self { diff --git a/src/librustc_data_structures/owning_ref/tests.rs b/src/librustc_data_structures/owning_ref/tests.rs index d368219cab..5bff5e035b 100644 --- a/src/librustc_data_structures/owning_ref/tests.rs +++ b/src/librustc_data_structures/owning_ref/tests.rs @@ -274,7 +274,9 @@ mod owning_handle { use std::cell::RefCell; let cell = Rc::new(RefCell::new(2)); let cell_ref = RcRef::new(cell); - let mut handle = OwningHandle::new_with_fn(cell_ref, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); + let mut handle = OwningHandle::new_with_fn(cell_ref, |x| { + unsafe { x.as_ref() }.unwrap().borrow_mut() + }); assert_eq!(*handle, 2); *handle = 3; assert_eq!(*handle, 3); @@ -319,8 +321,12 @@ mod owning_handle { let result = { let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString")))); let curr = RcRef::new(complex); - let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); - let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap()); + let curr = OwningHandle::new_with_fn(curr, |x| { + unsafe { x.as_ref() }.unwrap().borrow_mut() + }); + let mut curr = OwningHandle::new_with_fn(curr, |x| { + unsafe { x.as_ref() }.unwrap().try_write().unwrap() + }); assert_eq!(*curr, "someString"); *curr = "someOtherString"; curr @@ -353,8 +359,12 @@ mod owning_handle { let result = { let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString")))); let curr = RcRef::new(complex); - let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); - let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap()); + let curr = OwningHandle::new_with_fn(curr, |x| { + unsafe { x.as_ref() }.unwrap().borrow_mut() + }); + let mut curr = OwningHandle::new_with_fn(curr, |x| { + unsafe { x.as_ref() }.unwrap().try_write().unwrap() + }); assert_eq!(*curr, "someString"); *curr = "someOtherString"; curr diff --git a/src/librustc_data_structures/sharded.rs b/src/librustc_data_structures/sharded.rs new file mode 100644 index 0000000000..31cb22098b --- /dev/null +++ b/src/librustc_data_structures/sharded.rs @@ -0,0 +1,128 @@ +use std::hash::{Hasher, Hash}; +use std::mem; +use std::borrow::Borrow; +use std::collections::hash_map::RawEntryMut; +use crate::fx::{FxHasher, FxHashMap}; +use crate::sync::{Lock, LockGuard}; + +#[derive(Clone, Default)] +#[cfg_attr(parallel_compiler, repr(align(64)))] +struct CacheAligned(T); + +#[cfg(parallel_compiler)] +// 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700, +// but this should be tested on higher core count CPUs. How the `Sharded` type gets used +// may also affect the ideal nunber of shards. +const SHARD_BITS: usize = 5; + +#[cfg(not(parallel_compiler))] +const SHARD_BITS: usize = 0; + +const SHARDS: usize = 1 << SHARD_BITS; + +/// An array of cache-line aligned inner locked structures with convenience methods. +#[derive(Clone)] +pub struct Sharded { + shards: [CacheAligned>; SHARDS], +} + +impl Default for Sharded { + #[inline] + fn default() -> Self { + let mut shards: mem::MaybeUninit<[CacheAligned>; SHARDS]> = + mem::MaybeUninit::uninit(); + let first = shards.as_mut_ptr() as *mut CacheAligned>; + unsafe { + for i in 0..SHARDS { + first.add(i).write(CacheAligned(Lock::new(T::default()))); + } + Sharded { + shards: shards.assume_init(), + } + } + } +} + +impl Sharded { + #[inline] + pub fn get_shard_by_value(&self, val: &K) -> &Lock { + if SHARDS == 1 { + &self.shards[0].0 + } else { + self.get_shard_by_hash(make_hash(val)) + } + } + + #[inline] + pub fn get_shard_by_hash(&self, hash: u64) -> &Lock { + let hash_len = mem::size_of::(); + // Ignore the top 7 bits as hashbrown uses these and get the next SHARD_BITS highest bits. + // hashbrown also uses the lowest bits, so we can't use those + let bits = (hash >> (hash_len * 8 - 7 - SHARD_BITS)) as usize; + let i = bits % SHARDS; + &self.shards[i].0 + } + + pub fn lock_shards(&self) -> Vec> { + (0..SHARDS).map(|i| self.shards[i].0.lock()).collect() + } + + pub fn try_lock_shards(&self) -> Option>> { + (0..SHARDS).map(|i| self.shards[i].0.try_lock()).collect() + } +} + +pub type ShardedHashMap = Sharded>; + +impl ShardedHashMap { + pub fn len(&self) -> usize { + self.lock_shards().iter().map(|shard| shard.len()).sum() + } +} + +impl ShardedHashMap { + #[inline] + pub fn intern_ref(&self, value: &Q, make: impl FnOnce() -> K) -> K + where K: Borrow, + Q: Hash + Eq + { + let hash = make_hash(value); + let mut shard = self.get_shard_by_hash(hash).lock(); + let entry = shard.raw_entry_mut().from_key_hashed_nocheck(hash, value); + + match entry { + RawEntryMut::Occupied(e) => *e.key(), + RawEntryMut::Vacant(e) => { + let v = make(); + e.insert_hashed_nocheck(hash, v, ()); + v + } + } + } + + #[inline] + pub fn intern(&self, value: Q, make: impl FnOnce(Q) -> K) -> K + where K: Borrow, + Q: Hash + Eq + { + let hash = make_hash(&value); + let mut shard = self.get_shard_by_hash(hash).lock(); + let entry = shard.raw_entry_mut().from_key_hashed_nocheck(hash, &value); + + match entry { + RawEntryMut::Occupied(e) => *e.key(), + RawEntryMut::Vacant(e) => { + let v = make(value); + e.insert_hashed_nocheck(hash, v, ()); + v + } + } + } +} + +#[inline] +fn make_hash(val: &K) -> u64 { + let mut state = FxHasher::default(); + val.hash(&mut state); + state.finish() +} diff --git a/src/librustc_data_structures/sip128.rs b/src/librustc_data_structures/sip128.rs index e5de359e47..1c58eda24f 100644 --- a/src/librustc_data_structures/sip128.rs +++ b/src/librustc_data_structures/sip128.rs @@ -6,6 +6,9 @@ use std::slice; use std::ptr; use std::mem; +#[cfg(test)] +mod tests; + #[derive(Debug, Clone)] pub struct SipHasher128 { k0: u64, @@ -291,233 +294,3 @@ impl Sip24Rounds { compress!(state); } } - -#[cfg(test)] -mod test { - use std::hash::{Hash, Hasher}; - use std::{slice, mem}; - use super::SipHasher128; - - // Hash just the bytes of the slice, without length prefix - struct Bytes<'a>(&'a [u8]); - - impl<'a> Hash for Bytes<'a> { - #[allow(unused_must_use)] - fn hash(&self, state: &mut H) { - for byte in self.0 { - state.write_u8(*byte); - } - } - } - - fn hash_with(mut st: SipHasher128, x: &T) -> (u64, u64) { - x.hash(&mut st); - st.finish128() - } - - fn hash(x: &T) -> (u64, u64) { - hash_with(SipHasher128::new_with_keys(0, 0), x) - } - - const TEST_VECTOR : [[u8; 16]; 64] = [ - [0xa3,0x81,0x7f,0x04,0xba,0x25,0xa8,0xe6,0x6d,0xf6,0x72,0x14,0xc7,0x55,0x02,0x93], - [0xda,0x87,0xc1,0xd8,0x6b,0x99,0xaf,0x44,0x34,0x76,0x59,0x11,0x9b,0x22,0xfc,0x45], - [0x81,0x77,0x22,0x8d,0xa4,0xa4,0x5d,0xc7,0xfc,0xa3,0x8b,0xde,0xf6,0x0a,0xff,0xe4], - [0x9c,0x70,0xb6,0x0c,0x52,0x67,0xa9,0x4e,0x5f,0x33,0xb6,0xb0,0x29,0x85,0xed,0x51], - [0xf8,0x81,0x64,0xc1,0x2d,0x9c,0x8f,0xaf,0x7d,0x0f,0x6e,0x7c,0x7b,0xcd,0x55,0x79], - [0x13,0x68,0x87,0x59,0x80,0x77,0x6f,0x88,0x54,0x52,0x7a,0x07,0x69,0x0e,0x96,0x27], - [0x14,0xee,0xca,0x33,0x8b,0x20,0x86,0x13,0x48,0x5e,0xa0,0x30,0x8f,0xd7,0xa1,0x5e], - [0xa1,0xf1,0xeb,0xbe,0xd8,0xdb,0xc1,0x53,0xc0,0xb8,0x4a,0xa6,0x1f,0xf0,0x82,0x39], - [0x3b,0x62,0xa9,0xba,0x62,0x58,0xf5,0x61,0x0f,0x83,0xe2,0x64,0xf3,0x14,0x97,0xb4], - [0x26,0x44,0x99,0x06,0x0a,0xd9,0xba,0xab,0xc4,0x7f,0x8b,0x02,0xbb,0x6d,0x71,0xed], - [0x00,0x11,0x0d,0xc3,0x78,0x14,0x69,0x56,0xc9,0x54,0x47,0xd3,0xf3,0xd0,0xfb,0xba], - [0x01,0x51,0xc5,0x68,0x38,0x6b,0x66,0x77,0xa2,0xb4,0xdc,0x6f,0x81,0xe5,0xdc,0x18], - [0xd6,0x26,0xb2,0x66,0x90,0x5e,0xf3,0x58,0x82,0x63,0x4d,0xf6,0x85,0x32,0xc1,0x25], - [0x98,0x69,0xe2,0x47,0xe9,0xc0,0x8b,0x10,0xd0,0x29,0x93,0x4f,0xc4,0xb9,0x52,0xf7], - [0x31,0xfc,0xef,0xac,0x66,0xd7,0xde,0x9c,0x7e,0xc7,0x48,0x5f,0xe4,0x49,0x49,0x02], - [0x54,0x93,0xe9,0x99,0x33,0xb0,0xa8,0x11,0x7e,0x08,0xec,0x0f,0x97,0xcf,0xc3,0xd9], - [0x6e,0xe2,0xa4,0xca,0x67,0xb0,0x54,0xbb,0xfd,0x33,0x15,0xbf,0x85,0x23,0x05,0x77], - [0x47,0x3d,0x06,0xe8,0x73,0x8d,0xb8,0x98,0x54,0xc0,0x66,0xc4,0x7a,0xe4,0x77,0x40], - [0xa4,0x26,0xe5,0xe4,0x23,0xbf,0x48,0x85,0x29,0x4d,0xa4,0x81,0xfe,0xae,0xf7,0x23], - [0x78,0x01,0x77,0x31,0xcf,0x65,0xfa,0xb0,0x74,0xd5,0x20,0x89,0x52,0x51,0x2e,0xb1], - [0x9e,0x25,0xfc,0x83,0x3f,0x22,0x90,0x73,0x3e,0x93,0x44,0xa5,0xe8,0x38,0x39,0xeb], - [0x56,0x8e,0x49,0x5a,0xbe,0x52,0x5a,0x21,0x8a,0x22,0x14,0xcd,0x3e,0x07,0x1d,0x12], - [0x4a,0x29,0xb5,0x45,0x52,0xd1,0x6b,0x9a,0x46,0x9c,0x10,0x52,0x8e,0xff,0x0a,0xae], - [0xc9,0xd1,0x84,0xdd,0xd5,0xa9,0xf5,0xe0,0xcf,0x8c,0xe2,0x9a,0x9a,0xbf,0x69,0x1c], - [0x2d,0xb4,0x79,0xae,0x78,0xbd,0x50,0xd8,0x88,0x2a,0x8a,0x17,0x8a,0x61,0x32,0xad], - [0x8e,0xce,0x5f,0x04,0x2d,0x5e,0x44,0x7b,0x50,0x51,0xb9,0xea,0xcb,0x8d,0x8f,0x6f], - [0x9c,0x0b,0x53,0xb4,0xb3,0xc3,0x07,0xe8,0x7e,0xae,0xe0,0x86,0x78,0x14,0x1f,0x66], - [0xab,0xf2,0x48,0xaf,0x69,0xa6,0xea,0xe4,0xbf,0xd3,0xeb,0x2f,0x12,0x9e,0xeb,0x94], - [0x06,0x64,0xda,0x16,0x68,0x57,0x4b,0x88,0xb9,0x35,0xf3,0x02,0x73,0x58,0xae,0xf4], - [0xaa,0x4b,0x9d,0xc4,0xbf,0x33,0x7d,0xe9,0x0c,0xd4,0xfd,0x3c,0x46,0x7c,0x6a,0xb7], - [0xea,0x5c,0x7f,0x47,0x1f,0xaf,0x6b,0xde,0x2b,0x1a,0xd7,0xd4,0x68,0x6d,0x22,0x87], - [0x29,0x39,0xb0,0x18,0x32,0x23,0xfa,0xfc,0x17,0x23,0xde,0x4f,0x52,0xc4,0x3d,0x35], - [0x7c,0x39,0x56,0xca,0x5e,0xea,0xfc,0x3e,0x36,0x3e,0x9d,0x55,0x65,0x46,0xeb,0x68], - [0x77,0xc6,0x07,0x71,0x46,0xf0,0x1c,0x32,0xb6,0xb6,0x9d,0x5f,0x4e,0xa9,0xff,0xcf], - [0x37,0xa6,0x98,0x6c,0xb8,0x84,0x7e,0xdf,0x09,0x25,0xf0,0xf1,0x30,0x9b,0x54,0xde], - [0xa7,0x05,0xf0,0xe6,0x9d,0xa9,0xa8,0xf9,0x07,0x24,0x1a,0x2e,0x92,0x3c,0x8c,0xc8], - [0x3d,0xc4,0x7d,0x1f,0x29,0xc4,0x48,0x46,0x1e,0x9e,0x76,0xed,0x90,0x4f,0x67,0x11], - [0x0d,0x62,0xbf,0x01,0xe6,0xfc,0x0e,0x1a,0x0d,0x3c,0x47,0x51,0xc5,0xd3,0x69,0x2b], - [0x8c,0x03,0x46,0x8b,0xca,0x7c,0x66,0x9e,0xe4,0xfd,0x5e,0x08,0x4b,0xbe,0xe7,0xb5], - [0x52,0x8a,0x5b,0xb9,0x3b,0xaf,0x2c,0x9c,0x44,0x73,0xcc,0xe5,0xd0,0xd2,0x2b,0xd9], - [0xdf,0x6a,0x30,0x1e,0x95,0xc9,0x5d,0xad,0x97,0xae,0x0c,0xc8,0xc6,0x91,0x3b,0xd8], - [0x80,0x11,0x89,0x90,0x2c,0x85,0x7f,0x39,0xe7,0x35,0x91,0x28,0x5e,0x70,0xb6,0xdb], - [0xe6,0x17,0x34,0x6a,0xc9,0xc2,0x31,0xbb,0x36,0x50,0xae,0x34,0xcc,0xca,0x0c,0x5b], - [0x27,0xd9,0x34,0x37,0xef,0xb7,0x21,0xaa,0x40,0x18,0x21,0xdc,0xec,0x5a,0xdf,0x89], - [0x89,0x23,0x7d,0x9d,0xed,0x9c,0x5e,0x78,0xd8,0xb1,0xc9,0xb1,0x66,0xcc,0x73,0x42], - [0x4a,0x6d,0x80,0x91,0xbf,0x5e,0x7d,0x65,0x11,0x89,0xfa,0x94,0xa2,0x50,0xb1,0x4c], - [0x0e,0x33,0xf9,0x60,0x55,0xe7,0xae,0x89,0x3f,0xfc,0x0e,0x3d,0xcf,0x49,0x29,0x02], - [0xe6,0x1c,0x43,0x2b,0x72,0x0b,0x19,0xd1,0x8e,0xc8,0xd8,0x4b,0xdc,0x63,0x15,0x1b], - [0xf7,0xe5,0xae,0xf5,0x49,0xf7,0x82,0xcf,0x37,0x90,0x55,0xa6,0x08,0x26,0x9b,0x16], - [0x43,0x8d,0x03,0x0f,0xd0,0xb7,0xa5,0x4f,0xa8,0x37,0xf2,0xad,0x20,0x1a,0x64,0x03], - [0xa5,0x90,0xd3,0xee,0x4f,0xbf,0x04,0xe3,0x24,0x7e,0x0d,0x27,0xf2,0x86,0x42,0x3f], - [0x5f,0xe2,0xc1,0xa1,0x72,0xfe,0x93,0xc4,0xb1,0x5c,0xd3,0x7c,0xae,0xf9,0xf5,0x38], - [0x2c,0x97,0x32,0x5c,0xbd,0x06,0xb3,0x6e,0xb2,0x13,0x3d,0xd0,0x8b,0x3a,0x01,0x7c], - [0x92,0xc8,0x14,0x22,0x7a,0x6b,0xca,0x94,0x9f,0xf0,0x65,0x9f,0x00,0x2a,0xd3,0x9e], - [0xdc,0xe8,0x50,0x11,0x0b,0xd8,0x32,0x8c,0xfb,0xd5,0x08,0x41,0xd6,0x91,0x1d,0x87], - [0x67,0xf1,0x49,0x84,0xc7,0xda,0x79,0x12,0x48,0xe3,0x2b,0xb5,0x92,0x25,0x83,0xda], - [0x19,0x38,0xf2,0xcf,0x72,0xd5,0x4e,0xe9,0x7e,0x94,0x16,0x6f,0xa9,0x1d,0x2a,0x36], - [0x74,0x48,0x1e,0x96,0x46,0xed,0x49,0xfe,0x0f,0x62,0x24,0x30,0x16,0x04,0x69,0x8e], - [0x57,0xfc,0xa5,0xde,0x98,0xa9,0xd6,0xd8,0x00,0x64,0x38,0xd0,0x58,0x3d,0x8a,0x1d], - [0x9f,0xec,0xde,0x1c,0xef,0xdc,0x1c,0xbe,0xd4,0x76,0x36,0x74,0xd9,0x57,0x53,0x59], - [0xe3,0x04,0x0c,0x00,0xeb,0x28,0xf1,0x53,0x66,0xca,0x73,0xcb,0xd8,0x72,0xe7,0x40], - [0x76,0x97,0x00,0x9a,0x6a,0x83,0x1d,0xfe,0xcc,0xa9,0x1c,0x59,0x93,0x67,0x0f,0x7a], - [0x58,0x53,0x54,0x23,0x21,0xf5,0x67,0xa0,0x05,0xd5,0x47,0xa4,0xf0,0x47,0x59,0xbd], - [0x51,0x50,0xd1,0x77,0x2f,0x50,0x83,0x4a,0x50,0x3e,0x06,0x9a,0x97,0x3f,0xbd,0x7c], - ]; - - // Test vector from reference implementation - #[test] - fn test_siphash_2_4_test_vector() { - let k0 = 0x_07_06_05_04_03_02_01_00; - let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08; - - let mut input: Vec = Vec::new(); - - for i in 0 .. 64 { - let out = hash_with(SipHasher128::new_with_keys(k0, k1), - &Bytes(&input[..])); - let expected = ( - ((TEST_VECTOR[i][0] as u64) << 0) | - ((TEST_VECTOR[i][1] as u64) << 8) | - ((TEST_VECTOR[i][2] as u64) << 16) | - ((TEST_VECTOR[i][3] as u64) << 24) | - ((TEST_VECTOR[i][4] as u64) << 32) | - ((TEST_VECTOR[i][5] as u64) << 40) | - ((TEST_VECTOR[i][6] as u64) << 48) | - ((TEST_VECTOR[i][7] as u64) << 56), - - ((TEST_VECTOR[i][8] as u64) << 0) | - ((TEST_VECTOR[i][9] as u64) << 8) | - ((TEST_VECTOR[i][10] as u64) << 16) | - ((TEST_VECTOR[i][11] as u64) << 24) | - ((TEST_VECTOR[i][12] as u64) << 32) | - ((TEST_VECTOR[i][13] as u64) << 40) | - ((TEST_VECTOR[i][14] as u64) << 48) | - ((TEST_VECTOR[i][15] as u64) << 56), - ); - - assert_eq!(out, expected); - input.push(i as u8); - } - } - - #[test] #[cfg(target_arch = "arm")] - fn test_hash_usize() { - let val = 0xdeadbeef_deadbeef_u64; - assert!(hash(&(val as u64)) != hash(&(val as usize))); - assert_eq!(hash(&(val as u32)), hash(&(val as usize))); - } - #[test] #[cfg(target_arch = "x86_64")] - fn test_hash_usize() { - let val = 0xdeadbeef_deadbeef_u64; - assert_eq!(hash(&(val as u64)), hash(&(val as usize))); - assert!(hash(&(val as u32)) != hash(&(val as usize))); - } - #[test] #[cfg(target_arch = "x86")] - fn test_hash_usize() { - let val = 0xdeadbeef_deadbeef_u64; - assert!(hash(&(val as u64)) != hash(&(val as usize))); - assert_eq!(hash(&(val as u32)), hash(&(val as usize))); - } - - #[test] - fn test_hash_idempotent() { - let val64 = 0xdeadbeef_deadbeef_u64; - assert_eq!(hash(&val64), hash(&val64)); - let val32 = 0xdeadbeef_u32; - assert_eq!(hash(&val32), hash(&val32)); - } - - #[test] - fn test_hash_no_bytes_dropped_64() { - let val = 0xdeadbeef_deadbeef_u64; - - assert!(hash(&val) != hash(&zero_byte(val, 0))); - assert!(hash(&val) != hash(&zero_byte(val, 1))); - assert!(hash(&val) != hash(&zero_byte(val, 2))); - assert!(hash(&val) != hash(&zero_byte(val, 3))); - assert!(hash(&val) != hash(&zero_byte(val, 4))); - assert!(hash(&val) != hash(&zero_byte(val, 5))); - assert!(hash(&val) != hash(&zero_byte(val, 6))); - assert!(hash(&val) != hash(&zero_byte(val, 7))); - - fn zero_byte(val: u64, byte: usize) -> u64 { - assert!(byte < 8); - val & !(0xff << (byte * 8)) - } - } - - #[test] - fn test_hash_no_bytes_dropped_32() { - let val = 0xdeadbeef_u32; - - assert!(hash(&val) != hash(&zero_byte(val, 0))); - assert!(hash(&val) != hash(&zero_byte(val, 1))); - assert!(hash(&val) != hash(&zero_byte(val, 2))); - assert!(hash(&val) != hash(&zero_byte(val, 3))); - - fn zero_byte(val: u32, byte: usize) -> u32 { - assert!(byte < 4); - val & !(0xff << (byte * 8)) - } - } - - #[test] - fn test_hash_no_concat_alias() { - let s = ("aa", "bb"); - let t = ("aabb", ""); - let u = ("a", "abb"); - - assert!(s != t && t != u); - assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u)); - - let u = [1, 0, 0, 0]; - let v = (&u[..1], &u[1..3], &u[3..]); - let w = (&u[..], &u[4..4], &u[4..4]); - - assert!(v != w); - assert!(hash(&v) != hash(&w)); - } - - #[test] - fn test_write_short_works() { - let test_usize = 0xd0c0b0a0usize; - let mut h1 = SipHasher128::new_with_keys(0, 0); - h1.write_usize(test_usize); - h1.write(b"bytes"); - h1.write(b"string"); - h1.write_u8(0xFFu8); - h1.write_u8(0x01u8); - let mut h2 = SipHasher128::new_with_keys(0, 0); - h2.write(unsafe { - slice::from_raw_parts(&test_usize as *const _ as *const u8, - mem::size_of::()) - }); - h2.write(b"bytes"); - h2.write(b"string"); - h2.write(&[0xFFu8, 0x01u8]); - assert_eq!(h1.finish128(), h2.finish128()); - } - -} diff --git a/src/librustc_data_structures/sip128/tests.rs b/src/librustc_data_structures/sip128/tests.rs new file mode 100644 index 0000000000..90cc54448b --- /dev/null +++ b/src/librustc_data_structures/sip128/tests.rs @@ -0,0 +1,226 @@ +use super::*; + +use std::hash::{Hash, Hasher}; +use std::{slice, mem}; + +// Hash just the bytes of the slice, without length prefix +struct Bytes<'a>(&'a [u8]); + +impl<'a> Hash for Bytes<'a> { + #[allow(unused_must_use)] + fn hash(&self, state: &mut H) { + for byte in self.0 { + state.write_u8(*byte); + } + } +} + +fn hash_with(mut st: SipHasher128, x: &T) -> (u64, u64) { + x.hash(&mut st); + st.finish128() +} + +fn hash(x: &T) -> (u64, u64) { + hash_with(SipHasher128::new_with_keys(0, 0), x) +} + +const TEST_VECTOR : [[u8; 16]; 64] = [ + [0xa3,0x81,0x7f,0x04,0xba,0x25,0xa8,0xe6,0x6d,0xf6,0x72,0x14,0xc7,0x55,0x02,0x93], + [0xda,0x87,0xc1,0xd8,0x6b,0x99,0xaf,0x44,0x34,0x76,0x59,0x11,0x9b,0x22,0xfc,0x45], + [0x81,0x77,0x22,0x8d,0xa4,0xa4,0x5d,0xc7,0xfc,0xa3,0x8b,0xde,0xf6,0x0a,0xff,0xe4], + [0x9c,0x70,0xb6,0x0c,0x52,0x67,0xa9,0x4e,0x5f,0x33,0xb6,0xb0,0x29,0x85,0xed,0x51], + [0xf8,0x81,0x64,0xc1,0x2d,0x9c,0x8f,0xaf,0x7d,0x0f,0x6e,0x7c,0x7b,0xcd,0x55,0x79], + [0x13,0x68,0x87,0x59,0x80,0x77,0x6f,0x88,0x54,0x52,0x7a,0x07,0x69,0x0e,0x96,0x27], + [0x14,0xee,0xca,0x33,0x8b,0x20,0x86,0x13,0x48,0x5e,0xa0,0x30,0x8f,0xd7,0xa1,0x5e], + [0xa1,0xf1,0xeb,0xbe,0xd8,0xdb,0xc1,0x53,0xc0,0xb8,0x4a,0xa6,0x1f,0xf0,0x82,0x39], + [0x3b,0x62,0xa9,0xba,0x62,0x58,0xf5,0x61,0x0f,0x83,0xe2,0x64,0xf3,0x14,0x97,0xb4], + [0x26,0x44,0x99,0x06,0x0a,0xd9,0xba,0xab,0xc4,0x7f,0x8b,0x02,0xbb,0x6d,0x71,0xed], + [0x00,0x11,0x0d,0xc3,0x78,0x14,0x69,0x56,0xc9,0x54,0x47,0xd3,0xf3,0xd0,0xfb,0xba], + [0x01,0x51,0xc5,0x68,0x38,0x6b,0x66,0x77,0xa2,0xb4,0xdc,0x6f,0x81,0xe5,0xdc,0x18], + [0xd6,0x26,0xb2,0x66,0x90,0x5e,0xf3,0x58,0x82,0x63,0x4d,0xf6,0x85,0x32,0xc1,0x25], + [0x98,0x69,0xe2,0x47,0xe9,0xc0,0x8b,0x10,0xd0,0x29,0x93,0x4f,0xc4,0xb9,0x52,0xf7], + [0x31,0xfc,0xef,0xac,0x66,0xd7,0xde,0x9c,0x7e,0xc7,0x48,0x5f,0xe4,0x49,0x49,0x02], + [0x54,0x93,0xe9,0x99,0x33,0xb0,0xa8,0x11,0x7e,0x08,0xec,0x0f,0x97,0xcf,0xc3,0xd9], + [0x6e,0xe2,0xa4,0xca,0x67,0xb0,0x54,0xbb,0xfd,0x33,0x15,0xbf,0x85,0x23,0x05,0x77], + [0x47,0x3d,0x06,0xe8,0x73,0x8d,0xb8,0x98,0x54,0xc0,0x66,0xc4,0x7a,0xe4,0x77,0x40], + [0xa4,0x26,0xe5,0xe4,0x23,0xbf,0x48,0x85,0x29,0x4d,0xa4,0x81,0xfe,0xae,0xf7,0x23], + [0x78,0x01,0x77,0x31,0xcf,0x65,0xfa,0xb0,0x74,0xd5,0x20,0x89,0x52,0x51,0x2e,0xb1], + [0x9e,0x25,0xfc,0x83,0x3f,0x22,0x90,0x73,0x3e,0x93,0x44,0xa5,0xe8,0x38,0x39,0xeb], + [0x56,0x8e,0x49,0x5a,0xbe,0x52,0x5a,0x21,0x8a,0x22,0x14,0xcd,0x3e,0x07,0x1d,0x12], + [0x4a,0x29,0xb5,0x45,0x52,0xd1,0x6b,0x9a,0x46,0x9c,0x10,0x52,0x8e,0xff,0x0a,0xae], + [0xc9,0xd1,0x84,0xdd,0xd5,0xa9,0xf5,0xe0,0xcf,0x8c,0xe2,0x9a,0x9a,0xbf,0x69,0x1c], + [0x2d,0xb4,0x79,0xae,0x78,0xbd,0x50,0xd8,0x88,0x2a,0x8a,0x17,0x8a,0x61,0x32,0xad], + [0x8e,0xce,0x5f,0x04,0x2d,0x5e,0x44,0x7b,0x50,0x51,0xb9,0xea,0xcb,0x8d,0x8f,0x6f], + [0x9c,0x0b,0x53,0xb4,0xb3,0xc3,0x07,0xe8,0x7e,0xae,0xe0,0x86,0x78,0x14,0x1f,0x66], + [0xab,0xf2,0x48,0xaf,0x69,0xa6,0xea,0xe4,0xbf,0xd3,0xeb,0x2f,0x12,0x9e,0xeb,0x94], + [0x06,0x64,0xda,0x16,0x68,0x57,0x4b,0x88,0xb9,0x35,0xf3,0x02,0x73,0x58,0xae,0xf4], + [0xaa,0x4b,0x9d,0xc4,0xbf,0x33,0x7d,0xe9,0x0c,0xd4,0xfd,0x3c,0x46,0x7c,0x6a,0xb7], + [0xea,0x5c,0x7f,0x47,0x1f,0xaf,0x6b,0xde,0x2b,0x1a,0xd7,0xd4,0x68,0x6d,0x22,0x87], + [0x29,0x39,0xb0,0x18,0x32,0x23,0xfa,0xfc,0x17,0x23,0xde,0x4f,0x52,0xc4,0x3d,0x35], + [0x7c,0x39,0x56,0xca,0x5e,0xea,0xfc,0x3e,0x36,0x3e,0x9d,0x55,0x65,0x46,0xeb,0x68], + [0x77,0xc6,0x07,0x71,0x46,0xf0,0x1c,0x32,0xb6,0xb6,0x9d,0x5f,0x4e,0xa9,0xff,0xcf], + [0x37,0xa6,0x98,0x6c,0xb8,0x84,0x7e,0xdf,0x09,0x25,0xf0,0xf1,0x30,0x9b,0x54,0xde], + [0xa7,0x05,0xf0,0xe6,0x9d,0xa9,0xa8,0xf9,0x07,0x24,0x1a,0x2e,0x92,0x3c,0x8c,0xc8], + [0x3d,0xc4,0x7d,0x1f,0x29,0xc4,0x48,0x46,0x1e,0x9e,0x76,0xed,0x90,0x4f,0x67,0x11], + [0x0d,0x62,0xbf,0x01,0xe6,0xfc,0x0e,0x1a,0x0d,0x3c,0x47,0x51,0xc5,0xd3,0x69,0x2b], + [0x8c,0x03,0x46,0x8b,0xca,0x7c,0x66,0x9e,0xe4,0xfd,0x5e,0x08,0x4b,0xbe,0xe7,0xb5], + [0x52,0x8a,0x5b,0xb9,0x3b,0xaf,0x2c,0x9c,0x44,0x73,0xcc,0xe5,0xd0,0xd2,0x2b,0xd9], + [0xdf,0x6a,0x30,0x1e,0x95,0xc9,0x5d,0xad,0x97,0xae,0x0c,0xc8,0xc6,0x91,0x3b,0xd8], + [0x80,0x11,0x89,0x90,0x2c,0x85,0x7f,0x39,0xe7,0x35,0x91,0x28,0x5e,0x70,0xb6,0xdb], + [0xe6,0x17,0x34,0x6a,0xc9,0xc2,0x31,0xbb,0x36,0x50,0xae,0x34,0xcc,0xca,0x0c,0x5b], + [0x27,0xd9,0x34,0x37,0xef,0xb7,0x21,0xaa,0x40,0x18,0x21,0xdc,0xec,0x5a,0xdf,0x89], + [0x89,0x23,0x7d,0x9d,0xed,0x9c,0x5e,0x78,0xd8,0xb1,0xc9,0xb1,0x66,0xcc,0x73,0x42], + [0x4a,0x6d,0x80,0x91,0xbf,0x5e,0x7d,0x65,0x11,0x89,0xfa,0x94,0xa2,0x50,0xb1,0x4c], + [0x0e,0x33,0xf9,0x60,0x55,0xe7,0xae,0x89,0x3f,0xfc,0x0e,0x3d,0xcf,0x49,0x29,0x02], + [0xe6,0x1c,0x43,0x2b,0x72,0x0b,0x19,0xd1,0x8e,0xc8,0xd8,0x4b,0xdc,0x63,0x15,0x1b], + [0xf7,0xe5,0xae,0xf5,0x49,0xf7,0x82,0xcf,0x37,0x90,0x55,0xa6,0x08,0x26,0x9b,0x16], + [0x43,0x8d,0x03,0x0f,0xd0,0xb7,0xa5,0x4f,0xa8,0x37,0xf2,0xad,0x20,0x1a,0x64,0x03], + [0xa5,0x90,0xd3,0xee,0x4f,0xbf,0x04,0xe3,0x24,0x7e,0x0d,0x27,0xf2,0x86,0x42,0x3f], + [0x5f,0xe2,0xc1,0xa1,0x72,0xfe,0x93,0xc4,0xb1,0x5c,0xd3,0x7c,0xae,0xf9,0xf5,0x38], + [0x2c,0x97,0x32,0x5c,0xbd,0x06,0xb3,0x6e,0xb2,0x13,0x3d,0xd0,0x8b,0x3a,0x01,0x7c], + [0x92,0xc8,0x14,0x22,0x7a,0x6b,0xca,0x94,0x9f,0xf0,0x65,0x9f,0x00,0x2a,0xd3,0x9e], + [0xdc,0xe8,0x50,0x11,0x0b,0xd8,0x32,0x8c,0xfb,0xd5,0x08,0x41,0xd6,0x91,0x1d,0x87], + [0x67,0xf1,0x49,0x84,0xc7,0xda,0x79,0x12,0x48,0xe3,0x2b,0xb5,0x92,0x25,0x83,0xda], + [0x19,0x38,0xf2,0xcf,0x72,0xd5,0x4e,0xe9,0x7e,0x94,0x16,0x6f,0xa9,0x1d,0x2a,0x36], + [0x74,0x48,0x1e,0x96,0x46,0xed,0x49,0xfe,0x0f,0x62,0x24,0x30,0x16,0x04,0x69,0x8e], + [0x57,0xfc,0xa5,0xde,0x98,0xa9,0xd6,0xd8,0x00,0x64,0x38,0xd0,0x58,0x3d,0x8a,0x1d], + [0x9f,0xec,0xde,0x1c,0xef,0xdc,0x1c,0xbe,0xd4,0x76,0x36,0x74,0xd9,0x57,0x53,0x59], + [0xe3,0x04,0x0c,0x00,0xeb,0x28,0xf1,0x53,0x66,0xca,0x73,0xcb,0xd8,0x72,0xe7,0x40], + [0x76,0x97,0x00,0x9a,0x6a,0x83,0x1d,0xfe,0xcc,0xa9,0x1c,0x59,0x93,0x67,0x0f,0x7a], + [0x58,0x53,0x54,0x23,0x21,0xf5,0x67,0xa0,0x05,0xd5,0x47,0xa4,0xf0,0x47,0x59,0xbd], + [0x51,0x50,0xd1,0x77,0x2f,0x50,0x83,0x4a,0x50,0x3e,0x06,0x9a,0x97,0x3f,0xbd,0x7c], +]; + +// Test vector from reference implementation +#[test] +fn test_siphash_2_4_test_vector() { + let k0 = 0x_07_06_05_04_03_02_01_00; + let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08; + + let mut input: Vec = Vec::new(); + + for i in 0 .. 64 { + let out = hash_with(SipHasher128::new_with_keys(k0, k1), + &Bytes(&input[..])); + let expected = ( + ((TEST_VECTOR[i][0] as u64) << 0) | + ((TEST_VECTOR[i][1] as u64) << 8) | + ((TEST_VECTOR[i][2] as u64) << 16) | + ((TEST_VECTOR[i][3] as u64) << 24) | + ((TEST_VECTOR[i][4] as u64) << 32) | + ((TEST_VECTOR[i][5] as u64) << 40) | + ((TEST_VECTOR[i][6] as u64) << 48) | + ((TEST_VECTOR[i][7] as u64) << 56), + + ((TEST_VECTOR[i][8] as u64) << 0) | + ((TEST_VECTOR[i][9] as u64) << 8) | + ((TEST_VECTOR[i][10] as u64) << 16) | + ((TEST_VECTOR[i][11] as u64) << 24) | + ((TEST_VECTOR[i][12] as u64) << 32) | + ((TEST_VECTOR[i][13] as u64) << 40) | + ((TEST_VECTOR[i][14] as u64) << 48) | + ((TEST_VECTOR[i][15] as u64) << 56), + ); + + assert_eq!(out, expected); + input.push(i as u8); + } +} + +#[test] #[cfg(target_arch = "arm")] +fn test_hash_usize() { + let val = 0xdeadbeef_deadbeef_u64; + assert!(hash(&(val as u64)) != hash(&(val as usize))); + assert_eq!(hash(&(val as u32)), hash(&(val as usize))); +} +#[test] #[cfg(target_arch = "x86_64")] +fn test_hash_usize() { + let val = 0xdeadbeef_deadbeef_u64; + assert_eq!(hash(&(val as u64)), hash(&(val as usize))); + assert!(hash(&(val as u32)) != hash(&(val as usize))); +} +#[test] #[cfg(target_arch = "x86")] +fn test_hash_usize() { + let val = 0xdeadbeef_deadbeef_u64; + assert!(hash(&(val as u64)) != hash(&(val as usize))); + assert_eq!(hash(&(val as u32)), hash(&(val as usize))); +} + +#[test] +fn test_hash_idempotent() { + let val64 = 0xdeadbeef_deadbeef_u64; + assert_eq!(hash(&val64), hash(&val64)); + let val32 = 0xdeadbeef_u32; + assert_eq!(hash(&val32), hash(&val32)); +} + +#[test] +fn test_hash_no_bytes_dropped_64() { + let val = 0xdeadbeef_deadbeef_u64; + + assert!(hash(&val) != hash(&zero_byte(val, 0))); + assert!(hash(&val) != hash(&zero_byte(val, 1))); + assert!(hash(&val) != hash(&zero_byte(val, 2))); + assert!(hash(&val) != hash(&zero_byte(val, 3))); + assert!(hash(&val) != hash(&zero_byte(val, 4))); + assert!(hash(&val) != hash(&zero_byte(val, 5))); + assert!(hash(&val) != hash(&zero_byte(val, 6))); + assert!(hash(&val) != hash(&zero_byte(val, 7))); + + fn zero_byte(val: u64, byte: usize) -> u64 { + assert!(byte < 8); + val & !(0xff << (byte * 8)) + } +} + +#[test] +fn test_hash_no_bytes_dropped_32() { + let val = 0xdeadbeef_u32; + + assert!(hash(&val) != hash(&zero_byte(val, 0))); + assert!(hash(&val) != hash(&zero_byte(val, 1))); + assert!(hash(&val) != hash(&zero_byte(val, 2))); + assert!(hash(&val) != hash(&zero_byte(val, 3))); + + fn zero_byte(val: u32, byte: usize) -> u32 { + assert!(byte < 4); + val & !(0xff << (byte * 8)) + } +} + +#[test] +fn test_hash_no_concat_alias() { + let s = ("aa", "bb"); + let t = ("aabb", ""); + let u = ("a", "abb"); + + assert!(s != t && t != u); + assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u)); + + let u = [1, 0, 0, 0]; + let v = (&u[..1], &u[1..3], &u[3..]); + let w = (&u[..], &u[4..4], &u[4..4]); + + assert!(v != w); + assert!(hash(&v) != hash(&w)); +} + +#[test] +fn test_write_short_works() { + let test_usize = 0xd0c0b0a0usize; + let mut h1 = SipHasher128::new_with_keys(0, 0); + h1.write_usize(test_usize); + h1.write(b"bytes"); + h1.write(b"string"); + h1.write_u8(0xFFu8); + h1.write_u8(0x01u8); + let mut h2 = SipHasher128::new_with_keys(0, 0); + h2.write(unsafe { + slice::from_raw_parts(&test_usize as *const _ as *const u8, + mem::size_of::()) + }); + h2.write(b"bytes"); + h2.write(b"string"); + h2.write(&[0xFFu8, 0x01u8]); + assert_eq!(h1.finish128(), h2.finish128()); +} diff --git a/src/librustc_data_structures/small_c_str.rs b/src/librustc_data_structures/small_c_str.rs index bde7911267..9d90b9052d 100644 --- a/src/librustc_data_structures/small_c_str.rs +++ b/src/librustc_data_structures/small_c_str.rs @@ -3,6 +3,9 @@ use std::ops::Deref; use smallvec::SmallVec; +#[cfg(test)] +mod tests; + const SIZE: usize = 36; /// Like SmallVec but for C strings. @@ -66,47 +69,3 @@ impl Deref for SmallCStr { self.as_c_str() } } - -#[test] -fn short() { - const TEXT: &str = "abcd"; - let reference = ffi::CString::new(TEXT.to_string()).unwrap(); - - let scs = SmallCStr::new(TEXT); - - assert_eq!(scs.len_with_nul(), TEXT.len() + 1); - assert_eq!(scs.as_c_str(), reference.as_c_str()); - assert!(!scs.spilled()); -} - -#[test] -fn empty() { - const TEXT: &str = ""; - let reference = ffi::CString::new(TEXT.to_string()).unwrap(); - - let scs = SmallCStr::new(TEXT); - - assert_eq!(scs.len_with_nul(), TEXT.len() + 1); - assert_eq!(scs.as_c_str(), reference.as_c_str()); - assert!(!scs.spilled()); -} - -#[test] -fn long() { - const TEXT: &str = "01234567890123456789012345678901234567890123456789\ - 01234567890123456789012345678901234567890123456789\ - 01234567890123456789012345678901234567890123456789"; - let reference = ffi::CString::new(TEXT.to_string()).unwrap(); - - let scs = SmallCStr::new(TEXT); - - assert_eq!(scs.len_with_nul(), TEXT.len() + 1); - assert_eq!(scs.as_c_str(), reference.as_c_str()); - assert!(scs.spilled()); -} - -#[test] -#[should_panic] -fn internal_nul() { - let _ = SmallCStr::new("abcd\0def"); -} diff --git a/src/librustc_data_structures/small_c_str/tests.rs b/src/librustc_data_structures/small_c_str/tests.rs new file mode 100644 index 0000000000..47277604b2 --- /dev/null +++ b/src/librustc_data_structures/small_c_str/tests.rs @@ -0,0 +1,45 @@ +use super::*; + +#[test] +fn short() { + const TEXT: &str = "abcd"; + let reference = ffi::CString::new(TEXT.to_string()).unwrap(); + + let scs = SmallCStr::new(TEXT); + + assert_eq!(scs.len_with_nul(), TEXT.len() + 1); + assert_eq!(scs.as_c_str(), reference.as_c_str()); + assert!(!scs.spilled()); +} + +#[test] +fn empty() { + const TEXT: &str = ""; + let reference = ffi::CString::new(TEXT.to_string()).unwrap(); + + let scs = SmallCStr::new(TEXT); + + assert_eq!(scs.len_with_nul(), TEXT.len() + 1); + assert_eq!(scs.as_c_str(), reference.as_c_str()); + assert!(!scs.spilled()); +} + +#[test] +fn long() { + const TEXT: &str = "01234567890123456789012345678901234567890123456789\ + 01234567890123456789012345678901234567890123456789\ + 01234567890123456789012345678901234567890123456789"; + let reference = ffi::CString::new(TEXT.to_string()).unwrap(); + + let scs = SmallCStr::new(TEXT); + + assert_eq!(scs.len_with_nul(), TEXT.len() + 1); + assert_eq!(scs.as_c_str(), reference.as_c_str()); + assert!(scs.spilled()); +} + +#[test] +#[should_panic] +fn internal_nul() { + let _ = SmallCStr::new("abcd\0def"); +} diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index 91d6e29237..ce0aa07cc2 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -4,7 +4,7 @@ use std::ops; use std::mem; #[cfg(test)] -mod test; +mod tests; pub struct SnapshotMap where K: Hash + Clone + Eq diff --git a/src/librustc_data_structures/snapshot_map/test.rs b/src/librustc_data_structures/snapshot_map/tests.rs similarity index 100% rename from src/librustc_data_structures/snapshot_map/test.rs rename to src/librustc_data_structures/snapshot_map/tests.rs diff --git a/src/librustc_data_structures/svh.rs b/src/librustc_data_structures/svh.rs index df4f617683..3123c182b0 100644 --- a/src/librustc_data_structures/svh.rs +++ b/src/librustc_data_structures/svh.rs @@ -7,7 +7,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; -use serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use crate::stable_hasher; diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 73247c1469..3277b85c28 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -67,6 +67,51 @@ cfg_if! { use std::ops::Add; use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; + /// This is a single threaded variant of AtomicCell provided by crossbeam. + /// Unlike `Atomic` this is intended for all `Copy` types, + /// but it lacks the explicit ordering arguments. + #[derive(Debug)] + pub struct AtomicCell(Cell); + + impl AtomicCell { + #[inline] + pub fn new(v: T) -> Self { + AtomicCell(Cell::new(v)) + } + + #[inline] + pub fn get_mut(&mut self) -> &mut T { + self.0.get_mut() + } + } + + impl AtomicCell { + #[inline] + pub fn into_inner(self) -> T { + self.0.into_inner() + } + + #[inline] + pub fn load(&self) -> T { + self.0.get() + } + + #[inline] + pub fn store(&self, val: T) { + self.0.set(val) + } + + #[inline] + pub fn swap(&self, val: T) -> T { + self.0.replace(val) + } + } + + /// This is a single threaded variant of `AtomicU64`, `AtomicUsize`, etc. + /// It differs from `AtomicCell` in that it has explicit ordering arguments + /// and is only intended for use with the native atomic types. + /// You should use this type through the `AtomicU64`, `AtomicUsize`, etc, type aliases + /// as it's not intended to be used separately. #[derive(Debug)] pub struct Atomic(Cell); @@ -77,7 +122,8 @@ cfg_if! { } } - impl Atomic { + impl Atomic { + #[inline] pub fn into_inner(self) -> T { self.0.into_inner() } @@ -92,10 +138,14 @@ cfg_if! { self.0.set(val) } + #[inline] pub fn swap(&self, val: T, _: Ordering) -> T { self.0.replace(val) } + } + impl Atomic { + #[inline] pub fn compare_exchange(&self, current: T, new: T, @@ -113,6 +163,7 @@ cfg_if! { } impl + Copy> Atomic { + #[inline] pub fn fetch_add(&self, val: T, _: Ordering) -> T { let old = self.0.get(); self.0.set(old + val); @@ -271,6 +322,8 @@ cfg_if! { pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; + pub use crossbeam_utils::atomic::AtomicCell; + pub use std::sync::Arc as Lrc; pub use std::sync::Weak as Weak; diff --git a/src/librustc_data_structures/tiny_list.rs b/src/librustc_data_structures/tiny_list.rs index 3d74516d9c..1c0d9360f2 100644 --- a/src/librustc_data_structures/tiny_list.rs +++ b/src/librustc_data_structures/tiny_list.rs @@ -11,6 +11,9 @@ //! If you expect to store more than 1 element in the common case, steer clear //! and use a `Vec`, `Box<[T]>`, or a `SmallVec`. +#[cfg(test)] +mod tests; + #[derive(Clone, Hash, Debug, PartialEq)] pub struct TinyList { head: Option> @@ -118,139 +121,3 @@ impl Element { } } } - -#[cfg(test)] -mod test { - use super::*; - extern crate test; - use test::Bencher; - - #[test] - fn test_contains_and_insert() { - fn do_insert(i : u32) -> bool { - i % 2 == 0 - } - - let mut list = TinyList::new(); - - for i in 0 .. 10 { - for j in 0 .. i { - if do_insert(j) { - assert!(list.contains(&j)); - } else { - assert!(!list.contains(&j)); - } - } - - assert!(!list.contains(&i)); - - if do_insert(i) { - list.insert(i); - assert!(list.contains(&i)); - } - } - } - - #[test] - fn test_remove_first() { - let mut list = TinyList::new(); - list.insert(1); - list.insert(2); - list.insert(3); - list.insert(4); - assert_eq!(list.len(), 4); - - assert!(list.remove(&4)); - assert!(!list.contains(&4)); - - assert_eq!(list.len(), 3); - assert!(list.contains(&1)); - assert!(list.contains(&2)); - assert!(list.contains(&3)); - } - - #[test] - fn test_remove_last() { - let mut list = TinyList::new(); - list.insert(1); - list.insert(2); - list.insert(3); - list.insert(4); - assert_eq!(list.len(), 4); - - assert!(list.remove(&1)); - assert!(!list.contains(&1)); - - assert_eq!(list.len(), 3); - assert!(list.contains(&2)); - assert!(list.contains(&3)); - assert!(list.contains(&4)); - } - - #[test] - fn test_remove_middle() { - let mut list = TinyList::new(); - list.insert(1); - list.insert(2); - list.insert(3); - list.insert(4); - assert_eq!(list.len(), 4); - - assert!(list.remove(&2)); - assert!(!list.contains(&2)); - - assert_eq!(list.len(), 3); - assert!(list.contains(&1)); - assert!(list.contains(&3)); - assert!(list.contains(&4)); - } - - #[test] - fn test_remove_single() { - let mut list = TinyList::new(); - list.insert(1); - assert_eq!(list.len(), 1); - - assert!(list.remove(&1)); - assert!(!list.contains(&1)); - - assert_eq!(list.len(), 0); - } - - #[bench] - fn bench_insert_empty(b: &mut Bencher) { - b.iter(|| { - let mut list = TinyList::new(); - list.insert(1); - }) - } - - #[bench] - fn bench_insert_one(b: &mut Bencher) { - b.iter(|| { - let mut list = TinyList::new_single(0); - list.insert(1); - }) - } - - #[bench] - fn bench_remove_empty(b: &mut Bencher) { - b.iter(|| { - TinyList::new().remove(&1) - }); - } - - #[bench] - fn bench_remove_unknown(b: &mut Bencher) { - b.iter(|| { - TinyList::new_single(0).remove(&1) - }); - } - - #[bench] - fn bench_remove_one(b: &mut Bencher) { - b.iter(|| { - TinyList::new_single(1).remove(&1) - }); - } -} diff --git a/src/librustc_data_structures/tiny_list/tests.rs b/src/librustc_data_structures/tiny_list/tests.rs new file mode 100644 index 0000000000..8374659e1e --- /dev/null +++ b/src/librustc_data_structures/tiny_list/tests.rs @@ -0,0 +1,133 @@ +use super::*; + +extern crate test; +use test::Bencher; + +#[test] +fn test_contains_and_insert() { + fn do_insert(i : u32) -> bool { + i % 2 == 0 + } + + let mut list = TinyList::new(); + + for i in 0 .. 10 { + for j in 0 .. i { + if do_insert(j) { + assert!(list.contains(&j)); + } else { + assert!(!list.contains(&j)); + } + } + + assert!(!list.contains(&i)); + + if do_insert(i) { + list.insert(i); + assert!(list.contains(&i)); + } + } +} + +#[test] +fn test_remove_first() { + let mut list = TinyList::new(); + list.insert(1); + list.insert(2); + list.insert(3); + list.insert(4); + assert_eq!(list.len(), 4); + + assert!(list.remove(&4)); + assert!(!list.contains(&4)); + + assert_eq!(list.len(), 3); + assert!(list.contains(&1)); + assert!(list.contains(&2)); + assert!(list.contains(&3)); +} + +#[test] +fn test_remove_last() { + let mut list = TinyList::new(); + list.insert(1); + list.insert(2); + list.insert(3); + list.insert(4); + assert_eq!(list.len(), 4); + + assert!(list.remove(&1)); + assert!(!list.contains(&1)); + + assert_eq!(list.len(), 3); + assert!(list.contains(&2)); + assert!(list.contains(&3)); + assert!(list.contains(&4)); +} + +#[test] +fn test_remove_middle() { + let mut list = TinyList::new(); + list.insert(1); + list.insert(2); + list.insert(3); + list.insert(4); + assert_eq!(list.len(), 4); + + assert!(list.remove(&2)); + assert!(!list.contains(&2)); + + assert_eq!(list.len(), 3); + assert!(list.contains(&1)); + assert!(list.contains(&3)); + assert!(list.contains(&4)); +} + +#[test] +fn test_remove_single() { + let mut list = TinyList::new(); + list.insert(1); + assert_eq!(list.len(), 1); + + assert!(list.remove(&1)); + assert!(!list.contains(&1)); + + assert_eq!(list.len(), 0); +} + +#[bench] +fn bench_insert_empty(b: &mut Bencher) { + b.iter(|| { + let mut list = TinyList::new(); + list.insert(1); + }) +} + +#[bench] +fn bench_insert_one(b: &mut Bencher) { + b.iter(|| { + let mut list = TinyList::new_single(0); + list.insert(1); + }) +} + +#[bench] +fn bench_remove_empty(b: &mut Bencher) { + b.iter(|| { + TinyList::new().remove(&1) + }); +} + +#[bench] +fn bench_remove_unknown(b: &mut Bencher) { + b.iter(|| { + TinyList::new_single(0).remove(&1) + }); +} + +#[bench] +fn bench_remove_one(b: &mut Bencher) { + b.iter(|| { + TinyList::new_single(1).remove(&1) + }); +} diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index d7cbd1e2e4..ffc964ddb5 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -7,6 +7,8 @@ use std::fmt::Debug; use std::hash::Hash; use std::mem; +#[cfg(test)] +mod tests; #[derive(Clone, Debug)] pub struct TransitiveRelation { @@ -481,359 +483,3 @@ impl HashStable for Index { idx.hash_stable(hcx, hasher); } } - -#[test] -fn test_one_step() { - let mut relation = TransitiveRelation::default(); - relation.add("a", "b"); - relation.add("a", "c"); - assert!(relation.contains(&"a", &"c")); - assert!(relation.contains(&"a", &"b")); - assert!(!relation.contains(&"b", &"a")); - assert!(!relation.contains(&"a", &"d")); -} - -#[test] -fn test_many_steps() { - let mut relation = TransitiveRelation::default(); - relation.add("a", "b"); - relation.add("a", "c"); - relation.add("a", "f"); - - relation.add("b", "c"); - relation.add("b", "d"); - relation.add("b", "e"); - - relation.add("e", "g"); - - assert!(relation.contains(&"a", &"b")); - assert!(relation.contains(&"a", &"c")); - assert!(relation.contains(&"a", &"d")); - assert!(relation.contains(&"a", &"e")); - assert!(relation.contains(&"a", &"f")); - assert!(relation.contains(&"a", &"g")); - - assert!(relation.contains(&"b", &"g")); - - assert!(!relation.contains(&"a", &"x")); - assert!(!relation.contains(&"b", &"f")); -} - -#[test] -fn mubs_triangle() { - // a -> tcx - // ^ - // | - // b - let mut relation = TransitiveRelation::default(); - relation.add("a", "tcx"); - relation.add("b", "tcx"); - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"tcx"]); - assert_eq!(relation.parents(&"a"), vec![&"tcx"]); - assert_eq!(relation.parents(&"b"), vec![&"tcx"]); -} - -#[test] -fn mubs_best_choice1() { - // 0 -> 1 <- 3 - // | ^ | - // | | | - // +--> 2 <--+ - // - // mubs(0,3) = [1] - - // This tests a particular state in the algorithm, in which we - // need the second pare down call to get the right result (after - // intersection, we have [1, 2], but 2 -> 1). - - let mut relation = TransitiveRelation::default(); - relation.add("0", "1"); - relation.add("0", "2"); - - relation.add("2", "1"); - - relation.add("3", "1"); - relation.add("3", "2"); - - assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"2"]); - assert_eq!(relation.parents(&"0"), vec![&"2"]); - assert_eq!(relation.parents(&"2"), vec![&"1"]); - assert!(relation.parents(&"1").is_empty()); -} - -#[test] -fn mubs_best_choice2() { - // 0 -> 1 <- 3 - // | | | - // | v | - // +--> 2 <--+ - // - // mubs(0,3) = [2] - - // Like the precedecing test, but in this case intersection is [2, - // 1], and hence we rely on the first pare down call. - - let mut relation = TransitiveRelation::default(); - relation.add("0", "1"); - relation.add("0", "2"); - - relation.add("1", "2"); - - relation.add("3", "1"); - relation.add("3", "2"); - - assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1"]); - assert_eq!(relation.parents(&"0"), vec![&"1"]); - assert_eq!(relation.parents(&"1"), vec![&"2"]); - assert!(relation.parents(&"2").is_empty()); -} - -#[test] -fn mubs_no_best_choice() { - // in this case, the intersection yields [1, 2], and the "pare - // down" calls find nothing to remove. - let mut relation = TransitiveRelation::default(); - relation.add("0", "1"); - relation.add("0", "2"); - - relation.add("3", "1"); - relation.add("3", "2"); - - assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1", &"2"]); - assert_eq!(relation.parents(&"0"), vec![&"1", &"2"]); - assert_eq!(relation.parents(&"3"), vec![&"1", &"2"]); -} - -#[test] -fn mubs_best_choice_scc() { - // in this case, 1 and 2 form a cycle; we pick arbitrarily (but - // consistently). - - let mut relation = TransitiveRelation::default(); - relation.add("0", "1"); - relation.add("0", "2"); - - relation.add("1", "2"); - relation.add("2", "1"); - - relation.add("3", "1"); - relation.add("3", "2"); - - assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1"]); - assert_eq!(relation.parents(&"0"), vec![&"1"]); -} - -#[test] -fn pdub_crisscross() { - // diagonal edges run left-to-right - // a -> a1 -> x - // \/ ^ - // /\ | - // b -> b1 ---+ - - let mut relation = TransitiveRelation::default(); - relation.add("a", "a1"); - relation.add("a", "b1"); - relation.add("b", "a1"); - relation.add("b", "b1"); - relation.add("a1", "x"); - relation.add("b1", "x"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), - vec![&"a1", &"b1"]); - assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); - assert_eq!(relation.postdom_parent(&"a"), Some(&"x")); - assert_eq!(relation.postdom_parent(&"b"), Some(&"x")); -} - -#[test] -fn pdub_crisscross_more() { - // diagonal edges run left-to-right - // a -> a1 -> a2 -> a3 -> x - // \/ \/ ^ - // /\ /\ | - // b -> b1 -> b2 ---------+ - - let mut relation = TransitiveRelation::default(); - relation.add("a", "a1"); - relation.add("a", "b1"); - relation.add("b", "a1"); - relation.add("b", "b1"); - - relation.add("a1", "a2"); - relation.add("a1", "b2"); - relation.add("b1", "a2"); - relation.add("b1", "b2"); - - relation.add("a2", "a3"); - - relation.add("a3", "x"); - relation.add("b2", "x"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), - vec![&"a1", &"b1"]); - assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"), - vec![&"a2", &"b2"]); - assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); - - assert_eq!(relation.postdom_parent(&"a"), Some(&"x")); - assert_eq!(relation.postdom_parent(&"b"), Some(&"x")); -} - -#[test] -fn pdub_lub() { - // a -> a1 -> x - // ^ - // | - // b -> b1 ---+ - - let mut relation = TransitiveRelation::default(); - relation.add("a", "a1"); - relation.add("b", "b1"); - relation.add("a1", "x"); - relation.add("b1", "x"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"x"]); - assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); - - assert_eq!(relation.postdom_parent(&"a"), Some(&"a1")); - assert_eq!(relation.postdom_parent(&"b"), Some(&"b1")); - assert_eq!(relation.postdom_parent(&"a1"), Some(&"x")); - assert_eq!(relation.postdom_parent(&"b1"), Some(&"x")); -} - -#[test] -fn mubs_intermediate_node_on_one_side_only() { - // a -> c -> d - // ^ - // | - // b - - // "digraph { a -> c -> d; b -> d; }", - let mut relation = TransitiveRelation::default(); - relation.add("a", "c"); - relation.add("c", "d"); - relation.add("b", "d"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"d"]); -} - -#[test] -fn mubs_scc_1() { - // +-------------+ - // | +----+ | - // | v | | - // a -> c -> d <-+ - // ^ - // | - // b - - // "digraph { a -> c -> d; d -> c; a -> d; b -> d; }", - let mut relation = TransitiveRelation::default(); - relation.add("a", "c"); - relation.add("c", "d"); - relation.add("d", "c"); - relation.add("a", "d"); - relation.add("b", "d"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); -} - -#[test] -fn mubs_scc_2() { - // +----+ - // v | - // a -> c -> d - // ^ ^ - // | | - // +--- b - - // "digraph { a -> c -> d; d -> c; b -> d; b -> c; }", - let mut relation = TransitiveRelation::default(); - relation.add("a", "c"); - relation.add("c", "d"); - relation.add("d", "c"); - relation.add("b", "d"); - relation.add("b", "c"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); -} - -#[test] -fn mubs_scc_3() { - // +---------+ - // v | - // a -> c -> d -> e - // ^ ^ - // | | - // b ---+ - - // "digraph { a -> c -> d -> e -> c; b -> d; b -> e; }", - let mut relation = TransitiveRelation::default(); - relation.add("a", "c"); - relation.add("c", "d"); - relation.add("d", "e"); - relation.add("e", "c"); - relation.add("b", "d"); - relation.add("b", "e"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); -} - -#[test] -fn mubs_scc_4() { - // +---------+ - // v | - // a -> c -> d -> e - // | ^ ^ - // +---------+ | - // | - // b ---+ - - // "digraph { a -> c -> d -> e -> c; a -> d; b -> e; }" - let mut relation = TransitiveRelation::default(); - relation.add("a", "c"); - relation.add("c", "d"); - relation.add("d", "e"); - relation.add("e", "c"); - relation.add("a", "d"); - relation.add("b", "e"); - - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); -} - -#[test] -fn parent() { - // An example that was misbehaving in the compiler. - // - // 4 -> 1 -> 3 - // \ | / - // \ v / - // 2 -> 0 - // - // plus a bunch of self-loops - // - // Here `->` represents `<=` and `0` is `'static`. - - let pairs = vec![ - (2, /*->*/ 0), - (2, /*->*/ 2), - (0, /*->*/ 0), - (0, /*->*/ 0), - (1, /*->*/ 0), - (1, /*->*/ 1), - (3, /*->*/ 0), - (3, /*->*/ 3), - (4, /*->*/ 0), - (4, /*->*/ 1), - (1, /*->*/ 3), - ]; - - let mut relation = TransitiveRelation::default(); - for (a, b) in pairs { - relation.add(a, b); - } - - let p = relation.postdom_parent(&3); - assert_eq!(p, Some(&0)); -} diff --git a/src/librustc_data_structures/transitive_relation/tests.rs b/src/librustc_data_structures/transitive_relation/tests.rs new file mode 100644 index 0000000000..a462dbdb58 --- /dev/null +++ b/src/librustc_data_structures/transitive_relation/tests.rs @@ -0,0 +1,357 @@ +use super::*; + +#[test] +fn test_one_step() { + let mut relation = TransitiveRelation::default(); + relation.add("a", "b"); + relation.add("a", "c"); + assert!(relation.contains(&"a", &"c")); + assert!(relation.contains(&"a", &"b")); + assert!(!relation.contains(&"b", &"a")); + assert!(!relation.contains(&"a", &"d")); +} + +#[test] +fn test_many_steps() { + let mut relation = TransitiveRelation::default(); + relation.add("a", "b"); + relation.add("a", "c"); + relation.add("a", "f"); + + relation.add("b", "c"); + relation.add("b", "d"); + relation.add("b", "e"); + + relation.add("e", "g"); + + assert!(relation.contains(&"a", &"b")); + assert!(relation.contains(&"a", &"c")); + assert!(relation.contains(&"a", &"d")); + assert!(relation.contains(&"a", &"e")); + assert!(relation.contains(&"a", &"f")); + assert!(relation.contains(&"a", &"g")); + + assert!(relation.contains(&"b", &"g")); + + assert!(!relation.contains(&"a", &"x")); + assert!(!relation.contains(&"b", &"f")); +} + +#[test] +fn mubs_triangle() { + // a -> tcx + // ^ + // | + // b + let mut relation = TransitiveRelation::default(); + relation.add("a", "tcx"); + relation.add("b", "tcx"); + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"tcx"]); + assert_eq!(relation.parents(&"a"), vec![&"tcx"]); + assert_eq!(relation.parents(&"b"), vec![&"tcx"]); +} + +#[test] +fn mubs_best_choice1() { + // 0 -> 1 <- 3 + // | ^ | + // | | | + // +--> 2 <--+ + // + // mubs(0,3) = [1] + + // This tests a particular state in the algorithm, in which we + // need the second pare down call to get the right result (after + // intersection, we have [1, 2], but 2 -> 1). + + let mut relation = TransitiveRelation::default(); + relation.add("0", "1"); + relation.add("0", "2"); + + relation.add("2", "1"); + + relation.add("3", "1"); + relation.add("3", "2"); + + assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"2"]); + assert_eq!(relation.parents(&"0"), vec![&"2"]); + assert_eq!(relation.parents(&"2"), vec![&"1"]); + assert!(relation.parents(&"1").is_empty()); +} + +#[test] +fn mubs_best_choice2() { + // 0 -> 1 <- 3 + // | | | + // | v | + // +--> 2 <--+ + // + // mubs(0,3) = [2] + + // Like the precedecing test, but in this case intersection is [2, + // 1], and hence we rely on the first pare down call. + + let mut relation = TransitiveRelation::default(); + relation.add("0", "1"); + relation.add("0", "2"); + + relation.add("1", "2"); + + relation.add("3", "1"); + relation.add("3", "2"); + + assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1"]); + assert_eq!(relation.parents(&"0"), vec![&"1"]); + assert_eq!(relation.parents(&"1"), vec![&"2"]); + assert!(relation.parents(&"2").is_empty()); +} + +#[test] +fn mubs_no_best_choice() { + // in this case, the intersection yields [1, 2], and the "pare + // down" calls find nothing to remove. + let mut relation = TransitiveRelation::default(); + relation.add("0", "1"); + relation.add("0", "2"); + + relation.add("3", "1"); + relation.add("3", "2"); + + assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1", &"2"]); + assert_eq!(relation.parents(&"0"), vec![&"1", &"2"]); + assert_eq!(relation.parents(&"3"), vec![&"1", &"2"]); +} + +#[test] +fn mubs_best_choice_scc() { + // in this case, 1 and 2 form a cycle; we pick arbitrarily (but + // consistently). + + let mut relation = TransitiveRelation::default(); + relation.add("0", "1"); + relation.add("0", "2"); + + relation.add("1", "2"); + relation.add("2", "1"); + + relation.add("3", "1"); + relation.add("3", "2"); + + assert_eq!(relation.minimal_upper_bounds(&"0", &"3"), vec![&"1"]); + assert_eq!(relation.parents(&"0"), vec![&"1"]); +} + +#[test] +fn pdub_crisscross() { + // diagonal edges run left-to-right + // a -> a1 -> x + // \/ ^ + // /\ | + // b -> b1 ---+ + + let mut relation = TransitiveRelation::default(); + relation.add("a", "a1"); + relation.add("a", "b1"); + relation.add("b", "a1"); + relation.add("b", "b1"); + relation.add("a1", "x"); + relation.add("b1", "x"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), + vec![&"a1", &"b1"]); + assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); + assert_eq!(relation.postdom_parent(&"a"), Some(&"x")); + assert_eq!(relation.postdom_parent(&"b"), Some(&"x")); +} + +#[test] +fn pdub_crisscross_more() { + // diagonal edges run left-to-right + // a -> a1 -> a2 -> a3 -> x + // \/ \/ ^ + // /\ /\ | + // b -> b1 -> b2 ---------+ + + let mut relation = TransitiveRelation::default(); + relation.add("a", "a1"); + relation.add("a", "b1"); + relation.add("b", "a1"); + relation.add("b", "b1"); + + relation.add("a1", "a2"); + relation.add("a1", "b2"); + relation.add("b1", "a2"); + relation.add("b1", "b2"); + + relation.add("a2", "a3"); + + relation.add("a3", "x"); + relation.add("b2", "x"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), + vec![&"a1", &"b1"]); + assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"), + vec![&"a2", &"b2"]); + assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); + + assert_eq!(relation.postdom_parent(&"a"), Some(&"x")); + assert_eq!(relation.postdom_parent(&"b"), Some(&"x")); +} + +#[test] +fn pdub_lub() { + // a -> a1 -> x + // ^ + // | + // b -> b1 ---+ + + let mut relation = TransitiveRelation::default(); + relation.add("a", "a1"); + relation.add("b", "b1"); + relation.add("a1", "x"); + relation.add("b1", "x"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"x"]); + assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); + + assert_eq!(relation.postdom_parent(&"a"), Some(&"a1")); + assert_eq!(relation.postdom_parent(&"b"), Some(&"b1")); + assert_eq!(relation.postdom_parent(&"a1"), Some(&"x")); + assert_eq!(relation.postdom_parent(&"b1"), Some(&"x")); +} + +#[test] +fn mubs_intermediate_node_on_one_side_only() { + // a -> c -> d + // ^ + // | + // b + + // "digraph { a -> c -> d; b -> d; }", + let mut relation = TransitiveRelation::default(); + relation.add("a", "c"); + relation.add("c", "d"); + relation.add("b", "d"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"d"]); +} + +#[test] +fn mubs_scc_1() { + // +-------------+ + // | +----+ | + // | v | | + // a -> c -> d <-+ + // ^ + // | + // b + + // "digraph { a -> c -> d; d -> c; a -> d; b -> d; }", + let mut relation = TransitiveRelation::default(); + relation.add("a", "c"); + relation.add("c", "d"); + relation.add("d", "c"); + relation.add("a", "d"); + relation.add("b", "d"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); +} + +#[test] +fn mubs_scc_2() { + // +----+ + // v | + // a -> c -> d + // ^ ^ + // | | + // +--- b + + // "digraph { a -> c -> d; d -> c; b -> d; b -> c; }", + let mut relation = TransitiveRelation::default(); + relation.add("a", "c"); + relation.add("c", "d"); + relation.add("d", "c"); + relation.add("b", "d"); + relation.add("b", "c"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); +} + +#[test] +fn mubs_scc_3() { + // +---------+ + // v | + // a -> c -> d -> e + // ^ ^ + // | | + // b ---+ + + // "digraph { a -> c -> d -> e -> c; b -> d; b -> e; }", + let mut relation = TransitiveRelation::default(); + relation.add("a", "c"); + relation.add("c", "d"); + relation.add("d", "e"); + relation.add("e", "c"); + relation.add("b", "d"); + relation.add("b", "e"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); +} + +#[test] +fn mubs_scc_4() { + // +---------+ + // v | + // a -> c -> d -> e + // | ^ ^ + // +---------+ | + // | + // b ---+ + + // "digraph { a -> c -> d -> e -> c; a -> d; b -> e; }" + let mut relation = TransitiveRelation::default(); + relation.add("a", "c"); + relation.add("c", "d"); + relation.add("d", "e"); + relation.add("e", "c"); + relation.add("a", "d"); + relation.add("b", "e"); + + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]); +} + +#[test] +fn parent() { + // An example that was misbehaving in the compiler. + // + // 4 -> 1 -> 3 + // \ | / + // \ v / + // 2 -> 0 + // + // plus a bunch of self-loops + // + // Here `->` represents `<=` and `0` is `'static`. + + let pairs = vec![ + (2, /*->*/ 0), + (2, /*->*/ 2), + (0, /*->*/ 0), + (0, /*->*/ 0), + (1, /*->*/ 0), + (1, /*->*/ 1), + (3, /*->*/ 0), + (3, /*->*/ 3), + (4, /*->*/ 0), + (4, /*->*/ 1), + (1, /*->*/ 3), + ]; + + let mut relation = TransitiveRelation::default(); + for (a, b) in pairs { + relation.add(a, b); + } + + let p = relation.postdom_parent(&3); + assert_eq!(p, Some(&0)); +} diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index b28b015db7..42aa8203cb 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -10,33 +10,19 @@ path = "lib.rs" crate-type = ["dylib"] [dependencies] -arena = { path = "../libarena" } graphviz = { path = "../libgraphviz" } log = "0.4" env_logger = { version = "0.5", default-features = false } -rayon = { version = "0.2.0", package = "rustc-rayon" } -scoped-tls = "1.0" rustc = { path = "../librustc" } -rustc_allocator = { path = "../librustc_allocator" } rustc_target = { path = "../librustc_target" } -rustc_borrowck = { path = "../librustc_borrowck" } +rustc_ast_borrowck = { path = "../librustc_ast_borrowck" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } -rustc_incremental = { path = "../librustc_incremental" } -rustc_lint = { path = "../librustc_lint" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } -rustc_passes = { path = "../librustc_passes" } -rustc_plugin = { path = "../librustc_plugin" } -rustc_privacy = { path = "../librustc_privacy" } -rustc_resolve = { path = "../librustc_resolve" } rustc_save_analysis = { path = "../librustc_save_analysis" } -rustc_traits = { path = "../librustc_traits" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } -rustc_typeck = { path = "../librustc_typeck" } rustc_interface = { path = "../librustc_interface" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } -smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } -syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5fb6ed31b0..e9d85a53d1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -16,10 +16,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - pub extern crate getopts; #[cfg(unix)] extern crate libc; @@ -38,7 +34,8 @@ use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; use rustc::hir::def_id::LOCAL_CRATE; -use rustc::util::common::{time, ErrorReported, install_panic_hook}; +use rustc::util::common::{ErrorReported, install_panic_hook, print_time_passes_entry}; +use rustc::util::common::{set_time_depth, time}; use rustc_metadata::locator; use rustc_metadata::cstore::CStore; use rustc_codegen_utils::codegen_backend::CodegenBackend; @@ -46,7 +43,7 @@ use rustc_interface::interface; use rustc_interface::util::get_codegen_sysroot; use rustc_data_structures::sync::SeqCst; -use serialize::json::ToJson; +use rustc_serialize::json::ToJson; use std::borrow::Cow; use std::cmp::max; @@ -54,11 +51,12 @@ use std::default::Default; use std::env; use std::ffi::OsString; use std::io::{self, Read, Write}; +use std::mem; use std::panic::{self, catch_unwind}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; -use std::mem; +use std::time::Instant; use syntax::ast; use syntax::source_map::FileLoader; @@ -72,7 +70,7 @@ pub mod pretty; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; -/// Exit status code used for compilation failures and invalid flags. +/// Exit status code used for compilation failures and invalid flags. pub const EXIT_FAILURE: i32 = 1; const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ @@ -104,13 +102,20 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} - /// Called after parsing and returns true to continue execution - fn after_parsing(&mut self, _compiler: &interface::Compiler) -> bool { - true + /// Called after parsing. Return value instructs the compiler whether to + /// continue the compilation afterwards (defaults to `Compilation::Continue`) + fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation { + Compilation::Continue } - /// Called after analysis and returns true to continue execution - fn after_analysis(&mut self, _compiler: &interface::Compiler) -> bool { - true + /// Called after expansion. Return value instructs the compiler whether to + /// continue the compilation afterwards (defaults to `Compilation::Continue`) + fn after_expansion(&mut self, _compiler: &interface::Compiler) -> Compilation { + Compilation::Continue + } + /// Called after analysis. Return value instructs the compiler whether to + /// continue the compilation afterwards (defaults to `Compilation::Continue`) + fn after_analysis(&mut self, _compiler: &interface::Compiler) -> Compilation { + Compilation::Continue } } @@ -118,6 +123,18 @@ pub struct DefaultCallbacks; impl Callbacks for DefaultCallbacks {} +#[derive(Default)] +pub struct TimePassesCallbacks { + time_passes: bool, +} + +impl Callbacks for TimePassesCallbacks { + fn config(&mut self, config: &mut interface::Config) { + self.time_passes = + config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time; + } +} + // Parse args and run the compiler. This is the primary entry point for rustc. // See comments on CompilerCalls below for details about the callbacks argument. // The FileLoader provides a way to load files from sources other than the file system. @@ -281,7 +298,7 @@ pub fn run_compiler( } } - if !callbacks.after_parsing(compiler) { + if callbacks.after_parsing(compiler) == Compilation::Stop { return sess.compile_status(); } @@ -299,6 +316,11 @@ pub fn run_compiler( return sess.compile_status(); } + compiler.expansion()?; + if callbacks.after_expansion(compiler) == Compilation::Stop { + return sess.compile_status(); + } + compiler.prepare_outputs()?; if sess.opts.output_types.contains_key(&OutputType::DepInfo) @@ -342,7 +364,7 @@ pub fn run_compiler( compiler.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; - if !callbacks.after_analysis(compiler) { + if callbacks.after_analysis(compiler) == Compilation::Stop { return sess.compile_status(); } @@ -935,14 +957,11 @@ fn print_flag_list(cmdline_opt: &str, /// otherwise returns `None`. /// /// The compiler's handling of options is a little complicated as it ties into -/// our stability story, and it's even *more* complicated by historical -/// accidents. The current intention of each compiler option is to have one of -/// three modes: +/// our stability story. The current intention of each compiler option is to +/// have one of two modes: /// /// 1. An option is stable and can be used everywhere. -/// 2. An option is unstable, but was historically allowed on the stable -/// channel. -/// 3. An option is unstable, and can only be used on nightly. +/// 2. An option is unstable, and can only be used on nightly. /// /// Like unstable library and language features, however, unstable options have /// always required a form of "opt in" to indicate that you're using them. This @@ -985,19 +1004,13 @@ pub fn handle_options(args: &[String]) -> Option { // this option that was passed. // * If we're a nightly compiler, then unstable options are now unlocked, so // we're good to go. - // * Otherwise, if we're a truly unstable option then we generate an error + // * Otherwise, if we're an unstable option then we generate an error // (unstable option being used on stable) - // * If we're a historically stable-but-should-be-unstable option then we - // emit a warning that we're going to turn this into an error soon. nightly_options::check_nightly_options(&matches, &config::rustc_optgroups()); if matches.opt_present("h") || matches.opt_present("help") { - // Only show unstable options in --help if we *really* accept unstable - // options, which catches the case where we got `-Z unstable-options` on - // the stable channel of Rust which was accidentally allowed - // historically. - usage(matches.opt_present("verbose"), - nightly_options::is_unstable_enabled(&matches)); + // Only show unstable options in --help if we accept unstable options. + usage(matches.opt_present("verbose"), nightly_options::is_unstable_enabled(&matches)); return None; } @@ -1169,7 +1182,9 @@ pub fn init_rustc_env_logger() { } pub fn main() { + let start = Instant::now(); init_rustc_env_logger(); + let mut callbacks = TimePassesCallbacks::default(); let result = report_ices_to_stderr_if_any(|| { let args = env::args_os().enumerate() .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| { @@ -1177,10 +1192,14 @@ pub fn main() { &format!("Argument {} is not valid Unicode: {:?}", i, arg)) })) .collect::>(); - run_compiler(&args, &mut DefaultCallbacks, None, None) + run_compiler(&args, &mut callbacks, None, None) }).and_then(|result| result); - process::exit(match result { + let exit_code = match result { Ok(_) => EXIT_SUCCESS, Err(_) => EXIT_FAILURE, - }); + }; + // The extra `\t` is necessary to align this label with the others. + set_time_depth(0); + print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed()); + process::exit(exit_code); } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index d92f3aafa1..cb17401f62 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -12,14 +12,13 @@ use rustc::session::config::Input; use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; use rustc_interface::util::ReplaceBodyWithLoop; -use rustc_borrowck as borrowck; -use rustc_borrowck::graphviz as borrowck_dot; +use rustc_ast_borrowck as borrowck; +use rustc_ast_borrowck::graphviz as borrowck_dot; use rustc_mir::util::{write_mir_pretty, write_mir_graphviz}; use syntax::ast; use syntax::mut_visit::MutVisitor; use syntax::print::{pprust}; -use syntax::print::pprust::PrintState; use syntax_pos::FileName; use graphviz as dot; @@ -188,7 +187,7 @@ impl PpSourceMode { _ => panic!("Should use call_with_pp_support_hir"), } } - fn call_with_pp_support_hir<'tcx, A, F>(&self, tcx: TyCtxt<'tcx>, f: F) -> A + fn call_with_pp_support_hir(&self, tcx: TyCtxt<'_>, f: F) -> A where F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A, { @@ -228,7 +227,7 @@ impl PpSourceMode { trait PrinterSupport: pprust::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. - fn sess<'a>(&'a self) -> &'a Session; + fn sess(&self) -> &Session; /// Produces the pretty-print annotation object. /// @@ -240,7 +239,7 @@ trait PrinterSupport: pprust::PpAnn { trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. - fn sess<'a>(&'a self) -> &'a Session; + fn sess(&self) -> &Session; /// Provides a uniform interface for re-extracting a reference to an /// `hir_map::Map` from a value that now owns it. @@ -272,7 +271,7 @@ struct NoAnn<'hir> { } impl<'hir> PrinterSupport for NoAnn<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -282,7 +281,7 @@ impl<'hir> PrinterSupport for NoAnn<'hir> { } impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -297,12 +296,9 @@ impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { impl<'hir> pprust::PpAnn for NoAnn<'hir> {} impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { - fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) - -> io::Result<()> { + fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(tcx) = self.tcx { pprust_hir::PpAnn::nested(tcx.hir(), state, nested) - } else { - Ok(()) } } } @@ -313,7 +309,7 @@ struct IdentifiedAnnotation<'hir> { } impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -323,44 +319,44 @@ impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { } impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { - fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) -> io::Result<()> { + fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { match node { pprust::AnnNode::Expr(_) => s.popen(), - _ => Ok(()), + _ => {} } } - fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) -> io::Result<()> { + fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { match node { pprust::AnnNode::Ident(_) | - pprust::AnnNode::Name(_) => Ok(()), + pprust::AnnNode::Name(_) => {}, pprust::AnnNode::Item(item) => { - s.s.space()?; + s.s.space(); s.synth_comment(item.id.to_string()) } pprust::AnnNode::SubItem(id) => { - s.s.space()?; + s.s.space(); s.synth_comment(id.to_string()) } pprust::AnnNode::Block(blk) => { - s.s.space()?; + s.s.space(); s.synth_comment(format!("block {}", blk.id)) } pprust::AnnNode::Expr(expr) => { - s.s.space()?; - s.synth_comment(expr.id.to_string())?; + s.s.space(); + s.synth_comment(expr.id.to_string()); s.pclose() } pprust::AnnNode::Pat(pat) => { - s.s.space()?; - s.synth_comment(format!("pat {}", pat.id)) + s.s.space(); + s.synth_comment(format!("pat {}", pat.id)); } } } } impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -374,47 +370,44 @@ impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { } impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { - fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) - -> io::Result<()> { + fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(ref tcx) = self.tcx { pprust_hir::PpAnn::nested(tcx.hir(), state, nested) - } else { - Ok(()) } } - fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> { + fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { match node { pprust_hir::AnnNode::Expr(_) => s.popen(), - _ => Ok(()), + _ => {} } } - fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> { + fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { match node { - pprust_hir::AnnNode::Name(_) => Ok(()), + pprust_hir::AnnNode::Name(_) => {}, pprust_hir::AnnNode::Item(item) => { - s.s.space()?; - s.synth_comment(format!("hir_id: {} hir local_id: {}", - item.hir_id, item.hir_id.local_id.as_u32())) + s.s.space(); + s.synth_comment(format!("hir_id: {}", item.hir_id)); } pprust_hir::AnnNode::SubItem(id) => { - s.s.space()?; - s.synth_comment(id.to_string()) + s.s.space(); + s.synth_comment(id.to_string()); } pprust_hir::AnnNode::Block(blk) => { - s.s.space()?; - s.synth_comment(format!("block hir_id: {} hir local_id: {}", - blk.hir_id, blk.hir_id.local_id.as_u32())) + s.s.space(); + s.synth_comment(format!("block hir_id: {}", blk.hir_id)); } pprust_hir::AnnNode::Expr(expr) => { - s.s.space()?; - s.synth_comment(format!("expr hir_id: {} hir local_id: {}", - expr.hir_id, expr.hir_id.local_id.as_u32()))?; - s.pclose() + s.s.space(); + s.synth_comment(format!("expr hir_id: {}", expr.hir_id)); + s.pclose(); } pprust_hir::AnnNode::Pat(pat) => { - s.s.space()?; - s.synth_comment(format!("pat hir_id: {} hir local_id: {}", - pat.hir_id, pat.hir_id.local_id.as_u32())) + s.s.space(); + s.synth_comment(format!("pat hir_id: {}", pat.hir_id)); + } + pprust_hir::AnnNode::Arm(arm) => { + s.s.space(); + s.synth_comment(format!("arm hir_id: {}", arm.hir_id)); } } } @@ -435,19 +428,19 @@ impl<'a> PrinterSupport for HygieneAnnotation<'a> { } impl<'a> pprust::PpAnn for HygieneAnnotation<'a> { - fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) -> io::Result<()> { + fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { match node { pprust::AnnNode::Ident(&ast::Ident { name, span }) => { - s.s.space()?; + s.s.space(); // FIXME #16420: this doesn't display the connections // between syntax contexts s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt())) } pprust::AnnNode::Name(&name) => { - s.s.space()?; + s.s.space(); s.synth_comment(name.as_u32().to_string()) } - _ => Ok(()), + _ => {} } } } @@ -458,7 +451,7 @@ struct TypedAnnotation<'a, 'tcx> { } impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { &self.tcx.sess } @@ -471,37 +464,35 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { } fn node_path(&self, id: hir::HirId) -> Option { - Some(self.tcx.def_path_str(self.tcx.hir().local_def_id_from_hir_id(id))) + Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id))) } } impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { - fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) - -> io::Result<()> { + fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { let old_tables = self.tables.get(); if let pprust_hir::Nested::Body(id) = nested { self.tables.set(self.tcx.body_tables(id)); } - pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested)?; + pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested); self.tables.set(old_tables); - Ok(()) } - fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> { + fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { match node { pprust_hir::AnnNode::Expr(_) => s.popen(), - _ => Ok(()), + _ => {} } } - fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> { + fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { match node { pprust_hir::AnnNode::Expr(expr) => { - s.s.space()?; - s.s.word("as")?; - s.s.space()?; - s.s.word(self.tables.get().expr_ty(expr).to_string())?; - s.pclose() + s.s.space(); + s.s.word("as"); + s.s.space(); + s.s.word(self.tables.get().expr_ty(expr).to_string()); + s.pclose(); } - _ => Ok(()), + _ => {}, } } } @@ -695,16 +686,14 @@ pub fn visit_crate(sess: &Session, krate: &mut ast::Crate, ppm: PpMode) { } } -fn get_source(input: &Input, sess: &Session) -> (Vec, FileName) { +fn get_source(input: &Input, sess: &Session) -> (String, FileName) { let src_name = source_name(input); - let src = sess.source_map() + let src = String::clone(&sess.source_map() .get_source_file(&src_name) .unwrap() .src .as_ref() - .unwrap() - .as_bytes() - .to_vec(); + .unwrap()); (src, src_name) } @@ -727,29 +716,27 @@ pub fn print_after_parsing(sess: &Session, ofile: Option<&Path>) { let (src, src_name) = get_source(input, sess); - let mut rdr = &*src; - let mut out = Vec::new(); + let mut out = String::new(); if let PpmSource(s) = ppm { // Silently ignores an identified node. - let out: &mut dyn Write = &mut out; + let out = &mut out; s.call_with_pp_support(sess, None, move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - pprust::print_crate(sess.source_map(), + *out = pprust::print_crate(sess.source_map(), &sess.parse_sess, krate, src_name, - &mut rdr, - box out, + src, annotation.pp_ann(), false) - }).unwrap() + }) } else { unreachable!(); }; - write_output(out, ofile); + write_output(out.into_bytes(), ofile); } pub fn print_after_hir_lowering<'tcx>( @@ -772,52 +759,52 @@ pub fn print_after_hir_lowering<'tcx>( let (src, src_name) = get_source(input, tcx.sess); - let mut rdr = &src[..]; - let mut out = Vec::new(); + let mut out = String::new(); match (ppm, opt_uii) { (PpmSource(s), _) => { // Silently ignores an identified node. - let out: &mut dyn Write = &mut out; + let out = &mut out; + let src = src.clone(); s.call_with_pp_support(tcx.sess, Some(tcx), move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - pprust::print_crate(sess.source_map(), + *out = pprust::print_crate(sess.source_map(), &sess.parse_sess, krate, src_name, - &mut rdr, - box out, + src, annotation.pp_ann(), true) }) } (PpmHir(s), None) => { - let out: &mut dyn Write = &mut out; + let out = &mut out; + let src = src.clone(); s.call_with_pp_support_hir(tcx, move |annotation, krate| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - pprust_hir::print_crate(sess.source_map(), + *out = pprust_hir::print_crate(sess.source_map(), &sess.parse_sess, krate, src_name, - &mut rdr, - box out, + src, annotation.pp_ann()) }) } (PpmHirTree(s), None) => { - let out: &mut dyn Write = &mut out; + let out = &mut out; s.call_with_pp_support_hir(tcx, move |_annotation, krate| { debug!("pretty printing source code {:?}", s); - write!(out, "{:#?}", krate) - }) + *out = format!("{:#?}", krate); + }); } (PpmHir(s), Some(uii)) => { - let out: &mut dyn Write = &mut out; + let out = &mut out; + let src = src.clone(); s.call_with_pp_support_hir(tcx, move |annotation, _| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); @@ -825,49 +812,46 @@ pub fn print_after_hir_lowering<'tcx>( let mut pp_state = pprust_hir::State::new_from_input(sess.source_map(), &sess.parse_sess, src_name, - &mut rdr, - box out, + src, annotation.pp_ann()); for node_id in uii.all_matching_node_ids(hir_map) { let hir_id = tcx.hir().node_to_hir_id(node_id); let node = hir_map.get(hir_id); - pp_state.print_node(node)?; - pp_state.s.space()?; + pp_state.print_node(node); + pp_state.s.space(); let path = annotation.node_path(hir_id) .expect("-Z unpretty missing node paths"); - pp_state.synth_comment(path)?; - pp_state.s.hardbreak()?; + pp_state.synth_comment(path); + pp_state.s.hardbreak(); } - pp_state.s.eof() + *out = pp_state.s.eof(); }) } (PpmHirTree(s), Some(uii)) => { - let out: &mut dyn Write = &mut out; + let out = &mut out; s.call_with_pp_support_hir(tcx, move |_annotation, _krate| { debug!("pretty printing source code {:?}", s); for node_id in uii.all_matching_node_ids(tcx.hir()) { let hir_id = tcx.hir().node_to_hir_id(node_id); let node = tcx.hir().get(hir_id); - write!(out, "{:#?}", node)?; + out.push_str(&format!("{:#?}", node)); } - Ok(()) }) } _ => unreachable!(), } - .unwrap(); - write_output(out, ofile); + write_output(out.into_bytes(), ofile); } // In an ideal world, this would be a public function called by the driver after // analysis is performed. However, we want to call `phase_3_run_analysis_passes` // with a different callback than the standard driver, so that isn't easy. // Instead, we call that function ourselves. -fn print_with_analysis<'tcx>( - tcx: TyCtxt<'tcx>, +fn print_with_analysis( + tcx: TyCtxt<'_>, ppm: PpMode, uii: Option, ofile: Option<&Path>, @@ -887,7 +871,7 @@ fn print_with_analysis<'tcx>( let mut print = || match ppm { PpmMir | PpmMirCFG => { if let Some(nodeid) = nodeid { - let def_id = tcx.hir().local_def_id(nodeid); + let def_id = tcx.hir().local_def_id_from_node_id(nodeid); match ppm { PpmMir => write_mir_pretty(tcx, Some(def_id), &mut out), PpmMirCFG => write_mir_graphviz(tcx, Some(def_id), &mut out), @@ -908,7 +892,7 @@ fn print_with_analysis<'tcx>( suffix (b::c::d)"); let hir_id = tcx.hir().node_to_hir_id(nodeid); let node = tcx.hir().find(hir_id).unwrap_or_else(|| { - tcx.sess.fatal(&format!("--pretty flowgraph couldn't find id: {}", nodeid)) + tcx.sess.fatal(&format!("`--pretty=flowgraph` couldn't find ID: {}", nodeid)) }); match blocks::Code::from_node(&tcx.hir(), hir_id) { @@ -920,7 +904,7 @@ fn print_with_analysis<'tcx>( print_flowgraph(variants, tcx, code, mode, out) } None => { - let message = format!("--pretty=flowgraph needs block, fn, or method; \ + let message = format!("`--pretty=flowgraph` needs block, fn, or method; \ got {:?}", node); diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 3689a463a5..32f121f18f 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -7,15 +7,14 @@ edition = "2018" [lib] name = "rustc_errors" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] log = "0.4" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax_pos = { path = "../libsyntax_pos" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } unicode-width = "0.1.4" atty = "0.2" termcolor = "1.0" -annotate-snippets = "0.5.0" +annotate-snippets = "0.6.1" diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 3641d355ef..96a9b6c5c4 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -23,7 +23,7 @@ pub struct AnnotateSnippetEmitterWriter { source_map: Option>, /// If true, hides the longer explanation text short_message: bool, - /// If true, will normalize line numbers with LL to prevent noise in UI test diffs. + /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs. ui_testing: bool, } @@ -173,10 +173,6 @@ impl AnnotateSnippetEmitterWriter { /// Allows to modify `Self` to enable or disable the `ui_testing` flag. /// /// If this is set to true, line numbers will be normalized as `LL` in the output. - // FIXME(#59346): This method is used via the public interface, but setting the `ui_testing` - // flag currently does not anonymize line numbers. We would have to add the `maybe_anonymized` - // method from `emitter.rs` and implement rust-lang/annotate-snippets-rs#2 in order to - // anonymize line numbers. pub fn ui_testing(mut self, ui_testing: bool) -> Self { self.ui_testing = ui_testing; self @@ -202,7 +198,7 @@ impl AnnotateSnippetEmitterWriter { }; if let Some(snippet) = converter.to_annotation_snippet() { let dl = DisplayList::from(snippet); - let dlf = DisplayListFormatter::new(true); + let dlf = DisplayListFormatter::new(true, self.ui_testing); // FIXME(#59346): Figure out if we can _always_ print to stderr or not. // `emitter.rs` has the `Destination` enum that lists various possible output // destinations. diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index fc74e43ff5..41d0638f7c 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -380,10 +380,13 @@ impl<'a> Debug for DiagnosticBuilder<'a> { impl<'a> Drop for DiagnosticBuilder<'a> { fn drop(&mut self) { if !panicking() && !self.cancelled() { - let mut db = DiagnosticBuilder::new(self.handler, - Level::Bug, - "Error constructed but not emitted"); + let mut db = DiagnosticBuilder::new( + self.handler, + Level::Bug, + "the following error was constructed but not emitted", + ); db.emit(); + self.emit(); panic!(); } } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index a2717ab7ad..361b5cd935 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -723,39 +723,37 @@ impl EmitterWriter { for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() { // Only show macro locations that are local // and display them like a span_note - if let Some(def_site) = trace.def_site_span { - if def_site.is_dummy() { - continue; - } - if always_backtrace { - new_labels.push((def_site, - format!("in this expansion of `{}`{}", - trace.macro_decl_name, - if backtrace_len > 2 { - // if backtrace_len == 1 it'll be pointed - // at by "in this macro invocation" - format!(" (#{})", i + 1) - } else { - String::new() - }))); - } - // Check to make sure we're not in any <*macros> - if !sm.span_to_filename(def_site).is_macros() && - !trace.macro_decl_name.starts_with("desugaring of ") && - !trace.macro_decl_name.starts_with("#[") || - always_backtrace { - new_labels.push((trace.call_site, - format!("in this macro invocation{}", - if backtrace_len > 2 && always_backtrace { - // only specify order when the macro - // backtrace is multiple levels deep - format!(" (#{})", i + 1) - } else { - String::new() - }))); - if !always_backtrace { - break; - } + if trace.def_site_span.is_dummy() { + continue; + } + if always_backtrace { + new_labels.push((trace.def_site_span, + format!("in this expansion of `{}`{}", + trace.macro_decl_name, + if backtrace_len > 2 { + // if backtrace_len == 1 it'll be pointed + // at by "in this macro invocation" + format!(" (#{})", i + 1) + } else { + String::new() + }))); + } + // Check to make sure we're not in any <*macros> + if !sm.span_to_filename(trace.def_site_span).is_macros() && + !trace.macro_decl_name.starts_with("desugaring of ") && + !trace.macro_decl_name.starts_with("#[") || + always_backtrace { + new_labels.push((trace.call_site, + format!("in this macro invocation{}", + if backtrace_len > 2 && always_backtrace { + // only specify order when the macro + // backtrace is multiple levels deep + format!(" (#{})", i + 1) + } else { + String::new() + }))); + if !always_backtrace { + break; } } } @@ -1635,7 +1633,7 @@ impl Destination { } } - fn writable<'a>(&'a mut self) -> WritableDst<'a> { + fn writable(&mut self) -> WritableDst<'_> { match *self { Destination::Terminal(ref mut t) => WritableDst::Terminal(t), Destination::Buffered(ref mut t) => { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 70bd25a9d5..3b6a6a824c 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -5,16 +5,9 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] -#![allow(unused_attributes)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving pub use emitter::ColorConfig; @@ -230,7 +223,8 @@ impl CodeSuggestion { } } if let Some(cur_line) = fm.get_line(cur_lo.line - 1) { - buf.push_str(&cur_line[..cur_lo.col.to_usize()]); + let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize()); + buf.push_str(&cur_line[..end]); } } buf.push_str(&part.snippet); @@ -438,14 +432,14 @@ impl Handler { self.err_count.store(0, SeqCst); } - pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> { + pub fn struct_dummy(&self) -> DiagnosticBuilder<'_> { DiagnosticBuilder::new(self, Level::Cancelled, "") } - pub fn struct_span_warn<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); result.set_span(sp); if !self.flags.can_emit_warnings { @@ -453,11 +447,11 @@ impl Handler { } result } - pub fn struct_span_warn_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn_with_code>(&self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); result.set_span(sp); result.code(code); @@ -466,63 +460,63 @@ impl Handler { } result } - pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); if !self.flags.can_emit_warnings { result.cancel(); } result } - pub fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.set_span(sp); result } - pub fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err_with_code>(&self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.set_span(sp); result.code(code); result } // FIXME: This method should be removed (every error should have an associated error code). - pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> { DiagnosticBuilder::new(self, Level::Error, msg) } - pub fn struct_err_with_code<'a>( - &'a self, + pub fn struct_err_with_code( + &self, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.code(code); result } - pub fn struct_span_fatal<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg); result.set_span(sp); result } - pub fn struct_span_fatal_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal_with_code>(&self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg); result.set_span(sp); result.code(code); result } - pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { DiagnosticBuilder::new(self, Level::Fatal, msg) } @@ -563,10 +557,10 @@ impl Handler { pub fn span_err>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Error); } - pub fn mut_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn mut_span_err>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.set_span(sp); result @@ -605,10 +599,10 @@ impl Handler { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Note); } - pub fn span_note_diag<'a>(&'a self, - sp: Span, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn span_note_diag(&self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'_> { let mut db = DiagnosticBuilder::new(self, Note, msg); db.set_span(sp); db diff --git a/src/librustc_fs_util/Cargo.toml b/src/librustc_fs_util/Cargo.toml index 47918643f3..e74e380992 100644 --- a/src/librustc_fs_util/Cargo.toml +++ b/src/librustc_fs_util/Cargo.toml @@ -7,6 +7,5 @@ edition = "2018" [lib] name = "rustc_fs_util" path = "lib.rs" -crate-type = ["dylib"] [dependencies] diff --git a/src/librustc_fs_util/lib.rs b/src/librustc_fs_util/lib.rs index ce63bcafd7..eaf08d76b9 100644 --- a/src/librustc_fs_util/lib.rs +++ b/src/librustc_fs_util/lib.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use std::path::{Path, PathBuf}; use std::ffi::CString; use std::fs; diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml index df971ec5bd..a931ad3b66 100644 --- a/src/librustc_incremental/Cargo.toml +++ b/src/librustc_incremental/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [lib] name = "rustc_incremental" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] graphviz = { path = "../libgraphviz" } @@ -15,7 +15,7 @@ log = "0.4" rand = "0.6" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc_fs_util = { path = "../librustc_fs_util" } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index a43347a219..07d426af6e 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -51,7 +51,7 @@ use std::io::Write; use syntax::ast; use syntax_pos::Span; -pub fn assert_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.debugging_opts.dump_dep_graph { dump_graph(tcx); @@ -111,7 +111,7 @@ impl IfThisChanged<'tcx> { } fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = self.tcx.hir().local_def_id(hir_id); let def_path_hash = self.tcx.def_path_hash(def_id); for attr in attrs { if attr.check_name(ATTR_IF_THIS_CHANGED) { @@ -190,7 +190,7 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou for &(target_span, _, _, _) in then_this_would_need { tcx.sess.span_err( target_span, - "no #[rustc_if_this_changed] annotation detected"); + "no `#[rustc_if_this_changed]` annotation detected"); } return; diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index f502d04754..046fdc7227 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -35,7 +35,7 @@ const MODULE: Symbol = sym::module; const CFG: Symbol = sym::cfg; const KIND: Symbol = sym::kind; -pub fn assert_module_sources<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn assert_module_sources(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.incremental.is_none() { return; diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index ffea495d3e..b257311138 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -8,14 +8,7 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving - #[macro_use] extern crate log; mod assert_dep_graph; diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 5296ed0ffd..e569a9bc7d 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -206,7 +206,7 @@ impl Assertion { } } -pub fn check_dirty_clean_annotations<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { // can't add `#[rustc_dirty]` etc without opting in to this feature if !tcx.features().rustc_attrs { return; @@ -354,7 +354,7 @@ impl DirtyCleanVisitor<'tcx> { HirItem::GlobalAsm(..) => ("ItemGlobalAsm", LABELS_HIR_ONLY), // A type alias, e.g., `type Foo = Bar` - HirItem::Ty(..) => ("ItemTy", LABELS_HIR_ONLY), + HirItem::TyAlias(..) => ("ItemTy", LABELS_HIR_ONLY), // An enum definition, e.g., `enum Foo {C, D}` HirItem::Enum(..) => ("ItemEnum", LABELS_ADT), @@ -405,8 +405,8 @@ impl DirtyCleanVisitor<'tcx> { match item.node { ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL), ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), - ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), - ImplItemKind::Existential(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), + ImplItemKind::TyAlias(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), + ImplItemKind::OpaqueTy(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), } }, _ => self.tcx.sess.span_fatal( @@ -500,7 +500,7 @@ impl DirtyCleanVisitor<'tcx> { } fn check_item(&mut self, item_id: hir::HirId, item_span: Span) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item_id); + let def_id = self.tcx.hir().local_def_id(item_id); for attr in self.tcx.get_attrs(def_id).iter() { let assertion = match self.assertion_maybe(item_id, attr) { Some(a) => a, @@ -610,7 +610,7 @@ impl FindAllAttrs<'tcx> { for attr in &self.found_attrs { if !checked_attrs.contains(&attr.id) { self.tcx.sess.span_err(attr.span, &format!("found unchecked \ - #[rustc_dirty]/#[rustc_clean] attribute")); + `#[rustc_dirty]` / `#[rustc_clean]` attribute")); } } } diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index 7f697b5448..511175de5d 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -117,6 +117,9 @@ use std::time::{UNIX_EPOCH, SystemTime, Duration}; use rand::{RngCore, thread_rng}; +#[cfg(test)] +mod tests; + const LOCK_FILE_EXT: &str = ".lock"; const DEP_GRAPH_FILENAME: &str = "dep-graph.bin"; const WORK_PRODUCTS_FILENAME: &str = "work-products.bin"; @@ -538,7 +541,7 @@ fn find_source_directory_in_iter(iter: I, if source_directories_already_tried.contains(&session_dir) || !is_session_directory(&directory_name) || !is_finalized(&directory_name) { - debug!("find_source_directory_in_iter - ignoring."); + debug!("find_source_directory_in_iter - ignoring"); continue } @@ -693,7 +696,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { let timestamp = match extract_timestamp_from_session_dir(lock_file_name) { Ok(timestamp) => timestamp, Err(()) => { - debug!("Found lock-file with malformed timestamp: {}", + debug!("found lock-file with malformed timestamp: {}", crate_directory.join(&lock_file_name).display()); // Ignore it continue @@ -746,7 +749,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { let timestamp = match extract_timestamp_from_session_dir(directory_name) { Ok(timestamp) => timestamp, Err(()) => { - debug!("Found session-dir with malformed timestamp: {}", + debug!("found session-dir with malformed timestamp: {}", crate_directory.join(directory_name).display()); // Ignore it continue @@ -894,67 +897,3 @@ fn safe_remove_file(p: &Path) -> io::Result<()> { Ok(()) } } - -#[test] -fn test_all_except_most_recent() { - assert_eq!(all_except_most_recent( - vec![ - (UNIX_EPOCH + Duration::new(4, 0), PathBuf::from("4"), None), - (UNIX_EPOCH + Duration::new(1, 0), PathBuf::from("1"), None), - (UNIX_EPOCH + Duration::new(5, 0), PathBuf::from("5"), None), - (UNIX_EPOCH + Duration::new(3, 0), PathBuf::from("3"), None), - (UNIX_EPOCH + Duration::new(2, 0), PathBuf::from("2"), None), - ]).keys().cloned().collect::>(), - vec![ - PathBuf::from("1"), - PathBuf::from("2"), - PathBuf::from("3"), - PathBuf::from("4"), - ].into_iter().collect::>() - ); - - assert_eq!(all_except_most_recent( - vec![ - ]).keys().cloned().collect::>(), - FxHashSet::default() - ); -} - -#[test] -fn test_timestamp_serialization() { - for i in 0 .. 1_000u64 { - let time = UNIX_EPOCH + Duration::new(i * 1_434_578, (i as u32) * 239_000); - let s = timestamp_to_string(time); - assert_eq!(Ok(time), string_to_timestamp(&s)); - } -} - -#[test] -fn test_find_source_directory_in_iter() { - let already_visited = FxHashSet::default(); - - // Find newest - assert_eq!(find_source_directory_in_iter( - vec![PathBuf::from("crate-dir/s-3234-0000-svh"), - PathBuf::from("crate-dir/s-2234-0000-svh"), - PathBuf::from("crate-dir/s-1234-0000-svh")].into_iter(), &already_visited), - Some(PathBuf::from("crate-dir/s-3234-0000-svh"))); - - // Filter out "-working" - assert_eq!(find_source_directory_in_iter( - vec![PathBuf::from("crate-dir/s-3234-0000-working"), - PathBuf::from("crate-dir/s-2234-0000-svh"), - PathBuf::from("crate-dir/s-1234-0000-svh")].into_iter(), &already_visited), - Some(PathBuf::from("crate-dir/s-2234-0000-svh"))); - - // Handle empty - assert_eq!(find_source_directory_in_iter(vec![].into_iter(), &already_visited), - None); - - // Handle only working - assert_eq!(find_source_directory_in_iter( - vec![PathBuf::from("crate-dir/s-3234-0000-working"), - PathBuf::from("crate-dir/s-2234-0000-working"), - PathBuf::from("crate-dir/s-1234-0000-working")].into_iter(), &already_visited), - None); -} diff --git a/src/librustc_incremental/persist/fs/tests.rs b/src/librustc_incremental/persist/fs/tests.rs new file mode 100644 index 0000000000..09c2fc1463 --- /dev/null +++ b/src/librustc_incremental/persist/fs/tests.rs @@ -0,0 +1,65 @@ +use super::*; + +#[test] +fn test_all_except_most_recent() { + assert_eq!(all_except_most_recent( + vec![ + (UNIX_EPOCH + Duration::new(4, 0), PathBuf::from("4"), None), + (UNIX_EPOCH + Duration::new(1, 0), PathBuf::from("1"), None), + (UNIX_EPOCH + Duration::new(5, 0), PathBuf::from("5"), None), + (UNIX_EPOCH + Duration::new(3, 0), PathBuf::from("3"), None), + (UNIX_EPOCH + Duration::new(2, 0), PathBuf::from("2"), None), + ]).keys().cloned().collect::>(), + vec![ + PathBuf::from("1"), + PathBuf::from("2"), + PathBuf::from("3"), + PathBuf::from("4"), + ].into_iter().collect::>() + ); + + assert_eq!(all_except_most_recent( + vec![ + ]).keys().cloned().collect::>(), + FxHashSet::default() + ); +} + +#[test] +fn test_timestamp_serialization() { + for i in 0 .. 1_000u64 { + let time = UNIX_EPOCH + Duration::new(i * 1_434_578, (i as u32) * 239_000); + let s = timestamp_to_string(time); + assert_eq!(Ok(time), string_to_timestamp(&s)); + } +} + +#[test] +fn test_find_source_directory_in_iter() { + let already_visited = FxHashSet::default(); + + // Find newest + assert_eq!(find_source_directory_in_iter( + vec![PathBuf::from("crate-dir/s-3234-0000-svh"), + PathBuf::from("crate-dir/s-2234-0000-svh"), + PathBuf::from("crate-dir/s-1234-0000-svh")].into_iter(), &already_visited), + Some(PathBuf::from("crate-dir/s-3234-0000-svh"))); + + // Filter out "-working" + assert_eq!(find_source_directory_in_iter( + vec![PathBuf::from("crate-dir/s-3234-0000-working"), + PathBuf::from("crate-dir/s-2234-0000-svh"), + PathBuf::from("crate-dir/s-1234-0000-svh")].into_iter(), &already_visited), + Some(PathBuf::from("crate-dir/s-2234-0000-svh"))); + + // Handle empty + assert_eq!(find_source_directory_in_iter(vec![].into_iter(), &already_visited), + None); + + // Handle only working + assert_eq!(find_source_directory_in_iter( + vec![PathBuf::from("crate-dir/s-3234-0000-working"), + PathBuf::from("crate-dir/s-2234-0000-working"), + PathBuf::from("crate-dir/s-1234-0000-working")].into_iter(), &already_visited), + None); +} diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index d9bcc0b2a8..90aefb0f32 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -15,7 +15,7 @@ use super::fs::*; use super::file_format; use super::work_product; -pub fn dep_graph_tcx_init<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn dep_graph_tcx_init(tcx: TyCtxt<'_>) { if !tcx.dep_graph.is_fully_enabled() { return } @@ -192,7 +192,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { })) } -pub fn load_query_result_cache<'sess>(sess: &'sess Session) -> OnDiskCache<'sess> { +pub fn load_query_result_cache(sess: &Session) -> OnDiskCache<'_> { if sess.opts.incremental.is_none() || !sess.opts.debugging_opts.incremental_queries { return OnDiskCache::new_empty(sess.source_map()); diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 49c79ec09f..13e2c5d1c5 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -15,7 +15,7 @@ use super::dirty_clean; use super::file_format; use super::work_product; -pub fn save_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { let sess = tcx.sess; diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index bcaa421610..4937801d31 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -7,20 +7,18 @@ edition = "2018" [lib] name = "rustc_interface" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] log = "0.4" rayon = { version = "0.2.0", package = "rustc-rayon" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } -scoped-tls = "1.0" syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } rustc = { path = "../librustc" } -rustc_allocator = { path = "../librustc_allocator" } -rustc_borrowck = { path = "../librustc_borrowck" } +rustc_ast_borrowck = { path = "../librustc_ast_borrowck" } rustc_incremental = { path = "../librustc_incremental" } rustc_traits = { path = "../librustc_traits" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 674b2b60e4..fef60a47dc 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -12,7 +12,6 @@ use rustc_data_structures::OnDrop; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_metadata::cstore::CStore; -use std::io::Write; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index 7fc311d40c..2e593d4415 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -6,12 +6,6 @@ #![feature(generators)] #![cfg_attr(unix, feature(libc))] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - -#![allow(unused_imports)] - #![recursion_limit="256"] #[cfg(unix)] diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index c1b6e3409c..8b0b5a5b7a 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -2,56 +2,50 @@ use crate::interface::{Compiler, Result}; use crate::util; use crate::proc_macro_decls; -use log::{debug, info, warn, log_enabled}; +use log::{info, warn, log_enabled}; use rustc::dep_graph::DepGraph; use rustc::hir; use rustc::hir::lowering::lower_crate; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; -use rustc::middle::privacy::AccessLevels; +use rustc::middle::cstore::CrateStore; use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; use rustc::traits; use rustc::util::common::{time, ErrorReported}; -use rustc::util::profiling::ProfileCategory; -use rustc::session::{CompileResult, CrateDisambiguator, Session}; +use rustc::session::Session; use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType}; use rustc::session::search_paths::PathKind; -use rustc_allocator as allocator; -use rustc_borrowck as borrowck; +use rustc_ast_borrowck as borrowck; use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter}; use rustc_incremental; -use rustc_incremental::DepGraphFuture; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; use rustc_mir as mir; -use rustc_passes::{self, ast_validation, hir_stats, loops, rvalue_promotion, layout_test}; +use rustc_passes::{self, ast_validation, hir_stats, layout_test}; use rustc_plugin as plugin; use rustc_plugin::registry::Registry; use rustc_privacy; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_traits; use rustc_typeck as typeck; -use syntax::{self, ast, attr, diagnostics, visit}; +use syntax::{self, ast, diagnostics, visit}; use syntax::early_buffered_lints::BufferedEarlyLint; use syntax::ext::base::{NamedSyntaxExtension, ExtCtxt}; use syntax::mut_visit::MutVisitor; use syntax::parse::{self, PResult}; use syntax::util::node_count::NodeCounter; -use syntax::util::lev_distance::find_best_match_for_name; use syntax::symbol::Symbol; use syntax::feature_gate::AttributeType; -use syntax_pos::{FileName, edition::Edition, hygiene}; +use syntax_pos::FileName; use syntax_ext; -use serialize::json; +use rustc_serialize::json; use tempfile::Builder as TempFileBuilder; use std::any::Any; @@ -60,12 +54,10 @@ use std::ffi::OsString; use std::fs; use std::io::{self, Write}; use std::iter; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::mpsc; use std::cell::RefCell; use std::rc::Rc; -use std::mem; -use std::ops::Generator; pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { sess.diagnostic() @@ -211,15 +203,16 @@ impl ExpansionResult { impl BoxedResolver { pub fn to_expansion_result( - mut resolver: Rc>>, + resolver: Rc>, ) -> ExpansionResult { - if let Some(resolver) = Rc::get_mut(&mut resolver) { - mem::replace(resolver, None).unwrap().into_inner().complete() - } else { - let resolver = &*resolver; - resolver.as_ref().unwrap().borrow_mut().access(|resolver| { - ExpansionResult::from_resolver_ref(resolver) - }) + match Rc::try_unwrap(resolver) { + Ok(resolver) => resolver.into_inner().complete(), + Err(resolver) => { + let resolver = &*resolver; + resolver.borrow_mut().access(|resolver| { + ExpansionResult::from_resolver_ref(resolver) + }) + } } } } @@ -277,7 +270,12 @@ pub fn register_plugins<'a>( krate = time(sess, "crate injection", || { let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| &**s); - syntax::std_inject::maybe_inject_crates_ref(krate, alt_std_name, sess.edition()) + let (krate, name) = + syntax_ext::standard_library_imports::inject(krate, alt_std_name, sess.edition()); + if let Some(name) = name { + sess.parse_sess.injected_crate_name.set(name); + } + krate }); let registrars = time(sess, "plugin loading", || { @@ -371,7 +369,10 @@ fn configure_and_expand_inner<'a>( crate_loader, &resolver_arenas, ); - syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts, sess.edition()); + syntax_ext::register_builtin_macros(&mut resolver, sess.edition()); + syntax_ext::plugin_macro_defs::inject( + &mut krate, &mut resolver, plugin_info.syntax_exts, sess.edition() + ); // Expand all macros sess.profiler(|p| p.start_activity("macro expansion")); @@ -452,7 +453,7 @@ fn configure_and_expand_inner<'a>( sess.profiler(|p| p.end_activity("macro expansion")); time(sess, "maybe building test harness", || { - syntax::test::modify_for_testing( + syntax_ext::test_harness::inject( &sess.parse_sess, &mut resolver, sess.opts.test, @@ -468,7 +469,7 @@ fn configure_and_expand_inner<'a>( util::ReplaceBodyWithLoop::new(sess).visit_crate(&mut krate); } - let (has_proc_macro_decls, has_global_allocator) = time(sess, "AST validation", || { + let has_proc_macro_decls = time(sess, "AST validation", || { ast_validation::check_crate(sess, &krate) }); @@ -481,7 +482,7 @@ fn configure_and_expand_inner<'a>( let num_crate_types = crate_types.len(); let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro); let is_test_crate = sess.opts.test; - syntax_ext::proc_macro_decls::modify( + syntax_ext::proc_macro_harness::inject( &sess.parse_sess, &mut resolver, krate, @@ -494,19 +495,6 @@ fn configure_and_expand_inner<'a>( }); } - if has_global_allocator { - // Expand global allocators, which are treated as an in-tree proc macro - time(sess, "creating allocators", || { - allocator::expand::modify( - &sess.parse_sess, - &mut resolver, - &mut krate, - crate_name.to_string(), - sess.diagnostic(), - ) - }); - } - // Done with macro expansion! if sess.opts.debugging_opts.input_stats { @@ -572,7 +560,7 @@ pub fn lower_to_hir( // Discard hygiene data, which isn't required after lowering to HIR. if !sess.opts.debugging_opts.keep_hygiene_data { - syntax::ext::hygiene::clear_markings(); + syntax::ext::hygiene::clear_syntax_context_map(); } Ok(hir_forest) @@ -657,7 +645,8 @@ fn escape_dep_filename(filename: &FileName) -> String { filename.to_string().replace(" ", "\\ ") } -fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { +fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { + let sess = &compiler.sess; // Write out dependency rules to the dep-info file if requested if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { return; @@ -667,13 +656,30 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa let result = (|| -> io::Result<()> { // Build a list of files used to compile the output and // write Makefile-compatible dependency rules - let files: Vec = sess.source_map() + let mut files: Vec = sess.source_map() .files() .iter() .filter(|fmap| fmap.is_real_file()) .filter(|fmap| !fmap.is_imported()) - .map(|fmap| escape_dep_filename(&fmap.name)) + .map(|fmap| escape_dep_filename(&fmap.unmapped_path.as_ref().unwrap_or(&fmap.name))) .collect(); + + if sess.binary_dep_depinfo() { + for cnum in compiler.cstore.crates_untracked() { + let metadata = compiler.cstore.crate_data_as_rc_any(cnum); + let metadata = metadata.downcast_ref::().unwrap(); + if let Some((path, _)) = &metadata.source.dylib { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + if let Some((path, _)) = &metadata.source.rlib { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + if let Some((path, _)) = &metadata.source.rmeta { + files.push(escape_dep_filename(&FileName::Real(path.clone()))); + } + } + } + let mut file = fs::File::create(&deps_filename)?; for path in out_filenames { writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; @@ -688,12 +694,20 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa Ok(()) })(); - if let Err(e) = result { - sess.fatal(&format!( - "error writing dependencies to `{}`: {}", - deps_filename.display(), - e - )); + match result { + Ok(_) => { + if sess.opts.json_artifact_notifications { + sess.parse_sess.span_diagnostic + .emit_artifact_notification(&deps_filename, "dep-info"); + } + }, + Err(e) => { + sess.fatal(&format!( + "error writing dependencies to `{}`: {}", + deps_filename.display(), + e + )) + } } } @@ -742,7 +756,7 @@ pub fn prepare_outputs( } } - write_out_deps(sess, &outputs, &output_paths); + write_out_deps(compiler, &outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1; @@ -878,7 +892,7 @@ pub fn create_global_ctxt( /// Runs the resolution, type-checking, region checking and other /// miscellaneous analysis passes on the crate. -fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { +fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { assert_eq!(cnum, LOCAL_CRATE); let sess = tcx.sess; @@ -899,9 +913,10 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { }); }, { par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().check_mod_loops(tcx.hir().local_def_id(module)); - tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module)); - tcx.ensure().check_mod_unstable_api_usage(tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_loops(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().check_mod_attrs(tcx.hir().local_def_id_from_node_id(module)); + tcx.ensure().check_mod_unstable_api_usage( + tcx.hir().local_def_id_from_node_id(module)); }); }); }); @@ -924,9 +939,9 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { // "not all control paths return a value" is reported here. // // maybe move the check to a MIR pass? - tcx.ensure().check_mod_liveness(tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_liveness(tcx.hir().local_def_id_from_node_id(module)); - tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id_from_node_id(module)); }); }); }); @@ -986,7 +1001,7 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { }, { time(sess, "privacy checking modules", || { par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_privacy(tcx.hir().local_def_id_from_node_id(module)); }); }); }); @@ -995,8 +1010,8 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { Ok(()) } -fn encode_and_write_metadata<'tcx>( - tcx: TyCtxt<'tcx>, +fn encode_and_write_metadata( + tcx: TyCtxt<'_>, outputs: &OutputFilenames, ) -> (middle::cstore::EncodedMetadata, bool) { #[derive(PartialEq, Eq, PartialOrd, Ord)] @@ -1044,7 +1059,7 @@ fn encode_and_write_metadata<'tcx>( if let Err(e) = fs::rename(&metadata_filename, &out_filename) { tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)); } - if tcx.sess.opts.debugging_opts.emit_artifact_notifications { + if tcx.sess.opts.json_artifact_notifications { tcx.sess.parse_sess.span_diagnostic .emit_artifact_notification(&out_filename, "metadata"); } diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs index 9e1ef6b022..56180bcad0 100644 --- a/src/librustc_interface/proc_macro_decls.rs +++ b/src/librustc_interface/proc_macro_decls.rs @@ -6,17 +6,17 @@ use rustc::ty::query::Providers; use syntax::attr; use syntax::symbol::sym; -pub fn find<'tcx>(tcx: TyCtxt<'tcx>) -> Option { +pub fn find(tcx: TyCtxt<'_>) -> Option { tcx.proc_macro_decls_static(LOCAL_CRATE) } -fn proc_macro_decls_static<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option { +fn proc_macro_decls_static(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option { assert_eq!(cnum, LOCAL_CRATE); let mut finder = Finder { decls: None }; tcx.hir().krate().visit_all_item_likes(&mut finder); - finder.decls.map(|id| tcx.hir().local_def_id_from_hir_id(id)) + finder.decls.map(|id| tcx.hir().local_def_id(id)) } struct Finder { diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 570509ffb2..ed50dadb60 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,30 +2,18 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; -use rustc_data_structures::sync::Lrc; -use rustc::session::config::{Input, OutputFilenames, OutputType}; -use rustc::session::Session; +use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; -use rustc::util::profiling::ProfileCategory; -use rustc::lint; use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; -use rustc::ty; use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; -use rustc_passes::hir_stats; -use rustc_plugin::registry::Registry; -use serialize::json; use std::cell::{Ref, RefMut, RefCell}; -use std::ops::Deref; use std::rc::Rc; use std::sync::mpsc; use std::any::Any; use std::mem; -use syntax::parse::{self, PResult}; -use syntax::util::node_count::NodeCounter; -use syntax::{self, ast, attr, diagnostics, visit}; -use syntax_pos::hygiene; +use syntax::{self, ast}; /// Represent the result of a query. /// This result can be stolen with the `take` method and returned with the `give` method. @@ -88,7 +76,7 @@ pub(crate) struct Queries { parse: Query, crate_name: Query, register_plugins: Query<(ast::Crate, PluginInfo)>, - expansion: Query<(ast::Crate, Rc>>)>, + expansion: Query<(ast::Crate, Steal>>)>, dep_graph: Query, lower_to_hir: Query<(Steal, ExpansionResult)>, prepare_outputs: Query, @@ -154,7 +142,7 @@ impl Compiler { pub fn expansion( &self - ) -> Result<&Query<(ast::Crate, Rc>>)>> { + ) -> Result<&Query<(ast::Crate, Steal>>)>> { self.queries.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let (krate, plugin_info) = self.register_plugins()?.take(); @@ -164,7 +152,7 @@ impl Compiler { krate, &crate_name, plugin_info, - ).map(|(krate, resolver)| (krate, Rc::new(Some(RefCell::new(resolver))))) + ).map(|(krate, resolver)| (krate, Steal::new(Rc::new(RefCell::new(resolver))))) }) } @@ -188,9 +176,10 @@ impl Compiler { pub fn lower_to_hir(&self) -> Result<&Query<(Steal, ExpansionResult)>> { self.queries.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; - let (krate, resolver) = expansion_result.take(); - let resolver_ref = &*resolver; - let hir = Steal::new(resolver_ref.as_ref().unwrap().borrow_mut().access(|resolver| { + let peeked = expansion_result.peek(); + let krate = &peeked.0; + let resolver = peeked.1.steal(); + let hir = Steal::new(resolver.borrow_mut().access(|resolver| { passes::lower_to_hir( self.session(), self.cstore(), @@ -199,7 +188,6 @@ impl Compiler { &krate ) })?); - expansion_result.give((krate, Rc::new(None))); Ok((hir, BoxedResolver::to_expansion_result(resolver))) }) } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index a86d3cc439..f007a0cf2a 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -203,8 +203,6 @@ pub fn spawn_thread_pool R + Send, R: Send>( f: F, ) -> R { use rayon::{ThreadPool, ThreadPoolBuilder}; - use syntax; - use syntax_pos; let gcx_ptr = &Lock::new(0); @@ -642,14 +640,14 @@ pub fn build_output_filenames( ); None } else { + if !sess.opts.cg.extra_filename.is_empty() { + sess.warn("ignoring -C extra-filename flag due to -o flag"); + } Some(out_file.clone()) }; if *odir != None { sess.warn("ignoring --out-dir flag due to -o flag"); } - if !sess.opts.cg.extra_filename.is_empty() { - sess.warn("ignoring -C extra-filename flag due to -o flag"); - } OutputFilenames { out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), diff --git a/src/librustc_lexer/Cargo.toml b/src/librustc_lexer/Cargo.toml new file mode 100644 index 0000000000..0dbcda618e --- /dev/null +++ b/src/librustc_lexer/Cargo.toml @@ -0,0 +1,15 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_lexer" +version = "0.1.0" +edition = "2018" + +# Note that this crate purposefully does not depend on other rustc crates +[dependencies] +unicode-xid = { version = "0.1.0", optional = true } + +# Note: do not remove this blank `[lib]` section. +# This will be used when publishing this crate as `rustc-ap-rustc_lexer`. +[lib] +doctest = false +name = "rustc_lexer" diff --git a/src/librustc_lexer/src/cursor.rs b/src/librustc_lexer/src/cursor.rs new file mode 100644 index 0000000000..5831159c34 --- /dev/null +++ b/src/librustc_lexer/src/cursor.rs @@ -0,0 +1,57 @@ +use std::str::Chars; + +pub(crate) struct Cursor<'a> { + initial_len: usize, + chars: Chars<'a>, + #[cfg(debug_assertions)] + prev: char, +} + +pub(crate) const EOF_CHAR: char = '\0'; + +impl<'a> Cursor<'a> { + pub(crate) fn new(input: &'a str) -> Cursor<'a> { + Cursor { + initial_len: input.len(), + chars: input.chars(), + #[cfg(debug_assertions)] + prev: EOF_CHAR, + } + } + /// For debug assertions only + pub(crate) fn prev(&self) -> char { + #[cfg(debug_assertions)] + { + self.prev + } + + #[cfg(not(debug_assertions))] + { + '\0' + } + } + pub(crate) fn nth_char(&self, n: usize) -> char { + self.chars().nth(n).unwrap_or(EOF_CHAR) + } + pub(crate) fn is_eof(&self) -> bool { + self.chars.as_str().is_empty() + } + pub(crate) fn len_consumed(&self) -> usize { + self.initial_len - self.chars.as_str().len() + } + /// Returns an iterator over the remaining characters. + fn chars(&self) -> Chars<'a> { + self.chars.clone() + } + /// Moves to the next character. + pub(crate) fn bump(&mut self) -> Option { + let c = self.chars.next()?; + + #[cfg(debug_assertions)] + { + self.prev = c; + } + + Some(c) + } +} diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs new file mode 100644 index 0000000000..c02abe6b89 --- /dev/null +++ b/src/librustc_lexer/src/lib.rs @@ -0,0 +1,710 @@ +// We want to be able to build this crate with a stable compiler, so feature +// flags should be optional. +#![cfg_attr(not(feature = "unicode-xid"), feature(unicode_internals))] + +mod cursor; +pub mod unescape; + +use crate::cursor::{Cursor, EOF_CHAR}; + +pub struct Token { + pub kind: TokenKind, + pub len: usize, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum TokenKind { + LineComment, + BlockComment { terminated: bool }, + Whitespace, + Ident, + RawIdent, + Literal { kind: LiteralKind, suffix_start: usize }, + Lifetime { starts_with_number: bool }, + Semi, + Comma, + DotDotDot, + DotDotEq, + DotDot, + Dot, + OpenParen, + CloseParen, + OpenBrace, + CloseBrace, + OpenBracket, + CloseBracket, + At, + Pound, + Tilde, + Question, + ColonColon, + Colon, + Dollar, + EqEq, + Eq, + FatArrow, + Ne, + Not, + Le, + LArrow, + Lt, + ShlEq, + Shl, + Ge, + Gt, + ShrEq, + Shr, + RArrow, + Minus, + MinusEq, + And, + AndAnd, + AndEq, + Or, + OrOr, + OrEq, + PlusEq, + Plus, + StarEq, + Star, + SlashEq, + Slash, + CaretEq, + Caret, + PercentEq, + Percent, + Unknown, +} +use self::TokenKind::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum LiteralKind { + Int { base: Base, empty_int: bool }, + Float { base: Base, empty_exponent: bool }, + Char { terminated: bool }, + Byte { terminated: bool }, + Str { terminated: bool }, + ByteStr { terminated: bool }, + RawStr { n_hashes: usize, started: bool, terminated: bool }, + RawByteStr { n_hashes: usize, started: bool, terminated: bool }, +} +use self::LiteralKind::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Base { + Binary, + Octal, + Hexadecimal, + Decimal, +} + +impl Token { + fn new(kind: TokenKind, len: usize) -> Token { + Token { kind, len } + } +} + +pub fn strip_shebang(input: &str) -> Option { + debug_assert!(!input.is_empty()); + if !input.starts_with("#!") || input.starts_with("#![") { + return None; + } + Some(input.find('\n').unwrap_or(input.len())) +} + +pub fn first_token(input: &str) -> Token { + debug_assert!(!input.is_empty()); + Cursor::new(input).advance_token() +} + +pub fn tokenize(mut input: &str) -> impl Iterator + '_ { + std::iter::from_fn(move || { + if input.is_empty() { + return None; + } + let token = first_token(input); + input = &input[token.len..]; + Some(token) + }) +} + +impl Cursor<'_> { + fn advance_token(&mut self) -> Token { + let first_char = self.bump().unwrap(); + let token_kind = match first_char { + '/' => match self.nth_char(0) { + '/' => self.line_comment(), + '*' => self.block_comment(), + _ => { + if self.eat_assign() { + SlashEq + } else { + Slash + } + } + }, + c if character_properties::is_whitespace(c) => self.whitespace(), + 'r' => match (self.nth_char(0), self.nth_char(1)) { + ('#', c1) if character_properties::is_id_start(c1) => self.raw_ident(), + ('#', _) | ('"', _) => { + let (n_hashes, started, terminated) = self.raw_double_quoted_string(); + let suffix_start = self.len_consumed(); + if terminated { + self.eat_literal_suffix(); + } + let kind = RawStr { n_hashes, started, terminated }; + Literal { kind, suffix_start } + } + _ => self.ident(), + }, + 'b' => match (self.nth_char(0), self.nth_char(1)) { + ('\'', _) => { + self.bump(); + let terminated = self.single_quoted_string(); + let suffix_start = self.len_consumed(); + if terminated { + self.eat_literal_suffix(); + } + let kind = Byte { terminated }; + Literal { kind, suffix_start } + } + ('"', _) => { + self.bump(); + let terminated = self.double_quoted_string(); + let suffix_start = self.len_consumed(); + if terminated { + self.eat_literal_suffix(); + } + let kind = ByteStr { terminated }; + Literal { kind, suffix_start } + } + ('r', '"') | ('r', '#') => { + self.bump(); + let (n_hashes, started, terminated) = self.raw_double_quoted_string(); + let suffix_start = self.len_consumed(); + if terminated { + self.eat_literal_suffix(); + } + let kind = RawByteStr { n_hashes, started, terminated }; + Literal { kind, suffix_start } + } + _ => self.ident(), + }, + c if character_properties::is_id_start(c) => self.ident(), + c @ '0'..='9' => { + let literal_kind = self.number(c); + let suffix_start = self.len_consumed(); + self.eat_literal_suffix(); + TokenKind::Literal { kind: literal_kind, suffix_start } + } + ';' => Semi, + ',' => Comma, + '.' => { + if self.nth_char(0) == '.' { + self.bump(); + if self.nth_char(0) == '.' { + self.bump(); + DotDotDot + } else if self.nth_char(0) == '=' { + self.bump(); + DotDotEq + } else { + DotDot + } + } else { + Dot + } + } + '(' => OpenParen, + ')' => CloseParen, + '{' => OpenBrace, + '}' => CloseBrace, + '[' => OpenBracket, + ']' => CloseBracket, + '@' => At, + '#' => Pound, + '~' => Tilde, + '?' => Question, + ':' => { + if self.nth_char(0) == ':' { + self.bump(); + ColonColon + } else { + Colon + } + } + '$' => Dollar, + '=' => { + if self.nth_char(0) == '=' { + self.bump(); + EqEq + } else if self.nth_char(0) == '>' { + self.bump(); + FatArrow + } else { + Eq + } + } + '!' => { + if self.nth_char(0) == '=' { + self.bump(); + Ne + } else { + Not + } + } + '<' => match self.nth_char(0) { + '=' => { + self.bump(); + Le + } + '<' => { + self.bump(); + if self.eat_assign() { ShlEq } else { Shl } + } + '-' => { + self.bump(); + LArrow + } + _ => Lt, + }, + '>' => match self.nth_char(0) { + '=' => { + self.bump(); + Ge + } + '>' => { + self.bump(); + if self.eat_assign() { ShrEq } else { Shr } + } + _ => Gt, + }, + '-' => { + if self.nth_char(0) == '>' { + self.bump(); + RArrow + } else { + if self.eat_assign() { MinusEq } else { Minus } + } + } + '&' => { + if self.nth_char(0) == '&' { + self.bump(); + AndAnd + } else { + if self.eat_assign() { AndEq } else { And } + } + } + '|' => { + if self.nth_char(0) == '|' { + self.bump(); + OrOr + } else { + if self.eat_assign() { OrEq } else { Or } + } + } + '+' => { + if self.eat_assign() { + PlusEq + } else { + Plus + } + } + '*' => { + if self.eat_assign() { + StarEq + } else { + Star + } + } + '^' => { + if self.eat_assign() { + CaretEq + } else { + Caret + } + } + '%' => { + if self.eat_assign() { + PercentEq + } else { + Percent + } + } + '\'' => self.lifetime_or_char(), + '"' => { + let terminated = self.double_quoted_string(); + let suffix_start = self.len_consumed(); + if terminated { + self.eat_literal_suffix(); + } + let kind = Str { terminated }; + Literal { kind, suffix_start } + } + _ => Unknown, + }; + Token::new(token_kind, self.len_consumed()) + } + + fn line_comment(&mut self) -> TokenKind { + debug_assert!(self.prev() == '/' && self.nth_char(0) == '/'); + self.bump(); + loop { + match self.nth_char(0) { + '\n' => break, + '\r' if self.nth_char(1) == '\n' => break, + EOF_CHAR if self.is_eof() => break, + _ => { + self.bump(); + } + } + } + LineComment + } + + fn block_comment(&mut self) -> TokenKind { + debug_assert!(self.prev() == '/' && self.nth_char(0) == '*'); + self.bump(); + let mut depth = 1usize; + while let Some(c) = self.bump() { + match c { + '/' if self.nth_char(0) == '*' => { + self.bump(); + depth += 1; + } + '*' if self.nth_char(0) == '/' => { + self.bump(); + depth -= 1; + if depth == 0 { + break; + } + } + _ => (), + } + } + + BlockComment { terminated: depth == 0 } + } + + fn whitespace(&mut self) -> TokenKind { + debug_assert!(character_properties::is_whitespace(self.prev())); + while character_properties::is_whitespace(self.nth_char(0)) { + self.bump(); + } + Whitespace + } + + fn raw_ident(&mut self) -> TokenKind { + debug_assert!( + self.prev() == 'r' + && self.nth_char(0) == '#' + && character_properties::is_id_start(self.nth_char(1)) + ); + self.bump(); + self.bump(); + while character_properties::is_id_continue(self.nth_char(0)) { + self.bump(); + } + RawIdent + } + + fn ident(&mut self) -> TokenKind { + debug_assert!(character_properties::is_id_start(self.prev())); + while character_properties::is_id_continue(self.nth_char(0)) { + self.bump(); + } + Ident + } + + fn number(&mut self, first_digit: char) -> LiteralKind { + debug_assert!('0' <= self.prev() && self.prev() <= '9'); + let mut base = Base::Decimal; + if first_digit == '0' { + let has_digits = match self.nth_char(0) { + 'b' => { + base = Base::Binary; + self.bump(); + self.eat_decimal_digits() + } + 'o' => { + base = Base::Octal; + self.bump(); + self.eat_decimal_digits() + } + 'x' => { + base = Base::Hexadecimal; + self.bump(); + self.eat_hexadecimal_digits() + } + '0'..='9' | '_' | '.' | 'e' | 'E' => { + self.eat_decimal_digits(); + true + } + // just a 0 + _ => return Int { base, empty_int: false }, + }; + if !has_digits { + return Int { base, empty_int: true }; + } + } else { + self.eat_decimal_digits(); + }; + + match self.nth_char(0) { + // Don't be greedy if this is actually an + // integer literal followed by field/method access or a range pattern + // (`0..2` and `12.foo()`) + '.' if self.nth_char(1) != '.' + && !character_properties::is_id_start(self.nth_char(1)) => + { + // might have stuff after the ., and if it does, it needs to start + // with a number + self.bump(); + let mut empty_exponent = false; + if self.nth_char(0).is_digit(10) { + self.eat_decimal_digits(); + match self.nth_char(0) { + 'e' | 'E' => { + self.bump(); + empty_exponent = self.float_exponent().is_err() + } + _ => (), + } + } + Float { base, empty_exponent } + } + 'e' | 'E' => { + self.bump(); + let empty_exponent = self.float_exponent().is_err(); + Float { base, empty_exponent } + } + _ => Int { base, empty_int: false }, + } + } + + fn lifetime_or_char(&mut self) -> TokenKind { + debug_assert!(self.prev() == '\''); + let mut starts_with_number = false; + if (character_properties::is_id_start(self.nth_char(0)) + || self.nth_char(0).is_digit(10) && { + starts_with_number = true; + true + }) + && self.nth_char(1) != '\'' + { + self.bump(); + while character_properties::is_id_continue(self.nth_char(0)) { + self.bump(); + } + + return if self.nth_char(0) == '\'' { + self.bump(); + let kind = Char { terminated: true }; + Literal { kind, suffix_start: self.len_consumed() } + } else { + Lifetime { starts_with_number } + }; + } + let terminated = self.single_quoted_string(); + let suffix_start = self.len_consumed(); + if terminated { + self.eat_literal_suffix(); + } + let kind = Char { terminated }; + return Literal { kind, suffix_start }; + } + + fn single_quoted_string(&mut self) -> bool { + debug_assert!(self.prev() == '\''); + // parse `'''` as a single char literal + if self.nth_char(0) == '\'' && self.nth_char(1) == '\'' { + self.bump(); + } + let mut first = true; + loop { + match self.nth_char(0) { + '/' if !first => break, + '\n' if self.nth_char(1) != '\'' => break, + '\r' if self.nth_char(1) == '\n' => break, + EOF_CHAR if self.is_eof() => break, + '\'' => { + self.bump(); + return true; + } + '\\' => { + self.bump(); + self.bump(); + } + _ => { + self.bump(); + } + } + first = false; + } + false + } + + fn double_quoted_string(&mut self) -> bool { + debug_assert!(self.prev() == '"'); + loop { + match self.nth_char(0) { + '"' => { + self.bump(); + return true; + } + EOF_CHAR if self.is_eof() => return false, + '\\' if self.nth_char(1) == '\\' || self.nth_char(1) == '"' => { + self.bump(); + } + _ => (), + } + self.bump(); + } + } + + fn raw_double_quoted_string(&mut self) -> (usize, bool, bool) { + debug_assert!(self.prev() == 'r'); + let n_hashes = { + let mut acc: usize = 0; + loop { + match self.bump() { + Some('#') => acc += 1, + Some('"') => break acc, + None | Some(_) => return (acc, false, false), + } + } + }; + + loop { + match self.bump() { + Some('"') => { + let mut acc = n_hashes; + while self.nth_char(0) == '#' && acc > 0 { + self.bump(); + acc -= 1; + } + if acc == 0 { + return (n_hashes, true, true); + } + } + Some(_) => (), + None => return (n_hashes, true, false), + } + } + } + + fn eat_decimal_digits(&mut self) -> bool { + let mut has_digits = false; + loop { + match self.nth_char(0) { + '_' => { + self.bump(); + } + '0'..='9' => { + has_digits = true; + self.bump(); + } + _ => break, + } + } + has_digits + } + + fn eat_hexadecimal_digits(&mut self) -> bool { + let mut has_digits = false; + loop { + match self.nth_char(0) { + '_' => { + self.bump(); + } + '0'..='9' | 'a'..='f' | 'A'..='F' => { + has_digits = true; + self.bump(); + } + _ => break, + } + } + has_digits + } + + fn float_exponent(&mut self) -> Result<(), ()> { + debug_assert!(self.prev() == 'e' || self.prev() == 'E'); + if self.nth_char(0) == '-' || self.nth_char(0) == '+' { + self.bump(); + } + if self.eat_decimal_digits() { Ok(()) } else { Err(()) } + } + + fn eat_literal_suffix(&mut self) { + if !character_properties::is_id_start(self.nth_char(0)) { + return; + } + self.bump(); + + while character_properties::is_id_continue(self.nth_char(0)) { + self.bump(); + } + } + + fn eat_assign(&mut self) -> bool { + if self.nth_char(0) == '=' { + self.bump(); + true + } else { + false + } + } +} + +pub mod character_properties { + // this is Pattern_White_Space + #[cfg(feature = "unicode-xid")] + pub fn is_whitespace(c: char) -> bool { + match c { + '\u{0009}' | '\u{000A}' | '\u{000B}' | '\u{000C}' | '\u{000D}' | '\u{0020}' + | '\u{0085}' | '\u{200E}' | '\u{200F}' | '\u{2028}' | '\u{2029}' => true, + _ => false, + } + } + + #[cfg(not(feature = "unicode-xid"))] + pub fn is_whitespace(c: char) -> bool { + core::unicode::property::Pattern_White_Space(c) + } + + // this is XID_Start OR '_' (which formally is not a XID_Start) + #[cfg(feature = "unicode-xid")] + pub fn is_id_start(c: char) -> bool { + ('a' <= c && c <= 'z') + || ('A' <= c && c <= 'Z') + || c == '_' + || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c)) + } + + #[cfg(not(feature = "unicode-xid"))] + pub fn is_id_start(c: char) -> bool { + ('a' <= c && c <= 'z') + || ('A' <= c && c <= 'Z') + || c == '_' + || (c > '\x7f' && c.is_xid_start()) + } + + // this is XID_Continue + #[cfg(feature = "unicode-xid")] + pub fn is_id_continue(c: char) -> bool { + ('a' <= c && c <= 'z') + || ('A' <= c && c <= 'Z') + || ('0' <= c && c <= '9') + || c == '_' + || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c)) + } + + #[cfg(not(feature = "unicode-xid"))] + pub fn is_id_continue(c: char) -> bool { + ('a' <= c && c <= 'z') + || ('A' <= c && c <= 'Z') + || ('0' <= c && c <= '9') + || c == '_' + || (c > '\x7f' && c.is_xid_continue()) + } +} diff --git a/src/librustc_lexer/src/unescape.rs b/src/librustc_lexer/src/unescape.rs new file mode 100644 index 0000000000..d8e00d4c7c --- /dev/null +++ b/src/librustc_lexer/src/unescape.rs @@ -0,0 +1,325 @@ +//! Utilities for validating string and char literals and turning them into +//! values they represent. + +use std::str::Chars; +use std::ops::Range; + +#[cfg(test)] +mod tests; + +#[derive(Debug, PartialEq, Eq)] +pub enum EscapeError { + ZeroChars, + MoreThanOneChar, + + LoneSlash, + InvalidEscape, + BareCarriageReturn, + BareCarriageReturnInRawString, + EscapeOnlyChar, + + TooShortHexEscape, + InvalidCharInHexEscape, + OutOfRangeHexEscape, + + NoBraceInUnicodeEscape, + InvalidCharInUnicodeEscape, + EmptyUnicodeEscape, + UnclosedUnicodeEscape, + LeadingUnderscoreUnicodeEscape, + OverlongUnicodeEscape, + LoneSurrogateUnicodeEscape, + OutOfRangeUnicodeEscape, + + UnicodeEscapeInByte, + NonAsciiCharInByte, + NonAsciiCharInByteString, +} + +/// Takes a contents of a char literal (without quotes), and returns an +/// unescaped char or an error +pub fn unescape_char(literal_text: &str) -> Result { + let mut chars = literal_text.chars(); + unescape_char_or_byte(&mut chars, Mode::Char) + .map_err(|err| (literal_text.len() - chars.as_str().len(), err)) +} + +/// Takes a contents of a string literal (without quotes) and produces a +/// sequence of escaped characters or errors. +pub fn unescape_str(literal_text: &str, callback: &mut F) +where + F: FnMut(Range, Result), +{ + unescape_str_or_byte_str(literal_text, Mode::Str, callback) +} + +pub fn unescape_byte(literal_text: &str) -> Result { + let mut chars = literal_text.chars(); + unescape_char_or_byte(&mut chars, Mode::Byte) + .map(byte_from_char) + .map_err(|err| (literal_text.len() - chars.as_str().len(), err)) +} + +/// Takes a contents of a string literal (without quotes) and produces a +/// sequence of escaped characters or errors. +pub fn unescape_byte_str(literal_text: &str, callback: &mut F) +where + F: FnMut(Range, Result), +{ + unescape_str_or_byte_str(literal_text, Mode::ByteStr, &mut |range, char| { + callback(range, char.map(byte_from_char)) + }) +} + +/// Takes a contents of a string literal (without quotes) and produces a +/// sequence of characters or errors. +/// NOTE: Raw strings do not perform any explicit character escaping, here we +/// only translate CRLF to LF and produce errors on bare CR. +pub fn unescape_raw_str(literal_text: &str, callback: &mut F) +where + F: FnMut(Range, Result), +{ + unescape_raw_str_or_byte_str(literal_text, Mode::Str, callback) +} + +/// Takes a contents of a string literal (without quotes) and produces a +/// sequence of characters or errors. +/// NOTE: Raw strings do not perform any explicit character escaping, here we +/// only translate CRLF to LF and produce errors on bare CR. +pub fn unescape_raw_byte_str(literal_text: &str, callback: &mut F) +where + F: FnMut(Range, Result), +{ + unescape_raw_str_or_byte_str(literal_text, Mode::ByteStr, &mut |range, char| { + callback(range, char.map(byte_from_char)) + }) +} + +#[derive(Debug, Clone, Copy)] +pub enum Mode { + Char, + Str, + Byte, + ByteStr, +} + +impl Mode { + pub fn in_single_quotes(self) -> bool { + match self { + Mode::Char | Mode::Byte => true, + Mode::Str | Mode::ByteStr => false, + } + } + + pub fn in_double_quotes(self) -> bool { + !self.in_single_quotes() + } + + pub fn is_bytes(self) -> bool { + match self { + Mode::Byte | Mode::ByteStr => true, + Mode::Char | Mode::Str => false, + } + } +} + + +fn scan_escape(first_char: char, chars: &mut Chars<'_>, mode: Mode) -> Result { + if first_char != '\\' { + return match first_char { + '\t' | '\n' => Err(EscapeError::EscapeOnlyChar), + '\r' => Err(if chars.clone().next() == Some('\n') { + EscapeError::EscapeOnlyChar + } else { + EscapeError::BareCarriageReturn + }), + '\'' if mode.in_single_quotes() => Err(EscapeError::EscapeOnlyChar), + '"' if mode.in_double_quotes() => Err(EscapeError::EscapeOnlyChar), + _ => { + if mode.is_bytes() && !first_char.is_ascii() { + return Err(EscapeError::NonAsciiCharInByte); + } + Ok(first_char) + } + }; + } + + let second_char = chars.next().ok_or(EscapeError::LoneSlash)?; + + let res = match second_char { + '"' => '"', + 'n' => '\n', + 'r' => '\r', + 't' => '\t', + '\\' => '\\', + '\'' => '\'', + '0' => '\0', + + 'x' => { + let hi = chars.next().ok_or(EscapeError::TooShortHexEscape)?; + let hi = hi.to_digit(16).ok_or(EscapeError::InvalidCharInHexEscape)?; + + let lo = chars.next().ok_or(EscapeError::TooShortHexEscape)?; + let lo = lo.to_digit(16).ok_or(EscapeError::InvalidCharInHexEscape)?; + + let value = hi * 16 + lo; + + if !mode.is_bytes() && !is_ascii(value) { + return Err(EscapeError::OutOfRangeHexEscape); + } + let value = value as u8; + + value as char + } + + 'u' => { + if chars.next() != Some('{') { + return Err(EscapeError::NoBraceInUnicodeEscape); + } + + let mut n_digits = 1; + let mut value: u32 = match chars.next().ok_or(EscapeError::UnclosedUnicodeEscape)? { + '_' => return Err(EscapeError::LeadingUnderscoreUnicodeEscape), + '}' => return Err(EscapeError::EmptyUnicodeEscape), + c => c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?, + }; + + loop { + match chars.next() { + None => return Err(EscapeError::UnclosedUnicodeEscape), + Some('_') => continue, + Some('}') => { + if n_digits > 6 { + return Err(EscapeError::OverlongUnicodeEscape); + } + if mode.is_bytes() { + return Err(EscapeError::UnicodeEscapeInByte); + } + + break std::char::from_u32(value).ok_or_else(|| { + if value > 0x10FFFF { + EscapeError::OutOfRangeUnicodeEscape + } else { + EscapeError::LoneSurrogateUnicodeEscape + } + })?; + } + Some(c) => { + let digit = c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?; + n_digits += 1; + if n_digits > 6 { + continue; + } + let digit = digit as u32; + value = value * 16 + digit; + } + }; + } + } + _ => return Err(EscapeError::InvalidEscape), + }; + Ok(res) +} + +fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result { + let first_char = chars.next().ok_or(EscapeError::ZeroChars)?; + let res = scan_escape(first_char, chars, mode)?; + if chars.next().is_some() { + return Err(EscapeError::MoreThanOneChar); + } + Ok(res) +} + +/// Takes a contents of a string literal (without quotes) and produces a +/// sequence of escaped characters or errors. +fn unescape_str_or_byte_str(src: &str, mode: Mode, callback: &mut F) +where + F: FnMut(Range, Result), +{ + assert!(mode.in_double_quotes()); + let initial_len = src.len(); + let mut chars = src.chars(); + while let Some(first_char) = chars.next() { + let start = initial_len - chars.as_str().len() - first_char.len_utf8(); + + let unescaped_char = match first_char { + '\\' => { + let (second_char, third_char) = { + let mut chars = chars.clone(); + (chars.next(), chars.next()) + }; + match (second_char, third_char) { + (Some('\n'), _) | (Some('\r'), Some('\n')) => { + skip_ascii_whitespace(&mut chars); + continue; + } + _ => scan_escape(first_char, &mut chars, mode), + } + } + '\r' => { + let second_char = chars.clone().next(); + if second_char == Some('\n') { + chars.next(); + Ok('\n') + } else { + scan_escape(first_char, &mut chars, mode) + } + } + '\n' => Ok('\n'), + '\t' => Ok('\t'), + _ => scan_escape(first_char, &mut chars, mode), + }; + let end = initial_len - chars.as_str().len(); + callback(start..end, unescaped_char); + } + + fn skip_ascii_whitespace(chars: &mut Chars<'_>) { + let str = chars.as_str(); + let first_non_space = str + .bytes() + .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') + .unwrap_or(str.len()); + *chars = str[first_non_space..].chars() + } +} + +/// Takes a contents of a string literal (without quotes) and produces a +/// sequence of characters or errors. +/// NOTE: Raw strings do not perform any explicit character escaping, here we +/// only translate CRLF to LF and produce errors on bare CR. +fn unescape_raw_str_or_byte_str(literal_text: &str, mode: Mode, callback: &mut F) +where + F: FnMut(Range, Result), +{ + assert!(mode.in_double_quotes()); + let initial_len = literal_text.len(); + + let mut chars = literal_text.chars(); + while let Some(curr) = chars.next() { + let start = initial_len - chars.as_str().len() - curr.len_utf8(); + + let result = match (curr, chars.clone().next()) { + ('\r', Some('\n')) => { + chars.next(); + Ok('\n') + }, + ('\r', _) => Err(EscapeError::BareCarriageReturnInRawString), + (c, _) if mode.is_bytes() && !c.is_ascii() => + Err(EscapeError::NonAsciiCharInByteString), + (c, _) => Ok(c), + }; + let end = initial_len - chars.as_str().len(); + + callback(start..end, result); + } +} + +fn byte_from_char(c: char) -> u8 { + let res = c as u32; + assert!(res <= u8::max_value() as u32, "guaranteed because of Mode::Byte(Str)"); + res as u8 +} + +fn is_ascii(x: u32) -> bool { + x <= 0x7F +} diff --git a/src/librustc_lexer/src/unescape/tests.rs b/src/librustc_lexer/src/unescape/tests.rs new file mode 100644 index 0000000000..496527eb26 --- /dev/null +++ b/src/librustc_lexer/src/unescape/tests.rs @@ -0,0 +1,276 @@ +use super::*; + +#[test] +fn test_unescape_char_bad() { + fn check(literal_text: &str, expected_error: EscapeError) { + let actual_result = unescape_char(literal_text).map_err(|(_offset, err)| err); + assert_eq!(actual_result, Err(expected_error)); + } + + check("", EscapeError::ZeroChars); + check(r"\", EscapeError::LoneSlash); + + check("\n", EscapeError::EscapeOnlyChar); + check("\r\n", EscapeError::EscapeOnlyChar); + check("\t", EscapeError::EscapeOnlyChar); + check("'", EscapeError::EscapeOnlyChar); + check("\r", EscapeError::BareCarriageReturn); + + check("spam", EscapeError::MoreThanOneChar); + check(r"\x0ff", EscapeError::MoreThanOneChar); + check(r#"\"a"#, EscapeError::MoreThanOneChar); + check(r"\na", EscapeError::MoreThanOneChar); + check(r"\ra", EscapeError::MoreThanOneChar); + check(r"\ta", EscapeError::MoreThanOneChar); + check(r"\\a", EscapeError::MoreThanOneChar); + check(r"\'a", EscapeError::MoreThanOneChar); + check(r"\0a", EscapeError::MoreThanOneChar); + check(r"\u{0}x", EscapeError::MoreThanOneChar); + check(r"\u{1F63b}}", EscapeError::MoreThanOneChar); + + check(r"\v", EscapeError::InvalidEscape); + check(r"\💩", EscapeError::InvalidEscape); + check(r"\●", EscapeError::InvalidEscape); + + check(r"\x", EscapeError::TooShortHexEscape); + check(r"\x0", EscapeError::TooShortHexEscape); + check(r"\xf", EscapeError::TooShortHexEscape); + check(r"\xa", EscapeError::TooShortHexEscape); + check(r"\xx", EscapeError::InvalidCharInHexEscape); + check(r"\xы", EscapeError::InvalidCharInHexEscape); + check(r"\x🦀", EscapeError::InvalidCharInHexEscape); + check(r"\xtt", EscapeError::InvalidCharInHexEscape); + check(r"\xff", EscapeError::OutOfRangeHexEscape); + check(r"\xFF", EscapeError::OutOfRangeHexEscape); + check(r"\x80", EscapeError::OutOfRangeHexEscape); + + check(r"\u", EscapeError::NoBraceInUnicodeEscape); + check(r"\u[0123]", EscapeError::NoBraceInUnicodeEscape); + check(r"\u{0x}", EscapeError::InvalidCharInUnicodeEscape); + check(r"\u{", EscapeError::UnclosedUnicodeEscape); + check(r"\u{0000", EscapeError::UnclosedUnicodeEscape); + check(r"\u{}", EscapeError::EmptyUnicodeEscape); + check(r"\u{_0000}", EscapeError::LeadingUnderscoreUnicodeEscape); + check(r"\u{0000000}", EscapeError::OverlongUnicodeEscape); + check(r"\u{FFFFFF}", EscapeError::OutOfRangeUnicodeEscape); + check(r"\u{ffffff}", EscapeError::OutOfRangeUnicodeEscape); + check(r"\u{ffffff}", EscapeError::OutOfRangeUnicodeEscape); + + check(r"\u{DC00}", EscapeError::LoneSurrogateUnicodeEscape); + check(r"\u{DDDD}", EscapeError::LoneSurrogateUnicodeEscape); + check(r"\u{DFFF}", EscapeError::LoneSurrogateUnicodeEscape); + + check(r"\u{D800}", EscapeError::LoneSurrogateUnicodeEscape); + check(r"\u{DAAA}", EscapeError::LoneSurrogateUnicodeEscape); + check(r"\u{DBFF}", EscapeError::LoneSurrogateUnicodeEscape); +} + +#[test] +fn test_unescape_char_good() { + fn check(literal_text: &str, expected_char: char) { + let actual_result = unescape_char(literal_text); + assert_eq!(actual_result, Ok(expected_char)); + } + + check("a", 'a'); + check("ы", 'ы'); + check("🦀", '🦀'); + + check(r#"\""#, '"'); + check(r"\n", '\n'); + check(r"\r", '\r'); + check(r"\t", '\t'); + check(r"\\", '\\'); + check(r"\'", '\''); + check(r"\0", '\0'); + + check(r"\x00", '\0'); + check(r"\x5a", 'Z'); + check(r"\x5A", 'Z'); + check(r"\x7f", 127 as char); + + check(r"\u{0}", '\0'); + check(r"\u{000000}", '\0'); + check(r"\u{41}", 'A'); + check(r"\u{0041}", 'A'); + check(r"\u{00_41}", 'A'); + check(r"\u{4__1__}", 'A'); + check(r"\u{1F63b}", '😻'); +} + +#[test] +fn test_unescape_str_good() { + fn check(literal_text: &str, expected: &str) { + let mut buf = Ok(String::with_capacity(literal_text.len())); + unescape_str(literal_text, &mut |range, c| { + if let Ok(b) = &mut buf { + match c { + Ok(c) => b.push(c), + Err(e) => buf = Err((range, e)), + } + } + }); + let buf = buf.as_ref().map(|it| it.as_ref()); + assert_eq!(buf, Ok(expected)) + } + + check("foo", "foo"); + check("", ""); + check(" \t\n\r\n", " \t\n\n"); + + check("hello \\\n world", "hello world"); + check("hello \\\r\n world", "hello world"); + check("thread's", "thread's") +} + +#[test] +fn test_unescape_byte_bad() { + fn check(literal_text: &str, expected_error: EscapeError) { + let actual_result = unescape_byte(literal_text).map_err(|(_offset, err)| err); + assert_eq!(actual_result, Err(expected_error)); + } + + check("", EscapeError::ZeroChars); + check(r"\", EscapeError::LoneSlash); + + check("\n", EscapeError::EscapeOnlyChar); + check("\r\n", EscapeError::EscapeOnlyChar); + check("\t", EscapeError::EscapeOnlyChar); + check("'", EscapeError::EscapeOnlyChar); + check("\r", EscapeError::BareCarriageReturn); + + check("spam", EscapeError::MoreThanOneChar); + check(r"\x0ff", EscapeError::MoreThanOneChar); + check(r#"\"a"#, EscapeError::MoreThanOneChar); + check(r"\na", EscapeError::MoreThanOneChar); + check(r"\ra", EscapeError::MoreThanOneChar); + check(r"\ta", EscapeError::MoreThanOneChar); + check(r"\\a", EscapeError::MoreThanOneChar); + check(r"\'a", EscapeError::MoreThanOneChar); + check(r"\0a", EscapeError::MoreThanOneChar); + + check(r"\v", EscapeError::InvalidEscape); + check(r"\💩", EscapeError::InvalidEscape); + check(r"\●", EscapeError::InvalidEscape); + + check(r"\x", EscapeError::TooShortHexEscape); + check(r"\x0", EscapeError::TooShortHexEscape); + check(r"\xa", EscapeError::TooShortHexEscape); + check(r"\xf", EscapeError::TooShortHexEscape); + check(r"\xx", EscapeError::InvalidCharInHexEscape); + check(r"\xы", EscapeError::InvalidCharInHexEscape); + check(r"\x🦀", EscapeError::InvalidCharInHexEscape); + check(r"\xtt", EscapeError::InvalidCharInHexEscape); + + check(r"\u", EscapeError::NoBraceInUnicodeEscape); + check(r"\u[0123]", EscapeError::NoBraceInUnicodeEscape); + check(r"\u{0x}", EscapeError::InvalidCharInUnicodeEscape); + check(r"\u{", EscapeError::UnclosedUnicodeEscape); + check(r"\u{0000", EscapeError::UnclosedUnicodeEscape); + check(r"\u{}", EscapeError::EmptyUnicodeEscape); + check(r"\u{_0000}", EscapeError::LeadingUnderscoreUnicodeEscape); + check(r"\u{0000000}", EscapeError::OverlongUnicodeEscape); + + check("ы", EscapeError::NonAsciiCharInByte); + check("🦀", EscapeError::NonAsciiCharInByte); + + check(r"\u{0}", EscapeError::UnicodeEscapeInByte); + check(r"\u{000000}", EscapeError::UnicodeEscapeInByte); + check(r"\u{41}", EscapeError::UnicodeEscapeInByte); + check(r"\u{0041}", EscapeError::UnicodeEscapeInByte); + check(r"\u{00_41}", EscapeError::UnicodeEscapeInByte); + check(r"\u{4__1__}", EscapeError::UnicodeEscapeInByte); + check(r"\u{1F63b}", EscapeError::UnicodeEscapeInByte); + check(r"\u{0}x", EscapeError::UnicodeEscapeInByte); + check(r"\u{1F63b}}", EscapeError::UnicodeEscapeInByte); + check(r"\u{FFFFFF}", EscapeError::UnicodeEscapeInByte); + check(r"\u{ffffff}", EscapeError::UnicodeEscapeInByte); + check(r"\u{ffffff}", EscapeError::UnicodeEscapeInByte); + check(r"\u{DC00}", EscapeError::UnicodeEscapeInByte); + check(r"\u{DDDD}", EscapeError::UnicodeEscapeInByte); + check(r"\u{DFFF}", EscapeError::UnicodeEscapeInByte); + check(r"\u{D800}", EscapeError::UnicodeEscapeInByte); + check(r"\u{DAAA}", EscapeError::UnicodeEscapeInByte); + check(r"\u{DBFF}", EscapeError::UnicodeEscapeInByte); +} + +#[test] +fn test_unescape_byte_good() { + fn check(literal_text: &str, expected_byte: u8) { + let actual_result = unescape_byte(literal_text); + assert_eq!(actual_result, Ok(expected_byte)); + } + + check("a", b'a'); + + check(r#"\""#, b'"'); + check(r"\n", b'\n'); + check(r"\r", b'\r'); + check(r"\t", b'\t'); + check(r"\\", b'\\'); + check(r"\'", b'\''); + check(r"\0", b'\0'); + + check(r"\x00", b'\0'); + check(r"\x5a", b'Z'); + check(r"\x5A", b'Z'); + check(r"\x7f", 127); + check(r"\x80", 128); + check(r"\xff", 255); + check(r"\xFF", 255); +} + +#[test] +fn test_unescape_byte_str_good() { + fn check(literal_text: &str, expected: &[u8]) { + let mut buf = Ok(Vec::with_capacity(literal_text.len())); + unescape_byte_str(literal_text, &mut |range, c| { + if let Ok(b) = &mut buf { + match c { + Ok(c) => b.push(c), + Err(e) => buf = Err((range, e)), + } + } + }); + let buf = buf.as_ref().map(|it| it.as_ref()); + assert_eq!(buf, Ok(expected)) + } + + check("foo", b"foo"); + check("", b""); + check(" \t\n\r\n", b" \t\n\n"); + + check("hello \\\n world", b"hello world"); + check("hello \\\r\n world", b"hello world"); + check("thread's", b"thread's") +} + +#[test] +fn test_unescape_raw_str() { + fn check(literal: &str, expected: &[(Range, Result)]) { + let mut unescaped = Vec::with_capacity(literal.len()); + unescape_raw_str(literal, &mut |range, res| unescaped.push((range, res))); + assert_eq!(unescaped, expected); + } + + check("\r\n", &[(0..2, Ok('\n'))]); + check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]); + check("\rx", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString)), (1..2, Ok('x'))]); +} + +#[test] +fn test_unescape_raw_byte_str() { + fn check(literal: &str, expected: &[(Range, Result)]) { + let mut unescaped = Vec::with_capacity(literal.len()); + unescape_raw_byte_str(literal, &mut |range, res| unescaped.push((range, res))); + assert_eq!(unescaped, expected); + } + + check("\r\n", &[(0..2, Ok(byte_from_char('\n')))]); + check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]); + check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByteString))]); + check( + "🦀a", + &[(0..4, Err(EscapeError::NonAsciiCharInByteString)), (4..5, Ok(byte_from_char('a')))], + ); +} diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index fd2b635fae..041d0aaead 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [lib] name = "rustc_lint" path = "lib.rs" -crate-type = ["dylib"] [dependencies] log = "0.4" diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 12719c3b9d..bb2a5cab7d 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -21,9 +21,11 @@ //! If you define a new `LateLintPass`, you will also need to add it to the //! `late_lint_methods!` invocation in `lib.rs`. +use std::fmt::Write; + use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx}; use rustc::{lint, util}; use hir::Node; use util::nodemap::HirIdSet; @@ -33,13 +35,12 @@ use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext}; use rustc::util::nodemap::FxHashSet; use syntax::tokenstream::{TokenTree, TokenStream}; -use syntax::ast; +use syntax::ast::{self, Expr}; use syntax::ptr::P; -use syntax::ast::Expr; -use syntax::attr::{self, HasAttrs}; +use syntax::attr::{self, HasAttrs, AttributeTemplate}; use syntax::source_map::Spanned; use syntax::edition::Edition; -use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType}; +use syntax::feature_gate::{self, AttributeGate, AttributeType}; use syntax::feature_gate::{Stability, deprecated_attributes}; use syntax_pos::{BytePos, Span, SyntaxContext}; use syntax::symbol::{Symbol, kw, sym}; @@ -64,22 +65,30 @@ declare_lint! { declare_lint_pass!(WhileTrue => [WHILE_TRUE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { - if let hir::ExprKind::While(ref cond, ..) = e.node { - if let hir::ExprKind::Lit(ref lit) = cond.node { +/// Traverse through any amount of parenthesis and return the first non-parens expression. +fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr { + while let ast::ExprKind::Paren(sub) = &expr.node { + expr = sub; + } + expr +} + +impl EarlyLintPass for WhileTrue { + fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { + if let ast::ExprKind::While(cond, ..) = &e.node { + if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node { if let ast::LitKind::Bool(true) = lit.node { if lit.span.ctxt() == SyntaxContext::empty() { let msg = "denote infinite loops with `loop { ... }`"; - let condition_span = cx.tcx.sess.source_map().def_span(e.span); - let mut err = cx.struct_span_lint(WHILE_TRUE, condition_span, msg); - err.span_suggestion_short( - condition_span, - "use `loop`", - "loop".to_owned(), - Applicability::MachineApplicable - ); - err.emit(); + let condition_span = cx.sess.source_map().def_span(e.span); + cx.struct_span_lint(WHILE_TRUE, condition_span, msg) + .span_suggestion_short( + condition_span, + "use `loop`", + "loop".to_owned(), + Applicability::MachineApplicable + ) + .emit(); } } } @@ -110,11 +119,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { match it.node { hir::ItemKind::Fn(..) | - hir::ItemKind::Ty(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { - let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id); + let def_id = cx.tcx.hir().local_def_id(it.hir_id); self.check_heap_type(cx, it.span, cx.tcx.type_of(def_id)) } _ => () @@ -125,7 +134,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { for struct_field in struct_def.fields() { - let def_id = cx.tcx.hir().local_def_id_from_hir_id(struct_field.hir_id); + let def_id = cx.tcx.hir().local_def_id(struct_field.hir_id); self.check_heap_type(cx, struct_field.span, cx.tcx.type_of(def_id)); } @@ -399,7 +408,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { } "a trait" } - hir::ItemKind::Ty(..) => "a type alias", + hir::ItemKind::TyAlias(..) => "a type alias", hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) => { // If the trait is private, add the impl items to `private_traits` so they don't get // reported for missing docs. @@ -453,8 +462,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { let desc = match impl_item.node { hir::ImplItemKind::Const(..) => "an associated constant", hir::ImplItemKind::Method(..) => "a method", - hir::ImplItemKind::Type(_) => "an associated type", - hir::ImplItemKind::Existential(_) => "an associated existential type", + hir::ImplItemKind::TyAlias(_) => "an associated type", + hir::ImplItemKind::OpaqueTy(_) => "an associated `impl Trait` type", }; self.check_missing_docs_attrs(cx, Some(impl_item.hir_id), @@ -500,21 +509,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { if !ast_generics.params.is_empty() { return; } - let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id)); + let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.hir_id)); (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) } hir::ItemKind::Union(_, ref ast_generics) => { if !ast_generics.params.is_empty() { return; } - let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id)); + let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.hir_id)); (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) } hir::ItemKind::Enum(_, ref ast_generics) => { if !ast_generics.params.is_empty() { return; } - let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id)); + let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.hir_id)); (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) } _ => return, @@ -583,7 +592,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { if !self.impling_types.as_ref().unwrap().contains(&item.hir_id) { cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, - "type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \ + "type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` \ or a manual implementation") } } @@ -792,7 +801,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary { _ => return, }; - let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id); + let def_id = cx.tcx.hir().local_def_id(it.hir_id); let prfn = match cx.tcx.extern_mod_stmt_cnum(def_id) { Some(cnum) => cx.tcx.plugin_registrar_fn(cnum), None => { @@ -859,7 +868,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { if attr::contains_name(&it.attrs, sym::no_mangle) { // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to - let msg = "const items should never be #[no_mangle]"; + let msg = "const items should never be `#[no_mangle]`"; let mut err = cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg); // account for "pub const" (#45562) @@ -973,7 +982,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields { if let hir::ItemKind::Union(ref vdata, _) = item.node { for field in vdata.fields() { let field_ty = ctx.tcx.type_of( - ctx.tcx.hir().local_def_id_from_hir_id(field.hir_id)); + ctx.tcx.hir().local_def_id(field.hir_id)); if field_ty.needs_drop(ctx.tcx, ctx.param_env) { ctx.span_lint(UNIONS_WITH_DROP_FIELDS, field.span, @@ -1116,7 +1125,7 @@ impl TypeAliasBounds { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { let (ty, type_alias_generics) = match item.node { - hir::ItemKind::Ty(ref ty, ref generics) => (&*ty, generics), + hir::ItemKind::TyAlias(ref ty, ref generics) => (&*ty, generics), _ => return, }; let mut suggested_changing_assoc_types = false; @@ -1216,7 +1225,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { use rustc::ty::Predicate::*; if cx.tcx.features().trivial_bounds { - let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = cx.tcx.hir().local_def_id(item.hir_id); let predicates = cx.tcx.predicates_of(def_id); for &(predicate, span) in &predicates.predicates { let predicate_kind_name = match predicate { @@ -1350,7 +1359,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { declare_lint! { UNNAMEABLE_TEST_ITEMS, Warn, - "detects an item that cannot be named being marked as #[test_case]", + "detects an item that cannot be named being marked as `#[test_case]`", report_in_external_macro: true } @@ -1541,7 +1550,7 @@ impl ExplicitOutlivesRequirements { ty_generics: &'tcx ty::Generics, ) -> Vec> { let index = ty_generics.param_def_id_to_index[ - &tcx.hir().local_def_id_from_hir_id(param.hir_id)]; + &tcx.hir().local_def_id(param.hir_id)]; match param.kind { hir::GenericParamKind::Lifetime { .. } => { @@ -1659,7 +1668,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { use rustc::middle::resolve_lifetime::Region; let infer_static = cx.tcx.features().infer_static_outlives_requirements; - let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = cx.tcx.hir().local_def_id(item.hir_id); if let hir::ItemKind::Struct(_, ref hir_generics) | hir::ItemKind::Enum(_, ref hir_generics) | hir::ItemKind::Union(_, ref hir_generics) = item.node @@ -1823,3 +1832,144 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } } } + +declare_lint! { + pub INCOMPLETE_FEATURES, + Warn, + "incomplete features that may function improperly in some or all cases" +} + +declare_lint_pass!( + /// Check for used feature gates in `INCOMPLETE_FEATURES` in `feature_gate.rs`. + IncompleteFeatures => [INCOMPLETE_FEATURES] +); + +impl EarlyLintPass for IncompleteFeatures { + fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { + let features = cx.sess.features_untracked(); + features.declared_lang_features + .iter().map(|(name, span, _)| (name, span)) + .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span))) + .filter(|(name, _)| feature_gate::INCOMPLETE_FEATURES.iter().any(|f| name == &f)) + .for_each(|(name, &span)| { + cx.struct_span_lint( + INCOMPLETE_FEATURES, + span, + &format!( + "the feature `{}` is incomplete and may cause the compiler to crash", + name, + ) + ) + .emit(); + }); + } +} + +declare_lint! { + pub INVALID_VALUE, + Warn, + "an invalid value is being created (such as a NULL reference)" +} + +declare_lint_pass!(InvalidValue => [INVALID_VALUE]); + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) { + + const ZEROED_PATH: &[Symbol] = &[sym::core, sym::mem, sym::zeroed]; + const UININIT_PATH: &[Symbol] = &[sym::core, sym::mem, sym::uninitialized]; + + /// Information about why a type cannot be initialized this way. + /// Contains an error message and optionally a span to point at. + type InitError = (String, Option); + + /// Return `Some` only if we are sure this type does *not* + /// allow zero initialization. + fn ty_find_init_error<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { + use rustc::ty::TyKind::*; + match ty.sty { + // Primitive types that don't like 0 as a value. + Ref(..) => Some((format!("References must be non-null"), None)), + Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)), + FnPtr(..) => Some((format!("Function pointers must be non-null"), None)), + Never => Some((format!("The never type (`!`) has no valid value"), None)), + // Recurse for some compound types. + Adt(adt_def, substs) if !adt_def.is_union() => { + match adt_def.variants.len() { + 0 => Some((format!("0-variant enums have no valid value"), None)), + 1 => { + // Struct, or enum with exactly one variant. + // Proceed recursively, check all fields. + let variant = &adt_def.variants[VariantIdx::from_u32(0)]; + variant.fields.iter().find_map(|field| { + ty_find_init_error( + tcx, + field.ty(tcx, substs), + ).map(|(mut msg, span)| if span.is_none() { + // Point to this field, should be helpful for figuring + // out where the source of the error is. + let span = tcx.def_span(field.did); + write!(&mut msg, " (in this {} field)", adt_def.descr()) + .unwrap(); + (msg, Some(span)) + } else { + // Just forward. + (msg, span) + }) + }) + } + _ => None, // Conservative fallback for multi-variant enum. + } + } + Tuple(..) => { + // Proceed recursively, check all fields. + ty.tuple_fields().find_map(|field| ty_find_init_error(tcx, field)) + } + // FIXME: Would be nice to also warn for `NonNull`/`NonZero*`. + // FIXME: *Only for `mem::uninitialized`*, we could also warn for `bool`, + // `char`, and any multivariant enum. + // Conservative fallback. + _ => None, + } + } + + if let hir::ExprKind::Call(ref path_expr, ref _args) = expr.node { + if let hir::ExprKind::Path(ref qpath) = path_expr.node { + if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() { + if cx.match_def_path(def_id, &ZEROED_PATH) || + cx.match_def_path(def_id, &UININIT_PATH) + { + // This conjures an instance of a type out of nothing, + // using zeroed or uninitialized memory. + // We are extremely conservative with what we warn about. + let conjured_ty = cx.tables.expr_ty(expr); + if let Some((msg, span)) = ty_find_init_error(cx.tcx, conjured_ty) { + let mut err = cx.struct_span_lint( + INVALID_VALUE, + expr.span, + &format!( + "the type `{}` does not permit {}", + conjured_ty, + if cx.match_def_path(def_id, &ZEROED_PATH) { + "zero-initialization" + } else { + "being left uninitialized" + } + ), + ); + err.span_label(expr.span, + "this code causes undefined behavior when executed"); + err.span_label(expr.span, "help: use `MaybeUninit` instead"); + if let Some(span) = span { + err.span_note(span, &msg); + } else { + err.note(&msg); + } + err.emit(); + } + } + } + } + } + } +} diff --git a/src/librustc_lint/error_codes.rs b/src/librustc_lint/error_codes.rs index 3165673111..d7c39b780b 100644 --- a/src/librustc_lint/error_codes.rs +++ b/src/librustc_lint/error_codes.rs @@ -1,4 +1,4 @@ -use syntax::{register_diagnostic, register_diagnostics}; +use syntax::register_diagnostics; register_diagnostics! { E0721, // `await` keyword diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d808a15982..5648f9d0fd 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,10 +19,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; @@ -31,6 +27,7 @@ mod nonstandard_style; pub mod builtin; mod types; mod unused; +mod non_ascii_idents; use rustc::lint; use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; @@ -62,6 +59,7 @@ use nonstandard_style::*; use builtin::*; use types::*; use unused::*; +use non_ascii_idents::*; use rustc::lint::internal::*; /// Useful for other parts of the compiler. @@ -74,7 +72,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn lint_mod<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) { lint::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new()); } @@ -97,6 +95,9 @@ macro_rules! early_lint_passes { EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(), NonCamelCaseTypes: NonCamelCaseTypes, DeprecatedAttr: DeprecatedAttr::new(), + WhileTrue: WhileTrue, + NonAsciiIdents: NonAsciiIdents, + IncompleteFeatures: IncompleteFeatures, ]); ) } @@ -141,7 +142,6 @@ macro_rules! late_lint_mod_passes { ($macro:path, $args:tt) => ( $macro!($args, [ HardwiredLints: HardwiredLints, - WhileTrue: WhileTrue, ImproperCTypes: ImproperCTypes, VariantSizeDifferences: VariantSizeDifferences, BoxPointers: BoxPointers, @@ -177,6 +177,7 @@ macro_rules! late_lint_mod_passes { UnreachablePub: UnreachablePub, ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, + InvalidValue: InvalidValue, ]); ) } @@ -427,7 +428,17 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT), reference: "issue #59159 ", edition: None, - } + }, + FutureIncompatibleInfo { + id: LintId::of(INDIRECT_STRUCTURAL_MATCH), + reference: "issue #62411 ", + edition: None, + }, + FutureIncompatibleInfo { + id: LintId::of(SOFT_UNSTABLE), + reference: "issue #64266 ", + edition: None, + }, ]); // Register renamed and removed lints. @@ -474,9 +485,9 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { store.register_removed("resolve_trait_on_defaulted_unit", "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); store.register_removed("private_no_mangle_fns", - "no longer a warning, #[no_mangle] functions always exported"); + "no longer a warning, `#[no_mangle]` functions always exported"); store.register_removed("private_no_mangle_statics", - "no longer a warning, #[no_mangle] statics always exported"); + "no longer a warning, `#[no_mangle]` statics always exported"); store.register_removed("bad_repr", "replaced with a generic attribute input check"); store.register_removed("duplicate_matcher_binding_name", @@ -487,15 +498,17 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) { store.register_early_pass(sess, false, false, box DefaultHashTypes::new()); + store.register_early_pass(sess, false, false, box LintPassImpl); store.register_late_pass(sess, false, false, false, box TyTyKind); store.register_group( sess, false, - "internal", + "rustc::internal", None, vec![ LintId::of(DEFAULT_HASH_TYPES), LintId::of(USAGE_OF_TY_TYKIND), + LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), LintId::of(TY_PASS_BY_REFERENCE), LintId::of(USAGE_OF_QUALIFIED_TY), ], diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs new file mode 100644 index 0000000000..aa39211efc --- /dev/null +++ b/src/librustc_lint/non_ascii_idents.rs @@ -0,0 +1,22 @@ +use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use syntax::ast; + +declare_lint! { + pub NON_ASCII_IDENTS, + Allow, + "detects non-ASCII identifiers" +} + +declare_lint_pass!(NonAsciiIdents => [NON_ASCII_IDENTS]); + +impl EarlyLintPass for NonAsciiIdents { + fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { + if !ident.name.as_str().is_ascii() { + cx.struct_span_lint( + NON_ASCII_IDENTS, + ident.span, + "identifier contains non-ASCII characters", + ).emit(); + } + } +} diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index b221b8ed30..8f7fe6680c 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -20,7 +20,7 @@ pub enum MethodLateContext { } pub fn method_context(cx: &LateContext<'_, '_>, id: hir::HirId) -> MethodLateContext { - let def_id = cx.tcx.hir().local_def_id_from_hir_id(id); + let def_id = cx.tcx.hir().local_def_id(id); let item = cx.tcx.associated_item(def_id); match item.container { ty::TraitContainer(..) => MethodLateContext::TraitAutoImpl, @@ -137,7 +137,7 @@ impl EarlyLintPass for NonCamelCaseTypes { } match it.node { - ast::ItemKind::Ty(..) | + ast::ItemKind::TyAlias(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index d0258ca30c..e86230437f 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -73,7 +73,9 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>( // We only want to handle exclusive (`..`) ranges, // which are represented as `ExprKind::Struct`. if let ExprKind::Struct(_, eps, _) = &parent_expr.node { - debug_assert_eq!(eps.len(), 2); + if eps.len() != 2 { + return false; + } // We can suggest using an inclusive range // (`..=`) instead only if it is the `end` that is // overflowing and only by 1. @@ -888,7 +890,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) { - let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(id); + let def_id = self.cx.tcx.hir().local_def_id(id); let sig = self.cx.tcx.fn_sig(def_id); let sig = self.cx.tcx.erase_late_bound_regions(&sig); let inputs = if sig.c_variadic { @@ -912,7 +914,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } fn check_foreign_static(&mut self, id: hir::HirId, span: Span) { - let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(id); + let def_id = self.cx.tcx.hir().local_def_id(id); let ty = self.cx.tcx.type_of(def_id); self.check_type_for_ffi_and_report_errors(span, ty); } @@ -941,7 +943,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) { if let hir::ItemKind::Enum(ref enum_definition, _) = it.node { - let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id); + let item_def_id = cx.tcx.hir().local_def_id(it.hir_id); let t = cx.tcx.type_of(item_def_id); let ty = cx.tcx.erase_regions(&t); let layout = match cx.layout_of(ty) { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 2db2e0bc0d..6a3dfdbe31 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -15,7 +15,7 @@ use syntax::print::pprust; use syntax::symbol::{kw, sym}; use syntax::symbol::Symbol; use syntax::util::parser; -use syntax_pos::Span; +use syntax_pos::{Span, BytePos}; use rustc::hir; @@ -24,7 +24,7 @@ use log::debug; declare_lint! { pub UNUSED_MUST_USE, Warn, - "unused result of a type flagged as #[must_use]", + "unused result of a type flagged as `#[must_use]`", report_in_external_macro: true } @@ -208,7 +208,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } has_emitted } - ty::Array(ty, len) => match len.assert_usize(cx.tcx) { + ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) { // If the array is definitely non-empty, we can do `#[must_use]` checking. Some(n) if n != 0 => { let descr_pre = &format!( @@ -316,7 +316,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { let name = attr.name_or_empty(); if !attr::is_used(attr) { - debug!("Emitting warning for: {:?}", attr); + debug!("emitting warning for: {:?}", attr); cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute"); // Is it a builtin attribute that must be used at the crate level? let known_crate = attr_info.map(|&&(_, ty, ..)| { @@ -332,7 +332,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { let msg = match attr.style { ast::AttrStyle::Outer => { "crate-level attribute should be an inner attribute: add an exclamation \ - mark: #![foo]" + mark: `#![foo]`" } ast::AttrStyle::Inner => "crate-level attribute should be in the root module", }; @@ -353,31 +353,46 @@ declare_lint! { declare_lint_pass!(UnusedParens => [UNUSED_PARENS]); impl UnusedParens { + + fn is_expr_parens_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool { + followed_by_block && match inner.node { + ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, + _ => parser::contains_exterior_struct_lit(&inner), + } + } + fn check_unused_parens_expr(&self, - cx: &EarlyContext<'_>, - value: &ast::Expr, - msg: &str, - followed_by_block: bool) { + cx: &EarlyContext<'_>, + value: &ast::Expr, + msg: &str, + followed_by_block: bool, + left_pos: Option, + right_pos: Option) { match value.node { ast::ExprKind::Paren(ref inner) => { - let necessary = followed_by_block && match inner.node { - ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, - _ => parser::contains_exterior_struct_lit(&inner), - }; - if !necessary { + if !Self::is_expr_parens_necessary(inner, followed_by_block) { let expr_text = if let Ok(snippet) = cx.sess().source_map() .span_to_snippet(value.span) { snippet } else { pprust::expr_to_string(value) }; - Self::remove_outer_parens(cx, value.span, &expr_text, msg); + let keep_space = ( + left_pos.map(|s| s >= value.span.lo()).unwrap_or(false), + right_pos.map(|s| s <= value.span.hi()).unwrap_or(false), + ); + Self::remove_outer_parens(cx, value.span, &expr_text, msg, keep_space); } } ast::ExprKind::Let(_, ref expr) => { // FIXME(#60336): Properly handle `let true = (false && true)` // actually needing the parenthesis. - self.check_unused_parens_expr(cx, expr, "`let` head expression", followed_by_block); + self.check_unused_parens_expr( + cx, expr, + "`let` head expression", + followed_by_block, + None, None + ); } _ => {} } @@ -394,11 +409,15 @@ impl UnusedParens { } else { pprust::pat_to_string(value) }; - Self::remove_outer_parens(cx, value.span, &pattern_text, msg); + Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false)); } } - fn remove_outer_parens(cx: &EarlyContext<'_>, span: Span, pattern: &str, msg: &str) { + fn remove_outer_parens(cx: &EarlyContext<'_>, + span: Span, + pattern: &str, + msg: &str, + keep_space: (bool, bool)) { let span_msg = format!("unnecessary parentheses around {}", msg); let mut err = cx.struct_span_lint(UNUSED_PARENS, span, &span_msg); let mut ate_left_paren = false; @@ -424,11 +443,27 @@ impl UnusedParens { }, _ => false, } - }).to_owned(); + }); + + let replace = { + let mut replace = if keep_space.0 { + let mut s = String::from(" "); + s.push_str(parens_removed); + s + } else { + String::from(parens_removed) + }; + + if keep_space.1 { + replace.push(' '); + } + replace + }; + err.span_suggestion_short( span, "remove these parentheses", - parens_removed, + replace, Applicability::MachineApplicable, ); err.emit(); @@ -438,14 +473,35 @@ impl UnusedParens { impl EarlyLintPass for UnusedParens { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { use syntax::ast::ExprKind::*; - let (value, msg, followed_by_block) = match e.node { - If(ref cond, ..) => (cond, "`if` condition", true), - While(ref cond, ..) => (cond, "`while` condition", true), - ForLoop(_, ref cond, ..) => (cond, "`for` head expression", true), - Match(ref head, _) => (head, "`match` head expression", true), - Ret(Some(ref value)) => (value, "`return` value", false), - Assign(_, ref value) => (value, "assigned value", false), - AssignOp(.., ref value) => (value, "assigned value", false), + let (value, msg, followed_by_block, left_pos, right_pos) = match e.node { + If(ref cond, ref block, ..) => { + let left = e.span.lo() + syntax_pos::BytePos(2); + let right = block.span.lo(); + (cond, "`if` condition", true, Some(left), Some(right)) + } + + While(ref cond, ref block, ..) => { + let left = e.span.lo() + syntax_pos::BytePos(5); + let right = block.span.lo(); + (cond, "`while` condition", true, Some(left), Some(right)) + }, + + ForLoop(_, ref cond, ref block, ..) => { + (cond, "`for` head expression", true, None, Some(block.span.lo())) + } + + Match(ref head, _) => { + let left = e.span.lo() + syntax_pos::BytePos(5); + (head, "`match` head expression", true, Some(left), None) + } + + Ret(Some(ref value)) => { + let left = e.span.lo() + syntax_pos::BytePos(3); + (value, "`return` value", false, Some(left), None) + } + + Assign(_, ref value) => (value, "assigned value", false, None, None), + AssignOp(.., ref value) => (value, "assigned value", false, None, None), // either function/method call, or something this lint doesn't care about ref call_or_other => { let (args_to_check, call_kind) = match *call_or_other { @@ -467,12 +523,12 @@ impl EarlyLintPass for UnusedParens { } let msg = format!("{} argument", call_kind); for arg in args_to_check { - self.check_unused_parens_expr(cx, arg, &msg, false); + self.check_unused_parens_expr(cx, arg, &msg, false, None, None); } return; } }; - self.check_unused_parens_expr(cx, &value, msg, followed_by_block); + self.check_unused_parens_expr(cx, &value, msg, followed_by_block, left_pos, right_pos); } fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { @@ -492,7 +548,7 @@ impl EarlyLintPass for UnusedParens { fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { if let ast::StmtKind::Local(ref local) = s.node { if let Some(ref value) = local.init { - self.check_unused_parens_expr(cx, &value, "assigned value", false); + self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None); } } } @@ -570,9 +626,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation { if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind { let msg = match m { adjustment::AutoBorrowMutability::Immutable => - "unnecessary allocation, use & instead", + "unnecessary allocation, use `&` instead", adjustment::AutoBorrowMutability::Mutable { .. }=> - "unnecessary allocation, use &mut instead" + "unnecessary allocation, use `&mut` instead" }; cx.span_lint(UNUSED_ALLOCATION, e.span, msg); } diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 21fa872c8d..16cdbb7dd4 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -71,7 +71,8 @@ fn main() { let mut optional_components = vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", - "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"]; + "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx", + "hexagon"]; let mut version_cmd = Command::new(&llvm_config); version_cmd.arg("--version"); @@ -82,27 +83,19 @@ fn main() { if let (Some(major), Some(minor)) = (parts.next(), parts.next()) { (major, minor) } else { - (3, 9) + (6, 0) }; - if major > 3 { - optional_components.push("hexagon"); - } - if major > 6 { optional_components.push("riscv"); } - // FIXME: surely we don't need all these components, right? Stuff like mcjit - // or interpreter the compiler itself never uses. let required_components = &["ipo", "bitreader", "bitwriter", "linker", "asmparser", - "mcjit", "lto", - "interpreter", "instrumentation"]; let components = output(Command::new(&llvm_config).arg("--components")); @@ -119,6 +112,10 @@ fn main() { println!("cargo:rustc-cfg=llvm_component=\"{}\"", component); } + if major >= 9 { + println!("cargo:rustc-cfg=llvm_has_msp430_asm_parser"); + } + // Link in our own LLVM shims, compiled with the same flags as LLVM let mut cmd = Command::new(&llvm_config); cmd.arg("--cxxflags"); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 292ce8b0a0..647d473f01 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -1,13 +1,8 @@ -#![deny(rust_2018_idioms)] #![feature(nll)] #![feature(static_nobundle)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -// See librustc_cratesio_shim/Cargo.toml for a comment explaining this. -#[allow(unused_extern_crates)] -extern crate rustc_cratesio_shim; - // NOTE: This crate only exists to allow linking on mingw targets. /// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`. @@ -80,6 +75,8 @@ pub fn initialize_available_targets() { LLVMInitializeMSP430Target, LLVMInitializeMSP430TargetMC, LLVMInitializeMSP430AsmPrinter); + init_target!(all(llvm_component = "msp430", llvm_has_msp430_asm_parser), + LLVMInitializeMSP430AsmParser); init_target!(llvm_component = "riscv", LLVMInitializeRISCVTargetInfo, LLVMInitializeRISCVTarget, diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 3bdb86d313..d6c8e54c18 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index e9cf7bca25..85e2247ebd 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -1,5 +1,5 @@ #![feature(proc_macro_hygiene)] -#![deny(rust_2018_idioms)] +#![cfg_attr(not(bootstrap), allow(rustc::default_hash_types))] #![recursion_limit="128"] diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index d47bd0580d..a8df7e197a 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -414,6 +414,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { let mut dep_node_force_stream = quote! {}; let mut try_load_from_on_disk_cache_stream = quote! {}; let mut no_force_queries = Vec::new(); + let mut cached_queries = quote! {}; for group in groups.0 { let mut group_stream = quote! {}; @@ -427,6 +428,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { _ => quote! { #result_full }, }; + if modifiers.cache.is_some() { + cached_queries.extend(quote! { + #name, + }); + } + if modifiers.cache.is_some() && !modifiers.no_force { try_load_from_on_disk_cache_stream.extend(quote! { DepKind::#name => { @@ -549,6 +556,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { } } } + macro_rules! rustc_cached_queries { + ($($macro:tt)*) => { + $($macro)*(#cached_queries); + } + } + #query_description_stream impl DepNode { diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 76aba33b6a..5ff60a9267 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [lib] name = "rustc_metadata" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] flate2 = "1.0" @@ -18,8 +18,7 @@ rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } stable_deref_trait = "1.0.0" syntax = { path = "../libsyntax" } -syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 2073b31793..d5f1e71518 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -8,7 +8,6 @@ use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; -use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::DepKind; use rustc::mir::interpret::AllocDecodingState; use rustc::session::{Session, CrateDisambiguator}; @@ -26,9 +25,9 @@ use std::{cmp, fs}; use syntax::ast; use syntax::attr; +use syntax::ext::allocator::{global_allocator_spans, AllocatorKind}; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use syntax::symbol::{Symbol, sym}; -use syntax::visit; use syntax::{span_err, span_fatal}; use syntax_pos::{Span, DUMMY_SP}; use log::{debug, info, log_enabled}; @@ -587,8 +586,7 @@ impl<'a> CrateLoader<'a> { use std::{env, mem}; use crate::dynamic_lib::DynamicLibrary; use proc_macro::bridge::client::ProcMacro; - use syntax_ext::deriving::custom::ProcMacroDerive; - use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro}; + use syntax::ext::proc_macro::{BangProcMacro, AttrProcMacro, ProcMacroDerive}; let path = match dylib { Some(dylib) => dylib, @@ -888,7 +886,14 @@ impl<'a> CrateLoader<'a> { } fn inject_allocator_crate(&mut self, krate: &ast::Crate) { - let has_global_allocator = has_global_allocator(krate); + let has_global_allocator = match &*global_allocator_spans(krate) { + [span1, span2, ..] => { + self.sess.struct_span_err(*span2, "cannot define multiple global allocators") + .span_note(*span1, "the previous global allocator is defined here").emit(); + true + } + spans => !spans.is_empty() + }; self.sess.has_global_allocator.set(has_global_allocator); // Check to see if we actually need an allocator. This desire comes @@ -938,14 +943,14 @@ impl<'a> CrateLoader<'a> { } match global_allocator { Some(Some(other_crate)) => { - self.sess.err(&format!("the #[global_allocator] in {} \ + self.sess.err(&format!("the `#[global_allocator]` in {} \ conflicts with this global \ allocator in: {}", other_crate, data.root.name)); } Some(None) => { - self.sess.err(&format!("the #[global_allocator] in this \ + self.sess.err(&format!("the `#[global_allocator]` in this \ crate conflicts with global \ allocator in: {}", data.root.name)); } @@ -971,29 +976,12 @@ impl<'a> CrateLoader<'a> { if !has_default { self.sess.err("no global memory allocator found but one is \ required; link to std or \ - add #[global_allocator] to a static item \ + add `#[global_allocator]` to a static item \ that implements the GlobalAlloc trait."); } self.sess.allocator_kind.set(Some(AllocatorKind::DefaultLib)); - - fn has_global_allocator(krate: &ast::Crate) -> bool { - struct Finder(bool); - let mut f = Finder(false); - visit::walk_crate(&mut f, krate); - return f.0; - - impl<'ast> visit::Visitor<'ast> for Finder { - fn visit_item(&mut self, i: &'ast ast::Item) { - if attr::contains_name(&i.attrs, sym::global_allocator) { - self.0 = true; - } - visit::walk_item(self, i) - } - } - } } - fn inject_dependency_if(&self, krate: CrateNum, what: &str, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 04a9c4e9a1..ee1175e798 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -31,10 +31,10 @@ use syntax::attr; use syntax::source_map; use syntax::edition::Edition; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; +use syntax::ext::proc_macro::BangProcMacro; use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; use syntax::symbol::{Symbol, sym}; -use syntax_ext::proc_macro_impl::BangProcMacro; use syntax_pos::{Span, NO_EXPANSION, FileName}; use rustc_data_structures::bit_set::BitSet; @@ -250,7 +250,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, exported_symbols => { Arc::new(cdata.exported_symbols(tcx)) } } -pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { +pub fn provide(providers: &mut Providers<'_>) { // FIXME(#44234) - almost all of these queries have no sub-queries and // therefore no actual inputs, they're just reading tables calculated in // resolve! Does this work? Unsure! That's what the issue is about @@ -550,7 +550,7 @@ impl CrateStore for cstore::CStore { self.do_postorder_cnums_untracked() } - fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata { + fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata { encoder::encode_metadata(tcx) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 6a5f62aec1..935187dd06 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -31,7 +31,7 @@ use syntax::ast::{self, Ident}; use syntax::source_map; use syntax::symbol::{Symbol, sym}; use syntax::ext::base::{MacroKind, SyntaxExtension}; -use syntax::ext::hygiene::Mark; +use syntax::ext::hygiene::ExpnId; use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; use log::debug; @@ -413,9 +413,9 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Type => DefKind::TyAlias, EntryKind::TypeParam => DefKind::TyParam, EntryKind::ConstParam => DefKind::ConstParam, - EntryKind::Existential => DefKind::Existential, + EntryKind::OpaqueTy => DefKind::OpaqueTy, EntryKind::AssocType(_) => DefKind::AssocTy, - EntryKind::AssocExistential(_) => DefKind::AssocExistential, + EntryKind::AssocOpaqueTy(_) => DefKind::AssocOpaqueTy, EntryKind::Mod(_) => DefKind::Mod, EntryKind::Variant(_) => DefKind::Variant, EntryKind::Trait(_) => DefKind::Trait, @@ -458,7 +458,7 @@ crate fn proc_macro_def_path_table(crate_root: &CrateRoot<'_>, crate_root, ast::DUMMY_NODE_ID, DefPathData::MacroNs(name.as_interned_str()), - Mark::root(), + ExpnId::root(), DUMMY_SP); debug!("definition for {:?} is {:?}", name, def_index); assert_eq!(def_index, DefIndex::from_proc_macro_index(index)); @@ -910,8 +910,8 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::AssocType(container) => { (ty::AssocKind::Type, container, false) } - EntryKind::AssocExistential(container) => { - (ty::AssocKind::Existential, container, false) + EntryKind::AssocOpaqueTy(container) => { + (ty::AssocKind::OpaqueTy, container, false) } _ => bug!("cannot get associated-item of `{:?}`", def_key) }; @@ -980,14 +980,7 @@ impl<'a, 'tcx> CrateMetadata { } fn get_attributes(&self, item: &Entry<'tcx>, sess: &Session) -> Vec { - item.attributes - .decode((self, sess)) - .map(|mut attr| { - // Need new unique IDs: old thread-local IDs won't map to new threads. - attr.id = attr::mk_attr_id(); - attr - }) - .collect() + item.attributes.decode((self, sess)).collect() } // Translate a DefId from the current compilation environment to a DefId diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index b52b6dfbb5..d73a4966bc 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -667,7 +667,7 @@ impl EncodeContext<'tcx> { (id, md, attrs, vis): (hir::HirId, &hir::Mod, &[ast::Attribute], &hir::Visibility), ) -> Entry<'tcx> { let tcx = self.tcx; - let def_id = tcx.hir().local_def_id_from_hir_id(id); + let def_id = tcx.hir().local_def_id(id); debug!("EncodeContext::encode_info_for_mod({:?})", def_id); let data = ModData { @@ -683,7 +683,7 @@ impl EncodeContext<'tcx> { span: self.lazy(&tcx.def_span(def_id)), attributes: self.encode_attributes(attrs), children: self.lazy_seq(md.item_ids.iter().map(|item_id| { - tcx.hir().local_def_id_from_hir_id(item_id.id).index + tcx.hir().local_def_id(item_id.id).index })), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), @@ -868,8 +868,7 @@ impl EncodeContext<'tcx> { })) } ty::AssocKind::Type => EntryKind::AssocType(container), - ty::AssocKind::Existential => - span_bug!(ast_item.span, "existential type in trait"), + ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"), }; Entry { @@ -893,7 +892,7 @@ impl EncodeContext<'tcx> { None } } - ty::AssocKind::Existential => unreachable!(), + ty::AssocKind::OpaqueTy => unreachable!(), }, inherent_impls: LazySeq::empty(), variances: if trait_item.kind == ty::AssocKind::Method { @@ -964,7 +963,7 @@ impl EncodeContext<'tcx> { has_self: impl_item.method_has_self_argument, })) } - ty::AssocKind::Existential => EntryKind::AssocExistential(container), + ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container), ty::AssocKind::Type => EntryKind::AssocType(container) }; @@ -980,8 +979,8 @@ impl EncodeContext<'tcx> { let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; needs_inline || is_const_fn || always_encode_mir }, - hir::ImplItemKind::Existential(..) | - hir::ImplItemKind::Type(..) => false, + hir::ImplItemKind::OpaqueTy(..) | + hir::ImplItemKind::TyAlias(..) => false, }; Entry { @@ -1095,8 +1094,8 @@ impl EncodeContext<'tcx> { } hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod, hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, - hir::ItemKind::Ty(..) => EntryKind::Type, - hir::ItemKind::Existential(..) => EntryKind::Existential, + hir::ItemKind::TyAlias(..) => EntryKind::Type, + hir::ItemKind::OpaqueTy(..) => EntryKind::OpaqueTy, hir::ItemKind::Enum(..) => EntryKind::Enum(get_repr_options(tcx, def_id)), hir::ItemKind::Struct(ref struct_def, _) => { let variant = tcx.adt_def(def_id).non_enum_variant(); @@ -1105,7 +1104,7 @@ impl EncodeContext<'tcx> { // for methods, write all the stuff get_trait_method // needs to know let ctor = struct_def.ctor_hir_id() - .map(|ctor_hir_id| tcx.hir().local_def_id_from_hir_id(ctor_hir_id).index); + .map(|ctor_hir_id| tcx.hir().local_def_id(ctor_hir_id).index); let repr_options = get_repr_options(tcx, def_id); @@ -1194,7 +1193,7 @@ impl EncodeContext<'tcx> { hir::ItemKind::ForeignMod(ref fm) => { self.lazy_seq(fm.items .iter() - .map(|foreign_item| tcx.hir().local_def_id_from_hir_id( + .map(|foreign_item| tcx.hir().local_def_id( foreign_item.hir_id).index)) } hir::ItemKind::Enum(..) => { @@ -1228,8 +1227,8 @@ impl EncodeContext<'tcx> { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::Fn(..) | - hir::ItemKind::Ty(..) | - hir::ItemKind::Existential(..) | + hir::ItemKind::TyAlias(..) | + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | @@ -1248,12 +1247,12 @@ impl EncodeContext<'tcx> { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::Fn(..) | - hir::ItemKind::Ty(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Impl(..) | - hir::ItemKind::Existential(..) | + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)), hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)), _ => None, @@ -1262,12 +1261,12 @@ impl EncodeContext<'tcx> { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::Fn(..) | - hir::ItemKind::Ty(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Impl(..) | - hir::ItemKind::Existential(..) | + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)), _ => None, @@ -1313,10 +1312,10 @@ impl EncodeContext<'tcx> { /// Serialize the text of exported macros fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx> { use syntax::print::pprust; - let def_id = self.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id); + let def_id = self.tcx.hir().local_def_id(macro_def.hir_id); Entry { kind: EntryKind::MacroDef(self.lazy(&MacroDef { - body: pprust::tts_to_string(¯o_def.body.trees().collect::>()), + body: pprust::tokens_to_string(macro_def.body.clone()), legacy: macro_def.legacy, })), visibility: self.lazy(&ty::Visibility::Public), @@ -1656,7 +1655,7 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item) { intravisit::walk_item(self, item); - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); match item.node { hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these @@ -1666,7 +1665,7 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - let def_id = self.tcx.hir().local_def_id_from_hir_id(ni.hir_id); + let def_id = self.tcx.hir().local_def_id(ni.hir_id); self.record(def_id, EncodeContext::encode_info_for_foreign_item, (def_id, ni)); @@ -1678,7 +1677,7 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { intravisit::walk_variant(self, v, g, id); if let Some(ref discr) = v.node.disr_expr { - let def_id = self.tcx.hir().local_def_id_from_hir_id(discr.hir_id); + let def_id = self.tcx.hir().local_def_id(discr.hir_id); self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id); } } @@ -1691,7 +1690,7 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { self.encode_info_for_ty(ty); } fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id); + let def_id = self.tcx.hir().local_def_id(macro_def.hir_id); self.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def); } } @@ -1710,7 +1709,7 @@ impl EncodeContext<'tcx> { fn encode_info_for_generics(&mut self, generics: &hir::Generics) { for param in &generics.params { - let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id); + let def_id = self.tcx.hir().local_def_id(param.hir_id); match param.kind { GenericParamKind::Lifetime { .. } => continue, GenericParamKind::Type { ref default, .. } => { @@ -1730,7 +1729,7 @@ impl EncodeContext<'tcx> { fn encode_info_for_ty(&mut self, ty: &hir::Ty) { match ty.node { hir::TyKind::Array(_, ref length) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(length.hir_id); + let def_id = self.tcx.hir().local_def_id(length.hir_id); self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id); } _ => {} @@ -1740,7 +1739,7 @@ impl EncodeContext<'tcx> { fn encode_info_for_expr(&mut self, expr: &hir::Expr) { match expr.node { hir::ExprKind::Closure(..) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id); + let def_id = self.tcx.hir().local_def_id(expr.hir_id); self.record(def_id, EncodeContext::encode_info_for_closure, def_id); } _ => {} @@ -1752,7 +1751,7 @@ impl EncodeContext<'tcx> { /// so it's easier to do that here then to wait until we would encounter /// normally in the visitor walk. fn encode_addl_info_for_item(&mut self, item: &hir::Item) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); match item.node { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | @@ -1762,8 +1761,8 @@ impl EncodeContext<'tcx> { hir::ItemKind::GlobalAsm(..) | hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | - hir::ItemKind::Ty(..) | - hir::ItemKind::Existential(..) | + hir::ItemKind::TyAlias(..) | + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::TraitAlias(..) => { // no sub-item recording needed in these cases } @@ -1788,7 +1787,7 @@ impl EncodeContext<'tcx> { // If the struct has a constructor, encode it. if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { - let ctor_def_id = self.tcx.hir().local_def_id_from_hir_id(ctor_hir_id); + let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id); self.record(ctor_def_id, EncodeContext::encode_struct_ctor, (def_id, ctor_def_id)); @@ -1823,7 +1822,7 @@ struct ImplVisitor<'tcx> { impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { fn visit_item(&mut self, item: &hir::Item) { if let hir::ItemKind::Impl(..) = item.node { - let impl_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { self.impls .entry(trait_ref.def_id) @@ -1863,7 +1862,7 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { // will allow us to slice the metadata to the precise length that we just // generated regardless of trailing bytes that end up in it. -pub fn encode_metadata<'tcx>(tcx: TyCtxt<'tcx>) -> EncodedMetadata { +pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { let mut encoder = opaque::Encoder::new(vec![]); encoder.emit_raw_bytes(METADATA_HEADER); @@ -1905,7 +1904,7 @@ pub fn encode_metadata<'tcx>(tcx: TyCtxt<'tcx>) -> EncodedMetadata { EncodedMetadata { raw_data: result } } -pub fn get_repr_options<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> ReprOptions { +pub fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { let ty = tcx.type_of(did); match ty.sty { ty::Adt(ref def, _) => return def.repr, diff --git a/src/librustc_metadata/error_codes.rs b/src/librustc_metadata/error_codes.rs index 9ac582ebc4..0708a6243b 100644 --- a/src/librustc_metadata/error_codes.rs +++ b/src/librustc_metadata/error_codes.rs @@ -1,13 +1,12 @@ -#![allow(non_snake_case)] - -use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; +use syntax::{register_diagnostics, register_long_diagnostics}; register_long_diagnostics! { E0454: r##" A link name was given with an empty name. Erroneous code example: ```ignore (cannot-test-this-because-rustdoc-stops-compile-fail-before-codegen) -#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name +#[link(name = "")] extern {} +// error: `#[link(name = "")]` given with empty name ``` The rust compiler cannot link to an external library if you don't give it its @@ -61,7 +60,7 @@ A link was used without a name parameter. Erroneous code example: ```ignore (cannot-test-this-because-rustdoc-stops-compile-fail-before-codegen) #[link(kind = "dylib")] extern {} -// error: #[link(...)] specified without `name = "foo"` +// error: `#[link(...)]` specified without `name = "foo"` ``` Please add the name parameter to allow the rust compiler to find the library diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs index 0ce103cfa4..b2e40282d9 100644 --- a/src/librustc_metadata/foreign_modules.rs +++ b/src/librustc_metadata/foreign_modules.rs @@ -3,7 +3,7 @@ use rustc::hir; use rustc::middle::cstore::ForeignModule; use rustc::ty::TyCtxt; -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, modules: Vec::new(), @@ -25,11 +25,11 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { }; let foreign_items = fm.items.iter() - .map(|it| self.tcx.hir().local_def_id_from_hir_id(it.hir_id)) + .map(|it| self.tcx.hir().local_def_id(it.hir_id)) .collect(); self.modules.push(ForeignModule { foreign_items, - def_id: self.tcx.hir().local_def_id_from_hir_id(it.hir_id), + def_id: self.tcx.hir().local_def_id(it.hir_id), }); } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index e49ca8acf6..c96d02d9b3 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -1,6 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(box_patterns)] +#![feature(crate_visibility_modifier)] #![feature(drain_filter)] #![feature(in_band_lifetimes)] #![feature(libc)] @@ -8,19 +9,13 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![feature(rustc_diagnostic_macros)] -#![feature(crate_visibility_modifier)] -#![feature(specialization)] #![feature(rustc_private)] +#![feature(slice_patterns)] +#![feature(specialization)] #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - extern crate libc; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving extern crate proc_macro; #[macro_use] diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index cd6270046f..728fd004fc 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -4,7 +4,7 @@ use rustc::ty::TyCtxt; use rustc_target::spec::abi::Abi; use syntax::symbol::sym; -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { args: Vec::new(), }; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 7b335b3b48..66971bb6f8 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -11,7 +11,7 @@ use syntax::feature_gate::{self, GateIssue}; use syntax::symbol::{Symbol, sym}; use syntax::{span_err, struct_span_err}; -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, libs: Vec::new(), @@ -56,7 +56,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { name: None, kind: cstore::NativeUnknown, cfg: None, - foreign_module: Some(self.tcx.hir().local_def_id_from_hir_id(it.hir_id)), + foreign_module: Some(self.tcx.hir().local_def_id(it.hir_id)), wasm_import_module: None, }; let mut kind_specified = false; @@ -102,7 +102,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { match item.value_str() { Some(s) => lib.wasm_import_module = Some(s), None => { - let msg = "must be of the form #[link(wasm_import_module = \"...\")]"; + let msg = "must be of the form `#[link(wasm_import_module = \"...\")]`"; self.tcx.sess.span_err(item.span(), msg); } } @@ -117,7 +117,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { let requires_name = kind_specified || lib.wasm_import_module.is_none(); if lib.name.is_none() && requires_name { struct_span_err!(self.tcx.sess, m.span, E0459, - "#[link(...)] specified without \ + "`#[link(...)]` specified without \ `name = \"foo\"`") .span_label(m.span, "missing `name` argument") .emit(); @@ -136,7 +136,7 @@ impl Collector<'tcx> { match span { Some(span) => { struct_span_err!(self.tcx.sess, span, E0454, - "#[link(name = \"\")] given with empty name") + "`#[link(name = \"\")]` given with empty name") .span_label(span, "empty name given") .emit(); } @@ -187,7 +187,7 @@ impl Collector<'tcx> { &format!("an empty renaming target was specified for library `{}`",name)); } else if !any_duplicate { self.tcx.sess.err(&format!("renaming of the library `{}` was specified, \ - however this crate contains no #[link(...)] \ + however this crate contains no `#[link(...)]` \ attributes referencing this library.", name)); } else if renames.contains(name) { self.tcx.sess.err(&format!("multiple renamings were \ diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 8d1de4fd6c..c0ac691593 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -13,7 +13,6 @@ use rustc::ty::{self, Ty, ReprOptions}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_data_structures::svh::Svh; -use rustc_serialize as serialize; use syntax::{ast, attr}; use syntax::edition::Edition; use syntax::symbol::Symbol; @@ -85,8 +84,8 @@ impl Clone for Lazy { } } -impl serialize::UseSpecializedEncodable for Lazy {} -impl serialize::UseSpecializedDecodable for Lazy {} +impl rustc_serialize::UseSpecializedEncodable for Lazy {} +impl rustc_serialize::UseSpecializedDecodable for Lazy {} /// A sequence of type T referred to by its absolute position /// in the metadata and length, and which can be decoded lazily. @@ -133,8 +132,8 @@ impl Clone for LazySeq { } } -impl serialize::UseSpecializedEncodable for LazySeq {} -impl serialize::UseSpecializedDecodable for LazySeq {} +impl rustc_serialize::UseSpecializedEncodable for LazySeq {} +impl rustc_serialize::UseSpecializedDecodable for LazySeq {} /// Encoding / decoding state for `Lazy` and `LazySeq`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -240,7 +239,7 @@ pub enum EntryKind<'tcx> { Type, TypeParam, ConstParam, - Existential, + OpaqueTy, Enum(ReprOptions), Field, Variant(Lazy>), @@ -256,7 +255,7 @@ pub enum EntryKind<'tcx> { Impl(Lazy>), Method(Lazy>), AssocType(AssocContainer), - AssocExistential(AssocContainer), + AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, ConstQualif, Lazy), TraitAlias(Lazy>), } diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 5de5f5e757..21008c7372 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [lib] name = "rustc_mir" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] arena = { path = "../libarena" } @@ -15,12 +15,12 @@ either = "1.5.0" dot = { path = "../libgraphviz", package = "graphviz" } log = "0.4" log_settings = "0.1.1" -polonius-engine = "0.7.0" +polonius-engine = "0.9.0" rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } byteorder = { version = "1.1", features = ["i128"] } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 40d8173ce4..c9e6e7f70a 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -209,7 +209,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); - if let Some(local) = borrowed_place.base_local() { + if let mir::PlaceBase::Local(local) = borrowed_place.base { self.local_map.entry(local).or_default().insert(idx); } } @@ -315,7 +315,10 @@ impl<'a, 'tcx> GatherBorrows<'a, 'tcx> { // TEMP = &foo // // so extract `temp`. - let temp = if let &mir::Place::Base(mir::PlaceBase::Local(temp)) = assigned_place { + let temp = if let &mir::Place { + base: mir::PlaceBase::Local(temp), + projection: None, + } = assigned_place { temp } else { span_bug!( diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index b9cd1f07e8..4217a29bc6 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -2,7 +2,7 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local, - LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection, + LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, }; use rustc::ty::{self, Ty}; @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::Idx; use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; -use syntax::source_map::CompilerDesugaringKind; +use syntax::source_map::DesugaringKind; use super::nll::explain_borrow::BorrowExplanation; use super::nll::region_infer::{RegionName, RegionNameSource}; @@ -22,7 +22,7 @@ use super::{InitializationRequiringAction, PrefixSet}; use super::error_reporting::{IncludingDowncast, UseSpans}; use crate::dataflow::drop_flag_effects; use crate::dataflow::indexes::{MovePathIndex, MoveOutIndex}; -use crate::util::borrowck_errors::{BorrowckErrors, Origin}; +use crate::util::borrowck_errors; #[derive(Debug)] struct MoveSite { @@ -48,7 +48,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - (moved_place, used_place, span): (&Place<'tcx>, &Place<'tcx>, Span), + (moved_place, used_place, span): (PlaceRef<'cx, 'tcx>, PlaceRef<'cx, 'tcx>, Span), mpi: MovePathIndex, ) { debug!( @@ -72,9 +72,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .collect(); if move_out_indices.is_empty() { - let root_place = self.prefixes(&used_place, PrefixSet::All).last().unwrap(); + let root_place = self + .prefixes(used_place, PrefixSet::All) + .last() + .unwrap(); - if self.uninitialized_error_reported.contains(root_place) { + if self.uninitialized_error_reported.contains(&root_place) { debug!( "report_use_of_moved_or_uninitialized place: error about {:?} suppressed", root_place @@ -82,19 +85,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - self.uninitialized_error_reported.insert(root_place.clone()); + self.uninitialized_error_reported.insert(root_place); let item_msg = match self.describe_place_with_options(used_place, IncludingDowncast(true)) { Some(name) => format!("`{}`", name), None => "value".to_owned(), }; - let mut err = self.infcx.tcx.cannot_act_on_uninitialized_variable( + let mut err = self.cannot_act_on_uninitialized_variable( span, desired_action.as_noun(), &self.describe_place_with_options(moved_place, IncludingDowncast(true)) .unwrap_or_else(|| "_".to_owned()), - Origin::Mir, ); err.span_label(span, format!("use of possibly uninitialized {}", item_msg)); @@ -103,10 +105,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), ); + // This error should not be downgraded to a warning, + // even in migrate mode. + self.disable_error_downgrading(); err.buffer(&mut self.errors_buffer); } else { if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) { - if self.prefixes(&reported_place, PrefixSet::All) + if self.prefixes(*reported_place, PrefixSet::All) .any(|p| p == used_place) { debug!( @@ -120,12 +125,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let msg = ""; //FIXME: add "partially " or "collaterally " - let mut err = self.infcx.tcx.cannot_act_on_moved_value( + let mut err = self.cannot_act_on_moved_value( span, desired_action.as_noun(), msg, - self.describe_place_with_options(&moved_place, IncludingDowncast(true)), - Origin::Mir, + self.describe_place_with_options(moved_place, IncludingDowncast(true)), ); self.add_moved_or_invoked_closure_note( @@ -138,13 +142,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let is_partial_move = move_site_vec.iter().any(|move_site| { let move_out = self.move_data.moves[(*move_site).moi]; let moved_place = &self.move_data.move_paths[move_out.path].place; - used_place != moved_place && used_place.is_prefix_of(moved_place) + used_place != moved_place.as_ref() + && used_place.is_prefix_of(moved_place.as_ref()) }); for move_site in &move_site_vec { let move_out = self.move_data.moves[(*move_site).moi]; let moved_place = &self.move_data.move_paths[move_out.path].place; - let move_spans = self.move_spans(moved_place, move_out.source); + let move_spans = self.move_spans(moved_place.as_ref(), move_out.source); let move_span = move_spans.args_or_use(); let move_msg = if move_spans.for_closure() { @@ -174,7 +179,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("variable moved due to use{}", move_spans.describe()), ); } - if Some(CompilerDesugaringKind::ForLoop) == move_span.compiler_desugaring_kind() { + if Some(DesugaringKind::ForLoop) == move_span.desugaring_kind() { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { err.span_suggestion( move_span, @@ -202,7 +207,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - let ty = used_place.ty(self.body, self.infcx.tcx).ty; + let ty = + Place::ty_from(used_place.base, used_place.projection, self.body, self.infcx.tcx) + .ty; let needs_note = match ty.sty { ty::Closure(id, _) => { let tables = self.infcx.tcx.typeck_tables_of(id); @@ -218,7 +225,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let place = &self.move_data.move_paths[mpi].place; let ty = place.ty(self.body, self.infcx.tcx).ty; - let opt_name = self.describe_place_with_options(place, IncludingDowncast(true)); + let opt_name = + self.describe_place_with_options(place.as_ref(), IncludingDowncast(true)); let note_msg = match opt_name { Some(ref name) => format!("`{}`", name), None => "value".to_owned(), @@ -234,7 +242,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } } - let span = if let Place::Base(PlaceBase::Local(local)) = place { + let span = if let Place { + base: PlaceBase::Local(local), + projection: None, + } = place { let decl = &self.body.local_decls[*local]; Some(decl.source_info.span) } else { @@ -249,7 +260,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } if let Some((_, mut old_err)) = self.move_error_reported - .insert(move_out_indices, (used_place.clone(), err)) + .insert(move_out_indices, (used_place, err)) { // Cancel the old error so it doesn't ICE. old_err.cancel(); @@ -267,12 +278,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "report_move_out_while_borrowed: location={:?} place={:?} span={:?} borrow={:?}", location, place, span, borrow ); - let tcx = self.infcx.tcx; - let value_msg = match self.describe_place(place) { + let value_msg = match self.describe_place(place.as_ref()) { Some(name) => format!("`{}`", name), None => "value".to_owned(), }; - let borrow_msg = match self.describe_place(&borrow.borrowed_place) { + let borrow_msg = match self.describe_place(borrow.borrowed_place.as_ref()) { Some(name) => format!("`{}`", name), None => "value".to_owned(), }; @@ -280,13 +290,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); - let move_spans = self.move_spans(place, location); + let move_spans = self.move_spans(place.as_ref(), location); let span = move_spans.args_or_use(); - let mut err = tcx.cannot_move_when_borrowed( + let mut err = self.cannot_move_when_borrowed( span, - &self.describe_place(place).unwrap_or_else(|| "_".to_owned()), - Origin::Mir, + &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()), ); err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); err.span_label(span, format!("move out of {} occurs here", value_msg)); @@ -315,28 +324,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (place, _span): (&Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) -> DiagnosticBuilder<'cx> { - let tcx = self.infcx.tcx; - let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); // Conflicting borrows are reported separately, so only check for move // captures. - let use_spans = self.move_spans(place, location); + let use_spans = self.move_spans(place.as_ref(), location); let span = use_spans.var_or_use(); - let mut err = tcx.cannot_use_when_mutably_borrowed( + let mut err = self.cannot_use_when_mutably_borrowed( span, - &self.describe_place(place).unwrap_or_else(|| "_".to_owned()), + &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()), borrow_span, - &self.describe_place(&borrow.borrowed_place) + &self.describe_place(borrow.borrowed_place.as_ref()) .unwrap_or_else(|| "_".to_owned()), - Origin::Mir, ); borrow_spans.var_span_label(&mut err, { let place = &borrow.borrowed_place; - let desc_place = self.describe_place(place).unwrap_or_else(|| "_".to_owned()); + let desc_place = + self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()); format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe()) }); @@ -376,7 +383,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; // FIXME: supply non-"" `opt_via` when appropriate - let tcx = self.infcx.tcx; let first_borrow_desc; let mut err = match ( gen_borrow_kind, @@ -388,7 +394,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) { (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt) => { first_borrow_desc = "mutable "; - tcx.cannot_reborrow_already_borrowed( + self.cannot_reborrow_already_borrowed( span, &desc_place, &msg_place, @@ -398,12 +404,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { rgt, &msg_borrow, None, - Origin::Mir, ) } (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => { first_borrow_desc = "immutable "; - tcx.cannot_reborrow_already_borrowed( + self.cannot_reborrow_already_borrowed( span, &desc_place, &msg_place, @@ -413,42 +418,38 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { rgt, &msg_borrow, None, - Origin::Mir, ) } (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => { first_borrow_desc = "first "; - tcx.cannot_mutably_borrow_multiply( + self.cannot_mutably_borrow_multiply( span, &desc_place, &msg_place, issued_span, &msg_borrow, None, - Origin::Mir, ) } (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => { first_borrow_desc = "first "; - tcx.cannot_uniquely_borrow_by_two_closures( + self.cannot_uniquely_borrow_by_two_closures( span, &desc_place, issued_span, None, - Origin::Mir, ) } (BorrowKind::Mut { .. }, _, _, BorrowKind::Shallow, _, _) | (BorrowKind::Unique, _, _, BorrowKind::Shallow, _, _) => { - let mut err = tcx.cannot_mutate_in_match_guard( + let mut err = self.cannot_mutate_in_match_guard( span, issued_span, &desc_place, "mutably borrow", - Origin::Mir, ); borrow_spans.var_span_label( &mut err, @@ -462,7 +463,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (BorrowKind::Unique, _, _, _, _, _) => { first_borrow_desc = "first "; - tcx.cannot_uniquely_borrow_by_one_closure( + self.cannot_uniquely_borrow_by_one_closure( span, container_name, &desc_place, @@ -471,13 +472,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "it", "", None, - Origin::Mir, ) }, (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => { first_borrow_desc = "first "; - tcx.cannot_reborrow_already_uniquely_borrowed( + self.cannot_reborrow_already_uniquely_borrowed( span, container_name, &desc_place, @@ -487,13 +487,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "", None, second_borrow_desc, - Origin::Mir, ) } (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => { first_borrow_desc = "first "; - tcx.cannot_reborrow_already_uniquely_borrowed( + self.cannot_reborrow_already_uniquely_borrowed( span, container_name, &desc_place, @@ -503,7 +502,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "", None, second_borrow_desc, - Origin::Mir, ) } @@ -522,7 +520,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } else { let borrow_place = &issued_borrow.borrowed_place; - let borrow_place_desc = self.describe_place(borrow_place) + let borrow_place_desc = self.describe_place(borrow_place.as_ref()) .unwrap_or_else(|| "_".to_owned()); issued_spans.var_span_label( &mut err, @@ -591,8 +589,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> (String, String, String, String) { // Define a small closure that we can use to check if the type of a place // is a union. - let union_ty = |place: &Place<'tcx>| -> Option> { - let ty = place.ty(self.body, self.infcx.tcx).ty; + let union_ty = |place_base, place_projection| { + let ty = Place::ty_from(place_base, place_projection, self.body, self.infcx.tcx).ty; ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty) }; let describe_place = |place| self.describe_place(place).unwrap_or_else(|| "_".to_owned()); @@ -611,13 +609,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // field access to a union. If we find that, then we will keep the place of the // union being accessed and the field that was being accessed so we can check the // second borrowed place for the same union and a access to a different field. - let mut current = first_borrowed_place; - while let Place::Projection(box Projection { base, elem }) = current { + let Place { + base, + projection, + } = first_borrowed_place; + + let mut current = projection; + + while let Some(box Projection { base: base_proj, elem }) = current { match elem { - ProjectionElem::Field(field, _) if union_ty(base).is_some() => { - return Some((base, field)); + ProjectionElem::Field(field, _) if union_ty(base, base_proj).is_some() => { + return Some((PlaceRef { + base: base, + projection: base_proj, + }, field)); }, - _ => current = base, + _ => current = base_proj, } } None @@ -625,22 +632,36 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|(target_base, target_field)| { // With the place of a union and a field access into it, we traverse the second // borrowed place and look for a access to a different field of the same union. - let mut current = second_borrowed_place; - while let Place::Projection(box Projection { base, elem }) = current { + let Place { + base, + projection, + } = second_borrowed_place; + + let mut current = projection; + + while let Some(box Projection { base: proj_base, elem }) = current { if let ProjectionElem::Field(field, _) = elem { - if let Some(union_ty) = union_ty(base) { - if field != target_field && base == target_base { + if let Some(union_ty) = union_ty(base, proj_base) { + if field != target_field + && base == target_base.base + && proj_base == target_base.projection { + // FIXME when we avoid clone reuse describe_place closure + let describe_base_place = self.describe_place(PlaceRef { + base: base, + projection: proj_base, + }).unwrap_or_else(|| "_".to_owned()); + return Some(( - describe_place(base), - describe_place(first_borrowed_place), - describe_place(second_borrowed_place), + describe_base_place, + describe_place(first_borrowed_place.as_ref()), + describe_place(second_borrowed_place.as_ref()), union_ty.to_string(), )); } } } - current = base; + current = proj_base; } None }) @@ -648,7 +669,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If we didn't find a field access into a union, or both places match, then // only return the description of the first place. ( - describe_place(first_borrowed_place), + describe_place(first_borrowed_place.as_ref()), "".to_string(), "".to_string(), "".to_string(), @@ -679,20 +700,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); let drop_span = place_span.1; - let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All) + let root_place = self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All) .last() .unwrap(); let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.var_or_use(); - let proper_span = match *root_place { - Place::Base(PlaceBase::Local(local)) => self.body.local_decls[local].source_info.span, + assert!(root_place.projection.is_none()); + let proper_span = match root_place.base { + PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span, _ => drop_span, }; if self.access_place_error_reported - .contains(&(root_place.clone(), borrow_span)) + .contains(&(Place { + base: root_place.base.clone(), + projection: root_place.projection.clone(), + }, borrow_span)) { debug!( "suppressing access_place error when borrow doesn't live long enough for {:?}", @@ -702,16 +727,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } self.access_place_error_reported - .insert((root_place.clone(), borrow_span)); + .insert((Place { + base: root_place.base.clone(), + projection: root_place.projection.clone(), + }, borrow_span)); if let StorageDeadOrDrop::Destructor(dropped_ty) = - self.classify_drop_access_kind(&borrow.borrowed_place) + self.classify_drop_access_kind(borrow.borrowed_place.as_ref()) { // If a borrow of path `B` conflicts with drop of `D` (and // we're not in the uninteresting case where `B` is a // prefix of `D`), then report this as a more interesting // destructor conflict. - if !borrow.borrowed_place.is_prefix_of(place_span.0) { + if !borrow.borrowed_place.as_ref().is_prefix_of(place_span.0.as_ref()) { self.report_borrow_conflicts_with_destructor( location, borrow, place_span, kind, dropped_ty, ); @@ -719,7 +747,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - let place_desc = self.describe_place(&borrow.borrowed_place); + let place_desc = self.describe_place(borrow.borrowed_place.as_ref()); let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0)); let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place); @@ -833,10 +861,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - let mut err = self.infcx.tcx.path_does_not_live_long_enough( + let mut err = self.path_does_not_live_long_enough( borrow_span, &format!("`{}`", name), - Origin::Mir, ); if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { @@ -925,16 +952,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.var_or_use(); - let mut err = self.infcx - .tcx - .cannot_borrow_across_destructor(borrow_span, Origin::Mir); + let mut err = self.cannot_borrow_across_destructor(borrow_span); - let what_was_dropped = match self.describe_place(place) { + let what_was_dropped = match self.describe_place(place.as_ref()) { Some(name) => format!("`{}`", name.as_str()), None => String::from("temporary value"), }; - let label = match self.describe_place(&borrow.borrowed_place) { + let label = match self.describe_place(borrow.borrowed_place.as_ref()) { Some(borrowed) => format!( "here, drop of {D} needs exclusive access to `{B}`, \ because the type `{T}` implements the `Drop` trait", @@ -978,9 +1003,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { drop_span, borrow_span ); - let mut err = self.infcx - .tcx - .thread_local_value_does_not_live_long_enough(borrow_span, Origin::Mir); + let mut err = self.thread_local_value_does_not_live_long_enough(borrow_span); err.span_label( borrow_span, @@ -1024,8 +1047,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - let tcx = self.infcx.tcx; - let mut err = tcx.temporary_value_borrowed_for_too_long(proper_span, Origin::Mir); + let mut err = self.temporary_value_borrowed_for_too_long(proper_span); err.span_label( proper_span, "creates a temporary which is freed while still in use", @@ -1068,8 +1090,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { category: ConstraintCategory, opt_place_desc: Option<&String>, ) -> Option> { - let tcx = self.infcx.tcx; - let return_kind = match category { ConstraintCategory::Return => "return", ConstraintCategory::Yield => "yield", @@ -1085,7 +1105,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let (place_desc, note) = if let Some(place_desc) = opt_place_desc { let local_kind = match borrow.borrowed_place { - Place::Base(PlaceBase::Local(local)) => { + Place { + base: PlaceBase::Local(local), + projection: None, + } => { match self.body.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Temp => bug!("temporary or return pointer with a name"), @@ -1107,15 +1130,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("`{}` is borrowed here", place_desc), ) } else { - let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All) + let root_place = self.prefixes(borrow.borrowed_place.as_ref(), + PrefixSet::All) .last() .unwrap(); - let local = if let Place::Base(PlaceBase::Local(local)) = *root_place { + let local = if let PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } = root_place { local } else { bug!("try_report_cannot_return_reference_to_local: not a local") }; - match self.body.local_kind(local) { + match self.body.local_kind(*local) { LocalKind::ReturnPointer | LocalKind::Temp => ( "temporary value".to_string(), "temporary value created here".to_string(), @@ -1131,12 +1158,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } }; - let mut err = tcx.cannot_return_reference_to_local( + let mut err = self.cannot_return_reference_to_local( return_span, return_kind, reference_desc, &place_desc, - Origin::Mir, ); if return_span != borrow_span { @@ -1157,11 +1183,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> DiagnosticBuilder<'cx> { let tcx = self.infcx.tcx; - let mut err = tcx.cannot_capture_in_long_lived_closure( + let mut err = self.cannot_capture_in_long_lived_closure( args_span, captured_var, var_span, - Origin::Mir, ); let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) { @@ -1217,7 +1242,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "function" }; - let mut err = tcx.borrowed_data_escapes_closure(escape_span, escapes_from, Origin::Mir); + let mut err = borrowck_errors::borrowed_data_escapes_closure( + tcx, + escape_span, + escapes_from, + ); err.span_label( upvar_span, @@ -1359,14 +1388,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let loan_spans = self.retrieve_borrow_spans(loan); let loan_span = loan_spans.args_or_use(); - let tcx = self.infcx.tcx; if loan.kind == BorrowKind::Shallow { - let mut err = tcx.cannot_mutate_in_match_guard( + let mut err = self.cannot_mutate_in_match_guard( span, loan_span, - &self.describe_place(place).unwrap_or_else(|| "_".to_owned()), + &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()), "assign", - Origin::Mir, ); loan_spans.var_span_label( &mut err, @@ -1378,11 +1405,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - let mut err = tcx.cannot_assign_to_borrowed( + let mut err = self.cannot_assign_to_borrowed( span, loan_span, - &self.describe_place(place).unwrap_or_else(|| "_".to_owned()), - Origin::Mir, + &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()), ); loan_spans.var_span_label( @@ -1409,7 +1435,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { assigned_span: Span, err_place: &Place<'tcx>, ) { - let (from_arg, local_decl) = if let Place::Base(PlaceBase::Local(local)) = *err_place { + let (from_arg, local_decl) = if let Place { + base: PlaceBase::Local(local), + projection: None, + } = *err_place { if let LocalKind::Arg = self.body.local_kind(local) { (true, Some(&self.body.local_decls[local])) } else { @@ -1439,15 +1468,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { is_user_variable: None, .. }) - | None => (self.describe_place(place), assigned_span), - Some(decl) => (self.describe_place(err_place), decl.source_info.span), + | None => (self.describe_place(place.as_ref()), assigned_span), + Some(decl) => (self.describe_place(err_place.as_ref()), decl.source_info.span), }; - let mut err = self.infcx.tcx.cannot_reassign_immutable( + let mut err = self.cannot_reassign_immutable( span, place_description.as_ref().map(AsRef::as_ref).unwrap_or("_"), from_arg, - Origin::Mir, ); let msg = if from_arg { "cannot assign to immutable argument" @@ -1479,21 +1507,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.buffer(&mut self.errors_buffer); } - fn classify_drop_access_kind(&self, place: &Place<'tcx>) -> StorageDeadOrDrop<'tcx> { + fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOrDrop<'tcx> { let tcx = self.infcx.tcx; - match place { - Place::Base(PlaceBase::Local(_)) | - Place::Base(PlaceBase::Static(_)) => { + match place.projection { + None => { StorageDeadOrDrop::LocalStorageDead } - Place::Projection(box Projection { base, elem }) => { - let base_access = self.classify_drop_access_kind(base); + Some(box Projection { ref base, ref elem }) => { + let base_access = self.classify_drop_access_kind(PlaceRef { + base: place.base, + projection: base, + }); match elem { ProjectionElem::Deref => match base_access { StorageDeadOrDrop::LocalStorageDead | StorageDeadOrDrop::BoxedStorageDead => { assert!( - base.ty(self.body, tcx).ty.is_box(), + Place::ty_from(&place.base, base, self.body, tcx).ty.is_box(), "Drop of value behind a reference or raw pointer" ); StorageDeadOrDrop::BoxedStorageDead @@ -1501,7 +1531,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { StorageDeadOrDrop::Destructor(_) => base_access, }, ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => { - let base_ty = base.ty(self.body, tcx).ty; + let base_ty = Place::ty_from(&place.base, base, self.body, tcx).ty; match base_ty.sty { ty::Adt(def, _) if def.has_dtor(tcx) => { // Report the outermost adt with a destructor @@ -1568,8 +1598,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); // Check that the initial assignment of the reserve location is into a temporary. let mut target = *match reservation { - Place::Base(PlaceBase::Local(local)) - if self.body.local_kind(*local) == LocalKind::Temp => local, + Place { + base: PlaceBase::Local(local), + projection: None, + } if self.body.local_kind(*local) == LocalKind::Temp => local, _ => return None, }; @@ -1582,7 +1614,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { target, stmt ); if let StatementKind::Assign( - Place::Base(PlaceBase::Local(assigned_to)), + Place { + base: PlaceBase::Local(assigned_to), + projection: None, + }, box rvalue ) = &stmt.kind { debug!( @@ -1707,7 +1742,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { target, terminator ); if let TerminatorKind::Call { - destination: Some((Place::Base(PlaceBase::Local(assigned_to)), _)), + destination: Some((Place { + base: PlaceBase::Local(assigned_to), + projection: None, + }, _)), args, .. } = &terminator.kind diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 10c9a439bf..99899aa390 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -3,10 +3,10 @@ use rustc::hir::def::Namespace; use rustc::hir::def_id::DefId; use rustc::mir::{ AggregateKind, Constant, Field, Local, LocalKind, Location, Operand, - Place, PlaceBase, ProjectionElem, Rvalue, Statement, StatementKind, Static, - StaticKind, TerminatorKind, + Place, PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, + Static, StaticKind, Terminator, TerminatorKind, }; -use rustc::ty::{self, DefIdTree, Ty}; +use rustc::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; use rustc_errors::DiagnosticBuilder; @@ -15,6 +15,7 @@ use syntax::symbol::sym; use super::borrow_set::BorrowData; use super::{MirBorrowckCtxt}; +use crate::dataflow::move_paths::{InitLocation, LookupResult}; pub(super) struct IncludingDowncast(pub(super) bool); @@ -33,7 +34,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(super) fn add_moved_or_invoked_closure_note( &self, location: Location, - place: &Place<'tcx>, + place: PlaceRef<'cx, 'tcx>, diag: &mut DiagnosticBuilder<'_>, ) { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); @@ -120,8 +121,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// End-user visible description of `place` if one can be found. If the /// place is a temporary for instance, None will be returned. - pub(super) fn describe_place(&self, place: &Place<'tcx>) -> Option { - self.describe_place_with_options(place, IncludingDowncast(false)) + pub(super) fn describe_place(&self, place_ref: PlaceRef<'cx, 'tcx>) -> Option { + self.describe_place_with_options(place_ref, IncludingDowncast(false)) } /// End-user visible description of `place` if one can be found. If the @@ -130,7 +131,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// `Downcast` and `IncludingDowncast` is true pub(super) fn describe_place_with_options( &self, - place: &Place<'tcx>, + place: PlaceRef<'cx, 'tcx>, including_downcast: IncludingDowncast, ) -> Option { let mut buf = String::new(); @@ -143,22 +144,42 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Appends end-user visible description of `place` to `buf`. fn append_place_to_string( &self, - place: &Place<'tcx>, + place: PlaceRef<'cx, 'tcx>, buf: &mut String, mut autoderef: bool, including_downcast: &IncludingDowncast, ) -> Result<(), ()> { - match *place { - Place::Base(PlaceBase::Local(local)) => { - self.append_local_to_string(local, buf)?; + match place { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } => { + self.append_local_to_string(*local, buf)?; } - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => { + PlaceRef { + base: + PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }), + projection: None, + } => { buf.push_str("promoted"); } - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { - buf.push_str(&self.infcx.tcx.item_name(def_id).to_string()); + PlaceRef { + base: + PlaceBase::Static(box Static { + kind: StaticKind::Static(def_id), + .. + }), + projection: None, + } => { + buf.push_str(&self.infcx.tcx.item_name(*def_id).to_string()); } - Place::Projection(ref proj) => { + PlaceRef { + base, + projection: Some(ref proj), + } => { match proj.elem { ProjectionElem::Deref => { let upvar_field_projection = @@ -173,43 +194,66 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { if autoderef { + // FIXME turn this recursion into iteration self.append_place_to_string( - &proj.base, + PlaceRef { + base, + projection: &proj.base, + }, buf, autoderef, &including_downcast, )?; - } else if let Place::Base(PlaceBase::Local(local)) = proj.base { - if self.body.local_decls[local].is_ref_for_guard() { - self.append_place_to_string( - &proj.base, - buf, - autoderef, - &including_downcast, - )?; - } else { - buf.push_str(&"*"); - self.append_place_to_string( - &proj.base, - buf, - autoderef, - &including_downcast, - )?; - } } else { - buf.push_str(&"*"); - self.append_place_to_string( - &proj.base, - buf, - autoderef, - &including_downcast, - )?; + match (&proj.base, base) { + (None, PlaceBase::Local(local)) => { + if self.body.local_decls[*local].is_ref_for_guard() { + self.append_place_to_string( + PlaceRef { + base, + projection: &proj.base, + }, + buf, + autoderef, + &including_downcast, + )?; + } else { + // FIXME deduplicate this and the _ => body below + buf.push_str(&"*"); + self.append_place_to_string( + PlaceRef { + base, + projection: &proj.base, + }, + buf, + autoderef, + &including_downcast, + )?; + } + } + + _ => { + buf.push_str(&"*"); + self.append_place_to_string( + PlaceRef { + base, + projection: &proj.base, + }, + buf, + autoderef, + &including_downcast, + )?; + } + } } } } ProjectionElem::Downcast(..) => { self.append_place_to_string( - &proj.base, + PlaceRef { + base, + projection: &proj.base, + }, buf, autoderef, &including_downcast, @@ -228,9 +272,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let name = self.upvars[var_index].name.to_string(); buf.push_str(&name); } else { - let field_name = self.describe_field(&proj.base, field); + let field_name = self.describe_field(PlaceRef { + base, + projection: &proj.base, + }, field); self.append_place_to_string( - &proj.base, + PlaceRef { + base, + projection: &proj.base, + }, buf, autoderef, &including_downcast, @@ -242,7 +292,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { autoderef = true; self.append_place_to_string( - &proj.base, + PlaceRef { + base, + projection: &proj.base, + }, buf, autoderef, &including_downcast, @@ -259,7 +312,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // then use another while the borrow is held, don't output indices details // to avoid confusing the end-user self.append_place_to_string( - &proj.base, + PlaceRef { + base, + projection: &proj.base, + }, buf, autoderef, &including_downcast, @@ -287,18 +343,32 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// End-user visible description of the `field`nth field of `base` - fn describe_field(&self, base: &Place<'tcx>, field: Field) -> String { - match *base { - Place::Base(PlaceBase::Local(local)) => { - let local = &self.body.local_decls[local]; + fn describe_field(&self, place: PlaceRef<'cx, 'tcx>, field: Field) -> String { + // FIXME Place2 Make this work iteratively + match place { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } => { + let local = &self.body.local_decls[*local]; self.describe_field_from_ty(&local.ty, field, None) } - Place::Base(PlaceBase::Static(ref static_)) => + PlaceRef { + base: PlaceBase::Static(static_), + projection: None, + } => self.describe_field_from_ty(&static_.ty, field, None), - Place::Projection(ref proj) => match proj.elem { - ProjectionElem::Deref => self.describe_field(&proj.base, field), + PlaceRef { + base, + projection: Some(proj), + } => match proj.elem { + ProjectionElem::Deref => self.describe_field(PlaceRef { + base, + projection: &proj.base, + }, field), ProjectionElem::Downcast(_, variant_index) => { - let base_ty = base.ty(self.body, self.infcx.tcx).ty; + let base_ty = + Place::ty_from(place.base, place.projection, self.body, self.infcx.tcx).ty; self.describe_field_from_ty(&base_ty, field, Some(variant_index)) } ProjectionElem::Field(_, field_type) => { @@ -307,7 +377,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { - self.describe_field(&proj.base, field) + self.describe_field(PlaceRef { + base, + projection: &proj.base, + }, field) } }, } @@ -364,10 +437,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// Checks if a place is a thread-local static. - pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool { - if let Place::Base( - PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) - ) = place { + pub fn is_place_thread_local(&self, place_ref: PlaceRef<'cx, 'tcx>) -> bool { + if let PlaceRef { + base: PlaceBase::Static(box Static { + kind: StaticKind::Static(def_id), + .. + }), + projection: None, + } = place_ref { let attrs = self.infcx.tcx.get_attrs(*def_id); let is_thread_local = attrs.iter().any(|attr| attr.check_name(sym::thread_local)); @@ -401,6 +478,70 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.note(&message); } } + + pub(super) fn borrowed_content_source( + &self, + deref_base: PlaceRef<'cx, 'tcx>, + ) -> BorrowedContentSource<'tcx> { + let tcx = self.infcx.tcx; + + // Look up the provided place and work out the move path index for it, + // we'll use this to check whether it was originally from an overloaded + // operator. + match self.move_data.rev_lookup.find(deref_base) { + LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => { + debug!("borrowed_content_source: mpi={:?}", mpi); + + for i in &self.move_data.init_path_map[mpi] { + let init = &self.move_data.inits[*i]; + debug!("borrowed_content_source: init={:?}", init); + // We're only interested in statements that initialized a value, not the + // initializations from arguments. + let loc = match init.location { + InitLocation::Statement(stmt) => stmt, + _ => continue, + }; + + let bbd = &self.body[loc.block]; + let is_terminator = bbd.statements.len() == loc.statement_index; + debug!( + "borrowed_content_source: loc={:?} is_terminator={:?}", + loc, + is_terminator, + ); + if !is_terminator { + continue; + } else if let Some(Terminator { + kind: TerminatorKind::Call { + ref func, + from_hir_call: false, + .. + }, + .. + }) = bbd.terminator { + if let Some(source) + = BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx) + { + return source; + } + } + } + } + // Base is a `static` so won't be from an overloaded operator + _ => (), + }; + + // If we didn't find an overloaded deref or index, then assume it's a + // built in deref and check the type of the base. + let base_ty = Place::ty_from(deref_base.base, deref_base.projection, self.body, tcx).ty; + if base_ty.is_unsafe_ptr() { + BorrowedContentSource::DerefRawPointer + } else if base_ty.is_mutable_ptr() { + BorrowedContentSource::DerefMutableRef + } else { + BorrowedContentSource::DerefSharedRef + } + } } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { @@ -547,11 +688,95 @@ impl UseSpans { } } +pub(super) enum BorrowedContentSource<'tcx> { + DerefRawPointer, + DerefMutableRef, + DerefSharedRef, + OverloadedDeref(Ty<'tcx>), + OverloadedIndex(Ty<'tcx>), +} + +impl BorrowedContentSource<'tcx> { + pub(super) fn describe_for_unnamed_place(&self) -> String { + match *self { + BorrowedContentSource::DerefRawPointer => format!("a raw pointer"), + BorrowedContentSource::DerefSharedRef => format!("a shared reference"), + BorrowedContentSource::DerefMutableRef => { + format!("a mutable reference") + } + BorrowedContentSource::OverloadedDeref(ty) => { + if ty.is_rc() { + format!("an `Rc`") + } else if ty.is_arc() { + format!("an `Arc`") + } else { + format!("dereference of `{}`", ty) + } + } + BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty), + } + } + + pub(super) fn describe_for_named_place(&self) -> Option<&'static str> { + match *self { + BorrowedContentSource::DerefRawPointer => Some("raw pointer"), + BorrowedContentSource::DerefSharedRef => Some("shared reference"), + BorrowedContentSource::DerefMutableRef => Some("mutable reference"), + // Overloaded deref and index operators should be evaluated into a + // temporary. So we don't need a description here. + BorrowedContentSource::OverloadedDeref(_) + | BorrowedContentSource::OverloadedIndex(_) => None + } + } + + pub(super) fn describe_for_immutable_place(&self) -> String { + match *self { + BorrowedContentSource::DerefRawPointer => format!("a `*const` pointer"), + BorrowedContentSource::DerefSharedRef => format!("a `&` reference"), + BorrowedContentSource::DerefMutableRef => { + bug!("describe_for_immutable_place: DerefMutableRef isn't immutable") + }, + BorrowedContentSource::OverloadedDeref(ty) => { + if ty.is_rc() { + format!("an `Rc`") + } else if ty.is_arc() { + format!("an `Arc`") + } else { + format!("a dereference of `{}`", ty) + } + } + BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty), + } + } + + fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option { + match func.sty { + ty::FnDef(def_id, substs) => { + let trait_id = tcx.trait_of_item(def_id)?; + + let lang_items = tcx.lang_items(); + if Some(trait_id) == lang_items.deref_trait() + || Some(trait_id) == lang_items.deref_mut_trait() + { + Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0))) + } else if Some(trait_id) == lang_items.index_trait() + || Some(trait_id) == lang_items.index_mut_trait() + { + Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0))) + } else { + None + } + } + _ => None, + } + } +} + impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, - moved_place: &Place<'tcx>, // Could also be an upvar. + moved_place: PlaceRef<'cx, 'tcx>, // Could also be an upvar. location: Location, ) -> UseSpans { use self::UseSpans::*; @@ -601,7 +826,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .get(location.statement_index) { Some(&Statement { - kind: StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _), + kind: StatementKind::Assign(Place { + base: PlaceBase::Local(local), + projection: None, + }, _), .. }) => local, _ => return OtherUse(use_span), @@ -627,7 +855,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { def_id, is_generator, places ); if let Some((args_span, var_span)) = self.closure_span( - *def_id, &Place::from(target), places + *def_id, Place::from(target).as_ref(), places ) { return ClosureUse { is_generator, @@ -651,7 +879,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn closure_span( &self, def_id: DefId, - target_place: &Place<'tcx>, + target_place: PlaceRef<'cx, 'tcx>, places: &Vec>, ) -> Option<(Span, Span)> { debug!( @@ -667,7 +895,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { for (upvar, place) in self.infcx.tcx.upvars(def_id)?.values().zip(places) { match place { Operand::Copy(place) | - Operand::Move(place) if target_place == place => { + Operand::Move(place) if target_place == place.as_ref() => { debug!("closure_span: found captured local {:?}", place); return Some((*args_span, upvar.span)); }, diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs index 9a9310fbe0..bb217a1f96 100644 --- a/src/librustc_mir/borrow_check/flows.rs +++ b/src/librustc_mir/borrow_check/flows.rs @@ -3,7 +3,7 @@ //! FIXME: this might be better as a "generic" fixed-point combinator, //! but is not as ugly as it is right now. -use rustc::mir::{BasicBlock, Location}; +use rustc::mir::{BasicBlock, Local, Location}; use rustc::ty::RegionVid; use rustc_data_structures::bit_set::BitIter; @@ -15,12 +15,14 @@ use crate::dataflow::indexes::BorrowIndex; use crate::dataflow::move_paths::HasMoveData; use crate::dataflow::Borrows; use crate::dataflow::EverInitializedPlaces; -use crate::dataflow::{FlowAtLocation, FlowsAtLocation}; use crate::dataflow::MaybeUninitializedPlaces; +use crate::dataflow::{FlowAtLocation, FlowsAtLocation}; use either::Either; use std::fmt; use std::rc::Rc; +crate type PoloniusOutput = Output; + // (forced to be `pub` due to its use as an associated type below.) crate struct Flows<'b, 'tcx> { borrows: FlowAtLocation<'tcx, Borrows<'b, 'tcx>>, @@ -28,7 +30,7 @@ crate struct Flows<'b, 'tcx> { pub ever_inits: FlowAtLocation<'tcx, EverInitializedPlaces<'b, 'tcx>>, /// Polonius Output - pub polonius_output: Option>>, + pub polonius_output: Option>, } impl<'b, 'tcx> Flows<'b, 'tcx> { @@ -36,14 +38,9 @@ impl<'b, 'tcx> Flows<'b, 'tcx> { borrows: FlowAtLocation<'tcx, Borrows<'b, 'tcx>>, uninits: FlowAtLocation<'tcx, MaybeUninitializedPlaces<'b, 'tcx>>, ever_inits: FlowAtLocation<'tcx, EverInitializedPlaces<'b, 'tcx>>, - polonius_output: Option>>, + polonius_output: Option>, ) -> Self { - Flows { - borrows, - uninits, - ever_inits, - polonius_output, - } + Flows { borrows, uninits, ever_inits, polonius_output } } crate fn borrows_in_scope( diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4872440f5b..de27aec2b2 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -10,9 +10,8 @@ use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT}; use rustc::middle::borrowck::SignalledError; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{ - ClearCrossCrate, Local, Location, Body, Mutability, Operand, Place, PlaceBase, Static, - - StaticKind + ClearCrossCrate, Local, Location, Body, Mutability, Operand, Place, PlaceBase, PlaceRef, + Static, StaticKind }; use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; @@ -41,7 +40,6 @@ use crate::dataflow::MoveDataParamEnv; use crate::dataflow::{do_dataflow, DebugFormatted}; use crate::dataflow::EverInitializedPlaces; use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; -use crate::util::borrowck_errors::{BorrowckErrors, Origin}; use self::borrow_set::{BorrowData, BorrowSet}; use self::flows::Flows; @@ -87,7 +85,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> { +fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> { let input_body = tcx.mir_validated(def_id); debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id)); @@ -208,7 +206,7 @@ fn do_mir_borrowck<'a, 'tcx>( def_id, &attributes, &dead_unwinds, - Borrows::new(tcx, body, regioncx.clone(), &borrow_set), + Borrows::new(tcx, body, param_env, regioncx.clone(), &borrow_set), |rs, i| DebugFormatted::new(&rs.location(i)), )); let flow_uninits = FlowAtLocation::new(do_dataflow( @@ -244,6 +242,7 @@ fn do_mir_borrowck<'a, 'tcx>( infcx, body, mir_def_id: def_id, + param_env, move_data: &mdpe.move_data, location_table, movable_generator, @@ -254,6 +253,7 @@ fn do_mir_borrowck<'a, 'tcx>( move_error_reported: BTreeMap::new(), uninitialized_error_reported: Default::default(), errors_buffer, + disable_error_downgrading: false, nonlexical_regioncx: regioncx, used_mut: Default::default(), used_mut_upvars: SmallVec::new(), @@ -275,7 +275,7 @@ fn do_mir_borrowck<'a, 'tcx>( mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer // Convert any reservation warnings into lints. - let reservation_warnings = mem::replace(&mut mbcx.reservation_warnings, Default::default()); + let reservation_warnings = mem::take(&mut mbcx.reservation_warnings); for (_, (place, span, location, bk, borrow)) in reservation_warnings { let mut initial_diag = mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); @@ -335,7 +335,7 @@ fn do_mir_borrowck<'a, 'tcx>( } let span = local_decl.source_info.span; - if span.compiler_desugaring_kind().is_some() { + if span.desugaring_kind().is_some() { // If the `mut` arises as part of a desugaring, we should ignore it. continue; } @@ -365,7 +365,7 @@ fn do_mir_borrowck<'a, 'tcx>( if !mbcx.errors_buffer.is_empty() { mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span()); - if tcx.migrate_borrowck() { + if !mbcx.disable_error_downgrading && tcx.migrate_borrowck() { // When borrowck=migrate, check if AST-borrowck would // error on the given code. @@ -422,10 +422,11 @@ fn downgrade_if_error(diag: &mut Diagnostic) { } } -pub struct MirBorrowckCtxt<'cx, 'tcx> { - infcx: &'cx InferCtxt<'cx, 'tcx>, +crate struct MirBorrowckCtxt<'cx, 'tcx> { + crate infcx: &'cx InferCtxt<'cx, 'tcx>, body: &'cx Body<'tcx>, mir_def_id: DefId, + param_env: ty::ParamEnv<'tcx>, move_data: &'cx MoveData<'tcx>, /// Map from MIR `Location` to `LocationIndex`; created @@ -475,12 +476,15 @@ pub struct MirBorrowckCtxt<'cx, 'tcx> { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - move_error_reported: BTreeMap, (Place<'tcx>, DiagnosticBuilder<'cx>)>, + move_error_reported: BTreeMap, (PlaceRef<'cx, 'tcx>, DiagnosticBuilder<'cx>)>, /// This field keeps track of errors reported in the checking of uninitialized variables, /// so that we don't report seemingly duplicate errors. - uninitialized_error_reported: FxHashSet>, + uninitialized_error_reported: FxHashSet>, /// Errors to be reported buffer errors_buffer: Vec, + /// If there are no errors reported by the HIR borrow checker, we downgrade + /// all NLL errors to warnings. Setting this flag disables downgrading. + disable_error_downgrading: bool, /// This field keeps track of all the local variables that are declared mut and are mutated. /// Used for the warning issued by an unused mutable local variable. used_mut: FxHashSet, @@ -521,7 +525,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx fn visit_statement_entry( &mut self, location: Location, - stmt: &Statement<'tcx>, + stmt: &'cx Statement<'tcx>, flow_state: &Self::FlowState, ) { debug!( @@ -562,7 +566,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Use, - (place, span), + (place.as_ref(), span), flow_state, ); } @@ -593,7 +597,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Use, - (output, o.span), + (output.as_ref(), o.span), flow_state, ); } else { @@ -632,7 +636,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx fn visit_terminator_entry( &mut self, location: Location, - term: &Terminator<'tcx>, + term: &'cx Terminator<'tcx>, flow_state: &Self::FlowState, ) { let loc = location; @@ -735,8 +739,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx cleanup: _, } => { self.consume_operand(loc, (cond, span), flow_state); - use rustc::mir::interpret::InterpError::BoundsCheck; - if let BoundsCheck { ref len, ref index } = *msg { + use rustc::mir::interpret::PanicInfo; + if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { self.consume_operand(loc, (len, span), flow_state); self.consume_operand(loc, (index, span), flow_state); } @@ -891,7 +895,8 @@ enum InitializationRequiringAction { } struct RootPlace<'d, 'tcx> { - place: &'d Place<'tcx>, + place_base: &'d PlaceBase<'tcx>, + place_projection: &'d Option>>, is_local_mutation_allowed: LocalMutationIsAllowed, } @@ -920,6 +925,12 @@ impl InitializationRequiringAction { } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { + /// If there are no errors reported by the HIR borrow checker, we downgrade + /// all NLL errors to warnings. Calling this disables downgrading. + crate fn disable_error_downgrading(&mut self) { + self.disable_error_downgrading = true; + } + /// Checks an access to the given place to see if it is allowed. Examines the set of borrows /// that are in scope, as well as which paths have been initialized, to ensure that (a) the /// place is initialized and (b) it is not borrowed in some way that would prevent this @@ -1005,11 +1016,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut error_reported = false; let tcx = self.infcx.tcx; let body = self.body; + let param_env = self.param_env; let location_table = self.location_table.start_index(location); let borrow_set = self.borrow_set.clone(); each_borrow_involving_path( self, tcx, + param_env, body, location, (sd, place_span.0), @@ -1144,7 +1157,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn mutate_place( &mut self, location: Location, - place_span: (&Place<'tcx>, Span), + place_span: (&'cx Place<'tcx>, Span), kind: AccessDepth, mode: MutateMode, flow_state: &Flows<'cx, 'tcx>, @@ -1155,7 +1168,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Update, - place_span, + (place_span.0.as_ref(), place_span.1), flow_state, ); } @@ -1167,12 +1180,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Special case: you can assign a immutable local variable // (e.g., `x = ...`) so long as it has never been initialized // before (at this point in the flow). - if let &Place::Base(PlaceBase::Local(local)) = place_span.0 { - if let Mutability::Not = self.body.local_decls[local].mutability { + if let Place { + base: PlaceBase::Local(local), + projection: None, + } = place_span.0 { + if let Mutability::Not = self.body.local_decls[*local].mutability { // check for reassignments to immutable local variables self.check_if_reassignment_to_immutable_state( location, - local, + *local, place_span, flow_state, ); @@ -1193,7 +1209,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn consume_rvalue( &mut self, location: Location, - (rvalue, span): (&Rvalue<'tcx>, Span), + (rvalue, span): (&'cx Rvalue<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { match *rvalue { @@ -1230,7 +1246,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_path_or_subpath_is_moved( location, action, - (place, span), + (place.as_ref(), span), flow_state, ); } @@ -1258,7 +1274,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Use, - (place, span), + (place.as_ref(), span), flow_state, ); } @@ -1306,16 +1322,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) { let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| { - match *place { - Place::Projection { .. } => { - if let Some(field) = this.is_upvar_field_projection(place) { - this.used_mut_upvars.push(field); - } - } - Place::Base(PlaceBase::Local(local)) => { - this.used_mut.insert(local); + if place.projection.is_some() { + if let Some(field) = this.is_upvar_field_projection(place.as_ref()) { + this.used_mut_upvars.push(field); } - Place::Base(PlaceBase::Static(_)) => {} + } else if let PlaceBase::Local(local) = place.base { + this.used_mut.insert(local); } }; @@ -1323,11 +1335,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // captures of a closure are copied/moved directly // when generating MIR. match *operand { - Operand::Move(Place::Base(PlaceBase::Local(local))) - | Operand::Copy(Place::Base(PlaceBase::Local(local))) - if self.body.local_decls[local].is_user_variable.is_none() => - { - if self.body.local_decls[local].ty.is_mutable_pointer() { + Operand::Move(Place { + base: PlaceBase::Local(local), + projection: None, + }) | + Operand::Copy(Place { + base: PlaceBase::Local(local), + projection: None, + }) if self.body.local_decls[local].is_user_variable.is_none() => { + if self.body.local_decls[local].ty.is_mutable_ptr() { // The variable will be marked as mutable by the borrow. return; } @@ -1380,7 +1396,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn consume_operand( &mut self, location: Location, - (operand, span): (&Operand<'tcx>, Span), + (operand, span): (&'cx Operand<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { match *operand { @@ -1399,7 +1415,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Use, - (place, span), + (place.as_ref(), span), flow_state, ); } @@ -1417,7 +1433,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_path_or_subpath_is_moved( location, InitializationRequiringAction::Use, - (place, span), + (place.as_ref(), span), flow_state, ); } @@ -1435,30 +1451,35 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) { debug!("check_for_invalidation_at_exit({:?})", borrow); let place = &borrow.borrowed_place; - let root_place = self.prefixes(place, PrefixSet::All).last().unwrap(); + let root_place = self.prefixes(place.as_ref(), PrefixSet::All).last().unwrap(); // FIXME(nll-rfc#40): do more precise destructor tracking here. For now // we just know that all locals are dropped at function exit (otherwise // we'll have a memory leak) and assume that all statics have a destructor. // // FIXME: allow thread-locals to borrow other thread locals? - let (might_be_alive, will_be_dropped) = match root_place { - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => { + + assert!(root_place.projection.is_none()); + let (might_be_alive, will_be_dropped) = match root_place.base { + PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }) => { (true, false) } - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(_), .. })) => { + PlaceBase::Static(box Static { + kind: StaticKind::Static(_), + .. + }) => { // Thread-locals might be dropped after the function exits, but // "true" statics will never be. - (true, self.is_place_thread_local(&root_place)) + (true, self.is_place_thread_local(root_place)) } - Place::Base(PlaceBase::Local(_)) => { + PlaceBase::Local(_) => { // Locals are always dropped at function exit, and if they // have a destructor it would've been called already. (false, self.locals_are_invalidated_at_exit) } - Place::Projection(..) => { - bug!("root of {:?} is a projection ({:?})?", place, root_place) - } }; if !will_be_dropped { @@ -1473,6 +1494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if places_conflict::borrow_conflicts_with_place( self.infcx.tcx, + self.param_env, self.body, place, borrow.kind, @@ -1499,11 +1521,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("check_for_local_borrow({:?})", borrow); if borrow_of_local_data(&borrow.borrowed_place) { - let err = self.infcx.tcx - .cannot_borrow_across_generator_yield( + let err = self.cannot_borrow_across_generator_yield( self.retrieve_borrow_spans(borrow).var_or_use(), yield_span, - Origin::Mir, ); err.buffer(&mut self.errors_buffer); @@ -1566,7 +1586,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (&Place<'tcx>, Span), + place_span: (PlaceRef<'cx, 'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1634,7 +1654,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (&Place<'tcx>, Span), + place_span: (PlaceRef<'cx, 'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1689,25 +1709,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// An Err result includes a tag indicated why the search failed. /// Currently this can only occur if the place is built off of a /// static variable, as we do not track those in the MoveData. - fn move_path_closest_to<'a>( + fn move_path_closest_to( &mut self, - place: &'a Place<'tcx>, - ) -> Result<(&'a Place<'tcx>, MovePathIndex), NoMovePathFound> where 'cx: 'a { - let mut last_prefix = place; + place: PlaceRef<'cx, 'tcx>, + ) -> Result<(PlaceRef<'cx, 'tcx>, MovePathIndex), NoMovePathFound> { + let mut last_prefix = place.base; + for prefix in self.prefixes(place, PrefixSet::All) { if let Some(mpi) = self.move_path_for_place(prefix) { return Ok((prefix, mpi)); } - last_prefix = prefix; + + last_prefix = prefix.base; } - match *last_prefix { - Place::Base(PlaceBase::Local(_)) => panic!("should have move path for every Local"), - Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"), - Place::Base(PlaceBase::Static(_)) => Err(NoMovePathFound::ReachedStatic), + + match last_prefix { + PlaceBase::Local(_) => panic!("should have move path for every Local"), + PlaceBase::Static(_) => Err(NoMovePathFound::ReachedStatic), } } - fn move_path_for_place(&mut self, place: &Place<'tcx>) -> Option { + fn move_path_for_place(&mut self, place: PlaceRef<'cx, 'tcx>) -> Option { // If returns None, then there is no move path corresponding // to a direct owner of `place` (which means there is nothing // that borrowck tracks for its analysis). @@ -1721,94 +1743,97 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn check_if_assigned_path_is_moved( &mut self, location: Location, - (place, span): (&Place<'tcx>, Span), + (place, span): (&'cx Place<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { debug!("check_if_assigned_path_is_moved place: {:?}", place); // recur down place; dispatch to external checks when necessary - let mut place = place; - loop { - match *place { - Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => { - // assigning to `x` does not require `x` be initialized. + let mut place_projection = &place.projection; + + // None case => assigning to `x` does not require `x` be initialized. + while let Some(proj) = place_projection { + let Projection { ref base, ref elem } = **proj; + match *elem { + ProjectionElem::Index(_/*operand*/) | + ProjectionElem::ConstantIndex { .. } | + // assigning to P[i] requires P to be valid. + ProjectionElem::Downcast(_/*adt_def*/, _/*variant_idx*/) => + // assigning to (P->variant) is okay if assigning to `P` is okay + // + // FIXME: is this true even if P is a adt with a dtor? + { } + + // assigning to (*P) requires P to be initialized + ProjectionElem::Deref => { + self.check_if_full_path_is_moved( + location, InitializationRequiringAction::Use, + (PlaceRef { + base: &place.base, + projection: base, + }, span), flow_state); + // (base initialized; no need to + // recur further) break; } - Place::Projection(ref proj) => { - let Projection { ref base, ref elem } = **proj; - match *elem { - ProjectionElem::Index(_/*operand*/) | - ProjectionElem::ConstantIndex { .. } | - // assigning to P[i] requires P to be valid. - ProjectionElem::Downcast(_/*adt_def*/, _/*variant_idx*/) => - // assigning to (P->variant) is okay if assigning to `P` is okay - // - // FIXME: is this true even if P is a adt with a dtor? - { } - - // assigning to (*P) requires P to be initialized - ProjectionElem::Deref => { - self.check_if_full_path_is_moved( - location, InitializationRequiringAction::Use, - (base, span), flow_state); + + ProjectionElem::Subslice { .. } => { + panic!("we don't allow assignments to subslices, location: {:?}", + location); + } + + ProjectionElem::Field(..) => { + // if type of `P` has a dtor, then + // assigning to `P.f` requires `P` itself + // be already initialized + let tcx = self.infcx.tcx; + let base_ty = Place::ty_from(&place.base, base, self.body, tcx).ty; + match base_ty.sty { + ty::Adt(def, _) if def.has_dtor(tcx) => { + self.check_if_path_or_subpath_is_moved( + location, InitializationRequiringAction::Assignment, + (PlaceRef { + base: &place.base, + projection: base, + }, span), flow_state); + // (base initialized; no need to // recur further) break; } - ProjectionElem::Subslice { .. } => { - panic!("we don't allow assignments to subslices, location: {:?}", - location); - } - - ProjectionElem::Field(..) => { - // if type of `P` has a dtor, then - // assigning to `P.f` requires `P` itself - // be already initialized - let tcx = self.infcx.tcx; - match base.ty(self.body, tcx).ty.sty { - ty::Adt(def, _) if def.has_dtor(tcx) => { - self.check_if_path_or_subpath_is_moved( - location, InitializationRequiringAction::Assignment, - (base, span), flow_state); - - // (base initialized; no need to - // recur further) - break; - } - - - // Once `let s; s.x = V; read(s.x);`, - // is allowed, remove this match arm. - ty::Adt(..) | ty::Tuple(..) => { - check_parent_of_field(self, location, base, span, flow_state); - - if let Some(local) = place.base_local() { - // rust-lang/rust#21232, - // #54499, #54986: during - // period where we reject - // partial initialization, do - // not complain about - // unnecessary `mut` on an - // attempt to do a partial - // initialization. - self.used_mut.insert(local); - } - } - - _ => {} + // Once `let s; s.x = V; read(s.x);`, + // is allowed, remove this match arm. + ty::Adt(..) | ty::Tuple(..) => { + check_parent_of_field(self, location, PlaceRef { + base: &place.base, + projection: base, + }, span, flow_state); + + if let PlaceBase::Local(local) = place.base { + // rust-lang/rust#21232, + // #54499, #54986: during + // period where we reject + // partial initialization, do + // not complain about + // unnecessary `mut` on an + // attempt to do a partial + // initialization. + self.used_mut.insert(local); } } - } - place = base; + _ => {} + } } } + + place_projection = base; } fn check_parent_of_field<'cx, 'tcx>( this: &mut MirBorrowckCtxt<'cx, 'tcx>, location: Location, - base: &Place<'tcx>, + base: PlaceRef<'cx, 'tcx>, span: Span, flow_state: &Flows<'cx, 'tcx>, ) { @@ -1869,7 +1894,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // no move out from an earlier location) then this is an attempt at initialization // of the union - we should error in that case. let tcx = this.infcx.tcx; - if let ty::Adt(def, _) = base.ty(this.body, tcx).ty.sty { + if let ty::Adt(def, _) = + Place::ty_from(base.base, base.projection, this.body, tcx).ty.sty + { if def.is_union() { if this.move_data.path_map[mpi].iter().any(|moi| { this.move_data.moves[*moi].source.is_predecessor_of( @@ -1914,7 +1941,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // partial initialization, do not complain about mutability // errors except for actual mutation (as opposed to an attempt // to do a partial initialization). - let previously_initialized = if let Some(local) = place.base_local() { + let previously_initialized = if let PlaceBase::Local(local) = place.base { self.is_local_ever_initialized(local, flow_state).is_some() } else { true @@ -1930,7 +1957,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { BorrowKind::Mut { .. } => is_local_mutation_allowed, BorrowKind::Shared | BorrowKind::Shallow => unreachable!(), }; - match self.is_mutable(place, is_local_mutation_allowed) { + match self.is_mutable(place.as_ref(), is_local_mutation_allowed) { Ok(root_place) => { self.add_used_mut(root_place, flow_state); return false; @@ -1942,7 +1969,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => { - match self.is_mutable(place, is_local_mutation_allowed) { + match self.is_mutable(place.as_ref(), is_local_mutation_allowed) { Ok(root_place) => { self.add_used_mut(root_place, flow_state); return false; @@ -1962,8 +1989,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { | Write(wk @ WriteKind::StorageDeadOrDrop) | Write(wk @ WriteKind::MutableBorrow(BorrowKind::Shared)) | Write(wk @ WriteKind::MutableBorrow(BorrowKind::Shallow)) => { - if let (Err(_place_err), true) = ( - self.is_mutable(place, is_local_mutation_allowed), + if let (Err(place_err), true) = ( + self.is_mutable(place.as_ref(), is_local_mutation_allowed), self.errors_buffer.is_empty() ) { if self.infcx.tcx.migrate_borrowck() { @@ -1984,7 +2011,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.report_mutability_error( place, span, - _place_err, + place_err, error_access, location, ); @@ -2047,7 +2074,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn add_used_mut<'d>(&mut self, root_place: RootPlace<'d, 'tcx>, flow_state: &Flows<'cx, 'tcx>) { match root_place { RootPlace { - place: Place::Base(PlaceBase::Local(local)), + place_base: PlaceBase::Local(local), + place_projection: None, is_local_mutation_allowed, } => { // If the local may have been initialized, and it is now currently being @@ -2060,19 +2088,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } RootPlace { - place: _, + place_base: _, + place_projection: _, is_local_mutation_allowed: LocalMutationIsAllowed::Yes, } => {} RootPlace { - place: place @ Place::Projection(_), + place_base, + place_projection: place_projection @ Some(_), is_local_mutation_allowed: _, } => { - if let Some(field) = self.is_upvar_field_projection(place) { + if let Some(field) = self.is_upvar_field_projection(PlaceRef { + base: &place_base, + projection: &place_projection, + }) { self.used_mut_upvars.push(field); } } RootPlace { - place: Place::Base(PlaceBase::Static(..)), + place_base: PlaceBase::Static(..), + place_projection: None, is_local_mutation_allowed: _, } => {} } @@ -2082,51 +2116,75 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Returns the root place if the place passed in is a projection. fn is_mutable<'d>( &self, - place: &'d Place<'tcx>, + place: PlaceRef<'d, 'tcx>, is_local_mutation_allowed: LocalMutationIsAllowed, - ) -> Result, &'d Place<'tcx>> { - match *place { - Place::Base(PlaceBase::Local(local)) => { - let local = &self.body.local_decls[local]; + ) -> Result, PlaceRef<'d, 'tcx>> { + match place { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } => { + let local = &self.body.local_decls[*local]; match local.mutability { Mutability::Not => match is_local_mutation_allowed { LocalMutationIsAllowed::Yes => Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed: LocalMutationIsAllowed::Yes, }), LocalMutationIsAllowed::ExceptUpvars => Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars, }), LocalMutationIsAllowed::No => Err(place), }, Mutability::Mut => Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed, }), } } // The rules for promotion are made by `qualify_consts`, there wouldn't even be a // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this - Place::Base(PlaceBase::Static(box Static{kind: StaticKind::Promoted(_), ..})) => + PlaceRef { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }), + projection: None, + } => Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed, }), - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { - if !self.infcx.tcx.is_mutable_static(def_id) { + PlaceRef { + base: PlaceBase::Static(box Static { + kind: StaticKind::Static(def_id), + .. + }), + projection: None, + } => { + if !self.infcx.tcx.is_mutable_static(*def_id) { Err(place) } else { Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed, }) } } - Place::Projection(ref proj) => { + PlaceRef { + base: _, + projection: Some(proj), + } => { match proj.elem { ProjectionElem::Deref => { - let base_ty = proj.base.ty(self.body, self.infcx.tcx).ty; + let base_ty = + Place::ty_from(place.base, &proj.base, self.body, self.infcx.tcx).ty; // Check the kind of deref to decide match base_ty.sty { @@ -2146,7 +2204,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { _ => LocalMutationIsAllowed::Yes, }; - self.is_mutable(&proj.base, mode) + self.is_mutable(PlaceRef { + base: place.base, + projection: &proj.base, + }, mode) } } } @@ -2158,7 +2219,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // context. The users have to check by themselves. hir::MutMutable => { Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed, }) } @@ -2166,7 +2228,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } // `Box` owns its content, so mutable if its location is mutable _ if base_ty.is_box() => { - self.is_mutable(&proj.base, is_local_mutation_allowed) + self.is_mutable(PlaceRef { + base: place.base, + projection: &proj.base, + }, is_local_mutation_allowed) } // Deref should only be for reference, pointers or boxes _ => bug!("Deref of unexpected type: {:?}", base_ty), @@ -2183,7 +2248,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some(field) = upvar_field_projection { let upvar = &self.upvars[field.index()]; debug!( - "upvar.mutability={:?} local_mutation_is_allowed={:?} place={:?}", + "upvar.mutability={:?} local_mutation_is_allowed={:?} \ + place={:?}", upvar, is_local_mutation_allowed, place ); match (upvar.mutability, is_local_mutation_allowed) { @@ -2219,15 +2285,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // }); // } // ``` - let _ = self.is_mutable(&proj.base, is_local_mutation_allowed)?; + let _ = self.is_mutable(PlaceRef { + base: place.base, + projection: &proj.base, + }, is_local_mutation_allowed)?; Ok(RootPlace { - place, + place_base: place.base, + place_projection: place.projection, is_local_mutation_allowed, }) } } } else { - self.is_mutable(&proj.base, is_local_mutation_allowed) + self.is_mutable(PlaceRef { + base: place.base, + projection: &proj.base, + }, is_local_mutation_allowed) } } } @@ -2239,33 +2312,34 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// then returns the index of the field being projected. Note that this closure will always /// be `self` in the current MIR, because that is the only time we directly access the fields /// of a closure type. - pub fn is_upvar_field_projection(&self, place: &Place<'tcx>) -> Option { - let (place, by_ref) = if let Place::Projection(ref proj) = place { - if let ProjectionElem::Deref = proj.elem { - (&proj.base, true) - } else { - (place, false) - } - } else { - (place, false) - }; - - match place { - Place::Projection(ref proj) => match proj.elem { - ProjectionElem::Field(field, _ty) => { - let tcx = self.infcx.tcx; - let base_ty = proj.base.ty(self.body, tcx).ty; + pub fn is_upvar_field_projection(&self, place_ref: PlaceRef<'cx, 'tcx>) -> Option { + let mut place_projection = place_ref.projection; + let mut by_ref = false; + + if let Some(box Projection { + base, + elem: ProjectionElem::Deref, + }) = place_projection { + place_projection = &base; + by_ref = true; + } - if (base_ty.is_closure() || base_ty.is_generator()) && - (!by_ref || self.upvars[field.index()].by_ref) - { - Some(field) - } else { - None - } - }, - _ => None, + match place_projection { + Some(box Projection { + base, + elem: ProjectionElem::Field(field, _ty), + }) => { + let tcx = self.infcx.tcx; + let base_ty = Place::ty_from(place_ref.base, &base, self.body, tcx).ty; + + if (base_ty.is_closure() || base_ty.is_generator()) && + (!by_ref || self.upvars[field.index()].by_ref) { + Some(*field) + } else { + None + } } + _ => None, } } diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index d152293672..738a091b0d 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -1,7 +1,7 @@ use core::unicode::property::Pattern_White_Space; use rustc::mir::*; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty; use rustc_errors::{DiagnosticBuilder,Applicability}; use syntax_pos::Span; @@ -9,10 +9,9 @@ use crate::borrow_check::MirBorrowckCtxt; use crate::borrow_check::prefixes::PrefixSet; use crate::borrow_check::error_reporting::UseSpans; use crate::dataflow::move_paths::{ - IllegalMoveOrigin, IllegalMoveOriginKind, InitLocation, + IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex, }; -use crate::util::borrowck_errors::{BorrowckErrors, Origin}; // Often when desugaring a pattern match we may have many individual moves in // MIR that are all part of one operation from the user's point-of-view. For @@ -55,70 +54,6 @@ enum GroupedMoveError<'tcx> { }, } -enum BorrowedContentSource<'tcx> { - DerefRawPointer, - DerefMutableRef, - DerefSharedRef, - OverloadedDeref(Ty<'tcx>), - OverloadedIndex(Ty<'tcx>), -} - -impl BorrowedContentSource<'tcx> { - fn describe_for_unnamed_place(&self) -> String { - match *self { - BorrowedContentSource::DerefRawPointer => format!("a raw pointer"), - BorrowedContentSource::DerefSharedRef => format!("a shared reference"), - BorrowedContentSource::DerefMutableRef => { - format!("a mutable reference") - } - BorrowedContentSource::OverloadedDeref(ty) => { - if ty.is_rc() { - format!("an `Rc`") - } else if ty.is_arc() { - format!("an `Arc`") - } else { - format!("dereference of `{}`", ty) - } - } - BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty), - } - } - - fn describe_for_named_place(&self) -> Option<&'static str> { - match *self { - BorrowedContentSource::DerefRawPointer => Some("raw pointer"), - BorrowedContentSource::DerefSharedRef => Some("shared reference"), - BorrowedContentSource::DerefMutableRef => Some("mutable reference"), - // Overloaded deref and index operators should be evaluated into a - // temporary. So we don't need a description here. - BorrowedContentSource::OverloadedDeref(_) - | BorrowedContentSource::OverloadedIndex(_) => None - } - } - - fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option { - match func.sty { - ty::FnDef(def_id, substs) => { - let trait_id = tcx.trait_of_item(def_id)?; - - let lang_items = tcx.lang_items(); - if Some(trait_id) == lang_items.deref_trait() - || Some(trait_id) == lang_items.deref_mut_trait() - { - Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0))) - } else if Some(trait_id) == lang_items.index_trait() - || Some(trait_id) == lang_items.index_mut_trait() - { - Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0))) - } else { - None - } - } - _ => None, - } - } -} - impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { pub(crate) fn report_move_errors(&mut self, move_errors: Vec<(Place<'tcx>, MoveError<'tcx>)>) { let grouped_errors = self.group_move_errors(move_errors); @@ -156,7 +91,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // If that ever stops being the case, then the ever initialized // flow could be used. if let Some(StatementKind::Assign( - Place::Base(PlaceBase::Local(local)), + Place { + base: PlaceBase::Local(local), + projection: None, + }, box Rvalue::Use(Operand::Move(move_from)), )) = self.body.basic_blocks()[location.block] .statements @@ -193,7 +131,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - let move_spans = self.move_spans(&original_path, location); + let move_spans = self.move_spans(original_path.as_ref(), location); grouped_errors.push(GroupedMoveError::OtherIllegalMove { use_spans: move_spans, original_path, @@ -222,7 +160,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let from_simple_let = match_place.is_none(); let match_place = match_place.as_ref().unwrap_or(move_from); - match self.move_data.rev_lookup.find(match_place) { + match self.move_data.rev_lookup.find(match_place.as_ref()) { // Error with the match place LookupResult::Parent(_) => { for ge in &mut *grouped_errors { @@ -254,7 +192,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } // Error with the pattern LookupResult::Exact(_) => { - let mpi = match self.move_data.rev_lookup.find(move_from) { + let mpi = match self.move_data.rev_lookup.find(move_from.as_ref()) { LookupResult::Parent(Some(mpi)) => mpi, // move_from should be a projection from match_place. _ => unreachable!("Probably not unreachable..."), @@ -304,7 +242,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; debug!("report: original_path={:?} span={:?}, kind={:?} \ original_path.is_upvar_field_projection={:?}", original_path, span, kind, - self.is_upvar_field_projection(original_path)); + self.is_upvar_field_projection(original_path.as_ref())); ( match kind { IllegalMoveOriginKind::Static => { @@ -318,12 +256,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) } IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => { - self.infcx.tcx - .cannot_move_out_of_interior_of_drop(span, ty, Origin::Mir) + self.cannot_move_out_of_interior_of_drop(span, ty) } IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => - self.infcx.tcx.cannot_move_out_of_interior_noncopy( - span, ty, Some(*is_index), Origin::Mir + self.cannot_move_out_of_interior_noncopy( + span, ty, Some(*is_index), ), }, span, @@ -339,25 +276,26 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { place: &Place<'tcx>, span: Span ) -> DiagnosticBuilder<'a> { - let mut base_static = place; - loop { - match base_static { - Place::Base(_) => break, - Place::Projection(box Projection { base, .. }) => base_static = base, + let description = if place.projection.is_none() { + format!("static item `{}`", self.describe_place(place.as_ref()).unwrap()) + } else { + let mut base_static = &place.projection; + while let Some(box Projection { base: Some(ref proj), .. }) = base_static { + base_static = &proj.base; } - } + let base_static = PlaceRef { + base: &place.base, + projection: base_static, + }; - let description = if let Place::Base(_) = place { - format!("static item `{}`", self.describe_place(place).unwrap()) - } else { format!( "`{:?}` as `{:?}` is a static item", - self.describe_place(place).unwrap(), + self.describe_place(place.as_ref()).unwrap(), self.describe_place(base_static).unwrap(), ) }; - self.infcx.tcx.cannot_move_out_of(span, &description, Origin::Mir) + self.cannot_move_out_of(span, &description) } fn report_cannot_move_from_borrowed_content( @@ -366,27 +304,30 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { deref_target_place: &Place<'tcx>, span: Span, ) -> DiagnosticBuilder<'a> { - let origin = Origin::Mir; - // Inspect the type of the content behind the // borrow to provide feedback about why this // was a move rather than a copy. let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty; - let upvar_field = self.prefixes(&move_place, PrefixSet::All) + let upvar_field = self.prefixes(move_place.as_ref(), PrefixSet::All) .find_map(|p| self.is_upvar_field_projection(p)); - let deref_base = match deref_target_place { - Place::Projection(box Projection { base, elem: ProjectionElem::Deref }) => base, + let deref_base = match deref_target_place.projection { + Some(box Projection { ref base, elem: ProjectionElem::Deref }) => PlaceRef { + base: &deref_target_place.base, + projection: base, + }, _ => bug!("deref_target_place is not a deref projection"), }; - if let Place::Base(PlaceBase::Local(local)) = *deref_base { - let decl = &self.body.local_decls[local]; + if let PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } = deref_base { + let decl = &self.body.local_decls[*local]; if decl.is_ref_for_guard() { - let mut err = self.infcx.tcx.cannot_move_out_of( + let mut err = self.cannot_move_out_of( span, &format!("`{}` in pattern guard", decl.name.unwrap()), - origin, ); err.note( "variables bound in patterns cannot be moved from \ @@ -398,9 +339,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report: ty={:?}", ty); let mut err = match ty.sty { ty::Array(..) | ty::Slice(..) => - self.infcx.tcx.cannot_move_out_of_interior_noncopy( - span, ty, None, origin - ), + self.cannot_move_out_of_interior_noncopy(span, ty, None), ty::Closure(def_id, closure_substs) if def_id == self.mir_def_id && upvar_field.is_some() => { @@ -424,9 +363,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar_name = upvar.name; let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id); - let place_name = self.describe_place(move_place).unwrap(); + let place_name = self.describe_place(move_place.as_ref()).unwrap(); - let place_description = if self.is_upvar_field_projection(move_place).is_some() { + let place_description = if self + .is_upvar_field_projection(move_place.as_ref()) + .is_some() + { format!("`{}`, a {}", place_name, capture_description) } else { format!( @@ -442,7 +384,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { closure_kind_ty, closure_kind, place_description, ); - let mut diag = self.infcx.tcx.cannot_move_out_of(span, &place_description, origin); + let mut diag = self.cannot_move_out_of(span, &place_description); diag.span_label(upvar_span, "captured outer variable"); @@ -450,19 +392,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } _ => { let source = self.borrowed_content_source(deref_base); - match (self.describe_place(move_place), source.describe_for_named_place()) { + match ( + self.describe_place(move_place.as_ref()), + source.describe_for_named_place(), + ) { (Some(place_desc), Some(source_desc)) => { - self.infcx.tcx.cannot_move_out_of( + self.cannot_move_out_of( span, &format!("`{}` which is behind a {}", place_desc, source_desc), - origin, ) } (_, _) => { - self.infcx.tcx.cannot_move_out_of( + self.cannot_move_out_of( span, &source.describe_for_unnamed_place(), - origin, ) } } @@ -512,7 +455,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if binds_to.is_empty() { let place_ty = move_from.ty(self.body, self.infcx.tcx).ty; - let place_desc = match self.describe_place(&move_from) { + let place_desc = match self.describe_place(move_from.as_ref()) { Some(desc) => format!("`{}`", desc), None => format!("value"), }; @@ -540,7 +483,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => { let span = use_spans.var_or_use(); let place_ty = original_path.ty(self.body, self.infcx.tcx).ty; - let place_desc = match self.describe_place(original_path) { + let place_desc = match self.describe_place(original_path.as_ref()) { Some(desc) => format!("`{}`", desc), None => format!("value"), }; @@ -646,65 +589,4 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } } - - fn borrowed_content_source(&self, deref_base: &Place<'tcx>) -> BorrowedContentSource<'tcx> { - let tcx = self.infcx.tcx; - - // Look up the provided place and work out the move path index for it, - // we'll use this to check whether it was originally from an overloaded - // operator. - match self.move_data.rev_lookup.find(deref_base) { - LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => { - debug!("borrowed_content_source: mpi={:?}", mpi); - - for i in &self.move_data.init_path_map[mpi] { - let init = &self.move_data.inits[*i]; - debug!("borrowed_content_source: init={:?}", init); - // We're only interested in statements that initialized a value, not the - // initializations from arguments. - let loc = match init.location { - InitLocation::Statement(stmt) => stmt, - _ => continue, - }; - - let bbd = &self.body[loc.block]; - let is_terminator = bbd.statements.len() == loc.statement_index; - debug!( - "borrowed_content_source: loc={:?} is_terminator={:?}", - loc, - is_terminator, - ); - if !is_terminator { - continue; - } else if let Some(Terminator { - kind: TerminatorKind::Call { - ref func, - from_hir_call: false, - .. - }, - .. - }) = bbd.terminator { - if let Some(source) - = BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx) - { - return source; - } - } - } - } - // Base is a `static` so won't be from an overloaded operator - _ => (), - }; - - // If we didn't find an overloaded deref or index, then assume it's a - // built in deref and check the type of the base. - let base_ty = deref_base.ty(self.body, tcx).ty; - if base_ty.is_unsafe_ptr() { - BorrowedContentSource::DerefRawPointer - } else if base_ty.is_mutable_pointer() { - BorrowedContentSource::DerefMutableRef - } else { - BorrowedContentSource::DerefSharedRef - } - } } diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 92c2e4e01f..937c6383be 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -1,20 +1,18 @@ +use core::unicode::property::Pattern_White_Space; use rustc::hir; use rustc::hir::Node; -use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Body}; +use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body}; use rustc::mir::{ - Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind, + Mutability, Place, PlaceRef, PlaceBase, Projection, ProjectionElem, Static, StaticKind }; -use rustc::mir::{Terminator, TerminatorKind}; -use rustc::ty::{self, Const, DefIdTree, Ty, TyS, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; use syntax_pos::symbol::kw; -use crate::dataflow::move_paths::InitLocation; use crate::borrow_check::MirBorrowckCtxt; -use crate::util::borrowck_errors::{BorrowckErrors, Origin}; +use crate::borrow_check::error_reporting::BorrowedContentSource; use crate::util::collect_writes::FindAssignments; -use crate::util::suggest_ref_mut; use rustc_errors::Applicability; #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -29,7 +27,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { &mut self, access_place: &Place<'tcx>, span: Span, - the_place_err: &Place<'tcx>, + the_place_err: PlaceRef<'cx, 'tcx>, error_access: AccessKind, location: Location, ) { @@ -43,13 +41,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mut err; let item_msg; let reason; - let access_place_desc = self.describe_place(access_place); + let mut opt_source = None; + let access_place_desc = self.describe_place(access_place.as_ref()); debug!("report_mutability_error: access_place_desc={:?}", access_place_desc); match the_place_err { - Place::Base(PlaceBase::Local(local)) => { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } => { item_msg = format!("`{}`", access_place_desc.unwrap()); - if let Place::Base(PlaceBase::Local(_)) = access_place { + if let Place { + base: PlaceBase::Local(_), + projection: None, + } = access_place { reason = ", as it is not declared as mutable".to_string(); } else { let name = self.body.local_decls[*local] @@ -59,16 +64,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - Place::Projection(box Projection { - base, - elem: ProjectionElem::Field(upvar_index, _), - }) => { + PlaceRef { + base: _, + projection: + Some(box Projection { + base, + elem: ProjectionElem::Field(upvar_index, _), + }), + } => { debug_assert!(is_closure_or_generator( - base.ty(self.body, self.infcx.tcx).ty + Place::ty_from(&the_place_err.base, &base, self.body, self.infcx.tcx).ty )); item_msg = format!("`{}`", access_place_desc.unwrap()); - if self.is_upvar_field_projection(access_place).is_some() { + if self.is_upvar_field_projection(access_place.as_ref()).is_some() { reason = ", as it is not declared as mutable".to_string(); } else { let name = self.upvars[upvar_index.index()].name; @@ -76,26 +85,38 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - Place::Projection(box Projection { - base, - elem: ProjectionElem::Deref, - }) => { - if *base == Place::Base(PlaceBase::Local(Local::new(1))) && + PlaceRef { + base: _, + projection: + Some(box Projection { + base, + elem: ProjectionElem::Deref, + }), + } => { + if the_place_err.base == &PlaceBase::Local(Local::new(1)) && + base.is_none() && !self.upvars.is_empty() { item_msg = format!("`{}`", access_place_desc.unwrap()); debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr()); debug_assert!(is_closure_or_generator( - the_place_err.ty(self.body, self.infcx.tcx).ty + Place::ty_from( + the_place_err.base, + the_place_err.projection, + self.body, + self.infcx.tcx + ) + .ty )); - reason = if self.is_upvar_field_projection(access_place).is_some() { - ", as it is a captured variable in a `Fn` closure".to_string() - } else { - ", as `Fn` closures cannot mutate their captured variables".to_string() - } + reason = + if self.is_upvar_field_projection(access_place.as_ref()).is_some() { + ", as it is a captured variable in a `Fn` closure".to_string() + } else { + ", as `Fn` closures cannot mutate their captured variables".to_string() + } } else if { - if let Place::Base(PlaceBase::Local(local)) = *base { - self.body.local_decls[local].is_ref_for_guard() + if let (PlaceBase::Local(local), None) = (&the_place_err.base, base) { + self.body.local_decls[*local].is_ref_for_guard() } else { false } @@ -103,33 +124,49 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { item_msg = format!("`{}`", access_place_desc.unwrap()); reason = ", as it is immutable for the pattern guard".to_string(); } else { - let pointer_type = - if base.ty(self.body, self.infcx.tcx).ty.is_region_ptr() { - "`&` reference" - } else { - "`*const` pointer" - }; + let source = self.borrowed_content_source(PlaceRef { + base: the_place_err.base, + projection: base, + }); + let pointer_type = source.describe_for_immutable_place(); + opt_source = Some(source); if let Some(desc) = access_place_desc { item_msg = format!("`{}`", desc); reason = match error_access { AccessKind::Move | - AccessKind::Mutate => format!(" which is behind a {}", pointer_type), + AccessKind::Mutate => format!(" which is behind {}", pointer_type), AccessKind::MutableBorrow => { - format!(", as it is behind a {}", pointer_type) + format!(", as it is behind {}", pointer_type) } } } else { - item_msg = format!("data in a {}", pointer_type); + item_msg = format!("data in {}", pointer_type); reason = String::new(); } } } - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => - unreachable!(), + PlaceRef { + base: + PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }), + projection: None, + } => unreachable!(), - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })) => { - if let Place::Base(PlaceBase::Static(_)) = access_place { + PlaceRef { + base: + PlaceBase::Static(box Static { + kind: StaticKind::Static(def_id), + .. + }), + projection: None, + } => { + if let Place { + base: PlaceBase::Static(_), + projection: None, + } = access_place { item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); reason = String::new(); } else { @@ -139,22 +176,36 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - Place::Projection(box Projection { + PlaceRef { base: _, - elem: ProjectionElem::Index(_), - }) - | Place::Projection(box Projection { + projection: + Some(box Projection { + base: _, + elem: ProjectionElem::Index(_), + }), + } + | PlaceRef { base: _, - elem: ProjectionElem::ConstantIndex { .. }, - }) - | Place::Projection(box Projection { + projection: + Some(box Projection { + base: _, + elem: ProjectionElem::ConstantIndex { .. }, + }), + } + | PlaceRef { base: _, - elem: ProjectionElem::Subslice { .. }, - }) - | Place::Projection(box Projection { + projection: Some(box Projection { + base: _, + elem: ProjectionElem::Subslice { .. }, + }), + } + | PlaceRef { base: _, - elem: ProjectionElem::Downcast(..), - }) => bug!("Unexpected immutable place."), + projection: Some(box Projection { + base: _, + elem: ProjectionElem::Downcast(..), + }), + } => bug!("Unexpected immutable place."), } debug!("report_mutability_error: item_msg={:?}, reason={:?}", item_msg, reason); @@ -166,15 +217,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let span = match error_access { AccessKind::Move => { - err = self.infcx.tcx - .cannot_move_out_of(span, &(item_msg + &reason), Origin::Mir); + err = self.cannot_move_out_of(span, &(item_msg + &reason)); err.span_label(span, "cannot move"); err.buffer(&mut self.errors_buffer); return; } AccessKind::Mutate => { - err = self.infcx.tcx - .cannot_assign(span, &(item_msg + &reason), Origin::Mir); + err = self.cannot_assign(span, &(item_msg + &reason)); act = "assign"; acted_on = "written"; span @@ -185,18 +234,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let borrow_spans = self.borrow_spans(span, location); let borrow_span = borrow_spans.args_or_use(); - err = self.infcx.tcx.cannot_borrow_path_as_mutable_because( + err = self.cannot_borrow_path_as_mutable_because( borrow_span, &item_msg, &reason, - Origin::Mir, ); borrow_spans.var_span_label( &mut err, format!( "mutable borrow occurs due to use of `{}` in closure", // always Some() if the message is printed. - self.describe_place(access_place).unwrap_or_default(), + self.describe_place(access_place.as_ref()).unwrap_or_default(), ) ); borrow_span @@ -212,21 +260,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // something like `*((*_1).0`. The local that we get will be a reference to the // struct we've got a field access of (it must be a reference since there's a deref // after the field access). - Place::Projection(box Projection { - base: Place::Projection(box Projection { - base: Place::Projection(box Projection { - base, - elem: ProjectionElem::Deref, + PlaceRef { + base, + projection: Some(box Projection { + base: Some(box Projection { + base: Some(box Projection { + base: base_proj, + elem: ProjectionElem::Deref, + }), + elem: ProjectionElem::Field(field, _), }), - elem: ProjectionElem::Field(field, _), + elem: ProjectionElem::Deref, }), - elem: ProjectionElem::Deref, - }) => { + } => { err.span_label(span, format!("cannot {ACT}", ACT = act)); if let Some((span, message)) = annotate_struct_field( self.infcx.tcx, - base.ty(self.body, self.infcx.tcx).ty, + Place::ty_from(&base, &base_proj, self.body, self.infcx.tcx).ty, field, ) { err.span_suggestion( @@ -239,43 +290,46 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, // Suggest removing a `&mut` from the use of a mutable reference. - Place::Base(PlaceBase::Local(local)) - if { - self.body.local_decls.get(*local).map(|local_decl| { - if let ClearCrossCrate::Set( - mir::BindingForm::ImplicitSelf(kind) - ) = local_decl.is_user_variable.as_ref().unwrap() { - // Check if the user variable is a `&mut self` and we can therefore - // suggest removing the `&mut`. - // - // Deliberately fall into this case for all implicit self types, - // so that we don't fall in to the next case with them. - *kind == mir::ImplicitSelfKind::MutRef - } else if Some(kw::SelfLower) == local_decl.name { - // Otherwise, check if the name is the self kewyord - in which case - // we have an explicit self. Do the same thing in this case and check - // for a `self: &mut Self` to suggest removing the `&mut`. - if let ty::Ref( - _, _, hir::Mutability::MutMutable - ) = local_decl.ty.sty { - true - } else { - false - } + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } if { + self.body.local_decls.get(*local).map(|local_decl| { + if let ClearCrossCrate::Set( + mir::BindingForm::ImplicitSelf(kind) + ) = local_decl.is_user_variable.as_ref().unwrap() { + // Check if the user variable is a `&mut self` and we can therefore + // suggest removing the `&mut`. + // + // Deliberately fall into this case for all implicit self types, + // so that we don't fall in to the next case with them. + *kind == mir::ImplicitSelfKind::MutRef + } else if Some(kw::SelfLower) == local_decl.name { + // Otherwise, check if the name is the self kewyord - in which case + // we have an explicit self. Do the same thing in this case and check + // for a `self: &mut Self` to suggest removing the `&mut`. + if let ty::Ref( + _, _, hir::Mutability::MutMutable + ) = local_decl.ty.sty { + true } else { false } - }).unwrap_or(false) - } => - { + } else { + false + } + }).unwrap_or(false) + } => { err.span_label(span, format!("cannot {ACT}", ACT = act)); err.span_label(span, "try removing `&mut` here"); }, // We want to suggest users use `let mut` for local (user // variable) mutations... - Place::Base(PlaceBase::Local(local)) - if self.body.local_decls[*local].can_be_made_mutable() => { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } if self.body.local_decls[*local].can_be_made_mutable() => { // ... but it doesn't make sense to suggest it on // variables that are `ref x`, `ref mut x`, `&self`, // or `&mut self` (such variables are simply not @@ -293,12 +347,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } // Also suggest adding mut for upvars - Place::Projection(box Projection { + PlaceRef { base, - elem: ProjectionElem::Field(upvar_index, _), - }) => { + projection: Some(box Projection { + base: proj_base, + elem: ProjectionElem::Field(upvar_index, _), + }), + } => { debug_assert!(is_closure_or_generator( - base.ty(self.body, self.infcx.tcx).ty + Place::ty_from(&base, &proj_base, self.body, self.infcx.tcx).ty )); err.span_label(span, format!("cannot {ACT}", ACT = act)); @@ -326,8 +383,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // complete hack to approximate old AST-borrowck // diagnostic: if the span starts with a mutable borrow of // a local variable, then just suggest the user remove it. - Place::Base(PlaceBase::Local(_)) - if { + PlaceRef { + base: PlaceBase::Local(_), + projection: None, + } if { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { snippet.starts_with("&mut ") } else { @@ -339,10 +398,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_label(span, "try removing `&mut` here"); } - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(local)), - elem: ProjectionElem::Deref, - }) if { + PlaceRef { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + } if { if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) = self.body.local_decls[*local].is_user_variable { @@ -363,10 +425,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // // FIXME: can this case be generalized to work for an // arbitrary base for the projection? - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(local)), - elem: ProjectionElem::Deref, - }) if self.body.local_decls[*local].is_user_variable.is_some() => + PlaceRef { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + } if self.body.local_decls[*local].is_user_variable.is_some() => { let local_decl = &self.body.local_decls[*local]; let suggestion = match local_decl.is_user_variable.as_ref().unwrap() { @@ -443,10 +508,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - Place::Projection(box Projection { + PlaceRef { base, - elem: ProjectionElem::Deref, - }) if *base == Place::Base(PlaceBase::Local(Local::new(1))) && + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + // FIXME document what is this 1 magic number about + } if *base == PlaceBase::Local(Local::new(1)) && !self.upvars.is_empty() => { err.span_label(span, format!("cannot {ACT}", ACT = act)); @@ -456,60 +525,35 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(local)), - elem: ProjectionElem::Deref, - }) if error_access == AccessKind::MutableBorrow => { + PlaceRef { + base: _, + projection: Some(box Projection { + base: _, + elem: ProjectionElem::Deref, + }), + } => { err.span_label(span, format!("cannot {ACT}", ACT = act)); - let mpi = self.move_data.rev_lookup.find_local(*local); - for i in self.move_data.init_path_map[mpi].iter() { - if let InitLocation::Statement(location) = self.move_data.inits[*i].location { - if let Some( - Terminator { - kind: TerminatorKind::Call { - func: Operand::Constant(box Constant { - literal: Const { - ty: &TyS { - sty: ty::FnDef(id, substs), - .. - }, - .. - }, - .. - }), - .. - }, - .. - } - ) = &self.body.basic_blocks()[location.block].terminator { - let index_trait = self.infcx.tcx.lang_items().index_trait(); - if self.infcx.tcx.parent(id) == index_trait { - let mut found = false; - self.infcx.tcx.for_each_relevant_impl( - self.infcx.tcx.lang_items().index_mut_trait().unwrap(), - substs.type_at(0), - |_relevant_impl| { - found = true; - } - ); - - let extra = if found { - String::new() - } else { - format!(", but it is not implemented for `{}`", - substs.type_at(0)) - }; - - err.help( - &format!( - "trait `IndexMut` is required to modify indexed content{}", - extra, - ), - ); - } - } + match opt_source { + Some(BorrowedContentSource::OverloadedDeref(ty)) => { + err.help( + &format!( + "trait `DerefMut` is required to modify through a dereference, \ + but it is not implemented for `{}`", + ty, + ), + ); + }, + Some(BorrowedContentSource::OverloadedIndex(ty)) => { + err.help( + &format!( + "trait `IndexMut` is required to modify indexed content, \ + but it is not implemented for `{}`", + ty, + ), + ); } + _ => (), } } @@ -665,3 +709,16 @@ fn annotate_struct_field( None } + +/// If possible, suggest replacing `ref` with `ref mut`. +fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<(String)> { + let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).unwrap(); + if hi_src.starts_with("ref") + && hi_src["ref".len()..].starts_with(Pattern_White_Space) + { + let replacement = format!("ref mut{}", &hi_src["ref".len()..]); + Some(replacement) + } else { + None + } +} diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 058cdec5ce..5c230913a0 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -3,18 +3,22 @@ use crate::borrow_check::location::LocationTable; use crate::borrow_check::nll::ToRegionVid; use crate::borrow_check::nll::facts::AllFacts; use crate::borrow_check::nll::region_infer::values::LivenessValues; +use crate::borrow_check::places_conflict; use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; -use rustc::mir::{BasicBlock, BasicBlockData, Location, Body, Place, PlaceBase, Rvalue}; -use rustc::mir::{SourceInfo, Statement, Terminator}; -use rustc::mir::UserTypeProjection; +use rustc::mir::{ + BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceBase, Projection, + ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, + UserTypeProjection, +}; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty}; use rustc::ty::subst::SubstsRef; pub(super) fn generate_constraints<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, liveness_constraints: &mut LivenessValues, all_facts: &mut Option, location_table: &LocationTable, @@ -27,6 +31,8 @@ pub(super) fn generate_constraints<'cx, 'tcx>( liveness_constraints, location_table, all_facts, + body, + param_env, }; for (bb, data) in body.basic_blocks().iter_enumerated() { @@ -37,10 +43,12 @@ pub(super) fn generate_constraints<'cx, 'tcx>( /// 'cg = the duration of the constraint generation process itself. struct ConstraintGeneration<'cg, 'cx, 'tcx> { infcx: &'cg InferCtxt<'cx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, all_facts: &'cg mut Option, location_table: &'cg LocationTable, liveness_constraints: &'cg mut LivenessValues, borrow_set: &'cg BorrowSet<'tcx>, + body: &'cg Body<'tcx>, } impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { @@ -114,6 +122,17 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { self.location_table .start_index(location.successor_within_block()), )); + + // If there are borrows on this now dead local, we need to record them as `killed`. + if let StatementKind::StorageDead(ref local) = statement.kind { + record_killed_borrows_for_local( + all_facts, + self.borrow_set, + self.location_table, + local, + location, + ); + } } self.super_statement(statement, location); @@ -127,17 +146,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { ) { // When we see `X = ...`, then kill borrows of // `(*X).foo` and so forth. - if let Some(all_facts) = self.all_facts { - if let Place::Base(PlaceBase::Local(temp)) = place { - if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) { - all_facts.killed.reserve(borrow_indices.len()); - for &borrow_index in borrow_indices { - let location_index = self.location_table.mid_index(location); - all_facts.killed.push((borrow_index, location_index)); - } - } - } - } + self.record_killed_borrows_for_place(place, location); self.super_assign(place, rvalue, location); } @@ -164,6 +173,14 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { } } + // A `Call` terminator's return value can be a local which has borrows, + // so we need to record those as `killed` as well. + if let TerminatorKind::Call { ref destination, .. } = terminator.kind { + if let Some((place, _)) = destination { + self.record_killed_borrows_for_place(place, location); + } + } + self.super_terminator(terminator, location); } @@ -198,4 +215,97 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { self.liveness_constraints.add_element(vid, location); }); } + + /// When recording facts for Polonius, records the borrows on the specified place + /// as `killed`. For example, when assigning to a local, or on a call's return destination. + fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) { + if let Some(all_facts) = self.all_facts { + // Depending on the `Place` we're killing: + // - if it's a local, or a single deref of a local, + // we kill all the borrows on the local. + // - if it's a deeper projection, we have to filter which + // of the borrows are killed: the ones whose `borrowed_place` + // conflicts with the `place`. + match place { + Place { + base: PlaceBase::Local(local), + projection: None, + } | + Place { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }), + } => { + debug!( + "Recording `killed` facts for borrows of local={:?} at location={:?}", + local, location + ); + + record_killed_borrows_for_local( + all_facts, + self.borrow_set, + self.location_table, + local, + location, + ); + } + + Place { + base: PlaceBase::Static(_), + .. + } => { + // Ignore kills of static or static mut variables. + } + + Place { + base: PlaceBase::Local(local), + projection: Some(_), + } => { + // Kill conflicting borrows of the innermost local. + debug!( + "Recording `killed` facts for borrows of \ + innermost projected local={:?} at location={:?}", + local, location + ); + + if let Some(borrow_indices) = self.borrow_set.local_map.get(local) { + for &borrow_index in borrow_indices { + let places_conflict = places_conflict::places_conflict( + self.infcx.tcx, + self.param_env, + self.body, + &self.borrow_set.borrows[borrow_index].borrowed_place, + place, + places_conflict::PlaceConflictBias::NoOverlap, + ); + + if places_conflict { + let location_index = self.location_table.mid_index(location); + all_facts.killed.push((borrow_index, location_index)); + } + } + } + } + } + } + } +} + +/// When recording facts for Polonius, records the borrows on the specified local as `killed`. +fn record_killed_borrows_for_local( + all_facts: &mut AllFacts, + borrow_set: &BorrowSet<'_>, + location_table: &LocationTable, + local: &Local, + location: Location, +) { + if let Some(borrow_indices) = borrow_set.local_map.get(local) { + all_facts.killed.reserve(borrow_indices.len()); + for &borrow_index in borrow_indices { + let location_index = location_table.mid_index(location); + all_facts.killed.push((borrow_index, location_index)); + } + } } diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs index 1d9e6064c4..b5630251e5 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs @@ -234,10 +234,10 @@ impl<'s, D: ConstraintGraphDirecton> graph::WithNumNodes for RegionGraph<'s, D> } impl<'s, D: ConstraintGraphDirecton> graph::WithSuccessors for RegionGraph<'s, D> { - fn successors<'graph>( - &'graph self, + fn successors( + &self, node: Self::Node, - ) -> >::Iter { + ) -> >::Iter { self.outgoing_regions(node) } } diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index ed88b16253..aba3ef1cbb 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -7,7 +7,7 @@ use crate::borrow_check::nll::ConstraintDescription; use crate::borrow_check::{MirBorrowckCtxt, WriteKind}; use rustc::mir::{ CastKind, ConstraintCategory, FakeReadCause, Local, Location, Body, Operand, Place, PlaceBase, - Projection, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, + Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc::ty::{self, TyCtxt}; use rustc::ty::adjustment::{PointerCast}; @@ -252,7 +252,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(Cause::LiveVar(local, location)) => { let span = body.source_info(location).span; let spans = self - .move_spans(&Place::from(local), location) + .move_spans(Place::from(local).as_ref(), location) .or_else(|| self.borrow_spans(span, location)); let borrow_location = location; @@ -272,7 +272,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut should_note_order = false; if body.local_decls[local].name.is_some() { if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place { - if let Place::Base(PlaceBase::Local(borrowed_local)) = place { + if let Place { + base: PlaceBase::Local(borrowed_local), + projection: None, + } = place { if body.local_decls[*borrowed_local].name.is_some() && local != *borrowed_local { @@ -301,7 +304,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { region, ); if let Some(region_name) = region_name { - let opt_place_desc = self.describe_place(&borrow.borrowed_place); + let opt_place_desc = + self.describe_place(borrow.borrowed_place.as_ref()); BorrowExplanation::MustBeValidFor { category, from_closure, @@ -489,8 +493,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Just point to the function, to reduce the chance of overlapping spans. let function_span = match func { Operand::Constant(c) => c.span, - Operand::Copy(Place::Base(PlaceBase::Local(l))) | - Operand::Move(Place::Base(PlaceBase::Local(l))) => { + Operand::Copy(Place { + base: PlaceBase::Local(l), + projection: None, + }) | + Operand::Move(Place { + base: PlaceBase::Local(l), + projection: None, + }) => { let local_decl = &self.body.local_decls[*l]; if local_decl.name.is_none() { local_decl.source_info.span @@ -531,7 +541,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // it which simplifies the termination logic. let mut queue = vec![location]; let mut target = if let Some(&Statement { - kind: StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _), + kind: StatementKind::Assign(Place { + base: PlaceBase::Local(local), + projection: None, + }, _), .. }) = stmt { @@ -555,13 +568,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // The only kind of statement that we care about is assignments... if let StatementKind::Assign(place, box rvalue) = &stmt.kind { - let into = match place { - Place::Base(PlaceBase::Local(into)) => into, - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(into)), - elem: ProjectionElem::Deref, - }) => into, - _ => { + let into = match place.local_or_deref_local() { + Some(into) => into, + None => { // Continue at the next location. queue.push(current_location.successor_within_block()); continue; @@ -572,11 +581,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If we see a use, we should check whether it is our data, and if so // update the place that we're looking for to that new place. Rvalue::Use(operand) => match operand { - Operand::Copy(Place::Base(PlaceBase::Local(from))) - | Operand::Move(Place::Base(PlaceBase::Local(from))) + Operand::Copy(Place { + base: PlaceBase::Local(from), + projection: None, + }) + | Operand::Move(Place { + base: PlaceBase::Local(from), + projection: None, + }) if *from == target => { - target = *into; + target = into; } _ => {} }, @@ -585,8 +600,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Rvalue::Cast( CastKind::Pointer(PointerCast::Unsize), operand, ty ) => match operand { - Operand::Copy(Place::Base(PlaceBase::Local(from))) - | Operand::Move(Place::Base(PlaceBase::Local(from))) + Operand::Copy(Place { + base: PlaceBase::Local(from), + projection: None, + }) + | Operand::Move(Place { + base: PlaceBase::Local(from), + projection: None, + }) if *from == target => { debug!("was_captured_by_trait_object: ty={:?}", ty); @@ -616,7 +637,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("was_captured_by_trait_object: terminator={:?}", terminator); if let TerminatorKind::Call { - destination: Some((Place::Base(PlaceBase::Local(dest)), block)), + destination: Some((Place { + base: PlaceBase::Local(dest), + projection: None, + }, block)), args, .. } = &terminator.kind @@ -627,7 +651,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); // Check if one of the arguments to this function is the target place. let found_target = args.iter().any(|arg| { - if let Operand::Move(Place::Base(PlaceBase::Local(potential))) = arg { + if let Operand::Move(Place { + base: PlaceBase::Local(potential), + projection: None, + }) = arg { *potential == target } else { false diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs index d84afeac18..05451cdfb8 100644 --- a/src/librustc_mir/borrow_check/nll/facts.rs +++ b/src/librustc_mir/borrow_check/nll/facts.rs @@ -2,6 +2,7 @@ use crate::borrow_check::location::{LocationIndex, LocationTable}; use crate::dataflow::indexes::BorrowIndex; use polonius_engine::AllFacts as PoloniusAllFacts; use polonius_engine::Atom; +use rustc::mir::Local; use rustc::ty::{RegionVid, TyCtxt}; use rustc_data_structures::indexed_vec::Idx; use std::error::Error; @@ -10,7 +11,7 @@ use std::fs::{self, File}; use std::io::Write; use std::path::Path; -crate type AllFacts = PoloniusAllFacts; +crate type AllFacts = PoloniusAllFacts; crate trait AllFactsExt { /// Returns `true` if there is a need to gather `AllFacts` given the @@ -27,8 +28,7 @@ crate trait AllFactsExt { impl AllFactsExt for AllFacts { /// Return fn enabled(tcx: TyCtxt<'_>) -> bool { - tcx.sess.opts.debugging_opts.nll_facts - || tcx.sess.opts.debugging_opts.polonius + tcx.sess.opts.debugging_opts.nll_facts || tcx.sess.opts.debugging_opts.polonius } fn write_to_dir( @@ -60,6 +60,12 @@ impl AllFactsExt for AllFacts { outlives, region_live_at, invalidates, + var_used, + var_defined, + var_drop_used, + var_uses_region, + var_drops_region, + var_initialized_on_exit, ]) } Ok(()) @@ -84,11 +90,7 @@ struct FactWriter<'w> { } impl<'w> FactWriter<'w> { - fn write_facts_to_path( - &self, - rows: &[T], - file_name: &str, - ) -> Result<(), Box> + fn write_facts_to_path(&self, rows: &[T], file_name: &str) -> Result<(), Box> where T: FactRow, { @@ -102,19 +104,11 @@ impl<'w> FactWriter<'w> { } trait FactRow { - fn write( - &self, - out: &mut File, - location_table: &LocationTable, - ) -> Result<(), Box>; + fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box>; } impl FactRow for RegionVid { - fn write( - &self, - out: &mut File, - location_table: &LocationTable, - ) -> Result<(), Box> { + fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { write_row(out, location_table, &[self]) } } @@ -124,11 +118,7 @@ where A: FactCell, B: FactCell, { - fn write( - &self, - out: &mut File, - location_table: &LocationTable, - ) -> Result<(), Box> { + fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1]) } } @@ -139,11 +129,7 @@ where B: FactCell, C: FactCell, { - fn write( - &self, - out: &mut File, - location_table: &LocationTable, - ) -> Result<(), Box> { + fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1, &self.2]) } } @@ -155,11 +141,7 @@ where C: FactCell, D: FactCell, { - fn write( - &self, - out: &mut File, - location_table: &LocationTable, - ) -> Result<(), Box> { + fn write(&self, out: &mut File, location_table: &LocationTable) -> Result<(), Box> { write_row(out, location_table, &[&self.0, &self.1, &self.2, &self.3]) } } @@ -170,11 +152,7 @@ fn write_row( columns: &[&dyn FactCell], ) -> Result<(), Box> { for (index, c) in columns.iter().enumerate() { - let tail = if index == columns.len() - 1 { - "\n" - } else { - "\t" - }; + let tail = if index == columns.len() - 1 { "\n" } else { "\t" }; write!(out, "{:?}{}", c.to_string(location_table), tail)?; } Ok(()) diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index c7b4a40305..71106af767 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -9,7 +9,7 @@ use crate::borrow_check::{ReadKind, WriteKind}; use crate::borrow_check::nll::facts::AllFacts; use crate::borrow_check::path_utils::*; use crate::dataflow::indexes::BorrowIndex; -use rustc::ty::TyCtxt; +use rustc::ty::{self, TyCtxt}; use rustc::mir::visit::Visitor; use rustc::mir::{BasicBlock, Location, Body, Place, Rvalue}; use rustc::mir::{Statement, StatementKind}; @@ -19,6 +19,7 @@ use rustc_data_structures::graph::dominators::Dominators; pub(super) fn generate_invalidates<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, all_facts: &mut Option, location_table: &LocationTable, body: &Body<'tcx>, @@ -34,6 +35,7 @@ pub(super) fn generate_invalidates<'tcx>( let mut ig = InvalidationGenerator { all_facts, borrow_set, + param_env, tcx, location_table, body, @@ -45,6 +47,7 @@ pub(super) fn generate_invalidates<'tcx>( struct InvalidationGenerator<'cx, 'tcx> { tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, all_facts: &'cx mut AllFacts, location_table: &'cx LocationTable, body: &'cx Body<'tcx>, @@ -207,8 +210,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { cleanup: _, } => { self.consume_operand(location, cond); - use rustc::mir::interpret::InterpError::BoundsCheck; - if let BoundsCheck { ref len, ref index } = *msg { + use rustc::mir::interpret::PanicInfo; + if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { self.consume_operand(location, len); self.consume_operand(location, index); } @@ -401,11 +404,13 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { ); let tcx = self.tcx; let body = self.body; + let param_env = self.param_env; let borrow_set = self.borrow_set.clone(); let indices = self.borrow_set.borrows.indices(); each_borrow_involving_path( self, tcx, + param_env, body, location, (sd, place), diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index eb63e0de19..d65cdde303 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -11,7 +11,7 @@ use crate::transform::MirSource; use crate::borrow_check::Upvar; use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; -use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Body}; +use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Body}; use rustc::ty::{self, RegionKind, RegionVid}; use rustc_errors::Diagnostic; use std::fmt::Debug; @@ -84,7 +84,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( errors_buffer: &mut Vec, ) -> ( RegionInferenceContext<'tcx>, - Option>>, + Option>>, Option>, ) { let mut all_facts = if AllFacts::enabled(infcx.tcx) { @@ -138,6 +138,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( constraint_generation::generate_constraints( infcx, + param_env, &mut liveness_constraints, &mut all_facts, location_table, @@ -162,6 +163,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( // Generate various additional constraints. invalidation::generate_invalidates( infcx.tcx, + param_env, &mut all_facts, location_table, &body, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 9e08961f44..efa18587b7 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -4,8 +4,8 @@ use crate::borrow_check::nll::region_infer::RegionInferenceContext; use crate::borrow_check::nll::type_check::Locations; use crate::borrow_check::nll::universal_regions::DefiningTy; use crate::borrow_check::nll::ConstraintDescription; -use crate::util::borrowck_errors::{BorrowckErrors, Origin}; use crate::borrow_check::Upvar; +use crate::util::borrowck_errors; use rustc::hir::def_id::DefId; use rustc::infer::error_reporting::nice_region_error::NiceRegionError; use rustc::infer::InferCtxt; @@ -487,9 +487,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); } - let mut diag = infcx - .tcx - .borrowed_data_escapes_closure(span, escapes_from, Origin::Mir); + let mut diag = borrowck_errors::borrowed_data_escapes_closure( + infcx.tcx, + span, + escapes_from, + ); if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { diag.span_label( diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 4e609460c1..40388722bc 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -20,7 +20,7 @@ use rustc::mir::{ ConstraintCategory, Local, Location, }; use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable}; -use rustc::util::common::{self, ErrorReported}; +use rustc::util::common::ErrorReported; use rustc_data_structures::binary_search_util; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -468,22 +468,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { upvars: &[Upvar], mir_def_id: DefId, errors_buffer: &mut Vec, - ) -> Option> { - common::time_ext( - infcx.tcx.sess.time_extended(), - Some(infcx.tcx.sess), - &format!("solve_nll_region_constraints({:?})", mir_def_id), - || self.solve_inner(infcx, body, upvars, mir_def_id, errors_buffer), - ) - } - - fn solve_inner( - &mut self, - infcx: &InferCtxt<'_, 'tcx>, - body: &Body<'tcx>, - upvars: &[Upvar], - mir_def_id: DefId, - errors_buffer: &mut Vec, ) -> Option> { self.propagate_constraints(body); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index cfd80cecca..6f9f570793 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -162,7 +162,7 @@ impl LivenessValues { } /// Iterate through each region that has a value in this set. - crate fn rows<'a>(&'a self) -> impl Iterator { + crate fn rows(&self) -> impl Iterator { self.points.rows() } diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 3954d62ad5..99661b1f73 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -1,7 +1,7 @@ //! This module contains code to equate the input/output types appearing //! in the MIR with the expected input/output types from the function //! signature. This requires a bit of processing, as the expected types -//! are supplied to us before normalization and may contain existential +//! are supplied to us before normalization and may contain opaque //! `impl Trait` instances. In contrast, the input/output types found in //! the MIR (specifically, in the special local variables for the //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and @@ -113,8 +113,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span); } - // Return types are a bit more complex. They may contain existential `impl Trait` - // types. + // Return types are a bit more complex. They may contain opaque `impl Trait` types. let mir_output_ty = body.local_decls[RETURN_PLACE].ty; let output_span = body.local_decls[RETURN_PLACE].source_info.span; if let Err(terr) = self.eq_opaque_type_and_type( diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs index 4af78fa5e0..8970009b6e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs @@ -7,7 +7,7 @@ use crate::borrow_check::nll::ToRegionVid; use crate::dataflow::move_paths::MoveData; use crate::dataflow::FlowAtLocation; use crate::dataflow::MaybeInitializedPlaces; -use rustc::mir::{Local, Body}; +use rustc::mir::{Body, Local}; use rustc::ty::{RegionVid, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use std::rc::Rc; @@ -15,6 +15,7 @@ use std::rc::Rc; use super::TypeChecker; mod local_use_map; +mod polonius; mod trace; /// Combines liveness analysis with initialization analysis to @@ -57,15 +58,9 @@ pub(super) fn generate<'tcx>( }; if !live_locals.is_empty() { - trace::trace( - typeck, - body, - elements, - flow_inits, - move_data, - live_locals, - location_table, - ); + trace::trace(typeck, body, elements, flow_inits, move_data, live_locals, location_table); + + polonius::populate_var_liveness_facts(typeck, body, location_table); } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs new file mode 100644 index 0000000000..20d7ec55e3 --- /dev/null +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -0,0 +1,94 @@ +use crate::borrow_check::location::{LocationIndex, LocationTable}; +use crate::util::liveness::{categorize, DefUse}; +use rustc::mir::visit::{PlaceContext, Visitor}; +use rustc::mir::{Body, Local, Location}; +use rustc::ty::subst::Kind; +use rustc::ty::Ty; + +use super::TypeChecker; + +type VarPointRelations = Vec<(Local, LocationIndex)>; + +struct LivenessPointFactsExtractor<'me> { + var_defined: &'me mut VarPointRelations, + var_used: &'me mut VarPointRelations, + location_table: &'me LocationTable, +} + +// A Visitor to walk through the MIR and extract point-wise facts +impl LivenessPointFactsExtractor<'_> { + fn location_to_index(&self, location: Location) -> LocationIndex { + self.location_table.mid_index(location) + } + + fn insert_def(&mut self, local: Local, location: Location) { + debug!("LivenessFactsExtractor::insert_def()"); + self.var_defined.push((local, self.location_to_index(location))); + } + + fn insert_use(&mut self, local: Local, location: Location) { + debug!("LivenessFactsExtractor::insert_use()"); + self.var_used.push((local, self.location_to_index(location))); + } +} + +impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> { + fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) { + match categorize(context) { + Some(DefUse::Def) => self.insert_def(local, location), + Some(DefUse::Use) => self.insert_use(local, location), + _ => (), + // NOTE: Drop handling is now done in trace() + } + } +} + +fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty<'tcx>) { + debug!("add_regions(local={:?}, type={:?})", local, ty); + typeck.tcx().for_each_free_region(&ty, |region| { + let region_vid = typeck.borrowck_context.universal_regions.to_region_vid(region); + debug!("add_regions for region {:?}", region_vid); + if let Some(facts) = typeck.borrowck_context.all_facts { + facts.var_uses_region.push((local, region_vid)); + } + }); +} + +pub(super) fn populate_var_liveness_facts( + typeck: &mut TypeChecker<'_, 'tcx>, + mir: &Body<'tcx>, + location_table: &LocationTable, +) { + debug!("populate_var_liveness_facts()"); + + if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { + LivenessPointFactsExtractor { + var_defined: &mut facts.var_defined, + var_used: &mut facts.var_used, + location_table, + } + .visit_body(mir); + } + + for (local, local_decl) in mir.local_decls.iter_enumerated() { + add_var_uses_regions(typeck, local, local_decl.ty); + } +} + +// For every potentially drop()-touched region `region` in `local`'s type +// (`kind`), emit a Polonius `var_drops_region(local, region)` fact. +pub(super) fn add_var_drops_regions( + typeck: &mut TypeChecker<'_, 'tcx>, + local: Local, + kind: &Kind<'tcx>, +) { + debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind); + let tcx = typeck.tcx(); + + tcx.for_each_free_region(kind, |drop_live_region| { + let region_vid = typeck.borrowck_context.universal_regions.to_region_vid(drop_live_region); + if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { + facts.var_drops_region.push((local, region_vid)); + }; + }); +} diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index f160f658f5..039ed939ad 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -1,13 +1,14 @@ use crate::borrow_check::location::LocationTable; use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements}; use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap; +use crate::borrow_check::nll::type_check::liveness::polonius; use crate::borrow_check::nll::type_check::NormalizeLocation; use crate::borrow_check::nll::type_check::TypeChecker; use crate::dataflow::indexes::MovePathIndex; use crate::dataflow::move_paths::MoveData; use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces}; use rustc::infer::canonical::QueryRegionConstraints; -use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Body}; +use rustc::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; @@ -130,6 +131,12 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { for local in live_locals { self.reset_local_state(); self.add_defs_for(local); + + // FIXME: this is temporary until we can generate our own initialization + if self.cx.typeck.borrowck_context.all_facts.is_some() { + self.add_polonius_var_initialized_on_exit_for(local) + } + self.compute_use_live_points_for(local); self.compute_drop_live_points_for(local); @@ -150,6 +157,63 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } } + // WARNING: panics if self.cx.typeck.borrowck_context.all_facts != None + // + // FIXME: this analysis (the initialization tracking) should be + // done in Polonius, but isn't yet. + fn add_polonius_var_initialized_on_exit_for(&mut self, local: Local) { + let move_path = self.cx.move_data.rev_lookup.find_local(local); + let facts = self.cx.typeck.borrowck_context.all_facts.as_mut().unwrap(); + for block in self.cx.body.basic_blocks().indices() { + debug!("polonius: generating initialization facts for {:?} in {:?}", local, block); + + // iterate through the block, applying the effects of each statement + // up to and including location, and populate `var_initialized_on_exit` + self.cx.flow_inits.reset_to_entry_of(block); + let start_location = Location { block, statement_index: 0 }; + self.cx.flow_inits.apply_local_effect(start_location); + + for statement_index in 0..self.cx.body[block].statements.len() { + let current_location = Location { block, statement_index }; + + self.cx.flow_inits.reconstruct_statement_effect(current_location); + + // statement has not yet taken effect: + if self.cx.flow_inits.has_any_child_of(move_path).is_some() { + facts + .var_initialized_on_exit + .push((local, self.cx.location_table.start_index(current_location))); + } + + // statement has now taken effect + self.cx.flow_inits.apply_local_effect(current_location); + + if self.cx.flow_inits.has_any_child_of(move_path).is_some() { + facts + .var_initialized_on_exit + .push((local, self.cx.location_table.mid_index(current_location))); + } + } + + let terminator_location = self.cx.body.terminator_loc(block); + + if self.cx.flow_inits.has_any_child_of(move_path).is_some() { + facts + .var_initialized_on_exit + .push((local, self.cx.location_table.start_index(terminator_location))); + } + + // apply the effects of the terminator and push it if needed + self.cx.flow_inits.reset_to_exit_of(block); + + if self.cx.flow_inits.has_any_child_of(move_path).is_some() { + facts + .var_initialized_on_exit + .push((local, self.cx.location_table.mid_index(terminator_location))); + } + } + } + /// Clear the value of fields that are "per local variable". fn reset_local_state(&mut self) { self.defs.clear(); @@ -183,9 +247,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } if self.use_live_at.insert(p) { - self.cx - .elements - .push_predecessors(self.cx.body, p, &mut self.stack) + self.cx.elements.push_predecessors(self.cx.body, p, &mut self.stack) } } } @@ -211,6 +273,11 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,); if self.cx.initialized_at_terminator(location.block, mpi) { + // FIXME: this analysis (the initialization tracking) should be + // done in Polonius, but isn't yet. + if let Some(facts) = self.cx.typeck.borrowck_context.all_facts { + facts.var_drop_used.push((local, self.cx.location_table.mid_index(location))); + } if self.drop_live_at.insert(drop_point) { self.drop_locations.push(location); self.stack.push(drop_point); @@ -218,10 +285,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } } - debug!( - "compute_drop_live_points_for: drop_locations={:?}", - self.drop_locations - ); + debug!("compute_drop_live_points_for: drop_locations={:?}", self.drop_locations); // Reverse DFS. But for drops, we do it a bit differently. // The stack only ever stores *terminators of blocks*. Within @@ -257,17 +321,11 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { // block. One of them may be either a definition or use // live point. let term_location = self.cx.elements.to_location(term_point); - debug_assert_eq!( - self.cx.body.terminator_loc(term_location.block), - term_location, - ); + debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,); let block = term_location.block; let entry_point = self.cx.elements.entry_point(term_location.block); for p in (entry_point..term_point).rev() { - debug!( - "compute_drop_live_points_for_block: p = {:?}", - self.cx.elements.to_location(p), - ); + debug!("compute_drop_live_points_for_block: p = {:?}", self.cx.elements.to_location(p)); if self.defs.contains(p) { debug!("compute_drop_live_points_for_block: def site"); @@ -286,10 +344,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } for &pred_block in self.cx.body.predecessors_for(block).iter() { - debug!( - "compute_drop_live_points_for_block: pred_block = {:?}", - pred_block, - ); + debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,); // Check whether the variable is (at least partially) // initialized at the exit of this predecessor. If so, we @@ -320,18 +375,12 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { // If the terminator of this predecessor either *assigns* // our value or is a "normal use", then stop. if self.defs.contains(pred_term_point) { - debug!( - "compute_drop_live_points_for_block: defined at {:?}", - pred_term_loc - ); + debug!("compute_drop_live_points_for_block: defined at {:?}", pred_term_loc); continue; } if self.use_live_at.contains(pred_term_point) { - debug!( - "compute_drop_live_points_for_block: use-live at {:?}", - pred_term_loc - ); + debug!("compute_drop_live_points_for_block: use-live at {:?}", pred_term_loc); continue; } @@ -392,10 +441,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> { // "just ahead" of a terminator. self.flow_inits.reset_to_entry_of(block); for statement_index in 0..self.body[block].statements.len() { - let location = Location { - block, - statement_index, - }; + let location = Location { block, statement_index }; self.flow_inits.reconstruct_statement_effect(location); self.flow_inits.apply_local_effect(location); } @@ -462,12 +508,11 @@ impl LivenessContext<'_, '_, '_, 'tcx> { if let Some(data) = &drop_data.region_constraint_data { for &drop_location in drop_locations { - self.typeck - .push_region_constraints( - drop_location.to_locations(), - ConstraintCategory::Boring, - data, - ); + self.typeck.push_region_constraints( + drop_location.to_locations(), + ConstraintCategory::Boring, + data, + ); } } @@ -487,6 +532,8 @@ impl LivenessContext<'_, '_, '_, 'tcx> { live_at, self.location_table, ); + + polonius::add_var_drops_regions(&mut self.typeck, dropped_local, &kind); } } @@ -505,14 +552,15 @@ impl LivenessContext<'_, '_, '_, 'tcx> { let tcx = typeck.tcx(); tcx.for_each_free_region(&value, |live_region| { - let live_region_vid = typeck.borrowck_context - .universal_regions - .to_region_vid(live_region); - typeck.borrowck_context + let live_region_vid = + typeck.borrowck_context.universal_regions.to_region_vid(live_region); + typeck + .borrowck_context .constraints .liveness_constraints .add_elements(live_region_vid, live_at); + // FIXME: remove this when we can generate our own region-live-at reliably if let Some(facts) = typeck.borrowck_context.all_facts { for point in live_at.iter() { let loc = elements.to_location(point); @@ -530,14 +578,9 @@ impl LivenessContext<'_, '_, '_, 'tcx> { debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,); let param_env = typeck.param_env; - let (dropck_result, region_constraint_data) = param_env - .and(DropckOutlives::new(dropped_ty)) - .fully_perform(typeck.infcx) - .unwrap(); - - DropData { - dropck_result, - region_constraint_data, - } + let (dropck_result, region_constraint_data) = + param_env.and(DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx).unwrap(); + + DropData { dropck_result, region_constraint_data } } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index cdbbe1d02b..70d6c15d8e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1,7 +1,5 @@ //! This pass type-checks the MIR to ensure it is not broken. -#![allow(unreachable_code)] - use crate::borrow_check::borrow_set::BorrowSet; use crate::borrow_check::location::LocationTable; use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConstraint}; @@ -28,14 +26,14 @@ use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue}; +use rustc::mir::interpret::{ConstValue, PanicInfo}; use rustc::mir::tcx::PlaceTy; use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext}; use rustc::mir::*; use rustc::traits::query::type_op; use rustc::traits::query::type_op::custom::CustomTypeOp; use rustc::traits::query::{Fallible, NoSolution}; -use rustc::traits::{ObligationCause, PredicateObligations}; +use rustc::traits::{self, ObligationCause, PredicateObligations}; use rustc::ty::adjustment::{PointerCast}; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::{Subst, SubstsRef, UnpackedKind, UserSubsts}; @@ -499,30 +497,43 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }; // FIXME use place_projection.is_empty() when is available - if let Place::Base(_) = place { + if place.projection.is_none() { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { - let tcx = self.tcx(); - let trait_ref = ty::TraitRef { - def_id: tcx.lang_items().copy_trait().unwrap(), - substs: tcx.mk_substs_trait(place_ty.ty, &[]), + let is_promoted = match place { + Place { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }), + projection: None, + } => true, + _ => false, }; - // In order to have a Copy operand, the type T of the - // value must be Copy. Note that we prove that T: Copy, - // rather than using the `is_copy_modulo_regions` - // test. This is important because - // `is_copy_modulo_regions` ignores the resulting region - // obligations and assumes they pass. This can result in - // bounds from Copy impls being unsoundly ignored (e.g., - // #29149). Note that we decide to use Copy before knowing - // whether the bounds fully apply: in effect, the rule is - // that if a value of some type could implement Copy, then - // it must. - self.cx.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::CopyBound, - ); + if !is_promoted { + let tcx = self.tcx(); + let trait_ref = ty::TraitRef { + def_id: tcx.lang_items().copy_trait().unwrap(), + substs: tcx.mk_substs_trait(place_ty.ty, &[]), + }; + + // In order to have a Copy operand, the type T of the + // value must be Copy. Note that we prove that T: Copy, + // rather than using the `is_copy_modulo_regions` + // test. This is important because + // `is_copy_modulo_regions` ignores the resulting region + // obligations and assumes they pass. This can result in + // bounds from Copy impls being unsoundly ignored (e.g., + // #29149). Note that we decide to use Copy before knowing + // whether the bounds fully apply: in effect, the rule is + // that if a value of some type could implement Copy, then + // it must. + self.cx.prove_trait_ref( + trait_ref, + location.to_locations(), + ConstraintCategory::CopyBound, + ); + } } } @@ -658,7 +669,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { ProjectionElem::Subslice { from, to } => PlaceTy::from_ty( match base_ty.sty { ty::Array(inner, size) => { - let size = size.unwrap_usize(tcx); + let size = size.eval_usize(tcx, self.cx.param_env); let min_size = (from as u64) + (to as u64); if let Some(rest_size) = size.checked_sub(min_size) { tcx.mk_array(inner, rest_size) @@ -1203,10 +1214,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tcx = self.infcx.tcx; for proj in &user_ty.projs { - let projected_ty = curr_projected_ty.projection_ty_core(tcx, proj, |this, field, &()| { - let ty = this.field_ty(tcx, field); - self.normalize(ty, locations) - }); + let projected_ty = curr_projected_ty.projection_ty_core( + tcx, + self.param_env, + proj, + |this, field, &()| { + let ty = this.field_ty(tcx, field); + self.normalize(ty, locations) + }, + ); curr_projected_ty = projected_ty; } debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}", @@ -1268,15 +1284,43 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let opaque_defn_ty = tcx.type_of(opaque_def_id); let opaque_defn_ty = opaque_defn_ty.subst(tcx, opaque_decl.substs); let opaque_defn_ty = renumber::renumber_regions(infcx, &opaque_defn_ty); + let concrete_is_opaque = infcx + .resolve_vars_if_possible(&opaque_decl.concrete_ty).is_impl_trait(); + debug!( - "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}", + "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?} \ + concrete_is_opaque={}", opaque_decl.concrete_ty, infcx.resolve_vars_if_possible(&opaque_decl.concrete_ty), - opaque_defn_ty + opaque_defn_ty, + concrete_is_opaque ); - obligations.add(infcx - .at(&ObligationCause::dummy(), param_env) - .eq(opaque_decl.concrete_ty, opaque_defn_ty)?); + + // concrete_is_opaque is `true` when we're using an opaque `impl Trait` + // type without 'revealing' it. For example, code like this: + // + // type Foo = impl Debug; + // fn foo1() -> Foo { ... } + // fn foo2() -> Foo { foo1() } + // + // In `foo2`, we're not revealing the type of `Foo` - we're + // just treating it as the opaque type. + // + // When this occurs, we do *not* want to try to equate + // the concrete type with the underlying defining type + // of the opaque type - this will always fail, since + // the defining type of an opaque type is always + // some other type (e.g. not itself) + // Essentially, none of the normal obligations apply here - + // we're just passing around some unknown opaque type, + // without actually looking at the underlying type it + // gets 'revealed' into + + if !concrete_is_opaque { + obligations.add(infcx + .at(&ObligationCause::dummy(), param_env) + .eq(opaque_decl.concrete_ty, opaque_defn_ty)?); + } } debug!("eq_opaque_type_and_type: equated"); @@ -1335,15 +1379,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // of lowering. Assignments to other sorts of places *are* interesting // though. let category = match *place { - Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let BorrowCheckContext { + Place { + base: PlaceBase::Local(RETURN_PLACE), + projection: None, + } => if let BorrowCheckContext { universal_regions: UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. }, .. - } = self.borrowck_context - { + } = self.borrowck_context { if tcx.is_static(*def_id) { ConstraintCategory::UseAsStatic } else { @@ -1352,8 +1398,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } else { ConstraintCategory::Return }, - Place::Base(PlaceBase::Local(l)) - if !body.local_decls[l].is_user_variable.is_some() => { + Place { + base: PlaceBase::Local(l), + projection: None, + } if !body.local_decls[l].is_user_variable.is_some() => { ConstraintCategory::Boring } _ => ConstraintCategory::Assignment, @@ -1589,7 +1637,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); } - if let BoundsCheck { ref len, ref index } = *msg { + if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { if len.ty(body, tcx) != tcx.types.usize { span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) } @@ -1637,7 +1685,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Some((ref dest, _target_block)) => { let dest_ty = dest.ty(body, tcx).ty; let category = match *dest { - Place::Base(PlaceBase::Local(RETURN_PLACE)) => { + Place { + base: PlaceBase::Local(RETURN_PLACE), + projection: None, + } => { if let BorrowCheckContext { universal_regions: UniversalRegions { @@ -1656,8 +1707,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Return } } - Place::Base(PlaceBase::Local(l)) - if !body.local_decls[l].is_user_variable.is_some() => { + Place { + base: PlaceBase::Local(l), + projection: None, + } if !body.local_decls[l].is_user_variable.is_some() => { ConstraintCategory::Boring } _ => ConstraintCategory::Assignment, @@ -1953,18 +2006,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Rvalue::Repeat(operand, len) => if *len > 1 { - let operand_ty = operand.ty(body, tcx); - - let trait_ref = ty::TraitRef { - def_id: tcx.lang_items().copy_trait().unwrap(), - substs: tcx.mk_substs_trait(operand_ty, &[]), - }; - - self.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::CopyBound, - ); + if let Operand::Move(_) = operand { + // While this is located in `nll::typeck` this error is not an NLL error, it's + // a required check to make sure that repeated elements implement `Copy`. + let span = body.source_info(location).span; + let ty = operand.ty(body, tcx); + if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) { + self.infcx.report_selection_error( + &traits::Obligation::new( + ObligationCause::new( + span, + self.tcx().hir().def_index_to_hir_id(self.mir_def_id.index), + traits::ObligationCauseCode::RepeatVec, + ), + self.param_env, + ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate { + trait_ref: ty::TraitRef::new( + self.tcx().lang_items().copy_trait().unwrap(), + tcx.mk_substs_trait(ty, &[]), + ), + })), + ), + &traits::SelectionError::Unimplemented, + false, + ); + } + } }, Rvalue::NullaryOp(_, ty) => { @@ -2376,19 +2443,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // *p`, where the `p` has type `&'b mut Foo`, for example, we // need to ensure that `'b: 'a`. - let mut borrowed_place = borrowed_place; + let mut borrowed_projection = &borrowed_place.projection; debug!( "add_reborrow_constraint({:?}, {:?}, {:?})", location, borrow_region, borrowed_place ); - while let Place::Projection(box Projection { base, elem }) = borrowed_place { - debug!("add_reborrow_constraint - iteration {:?}", borrowed_place); + while let Some(box proj) = borrowed_projection { + debug!("add_reborrow_constraint - iteration {:?}", borrowed_projection); - match *elem { + match proj.elem { ProjectionElem::Deref => { let tcx = self.infcx.tcx; - let base_ty = base.ty(body, tcx).ty; + let base_ty = Place::ty_from(&borrowed_place.base, &proj.base, body, tcx).ty; debug!("add_reborrow_constraint - base_ty = {:?}", base_ty); match base_ty.sty { @@ -2453,7 +2520,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // The "propagate" case. We need to check that our base is valid // for the borrow's lifetime. - borrowed_place = base; + borrowed_projection = &proj.base; } } diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index a85f4776a8..3e090aed52 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -768,7 +768,7 @@ fn for_each_late_bound_region_defined_on<'tcx>( local_id: *late_bound, }; let name = tcx.hir().name(hir_id).as_interned_str(); - let region_def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let region_def_id = tcx.hir().local_def_id(hir_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, bound_region: ty::BoundRegion::BrNamed(region_def_id, name), diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index aa2b177e54..43a012e149 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -4,7 +4,7 @@ use crate::borrow_check::AccessDepth; use crate::dataflow::indexes::BorrowIndex; use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase}; use rustc::mir::{ProjectionElem, BorrowKind}; -use rustc::ty::TyCtxt; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::graph::dominators::Dominators; /// Returns `true` if the borrow represented by `kind` is @@ -25,6 +25,7 @@ pub(super) enum Control { pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( s: &mut S, tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, _location: Location, access_place: (AccessDepth, &Place<'tcx>), @@ -47,10 +48,11 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( if places_conflict::borrow_conflicts_with_place( tcx, + param_env, body, &borrowed.borrowed_place, borrowed.kind, - place, + place.as_ref(), access, places_conflict::PlaceConflictBias::Overlap, ) { @@ -130,7 +132,7 @@ pub(super) fn is_active<'tcx>( /// Determines if a given borrow is borrowing local data /// This is called for all Yield statements on movable generators -pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool { +pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { place.iterate(|place_base, place_projection| { match place_base { PlaceBase::Static(..) => return false, diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index a8f28b64b4..72d5588c34 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -55,7 +55,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { for proj in place_projection { if proj.elem == ProjectionElem::Deref { - let ty = proj.base.ty(body, tcx).ty; + let ty = Place::ty_from(place_base, &proj.base, body, tcx).ty; match ty.sty { // For both derefs of raw pointers and `&T` // references, the original path is `Copy` and diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 64ca00defc..4dd2794f11 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -3,8 +3,8 @@ use crate::borrow_check::Overlap; use crate::borrow_check::{Deep, Shallow, AccessDepth}; use rustc::hir; use rustc::mir::{ - BorrowKind, Body, Place, PlaceBase, Projection, ProjectionElem, ProjectionsIter, - StaticKind + Body, BorrowKind, Place, PlaceBase, PlaceRef, Projection, ProjectionElem, ProjectionsIter, + StaticKind, }; use rustc::ty::{self, TyCtxt}; use std::cmp::max; @@ -26,6 +26,7 @@ crate enum PlaceConflictBias { /// dataflow). crate fn places_conflict<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, borrow_place: &Place<'tcx>, access_place: &Place<'tcx>, @@ -33,10 +34,11 @@ crate fn places_conflict<'tcx>( ) -> bool { borrow_conflicts_with_place( tcx, + param_env, body, borrow_place, BorrowKind::Mut { allow_two_phase_borrow: true }, - access_place, + access_place.as_ref(), AccessDepth::Deep, bias, ) @@ -48,10 +50,11 @@ crate fn places_conflict<'tcx>( /// order to make the conservative choice and preserve soundness. pub(super) fn borrow_conflicts_with_place<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, - access_place: &Place<'tcx>, + access_place: PlaceRef<'_, 'tcx>, access: AccessDepth, bias: PlaceConflictBias, ) -> bool { @@ -62,8 +65,14 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( // This Local/Local case is handled by the more general code below, but // it's so common that it's a speed win to check for it first. - if let Place::Base(PlaceBase::Local(l1)) = borrow_place { - if let Place::Base(PlaceBase::Local(l2)) = access_place { + if let Place { + base: PlaceBase::Local(l1), + projection: None, + } = borrow_place { + if let PlaceRef { + base: PlaceBase::Local(l2), + projection: None, + } = access_place { return l1 == l2; } } @@ -72,6 +81,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( access_place.iterate(|access_base, access_projections| { place_components_conflict( tcx, + param_env, body, (borrow_base, borrow_projections), borrow_kind, @@ -85,6 +95,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( fn place_components_conflict<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>), borrow_kind: BorrowKind, @@ -137,7 +148,7 @@ fn place_components_conflict<'tcx>( let borrow_base = borrow_projections.0; let access_base = access_projections.0; - match place_base_conflict(tcx, borrow_base, access_base) { + match place_base_conflict(tcx, param_env, borrow_base, access_base) { Overlap::Arbitrary => { bug!("Two base can't return Arbitrary"); } @@ -175,7 +186,7 @@ fn place_components_conflict<'tcx>( // check whether the components being borrowed vs // accessed are disjoint (as in the second example, // but not the first). - match place_projection_conflict(tcx, body, borrow_c, access_c, bias) { + match place_projection_conflict(tcx, body, borrow_base, borrow_c, access_c, bias) { Overlap::Arbitrary => { // We have encountered different fields of potentially // the same union - the borrow now partially overlaps. @@ -214,7 +225,7 @@ fn place_components_conflict<'tcx>( let base = &borrow_c.base; let elem = &borrow_c.elem; - let base_ty = base.ty(body, tcx).ty; + let base_ty = Place::ty_from(borrow_base, base, body, tcx).ty; match (elem, &base_ty.sty, access) { (_, _, Shallow(Some(ArtificialField::ArrayLength))) @@ -300,6 +311,7 @@ fn place_components_conflict<'tcx>( // between `elem1` and `elem2`. fn place_base_conflict<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, elem1: &PlaceBase<'tcx>, elem2: &PlaceBase<'tcx>, ) -> Overlap { @@ -333,7 +345,7 @@ fn place_base_conflict<'tcx>( (StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => { if promoted_1 == promoted_2 { if let ty::Array(_, len) = s1.ty.sty { - if let Some(0) = len.assert_usize(tcx) { + if let Some(0) = len.try_eval_usize(tcx, param_env) { // Ignore conflicts with promoted [T; 0]. debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); return Overlap::Disjoint; @@ -368,6 +380,7 @@ fn place_base_conflict<'tcx>( fn place_projection_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, + pi1_base: &PlaceBase<'tcx>, pi1: &Projection<'tcx>, pi2: &Projection<'tcx>, bias: PlaceConflictBias, @@ -384,7 +397,7 @@ fn place_projection_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD"); Overlap::EqualOrDisjoint } else { - let ty = pi1.base.ty(body, tcx).ty; + let ty = Place::ty_from(pi1_base, &pi1.base, body, tcx).ty; match ty.sty { ty::Adt(def, _) if def.is_union() => { // Different fields of a union, we are basically stuck. diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 0cc1dfd4de..ecafd4eb11 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -11,26 +11,23 @@ use super::MirBorrowckCtxt; use rustc::hir; use rustc::ty::{self, TyCtxt}; -use rustc::mir::{Body, Place, PlaceBase, ProjectionElem}; +use rustc::mir::{Body, Place, PlaceBase, PlaceRef, ProjectionElem}; -pub trait IsPrefixOf<'tcx> { - fn is_prefix_of(&self, other: &Place<'tcx>) -> bool; +pub trait IsPrefixOf<'cx, 'tcx> { + fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool; } -impl<'tcx> IsPrefixOf<'tcx> for Place<'tcx> { - fn is_prefix_of(&self, other: &Place<'tcx>) -> bool { - let mut cursor = other; +impl<'cx, 'tcx> IsPrefixOf<'cx, 'tcx> for PlaceRef<'cx, 'tcx> { + fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool { + let mut cursor = other.projection; loop { - if self == cursor { - return true; + if self.projection == cursor { + return self.base == other.base; } - match *cursor { - Place::Base(PlaceBase::Local(_)) | - Place::Base(PlaceBase::Static(_)) => return false, - Place::Projection(ref proj) => { - cursor = &proj.base; - } + match cursor { + None => return false, + Some(proj) => cursor = &proj.base, } } } @@ -40,7 +37,7 @@ pub(super) struct Prefixes<'cx, 'tcx> { body: &'cx Body<'tcx>, tcx: TyCtxt<'tcx>, kind: PrefixSet, - next: Option<&'cx Place<'tcx>>, + next: Option<(PlaceRef<'cx, 'tcx>)>, } #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -59,9 +56,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Returns an iterator over the prefixes of `place` /// (inclusive) from longest to smallest, potentially /// terminating the iteration early based on `kind`. - pub(super) fn prefixes(&self, place: &'cx Place<'tcx>, kind: PrefixSet) -> Prefixes<'cx, 'tcx> { + pub(super) fn prefixes( + &self, + place_ref: PlaceRef<'cx, 'tcx>, + kind: PrefixSet, + ) -> Prefixes<'cx, 'tcx> { Prefixes { - next: Some(place), + next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx, @@ -70,7 +71,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { - type Item = &'cx Place<'tcx>; + type Item = PlaceRef<'cx, 'tcx>; fn next(&mut self) -> Option { let mut cursor = self.next?; @@ -80,27 +81,42 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { // downcasts here, but may return a base of a downcast). 'cursor: loop { - let proj = match *cursor { - Place::Base(PlaceBase::Local(_)) | // search yielded this leaf - Place::Base(PlaceBase::Static(_)) => { + let proj = match &cursor { + PlaceRef { + base: PlaceBase::Local(_), + projection: None, + } + | // search yielded this leaf + PlaceRef { + base: PlaceBase::Static(_), + projection: None, + } => { self.next = None; return Some(cursor); } - - Place::Projection(ref proj) => proj, + PlaceRef { + base: _, + projection: Some(proj), + } => proj, }; match proj.elem { ProjectionElem::Field(_ /*field*/, _ /*ty*/) => { - // FIXME: add union handling - self.next = Some(&proj.base); + // FIXME: add union handling + self.next = Some(PlaceRef { + base: cursor.base, + projection: &proj.base, + }); return Some(cursor); } ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Index(_) => { - cursor = &proj.base; + cursor = PlaceRef { + base: cursor.base, + projection: &proj.base, + }; continue 'cursor; } ProjectionElem::Deref => { @@ -121,7 +137,10 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { PrefixSet::All => { // all prefixes: just blindly enqueue the base // of the projection - self.next = Some(&proj.base); + self.next = Some(PlaceRef { + base: cursor.base, + projection: &proj.base, + }); return Some(cursor); } PrefixSet::Supporting => { @@ -134,7 +153,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { // derefs, except we stop at the deref of a shared // reference. - let ty = proj.base.ty(self.body, self.tcx).ty; + let ty = Place::ty_from(cursor.base, &proj.base, self.body, self.tcx).ty; match ty.sty { ty::RawPtr(_) | ty::Ref( @@ -152,12 +171,18 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { _, /*ty*/ hir::MutMutable, ) => { - self.next = Some(&proj.base); + self.next = Some(PlaceRef { + base: cursor.base, + projection: &proj.base, + }); return Some(cursor); } ty::Adt(..) if ty.is_box() => { - self.next = Some(&proj.base); + self.next = Some(PlaceRef { + base: cursor.base, + projection: &proj.base, + }); return Some(cursor); } diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index 9c5569011d..2587d14a73 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -59,7 +59,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { // be those that were never initialized - we will consider those as being used as // they will either have been removed by unreachable code optimizations; or linted // as unused variables. - if let Some(local) = into.base_local() { + if let PlaceBase::Local(local) = into.base { let _ = self.never_initialized_mut_locals.remove(&local); } } @@ -90,7 +90,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc ) { match &statement.kind { StatementKind::Assign(into, _) => { - if let Some(local) = into.base_local() { + if let PlaceBase::Local(local) = into.base { debug!( "visit_statement: statement={:?} local={:?} \ never_initialized_mut_locals={:?}", @@ -118,7 +118,10 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc "assignment of {:?} to {:?}, adding {:?} to used mutable set", path.place, local, path.place ); - if let Place::Base(PlaceBase::Local(user_local)) = path.place { + if let Place { + base: PlaceBase::Local(user_local), + projection: None, + } = path.place { self.mbcx.used_mut.insert(user_local); } } diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 0640c01d25..7005f274e0 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -4,7 +4,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; -use rustc::mir::interpret::InterpError::BoundsCheck; +use rustc::mir::interpret::{PanicInfo::BoundsCheck}; use rustc::mir::*; use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; @@ -73,13 +73,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let (usize_ty, bool_ty) = (this.hir.usize_ty(), this.hir.bool_ty()); let slice = unpack!(block = this.as_place(block, lhs)); - // region_scope=None so place indexes live forever. They are scalars so they - // do not need storage annotations, and they are often copied between - // places. // Making this a *fresh* temporary also means we do not have to worry about // the index changing later: Nothing will ever change this temporary. // The "retagging" transformation (for Stacked Borrows) relies on this. - let idx = unpack!(block = this.as_temp(block, None, index, Mutability::Mut)); + let idx = unpack!(block = this.as_temp( + block, + expr.temp_lifetime, + index, + Mutability::Not, + )); // bounds check: let (len, lt) = ( @@ -121,10 +123,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; block.and(place) } - ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static { - ty: expr.ty, - kind: StaticKind::Static(id), - })))), + ExprKind::StaticRef { id } => block.and(Place { + base: PlaceBase::Static(Box::new(Static { + ty: expr.ty, + kind: StaticKind::Static(id), + })), + projection: None, + }), ExprKind::PlaceTypeAscription { source, user_ty } => { let place = unpack!(block = this.as_place(block, source)); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 17e7b1acc6..ec061e7453 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -7,7 +7,7 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; use rustc::middle::region; -use rustc::mir::interpret::InterpError; +use rustc::mir::interpret::PanicInfo; use rustc::mir::*; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts}; use syntax_pos::Span; @@ -101,7 +101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, Operand::Move(is_min), false, - InterpError::OverflowNeg, + PanicInfo::OverflowNeg, expr_span, ); } @@ -128,7 +128,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr_span, scope, result, - value.ty, + expr.ty, ); } @@ -401,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let val = result_value.clone().field(val_fld, ty); let of = result_value.field(of_fld, bool_ty); - let err = InterpError::Overflow(op); + let err = PanicInfo::Overflow(op); block = self.assert(block, Operand::Move(of), false, err, span); @@ -411,11 +411,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Checking division and remainder is more complex, since we 1. always check // and 2. there are two possible failure cases, divide-by-zero and overflow. - let (zero_err, overflow_err) = if op == BinOp::Div { - (InterpError::DivisionByZero, InterpError::Overflow(op)) + let zero_err = if op == BinOp::Div { + PanicInfo::DivisionByZero } else { - (InterpError::RemainderByZero, InterpError::Overflow(op)) + PanicInfo::RemainderByZero }; + let overflow_err = PanicInfo::Overflow(op); // Check for / 0 let is_zero = self.temp(bool_ty, span); @@ -497,32 +498,48 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arg_place = unpack!(block = this.as_place(block, arg)); let mutability = match arg_place { - Place::Base(PlaceBase::Local(local)) => this.local_decls[local].mutability, - Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(local)), - elem: ProjectionElem::Deref, - }) => { + Place { + base: PlaceBase::Local(local), + projection: None, + } => this.local_decls[local].mutability, + Place { + base: PlaceBase::Local(local), + projection: Some(box Projection { + base: None, + elem: ProjectionElem::Deref, + }) + } => { debug_assert!( this.local_decls[local].is_ref_for_guard(), "Unexpected capture place", ); this.local_decls[local].mutability } - Place::Projection(box Projection { + Place { + ref base, + projection: Some(box Projection { + base: ref base_proj, + elem: ProjectionElem::Field(upvar_index, _), + }), + } + | Place { ref base, - elem: ProjectionElem::Field(upvar_index, _), - }) - | Place::Projection(box Projection { - base: - Place::Projection(box Projection { - ref base, + projection: Some(box Projection { + base: Some(box Projection { + base: ref base_proj, elem: ProjectionElem::Field(upvar_index, _), }), - elem: ProjectionElem::Deref, - }) => { + elem: ProjectionElem::Deref, + }), + } => { + let place = PlaceRef { + base, + projection: base_proj, + }; + // Not projected from the implicit `self` in a closure. debug_assert!( - match base.local_or_deref_local() { + match place.local_or_deref_local() { Some(local) => local == Local::new(1), None => false, }, diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 1fe6be8bbc..dbcc330eca 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -3,6 +3,7 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::scope::DropKind; use crate::hair::*; +use rustc::hir; use rustc::middle::region; use rustc::mir::*; @@ -66,32 +67,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; let temp_place = &Place::from(temp); - if !expr_ty.is_never() { - this.cfg.push( - block, - Statement { - source_info, - kind: StatementKind::StorageLive(temp), - }, - ); - - // In constants, `temp_lifetime` is `None` for temporaries that live for the - // `'static` lifetime. Thus we do not drop these temporaries and simply leak them. - // This is equivalent to what `let x = &foo();` does in functions. The temporary - // is lifted to their surrounding scope. In a function that means the temporary lives - // until just before the function returns. In constants that means it outlives the - // constant's initialization value computation. Anything outliving a constant - // must have the `'static` lifetime and live forever. - // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything - // within a block will keep the regular drops just like runtime code. - if let Some(temp_lifetime) = temp_lifetime { - this.schedule_drop( - expr_span, - temp_lifetime, - temp, - expr_ty, - DropKind::Storage, + match expr.kind { + // Don't bother with StorageLive and Dead for these temporaries, + // they are never assigned. + ExprKind::Break { .. } | + ExprKind::Continue { .. } | + ExprKind::Return { .. } => (), + ExprKind::Block { + body: hir::Block { expr: None, targeted_by_break: false, .. } + } if expr_ty.is_never() => (), + _ => { + this.cfg.push( + block, + Statement { + source_info, + kind: StatementKind::StorageLive(temp), + }, ); + + // In constants, `temp_lifetime` is `None` for temporaries that + // live for the `'static` lifetime. Thus we do not drop these + // temporaries and simply leak them. + // This is equivalent to what `let x = &foo();` does in + // functions. The temporary is lifted to their surrounding + // scope. In a function that means the temporary lives until + // just before the function returns. In constants that means it + // outlives the constant's initialization value computation. + // Anything outliving a constant must have the `'static` + // lifetime and live forever. + // Anything with a shorter lifetime (e.g the `&foo()` in + // `bar(&foo())` or anything within a block will keep the + // regular drops just like runtime code. + if let Some(temp_lifetime) = temp_lifetime { + this.schedule_drop( + expr_span, + temp_lifetime, + temp, + expr_ty, + DropKind::Storage, + ); + } } } diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 222ce6d1c9..f679a00035 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -31,7 +31,7 @@ pub enum RvalueFunc { /// Determines the category for a given expression. Note that scope /// and paren expressions have no category. impl Category { - pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option { + pub fn of(ek: &ExprKind<'_>) -> Option { match *ek { ExprKind::Scope { .. } => None, diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 0a2ea78bfd..02ab53fe8c 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -79,17 +79,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::LogicalOp { op, lhs, rhs } => { // And: // - // [block: If(lhs)] -true-> [else_block: dest = (rhs)] - // | (false) - // [shortcurcuit_block: dest = false] + // [block: If(lhs)] -true-> [else_block: If(rhs)] -true-> [true_block] + // | | (false) + // +----------false-----------+------------------> [false_block] // // Or: // - // [block: If(lhs)] -false-> [else_block: dest = (rhs)] - // | (true) - // [shortcurcuit_block: dest = true] + // [block: If(lhs)] -false-> [else_block: If(rhs)] -true-> [true_block] + // | (true) | (false) + // [true_block] [false_block] - let (shortcircuit_block, mut else_block, join_block) = ( + let (true_block, false_block, mut else_block, join_block) = ( + this.cfg.start_new_block(), this.cfg.start_new_block(), this.cfg.start_new_block(), this.cfg.start_new_block(), @@ -97,60 +98,54 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let lhs = unpack!(block = this.as_local_operand(block, lhs)); let blocks = match op { - LogicalOp::And => (else_block, shortcircuit_block), - LogicalOp::Or => (shortcircuit_block, else_block), + LogicalOp::And => (else_block, false_block), + LogicalOp::Or => (true_block, else_block), }; let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1); this.cfg.terminate(block, source_info, term); + let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs)); + let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block); + this.cfg.terminate(else_block, source_info, term); + this.cfg.push_assign_constant( - shortcircuit_block, + true_block, source_info, destination, Constant { span: expr_span, ty: this.hir.bool_ty(), user_ty: None, - literal: match op { - LogicalOp::And => this.hir.false_literal(), - LogicalOp::Or => this.hir.true_literal(), - }, + literal: this.hir.true_literal(), }, ); - this.cfg.terminate( - shortcircuit_block, + + this.cfg.push_assign_constant( + false_block, source_info, - TerminatorKind::Goto { target: join_block }, + destination, + Constant { + span: expr_span, + ty: this.hir.bool_ty(), + user_ty: None, + literal: this.hir.false_literal(), + }, ); - let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs)); - this.cfg.push_assign( - else_block, + this.cfg.terminate( + true_block, source_info, - destination, - Rvalue::Use(rhs), + TerminatorKind::Goto { target: join_block }, ); this.cfg.terminate( - else_block, + false_block, source_info, TerminatorKind::Goto { target: join_block }, ); join_block.unit() } - ExprKind::Loop { - condition: opt_cond_expr, - body, - } => { - // [block] --> [loop_block] -/eval. cond./-> [loop_block_end] -1-> [exit_block] - // ^ | - // | 0 - // | | - // | v - // [body_block_end] <-/eval. body/-- [body_block] - // - // If `opt_cond_expr` is `None`, then the graph is somewhat simplified: - // + ExprKind::Loop { body } => { // [block] // | // [loop_block] -> [body_block] -/eval. body/-> [body_block_end] @@ -177,33 +172,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination.clone(), move |this| { // conduct the test, if necessary - let body_block; - if let Some(cond_expr) = opt_cond_expr { - let cond_expr = this.hir.mirror(cond_expr); - let (true_block, false_block) - = this.test_bool(loop_block, cond_expr, source_info); - body_block = true_block; - - // if the test is false, there's no `break` to assign `destination`, so - // we have to do it - this.cfg.push_assign_unit(false_block, source_info, destination); - this.cfg.terminate( - false_block, - source_info, - TerminatorKind::Goto { target: exit_block }, - ); - } else { - body_block = this.cfg.start_new_block(); - let diverge_cleanup = this.diverge_cleanup(); - this.cfg.terminate( - loop_block, - source_info, - TerminatorKind::FalseUnwind { - real_target: body_block, - unwind: Some(diverge_cleanup), - }, - ) - } + let body_block = this.cfg.start_new_block(); + let diverge_cleanup = this.diverge_cleanup(); + this.cfg.terminate( + loop_block, + source_info, + TerminatorKind::FalseUnwind { + real_target: body_block, + unwind: Some(diverge_cleanup), + }, + ); // The “return” value of the loop body must always be an unit. We therefore // introduce a unit temporary as the destination for the loop body. @@ -325,7 +303,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Create a "fake" temporary variable so that we check that the // value is Sized. Usually, this is caught in type checking, but // in the case of box expr there is no such check. - if let Place::Projection(..) = destination { + if destination.projection.is_some() { this.local_decls .push(LocalDecl::new_temp(expr.ty, expr.span)); } diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index f831f5105a..d72b0addae 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -228,10 +228,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; // Step 5. Create everything else: the guards and the arms. + let match_scope = self.scopes.topmost(); + let arm_end_blocks: Vec<_> = arm_candidates.into_iter().map(|(arm, mut candidates)| { let arm_source_info = self.source_info(arm.span); - let region_scope = (arm.scope, arm_source_info); - self.in_scope(region_scope, arm.lint_level, |this| { + let arm_scope = (arm.scope, arm_source_info); + self.in_scope(arm_scope, arm.lint_level, |this| { let body = this.hir.mirror(arm.body.clone()); let scope = this.declare_bindings( None, @@ -248,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { arm.guard.clone(), &fake_borrow_temps, scrutinee_span, - region_scope, + match_scope, ); } else { arm_block = this.cfg.start_new_block(); @@ -259,7 +261,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { arm.guard.clone(), &fake_borrow_temps, scrutinee_span, - region_scope, + match_scope, ); this.cfg.terminate( binding_end, @@ -534,7 +536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let var_ty = self.local_decls[local_id].ty; let region_scope = self.hir.region_scope_tree.var_scope(var.local_id); self.schedule_drop(span, region_scope, local_id, var_ty, DropKind::Storage); - Place::Base(PlaceBase::Local(local_id)) + Place::from(local_id) } pub fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) { @@ -935,11 +937,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { for Binding { source, .. } in matched_candidates.iter().flat_map(|candidate| &candidate.bindings) { - let mut cursor = source; - while let Place::Projection(box Projection { base, elem }) = cursor { + let mut cursor = &source.projection; + while let Some(box Projection { base, elem }) = cursor { cursor = base; if let ProjectionElem::Deref = elem { - fake_borrows.insert(cursor.clone()); + fake_borrows.insert(Place { + base: source.base.clone(), + projection: cursor.clone(), + }); break; } } @@ -1275,7 +1280,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, fake_borrows: &'b FxHashSet>, temp_span: Span, - ) -> Vec<(&'b Place<'tcx>, Local)> { + ) -> Vec<(PlaceRef<'b, 'tcx>, Local)> { let tcx = self.hir.tcx(); debug!("add_fake_borrows fake_borrows = {:?}", fake_borrows); @@ -1285,18 +1290,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Insert a Shallow borrow of the prefixes of any fake borrows. for place in fake_borrows { - let mut prefix_cursor = place; - while let Place::Projection(box Projection { base, elem }) = prefix_cursor { + let mut prefix_cursor = &place.projection; + while let Some(box Projection { base, elem }) = prefix_cursor { if let ProjectionElem::Deref = elem { // Insert a shallow borrow after a deref. For other // projections the borrow of prefix_cursor will // conflict with any mutation of base. - all_fake_borrows.push(base); + all_fake_borrows.push(PlaceRef { + base: &place.base, + projection: base, + }); } prefix_cursor = base; } - all_fake_borrows.push(place); + all_fake_borrows.push(place.as_ref()); } // Deduplicate and ensure a deterministic order. @@ -1306,7 +1314,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("add_fake_borrows all_fake_borrows = {:?}", all_fake_borrows); all_fake_borrows.into_iter().map(|matched_place| { - let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty; + let fake_borrow_deref_ty = Place::ty_from( + matched_place.base, + matched_place.projection, + &self.local_decls, + tcx, + ) + .ty; let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty); let fake_borrow_temp = self.local_decls.push( LocalDecl::new_temp(fake_borrow_ty, temp_span) @@ -1337,9 +1351,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, candidate: Candidate<'pat, 'tcx>, guard: Option>, - fake_borrows: &Vec<(&Place<'tcx>, Local)>, + fake_borrows: &Vec<(PlaceRef<'_, 'tcx>, Local)>, scrutinee_span: Span, - region_scope: (region::Scope, SourceInfo), + region_scope: region::Scope, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -1463,21 +1477,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode)) .collect(), }; - debug!("Entering guard building context: {:?}", guard_frame); + debug!("entering guard building context: {:?}", guard_frame); self.guard_context.push(guard_frame); let re_erased = tcx.lifetimes.re_erased; let scrutinee_source_info = self.source_info(scrutinee_span); - for &(place, temp) in fake_borrows { + for (place, temp) in fake_borrows { let borrow = Rvalue::Ref( re_erased, BorrowKind::Shallow, - place.clone(), + Place { + base: place.base.clone(), + projection: place.projection.clone(), + }, ); self.cfg.push_assign( block, scrutinee_source_info, - &Place::from(temp), + &Place::from(*temp), borrow, ); } @@ -1547,7 +1564,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // place they refer to can't be modified by the guard. for binding in by_value_bindings.clone() { let local_id = self.var_local_id(binding.var_id, RefWithinGuard); - let place = Place::from(local_id); + let place = Place::from(local_id); self.cfg.push( post_guard_block, Statement { diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index b1b5233fbc..d9b748f71f 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'pat, 'tcx>) { // repeatedly simplify match pairs until fixed point is reached loop { - let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]); + let match_pairs = mem::take(&mut candidate.match_pairs); let mut changed = false; for match_pair in match_pairs { match self.simplify_match_pair(match_pair, candidate) { @@ -161,7 +161,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| { i == variant_index || { - self.hir.tcx().features().never_type && self.hir.tcx().features().exhaustive_patterns && !v.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()).is_empty() } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 95e2e52092..1c93abd40d 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -109,10 +109,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match *match_pair.pattern.kind { PatternKind::Constant { value } => { - let switch_ty = ty::ParamEnv::empty().and(switch_ty); indices.entry(value) .or_insert_with(|| { - options.push(value.unwrap_bits(self.hir.tcx(), switch_ty)); + options.push(value.eval_bits( + self.hir.tcx(), self.hir.param_env, switch_ty, + )); options.len() - 1 }); true @@ -653,11 +654,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { use std::cmp::Ordering::*; use rustc::hir::RangeEnd::*; - let param_env = ty::ParamEnv::empty().and(test.ty); let tcx = self.hir.tcx(); - let lo = compare_const_vals(tcx, test.lo, pat.hi, param_env)?; - let hi = compare_const_vals(tcx, test.hi, pat.lo, param_env)?; + let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test.ty)?; + let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test.ty)?; match (test.end, pat.end, lo, hi) { // pat < test @@ -772,11 +772,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> Option { use std::cmp::Ordering::*; - let param_env = ty::ParamEnv::empty().and(range.ty); let tcx = self.hir.tcx(); - let a = compare_const_vals(tcx, range.lo, value, param_env)?; - let b = compare_const_vals(tcx, value, range.hi, param_env)?; + let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.ty)?; + let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.ty)?; match (b, range.end) { (Less, _) | @@ -826,6 +825,6 @@ impl Test<'_> { } } -fn is_switch_ty<'tcx>(ty: Ty<'tcx>) -> bool { +fn is_switch_ty(ty: Ty<'_>) -> bool { ty.is_integral() || ty.is_char() || ty.is_bool() } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index fdc2473b04..6a3bb8b8b8 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -22,7 +22,7 @@ use syntax_pos::Span; use super::lints; /// Construct the MIR for a given `DefId`. -pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> { +pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); // Figure out what primary body this item has. @@ -69,7 +69,7 @@ pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) let fn_sig = cx.tables().liberated_fn_sigs()[id].clone(); - let fn_def_id = tcx.hir().local_def_id_from_hir_id(id); + let fn_def_id = tcx.hir().local_def_id(id); let ty = tcx.type_of(fn_def_id); let mut abi = fn_sig.abi; @@ -121,7 +121,7 @@ pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> { self_arg = None; } - ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&*arg.pat), self_arg) + ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&arg), self_arg) }); let arguments = implicit_argument.into_iter().chain(explicit_arguments); @@ -171,11 +171,11 @@ pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> { /////////////////////////////////////////////////////////////////////////// // BuildMir -- walks a crate, looking for fn items and methods to build MIR from -fn liberated_closure_env_ty<'tcx>( - tcx: TyCtxt<'tcx>, +fn liberated_closure_env_ty( + tcx: TyCtxt<'_>, closure_expr_id: hir::HirId, body_id: hir::BodyId, -) -> Ty<'tcx> { +) -> Ty<'_> { let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_id); let (closure_def_id, closure_substs) = match closure_ty.sty { @@ -485,7 +485,7 @@ macro_rules! unpack { }; } -fn should_abort_on_panic<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: DefId, abi: Abi) -> bool { +fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool { // Not callable from C, so we can safely unwind through these if abi == Abi::Rust || abi == Abi::RustCall { return false; } @@ -511,7 +511,7 @@ fn should_abort_on_panic<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: DefId, abi: Abi) -> /////////////////////////////////////////////////////////////////////////// /// the main entry point for building MIR for a function -struct ArgInfo<'tcx>(Ty<'tcx>, Option, Option<&'tcx hir::Pat>, Option); +struct ArgInfo<'tcx>(Ty<'tcx>, Option, Option<&'tcx hir::Arg>, Option); fn construct_fn<'a, 'tcx, A>( hir: Cx<'a, 'tcx>, @@ -534,7 +534,7 @@ where let span = tcx_hir.span(fn_id); let hir_tables = hir.tables(); - let fn_def_id = tcx_hir.local_def_id_from_hir_id(fn_id); + let fn_def_id = tcx_hir.local_def_id(fn_id); // Gather the upvars of a closure, if any. let mut upvar_mutbls = vec![]; @@ -604,9 +604,18 @@ where } let arg_scope_s = (arg_scope, source_info); - unpack!(block = builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { - builder.args_and_body(block, &arguments, arg_scope, &body.value) - })); + // `return_block` is called when we evaluate a `return` expression, so + // we just use `START_BLOCK` here. + unpack!(block = builder.in_breakable_scope( + None, + START_BLOCK, + Place::RETURN_PLACE, + |builder| { + builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { + builder.args_and_body(block, &arguments, arg_scope, &body.value) + }) + }, + )); // Attribute epilogue to function's closing brace let fn_end = span.shrink_to_hi(); let source_info = builder.source_info(fn_end); @@ -773,13 +782,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { -> BlockAnd<()> { // Allocate locals for the function arguments - for &ArgInfo(ty, _, pattern, _) in arguments.iter() { + for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() { // If this is a simple binding pattern, give the local a name for // debuginfo and so that error reporting knows that this is a user // variable. For any other pattern the pattern introduces new // variables which will be named instead. - let (name, span) = if let Some(pat) = pattern { - (pat.simple_ident().map(|ident| ident.name), pat.span) + let (name, span) = if let Some(arg) = arg_opt { + (arg.pat.simple_ident().map(|ident| ident.name), arg.pat.span) } else { (None, self.fn_span) }; @@ -804,18 +813,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Function arguments always get the first Local indices after the return place let local = Local::new(index + 1); let place = Place::from(local); - let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info; + let &ArgInfo(ty, opt_ty_info, arg_opt, ref self_binding) = arg_info; // Make sure we drop (parts of) the argument even when not matched on. self.schedule_drop( - pattern.as_ref().map_or(ast_body.span, |pat| pat.span), + arg_opt.as_ref().map_or(ast_body.span, |arg| arg.pat.span), argument_scope, local, ty, DropKind::Value, ); - if let Some(pattern) = pattern { - let pattern = self.hir.pattern_from_hir(pattern); + if let Some(arg) = arg_opt { + let pattern = self.hir.pattern_from_hir(&arg.pat); + let original_source_scope = self.source_scope; let span = pattern.span; - + self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span); match *pattern.kind { // Don't introduce extra copies for simple bindings PatternKind::Binding { @@ -826,6 +836,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .. } => { self.local_decls[local].mutability = mutability; + self.local_decls[local].source_info.scope = self.source_scope; self.local_decls[local].is_user_variable = if let Some(kind) = self_binding { Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind))) @@ -851,6 +862,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unpack!(block = self.place_into_pattern(block, pattern, &place, false)); } } + self.source_scope = original_source_scope; } } @@ -860,11 +872,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let body = self.hir.mirror(ast_body); - // `return_block` is called when we evaluate a `return` expression, so - // we just use `START_BLOCK` here. - self.in_breakable_scope(None, START_BLOCK, Place::RETURN_PLACE, |this| { - this.into(&Place::RETURN_PLACE, block, body) - }) + self.into(&Place::RETURN_PLACE, block, body) + } + + fn set_correct_source_scope_for_arg( + &mut self, + arg_hir_id: hir::HirId, + original_source_scope: SourceScope, + pattern_span: Span + ) { + let tcx = self.hir.tcx(); + let current_root = tcx.maybe_lint_level_root_bounded( + arg_hir_id, + self.hir.root_lint_level + ); + let parent_root = tcx.maybe_lint_level_root_bounded( + self.source_scope_local_data[original_source_scope].lint_root, + self.hir.root_lint_level, + ); + if current_root != parent_root { + self.source_scope = self.new_source_scope( + pattern_span, + LintLevel::Explicit(current_root), + None + ); + } } fn get_unit_temp(&mut self) -> Place<'tcx> { diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 1b5fa1c977..a04c041ca9 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -332,9 +332,9 @@ impl<'tcx> Scopes<'tcx> { } } - fn num_scopes_to(&self, region_scope: (region::Scope, SourceInfo), span: Span) -> usize { - let scope_count = 1 + self.scopes.iter().rev() - .position(|scope| scope.region_scope == region_scope.0) + fn num_scopes_above(&self, region_scope: region::Scope, span: Span) -> usize { + let scope_count = self.scopes.iter().rev() + .position(|scope| scope.region_scope == region_scope) .unwrap_or_else(|| { span_bug!(span, "region_scope {:?} does not enclose", region_scope) }); @@ -354,7 +354,7 @@ impl<'tcx> Scopes<'tcx> { /// Returns the topmost active scope, which is known to be alive until /// the next scope expression. - fn topmost(&self) -> region::Scope { + pub(super) fn topmost(&self) -> region::Scope { self.scopes.last().expect("topmost_scope: no scopes present").region_scope } @@ -514,7 +514,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { assert!(value.is_none(), "`return` and `break` should have a destination"); } - self.exit_scope(source_info.span, (region_scope, source_info), block, target_block); + self.exit_scope(source_info.span, region_scope, block, target_block); self.cfg.start_new_block().unit() } @@ -523,12 +523,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// needed. See module comment for details. pub fn exit_scope(&mut self, span: Span, - region_scope: (region::Scope, SourceInfo), + region_scope: region::Scope, mut block: BasicBlock, target: BasicBlock) { debug!("exit_scope(region_scope={:?}, block={:?}, target={:?})", region_scope, block, target); - let scope_count = self.scopes.num_scopes_to(region_scope, span); + let scope_count = self.scopes.num_scopes_above(region_scope, span); // If we are emitting a `drop` statement, we need to have the cached // diverge cleanup pads ready in case that drop panics. @@ -545,7 +545,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { continue; } let source_info = scope.source_info(span); - block = match scope.cached_exits.entry((target, region_scope.0)) { + block = match scope.cached_exits.entry((target, region_scope)) { Entry::Occupied(e) => { self.cfg.terminate(block, source_info, TerminatorKind::Goto { target: *e.get() }); @@ -851,8 +851,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // If constants and statics, we don't generate StorageLive for this // temporary, so don't try to generate StorageDead for it either. _ if self.local_scope().is_none() => (), - Operand::Copy(Place::Base(PlaceBase::Local(cond_temp))) - | Operand::Move(Place::Base(PlaceBase::Local(cond_temp))) => { + Operand::Copy(Place { + base: PlaceBase::Local(cond_temp), + projection: None, + }) + | Operand::Move(Place { + base: PlaceBase::Local(cond_temp), + projection: None, + }) => { // Manually drop the condition on both branches. let top_scope = self.scopes.scopes.last_mut().unwrap(); let top_drop_data = top_scope.drops.pop().unwrap(); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 887ef4b520..36d80d0cb5 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -11,7 +11,7 @@ use rustc::hir::def::DefKind; use rustc::hir::def_id::DefId; use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef}; use rustc::mir; -use rustc::ty::{self, TyCtxt, query::TyCtxtAt}; +use rustc::ty::{self, TyCtxt}; use rustc::ty::layout::{self, LayoutOf, VariantIdx}; use rustc::ty::subst::Subst; use rustc::traits::Reveal; @@ -20,9 +20,9 @@ use rustc_data_structures::fx::FxHashMap; use syntax::source_map::{Span, DUMMY_SP}; use crate::interpret::{self, - PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, + PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, Pointer, RawConst, ConstValue, - InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpretCx, StackPopCleanup, + InterpResult, InterpErrorInfo, GlobalId, InterpCx, StackPopCleanup, Allocation, AllocId, MemoryKind, Memory, snapshot, RefTracking, intern_const_alloc_recursive, }; @@ -34,7 +34,7 @@ const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000; /// Should be a power of two for performance reasons. const DETECTOR_SNAPSHOT_PERIOD: isize = 256; -/// The `InterpretCx` is only meant to be used to do field and index projections into constants for +/// The `InterpCx` is only meant to be used to do field and index projections into constants for /// `simd_shuffle` and const patterns in match arms. /// /// The function containing the `match` that is currently being analyzed may have generic bounds @@ -47,7 +47,7 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> CompileTimeEvalContext<'mir, 'tcx> { debug!("mk_eval_cx: {:?}", param_env); - InterpretCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new()) + InterpCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default()) } pub(crate) fn eval_promoted<'mir, 'tcx>( @@ -98,7 +98,7 @@ fn op_to_const<'tcx>( Ok(mplace) => { let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef { offset: ptr.offset, align: mplace.align, alloc } + ConstValue::ByRef { alloc, offset: ptr.offset } }, // see comment on `let try_as_immediate` above Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { @@ -109,10 +109,10 @@ fn op_to_const<'tcx>( // `Immediate` is when we are called from `const_field`, and that `Immediate` // comes from a constant so it can happen have `Undef`, because the indirect // memory that was read had undefined bytes. - let mplace = op.to_mem_place(); + let mplace = op.assert_mem_place(); let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef { offset: ptr.offset, align: mplace.align, alloc } + ConstValue::ByRef { alloc, offset: ptr.offset } }, }, Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { @@ -181,17 +181,17 @@ fn eval_body_using_ecx<'mir, 'tcx>( Ok(ret) } -impl<'tcx> Into> for ConstEvalError { - fn into(self) -> InterpErrorInfo<'tcx> { - InterpError::MachineError(self.to_string()).into() - } -} - #[derive(Clone, Debug)] enum ConstEvalError { NeedsRfc(String), } +impl<'tcx> Into> for ConstEvalError { + fn into(self) -> InterpErrorInfo<'tcx> { + err_unsup!(Unsupported(self.to_string())).into() + } +} + impl fmt::Display for ConstEvalError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::ConstEvalError::*; @@ -303,7 +303,7 @@ impl interpret::AllocMap for FxHashMap { } crate type CompileTimeEvalContext<'mir, 'tcx> = - InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; + InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; impl interpret::MayLeak for ! { #[inline(always)] @@ -316,6 +316,7 @@ impl interpret::MayLeak for ! { impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> { type MemoryKinds = !; type PointerTag = (); + type ExtraFnVal = !; type FrameExtra = (); type MemoryExtra = (); @@ -325,13 +326,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, const STATIC_KIND: Option = None; // no copying of statics allowed + // We do not check for alignment to avoid having to carry an `Align` + // in `ConstValue::ByRef`. + const CHECK_ALIGN: bool = false; + #[inline(always)] - fn enforce_validity(_ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool { + fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { false // for now, we don't enforce validity } fn find_fn( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], dest: Option>, @@ -340,7 +345,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, debug!("eval_fn_call: {:?}", instance); // Only check non-glue functions if let ty::InstanceDef::Item(def_id) = instance.def { - // Execution might have wandered off into other crates, so we cannot to a stability- + // Execution might have wandered off into other crates, so we cannot do a stability- // sensitive check here. But we can at least rule out functions that are not const // at all. if !ecx.tcx.is_const_fn_raw(def_id) { @@ -351,7 +356,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.goto_block(ret)?; // fully evaluated and done Ok(None) } else { - err!(MachineError(format!("calling non-const function `{}`", instance))) + throw_unsup_format!("calling non-const function `{}`", instance) }; } } @@ -359,7 +364,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, Ok(Some(match ecx.load_mir(instance.def) { Ok(body) => body, Err(err) => { - if let InterpError::NoMirFor(ref path) = err.kind { + if let err_unsup!(NoMirFor(ref path)) = err.kind { return Err( ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path)) .into(), @@ -370,8 +375,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, })) } + fn call_extra_fn( + _ecx: &mut InterpCx<'mir, 'tcx, Self>, + fn_val: !, + _args: &[OpTy<'tcx>], + _dest: Option>, + _ret: Option, + ) -> InterpResult<'tcx> { + match fn_val {} + } + fn call_intrinsic( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], dest: PlaceTy<'tcx>, @@ -386,8 +401,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) } - fn ptr_op( - _ecx: &InterpretCx<'mir, 'tcx, Self>, + fn ptr_to_int( + _mem: &Memory<'mir, 'tcx, Self>, + _ptr: Pointer, + ) -> InterpResult<'tcx, u64> { + Err( + ConstEvalError::NeedsRfc("pointer-to-integer cast".to_string()).into(), + ) + } + + fn binary_ptr_op( + _ecx: &InterpCx<'mir, 'tcx, Self>, _bin_op: mir::BinOp, _left: ImmTy<'tcx>, _right: ImmTy<'tcx>, @@ -398,18 +422,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn find_foreign_static( + _tcx: TyCtxt<'tcx>, _def_id: DefId, - _tcx: TyCtxtAt<'tcx>, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - err!(ReadForeignStatic) + throw_unsup!(ReadForeignStatic) } #[inline(always)] fn tag_allocation<'b>( + _memory_extra: &(), _id: AllocId, alloc: Cow<'b, Allocation>, _kind: Option>, - _memory: &Memory<'mir, 'tcx, Self>, ) -> (Cow<'b, Allocation>, Self::PointerTag) { // We do not use a tag so we can just cheaply forward the allocation (alloc, ()) @@ -417,14 +441,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, #[inline(always)] fn tag_static_base_pointer( + _memory_extra: &(), _id: AllocId, - _memory: &Memory<'mir, 'tcx, Self>, ) -> Self::PointerTag { () } fn box_alloc( - _ecx: &mut InterpretCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'mir, 'tcx, Self>, _dest: PlaceTy<'tcx>, ) -> InterpResult<'tcx> { Err( @@ -432,7 +456,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) } - fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { { let steps = &mut ecx.machine.steps_since_detector_enabled; @@ -457,13 +481,13 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } #[inline(always)] - fn stack_push(_ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { Ok(()) } /// Called immediately before a stack frame gets popped. #[inline(always)] - fn stack_pop(_ecx: &mut InterpretCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> { + fn stack_pop(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> { Ok(()) } } @@ -508,7 +532,7 @@ pub fn const_variant_index<'tcx>( } pub fn error_to_const_error<'mir, 'tcx>( - ecx: &InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, mut error: InterpErrorInfo<'tcx>, ) -> ConstEvalErr<'tcx> { error.print_backtrace(); @@ -541,9 +565,8 @@ fn validate_and_turn_into_const<'tcx>( let ptr = mplace.ptr.to_ptr()?; Ok(tcx.mk_const(ty::Const { val: ConstValue::ByRef { - offset: ptr.offset, - align: mplace.align, alloc: ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), + offset: ptr.offset, }, ty: mplace.layout.ty, })) @@ -632,7 +655,12 @@ pub fn const_eval_raw_provider<'tcx>( } let span = tcx.def_span(cid.instance.def_id()); - let mut ecx = InterpretCx::new(tcx.at(span), key.param_env, CompileTimeInterpreter::new()); + let mut ecx = InterpCx::new( + tcx.at(span), + key.param_env, + CompileTimeInterpreter::new(), + Default::default() + ); let res = ecx.load_mir(cid.instance.def); res.map(|body| { @@ -645,7 +673,7 @@ pub fn const_eval_raw_provider<'tcx>( |body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env) ).and_then(|place| { Ok(RawConst { - alloc_id: place.to_ptr().expect("we allocated this ptr!").alloc_id, + alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty }) }).map_err(|error| { @@ -681,8 +709,8 @@ pub fn const_eval_raw_provider<'tcx>( // promoting runtime code is only allowed to error if it references broken constants // any other kind of error will be reported to the user as a deny-by-default lint _ => if let Some(p) = cid.promoted { - let span = tcx.optimized_mir(def_id).promoted[p].span; - if let InterpError::ReferencedConstant = err.error { + let span = tcx.promoted_mir(def_id)[p].span; + if let err_inval!(ReferencedConstant) = err.error { err.report_as_error( tcx.at(span), "evaluation of constant expression failed", diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs index a73ec2ed8e..c071b3101f 100644 --- a/src/librustc_mir/dataflow/drop_flag_effects.rs +++ b/src/librustc_mir/dataflow/drop_flag_effects.rs @@ -14,8 +14,8 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>, { let mut next_child = move_data.move_paths[path].first_child; while let Some(child_index) = next_child { - match move_data.move_paths[child_index].place { - mir::Place::Projection(ref proj) => { + match move_data.move_paths[child_index].place.projection { + Some(ref proj) => { if cond(proj) { return Some(child_index) } @@ -171,7 +171,7 @@ pub(crate) fn drop_flag_effects_for_function_entry<'tcx, F>( let move_data = &ctxt.move_data; for arg in body.args_iter() { let place = mir::Place::from(arg); - let lookup_result = move_data.rev_lookup.find(&place); + let lookup_result = move_data.rev_lookup.find(place.as_ref()); on_lookup_result_bits(tcx, body, move_data, lookup_result, |mpi| callback(mpi, DropFlagState::Present)); diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 0f7f37f2db..d94ebdbae2 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -92,7 +92,7 @@ struct BorrowedLocalsVisitor<'gk> { trans: &'gk mut GenKillSet, } -fn find_local<'tcx>(place: &Place<'tcx>) -> Option { +fn find_local(place: &Place<'_>) -> Option { place.iterate(|place_base, place_projection| { for proj in place_projection { if proj.elem == ProjectionElem::Deref { diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index dcc6ba5ca0..018fd2e97b 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -2,7 +2,7 @@ use crate::borrow_check::borrow_set::{BorrowSet, BorrowData}; use crate::borrow_check::place_ext::PlaceExt; use rustc::mir::{self, Location, Place, PlaceBase, Body}; -use rustc::ty::TyCtxt; +use rustc::ty::{self, TyCtxt}; use rustc::ty::RegionVid; use rustc_data_structures::bit_set::BitSet; @@ -32,6 +32,7 @@ newtype_index! { pub struct Borrows<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, + param_env: ty::ParamEnv<'tcx>, borrow_set: Rc>, borrows_out_of_scope_at_location: FxHashMap>, @@ -137,6 +138,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { crate fn new( tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, + param_env: ty::ParamEnv<'tcx>, nonlexical_regioncx: Rc>, borrow_set: &Rc>, ) -> Self { @@ -153,6 +155,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { Borrows { tcx: tcx, body: body, + param_env, borrow_set: borrow_set.clone(), borrows_out_of_scope_at_location, _nonlexical_regioncx: nonlexical_regioncx, @@ -194,7 +197,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { ) { debug!("kill_borrows_on_place: place={:?}", place); - if let Some(local) = place.base_local() { + if let PlaceBase::Local(local) = place.base { let other_borrows_of_local = self .borrow_set .local_map @@ -205,7 +208,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { // If the borrowed place is a local with no projections, all other borrows of this // local must conflict. This is purely an optimization so we don't have to call // `places_conflict` for every borrow. - if let Place::Base(PlaceBase::Local(_)) = place { + if place.projection.is_none() { trans.kill_all(other_borrows_of_local); return; } @@ -218,6 +221,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { .filter(|&&i| { places_conflict::places_conflict( self.tcx, + self.param_env, self.body, &self.borrow_set.borrows[i].borrowed_place, place, diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index 065cfe8a4e..69bbe08792 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -309,7 +309,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). on_lookup_result_bits(self.tcx, self.body, self.move_data(), - self.move_data().rev_lookup.find(dest_place), + self.move_data().rev_lookup.find(dest_place.as_ref()), |mpi| { in_out.insert(mpi); }); } } @@ -367,7 +367,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { // when a call returns successfully, that means we need to set // the bits for that dest_place to 0 (initialized). on_lookup_result_bits(self.tcx, self.body, self.move_data(), - self.move_data().rev_lookup.find(dest_place), + self.move_data().rev_lookup.find(dest_place.as_ref()), |mpi| { in_out.remove(mpi); }); } } @@ -423,7 +423,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). on_lookup_result_bits(self.tcx, self.body, self.move_data(), - self.move_data().rev_lookup.find(dest_place), + self.move_data().rev_lookup.find(dest_place.as_ref()), |mpi| { in_out.insert(mpi); }); } } diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index 7fa950cb98..0e01701ea9 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -121,11 +121,15 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { StatementKind::StorageDead(l) => sets.kill(l), StatementKind::Assign(ref place, _) | StatementKind::SetDiscriminant { ref place, .. } => { - place.base_local().map(|l| sets.gen(l)); + if let PlaceBase::Local(local) = place.base { + sets.gen(local); + } } StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => { for p in &**outputs { - p.base_local().map(|l| sets.gen(l)); + if let PlaceBase::Local(local) = p.base { + sets.gen(local); + } } } _ => (), @@ -146,7 +150,9 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { _dest_bb: mir::BasicBlock, dest_place: &mir::Place<'tcx>, ) { - dest_place.base_local().map(|l| in_out.insert(l)); + if let PlaceBase::Local(local) = dest_place.base { + in_out.insert(local); + } } } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 5433a9013a..7fe2a890a5 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -314,12 +314,12 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> { fn visit_statement_entry(&mut self, _loc: Location, - _stmt: &Statement<'tcx>, + _stmt: &'a Statement<'tcx>, _flow_state: &Self::FlowState) {} fn visit_terminator_entry(&mut self, _loc: Location, - _term: &Terminator<'tcx>, + _term: &'a Terminator<'tcx>, _flow_state: &Self::FlowState) {} // Main entry point: this drives the processing of results. @@ -333,6 +333,8 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> { } fn process_basic_block(&mut self, bb: BasicBlock, flow_state: &mut Self::FlowState) { + self.visit_block_entry(bb, flow_state); + let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = self.body()[bb]; let mut location = Location { block: bb, statement_index: 0 }; @@ -587,10 +589,8 @@ impl GenKillSet { self.gen_set.insert(e); self.kill_set.remove(e); } - fn gen_all(&mut self, i: I) - where I: IntoIterator, - I::Item: Borrow - { + + fn gen_all(&mut self, i: impl IntoIterator>) { for j in i { self.gen(*j.borrow()); } @@ -601,10 +601,7 @@ impl GenKillSet { self.kill_set.insert(e); } - fn kill_all(&mut self, i: I) - where I: IntoIterator, - I::Item: Borrow - { + fn kill_all(&mut self, i: impl IntoIterator>) { for j in i { self.kill(*j.borrow()); } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index f282c276e0..366b96b53b 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -106,13 +106,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { for proj in place_projection { let body = self.builder.body; let tcx = self.builder.tcx; - let place_ty = proj.base.ty(body, tcx).ty; + let place_ty = Place::ty_from(place_base, &proj.base, body, tcx).ty; match place_ty.sty { ty::Ref(..) | ty::RawPtr(..) => return Err(MoveError::cannot_move_out_of( self.loc, BorrowedContent { - target_place: Place::Projection(Box::new(proj.clone())), + target_place: Place { + base: place_base.clone(), + projection: Some(Box::new(proj.clone())), + } })), ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => return Err(MoveError::cannot_move_out_of(self.loc, @@ -159,7 +162,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { &mut self.builder.data.path_map, &mut self.builder.data.init_path_map, Some(base), - Place::Projection(Box::new(proj.clone())), + Place { + base: place_base.clone(), + projection: Some(Box::new(proj.clone())), + }, ); ent.insert(path); path @@ -268,9 +274,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // move-path for the interior so it will be separate from // the exterior. self.create_move_path(&place.clone().deref()); - self.gather_init(place, InitKind::Shallow); + self.gather_init(place.as_ref(), InitKind::Shallow); } else { - self.gather_init(place, InitKind::Deep); + self.gather_init(place.as_ref(), InitKind::Deep); } self.gather_rvalue(rval); } @@ -280,7 +286,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { StatementKind::InlineAsm(ref asm) => { for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { if !kind.is_indirect { - self.gather_init(output, InitKind::Deep); + self.gather_init(output.as_ref(), InitKind::Deep); } } for (_, input) in asm.inputs.iter() { @@ -370,7 +376,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { TerminatorKind::DropAndReplace { ref location, ref value, .. } => { self.create_move_path(location); self.gather_operand(value); - self.gather_init(location, InitKind::Deep); + self.gather_init(location.as_ref(), InitKind::Deep); } TerminatorKind::Call { ref func, @@ -385,7 +391,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } if let Some((ref destination, _bb)) = *destination { self.create_move_path(destination); - self.gather_init(destination, InitKind::NonPanicPathOnly); + self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly); } } } @@ -420,22 +426,24 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.builder.data.loc_map[self.loc].push(move_out); } - fn gather_init(&mut self, place: &Place<'tcx>, kind: InitKind) { + fn gather_init(&mut self, place: PlaceRef<'cx, 'tcx>, kind: InitKind) { debug!("gather_init({:?}, {:?})", self.loc, place); - let place = match place { - // Check if we are assigning into a field of a union, if so, lookup the place - // of the union so it is marked as initialized again. - Place::Projection(box Projection { - base, - elem: ProjectionElem::Field(_, _), - }) if match base.ty(self.builder.body, self.builder.tcx).ty.sty { - ty::Adt(def, _) if def.is_union() => true, - _ => false, - } => base, - // Otherwise, lookup the place. - _ => place, - }; + let mut place = place; + + // Check if we are assigning into a field of a union, if so, lookup the place + // of the union so it is marked as initialized again. + if let Some(box Projection { base: proj_base, elem: ProjectionElem::Field(_, _) }) = + place.projection + { + if let ty::Adt(def, _) = + Place::ty_from(place.base, proj_base, self.builder.body, self.builder.tcx).ty.sty + { + if def.is_union() { + place = PlaceRef { base: place.base, projection: proj_base } + } + } + } if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) { let init = self.builder.data.inits.push(Init { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 938450c63a..5c2255882b 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -240,8 +240,8 @@ impl MovePathLookup { // alternative will *not* create a MovePath on the fly for an // unknown place, but will rather return the nearest available // parent. - pub fn find(&self, place: &Place<'tcx>) -> LookupResult { - place.iterate(|place_base, place_projection| { + pub fn find(&self, place_ref: PlaceRef<'cx, 'tcx>) -> LookupResult { + place_ref.iterate(|place_base, place_projection| { let mut result = match place_base { PlaceBase::Local(local) => self.locals[*local], PlaceBase::Static(..) => return LookupResult::Parent(None), @@ -318,7 +318,10 @@ impl<'tcx> MoveData<'tcx> { pub fn base_local(&self, mut mpi: MovePathIndex) -> Option { loop { let path = &self.move_paths[mpi]; - if let Place::Base(PlaceBase::Local(l)) = path.place { return Some(l); } + if let Place { + base: PlaceBase::Local(l), + projection: None, + } = path.place { return Some(l); } if let Some(parent) = path.parent { mpi = parent; continue } else { return None } } } diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index 4807782c66..86c263a447 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { @@ -331,7 +329,7 @@ An if-let pattern attempts to match the pattern, and enters the body if the match was successful. If the match is irrefutable (when it cannot fail to match), use a regular `let`-binding instead. For instance: -```compile_pass +``` struct Irrefutable(i32); let irr = Irrefutable(0); @@ -360,7 +358,7 @@ A while-let pattern attempts to match the pattern, and enters the body if the match was successful. If the match is irrefutable (when it cannot fail to match), use a regular `let`-binding inside a `loop` instead. For instance: -```compile_pass,no_run +```no_run struct Irrefutable(i32); let irr = Irrefutable(0); @@ -1991,7 +1989,7 @@ When matching on a variable it cannot be mutated in the match guards, as this could cause the match to be non-exhaustive: ```compile_fail,E0510 -#![feature(nll, bind_by_move_pattern_guards)] +#![feature(bind_by_move_pattern_guards)] let mut x = Some(0); match x { None => (), @@ -2029,7 +2027,6 @@ Local variables, function parameters and temporaries are all dropped before the end of the function body. So a reference to them cannot be returned. ```compile_fail,E0515 -#![feature(nll)] fn get_dangling_reference() -> &'static i32 { let x = 0; &x @@ -2037,7 +2034,6 @@ fn get_dangling_reference() -> &'static i32 { ``` ```compile_fail,E0515 -#![feature(nll)] use std::slice::Iter; fn get_dangling_iterator<'a>() -> Iter<'a, i32> { let v = vec![1, 2, 3]; @@ -2235,7 +2231,6 @@ function which outlived the lifetime of the function. Example of erroneous code: ```compile_fail,E0712 -#![feature(nll)] #![feature(thread_local)] #[thread_local] @@ -2288,8 +2283,6 @@ not run while the string-data is borrowed; for example by taking `S` by reference: ``` -#![feature(nll)] - pub struct S<'a> { data: &'a mut String } impl<'a> Drop for S<'a> { @@ -2314,7 +2307,6 @@ while a borrow is still in active use. Erroneous code example: ```compile_fail,E0716 -# #![feature(nll)] fn foo() -> i32 { 22 } fn bar(x: &i32) -> &i32 { x } let p = bar(&foo()); @@ -2462,12 +2454,12 @@ register_diagnostics! { // E0298, // cannot compare constants // E0299, // mismatched types between arms // E0471, // constant evaluation error (in pattern) -// E0385, // {} in an aliasable location +// E0385, // {} in an aliasable location E0493, // destructors cannot be evaluated at compile-time - E0521, // borrowed data escapes outside of closure + E0521, // borrowed data escapes outside of closure E0524, // two closures require unique access to `..` at the same time E0526, // shuffle indices are not constant E0594, // cannot assign to {} - E0598, // lifetime of {} is too short to guarantee its contents can be... +// E0598, // lifetime of {} is too short to guarantee its contents can be... E0625, // thread-local statics cannot be accessed at compile-time } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 94b4f6e8dd..1c6a743155 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -542,7 +542,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( // Now comes the rote stuff: hir::ExprKind::Repeat(ref v, ref count) => { - let def_id = cx.tcx.hir().local_def_id_from_hir_id(count.hir_id); + let def_id = cx.tcx.hir().local_def_id(count.hir_id); let substs = InternalSubsts::identity_for_item(cx.tcx.global_tcx(), def_id); let instance = ty::Instance::resolve( cx.tcx.global_tcx(), @@ -556,7 +556,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( }; let span = cx.tcx.def_span(def_id); let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) { - Ok(cv) => cv.unwrap_usize(cx.tcx), + Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), Err(ErrorHandled::Reported) => 0, Err(ErrorHandled::TooGeneric) => { cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters"); @@ -599,15 +599,8 @@ fn make_mirror_unadjusted<'a, 'tcx>( arms: arms.iter().map(|a| convert_arm(cx, a)).collect(), } } - hir::ExprKind::While(ref cond, ref body, _) => { - ExprKind::Loop { - condition: Some(cond.to_ref()), - body: block::to_expr_ref(cx, body), - } - } hir::ExprKind::Loop(ref body, _, _) => { ExprKind::Loop { - condition: None, body: block::to_expr_ref(cx, body), } } @@ -910,9 +903,9 @@ fn convert_path_expr<'a, 'tcx>( Res::Def(DefKind::ConstParam, def_id) => { let hir_id = cx.tcx.hir().as_local_hir_id(def_id).unwrap(); let item_id = cx.tcx.hir().get_parent_node(hir_id); - let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(item_id); + let item_def_id = cx.tcx.hir().local_def_id(item_id); let generics = cx.tcx.generics_of(item_def_id); - let local_def_id = cx.tcx.hir().local_def_id_from_hir_id(hir_id); + let local_def_id = cx.tcx.hir().local_def_id(hir_id); let index = generics.param_def_id_to_index[&local_def_id]; let name = cx.tcx.hir().name(hir_id).as_interned_str(); let val = ConstValue::Param(ty::ParamConst::new(index, name)); @@ -1191,7 +1184,7 @@ fn capture_upvar<'tcx>( ) -> ExprRef<'tcx> { let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_hir_id }, - closure_expr_id: cx.tcx.hir().local_def_id_from_hir_id(closure_expr.hir_id).to_local(), + closure_expr_id: cx.tcx.hir().local_def_id(closure_expr.hir_id).to_local(), }; let upvar_capture = cx.tables().upvar_capture(upvar_id); let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index a21d900cf5..3d9349df5b 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -54,7 +54,7 @@ pub struct Cx<'a, 'tcx> { impl<'a, 'tcx> Cx<'a, 'tcx> { pub fn new(infcx: &'a InferCtxt<'a, 'tcx>, src_id: hir::HirId) -> Cx<'a, 'tcx> { let tcx = infcx.tcx; - let src_def_id = tcx.hir().local_def_id_from_hir_id(src_id); + let src_def_id = tcx.hir().local_def_id(src_id); let tables = tcx.typeck_tables_of(src_def_id); let body_owner_kind = tcx.hir().body_owner_kind(src_id); diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs index 946d66fc91..c365cc2ad8 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir/hair/cx/to_ref.rs @@ -1,7 +1,7 @@ use crate::hair::*; use rustc::hir; -use syntax::ptr::P; +use rustc::hir::ptr::P; pub trait ToRef { type Output; diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 5431a31c4b..0638cb462f 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -173,7 +173,6 @@ pub enum ExprKind<'tcx> { source: ExprRef<'tcx>, }, Loop { - condition: Option>, body: ExprRef<'tcx>, }, Match { diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index fc2951895f..8a3d904e77 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -218,10 +218,8 @@ impl LiteralExpander<'tcx> { (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => { let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id); ConstValue::ByRef { - offset: p.offset, - // FIXME(oli-obk): this should be the type's layout - align: alloc.align, alloc, + offset: p.offset, } }, // unsize array to slice if pattern is array but match value or other patterns are slice @@ -230,7 +228,7 @@ impl LiteralExpander<'tcx> { ConstValue::Slice { data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id), start: p.offset.bytes().try_into().unwrap(), - end: n.unwrap_usize(self.tcx).try_into().unwrap(), + end: n.eval_usize(self.tcx, ty::ParamEnv::empty()).try_into().unwrap(), } }, // fat pointers stay the same @@ -648,8 +646,8 @@ fn all_constructors<'a, 'tcx>( ConstantValue(ty::Const::from_bool(cx.tcx, b)) }).collect() } - ty::Array(ref sub_ty, len) if len.assert_usize(cx.tcx).is_some() => { - let len = len.unwrap_usize(cx.tcx); + ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => { + let len = len.eval_usize(cx.tcx, cx.param_env); if len != 0 && cx.is_uninhabited(sub_ty) { vec![] } else { @@ -791,7 +789,7 @@ where match (value.val, &value.ty.sty) { (_, ty::Array(_, n)) => max_fixed_len = cmp::max( max_fixed_len, - n.unwrap_usize(cx.tcx), + n.eval_usize(cx.tcx, cx.param_env), ), (ConstValue::Slice{ start, end, .. }, ty::Slice(_)) => max_fixed_len = cmp::max( max_fixed_len, @@ -832,10 +830,14 @@ struct IntRange<'tcx> { } impl<'tcx> IntRange<'tcx> { - fn from_ctor(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) -> Option> { + fn from_ctor( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ctor: &Constructor<'tcx>, + ) -> Option> { // Floating-point ranges are permitted and we don't want // to consider them when constructing integer ranges. - fn is_integral<'tcx>(ty: Ty<'tcx>) -> bool { + fn is_integral(ty: Ty<'_>) -> bool { match ty.sty { ty::Char | ty::Int(_) | ty::Uint(_) => true, _ => false, @@ -858,7 +860,7 @@ impl<'tcx> IntRange<'tcx> { } ConstantValue(val) if is_integral(val.ty) => { let ty = val.ty; - if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) { + if let Some(val) = val.try_eval_bits(tcx, param_env, ty) { let bias = IntRange::signed_bias(tcx, ty); let val = val ^ bias; Some(IntRange { range: val..=val, ty }) @@ -870,13 +872,17 @@ impl<'tcx> IntRange<'tcx> { } } - fn from_pat(tcx: TyCtxt<'tcx>, mut pat: &Pattern<'tcx>) -> Option> { + fn from_pat( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + mut pat: &Pattern<'tcx>, + ) -> Option> { let range = loop { match pat.kind { box PatternKind::Constant { value } => break ConstantValue(value), box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange( - lo.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(), - hi.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(), + lo.eval_bits(tcx, param_env, ty), + hi.eval_bits(tcx, param_env, ty), ty, end, ), @@ -886,7 +892,7 @@ impl<'tcx> IntRange<'tcx> { _ => return None, } }; - Self::from_ctor(tcx, &range) + Self::from_ctor(tcx, param_env, &range) } // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it. @@ -921,10 +927,11 @@ impl<'tcx> IntRange<'tcx> { fn subtract_from( self, tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, ranges: Vec>, ) -> Vec> { let ranges = ranges.into_iter().filter_map(|r| { - IntRange::from_ctor(tcx, &r).map(|i| i.range) + IntRange::from_ctor(tcx, param_env, &r).map(|i| i.range) }); let mut remaining_ranges = vec![]; let ty = self.ty; @@ -991,6 +998,7 @@ enum MissingCtors<'tcx> { fn compute_missing_ctors<'tcx>( info: MissingCtorsInfo, tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, all_ctors: &Vec>, used_ctors: &Vec>, ) -> MissingCtors<'tcx> { @@ -1003,10 +1011,10 @@ fn compute_missing_ctors<'tcx>( // If a constructor appears in a `match` arm, we can // eliminate it straight away. refined_ctors = vec![] - } else if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) { + } else if let Some(interval) = IntRange::from_ctor(tcx, param_env, used_ctor) { // Refine the required constructors for the type by subtracting // the range defined by the current constructor pattern. - refined_ctors = interval.subtract_from(tcx, refined_ctors); + refined_ctors = interval.subtract_from(tcx, param_env, refined_ctors); } // If the constructor patterns that have been considered so far @@ -1121,7 +1129,9 @@ pub fn is_useful<'p, 'a, 'tcx>( if is_declared_nonexhaustive { Useful } else { - split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c| + split_grouped_constructors( + cx.tcx, cx.param_env, constructors, matrix, pcx.ty, + ).into_iter().map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) ).find(|result| result.is_useful()).unwrap_or(NotUseful) } @@ -1160,8 +1170,9 @@ pub fn is_useful<'p, 'a, 'tcx>( // non-wildcard patterns in the current column. We always determine if // the set is empty, but we only fully construct them on-demand, // because they're rarely used and can be big. - let cheap_missing_ctors = - compute_missing_ctors(MissingCtorsInfo::Emptiness, cx.tcx, &all_ctors, &used_ctors); + let cheap_missing_ctors = compute_missing_ctors( + MissingCtorsInfo::Emptiness, cx.tcx, cx.param_env, &all_ctors, &used_ctors, + ); let is_privately_empty = all_ctors.is_empty() && !cx.is_uninhabited(pcx.ty); let is_declared_nonexhaustive = cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty); @@ -1171,12 +1182,13 @@ pub fn is_useful<'p, 'a, 'tcx>( // For privately empty and non-exhaustive enums, we work as if there were an "extra" // `_` constructor for the type, so we can never match over all constructors. let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive || - (pcx.ty.is_pointer_sized() && !cx.tcx.features().precise_pointer_size_matching); + (pcx.ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching); if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive { - split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| { - is_useful_specialized(cx, matrix, v, c, pcx.ty, witness) - }).find(|result| result.is_useful()).unwrap_or(NotUseful) + split_grouped_constructors(cx.tcx, cx.param_env, all_ctors, matrix, pcx.ty) + .into_iter().map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)) + .find(|result| result.is_useful()) + .unwrap_or(NotUseful) } else { let matrix = rows.iter().filter_map(|r| { if r[0].is_wildcard() { @@ -1244,9 +1256,9 @@ pub fn is_useful<'p, 'a, 'tcx>( witness }).collect() } else { - let expensive_missing_ctors = - compute_missing_ctors(MissingCtorsInfo::Ctors, cx.tcx, &all_ctors, - &used_ctors); + let expensive_missing_ctors = compute_missing_ctors( + MissingCtorsInfo::Ctors, cx.tcx, cx.param_env, &all_ctors, &used_ctors, + ); if let MissingCtors::Ctors(missing_ctors) = expensive_missing_ctors { pats.into_iter().flat_map(|witness| { missing_ctors.iter().map(move |ctor| { @@ -1329,14 +1341,14 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>, PatternKind::Constant { value } => Some(vec![ConstantValue(value)]), PatternKind::Range(PatternRange { lo, hi, ty, end }) => Some(vec![ConstantRange( - lo.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(), - hi.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(), + lo.eval_bits(cx.tcx, cx.param_env, ty), + hi.eval_bits(cx.tcx, cx.param_env, ty), ty, end, )]), PatternKind::Array { .. } => match pcx.ty.sty { ty::Array(_, length) => Some(vec![ - Slice(length.unwrap_usize(cx.tcx)) + Slice(length.eval_usize(cx.tcx, cx.param_env)) ]), _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty) }, @@ -1404,7 +1416,8 @@ fn constructor_sub_pattern_tys<'a, 'tcx>( match ty.sty { // If the field type returned is an array of an unknown // size return an TyErr. - ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() => + ty::Array(_, len) + if len.try_eval_usize(cx.tcx, cx.param_env).is_none() => cx.tcx.types.err, _ => ty, } @@ -1434,11 +1447,12 @@ fn slice_pat_covered_by_const<'tcx>( prefix: &[Pattern<'tcx>], slice: &Option>, suffix: &[Pattern<'tcx>], + param_env: ty::ParamEnv<'tcx>, ) -> Result { let data: &[u8] = match (const_val.val, &const_val.ty.sty) { (ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => { assert_eq!(*t, tcx.types.u8); - let n = n.assert_usize(tcx).unwrap(); + let n = n.eval_usize(tcx, param_env); let ptr = Pointer::new(AllocId(0), offset); alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap() }, @@ -1466,7 +1480,7 @@ fn slice_pat_covered_by_const<'tcx>( { match pat.kind { box PatternKind::Constant { value } => { - let b = value.unwrap_bits(tcx, ty::ParamEnv::empty().and(pat.ty)); + let b = value.eval_bits(tcx, param_env, pat.ty); assert_eq!(b as u8 as u128, b); if b as u8 != *ch { return Ok(false); @@ -1488,7 +1502,7 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) _ => return false, }; if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty { - !ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching + !ty.is_ptr_sized_integral() || tcx.features().precise_pointer_size_matching } else { false } @@ -1528,6 +1542,7 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) /// merging operation depicted above.) fn split_grouped_constructors<'p, 'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, ctors: Vec>, &Matrix(ref m): &Matrix<'p, 'tcx>, ty: Ty<'tcx>, @@ -1542,7 +1557,7 @@ fn split_grouped_constructors<'p, 'tcx>( // We only care about finding all the subranges within the range of the constructor // range. Anything else is irrelevant, because it is guaranteed to result in // `NotUseful`, which is the default case anyway, and can be ignored. - let ctor_range = IntRange::from_ctor(tcx, &ctor).unwrap(); + let ctor_range = IntRange::from_ctor(tcx, param_env, &ctor).unwrap(); /// Represents a border between 2 integers. Because the intervals spanning borders /// must be able to cover every integer, we need to be able to represent @@ -1567,7 +1582,7 @@ fn split_grouped_constructors<'p, 'tcx>( // `borders` is the set of borders between equivalence classes: each equivalence // class lies between 2 borders. let row_borders = m.iter() - .flat_map(|row| IntRange::from_pat(tcx, row[0])) + .flat_map(|row| IntRange::from_pat(tcx, param_env, row[0])) .flat_map(|range| ctor_range.intersection(&range)) .flat_map(|range| range_borders(range)); let ctor_borders = range_borders(ctor_range.clone()); @@ -1606,11 +1621,12 @@ fn split_grouped_constructors<'p, 'tcx>( /// Checks whether there exists any shared value in either `ctor` or `pat` by intersecting them. fn constructor_intersects_pattern<'p, 'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, ctor: &Constructor<'tcx>, pat: &'p Pattern<'tcx>, ) -> Option; 2]>> { if should_treat_range_exhaustively(tcx, ctor) { - match (IntRange::from_ctor(tcx, ctor), IntRange::from_pat(tcx, pat)) { + match (IntRange::from_ctor(tcx, param_env, ctor), IntRange::from_pat(tcx, param_env, pat)) { (Some(ctor), Some(pat)) => { ctor.intersection(&pat).map(|_| { let (pat_lo, pat_hi) = pat.range.into_inner(); @@ -1625,7 +1641,7 @@ fn constructor_intersects_pattern<'p, 'tcx>( // Fallback for non-ranges and ranges that involve floating-point numbers, which are not // conveniently handled by `IntRange`. For these cases, the constructor may not be a range // so intersection actually devolves into being covered by the pattern. - match constructor_covered_by_range(tcx, ctor, pat) { + match constructor_covered_by_range(tcx, param_env, ctor, pat) { Ok(true) => Some(smallvec![]), Ok(false) | Err(ErrorReported) => None, } @@ -1634,6 +1650,7 @@ fn constructor_intersects_pattern<'p, 'tcx>( fn constructor_covered_by_range<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, ctor: &Constructor<'tcx>, pat: &Pattern<'tcx>, ) -> Result { @@ -1643,9 +1660,9 @@ fn constructor_covered_by_range<'tcx>( _ => bug!("`constructor_covered_by_range` called with {:?}", pat), }; trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty); - let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, ty::ParamEnv::empty().and(ty)) + let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, param_env, ty) .map(|res| res != Ordering::Less); - let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, ty::ParamEnv::empty().and(ty)); + let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, param_env, ty); macro_rules! some_or_ok { ($e:expr) => { match $e { @@ -1762,7 +1779,7 @@ fn specialize<'p, 'a: 'p, 'tcx>( ConstValue::ByRef { offset, alloc, .. } => ( alloc, offset, - n.unwrap_usize(cx.tcx), + n.eval_usize(cx.tcx, cx.param_env), t, ), _ => span_bug!( @@ -1823,7 +1840,7 @@ fn specialize<'p, 'a: 'p, 'tcx>( // If the constructor is a: // Single value: add a row if the constructor equals the pattern. // Range: add a row if the constructor contains the pattern. - constructor_intersects_pattern(cx.tcx, constructor, pat) + constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat) } } } @@ -1832,7 +1849,7 @@ fn specialize<'p, 'a: 'p, 'tcx>( // If the constructor is a: // Single value: add a row if the pattern contains the constructor. // Range: add a row if the constructor intersects the pattern. - constructor_intersects_pattern(cx.tcx, constructor, pat) + constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat) } PatternKind::Array { ref prefix, ref slice, ref suffix } | @@ -1856,7 +1873,9 @@ fn specialize<'p, 'a: 'p, 'tcx>( } } ConstantValue(cv) => { - match slice_pat_covered_by_const(cx.tcx, pat.span, cv, prefix, slice, suffix) { + match slice_pat_covered_by_const( + cx.tcx, pat.span, cv, prefix, slice, suffix, cx.param_env, + ) { Ok(true) => Some(smallvec![]), Ok(false) => None, Err(ErrorReported) => None diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index ed850379af..17fd9377a1 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -4,6 +4,7 @@ use super::_match::WitnessPreference::*; use super::{Pattern, PatternContext, PatternError, PatternKind}; +use rustc::middle::borrowck::SignalledError; use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor as euv; @@ -18,32 +19,35 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc::hir::def::*; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use rustc::hir::ptr::P; use rustc::hir::{self, Pat, PatKind}; use smallvec::smallvec; use std::slice; -use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -pub(crate) fn check_match<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) -> SignalledError { let body_id = if let Some(id) = tcx.hir().as_local_hir_id(def_id) { tcx.hir().body_owned_by(id) } else { - return; + return SignalledError::NoErrorsSeen; }; - MatchVisitor { + let mut visitor = MatchVisitor { tcx, body_owner: def_id, tables: tcx.body_tables(body_id), region_scope_tree: &tcx.region_scope_tree(def_id), param_env: tcx.param_env(def_id), identity_substs: InternalSubsts::identity_for_item(tcx, def_id), - }.visit_body(tcx.hir().body(body_id)); + signalled_error: SignalledError::NoErrorsSeen, + }; + visitor.visit_body(tcx.hir().body(body_id)); + visitor.signalled_error } -fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> DiagnosticBuilder<'a> { +fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> { struct_span_err!(sess, sp, E0004, "{}", &error_message) } @@ -54,6 +58,7 @@ struct MatchVisitor<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, identity_substs: SubstsRef<'tcx>, region_scope_tree: &'a region::ScopeTree, + signalled_error: SignalledError, } impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { @@ -64,11 +69,8 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { fn visit_expr(&mut self, ex: &'tcx hir::Expr) { intravisit::walk_expr(self, ex); - match ex.node { - hir::ExprKind::Match(ref scrut, ref arms, source) => { - self.check_match(scrut, arms, source); - } - _ => {} + if let hir::ExprKind::Match(ref scrut, ref arms, source) = ex.node { + self.check_match(scrut, arms, source); } } @@ -130,7 +132,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { - fn check_patterns(&self, has_guard: bool, pats: &[P]) { + fn check_patterns(&mut self, has_guard: bool, pats: &[P]) { check_legality_of_move_bindings(self, has_guard, pats); for pat in pats { check_legality_of_bindings_in_at_patterns(self, pat); @@ -138,11 +140,11 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } fn check_match( - &self, + &mut self, scrut: &hir::Expr, arms: &'tcx [hir::Arm], - source: hir::MatchSource) - { + source: hir::MatchSource + ) { for arm in arms { // First, check legality of move bindings. self.check_patterns(arm.guard.is_some(), &arm.pats); @@ -150,6 +152,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { // Second, if there is a guard on each arm, make sure it isn't // assigning or borrowing anything mutably. if let Some(ref guard) = arm.guard { + self.signalled_error = SignalledError::SawSomeError; if !self.tcx.features().bind_by_move_pattern_guards { check_for_mutation_in_guard(self, &guard); } @@ -170,6 +173,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { let mut patcx = PatternContext::new(self.tcx, self.param_env.and(self.identity_substs), self.tables); + patcx.include_lint_checks(); let pattern = expand_pattern(cx, patcx.lower_pattern(&pat)); if !patcx.errors.is_empty() { patcx.report_inlining_errors(pat.span); @@ -266,6 +270,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { let mut patcx = PatternContext::new(self.tcx, self.param_env.and(self.identity_substs), self.tables); + patcx.include_lint_checks(); let pattern = patcx.lower_pattern(pat); let pattern_ty = pattern.ty; let pats: Matrix<'_, '_> = vec![smallvec![ @@ -371,7 +376,8 @@ fn check_arms<'a, 'tcx>( match is_useful(cx, &seen, &v, LeaveOutWitness) { NotUseful => { match source { - hir::MatchSource::IfDesugar { .. } => bug!(), + hir::MatchSource::IfDesugar { .. } | + hir::MatchSource::WhileDesugar => bug!(), hir::MatchSource::IfLetDesugar { .. } => { cx.tcx.lint_hir( lint::builtin::IRREFUTABLE_LET_PATTERNS, @@ -545,7 +551,7 @@ fn maybe_point_at_variant( // Legality of move bindings checking fn check_legality_of_move_bindings( - cx: &MatchVisitor<'_, '_>, + cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pats: &[P], ) { @@ -562,7 +568,12 @@ fn check_legality_of_move_bindings( }) } let span_vec = &mut Vec::new(); - let check_move = |p: &Pat, sub: Option<&Pat>, span_vec: &mut Vec| { + let check_move = | + cx: &mut MatchVisitor<'_, '_>, + p: &Pat, + sub: Option<&Pat>, + span_vec: &mut Vec, + | { // check legality of moving out of the enum // x @ Foo(..) is legal, but x @ Foo(y) isn't. @@ -571,15 +582,17 @@ fn check_legality_of_move_bindings( "cannot bind by-move with sub-bindings") .span_label(p.span, "binds an already bound by-move value by moving it") .emit(); - } else if has_guard && !cx.tcx.features().bind_by_move_pattern_guards { - let mut err = struct_span_err!(cx.tcx.sess, p.span, E0008, - "cannot bind by-move into a pattern guard"); - err.span_label(p.span, "moves value into pattern guard"); - if cx.tcx.sess.opts.unstable_features.is_nightly_build() { - err.help("add #![feature(bind_by_move_pattern_guards)] to the \ - crate attributes to enable"); + } else if has_guard { + if !cx.tcx.features().bind_by_move_pattern_guards { + let mut err = struct_span_err!(cx.tcx.sess, p.span, E0008, + "cannot bind by-move into a pattern guard"); + err.span_label(p.span, "moves value into pattern guard"); + if cx.tcx.sess.opts.unstable_features.is_nightly_build() { + err.help("add `#![feature(bind_by_move_pattern_guards)]` to the \ + crate attributes to enable"); + } + err.emit(); } - err.emit(); } else if let Some(_by_ref_span) = by_ref_span { span_vec.push(p.span); } @@ -593,7 +606,7 @@ fn check_legality_of_move_bindings( ty::BindByValue(..) => { let pat_ty = cx.tables.node_type(p.hir_id); if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { - check_move(p, sub.as_ref().map(|p| &**p), span_vec); + check_move(cx, p, sub.as_ref().map(|p| &**p), span_vec); } } _ => {} @@ -663,7 +676,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> { "cannot mutably borrow in a pattern guard"); err.span_label(span, "borrowed mutably in pattern guard"); if self.cx.tcx.sess.opts.unstable_features.is_nightly_build() { - err.help("add #![feature(bind_by_move_pattern_guards)] to the \ + err.help("add `#![feature(bind_by_move_pattern_guards)]` to the \ crate attributes to enable"); } err.emit(); diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index cf597ce0b6..c82bb5d2ed 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -10,9 +10,11 @@ use crate::const_eval::const_variant_index; use crate::hair::util::UserAnnotatedTyHelpers; use crate::hair::constant::*; +use rustc::lint; use rustc::mir::{Field, BorrowKind, Mutability}; use rustc::mir::{UserTypeProjection}; use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer}; +use rustc::traits::{ObligationCause, PredicateObligation}; use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree}; use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc::ty::subst::{SubstsRef, Kind}; @@ -20,13 +22,14 @@ use rustc::ty::layout::{VariantIdx, Size}; use rustc::hir::{self, PatKind, RangeEnd}; use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; +use rustc::hir::ptr::P; use rustc_data_structures::indexed_vec::Idx; +use rustc_data_structures::fx::FxHashSet; use std::cmp::Ordering; use std::fmt; use syntax::ast; -use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::Span; @@ -159,7 +162,7 @@ pub enum PatternKind<'tcx> { /// Matches against a slice, checking the length and extracting elements. /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty. - /// e.g., `&[ref xs..]`. + /// e.g., `&[ref xs @ ..]`. Slice { prefix: Vec>, slice: Option>, @@ -332,6 +335,7 @@ pub struct PatternContext<'a, 'tcx> { pub tables: &'a ty::TypeckTables<'tcx>, pub substs: SubstsRef<'tcx>, pub errors: Vec, + include_lint_checks: bool, } impl<'a, 'tcx> Pattern<'tcx> { @@ -363,10 +367,16 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { param_env: param_env_and_substs.param_env, tables, substs: param_env_and_substs.value, - errors: vec![] + errors: vec![], + include_lint_checks: false, } } + pub fn include_lint_checks(&mut self) -> &mut Self { + self.include_lint_checks = true; + self + } + pub fn lower_pattern(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> { // When implicit dereferences have been inserted in this pattern, the unadjusted lowered // pattern has the type that results *after* dereferencing. For example, in this code: @@ -436,7 +446,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { self.tcx, lo, hi, - self.param_env.and(ty), + self.param_env, + ty, ); match (end, cmp) { (RangeEnd::Excluded, Some(Ordering::Less)) => @@ -718,7 +729,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Array(_, len) => { // fixed-length array - let len = len.unwrap_usize(self.tcx); + let len = len.eval_usize(self.tcx, self.param_env); assert!(len >= prefix.len() as u64 + suffix.len() as u64); PatternKind::Array { prefix: prefix, slice: slice, suffix: suffix } } @@ -942,7 +953,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { /// Converts an evaluated constant to a pattern (if possible). /// This means aggregate values (like structs and enums) are converted - /// to a pattern that matches the value (as if you'd compared via equality). + /// to a pattern that matches the value (as if you'd compared via structural equality). fn const_to_pat( &self, instance: ty::Instance<'tcx>, @@ -950,15 +961,86 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { id: hir::HirId, span: Span, ) -> Pattern<'tcx> { + // This method is just a warpper handling a validity check; the heavy lifting is + // performed by the recursive const_to_pat_inner method, which is not meant to be + // invoked except by this method. + // + // once indirect_structural_match is a full fledged error, this + // level of indirection can be eliminated + debug!("const_to_pat: cv={:#?} id={:?}", cv, id); - let adt_subpattern = |i, variant_opt| { + debug!("const_to_pat: cv.ty={:?} span={:?}", cv.ty, span); + + let mut saw_error = false; + let inlined_const_as_pat = self.const_to_pat_inner(instance, cv, id, span, &mut saw_error); + + if self.include_lint_checks && !saw_error { + // If we were able to successfully convert the const to some pat, double-check + // that the type of the const obeys `#[structural_match]` constraint. + if let Some(adt_def) = search_for_adt_without_structural_match(self.tcx, cv.ty) { + + let path = self.tcx.def_path_str(adt_def.did); + let msg = format!( + "to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + path, + path, + ); + + // before issuing lint, double-check there even *is* a + // semantic PartialEq for us to dispatch to. + // + // (If there isn't, then we can safely issue a hard + // error, because that's never worked, due to compiler + // using PartialEq::eq in this scenario in the past.) + + let ty_is_partial_eq: bool = { + let partial_eq_trait_id = self.tcx.lang_items().eq_trait().unwrap(); + let obligation: PredicateObligation<'_> = + self.tcx.predicate_for_trait_def(self.param_env, + ObligationCause::misc(span, id), + partial_eq_trait_id, + 0, + cv.ty, + &[]); + self.tcx + .infer_ctxt() + .enter(|infcx| infcx.predicate_may_hold(&obligation)) + }; + + if !ty_is_partial_eq { + // span_fatal avoids ICE from resolution of non-existent method (rare case). + self.tcx.sess.span_fatal(span, &msg); + } else { + self.tcx.lint_hir(lint::builtin::INDIRECT_STRUCTURAL_MATCH, id, span, &msg); + } + } + } + + inlined_const_as_pat + } + + /// Recursive helper for `const_to_pat`; invoke that (instead of calling this directly). + fn const_to_pat_inner( + &self, + instance: ty::Instance<'tcx>, + cv: &'tcx ty::Const<'tcx>, + id: hir::HirId, + span: Span, + // This tracks if we signal some hard error for a given const + // value, so that we will not subsequently issue an irrelevant + // lint for the same const value. + saw_const_match_error: &mut bool, + ) -> Pattern<'tcx> { + + let mut adt_subpattern = |i, variant_opt| { let field = Field::new(i); let val = crate::const_eval::const_field( self.tcx, self.param_env, variant_opt, field, cv ); - self.const_to_pat(instance, val, id, span) + self.const_to_pat_inner(instance, val, id, span, saw_const_match_error) }; - let adt_subpatterns = |n, variant_opt| { + let mut adt_subpatterns = |n, variant_opt| { (0..n).map(|i| { let field = Field::new(i); FieldPattern { @@ -967,7 +1049,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } }).collect::>() }; - debug!("const_to_pat: cv.ty={:?} span={:?}", cv.ty, span); + + let kind = match cv.ty.sty { ty::Float(_) => { self.tcx.lint_hir( @@ -982,9 +1065,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } ty::Adt(adt_def, _) if adt_def.is_union() => { // Matching on union fields is unsafe, we can't hide it in constants + *saw_const_match_error = true; self.tcx.sess.span_err(span, "cannot use unions in constant patterns"); PatternKind::Wild } + // keep old code until future-compat upgraded to errors. ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => { let path = self.tcx.def_path_str(adt_def.did); let msg = format!( @@ -993,9 +1078,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { path, path, ); + *saw_const_match_error = true; self.tcx.sess.span_err(span, &msg); PatternKind::Wild } + // keep old code until future-compat upgraded to errors. ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => { // HACK(estebank): Side-step ICE #53708, but anything other than erroring here @@ -1007,6 +1094,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { path, path, ); + *saw_const_match_error = true; self.tcx.sess.span_err(span, &msg); PatternKind::Wild } @@ -1036,7 +1124,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } ty::Array(_, n) => { PatternKind::Array { - prefix: (0..n.unwrap_usize(self.tcx)) + prefix: (0..n.eval_usize(self.tcx, self.param_env)) .map(|i| adt_subpattern(i as usize, None)) .collect(), slice: None, @@ -1058,6 +1146,127 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } } +/// This method traverses the structure of `ty`, trying to find an +/// instance of an ADT (i.e. struct or enum) that was declared without +/// the `#[structural_match]` attribute. +/// +/// The "structure of a type" includes all components that would be +/// considered when doing a pattern match on a constant of that +/// type. +/// +/// * This means this method descends into fields of structs/enums, +/// and also descends into the inner type `T` of `&T` and `&mut T` +/// +/// * The traversal doesn't dereference unsafe pointers (`*const T`, +/// `*mut T`), and it does not visit the type arguments of an +/// instantiated generic like `PhantomData`. +/// +/// The reason we do this search is Rust currently require all ADT's +/// reachable from a constant's type to be annotated with +/// `#[structural_match]`, an attribute which essentially says that +/// the implementation of `PartialEq::eq` behaves *equivalently* to a +/// comparison against the unfolded structure. +/// +/// For more background on why Rust has this requirement, and issues +/// that arose when the requirement was not enforced completely, see +/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. +fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>) + -> Option<&'tcx AdtDef> +{ + // Import here (not mod level), because `TypeFoldable::fold_with` + // conflicts with `PatternFoldable::fold_with` + use crate::rustc::ty::fold::TypeVisitor; + use crate::rustc::ty::TypeFoldable; + + let mut search = Search { tcx, found: None, seen: FxHashSet::default() }; + ty.visit_with(&mut search); + return search.found; + + struct Search<'tcx> { + tcx: TyCtxt<'tcx>, + + // records the first ADT we find without `#[structural_match` + found: Option<&'tcx AdtDef>, + + // tracks ADT's previously encountered during search, so that + // we will not recur on them again. + seen: FxHashSet<&'tcx AdtDef>, + } + + impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { + debug!("Search visiting ty: {:?}", ty); + + let (adt_def, substs) = match ty.sty { + ty::Adt(adt_def, substs) => (adt_def, substs), + ty::RawPtr(..) => { + // `#[structural_match]` ignores substructure of + // `*const _`/`*mut _`, so skip super_visit_with + // + // (But still tell caller to continue search.) + return false; + } + ty::FnDef(..) | ty::FnPtr(..) => { + // types of formals and return in `fn(_) -> _` are also irrelevant + // + // (But still tell caller to continue search.) + return false; + } + ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0) + => { + // rust-lang/rust#62336: ignore type of contents + // for empty array. + return false; + } + _ => { + ty.super_visit_with(self); + return false; + } + }; + + if !self.tcx.has_attr(adt_def.did, sym::structural_match) { + self.found = Some(&adt_def); + debug!("Search found adt_def: {:?}", adt_def); + return true // Halt visiting! + } + + if self.seen.contains(adt_def) { + debug!("Search already seen adt_def: {:?}", adt_def); + // let caller continue its search + return false; + } + + self.seen.insert(adt_def); + + // `#[structural_match]` does not care about the + // instantiation of the generics in an ADT (it + // instead looks directly at its fields outside + // this match), so we skip super_visit_with. + // + // (Must not recur on substs for `PhantomData` cf + // rust-lang/rust#55028 and rust-lang/rust#55837; but also + // want to skip substs when only uses of generic are + // behind unsafe pointers `*const T`/`*mut T`.) + + // even though we skip super_visit_with, we must recur on + // fields of ADT. + let tcx = self.tcx; + for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) { + if field_ty.visit_with(self) { + // found an ADT without `#[structural_match]`; halt visiting! + assert!(self.found.is_some()); + return true; + } + } + + // Even though we do not want to recur on substs, we do + // want our caller to continue its own search. + false + } + } +} + impl UserAnnotatedTyHelpers<'tcx> for PatternContext<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx @@ -1250,7 +1459,8 @@ pub fn compare_const_vals<'tcx>( tcx: TyCtxt<'tcx>, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, - ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, ) -> Option { trace!("compare_const_vals: {:?}, {:?}", a, b); @@ -1265,15 +1475,16 @@ pub fn compare_const_vals<'tcx>( let fallback = || from_bool(a == b); // Use the fallback if any type differs - if a.ty != b.ty || a.ty != ty.value { + if a.ty != b.ty || a.ty != ty { return fallback(); } - // FIXME: This should use assert_bits(ty) instead of use_bits - // but triggers possibly bugs due to mismatching of arrays and slices - if let (Some(a), Some(b)) = (a.to_bits(tcx, ty), b.to_bits(tcx, ty)) { + let a_bits = a.try_eval_bits(tcx, param_env, ty); + let b_bits = b.try_eval_bits(tcx, param_env, ty); + + if let (Some(a), Some(b)) = (a_bits, b_bits) { use ::rustc_apfloat::Float; - return match ty.value.sty { + return match ty.sty { ty::Float(ast::FloatTy::F32) => { let l = ::rustc_apfloat::ieee::Single::from_bits(a); let r = ::rustc_apfloat::ieee::Single::from_bits(b); @@ -1296,7 +1507,7 @@ pub fn compare_const_vals<'tcx>( } } - if let ty::Str = ty.value.sty { + if let ty::Str = ty.sty { match (a.val, b.val) { ( ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a }, diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index fbacdf6cd9..26cfbfe53a 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -1,28 +1,19 @@ use rustc::ty::{self, Ty, TypeAndMut}; use rustc::ty::layout::{self, TyLayout, Size}; use rustc::ty::adjustment::{PointerCast}; -use syntax::ast::{FloatTy, IntTy, UintTy}; +use syntax::ast::FloatTy; use syntax::symbol::sym; use rustc_apfloat::ieee::{Single, Double}; use rustc_apfloat::{Float, FloatConvert}; use rustc::mir::interpret::{ - Scalar, InterpResult, Pointer, PointerArithmetic, InterpError, + Scalar, InterpResult, PointerArithmetic, }; use rustc::mir::CastKind; -use super::{InterpretCx, Machine, PlaceTy, OpTy, Immediate}; - -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { - fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { - match ty.sty { - ty::RawPtr(ty::TypeAndMut { ty, .. }) | - ty::Ref(_, ty, _) => !self.type_is_sized(ty), - ty::Adt(def, _) if def.is_box() => !self.type_is_sized(ty.boxed_ty()), - _ => false, - } - } +use super::{InterpCx, Machine, PlaceTy, OpTy, ImmTy, Immediate, FnVal}; +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn cast( &mut self, src: OpTy<'tcx, M::PointerTag>, @@ -37,40 +28,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { Misc | Pointer(PointerCast::MutToConstPointer) => { let src = self.read_immediate(src)?; - - if self.type_is_fat_ptr(src.layout.ty) { - match (*src, self.type_is_fat_ptr(dest.layout.ty)) { - // pointers to extern types - (Immediate::Scalar(_),_) | - // slices and trait objects to other slices/trait objects - (Immediate::ScalarPair(..), true) => { - // No change to immediate - self.write_immediate(*src, dest)?; - } - // slices and trait objects to thin pointers (dropping the metadata) - (Immediate::ScalarPair(data, _), false) => { - self.write_scalar(data, dest)?; - } - } - } else { - match src.layout.variants { - layout::Variants::Single { index } => { - if let Some(discr) = - src.layout.ty.discriminant_for_variant(*self.tcx, index) - { - // Cast from a univariant enum - assert!(src.layout.is_zst()); - return self.write_scalar( - Scalar::from_uint(discr.val, dest.layout.size), - dest); - } - } - layout::Variants::Multiple { .. } => {}, - } - - let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?; - self.write_scalar(dest_val, dest)?; - } + let res = self.cast_immediate(src, dest.layout)?; + self.write_immediate(res, dest)?; } Pointer(PointerCast::ReifyFnPointer) => { @@ -80,13 +39,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { if self.tcx.has_attr(def_id, sym::rustc_args_required_const) { bug!("reifying a fn ptr that requires const arguments"); } - let instance: InterpResult<'tcx, _> = ty::Instance::resolve( + let instance = ty::Instance::resolve( *self.tcx, self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::TooGeneric.into()); - let fn_ptr = self.memory.create_fn_alloc(instance?); + ).ok_or_else(|| err_inval!(TooGeneric))?; + let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } _ => bug!("reify fn pointer on {:?}", src.layout.ty), @@ -115,7 +74,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { substs, ty::ClosureKind::FnOnce, ); - let fn_ptr = self.memory.create_fn_alloc(instance); + let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into()); self.write_immediate(val, dest)?; } @@ -126,36 +85,76 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { Ok(()) } - fn cast_scalar( + fn cast_immediate( &self, - val: Scalar, - src_layout: TyLayout<'tcx>, + src: ImmTy<'tcx, M::PointerTag>, dest_layout: TyLayout<'tcx>, - ) -> InterpResult<'tcx, Scalar> { + ) -> InterpResult<'tcx, Immediate> { use rustc::ty::TyKind::*; - trace!("Casting {:?}: {:?} to {:?}", val, src_layout.ty, dest_layout.ty); + trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, dest_layout.ty); - match src_layout.ty.sty { + match src.layout.ty.sty { // Floating point - Float(FloatTy::F32) => self.cast_from_float(val.to_f32()?, dest_layout.ty), - Float(FloatTy::F64) => self.cast_from_float(val.to_f64()?, dest_layout.ty), - // Integer(-like), including fn ptr casts and casts from enums that - // are represented as integers (this excludes univariant enums, which - // are handled in `cast` directly). - _ => { + Float(FloatTy::F32) => + return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty)?.into()), + Float(FloatTy::F64) => + return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty)?.into()), + // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that + // are represented as integers. + _ => assert!( - src_layout.ty.is_bool() || src_layout.ty.is_char() || - src_layout.ty.is_enum() || src_layout.ty.is_integral() || - src_layout.ty.is_unsafe_ptr() || src_layout.ty.is_fn_ptr() || - src_layout.ty.is_region_ptr(), - "Unexpected cast from type {:?}", src_layout.ty - ); - match val.to_bits_or_ptr(src_layout.size, self) { - Err(ptr) => self.cast_from_ptr(ptr, dest_layout.ty), - Ok(data) => self.cast_from_int(data, src_layout, dest_layout), + src.layout.ty.is_bool() || src.layout.ty.is_char() || + src.layout.ty.is_enum() || src.layout.ty.is_integral() || + src.layout.ty.is_any_ptr(), + "Unexpected cast from type {:?}", src.layout.ty + ) + } + + // Handle cast from a univariant (ZST) enum. + match src.layout.variants { + layout::Variants::Single { index } => { + if let Some(discr) = + src.layout.ty.discriminant_for_variant(*self.tcx, index) + { + assert!(src.layout.is_zst()); + return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); } } + layout::Variants::Multiple { .. } => {}, + } + + // Handle casting the metadata away from a fat pointer. + if src.layout.ty.is_unsafe_ptr() && dest_layout.ty.is_unsafe_ptr() && + dest_layout.size != src.layout.size + { + assert_eq!(src.layout.size, 2*self.memory.pointer_size()); + assert_eq!(dest_layout.size, self.memory.pointer_size()); + assert!(dest_layout.ty.is_unsafe_ptr()); + match *src { + Immediate::ScalarPair(data, _) => + return Ok(data.into()), + Immediate::Scalar(..) => + bug!( + "{:?} input to a fat-to-thin cast ({:?} -> {:?})", + *src, src.layout.ty, dest_layout.ty + ), + }; + } + + // Handle casting any ptr to raw ptr (might be a fat ptr). + if src.layout.ty.is_any_ptr() && dest_layout.ty.is_unsafe_ptr() + { + // The only possible size-unequal case was handled above. + assert_eq!(src.layout.size, dest_layout.size); + return Ok(*src); } + + // For all remaining casts, we either + // (a) cast a raw ptr to usize, or + // (b) cast from an integer-like (including bool, char, enums). + // In both cases we want the bits. + let bits = self.force_bits(src.to_scalar()?, src.layout.size)?; + Ok(self.cast_from_int(bits, src.layout, dest_layout)?.into()) } fn cast_from_int( @@ -199,7 +198,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { }, // Casts to bool are not permitted by rustc, no need to handle them here. - _ => err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), + _ => bug!("invalid int to {:?} cast", dest_layout.ty), } } @@ -236,23 +235,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } } - fn cast_from_ptr( - &self, - ptr: Pointer, - ty: Ty<'tcx> - ) -> InterpResult<'tcx, Scalar> { - use rustc::ty::TyKind::*; - match ty.sty { - // Casting to a reference or fn pointer is not permitted by rustc, - // no need to support it here. - RawPtr(_) | - Int(IntTy::Isize) | - Uint(UintTy::Usize) => Ok(ptr.into()), - Int(_) | Uint(_) => err!(ReadPointerAsBytes), - _ => err!(Unimplemented(format!("ptr to {:?} cast", ty))), - } - } - fn unsize_into_ptr( &mut self, src: OpTy<'tcx, M::PointerTag>, @@ -262,7 +244,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { dty: Ty<'tcx>, ) -> InterpResult<'tcx> { // A -> A conversion - let (src_pointee_ty, dest_pointee_ty) = self.tcx.struct_lockstep_tails(sty, dty); + let (src_pointee_ty, dest_pointee_ty) = + self.tcx.struct_lockstep_tails_erasing_lifetimes(sty, dty, self.param_env); match (&src_pointee_ty.sty, &dest_pointee_ty.sty) { (&ty::Array(_, length), &ty::Slice(_)) => { @@ -270,7 +253,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // u64 cast is from usize to u64, which is always good let val = Immediate::new_slice( ptr, - length.unwrap_usize(self.tcx.tcx), + length.eval_usize(self.tcx.tcx, self.param_env), self, ); self.write_immediate(val, dest) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index c6e762bddd..6f4227ed34 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -16,8 +16,7 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc::mir::interpret::{ ErrorHandled, GlobalId, Scalar, Pointer, FrameInfo, AllocId, - InterpResult, InterpError, - truncate, sign_extend, + InterpResult, truncate, sign_extend, }; use rustc_data_structures::fx::FxHashMap; @@ -26,7 +25,7 @@ use super::{ Memory, Machine }; -pub struct InterpretCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { +pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { /// Stores the `Machine` instance. pub machine: M, @@ -135,7 +134,7 @@ pub enum LocalValue { impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { - LocalValue::Dead => err!(DeadLocal), + LocalValue::Dead => throw_unsup!(DeadLocal), LocalValue::Uninitialized => bug!("The type checker should prevent reading from a never-written local"), LocalValue::Live(val) => Ok(val), @@ -148,7 +147,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => err!(DeadLocal), + LocalValue::Dead => throw_unsup!(DeadLocal), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) | ref mut local @ LocalValue::Uninitialized => { @@ -158,14 +157,14 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> { #[inline] fn data_layout(&self) -> &layout::TargetDataLayout { &self.tcx.data_layout } } -impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpretCx<'mir, 'tcx, M> +impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'mir, 'tcx, M> where M: Machine<'mir, 'tcx>, { @@ -175,7 +174,7 @@ where } } -impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpretCx<'mir, 'tcx, M> +impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'mir, 'tcx, M> where M: Machine<'mir, 'tcx>, { @@ -184,24 +183,30 @@ where } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { type Ty = Ty<'tcx>; type TyLayout = InterpResult<'tcx, TyLayout<'tcx>>; #[inline] fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { - self.tcx.layout_of(self.param_env.and(ty)) - .map_err(|layout| InterpError::Layout(layout).into()) + self.tcx + .layout_of(self.param_env.and(ty)) + .map_err(|layout| err_inval!(Layout(layout)).into()) } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { - pub fn new(tcx: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>, machine: M) -> Self { - InterpretCx { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { + pub fn new( + tcx: TyCtxtAt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + machine: M, + memory_extra: M::MemoryExtra, + ) -> Self { + InterpCx { machine, tcx, param_env, - memory: Memory::new(tcx), + memory: Memory::new(tcx, memory_extra), stack: Vec::new(), vtables: FxHashMap::default(), } @@ -217,6 +222,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { &mut self.memory } + #[inline(always)] + pub fn force_ptr( + &self, + scalar: Scalar, + ) -> InterpResult<'tcx, Pointer> { + self.memory.force_ptr(scalar) + } + + #[inline(always)] + pub fn force_bits( + &self, + scalar: Scalar, + size: Size + ) -> InterpResult<'tcx, u128> { + self.memory.force_bits(scalar, size) + } + #[inline(always)] pub fn tag_static_base_pointer(&self, ptr: Pointer) -> Pointer { self.memory.tag_static_base_pointer(ptr) @@ -248,6 +270,27 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.frame().body } + #[inline(always)] + pub fn sign_extend(&self, value: u128, ty: TyLayout<'_>) -> u128 { + assert!(ty.abi.is_signed()); + sign_extend(value, ty.size) + } + + #[inline(always)] + pub fn truncate(&self, value: u128, ty: TyLayout<'_>) -> u128 { + truncate(value, ty.size) + } + + #[inline] + pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { + ty.is_sized(self.tcx, self.param_env) + } + + #[inline] + pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { + ty.is_freeze(*self.tcx, self.param_env, DUMMY_SP) + } + pub(super) fn subst_and_normalize_erasing_regions>( &self, substs: T, @@ -259,7 +302,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { &substs, )), None => if substs.needs_subst() { - err!(TooGeneric).into() + throw_inval!(TooGeneric) } else { Ok(substs) }, @@ -280,15 +323,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::TooGeneric.into()) - } - - pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx, self.param_env) - } - - pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(*self.tcx, self.param_env, DUMMY_SP) + ).ok_or_else(|| err_inval!(TooGeneric).into()) } pub fn load_mir( @@ -301,14 +336,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { && self.tcx.has_typeck_tables(did) && self.tcx.typeck_tables_of(did).tainted_by_errors { - return err!(TypeckError); + throw_inval!(TypeckError) } trace!("load mir {:?}", instance); match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - err!(NoMirFor(self.tcx.def_path_str(def_id))) + throw_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } @@ -321,7 +356,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { match self.stack.last() { Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)?), None => if t.needs_subst() { - err!(TooGeneric).into() + throw_inval!(TooGeneric) } else { Ok(t) }, @@ -338,7 +373,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let substituted = t.subst(*self.tcx, substs); if substituted.needs_subst() { - return err!(TooGeneric); + throw_inval!(TooGeneric) } Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)) @@ -350,15 +385,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { local: mir::Local, layout: Option>, ) -> InterpResult<'tcx, TyLayout<'tcx>> { - match frame.locals[local].layout.get() { + // `const_prop` runs into this with an invalid (empty) frame, so we + // have to support that case (mostly by skipping all caching). + match frame.locals.get(local).and_then(|state| state.layout.get()) { None => { let layout = crate::interpret::operand::from_known_layout(layout, || { let local_ty = frame.body.local_decls[local].ty; let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs)?; self.layout_of(local_ty) })?; - // Layouts of locals are requested a lot, so we cache them. - frame.locals[local].layout.set(Some(layout)); + if let Some(state) = frame.locals.get(local) { + // Layouts of locals are requested a lot, so we cache them. + state.layout.set(Some(layout)); + } Ok(layout) } Some(layout) => Ok(layout), @@ -471,7 +510,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { pub fn push_stack_frame( &mut self, instance: ty::Instance<'tcx>, - span: source_map::Span, + span: Span, body: &'mir mir::Body<'tcx>, return_place: Option>, return_to_block: StackPopCleanup, @@ -537,7 +576,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { - err!(StackFrameLimitReached) + throw_exhaust!(StackFrameLimitReached) } else { Ok(()) } @@ -585,7 +624,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } } else { // Uh, that shouldn't happen... the function did not intend to return - return err!(Unreachable); + throw_ub!(Unreachable) } // Jump to new block -- *after* validation so that the spans make more sense. match frame.return_to_block { @@ -659,8 +698,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles. let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { - ErrorHandled::Reported => InterpError::ReferencedConstant, - ErrorHandled::TooGeneric => InterpError::TooGeneric, + ErrorHandled::Reported => + err_inval!(ReferencedConstant), + ErrorHandled::TooGeneric => + err_inval!(TooGeneric), } })?; self.raw_const_to_mplace(val) @@ -761,32 +802,4 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span); frames } - - #[inline(always)] - pub fn sign_extend(&self, value: u128, ty: TyLayout<'_>) -> u128 { - assert!(ty.abi.is_signed()); - sign_extend(value, ty.size) - } - - #[inline(always)] - pub fn truncate(&self, value: u128, ty: TyLayout<'_>) -> u128 { - truncate(value, ty.size) - } - - #[inline(always)] - pub fn force_ptr( - &self, - scalar: Scalar, - ) -> InterpResult<'tcx, Pointer> { - self.memory.force_ptr(scalar) - } - - #[inline(always)] - pub fn force_bits( - &self, - scalar: Scalar, - size: Size - ) -> InterpResult<'tcx, u128> { - self.memory.force_bits(scalar, size) - } } diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index f0d64e217a..1074ab941a 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -4,9 +4,7 @@ //! memory, we need to extract all memory allocations to the global memory pool so they stay around. use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; -use rustc::mir::interpret::{ - InterpResult, ErrorHandled, -}; +use rustc::mir::interpret::{InterpResult, ErrorHandled}; use rustc::hir; use rustc::hir::def_id::DefId; use super::validity::RefTracking; @@ -16,7 +14,7 @@ use syntax::ast::Mutability; use syntax_pos::Span; use super::{ - ValueVisitor, MemoryKind, Pointer, AllocId, MPlaceTy, InterpError, Scalar, + ValueVisitor, MemoryKind, Pointer, AllocId, MPlaceTy, Scalar, }; use crate::const_eval::{CompileTimeInterpreter, CompileTimeEvalContext}; @@ -146,7 +144,9 @@ for let value = self.ecx.read_immediate(mplace.into())?; // Handle trait object vtables if let Ok(meta) = value.to_meta() { - if let ty::Dynamic(..) = self.ecx.tcx.struct_tail(referenced_ty).sty { + if let ty::Dynamic(..) = + self.ecx.tcx.struct_tail_erasing_lifetimes(referenced_ty, self.param_env).sty + { if let Ok(vtable) = meta.unwrap().to_ptr() { // explitly choose `Immutable` here, since vtables are immutable, even // if the reference of the fat pointer is mutable @@ -176,7 +176,8 @@ for (InternMode::ConstBase, hir::Mutability::MutMutable) | (InternMode::Const, hir::Mutability::MutMutable) => { match referenced_ty.sty { - ty::Array(_, n) if n.unwrap_usize(self.ecx.tcx.tcx) == 0 => {} + ty::Array(_, n) + if n.eval_usize(self.ecx.tcx.tcx, self.param_env) == 0 => {} ty::Slice(_) if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {} _ => bug!("const qualif failed to prevent mutable references"), @@ -291,7 +292,7 @@ pub fn intern_const_alloc_recursive( if let Err(error) = interned { // This can happen when e.g. the tag of an enum is not a valid discriminant. We do have // to read enum discriminants in order to find references in enum variant fields. - if let InterpError::ValidationFailure(_) = error.kind { + if let err_unsup!(ValidationFailure(_)) = error.kind { let err = crate::const_eval::error_to_const_error(&ecx, error); match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") { Ok(mut diag) => { @@ -326,9 +327,7 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return err!(ValidationFailure( - "encountered dangling pointer in final constant".into(), - )) + throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) } } Ok(()) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index beb5049307..89c5be137a 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -6,12 +6,10 @@ use syntax::symbol::Symbol; use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; -use rustc::mir::interpret::{ - InterpResult, InterpError, Scalar, -}; +use rustc::mir::interpret::{InterpResult, Scalar}; use super::{ - Machine, PlaceTy, OpTy, InterpretCx, Immediate, + Machine, PlaceTy, OpTy, InterpCx, Immediate, }; mod type_name; @@ -39,7 +37,7 @@ fn numeric_intrinsic<'tcx, Tag>( Ok(Scalar::from_uint(bits_out, size)) } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Returns `true` if emulation happened. pub fn emulate_intrinsic( &mut self, @@ -100,11 +98,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?; let kind = match layout_of.abi { ty::layout::Abi::Scalar(ref scalar) => scalar.value, - _ => Err(::rustc::mir::interpret::InterpError::TypeNotPrimitive(ty))?, + _ => throw_unsup!(TypeNotPrimitive(ty)), }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { - return err!(Intrinsic(format!("{} called on 0", intrinsic_name))); + throw_ub_format!("`{}` called on 0", intrinsic_name); } numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)? } else { @@ -189,10 +187,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let (val, overflowed) = self.binary_op(bin_op, l, r)?; if overflowed { let layout = self.layout_of(substs.type_at(0))?; - let r_val = r.to_scalar()?.to_bits(layout.size)?; - return err!(Intrinsic( - format!("Overflowing shift by {} in {}", r_val, intrinsic_name), - )); + let r_val = r.to_scalar()?.to_bits(layout.size)?; + throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name); } self.write_scalar(val, dest)?; } @@ -230,21 +226,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::PointerTag>], - dest: Option>, + _dest: Option>, ) -> InterpResult<'tcx, bool> { let def_id = instance.def_id(); - // Some fn calls are actually BinOp intrinsics - if let Some((op, oflo)) = self.tcx.is_binop_lang_item(def_id) { - let dest = dest.expect("128 lowerings can't diverge"); - let l = self.read_immediate(args[0])?; - let r = self.read_immediate(args[1])?; - if oflo { - self.binop_with_overflow(op, l, r, dest)?; - } else { - self.binop_ignore_overflow(op, l, r, dest)?; - } - return Ok(true); - } else if Some(def_id) == self.tcx.lang_items().panic_fn() { + if Some(def_id) == self.tcx.lang_items().panic_fn() { assert!(args.len() == 1); // &(&'static str, &'static str, u32, u32) let place = self.deref_operand(args[0])?; @@ -261,7 +246,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic { msg, file, line, col }.into()); + throw_panic!(Panic { msg, file, line, col }) } else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() { assert!(args.len() == 2); // &'static str, &(&'static str, u32, u32) @@ -279,7 +264,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic { msg, file, line, col }.into()); + throw_panic!(Panic { msg, file, line, col }) } else { return Ok(false); } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 91263932cc..33ffb1d320 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -7,11 +7,11 @@ use std::hash::Hash; use rustc::hir::def_id::DefId; use rustc::mir; -use rustc::ty::{self, query::TyCtxtAt}; +use rustc::ty::{self, TyCtxt}; use super::{ Allocation, AllocId, InterpResult, Scalar, AllocationExtra, - InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory + InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, }; /// Whether this kind of memory is allowed to leak @@ -59,6 +59,11 @@ pub trait AllocMap { fn get(&self, k: K) -> Option<&V> { self.get_or(k, || Err(())).ok() } + + /// Mutable lookup. + fn get_mut(&mut self, k: K) -> Option<&mut V> { + self.get_mut_or(k, || Err(())).ok() + } } /// Methods of this trait signifies a point where CTFE evaluation would fail @@ -72,13 +77,18 @@ pub trait Machine<'mir, 'tcx>: Sized { /// The `default()` is used for pointers to consts, statics, vtables and functions. type PointerTag: ::std::fmt::Debug + Copy + Eq + Hash + 'static; + /// Machines can define extra (non-instance) things that represent values of function pointers. + /// For example, Miri uses this to return a fucntion pointer from `dlsym` + /// that can later be called to execute the right thing. + type ExtraFnVal: ::std::fmt::Debug + Copy; + /// Extra data stored in every call frame. type FrameExtra; /// Extra data stored in memory. A reference to this is available when `AllocExtra` /// gets initialized, so you can e.g., have an `Rc` here if there is global state you /// need access to in the `AllocExtra` hooks. - type MemoryExtra: Default; + type MemoryExtra; /// Extra data stored in every allocation. type AllocExtra: AllocationExtra + 'static; @@ -99,12 +109,15 @@ pub trait Machine<'mir, 'tcx>: Sized { /// that is added to the memory so that the work is not done twice. const STATIC_KIND: Option; + /// Whether memory accesses should be alignment-checked. + const CHECK_ALIGN: bool; + /// Whether to enforce the validity invariant - fn enforce_validity(ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool; + fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; /// Called before a basic block terminator is executed. /// You can use this to detect endlessly running programs. - fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>; + fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>; /// Entry point to all function calls. /// @@ -117,17 +130,27 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them /// was used. fn find_fn( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], dest: Option>, ret: Option, ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>; + /// Execute `fn_val`. it is the hook's responsibility to advance the instruction + /// pointer as appropriate. + fn call_extra_fn( + ecx: &mut InterpCx<'mir, 'tcx, Self>, + fn_val: Self::ExtraFnVal, + args: &[OpTy<'tcx, Self::PointerTag>], + dest: Option>, + ret: Option, + ) -> InterpResult<'tcx>; + /// Directly process an intrinsic without pushing a stack frame. /// If this returns successfully, the engine will take care of jumping to the next block. fn call_intrinsic( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], dest: PlaceTy<'tcx, Self::PointerTag>, @@ -141,16 +164,15 @@ pub trait Machine<'mir, 'tcx>: Sized { /// /// This allocation will then be fed to `tag_allocation` to initialize the "extra" state. fn find_foreign_static( + tcx: TyCtxt<'tcx>, def_id: DefId, - tcx: TyCtxtAt<'tcx>, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>>; - /// Called for all binary operations on integer(-like) types when one operand is a pointer - /// value, and for the `Offset` operation that is inherently about pointers. + /// Called for all binary operations where the LHS has pointer type. /// /// Returns a (value, overflowed) pair if the operation succeeded - fn ptr_op( - ecx: &InterpretCx<'mir, 'tcx, Self>, + fn binary_ptr_op( + ecx: &InterpCx<'mir, 'tcx, Self>, bin_op: mir::BinOp, left: ImmTy<'tcx, Self::PointerTag>, right: ImmTy<'tcx, Self::PointerTag>, @@ -158,7 +180,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Heap allocations via the `box` keyword. fn box_alloc( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, dest: PlaceTy<'tcx, Self::PointerTag>, ) -> InterpResult<'tcx>; @@ -179,10 +201,10 @@ pub trait Machine<'mir, 'tcx>: Sized { /// For static allocations, the tag returned must be the same as the one returned by /// `tag_static_base_pointer`. fn tag_allocation<'b>( + memory_extra: &Self::MemoryExtra, id: AllocId, alloc: Cow<'b, Allocation>, kind: Option>, - memory: &Memory<'mir, 'tcx, Self>, ) -> (Cow<'b, Allocation>, Self::PointerTag); /// Return the "base" tag for the given static allocation: the one that is used for direct @@ -191,14 +213,14 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Be aware that requesting the `Allocation` for that `id` will lead to cycles /// for cyclic statics! fn tag_static_base_pointer( + memory_extra: &Self::MemoryExtra, id: AllocId, - memory: &Memory<'mir, 'tcx, Self>, ) -> Self::PointerTag; /// Executes a retagging operation #[inline] fn retag( - _ecx: &mut InterpretCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'mir, 'tcx, Self>, _kind: mir::RetagKind, _place: PlaceTy<'tcx, Self::PointerTag>, ) -> InterpResult<'tcx> { @@ -206,29 +228,27 @@ pub trait Machine<'mir, 'tcx>: Sized { } /// Called immediately before a new stack frame got pushed - fn stack_push(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>; + fn stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>; /// Called immediately after a stack frame gets popped fn stack_pop( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, extra: Self::FrameExtra, ) -> InterpResult<'tcx>; fn int_to_ptr( - int: u64, _mem: &Memory<'mir, 'tcx, Self>, + int: u64, ) -> InterpResult<'tcx, Pointer> { - if int == 0 { - err!(InvalidNullPointerUsage) + Err((if int == 0 { + err_unsup!(InvalidNullPointerUsage) } else { - err!(ReadBytesAsPointer) - } + err_unsup!(ReadBytesAsPointer) + }).into()) } fn ptr_to_int( - _ptr: Pointer, _mem: &Memory<'mir, 'tcx, Self>, - ) -> InterpResult<'tcx, u64> { - err!(ReadPointerAsBytes) - } + _ptr: Pointer, + ) -> InterpResult<'tcx, u64>; } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 56a0e14535..aef09df453 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -18,7 +18,7 @@ use syntax::ast::Mutability; use super::{ Pointer, AllocId, Allocation, GlobalId, AllocationExtra, - InterpResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic, + InterpResult, Scalar, GlobalAlloc, PointerArithmetic, Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, }; @@ -54,6 +54,25 @@ pub enum AllocCheck { MaybeDead, } +/// The value of a function pointer. +#[derive(Debug, Copy, Clone)] +pub enum FnVal<'tcx, Other> { + Instance(Instance<'tcx>), + Other(Other), +} + +impl<'tcx, Other> FnVal<'tcx, Other> { + pub fn as_instance(self) -> InterpResult<'tcx, Instance<'tcx>> { + match self { + FnVal::Instance(instance) => + Ok(instance), + FnVal::Other(_) => throw_unsup_format!( + "'foreign' function pointers are not supported in this context" + ), + } + } +} + // `Memory` has to depend on the `Machine` because some of its operations // (e.g., `get`) call a `Machine` hook. pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { @@ -69,16 +88,20 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { // FIXME: this should not be public, but interning currently needs access to it pub(super) alloc_map: M::MemoryMap, + /// Map for "extra" function pointers. + extra_fn_ptr_map: FxHashMap, + /// To be able to compare pointers with NULL, and to check alignment for accesses /// to ZSTs (where pointers may dangle), we keep track of the size even for allocations /// that do not exist any more. + // FIXME: this should not be public, but interning currently needs access to it pub(super) dead_alloc_map: FxHashMap, /// Extra data added by the machine. pub extra: M::MemoryExtra, /// Lets us implement `HasDataLayout`, which is awfully convenient. - pub(super) tcx: TyCtxtAt<'tcx>, + pub tcx: TyCtxtAt<'tcx>, } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for Memory<'mir, 'tcx, M> { @@ -98,6 +121,7 @@ where fn clone(&self) -> Self { Memory { alloc_map: self.alloc_map.clone(), + extra_fn_ptr_map: self.extra_fn_ptr_map.clone(), dead_alloc_map: self.dead_alloc_map.clone(), extra: (), tcx: self.tcx, @@ -106,22 +130,36 @@ where } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { - pub fn new(tcx: TyCtxtAt<'tcx>) -> Self { + pub fn new(tcx: TyCtxtAt<'tcx>, extra: M::MemoryExtra) -> Self { Memory { alloc_map: M::MemoryMap::default(), + extra_fn_ptr_map: FxHashMap::default(), dead_alloc_map: FxHashMap::default(), - extra: M::MemoryExtra::default(), + extra, tcx, } } #[inline] pub fn tag_static_base_pointer(&self, ptr: Pointer) -> Pointer { - ptr.with_tag(M::tag_static_base_pointer(ptr.alloc_id, &self)) + ptr.with_tag(M::tag_static_base_pointer(&self.extra, ptr.alloc_id)) } - pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer { - let id = self.tcx.alloc_map.lock().create_fn_alloc(instance); + pub fn create_fn_alloc( + &mut self, + fn_val: FnVal<'tcx, M::ExtraFnVal>, + ) -> Pointer + { + let id = match fn_val { + FnVal::Instance(instance) => self.tcx.alloc_map.lock().create_fn_alloc(instance), + FnVal::Other(extra) => { + // FIXME(RalfJung): Should we have a cache here? + let id = self.tcx.alloc_map.lock().reserve(); + let old = self.extra_fn_ptr_map.insert(id, extra); + assert!(old.is_none()); + id + } + }; self.tag_static_base_pointer(Pointer::from(id)) } @@ -150,7 +188,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> Pointer { let id = self.tcx.alloc_map.lock().reserve(); - let (alloc, tag) = M::tag_allocation(id, Cow::Owned(alloc), Some(kind), &self); + let (alloc, tag) = M::tag_allocation(&self.extra, id, Cow::Owned(alloc), Some(kind)); self.alloc_map.insert(id, (kind, alloc.into_owned())); Pointer::from(id).with_tag(tag) } @@ -158,28 +196,29 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn reallocate( &mut self, ptr: Pointer, - old_size: Size, - old_align: Align, + old_size_and_align: Option<(Size, Align)>, new_size: Size, new_align: Align, kind: MemoryKind, ) -> InterpResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { - return err!(ReallocateNonBasePtr); + throw_unsup!(ReallocateNonBasePtr) } // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". // This happens so rarely, the perf advantage is outweighed by the maintenance cost. let new_ptr = self.allocate(new_size, new_align, kind); + let old_size = match old_size_and_align { + Some((size, _align)) => size, + None => Size::from_bytes(self.get(ptr.alloc_id)?.bytes.len() as u64), + }; self.copy( - ptr.into(), - old_align, - new_ptr.into(), - new_align, + ptr, + new_ptr, old_size.min(new_size), /*nonoverlapping*/ true, )?; - self.deallocate(ptr, Some((old_size, old_align)), kind)?; + self.deallocate(ptr, old_size_and_align, kind)?; Ok(new_ptr) } @@ -198,47 +237,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn deallocate( &mut self, ptr: Pointer, - size_and_align: Option<(Size, Align)>, + old_size_and_align: Option<(Size, Align)>, kind: MemoryKind, ) -> InterpResult<'tcx> { trace!("deallocating: {}", ptr.alloc_id); if ptr.offset.bytes() != 0 { - return err!(DeallocateNonBasePtr); + throw_unsup!(DeallocateNonBasePtr) } let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { Some(alloc) => alloc, None => { // Deallocating static memory -- always an error - return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => err!(DeallocatedWrongMemoryKind( + return Err(match self.tcx.alloc_map.lock().get(ptr.alloc_id) { + Some(GlobalAlloc::Function(..)) => err_unsup!(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), )), - Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind( - "static".to_string(), - format!("{:?}", kind), - )), - None => err!(DoubleFree) + Some(GlobalAlloc::Static(..)) | Some(GlobalAlloc::Memory(..)) => err_unsup!( + DeallocatedWrongMemoryKind("static".to_string(), format!("{:?}", kind)) + ), + None => err_unsup!(DoubleFree), } + .into()); } }; if alloc_kind != kind { - return err!(DeallocatedWrongMemoryKind( + throw_unsup!(DeallocatedWrongMemoryKind( format!("{:?}", alloc_kind), format!("{:?}", kind), - )); + )) } - if let Some((size, align)) = size_and_align { + if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); - return err!(IncorrectAllocationInformation(size, - bytes, - align, - alloc.align)); + throw_unsup!(IncorrectAllocationInformation(size, bytes, align, alloc.align)) } } @@ -268,11 +303,27 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { /// `Pointer` they need. And even if you already have a `Pointer`, call this method /// to make sure it is sufficiently aligned and not dangling. Not doing that may /// cause ICEs. + /// + /// Most of the time you should use `check_mplace_access`, but when you just have a pointer, + /// this method is still appropriate. + #[inline(always)] pub fn check_ptr_access( &self, sptr: Scalar, size: Size, align: Align, + ) -> InterpResult<'tcx, Option>> { + let align = if M::CHECK_ALIGN { Some(align) } else { None }; + self.check_ptr_access_align(sptr, size, align) + } + + /// Like `check_ptr_access`, but *definitely* checks alignment when `align` + /// is `Some` (overriding `M::CHECK_ALIGN`). + pub(super) fn check_ptr_access_align( + &self, + sptr: Scalar, + size: Size, + align: Option, ) -> InterpResult<'tcx, Option>> { fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> { if offset % align.bytes() == 0 { @@ -280,7 +331,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - err!(AlignmentCheckFailed { + throw_unsup!(AlignmentCheckFailed { has: Align::from_bytes(offset_pow2).unwrap(), required: align, }) @@ -300,11 +351,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(bits) => { let bits = bits as u64; // it's ptr-sized assert!(size.bytes() == 0); - // Must be non-NULL and aligned. + // Must be non-NULL. if bits == 0 { - return err!(InvalidNullPointerUsage); + throw_unsup!(InvalidNullPointerUsage) + } + // Must be aligned. + if let Some(align) = align { + check_offset_align(bits, align)?; } - check_offset_align(bits, align)?; None } Err(ptr) => { @@ -317,18 +371,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { end_ptr.check_in_alloc(allocation_size, CheckInAllocMsg::MemoryAccessTest)?; // Test align. Check this last; if both bounds and alignment are violated // we want the error to be about the bounds. - if alloc_align.bytes() < align.bytes() { - // The allocation itself is not aligned enough. - // FIXME: Alignment check is too strict, depending on the base address that - // got picked we might be aligned even if this check fails. - // We instead have to fall back to converting to an integer and checking - // the "real" alignment. - return err!(AlignmentCheckFailed { - has: alloc_align, - required: align, - }); + if let Some(align) = align { + if alloc_align.bytes() < align.bytes() { + // The allocation itself is not aligned enough. + // FIXME: Alignment check is too strict, depending on the base address that + // got picked we might be aligned even if this check fails. + // We instead have to fall back to converting to an integer and checking + // the "real" alignment. + throw_unsup!(AlignmentCheckFailed { + has: alloc_align, + required: align, + }); + } + check_offset_align(ptr.offset.bytes(), align)?; } - check_offset_align(ptr.offset.bytes(), align)?; // We can still be zero-sized in this branch, in which case we have to // return `None`. @@ -365,23 +421,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { /// contains a reference to memory that was created during its evaluation (i.e., not to /// another static), those inner references only exist in "resolved" form. fn get_static_alloc( - id: AllocId, + memory_extra: &M::MemoryExtra, tcx: TyCtxtAt<'tcx>, - memory: &Memory<'mir, 'tcx, M>, + id: AllocId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { let alloc = tcx.alloc_map.lock().get(id); let alloc = match alloc { Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), Some(GlobalAlloc::Function(..)) => - return err!(DerefFunctionPointer), + throw_unsup!(DerefFunctionPointer), None => - return err!(DanglingPointerDeref), + throw_unsup!(DanglingPointerDeref), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { trace!("static_alloc: foreign item {:?}", def_id); - M::find_foreign_static(def_id, tcx)? + M::find_foreign_static(tcx.tcx, def_id)? } else { trace!("static_alloc: Need to compute {:?}", def_id); let instance = Instance::mono(tcx.tcx, def_id); @@ -397,8 +453,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // for statics assert!(tcx.is_static(def_id)); match err { - ErrorHandled::Reported => InterpError::ReferencedConstant, - ErrorHandled::TooGeneric => InterpError::TooGeneric, + ErrorHandled::Reported => + err_inval!(ReferencedConstant), + ErrorHandled::TooGeneric => + err_inval!(TooGeneric), } })?; // Make sure we use the ID of the resolved memory, not the lazy one! @@ -411,10 +469,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // We got tcx memory. Let the machine figure out whether and how to // turn that into memory with the right pointer tag. Ok(M::tag_allocation( + memory_extra, id, // always use the ID we got as input, not the "hidden" one. alloc, M::STATIC_KIND.map(MemoryKind::Machine), - memory ).0) } @@ -427,7 +485,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // `get_static_alloc` that we can actually use directly without inserting anything anywhere. // So the error type is `InterpResult<'tcx, &Allocation>`. let a = self.alloc_map.get_or(id, || { - let alloc = Self::get_static_alloc(id, self.tcx, &self).map_err(Err)?; + let alloc = Self::get_static_alloc(&self.extra, self.tcx, id).map_err(Err)?; match alloc { Cow::Borrowed(alloc) => { // We got a ref, cheaply return that as an "error" so that the @@ -456,17 +514,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { id: AllocId, ) -> InterpResult<'tcx, &mut Allocation> { let tcx = self.tcx; - let alloc = Self::get_static_alloc(id, tcx, &self); + let memory_extra = &self.extra; let a = self.alloc_map.get_mut_or(id, || { // Need to make a copy, even if `get_static_alloc` is able // to give us a cheap reference. - let alloc = alloc?; + let alloc = Self::get_static_alloc(memory_extra, tcx, id)?; if alloc.mutability == Mutability::Immutable { - return err!(ModifiedConstantMemory); + throw_unsup!(ModifiedConstantMemory) } match M::STATIC_KIND { Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())), - None => err!(ModifiedStatic), + None => throw_unsup!(ModifiedStatic), } }); // Unpack the error type manually because type inference doesn't @@ -476,7 +534,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(a) => { let a = &mut a.1; if a.mutability == Mutability::Immutable { - return err!(ModifiedConstantMemory); + throw_unsup!(ModifiedConstantMemory) } Ok(a) } @@ -500,19 +558,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)); } - // # Statics and function pointers + // # Function pointers + // (both global from `alloc_map` and local from `extra_fn_ptr_map`) + if let Ok(_) = self.get_fn_alloc(id) { + return if let AllocCheck::Dereferencable = liveness { + // The caller requested no function pointers. + throw_unsup!(DerefFunctionPointer) + } else { + Ok((Size::ZERO, Align::from_bytes(1).unwrap())) + }; + } + + // # Statics // Can't do this in the match argument, we may get cycle errors since the lock would // be held throughout the match. let alloc = self.tcx.alloc_map.lock().get(id); match alloc { - Some(GlobalAlloc::Function(..)) => { - if let AllocCheck::Dereferencable = liveness { - // The caller requested no function pointers. - err!(DerefFunctionPointer) - } else { - Ok((Size::ZERO, Align::from_bytes(1).unwrap())) - } - }, Some(GlobalAlloc::Static(did)) => { // Use size and align of the type. let ty = self.tcx.type_of(did); @@ -523,6 +584,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Need to duplicate the logic here, because the global allocations have // different associated types than the interpreter-local ones. Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)), + Some(GlobalAlloc::Function(_)) => + bug!("We already checked function pointers above"), // The rest must be dead. None => if let AllocCheck::MaybeDead = liveness { // Deallocated pointers are allowed, we should be able to find @@ -531,20 +594,32 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { .expect("deallocated pointers should all be recorded in \ `dead_alloc_map`")) } else { - err!(DanglingPointerDeref) + throw_unsup!(DanglingPointerDeref) }, } } - pub fn get_fn(&self, ptr: Pointer) -> InterpResult<'tcx, Instance<'tcx>> { - if ptr.offset.bytes() != 0 { - return err!(InvalidFunctionPointer); + fn get_fn_alloc(&self, id: AllocId) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { + trace!("reading fn ptr: {}", id); + if let Some(extra) = self.extra_fn_ptr_map.get(&id) { + Ok(FnVal::Other(*extra)) + } else { + match self.tcx.alloc_map.lock().get(id) { + Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), + _ => throw_unsup!(ExecuteMemory), + } } - trace!("reading fn ptr: {}", ptr.alloc_id); - match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(instance)) => Ok(instance), - _ => Err(InterpError::ExecuteMemory.into()), + } + + pub fn get_fn( + &self, + ptr: Scalar, + ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { + let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value. + if ptr.offset.bytes() != 0 { + throw_unsup!(InvalidFunctionPointer) } + self.get_fn_alloc(ptr.alloc_id) } pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> { @@ -680,6 +755,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { /// Reading and writing. impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { + /// Reads the given number of bytes from memory. Returns them as a slice. + /// /// Performs appropriate bounds checks. pub fn read_bytes( &self, @@ -693,39 +770,34 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { self.get(ptr.alloc_id)?.get_bytes(self, ptr, size) } + /// Reads a 0-terminated sequence of bytes from memory. Returns them as a slice. + /// /// Performs appropriate bounds checks. + pub fn read_c_str(&self, ptr: Scalar) -> InterpResult<'tcx, &[u8]> { + let ptr = self.force_ptr(ptr)?; // We need to read at least 1 byte, so we *need* a ptr. + self.get(ptr.alloc_id)?.read_c_str(self, ptr) + } + + /// Expects the caller to have checked bounds and alignment. pub fn copy( &mut self, - src: Scalar, - src_align: Align, - dest: Scalar, - dest_align: Align, + src: Pointer, + dest: Pointer, size: Size, nonoverlapping: bool, ) -> InterpResult<'tcx> { - self.copy_repeatedly(src, src_align, dest, dest_align, size, 1, nonoverlapping) + self.copy_repeatedly(src, dest, size, 1, nonoverlapping) } - /// Performs appropriate bounds checks. + /// Expects the caller to have checked bounds and alignment. pub fn copy_repeatedly( &mut self, - src: Scalar, - src_align: Align, - dest: Scalar, - dest_align: Align, + src: Pointer, + dest: Pointer, size: Size, length: u64, nonoverlapping: bool, ) -> InterpResult<'tcx> { - // We need to check *both* before early-aborting due to the size being 0. - let (src, dest) = match (self.check_ptr_access(src, size, src_align)?, - self.check_ptr_access(dest, size * length, dest_align)?) - { - (Some(src), Some(dest)) => (src, dest), - // One of the two sizes is 0. - _ => return Ok(()), - }; - // first copy the relocations to a temporary buffer, because // `get_bytes_mut` will clear the relocations, which is correct, // since we don't want to keep any relocations at the target. @@ -780,9 +852,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if (src.offset <= dest.offset && src.offset + size > dest.offset) || (dest.offset <= src.offset && dest.offset + size > src.offset) { - return err!(Intrinsic( - "copy_nonoverlapping called on overlapping ranges".to_string(), - )); + throw_ub_format!( + "copy_nonoverlapping called on overlapping ranges" + ) } } @@ -890,7 +962,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, Pointer> { match scalar { Scalar::Ptr(ptr) => Ok(ptr), - _ => M::int_to_ptr(scalar.to_usize(self)?, self) + _ => M::int_to_ptr(&self, scalar.to_usize(self)?) } } @@ -901,7 +973,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, u128> { match scalar.to_bits_or_ptr(size, self) { Ok(bits) => Ok(bits), - Err(ptr) => Ok(M::ptr_to_int(ptr, self)? as u128) + Err(ptr) => Ok(M::ptr_to_int(&self, ptr)? as u128) } } } diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 259bd6af0d..45d24347e4 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -19,12 +19,12 @@ mod intern; pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here pub use self::eval_context::{ - InterpretCx, Frame, StackPopCleanup, LocalState, LocalValue, + InterpCx, Frame, StackPopCleanup, LocalState, LocalValue, }; pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy}; -pub use self::memory::{Memory, MemoryKind, AllocCheck}; +pub use self::memory::{Memory, MemoryKind, AllocCheck, FnVal}; pub use self::machine::{Machine, AllocMap, MayLeak}; diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c72078fa89..f778eb1734 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -11,11 +11,10 @@ use rustc::ty::layout::{ use rustc::mir::interpret::{ GlobalId, AllocId, ConstValue, Pointer, Scalar, - InterpResult, InterpError, - sign_extend, truncate, + InterpResult, sign_extend, truncate, }; use super::{ - InterpretCx, Machine, + InterpCx, Machine, MemPlace, MPlaceTy, PlaceTy, Place, }; pub use rustc::mir::interpret::ScalarMaybeUndef; @@ -33,12 +32,21 @@ pub enum Immediate { ScalarPair(ScalarMaybeUndef, ScalarMaybeUndef), } -impl<'tcx, Tag> Immediate { - #[inline] - pub fn from_scalar(val: Scalar) -> Self { - Immediate::Scalar(ScalarMaybeUndef::Scalar(val)) +impl From> for Immediate { + #[inline(always)] + fn from(val: ScalarMaybeUndef) -> Self { + Immediate::Scalar(val) + } +} + +impl From> for Immediate { + #[inline(always)] + fn from(val: Scalar) -> Self { + Immediate::Scalar(val.into()) } +} +impl<'tcx, Tag> Immediate { pub fn new_slice( val: Scalar, len: u64, @@ -123,23 +131,23 @@ pub enum Operand { impl Operand { #[inline] - pub fn to_mem_place(self) -> MemPlace + pub fn assert_mem_place(self) -> MemPlace where Tag: ::std::fmt::Debug { match self { Operand::Indirect(mplace) => mplace, - _ => bug!("to_mem_place: expected Operand::Indirect, got {:?}", self), + _ => bug!("assert_mem_place: expected Operand::Indirect, got {:?}", self), } } #[inline] - pub fn to_immediate(self) -> Immediate + pub fn assert_immediate(self) -> Immediate where Tag: ::std::fmt::Debug { match self { Operand::Immediate(imm) => imm, - _ => bug!("to_immediate: expected Operand::Immediate, got {:?}", self), + _ => bug!("assert_immediate: expected Operand::Immediate, got {:?}", self), } } @@ -183,7 +191,7 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { #[inline] pub fn from_scalar(val: Scalar, layout: TyLayout<'tcx>) -> Self { - ImmTy { imm: Immediate::from_scalar(val), layout } + ImmTy { imm: val.into(), layout } } #[inline] @@ -213,7 +221,20 @@ pub(super) fn from_known_layout<'tcx>( } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { + /// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST. + /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot. + #[inline] + pub fn force_op_ptr( + &self, + op: OpTy<'tcx, M::PointerTag>, + ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { + match op.try_as_mplace() { + Ok(mplace) => Ok(self.force_mplace_ptr(mplace)?.into()), + Err(imm) => Ok(imm.into()), // Nothing to cast/force + } + } + /// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`. /// Returns `None` if the layout does not permit loading this as a value. fn try_read_immediate_from_mplace( @@ -224,12 +245,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // Don't touch unsized return Ok(None); } - let (ptr, ptr_align) = mplace.to_scalar_ptr_align(); - let ptr = match self.memory.check_ptr_access(ptr, mplace.layout.size, ptr_align)? { + let ptr = match self.check_mplace_access(mplace, None)? { Some(ptr) => ptr, None => return Ok(Some(ImmTy { // zero-sized type - imm: Immediate::Scalar(Scalar::zst().into()), + imm: Scalar::zst().into(), layout: mplace.layout, })), }; @@ -240,7 +260,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { .get(ptr.alloc_id)? .read_scalar(self, ptr, mplace.layout.size)?; Ok(Some(ImmTy { - imm: Immediate::Scalar(scalar), + imm: scalar.into(), layout: mplace.layout, })) } @@ -319,8 +339,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, &str> { let len = mplace.len(self)?; let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?; - let str = ::std::str::from_utf8(bytes) - .map_err(|err| InterpError::ValidationFailure(err.to_string()))?; + let str = ::std::str::from_utf8(bytes).map_err(|err| { + err_unsup!(ValidationFailure(err.to_string())) + })?; Ok(str) } @@ -342,7 +363,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let field = field.try_into().unwrap(); let field_layout = op.layout.field(self, field)?; if field_layout.is_zst() { - let immediate = Immediate::Scalar(Scalar::zst().into()); + let immediate = Scalar::zst().into(); return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout }); } let offset = op.layout.fields.offset(field); @@ -352,7 +373,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // extract fields from types with `ScalarPair` ABI Immediate::ScalarPair(a, b) => { let val = if offset.bytes() == 0 { a } else { b }; - Immediate::Scalar(val) + Immediate::from(val) }, Immediate::Scalar(val) => bug!("field access on non aggregate {:#?}, {:#?}", val, op.layout), @@ -389,14 +410,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { Deref => self.deref_operand(base)?.into(), Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() { OpTy { - op: Operand::Immediate(Immediate::Scalar(Scalar::zst().into())), + op: Operand::Immediate(Scalar::zst().into()), // the actual index doesn't matter, so we just pick a convenient one like 0 layout: base.layout.field(self, 0)?, } } else { // The rest should only occur as mplace, we do not use Immediates for types // allowing such operations. This matches place_projection forcing an allocation. - let mplace = base.to_mem_place(); + let mplace = base.assert_mem_place(); self.mplace_projection(mplace, proj_elem)?.into() } }) @@ -413,7 +434,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let layout = self.layout_of_local(frame, local, layout)?; let op = if layout.is_zst() { // Do not read from ZST, they might not be initialized - Operand::Immediate(Immediate::Scalar(Scalar::zst().into())) + Operand::Immediate(Scalar::zst().into()) } else { frame.locals[local].access()? }; @@ -443,17 +464,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { mir_place: &mir::Place<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { - use rustc::mir::Place; use rustc::mir::PlaceBase; mir_place.iterate(|place_base, place_projection| { let mut op = match place_base { - PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), + PlaceBase::Local(mir::RETURN_PLACE) => + throw_unsup!(ReadFromReturnPointer), PlaceBase::Local(local) => { - // FIXME use place_projection.is_empty() when is available // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. - let layout = if let Place::Base(_) = mir_place { + // FIXME use place_projection.is_empty() when is available + let layout = if mir_place.projection.is_none() { layout } else { None @@ -519,7 +540,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { }; // Early-return cases. match val.val { - ConstValue::Param(_) => return err!(TooGeneric), // FIXME(oli-obk): try to monomorphize + ConstValue::Param(_) => + // FIXME(oli-obk): try to monomorphize + throw_inval!(TooGeneric), ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; return Ok(OpTy::from(self.const_eval_raw(GlobalId { @@ -534,15 +557,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.layout_of(self.monomorphize(val.ty)?) })?; let op = match val.val { - ConstValue::ByRef { offset, align, alloc } => { + ConstValue::ByRef { alloc, offset } => { let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. let ptr = self.tag_static_base_pointer(Pointer::new(id, offset)); - Operand::Indirect(MemPlace::from_ptr(ptr, align)) + Operand::Indirect(MemPlace::from_ptr(ptr, layout.align.abi)) }, ConstValue::Scalar(x) => - Operand::Immediate(Immediate::Scalar(tag_scalar(x).into())), + Operand::Immediate(tag_scalar(x).into()), ConstValue::Slice { data, start, end } => { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. @@ -593,7 +616,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { layout::DiscriminantKind::Tag => { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { Ok(raw_discr) => raw_discr, - Err(_) => return err!(InvalidDiscriminant(raw_discr.erase_tag())), + Err(_) => + throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag())), }; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type @@ -619,7 +643,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { .discriminants(*def_id, self.tcx.tcx) .find(|(_, var)| var.val == real_discr), _ => bug!("tagged layout for non-adt non-generator"), - }.ok_or_else(|| InterpError::InvalidDiscriminant(raw_discr.erase_tag()))?; + }.ok_or_else( + || err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())) + )?; (real_discr, index.0) }, layout::DiscriminantKind::Niche { @@ -629,15 +655,16 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } => { let variants_start = niche_variants.start().as_u32() as u128; let variants_end = niche_variants.end().as_u32() as u128; - let raw_discr = raw_discr.not_undef() - .map_err(|_| InterpError::InvalidDiscriminant(ScalarMaybeUndef::Undef))?; + let raw_discr = raw_discr.not_undef().map_err(|_| { + err_unsup!(InvalidDiscriminant(ScalarMaybeUndef::Undef)) + })?; match raw_discr.to_bits_or_ptr(discr_val.layout.size, self) { Err(ptr) => { // The niche must be just 0 (which an inbounds pointer value never is) let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return err!(InvalidDiscriminant(raw_discr.erase_tag().into())); + throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag().into())) } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 029a440f34..e638ebcc34 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -4,10 +4,10 @@ use syntax::ast::FloatTy; use rustc_apfloat::Float; use rustc::mir::interpret::{InterpResult, Scalar}; -use super::{InterpretCx, PlaceTy, Immediate, Machine, ImmTy}; +use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy}; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Applies the binary operation `op` to the two operands and writes a tuple of the result /// and a boolean signifying the potential overflow to the destination. pub fn binop_with_overflow( @@ -36,7 +36,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn binary_char_op( &self, bin_op: mir::BinOp, @@ -147,15 +147,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // For the remaining ops, the types must be the same on both sides if left_layout.ty != right_layout.ty { - let msg = format!( - "unimplemented asymmetric binary op {:?}: {:?} ({:?}), {:?} ({:?})", + bug!( + "invalid asymmetric binary op {:?}: {:?} ({:?}), {:?} ({:?})", bin_op, - l, - left_layout.ty, - r, - right_layout.ty - ); - return err!(Unimplemented(msg)); + l, left_layout.ty, + r, right_layout.ty, + ) } // Operations that need special treatment for signed integers @@ -173,8 +170,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { return Ok((Scalar::from_bool(op(&l, &r)), false)); } let op: Option (i128, bool)> = match bin_op { - Div if r == 0 => return err!(DivisionByZero), - Rem if r == 0 => return err!(RemainderByZero), + Div if r == 0 => throw_panic!(DivisionByZero), + Rem if r == 0 => throw_panic!(RemainderByZero), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), Add => Some(i128::overflowing_add), @@ -231,8 +228,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { Add => u128::overflowing_add, Sub => u128::overflowing_sub, Mul => u128::overflowing_mul, - Div if r == 0 => return err!(DivisionByZero), - Rem if r == 0 => return err!(RemainderByZero), + Div if r == 0 => throw_panic!(DivisionByZero), + Rem if r == 0 => throw_panic!(RemainderByZero), Div => u128::overflowing_div, Rem => u128::overflowing_rem, _ => bug!(), @@ -243,14 +240,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } _ => { - let msg = format!( - "unimplemented binary op {:?}: {:?}, {:?} (both {:?})", + bug!( + "invalid binary op {:?}: {:?}, {:?} (both {:?})", bin_op, l, r, right_layout.ty, - ); - return err!(Unimplemented(msg)); + ) } }; @@ -290,30 +286,29 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { FloatTy::F64 => self.binary_float_op(bin_op, left.to_f64()?, right.to_f64()?), }) } - _ => { - // Must be integer(-like) types. Don't forget about == on fn pointers. - assert!( - left.layout.ty.is_integral() || - left.layout.ty.is_unsafe_ptr() || left.layout.ty.is_fn_ptr(), - "Unexpected LHS type {:?} for BinOp {:?}", left.layout.ty, bin_op); + _ if left.layout.ty.is_integral() => { + // the RHS type can be different, e.g. for shifts -- but it has to be integral, too assert!( - right.layout.ty.is_integral() || - right.layout.ty.is_unsafe_ptr() || right.layout.ty.is_fn_ptr(), - "Unexpected RHS type {:?} for BinOp {:?}", right.layout.ty, bin_op); - - // Handle operations that support pointer values - if left.to_scalar_ptr()?.is_ptr() || - right.to_scalar_ptr()?.is_ptr() || - bin_op == mir::BinOp::Offset - { - return M::ptr_op(self, bin_op, left, right); - } + right.layout.ty.is_integral(), + "Unexpected types for BinOp: {:?} {:?} {:?}", + left.layout.ty, bin_op, right.layout.ty + ); - // Everything else only works with "proper" bits - let l = left.to_bits().expect("we checked is_ptr"); - let r = right.to_bits().expect("we checked is_ptr"); + let l = self.force_bits(left.to_scalar()?, left.layout.size)?; + let r = self.force_bits(right.to_scalar()?, right.layout.size)?; self.binary_int_op(bin_op, l, left.layout, r, right.layout) } + _ if left.layout.ty.is_any_ptr() => { + // The RHS type must be the same *or an integer type* (for `Offset`). + assert!( + right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), + "Unexpected types for BinOp: {:?} {:?} {:?}", + left.layout.ty, bin_op, right.layout.ty + ); + + M::binary_ptr_op(self, bin_op, left, right) + } + _ => bug!("Invalid MIR: bad LHS type for binop: {:?}", left.layout.ty), } } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 1351b5bb8b..f66c4adf76 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -13,8 +13,8 @@ use rustc::ty::TypeFoldable; use super::{ GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, - InterpretCx, Machine, AllocMap, AllocationExtra, - RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue + InterpCx, Machine, AllocMap, AllocationExtra, + RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] @@ -122,21 +122,6 @@ impl MemPlace { Self::from_scalar_ptr(ptr.into(), align) } - #[inline(always)] - pub fn to_scalar_ptr_align(self) -> (Scalar, Align) { - assert!(self.meta.is_none()); - (self.ptr, self.align) - } - - /// metact the ptr part of the mplace - #[inline(always)] - pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { - // At this point, we forget about the alignment information -- - // the place has been turned into a reference, and no matter where it came from, - // it now must be aligned. - self.to_scalar_ptr_align().0.to_ptr() - } - /// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space. /// This is the inverse of `ref_to_mplace`. #[inline(always)] @@ -230,6 +215,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { } } +// These are defined here because they produce a place. impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { #[inline(always)] pub fn try_as_mplace(self) -> Result, ImmTy<'tcx, Tag>> { @@ -240,12 +226,12 @@ impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { } #[inline(always)] - pub fn to_mem_place(self) -> MPlaceTy<'tcx, Tag> { + pub fn assert_mem_place(self) -> MPlaceTy<'tcx, Tag> { self.try_as_mplace().unwrap() } } -impl<'tcx, Tag: ::std::fmt::Debug> Place { +impl Place { /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] pub fn null(cx: &impl HasDataLayout) -> Self { @@ -263,34 +249,24 @@ impl<'tcx, Tag: ::std::fmt::Debug> Place { } #[inline] - pub fn to_mem_place(self) -> MemPlace { + pub fn assert_mem_place(self) -> MemPlace { match self { Place::Ptr(mplace) => mplace, - _ => bug!("to_mem_place: expected Place::Ptr, got {:?}", self), + _ => bug!("assert_mem_place: expected Place::Ptr, got {:?}", self), } } - - #[inline] - pub fn to_scalar_ptr_align(self) -> (Scalar, Align) { - self.to_mem_place().to_scalar_ptr_align() - } - - #[inline] - pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { - self.to_mem_place().to_ptr() - } } impl<'tcx, Tag: ::std::fmt::Debug> PlaceTy<'tcx, Tag> { #[inline] - pub fn to_mem_place(self) -> MPlaceTy<'tcx, Tag> { - MPlaceTy { mplace: self.place.to_mem_place(), layout: self.layout } + pub fn assert_mem_place(self) -> MPlaceTy<'tcx, Tag> { + MPlaceTy { mplace: self.place.assert_mem_place(), layout: self.layout } } } // separating the pointer tag for `impl Trait`, see https://github.com/rust-lang/rust/issues/54385 -impl<'mir, 'tcx, Tag, M> InterpretCx<'mir, 'tcx, M> +impl<'mir, 'tcx, Tag, M> InterpCx<'mir, 'tcx, M> where // FIXME: Working around https://github.com/rust-lang/rust/issues/54385 Tag: ::std::fmt::Debug + Copy + Eq + Hash + 'static, @@ -301,8 +277,6 @@ where { /// Take a value, which represents a (thin or fat) reference, and make it a place. /// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`. - /// This does NOT call the "deref" machine hook, so it does NOT count as a - /// deref as far as Stacked Borrows is concerned. Use `deref_operand` for that! pub fn ref_to_mplace( &self, val: ImmTy<'tcx, M::PointerTag>, @@ -322,8 +296,8 @@ where Ok(MPlaceTy { mplace, layout }) } - // Take an operand, representing a pointer, and dereference it to a place -- that - // will always be a MemPlace. Lives in `place.rs` because it creates a place. + /// Take an operand, representing a pointer, and dereference it to a place -- that + /// will always be a MemPlace. Lives in `place.rs` because it creates a place. pub fn deref_operand( &self, src: OpTy<'tcx, M::PointerTag>, @@ -333,6 +307,36 @@ where self.ref_to_mplace(val) } + /// Check if the given place is good for memory access with the given + /// size, falling back to the layout's size if `None` (in the latter case, + /// this must be a statically sized type). + /// + /// On success, returns `None` for zero-sized accesses (where nothing else is + /// left to do) and a `Pointer` to use for the actual access otherwise. + #[inline] + pub fn check_mplace_access( + &self, + place: MPlaceTy<'tcx, M::PointerTag>, + size: Option, + ) -> InterpResult<'tcx, Option>> { + let size = size.unwrap_or_else(|| { + assert!(!place.layout.is_unsized()); + assert!(place.meta.is_none()); + place.layout.size + }); + self.memory.check_ptr_access(place.ptr, size, place.align) + } + + /// Force `place.ptr` to a `Pointer`. + /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot. + pub fn force_mplace_ptr( + &self, + mut place: MPlaceTy<'tcx, M::PointerTag>, + ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { + place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into(); + Ok(place) + } + /// Offset a pointer to project to a field. Unlike `place_field`, this is always /// possible without allocating, so it can take `&self`. Also return the field's layout. /// This supports both struct and array fields. @@ -351,8 +355,8 @@ where if field >= len { // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. - debug!("Tried to access element {} of array/slice with length {}", field, len); - return err!(BoundsCheck { len, index: field }); + debug!("tried to access element {} of array/slice with length {}", field, len); + throw_panic!(BoundsCheck { len, index: field }); } stride * field } @@ -583,7 +587,7 @@ where // global table but not in its local memory: It calls back into tcx through // a query, triggering the CTFE machinery to actually turn this lazy reference // into a bunch of bytes. IOW, statics are evaluated with CTFE even when - // this InterpretCx uses another Machine (e.g., in miri). This is what we + // this InterpCx uses another Machine (e.g., in miri). This is what we // want! This way, computing statics works consistently between codegen // and miri: They use the same query to eventually obtain a `ty::Const` // and use that for further computation. @@ -618,7 +622,7 @@ where .layout_of(self.monomorphize(self.frame().body.return_ty())?)?, } } - None => return err!(InvalidNullPointerUsage), + None => throw_unsup!(InvalidNullPointerUsage), }, PlaceBase::Local(local) => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing @@ -741,14 +745,12 @@ where value: Immediate, dest: MPlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx> { - let (ptr, ptr_align) = dest.to_scalar_ptr_align(); // Note that it is really important that the type here is the right one, and matches the // type things are read at. In case `src_val` is a `ScalarPair`, we don't do any magic here // to handle padding properly, which is only correct if we never look at this data with the // wrong type. - assert!(!dest.layout.is_unsized()); - let ptr = match self.memory.check_ptr_access(ptr, dest.layout.size, ptr_align)? { + let ptr = match self.check_mplace_access(dest, None)? { Some(ptr) => ptr, None => return Ok(()), // zero-sized access }; @@ -850,14 +852,21 @@ where dest.layout.size }); assert_eq!(src.meta, dest.meta, "Can only copy between equally-sized instances"); + + let src = self.check_mplace_access(src, Some(size))?; + let dest = self.check_mplace_access(dest, Some(size))?; + let (src_ptr, dest_ptr) = match (src, dest) { + (Some(src_ptr), Some(dest_ptr)) => (src_ptr, dest_ptr), + (None, None) => return Ok(()), // zero-sized copy + _ => bug!("The pointers should both be Some or both None"), + }; + self.memory.copy( - src.ptr, src.align, - dest.ptr, dest.align, + src_ptr, + dest_ptr, size, /*nonoverlapping*/ true, - )?; - - Ok(()) + ) } /// Copies the data from an operand to a place. The layouts may disagree, but they must diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index ad631793a0..47289064f4 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -11,8 +11,7 @@ use rustc::ich::StableHashingContextProvider; use rustc::mir; use rustc::mir::interpret::{ AllocId, Pointer, Scalar, - Relocations, Allocation, UndefMask, - InterpResult, InterpError, + Relocations, Allocation, UndefMask, InterpResult, }; use rustc::ty::{self, TyCtxt}; @@ -77,7 +76,7 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> { } // Second cycle - Err(InterpError::InfiniteLoop.into()) + throw_exhaust!(InfiniteLoop) } } @@ -305,8 +304,8 @@ impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup { #[derive(Eq, PartialEq)] struct FrameSnapshot<'a, 'tcx> { - instance: &'a ty::Instance<'tcx>, - span: &'a Span, + instance: ty::Instance<'tcx>, + span: Span, return_to_block: &'a StackPopCleanup, return_place: Option>>, locals: IndexVec>>, @@ -345,8 +344,8 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> } = self; FrameSnapshot { - instance, - span, + instance: *instance, + span: *span, return_to_block, block, stmt: *stmt, diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 2f99973b90..d152e2b50f 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -1,4 +1,4 @@ -//! This module contains the `InterpretCx` methods for executing a single step of the interpreter. +//! This module contains the `InterpCx` methods for executing a single step of the interpreter. //! //! The main entry point is the `step` method. @@ -6,7 +6,7 @@ use rustc::mir; use rustc::ty::layout::LayoutOf; use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic}; -use super::{InterpretCx, Machine}; +use super::{InterpCx, Machine}; /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the /// same type as the result. @@ -35,7 +35,7 @@ fn binop_right_homogeneous(op: mir::BinOp) -> bool { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn run(&mut self) -> InterpResult<'tcx> { while self.step()? {} Ok(()) @@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // size of MIR constantly. Nop => {} - InlineAsm { .. } => return err!(InlineAsm), + InlineAsm { .. } => throw_unsup_format!("inline assembly is not supported"), } self.stack[frame_idx].stmt += 1; @@ -209,17 +209,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let dest = self.force_allocation(dest)?; let length = dest.len(self)?; - if length > 0 { - // write the first + if let Some(first_ptr) = self.check_mplace_access(dest, None)? { + // Write the first. let first = self.mplace_field(dest, 0)?; self.copy_op(op, first.into())?; if length > 1 { - // copy the rest - let (dest, dest_align) = first.to_scalar_ptr_align(); - let rest = dest.ptr_offset(first.layout.size, self)?; + let elem_size = first.layout.size; + // Copy the rest. This is performance-sensitive code + // for big static/const arrays! + let rest_ptr = first_ptr.offset(elem_size, self)?; self.memory.copy_repeatedly( - dest, dest_align, rest, dest_align, first.layout.size, length - 1, true + first_ptr, rest_ptr, elem_size, length - 1, /*nonoverlapping:*/true )?; } } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 13baf245d1..1d6b48e9da 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -6,12 +6,12 @@ use rustc::ty::layout::{self, TyLayout, LayoutOf}; use syntax::source_map::Span; use rustc_target::spec::abi::Abi; -use rustc::mir::interpret::{InterpResult, PointerArithmetic, InterpError, Scalar}; use super::{ - InterpretCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup + InterpResult, PointerArithmetic, Scalar, + InterpCx, Machine, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, }; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline] pub fn goto_block(&mut self, target: Option) -> InterpResult<'tcx> { if let Some(target) = target { @@ -19,7 +19,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.frame_mut().stmt = 0; Ok(()) } else { - err!(Unreachable) + throw_ub!(Unreachable) } } @@ -76,25 +76,24 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { }; let func = self.eval_operand(func, None)?; - let (fn_def, abi) = match func.layout.ty.sty { + let (fn_val, abi) = match func.layout.ty.sty { ty::FnPtr(sig) => { let caller_abi = sig.abi(); - let fn_ptr = self.force_ptr(self.read_scalar(func)?.not_undef()?)?; - let instance = self.memory.get_fn(fn_ptr)?; - (instance, caller_abi) + let fn_ptr = self.read_scalar(func)?.not_undef()?; + let fn_val = self.memory.get_fn(fn_ptr)?; + (fn_val, caller_abi) } ty::FnDef(def_id, substs) => { let sig = func.layout.ty.fn_sig(*self.tcx); - (self.resolve(def_id, substs)?, sig.abi()) + (FnVal::Instance(self.resolve(def_id, substs)?), sig.abi()) }, _ => { - let msg = format!("can't handle callee of type {:?}", func.layout.ty); - return err!(Unimplemented(msg)); + bug!("invalid callee of type {:?}", func.layout.ty) } }; let args = self.eval_operands(args)?; self.eval_fn_call( - fn_def, + fn_val, terminator.source_info.span, abi, &args[..], @@ -135,25 +134,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.goto_block(Some(target))?; } else { // Compute error message - use rustc::mir::interpret::InterpError::*; - return match *msg { + use rustc::mir::interpret::PanicInfo::*; + return Err(match msg { BoundsCheck { ref len, ref index } => { - let len = self.read_immediate(self.eval_operand(len, None)?) - .expect("can't eval len").to_scalar()? + let len = self + .read_immediate(self.eval_operand(len, None)?) + .expect("can't eval len") + .to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - let index = self.read_immediate(self.eval_operand(index, None)?) - .expect("can't eval index").to_scalar()? + let index = self + .read_immediate(self.eval_operand(index, None)?) + .expect("can't eval index") + .to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - err!(BoundsCheck { len, index }) + err_panic!(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!(), - }; + Overflow(op) => err_panic!(Overflow(*op)), + OverflowNeg => err_panic!(OverflowNeg), + DivisionByZero => err_panic!(DivisionByZero), + RemainderByZero => err_panic!(RemainderByZero), + GeneratorResumedAfterReturn => err_panic!(GeneratorResumedAfterReturn), + GeneratorResumedAfterPanic => err_panic!(GeneratorResumedAfterPanic), + Panic { .. } => bug!("`Panic` variant cannot occur in MIR"), + } + .into()); } } @@ -166,7 +170,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { `simplify_branches` mir pass"), FalseUnwind { .. } => bug!("should have been eliminated by\ `simplify_branches` mir pass"), - Unreachable => return err!(Unreachable), + Unreachable => throw_ub!(Unreachable), } Ok(()) @@ -213,13 +217,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { return Ok(()); } let caller_arg = caller_arg.next() - .ok_or_else(|| InterpError::FunctionArgCountMismatch)?; + .ok_or_else(|| err_unsup!(FunctionArgCountMismatch)) ?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } // Now, check if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { - return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); + throw_unsup!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)) } // We allow some transmutes here self.copy_op_transmute(caller_arg, callee_arg) @@ -228,25 +232,32 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { /// Call this function -- pushing the stack frame and initializing the arguments. fn eval_fn_call( &mut self, - instance: ty::Instance<'tcx>, + fn_val: FnVal<'tcx, M::ExtraFnVal>, span: Span, caller_abi: Abi, args: &[OpTy<'tcx, M::PointerTag>], dest: Option>, ret: Option, ) -> InterpResult<'tcx> { - trace!("eval_fn_call: {:#?}", instance); + trace!("eval_fn_call: {:#?}", fn_val); + + let instance = match fn_val { + FnVal::Instance(instance) => instance, + FnVal::Other(extra) => { + return M::call_extra_fn(self, extra, args, dest, ret); + } + }; match instance.def { ty::InstanceDef::Intrinsic(..) => { if caller_abi != Abi::RustIntrinsic { - return err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); + throw_unsup!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)) } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) let dest = match dest { Some(dest) => dest, - None => return err!(Unreachable) + None => throw_ub!(Unreachable) }; M::call_intrinsic(self, instance, args, dest)?; // No stack frame gets pushed, the main loop will just act as if the @@ -273,10 +284,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { _ => bug!("unexpected callee ty: {:?}", instance_ty), } }; - // Rust and RustCall are compatible - let normalize_abi = |abi| if abi == Abi::RustCall { Abi::Rust } else { abi }; + let normalize_abi = |abi| match abi { + Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic => + // These are all the same ABI, really. + Abi::Rust, + abi => + abi, + }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { - return err!(FunctionAbiMismatch(caller_abi, callee_abi)); + throw_unsup!(FunctionAbiMismatch(caller_abi, callee_abi)) } } @@ -371,7 +387,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // Now we should have no more caller args if caller_iter.next().is_some() { trace!("Caller has passed too many args"); - return err!(FunctionArgCountMismatch); + throw_unsup!(FunctionArgCountMismatch) } // Don't forget to check the return type! if let Some(caller_ret) = dest { @@ -383,15 +399,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { caller_ret.layout, callee_ret.layout, ) { - return err!(FunctionRetMismatch( - caller_ret.layout.ty, callee_ret.layout.ty - )); + throw_unsup!( + FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) + ) } } else { let local = mir::RETURN_PLACE; - let ty = self.frame().body.local_decls[local].ty; - if !self.tcx.is_ty_uninhabited_from_any_module(ty) { - return err!(FunctionRetMismatch(self.tcx.types.never, ty)); + let callee_layout = self.layout_of_local(self.frame(), local, None)?; + if !callee_layout.abi.is_uninhabited() { + throw_unsup!(FunctionRetMismatch( + self.tcx.types.never, callee_layout.ty + )) } } Ok(()) @@ -419,7 +437,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } None => { // Unsized self. - args[0].to_mem_place() + args[0].assert_mem_place() } }; // Find and consult vtable @@ -431,8 +449,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.tcx.data_layout.pointer_align.abi, )?.expect("cannot be a ZST"); let fn_ptr = self.memory.get(vtable_slot.alloc_id)? - .read_ptr_sized(self, vtable_slot)?.to_ptr()?; - let instance = self.memory.get_fn(fn_ptr)?; + .read_ptr_sized(self, vtable_slot)?.not_undef()?; + let drop_fn = self.memory.get_fn(fn_ptr)?; // `*mut receiver_place.layout.ty` is almost the layout that we // want for args[0]: We have to project to field 0 because we want @@ -443,11 +461,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { // Adjust receiver argument. args[0] = OpTy::from(ImmTy { layout: this_receiver_ptr, - imm: Immediate::Scalar(receiver_place.ptr.into()) + imm: receiver_place.ptr.into() }); trace!("Patched self operand to {:#?}", args[0]); // recurse with concrete function - self.eval_fn_call(instance, span, caller_abi, &args, dest, ret) + self.eval_fn_call(drop_fn, span, caller_abi, &args, dest, ret) } } } @@ -482,7 +500,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let dest = MPlaceTy::dangling(self.layout_of(ty)?, self); self.eval_fn_call( - instance, + FnVal::Instance(instance), span, Abi::Rust, &[arg.into()], diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 5d2f268d26..e55b0d0fb1 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,10 +1,10 @@ use rustc::ty::{self, Ty, Instance}; use rustc::ty::layout::{Size, Align, LayoutOf}; -use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic}; +use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic,}; -use super::{InterpretCx, InterpError, Machine, MemoryKind}; +use super::{InterpCx, Machine, MemoryKind, FnVal}; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for /// objects. /// @@ -56,7 +56,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let tcx = &*self.tcx; let drop = Instance::resolve_drop_in_place(*tcx, ty); - let drop = self.memory.create_fn_alloc(drop); + let drop = self.memory.create_fn_alloc(FnVal::Instance(drop)); // no need to do any alignment checks on the memory accesses below, because we know the // allocation is correctly aligned as we created it above. Also we're only offsetting by @@ -83,8 +83,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::TooGeneric)?; - let fn_ptr = self.memory.create_fn_alloc(instance); + ).ok_or_else(|| err_inval!(TooGeneric))?; + let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?; self.memory .get_mut(method_ptr.alloc_id)? @@ -112,8 +112,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { let drop_fn = self.memory .get(vtable.alloc_id)? .read_ptr_sized(self, vtable)? - .to_ptr()?; - let drop_instance = self.memory.get_fn(drop_fn)?; + .not_undef()?; + // We *need* an instance here, no other kind of function value, to be able + // to determine the type. + let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?; trace!("Found drop fn: {:?}", drop_instance); let fn_sig = drop_instance.ty(*self.tcx).fn_sig(*self.tcx); let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, &fn_sig); diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index b2a159fef5..82d6d7db01 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -6,17 +6,15 @@ use rustc::hir; use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx}; use rustc::ty; use rustc_data_structures::fx::FxHashSet; -use rustc::mir::interpret::{ - GlobalAlloc, InterpResult, InterpError, -}; use std::hash::Hash; use super::{ - OpTy, Machine, InterpretCx, ValueVisitor, MPlaceTy, + GlobalAlloc, InterpResult, + OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, }; -macro_rules! validation_failure { +macro_rules! throw_validation_failure { ($what:expr, $where:expr, $details:expr) => {{ let where_ = path_format(&$where); let where_ = if where_.is_empty() { @@ -24,7 +22,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(ValidationFailure(format!( + throw_unsup!(ValidationFailure(format!( "encountered {}{}, but expected {}", $what, where_, $details, ))) @@ -36,7 +34,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(ValidationFailure(format!( + throw_unsup!(ValidationFailure(format!( "encountered {}{}", $what, where_, ))) @@ -47,14 +45,14 @@ macro_rules! try_validation { ($e:expr, $what:expr, $where:expr, $details:expr) => {{ match $e { Ok(x) => x, - Err(_) => return validation_failure!($what, $where, $details), + Err(_) => throw_validation_failure!($what, $where, $details), } }}; ($e:expr, $what:expr, $where:expr) => {{ match $e { Ok(x) => x, - Err(_) => return validation_failure!($what, $where), + Err(_) => throw_validation_failure!($what, $where), } }} } @@ -153,15 +151,16 @@ fn wrapping_range_format(r: &RangeInclusive, max_hi: u128) -> String { debug_assert!(hi <= max_hi); if lo > hi { format!("less or equal to {}, or greater or equal to {}", hi, lo) + } else if lo == hi { + format!("equal to {}", lo) + } else if lo == 0 { + debug_assert!(hi < max_hi, "should not be printing if the range covers everything"); + format!("less or equal to {}", hi) + } else if hi == max_hi { + debug_assert!(lo > 0, "should not be printing if the range covers everything"); + format!("greater or equal to {}", lo) } else { - if lo == 0 { - debug_assert!(hi < max_hi, "should not be printing if the range covers everything"); - format!("less or equal to {}", hi) - } else if hi == max_hi { - format!("greater or equal to {}", lo) - } else { - format!("in the range {:?}", r) - } + format!("in the range {:?}", r) } } @@ -174,7 +173,7 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { MPlaceTy<'tcx, M::PointerTag>, Vec, >>, - ecx: &'rt InterpretCx<'mir, 'tcx, M>, + ecx: &'rt InterpCx<'mir, 'tcx, M>, } impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> { @@ -259,7 +258,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> type V = OpTy<'tcx, M::PointerTag>; #[inline(always)] - fn ecx(&self) -> &InterpretCx<'mir, 'tcx, M> { + fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> { &self.ecx } @@ -298,12 +297,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> match self.walk_value(op) { Ok(()) => Ok(()), Err(err) => match err.kind { - InterpError::InvalidDiscriminant(val) => - validation_failure!( + err_unsup!(InvalidDiscriminant(val)) => + throw_validation_failure!( val, self.path, "a valid enum discriminant" ), - InterpError::ReadPointerAsBytes => - validation_failure!( + err_unsup!(ReadPointerAsBytes) => + throw_validation_failure!( "a pointer", self.path, "plain (non-pointer) bytes" ), _ => Err(err), @@ -362,7 +361,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> "uninitialized data in fat pointer metadata", self.path); let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?; if layout.is_unsized() { - let tail = self.ecx.tcx.struct_tail(layout.ty); + let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(layout.ty, + self.ecx.param_env); match tail.sty { ty::Dynamic(..) => { let vtable = meta.unwrap(); @@ -398,7 +398,9 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // alignment and size determined by the layout (size will be 0, // alignment should take attributes into account). .unwrap_or_else(|| (layout.size, layout.align.abi)); - let ptr: Option<_> = match self.ecx.memory.check_ptr_access(ptr, size, align) { + let ptr: Option<_> = match + self.ecx.memory.check_ptr_access_align(ptr, size, Some(align)) + { Ok(ptr) => ptr, Err(err) => { info!( @@ -406,20 +408,20 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> ptr, size, align ); match err.kind { - InterpError::InvalidNullPointerUsage => - return validation_failure!("NULL reference", self.path), - InterpError::AlignmentCheckFailed { required, has } => - return validation_failure!(format!("unaligned reference \ + err_unsup!(InvalidNullPointerUsage) => + throw_validation_failure!("NULL reference", self.path), + err_unsup!(AlignmentCheckFailed { required, has }) => + throw_validation_failure!(format!("unaligned reference \ (required {} byte alignment but found {})", required.bytes(), has.bytes()), self.path), - InterpError::ReadBytesAsPointer => - return validation_failure!( - "integer pointer in non-ZST reference", + err_unsup!(ReadBytesAsPointer) => + throw_validation_failure!( + "dangling reference (created from integer)", self.path ), _ => - return validation_failure!( - "dangling (not entirely in bounds) reference", + throw_validation_failure!( + "dangling reference (not entirely in bounds)", self.path ), } @@ -441,9 +443,16 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } } - // Check if we have encountered this pointer+layout combination - // before. Proceed recursively even for ZST, no - // reason to skip them! E.g., `!` is a ZST and we want to validate it. + // Proceed recursively even for ZST, no reason to skip them! + // `!` is a ZST and we want to validate it. + // Normalize before handing `place` to tracking because that will + // check for duplicates. + let place = if size.bytes() > 0 { + self.ecx.force_mplace_ptr(place) + .expect("we already bounds-checked") + } else { + place + }; let path = &self.path; ref_tracking.track(place, || { // We need to clone the path anyway, make sure it gets created @@ -457,10 +466,10 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } ty::FnPtr(_sig) => { let value = value.to_scalar_or_undef(); - let ptr = try_validation!(value.to_ptr(), - value, self.path, "a pointer"); - let _fn = try_validation!(self.ecx.memory.get_fn(ptr), - value, self.path, "a function pointer"); + let _fn = try_validation!( + value.not_undef().and_then(|ptr| self.ecx.memory.get_fn(ptr)), + value, self.path, "a function pointer" + ); // FIXME: Check if the signature matches } // This should be all the primitive types @@ -471,7 +480,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> fn visit_uninhabited(&mut self) -> InterpResult<'tcx> { - validation_failure!("a value of an uninhabited type", self.path) + throw_validation_failure!("a value of an uninhabited type", self.path) } fn visit_scalar( @@ -504,29 +513,27 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> if lo == 1 && hi == max_hi { // Only NULL is the niche. So make sure the ptr is NOT NULL. if self.ecx.memory.ptr_may_be_null(ptr) { - // These conditions are just here to improve the diagnostics so we can - // differentiate between null pointers and dangling pointers - if self.ref_tracking_for_consts.is_some() && - self.ecx.memory.get(ptr.alloc_id).is_err() && - self.ecx.memory.get_fn(ptr).is_err() { - return validation_failure!( - "encountered dangling pointer", self.path - ); - } - return validation_failure!("a potentially NULL pointer", self.path); + throw_validation_failure!( + "a potentially NULL pointer", + self.path, + format!( + "something that cannot possibly fail to be {}", + wrapping_range_format(&layout.valid_range, max_hi) + ) + ) } return Ok(()); } else { - // Conservatively, we reject, because the pointer *could* have this + // Conservatively, we reject, because the pointer *could* have a bad // value. - return validation_failure!( + throw_validation_failure!( "a pointer", self.path, format!( "something that cannot possibly fail to be {}", wrapping_range_format(&layout.valid_range, max_hi) ) - ); + ) } } Ok(data) => @@ -536,7 +543,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> if wrapping_range_contains(&layout.valid_range, bits) { Ok(()) } else { - validation_failure!( + throw_validation_failure!( bits, self.path, format!("something {}", wrapping_range_format(&layout.valid_range, max_hi)) @@ -551,7 +558,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> ) -> InterpResult<'tcx> { match op.layout.ty.sty { ty::Str => { - let mplace = op.to_mem_place(); // strings are never immediate + let mplace = op.assert_mem_place(); // strings are never immediate try_validation!(self.ecx.read_str(mplace), "uninitialized or non-UTF-8 data in str", self.path); } @@ -568,7 +575,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> return Ok(()); } // non-ZST array cannot be immediate, slices are never immediate - let mplace = op.to_mem_place(); + let mplace = op.assert_mem_place(); // This is the length of the array/slice. let len = mplace.len(self.ecx)?; // zero length slices have nothing to be checked @@ -579,7 +586,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> let ty_size = self.ecx.layout_of(tys)?.size; // This is the size in bytes of the whole array. let size = ty_size * len; - + // Size is not 0, get a pointer. let ptr = self.ecx.force_ptr(mplace.ptr)?; // NOTE: Keep this in sync with the handling of integer and float @@ -603,16 +610,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> Err(err) => { // For some errors we might be able to provide extra information match err.kind { - InterpError::ReadUndefBytes(offset) => { + err_unsup!(ReadUndefBytes(offset)) => { // Some byte was undefined, determine which // element that byte belongs to so we can // provide an index. let i = (offset.bytes() / ty_size.bytes()) as usize; self.path.push(PathElem::ArrayElem(i)); - return validation_failure!( - "undefined bytes", self.path - ) + throw_validation_failure!("undefined bytes", self.path) }, // Other errors shouldn't be possible _ => return Err(err), @@ -628,7 +633,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// This function checks the data at `op`. `op` is assumed to cover valid memory if it /// is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. @@ -636,7 +641,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { /// `ref_tracking_for_consts` can be `None` to avoid recursive checking below references. /// This also toggles between "run-time" (no recursion) and "compile-time" (with recursion) /// validation (e.g., pointer values are fine in integers at runtime) and various other const - /// specific validation checks + /// specific validation checks. pub fn validate_operand( &self, op: OpTy<'tcx, M::PointerTag>, @@ -655,6 +660,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { ecx: self, }; + // Try to cast to ptr *once* instead of all the time. + let op = self.force_op_ptr(op).unwrap_or(op); + // Run it visitor.visit_value(op) } diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index d04dc3ab37..91fbd307db 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -8,7 +8,7 @@ use rustc::mir::interpret::{ }; use super::{ - Machine, InterpretCx, MPlaceTy, OpTy, + Machine, InterpCx, MPlaceTy, OpTy, }; // A thing that we can project into, and that has a layout. @@ -21,7 +21,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy { /// Makes this into an `OpTy`. fn to_op( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>>; /// Creates this from an `MPlaceTy`. @@ -30,14 +30,14 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy { /// Projects to the given enum variant. fn project_downcast( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, variant: VariantIdx, ) -> InterpResult<'tcx, Self>; /// Projects to the n-th field. fn project_field( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, field: u64, ) -> InterpResult<'tcx, Self>; } @@ -53,7 +53,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: #[inline(always)] fn to_op( self, - _ecx: &InterpretCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { Ok(self) } @@ -66,7 +66,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: #[inline(always)] fn project_downcast( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, variant: VariantIdx, ) -> InterpResult<'tcx, Self> { ecx.operand_downcast(self, variant) @@ -75,7 +75,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: #[inline(always)] fn project_field( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, field: u64, ) -> InterpResult<'tcx, Self> { ecx.operand_field(self, field) @@ -91,7 +91,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, #[inline(always)] fn to_op( self, - _ecx: &InterpretCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { Ok(self.into()) } @@ -104,7 +104,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, #[inline(always)] fn project_downcast( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, variant: VariantIdx, ) -> InterpResult<'tcx, Self> { ecx.mplace_downcast(self, variant) @@ -113,7 +113,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, #[inline(always)] fn project_field( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, field: u64, ) -> InterpResult<'tcx, Self> { ecx.mplace_field(self, field) @@ -126,9 +126,9 @@ macro_rules! make_value_visitor { pub trait $visitor_trait_name<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { type V: Value<'mir, 'tcx, M>; - /// The visitor must have an `InterpretCx` in it. + /// The visitor must have an `InterpCx` in it. fn ecx(&$($mutability)? self) - -> &$($mutability)? InterpretCx<'mir, 'tcx, M>; + -> &$($mutability)? InterpCx<'mir, 'tcx, M>; // Recursive actions, ready to be overloaded. /// Visits the given value, dispatching as appropriate to more specialized visitors. @@ -242,7 +242,7 @@ macro_rules! make_value_visitor { match v.layout().ty.sty { ty::Dynamic(..) => { // immediate trait objects are not a thing - let dest = v.to_op(self.ecx())?.to_mem_place(); + let dest = v.to_op(self.ecx())?.assert_mem_place(); let inner = self.ecx().unpack_dyn_trait(dest)?.1; trace!("walk_value: dyn object layout: {:#?}", inner.layout); // recurse with the inner type @@ -316,7 +316,7 @@ macro_rules! make_value_visitor { MPlaceTy::dangling(v.layout(), self.ecx()) } else { // non-ZST array/slice/str cannot be immediate - v.to_op(self.ecx())?.to_mem_place() + v.to_op(self.ecx())?.assert_mem_place() }; // Now we can go over all the fields. let iter = self.ecx().mplace_array_fields(mplace)? diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index cb02e1a778..cccf7b9545 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -15,30 +15,22 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(decl_macro)] #![feature(exhaustive_patterns)] #![feature(rustc_diagnostic_macros)] -#![feature(rustc_attrs)] #![feature(never_type)] #![feature(specialization)] #![feature(try_trait)] #![feature(unicode_internals)] -#![feature(step_trait)] #![feature(slice_concat_ext)] #![feature(trusted_len)] #![feature(try_blocks)] +#![feature(mem_take)] +#![feature(associated_type_bounds)] #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate log; -#[macro_use] -extern crate rustc; +#[macro_use] extern crate rustc; #[macro_use] extern crate rustc_data_structures; -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving -#[macro_use] -extern crate syntax; +#[macro_use] extern crate syntax; mod error_codes; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index bb2738d5aa..12d763bb79 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -281,15 +281,15 @@ impl<'tcx> InliningMap<'tcx> { } } -pub fn collect_crate_mono_items<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn collect_crate_mono_items( + tcx: TyCtxt<'_>, mode: MonoItemCollectionMode, -) -> (FxHashSet>, InliningMap<'tcx>) { +) -> (FxHashSet>, InliningMap<'_>) { let roots = time(tcx.sess, "collecting roots", || { collect_roots(tcx, mode) }); - debug!("Building mono item graph, beginning at roots"); + debug!("building mono item graph, beginning at roots"); let mut visited = MTLock::new(FxHashSet::default()); let mut inlining_map = MTLock::new(InliningMap::new()); @@ -315,8 +315,8 @@ pub fn collect_crate_mono_items<'tcx>( // Find all non-generic items by walking the HIR. These items serve as roots to // start monomorphizing from. -fn collect_roots<'tcx>(tcx: TyCtxt<'tcx>, mode: MonoItemCollectionMode) -> Vec> { - debug!("Collecting roots"); +fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec> { + debug!("collecting roots"); let mut roots = Vec::new(); { @@ -851,12 +851,13 @@ fn find_vtable_types_for_unsizing<'tcx>( target_ty: Ty<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { + let param_env = ty::ParamEnv::reveal_all(); let type_has_metadata = |ty: Ty<'tcx>| -> bool { use syntax_pos::DUMMY_SP; - if ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) { + if ty.is_sized(tcx.at(DUMMY_SP), param_env) { return false; } - let tail = tcx.struct_tail(ty); + let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env); match tail.sty { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, @@ -866,7 +867,7 @@ fn find_vtable_types_for_unsizing<'tcx>( if type_has_metadata(inner_source) { (inner_source, inner_target) } else { - tcx.struct_lockstep_tails(inner_source, inner_target) + tcx.struct_lockstep_tails_erasing_lifetimes(inner_source, inner_target, param_env) } }; @@ -912,7 +913,7 @@ fn find_vtable_types_for_unsizing<'tcx>( } } -fn create_fn_mono_item<'tcx>(instance: Instance<'tcx>) -> MonoItem<'tcx> { +fn create_fn_mono_item(instance: Instance<'_>) -> MonoItem<'_> { debug!("create_fn_mono_item(instance={})", instance); MonoItem::Fn(instance) } @@ -968,10 +969,10 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | hir::ItemKind::ForeignMod(..) | - hir::ItemKind::Ty(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | - hir::ItemKind::Existential(..) | + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Mod(..) => { // Nothing to do, just keep recursing... } @@ -989,7 +990,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { hir::ItemKind::Union(_, ref generics) => { if generics.params.is_empty() { if self.mode == MonoItemCollectionMode::Eager { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); debug!("RootCollector: ADT drop-glue for {}", def_id_to_string(self.tcx, def_id)); @@ -1001,11 +1002,11 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { hir::ItemKind::GlobalAsm(..) => { debug!("RootCollector: ItemKind::GlobalAsm({})", def_id_to_string(self.tcx, - self.tcx.hir().local_def_id_from_hir_id(item.hir_id))); + self.tcx.hir().local_def_id(item.hir_id))); self.output.push(MonoItem::GlobalAsm(item.hir_id)); } hir::ItemKind::Static(..) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); debug!("RootCollector: ItemKind::Static({})", def_id_to_string(self.tcx, def_id)); self.output.push(MonoItem::Static(def_id)); @@ -1015,7 +1016,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { // actually used somewhere. Just declaring them is insufficient. // but even just declaring them must collect the items they refer to - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let instance = Instance::mono(self.tcx, def_id); let cid = GlobalId { @@ -1029,7 +1030,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { } } hir::ItemKind::Fn(..) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); self.push_if_root(def_id); } } @@ -1043,7 +1044,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) { match ii.node { hir::ImplItemKind::Method(hir::MethodSig { .. }, _) => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(ii.hir_id); + let def_id = self.tcx.hir().local_def_id(ii.hir_id); self.push_if_root(def_id); } _ => { /* Nothing to do here */ } @@ -1114,7 +1115,7 @@ impl RootCollector<'_, 'v> { } } -fn item_requires_monomorphization<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let generics = tcx.generics_of(def_id); generics.requires_monomorphization(tcx) } @@ -1136,12 +1137,17 @@ fn create_mono_items_for_default_impls<'tcx>( } } - let impl_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id); + let impl_def_id = tcx.hir().local_def_id(item.hir_id); debug!("create_mono_items_for_default_impls(item={})", def_id_to_string(tcx, impl_def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { + let param_env = ty::ParamEnv::reveal_all(); + let trait_ref = tcx.normalize_erasing_regions( + param_env, + trait_ref, + ); let overridden_methods: FxHashSet<_> = impl_item_refs.iter() .map(|iiref| iiref.ident.modern()) @@ -1164,9 +1170,8 @@ fn create_mono_items_for_default_impls<'tcx>( } } }); - let instance = ty::Instance::resolve(tcx, - ty::ParamEnv::reveal_all(), + param_env, method.def_id, substs).unwrap(); @@ -1243,7 +1248,7 @@ fn collect_neighbours<'tcx>( } } -fn def_id_to_string<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> String { +fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String { let mut output = String::new(); let printer = DefPathBasedNames::new(tcx, false, false); printer.push_def_path(def_id, &mut output); diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 2bcf058ad7..e63426281b 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -55,7 +55,7 @@ pub trait MonoItemExt<'tcx>: fmt::Debug { tcx.symbol_name(Instance::mono(tcx, def_id)) } MonoItem::GlobalAsm(hir_id) => { - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); ty::SymbolName { name: InternedString::intern(&format!("global_asm_{:?}", def_id)) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 32e4d4f437..ad9db4e0aa 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -314,7 +314,7 @@ fn mono_item_visibility( }; } MonoItem::GlobalAsm(hir_id) => { - let def_id = tcx.hir().local_def_id_from_hir_id(*hir_id); + let def_id = tcx.hir().local_def_id(*hir_id); return if tcx.is_reachable_non_generic(def_id) { *can_be_internalized = false; default_visibility(tcx, def_id, false) @@ -698,7 +698,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( Some(def_id) } MonoItem::Static(def_id) => Some(def_id), - MonoItem::GlobalAsm(hir_id) => Some(tcx.hir().local_def_id_from_hir_id(hir_id)), + MonoItem::GlobalAsm(hir_id) => Some(tcx.hir().local_def_id(hir_id)), } } @@ -839,10 +839,10 @@ where } } -fn collect_and_partition_mono_items<'tcx>( - tcx: TyCtxt<'tcx>, +fn collect_and_partition_mono_items( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> (Arc, Arc>>>) { +) -> (Arc, Arc>>>) { assert_eq!(cnum, LOCAL_CRATE); let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 7987095a33..33447eba74 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -304,8 +304,10 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); + let param_env = tcx.param_env(def_id); + let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty); - let is_copy = self_ty.is_copy_modulo_regions(tcx, tcx.param_env(def_id), builder.span); + let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span); let dest = Place::RETURN_PLACE; let src = Place::from(Local::new(1+0)).deref(); @@ -313,7 +315,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) - match self_ty.sty { _ if is_copy => builder.copy_shim(), ty::Array(ty, len) => { - let len = len.unwrap_usize(tcx); + let len = len.eval_usize(tcx, param_env); builder.array_shim(dest, src, ty, len) } ty::Closure(def_id, substs) => { @@ -322,7 +324,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) - substs.upvar_tys(def_id, tcx) ) } - ty::Tuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().map(|k| k.expect_ty())), + ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()), _ => { bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty) } @@ -829,7 +831,7 @@ fn build_call_shim<'tcx>( body } -pub fn build_adt_ctor<'tcx>(tcx: TyCtxt<'tcx>, ctor_id: DefId) -> &'tcx Body<'tcx> { +pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); let span = tcx.hir().span_if_local(ctor_id) diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index e01017d7c9..d573423906 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -14,35 +14,31 @@ pub struct AddRetag; /// after the assignment, we can be sure to obtain the same place value. /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic /// copies. Data races are UB.) -fn is_stable<'tcx>( - place: &Place<'tcx>, +fn is_stable( + place: PlaceRef<'_, '_>, ) -> bool { - use rustc::mir::Place::*; - - match *place { - // Locals and statics have stable addresses, for sure - Base(PlaceBase::Local { .. }) | - Base(PlaceBase::Static { .. }) => - true, - // Recurse for projections - Projection(ref proj) => { - match proj.elem { - // Which place this evaluates to can change with any memory write, - // so cannot assume this to be stable. - ProjectionElem::Deref => - false, - // Array indices are intersting, but MIR building generates a *fresh* - // temporary for every array access, so the index cannot be changed as - // a side-effect. - ProjectionElem::Index { .. } | - // The rest is completely boring, they just offset by a constant. - ProjectionElem::Field { .. } | - ProjectionElem::ConstantIndex { .. } | - ProjectionElem::Subslice { .. } | - ProjectionElem::Downcast { .. } => - is_stable(&proj.base), - } + if let Some(proj) = &place.projection { + match proj.elem { + // Which place this evaluates to can change with any memory write, + // so cannot assume this to be stable. + ProjectionElem::Deref => + false, + // Array indices are intersting, but MIR building generates a *fresh* + // temporary for every array access, so the index cannot be changed as + // a side-effect. + ProjectionElem::Index { .. } | + // The rest is completely boring, they just offset by a constant. + ProjectionElem::Field { .. } | + ProjectionElem::ConstantIndex { .. } | + ProjectionElem::Subslice { .. } | + ProjectionElem::Downcast { .. } => + is_stable(PlaceRef { + base: place.base, + projection: &proj.base, + }), } + } else { + true } } @@ -83,7 +79,8 @@ impl MirPass for AddRetag { let needs_retag = |place: &Place<'tcx>| { // FIXME: Instead of giving up for unstable places, we should introduce // a temporary and retag on that. - is_stable(place) && may_have_reference(place.ty(&*local_decls, tcx).ty, tcx) + is_stable(place.as_ref()) + && may_have_reference(place.ty(&*local_decls, tcx).ty, tcx) }; // PART 1 diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 24df3549be..d5c5267a11 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -248,8 +248,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { }], &[]); } } - let is_borrow_of_interior_mut = context.is_borrow() && !proj.base - .ty(self.body, self.tcx) + let is_borrow_of_interior_mut = context.is_borrow() && + !Place::ty_from(&place.base, &proj.base, self.body, self.tcx) .ty .is_freeze(self.tcx, self.param_env, self.source_info.span); // prevent @@ -264,15 +264,15 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { ); } let old_source_info = self.source_info; - if let Place::Base(PlaceBase::Local(local)) = proj.base { - if self.body.local_decls[local].internal { + if let (PlaceBase::Local(local), None) = (&place.base, &proj.base) { + if self.body.local_decls[*local].internal { // Internal locals are used in the `move_val_init` desugaring. // We want to check unsafety against the source info of the // desugaring, rather than the source info of the RHS. - self.source_info = self.body.local_decls[local].source_info; + self.source_info = self.body.local_decls[*local].source_info; } } - let base_ty = proj.base.ty(self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.base, &proj.base, self.body, self.tcx).ty; match base_ty.sty { ty::RawPtr(..) => { self.require_unsafe("dereference of raw pointer", @@ -404,15 +404,16 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } fn check_mut_borrowing_layout_constrained_field( &mut self, - mut place: &Place<'tcx>, + place: &Place<'tcx>, is_mut_use: bool, ) { - while let &Place::Projection(box Projection { - ref base, ref elem - }) = place { - match *elem { + let mut projection = &place.projection; + while let Some(proj) = projection { + match proj.elem { ProjectionElem::Field(..) => { - let ty = base.ty(&self.body.local_decls, self.tcx).ty; + let ty = + Place::ty_from(&place.base, &proj.base, &self.body.local_decls, self.tcx) + .ty; match ty.sty { ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) { (Bound::Unbounded, Bound::Unbounded) => {}, @@ -446,7 +447,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } _ => {} } - place = base; + projection = &proj.base; } } } @@ -480,11 +481,11 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'a> { } } -fn check_unused_unsafe<'a, 'tcx>( - tcx: TyCtxt<'tcx>, +fn check_unused_unsafe( + tcx: TyCtxt<'_>, def_id: DefId, used_unsafe: &FxHashSet, - unsafe_blocks: &'a mut Vec<(hir::HirId, bool)>, + unsafe_blocks: &mut Vec<(hir::HirId, bool)>, ) { let body_id = tcx.hir().as_local_hir_id(def_id).and_then(|hir_id| { @@ -506,7 +507,7 @@ fn check_unused_unsafe<'a, 'tcx>( hir::intravisit::Visitor::visit_body(&mut visitor, body); } -fn unsafety_check_result<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> UnsafetyCheckResult { +fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult { debug!("unsafety_violations({:?})", def_id); // N.B., this borrow is valid because all the consumers of @@ -545,17 +546,17 @@ fn unsafety_check_result<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> UnsafetyChec } } -fn unsafe_derive_on_repr_packed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: DefId) { let lint_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(|| bug!("checking unsafety for non-local def id {:?}", def_id)); // FIXME: when we make this a hard error, this should have its // own error code. let message = if tcx.generics_of(def_id).own_requires_monomorphization() { - "#[derive] can't be used on a #[repr(packed)] struct with \ + "`#[derive]` can't be used on a `#[repr(packed)]` struct with \ type or const parameters (error E0133)".to_string() } else { - "#[derive] can't be used on a #[repr(packed)] struct that \ + "`#[derive]` can't be used on a `#[repr(packed)]` struct that \ does not derive Copy (error E0133)".to_string() }; tcx.lint_hir(SAFE_PACKED_BORROWS, @@ -602,7 +603,7 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id db.emit(); } -fn builtin_derive_def_id<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { +fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { debug!("builtin_derive_def_id({:?})", def_id); if let Some(impl_def_id) = tcx.impl_of_method(def_id) { if tcx.has_attr(impl_def_id, sym::automatically_derived) { @@ -618,7 +619,7 @@ fn builtin_derive_def_id<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option(tcx: TyCtxt<'tcx>, def_id: DefId) { +pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { debug!("check_unsafety({:?})", def_id); // closures are handled by their parent fn. diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index c7a2fdd938..38d26d0ba5 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -13,7 +13,7 @@ use rustc::mir::{ use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, }; -use rustc::mir::interpret::{InterpError, Scalar, GlobalId, InterpResult}; +use rustc::mir::interpret::{Scalar, GlobalId, InterpResult, PanicInfo}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; @@ -23,7 +23,7 @@ use rustc::ty::layout::{ }; use crate::interpret::{ - self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, + self, InterpCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind, StackPopCleanup, LocalValue, LocalState, }; use crate::const_eval::{ @@ -117,7 +117,7 @@ type Const<'tcx> = OpTy<'tcx>; /// Finds optimization opportunities on the MIR. struct ConstPropagator<'mir, 'tcx> { - ecx: InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, can_const_prop: IndexVec, @@ -202,7 +202,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // If the local is `Unitialized` or `Dead` then we haven't propagated a value into it. // - // `InterpretCx::access_local()` mostly takes care of this for us however, for ZSTs, + // `InterpCx::access_local()` mostly takes care of this for us however, for ZSTs, // it will synthesize a value for us. In doing so, that will cause the // `get_const(l).is_empty()` assert right before we call `set_const()` in `visit_statement` // to fail. @@ -258,94 +258,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let diagnostic = error_to_const_error(&self.ecx, error); use rustc::mir::interpret::InterpError::*; match diagnostic.error { - // don't report these, they make no sense in a const prop context - | MachineError(_) - | Exit(_) - // at runtime these transformations might make sense - // FIXME: figure out the rules and start linting - | FunctionAbiMismatch(..) - | FunctionArgMismatch(..) - | FunctionRetMismatch(..) - | FunctionArgCountMismatch - // fine at runtime, might be a register address or sth - | ReadBytesAsPointer - // fine at runtime - | ReadForeignStatic - | Unimplemented(_) - // don't report const evaluator limits - | StackFrameLimitReached - | NoMirFor(..) - | InlineAsm - => {}, - - | InvalidMemoryAccess - | DanglingPointerDeref - | DoubleFree - | InvalidFunctionPointer - | InvalidBool - | InvalidDiscriminant(..) - | PointerOutOfBounds { .. } - | InvalidNullPointerUsage - | ValidationFailure(..) - | InvalidPointerMath - | ReadUndefBytes(_) - | DeadLocal - | InvalidBoolOp(_) - | DerefFunctionPointer - | ExecuteMemory - | Intrinsic(..) - | InvalidChar(..) - | AbiViolation(_) - | AlignmentCheckFailed{..} - | CalledClosureAsFunction - | VtableForArgumentlessMethod - | ModifiedConstantMemory - | ModifiedStatic - | AssumptionNotHeld - // FIXME: should probably be removed and turned into a bug! call - | TypeNotPrimitive(_) - | ReallocatedWrongMemoryKind(_, _) - | DeallocatedWrongMemoryKind(_, _) - | ReallocateNonBasePtr - | DeallocateNonBasePtr - | IncorrectAllocationInformation(..) - | UnterminatedCString(_) - | HeapAllocZeroBytes - | HeapAllocNonPowerOfTwoAlignment(_) - | Unreachable - | ReadFromReturnPointer - | GeneratorResumedAfterReturn - | GeneratorResumedAfterPanic - | ReferencedConstant - | InfiniteLoop - => { - // FIXME: report UB here - }, - - | OutOfTls - | TlsOutOfBounds - | PathNotFound(_) - => bug!("these should not be in rustc, but in miri's machine errors"), - - | Layout(_) - | UnimplementedTraitSelection - | TypeckError - | TooGeneric - // these are just noise - => {}, - - // non deterministic - | ReadPointerAsBytes - // FIXME: implement - => {}, - - | Panic { .. } - | BoundsCheck{..} - | Overflow(_) - | OverflowNeg - | DivisionByZero - | RemainderByZero - => { + Exit(_) => bug!("the CTFE program cannot exit"), + Unsupported(_) + | UndefinedBehavior(_) + | InvalidProgram(_) + | ResourceExhaustion(_) => { + // Ignore these errors. + } + Panic(_) => { diagnostic.report_as_lint( self.ecx.tcx, "this expression will panic at runtime", @@ -522,7 +442,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need to do overflow check here: For actual CTFE, MIR // generation emits code that does this before calling the op. if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { - return err!(OverflowNeg); + throw_panic!(OverflowNeg) } } UnOp::Not => { @@ -600,7 +520,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) } else { if overflow { - let err = InterpError::Overflow(op).into(); + let err = err_panic!(Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; } @@ -781,7 +701,10 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { .ty; if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) { - if let Place::Base(PlaceBase::Local(local)) = *place { + if let Place { + base: PlaceBase::Local(local), + projection: None, + } = *place { trace!("checking whether {:?} can be stored to {:?}", value, local); if self.can_const_prop[local] { trace!("storing {:?} to {:?}", value, local); @@ -811,7 +734,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { self.super_terminator(terminator, location); let source_info = terminator.source_info; match &mut terminator.kind { - TerminatorKind::Assert { expected, msg, ref mut cond, .. } => { + TerminatorKind::Assert { expected, ref msg, ref mut cond, .. } => { if let Some(value) = self.eval_operand(&cond, source_info) { trace!("assertion on {:?} should be {:?}", value, expected); let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected)); @@ -821,11 +744,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // doesn't use the invalid value match cond { Operand::Move(ref place) | Operand::Copy(ref place) => { - let mut place = place; - while let Place::Projection(ref proj) = *place { - place = &proj.base; - } - if let Place::Base(PlaceBase::Local(local)) = *place { + if let PlaceBase::Local(local) = place.base { self.remove_const(local); } }, @@ -837,13 +756,13 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { .hir() .as_local_hir_id(self.source.def_id()) .expect("some part of a failing const eval must be local"); - use rustc::mir::interpret::InterpError::*; let msg = match msg { - Overflow(_) | - OverflowNeg | - DivisionByZero | - RemainderByZero => msg.description().to_owned(), - BoundsCheck { ref len, ref index } => { + PanicInfo::Overflow(_) | + PanicInfo::OverflowNeg | + PanicInfo::DivisionByZero | + PanicInfo::RemainderByZero => + msg.description().to_owned(), + PanicInfo::BoundsCheck { ref len, ref index } => { let len = self .eval_operand(len, source_info) .expect("len must be const"); diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index c850b48e07..7c9eeb5a57 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -47,7 +47,7 @@ impl MirPass for CopyPropagation { let mut changed = false; for dest_local in body.local_decls.indices() { - debug!("Considering destination local: {:?}", dest_local); + debug!("considering destination local: {:?}", dest_local); let action; let location; @@ -94,7 +94,10 @@ impl MirPass for CopyPropagation { // That use of the source must be an assignment. match statement.kind { StatementKind::Assign( - Place::Base(PlaceBase::Local(local)), + Place { + base: PlaceBase::Local(local), + projection: None, + }, box Rvalue::Use(ref operand) ) if local == dest_local => { let maybe_action = match *operand { @@ -145,12 +148,24 @@ fn eliminate_self_assignments( if let Some(stmt) = body[location.block].statements.get(location.statement_index) { match stmt.kind { StatementKind::Assign( - Place::Base(PlaceBase::Local(local)), - box Rvalue::Use(Operand::Copy(Place::Base(PlaceBase::Local(src_local)))), + Place { + base: PlaceBase::Local(local), + projection: None, + }, + box Rvalue::Use(Operand::Copy(Place { + base: PlaceBase::Local(src_local), + projection: None, + })), ) | StatementKind::Assign( - Place::Base(PlaceBase::Local(local)), - box Rvalue::Use(Operand::Move(Place::Base(PlaceBase::Local(src_local)))), + Place { + base: PlaceBase::Local(local), + projection: None, + }, + box Rvalue::Use(Operand::Move(Place { + base: PlaceBase::Local(src_local), + projection: None, + })), ) if local == dest_local && dest_local == src_local => {} _ => { continue; @@ -159,7 +174,7 @@ fn eliminate_self_assignments( } else { continue; } - debug!("Deleting a self-assignment for {:?}", dest_local); + debug!("deleting a self-assignment for {:?}", dest_local); body.make_statement_nop(location); changed = true; } @@ -177,7 +192,10 @@ impl<'tcx> Action<'tcx> { fn local_copy(body: &Body<'tcx>, def_use_analysis: &DefUseAnalysis, src_place: &Place<'tcx>) -> Option> { // The source must be a local. - let src_local = if let Place::Base(PlaceBase::Local(local)) = *src_place { + let src_local = if let Place { + base: PlaceBase::Local(local), + projection: None, + } = *src_place { local } else { debug!(" Can't copy-propagate local: source is not a local"); @@ -331,8 +349,14 @@ impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> { self.super_operand(operand, location); match *operand { - Operand::Copy(Place::Base(PlaceBase::Local(local))) | - Operand::Move(Place::Base(PlaceBase::Local(local))) if local == self.dest_local => {} + Operand::Copy(Place { + base: PlaceBase::Local(local), + projection: None, + }) | + Operand::Move(Place { + base: PlaceBase::Local(local), + projection: None, + }) if local == self.dest_local => {} _ => return, } diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 243820ba7d..a6fb555f20 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -14,7 +14,7 @@ use crate::util as mir_util; pub struct Marker(pub &'static str); impl MirPass for Marker { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { Cow::Borrowed(self.0) } @@ -52,7 +52,7 @@ pub fn on_mir_pass<'tcx>( } } -pub fn emit_mir<'tcx>(tcx: TyCtxt<'tcx>, outputs: &OutputFilenames) -> io::Result<()> { +pub fn emit_mir(tcx: TyCtxt<'_>, outputs: &OutputFilenames) -> io::Result<()> { let path = outputs.path(OutputType::Mir); let mut f = File::create(&path)?; mir_util::write_mir_pretty(tcx, None, &mut f)?; diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index ad19b974d7..0a021d9b8f 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -105,7 +105,7 @@ fn find_dead_unwinds<'tcx>( init_data.apply_location(tcx, body, env, loc); } - let path = match env.move_data.rev_lookup.find(location) { + let path = match env.move_data.rev_lookup.find(location.as_ref()) { LookupResult::Exact(e) => e, LookupResult::Parent(..) => { debug!("find_dead_unwinds: has parent; skipping"); @@ -360,7 +360,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { statement_index: data.statements.len() }); - let path = self.move_data().rev_lookup.find(location); + let path = self.move_data().rev_lookup.find(location.as_ref()); debug!("collect_drop_flags: {:?}, place {:?} ({:?})", bb, location, path); @@ -399,7 +399,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { match terminator.kind { TerminatorKind::Drop { ref location, target, unwind } => { let init_data = self.initialization_data_at(loc); - match self.move_data().rev_lookup.find(location) { + match self.move_data().rev_lookup.find(location.as_ref()) { LookupResult::Exact(path) => { elaborate_drop( &mut Elaborator { @@ -488,7 +488,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { is_cleanup: false, }); - match self.move_data().rev_lookup.find(location) { + match self.move_data().rev_lookup.find(location.as_ref()) { LookupResult::Exact(path) => { debug!("elaborate_drop_and_replace({:?}) - tracked {:?}", terminator, path); let init_data = self.initialization_data_at(loc); @@ -558,7 +558,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { assert!(!self.patch.is_patched(bb)); let loc = Location { block: tgt, statement_index: 0 }; - let path = self.move_data().rev_lookup.find(place); + let path = self.move_data().rev_lookup.find(place.as_ref()); on_lookup_result_bits( self.tcx, self.body, self.move_data(), path, |child| self.set_drop_flag(loc, child, DropFlagState::Present) @@ -632,7 +632,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { assert!(!self.patch.is_patched(bb)); let loc = Location { block: bb, statement_index: data.statements.len() }; - let path = self.move_data().rev_lookup.find(place); + let path = self.move_data().rev_lookup.find(place.as_ref()); on_lookup_result_bits( self.tcx, self.body, self.move_data(), path, |child| self.set_drop_flag(loc, child, DropFlagState::Present) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 1acebede2e..94bb70e10a 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -104,11 +104,14 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor { place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.base_local() == Some(self_arg()) { - replace_base(place, Place::Projection(Box::new(Projection { - base: Place::Base(PlaceBase::Local(self_arg())), - elem: ProjectionElem::Deref, - }))); + if place.base == PlaceBase::Local(self_arg()) { + replace_base(place, Place { + base: PlaceBase::Local(self_arg()), + projection: Some(Box::new(Projection { + base: None, + elem: ProjectionElem::Deref, + })), + }); } else { self.super_place(place, context, location); } @@ -131,11 +134,14 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if place.base_local() == Some(self_arg()) { - replace_base(place, Place::Projection(Box::new(Projection { - base: Place::Base(PlaceBase::Local(self_arg())), - elem: ProjectionElem::Field(Field::new(0), self.ref_gen_ty), - }))); + if place.base == PlaceBase::Local(self_arg()) { + replace_base(place, Place { + base: PlaceBase::Local(self_arg()), + projection: Some(Box::new(Projection { + base: None, + elem: ProjectionElem::Field(Field::new(0), self.ref_gen_ty), + })), + }); } else { self.super_place(place, context, location); } @@ -143,11 +149,13 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { } fn replace_base(place: &mut Place<'tcx>, new_base: Place<'tcx>) { - if let Place::Projection(proj) = place { - replace_base(&mut proj.base, new_base); - } else { - *place = new_base; + let mut projection = &mut place.projection; + while let Some(box proj) = projection { + projection = &mut proj.base; } + + place.base = new_base.base; + *projection = new_base.projection; } fn self_arg() -> Local { @@ -203,10 +211,13 @@ impl TransformVisitor<'tcx> { let self_place = Place::from(self_arg()); let base = self_place.downcast_unnamed(variant_index); let field = Projection { - base: base, + base: base.projection, elem: ProjectionElem::Field(Field::new(idx), ty), }; - Place::Projection(Box::new(field)) + Place { + base: base.base, + projection: Some(Box::new(field)), + } } // Create a statement which changes the discriminant @@ -245,7 +256,7 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { place: &mut Place<'tcx>, context: PlaceContext, location: Location) { - if let Some(l) = place.base_local() { + if let PlaceBase::Local(l) = place.base { // Replace an Local in the remap with a generator struct access if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { replace_base(place, self.make_field(variant_index, idx, ty)); @@ -835,7 +846,10 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut &Terminator { source_info, kind: TerminatorKind::Drop { - location: Place::Base(PlaceBase::Local(local)), + location: Place { + base: PlaceBase::Local(local), + projection: None, + }, target, unwind } @@ -1002,7 +1016,7 @@ fn create_generator_resume_function<'tcx>( let mut cases = create_cases(body, &transform, |point| Some(point.resume)); - use rustc::mir::interpret::InterpError::{ + use rustc::mir::interpret::PanicInfo::{ GeneratorResumedAfterPanic, GeneratorResumedAfterReturn, }; @@ -1028,14 +1042,14 @@ fn create_generator_resume_function<'tcx>( dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(()) ); } -fn source_info<'tcx>(body: &Body<'tcx>) -> SourceInfo { +fn source_info(body: &Body<'_>) -> SourceInfo { SourceInfo { span: body.span, scope: OUTERMOST_SOURCE_SCOPE, } } -fn insert_clean_drop<'tcx>(body: &mut Body<'tcx>) -> BasicBlock { +fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { let return_block = insert_term_block(body, TerminatorKind::Return); // Create a block to destroy an unresumed generators. This can only destroy upvars. diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index dc73e58d15..40cb1fbdc5 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -159,7 +159,7 @@ impl Inliner<'tcx> { // Simplify if we inlined anything. if changed { - debug!("Running simplify cfg on {:?}", self.source); + debug!("running simplify cfg on {:?}", self.source); CfgSimplifier::new(caller_body).simplify(); remove_dead_blocks(caller_body); } @@ -232,13 +232,6 @@ impl Inliner<'tcx> { return false; } - // Do not inline {u,i}128 lang items, codegen const eval depends - // on detecting calls to these lang items and intercepting them - if tcx.is_binop_lang_item(callsite.callee).is_some() { - debug!(" not inlining 128bit integer lang item"); - return false; - } - let codegen_fn_attrs = tcx.codegen_fn_attrs(callsite.callee); let hinted = match codegen_fn_attrs.inline { @@ -247,7 +240,7 @@ impl Inliner<'tcx> { // need to check for first. attr::InlineAttr::Always => true, attr::InlineAttr::Never => { - debug!("#[inline(never)] present - not inlining"); + debug!("`#[inline(never)]` present - not inlining"); return false } attr::InlineAttr::Hint => true, @@ -397,7 +390,7 @@ impl Inliner<'tcx> { match terminator.kind { // FIXME: Handle inlining of diverging calls TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => { - debug!("Inlined {:?} into {:?}", callsite.callee, self.source); + debug!("inlined {:?} into {:?}", callsite.callee, self.source); let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len()); let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len()); @@ -456,7 +449,7 @@ impl Inliner<'tcx> { } let dest = if dest_needs_borrow(&destination.0) { - debug!("Creating temp for return destination"); + debug!("creating temp for return destination"); let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, @@ -603,14 +596,17 @@ impl Inliner<'tcx> { // FIXME: Analysis of the usage of the arguments to avoid // unnecessary temporaries. - if let Operand::Move(Place::Base(PlaceBase::Local(local))) = arg { + if let Operand::Move(Place { + base: PlaceBase::Local(local), + projection: None, + }) = arg { if caller_body.local_kind(local) == LocalKind::Temp { // Reuse the operand if it's a temporary already return local; } } - debug!("Creating temp for argument {:?}", arg); + debug!("creating temp for argument {:?}", arg); // Otherwise, create a temporary for the arg let arg = Rvalue::Use(arg); @@ -659,7 +655,7 @@ struct Integrator<'a, 'tcx> { impl<'a, 'tcx> Integrator<'a, 'tcx> { fn update_target(&self, tgt: BasicBlock) -> BasicBlock { let new = BasicBlock::new(tgt.index() + self.block_idx); - debug!("Updating target `{:?}`, new: `{:?}`", tgt, new); + debug!("updating target `{:?}`, new: `{:?}`", tgt, new); new } } @@ -671,7 +667,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { _location: Location) { if *local == RETURN_PLACE { match self.destination { - Place::Base(PlaceBase::Local(l)) => { + Place { + base: PlaceBase::Local(l), + projection: None, + } => { *local = l; return; }, @@ -692,13 +691,20 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { _location: Location) { match place { - Place::Base(PlaceBase::Local(RETURN_PLACE)) => { + Place { + base: PlaceBase::Local(RETURN_PLACE), + projection: None, + } => { // Return pointer; update the place itself *place = self.destination.clone(); }, - Place::Base( - PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. }) - ) => { + Place { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(promoted), + .. + }), + projection: None, + } => { if let Some(p) = self.promoted_map.get(*promoted).cloned() { *promoted = p; } diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index c338e1ebe9..5542926503 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -39,19 +39,23 @@ pub struct InstCombineVisitor<'tcx> { impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { if self.optimizations.and_stars.remove(&location) { - debug!("Replacing `&*`: {:?}", rvalue); + debug!("replacing `&*`: {:?}", rvalue); let new_place = match *rvalue { - Rvalue::Ref(_, _, Place::Projection(ref mut projection)) => { + Rvalue::Ref(_, _, Place { + ref mut base, + projection: Some(ref mut projection), + }) => Place { // Replace with dummy - mem::replace(&mut projection.base, Place::Base(PlaceBase::Local(Local::new(0)))) - } + base: mem::replace(base, PlaceBase::Local(Local::new(0))), + projection: projection.base.take(), + }, _ => bug!("Detected `&*` but didn't find `&*`!"), }; *rvalue = Rvalue::Use(Operand::Copy(new_place)) } if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) { - debug!("Replacing `Len([_; N])`: {:?}", rvalue); + debug!("replacing `Len([_; N])`: {:?}", rvalue); *rvalue = Rvalue::Use(Operand::Constant(box constant)); } @@ -78,9 +82,12 @@ impl OptimizationFinder<'b, 'tcx> { impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - if let Rvalue::Ref(_, _, Place::Projection(ref projection)) = *rvalue { + if let Rvalue::Ref(_, _, Place { + ref base, + projection: Some(ref projection), + }) = *rvalue { if let ProjectionElem::Deref = projection.elem { - if projection.base.ty(self.body, self.tcx).ty.is_region_ptr() { + if Place::ty_from(&base, &projection.base, self.body, self.tcx).ty.is_region_ptr() { self.optimizations.and_stars.insert(location); } } diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs deleted file mode 100644 index f09a77d486..0000000000 --- a/src/librustc_mir/transform/lower_128bit.rs +++ /dev/null @@ -1,230 +0,0 @@ -//! Replaces 128-bit operators with lang item calls - -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::LangItem; -use rustc::mir::*; -use rustc::ty::{self, List, Ty, TyCtxt}; -use rustc_data_structures::indexed_vec::{Idx}; -use crate::transform::{MirPass, MirSource}; - -pub struct Lower128Bit; - -impl MirPass for Lower128Bit { - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops; - let target_default = tcx.sess.host.options.i128_lowering; - if !debugging_override.unwrap_or(target_default) { - return - } - - self.lower_128bit_ops(tcx, body); -} -} - -impl Lower128Bit { - fn lower_128bit_ops<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); - - let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); - for block in basic_blocks.iter_mut() { - for i in (0..block.statements.len()).rev() { - let (lang_item, rhs_kind) = - if let Some((lang_item, rhs_kind)) = - lower_to(&block.statements[i], local_decls, tcx) - { - (lang_item, rhs_kind) - } else { - continue; - }; - - let rhs_override_ty = rhs_kind.ty(tcx); - let cast_local = - match rhs_override_ty { - None => None, - Some(ty) => { - let local_decl = LocalDecl::new_internal( - ty, block.statements[i].source_info.span); - Some(local_decls.push(local_decl)) - }, - }; - - let storage_dead = cast_local.map(|local| { - Statement { - source_info: block.statements[i].source_info, - kind: StatementKind::StorageDead(local), - } - }); - let after_call = BasicBlockData { - statements: storage_dead.into_iter() - .chain(block.statements.drain((i+1)..)).collect(), - is_cleanup: block.is_cleanup, - terminator: block.terminator.take(), - }; - - let bin_statement = block.statements.pop().unwrap(); - let source_info = bin_statement.source_info; - let (place, lhs, mut rhs) = match bin_statement.kind { - StatementKind::Assign(place, box rvalue) => { - match rvalue { - Rvalue::BinaryOp(_, lhs, rhs) - | Rvalue::CheckedBinaryOp(_, lhs, rhs) => (place, lhs, rhs), - _ => bug!(), - } - } - _ => bug!() - }; - - if let Some(local) = cast_local { - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::StorageLive(local), - }); - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::Assign( - Place::from(local), - box Rvalue::Cast( - CastKind::Misc, - rhs, - rhs_override_ty.unwrap())), - }); - rhs = Operand::Move(Place::from(local)); - } - - let call_did = check_lang_item_type( - lang_item, &place, &lhs, &rhs, local_decls, tcx); - - let bb = BasicBlock::new(cur_len + new_blocks.len()); - new_blocks.push(after_call); - - block.terminator = - Some(Terminator { - source_info, - kind: TerminatorKind::Call { - func: Operand::function_handle(tcx, call_did, - List::empty(), source_info.span), - args: vec![lhs, rhs], - destination: Some((place, bb)), - cleanup: None, - from_hir_call: false, - }, - }); - } - } - - basic_blocks.extend(new_blocks); - } -} - -fn check_lang_item_type<'tcx, D>( - lang_item: LangItem, - place: &Place<'tcx>, - lhs: &Operand<'tcx>, - rhs: &Operand<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> DefId -where - D: HasLocalDecls<'tcx>, -{ - let did = tcx.require_lang_item(lang_item); - let poly_sig = tcx.fn_sig(did); - let sig = poly_sig.no_bound_vars().unwrap(); - let lhs_ty = lhs.ty(local_decls, tcx); - let rhs_ty = rhs.ty(local_decls, tcx); - let place_ty = place.ty(local_decls, tcx).ty; - let expected = [lhs_ty, rhs_ty, place_ty]; - assert_eq!(sig.inputs_and_output[..], expected, - "lang item `{}`", tcx.def_path_str(did)); - did -} - -fn lower_to<'tcx, D>( - statement: &Statement<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> Option<(LangItem, RhsKind)> -where - D: HasLocalDecls<'tcx>, -{ - match statement.kind { - StatementKind::Assign(_, box Rvalue::BinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_op(bin_op, is_signed); - } - }, - StatementKind::Assign(_, box Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_checked_op(bin_op, is_signed); - } - }, - _ => {}, - } - None -} - -#[derive(Copy, Clone)] -enum RhsKind { - Unchanged, - ForceU128, - ForceU32, -} - -impl RhsKind { - fn ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option> { - match *self { - RhsKind::Unchanged => None, - RhsKind::ForceU128 => Some(tcx.types.u128), - RhsKind::ForceU32 => Some(tcx.types.u32), - } - } -} - -fn sign_of_128bit(ty: Ty<'_>) -> Option { - match ty.sty { - ty::Int(syntax::ast::IntTy::I128) => Some(true), - ty::Uint(syntax::ast::UintTy::U128) => Some(false), - _ => None, - } -} - -fn item_for_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Div, true) => (LangItem::I128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Div, false) => (LangItem::U128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, true) => (LangItem::I128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, false) => (LangItem::U128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shl, false) => (LangItem::U128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, true) => (LangItem::I128ShrFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, false) => (LangItem::U128ShrFnLangItem, RhsKind::ForceU32), - _ => return None, - }; - Some(i) -} - -fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shl, false) => (LangItem::U128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, true) => (LangItem::I128ShroFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, false) => (LangItem::U128ShroFnLangItem, RhsKind::ForceU128), - _ => bug!("That should be all the checked ones?"), - }; - Some(i) -} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 81d91dcd0a..61d0b1f348 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,4 +1,5 @@ use crate::{build, shim}; +use rustc_data_structures::indexed_vec::IndexVec; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::mir::{Body, MirPhase, Promoted}; use rustc::ty::{TyCtxt, InstanceDef}; @@ -33,7 +34,6 @@ pub mod copy_prop; pub mod const_prop; pub mod generator; pub mod inline; -pub mod lower_128bit; pub mod uniform_array_move_out; pub(crate) fn provide(providers: &mut Providers<'_>) { @@ -46,17 +46,18 @@ pub(crate) fn provide(providers: &mut Providers<'_>) { mir_validated, optimized_mir, is_mir_available, + promoted_mir, ..*providers }; } -fn is_mir_available<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_mir_available(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.mir_keys(def_id.krate).contains(&def_id) } /// Finds the full set of `DefId`s within the current crate that have /// MIR associated with them. -fn mir_keys<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx DefIdSet { +fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet { assert_eq!(krate, LOCAL_CRATE); let mut set = DefIdSet::default(); @@ -78,7 +79,7 @@ fn mir_keys<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx DefIdSet { _: hir::HirId, _: Span) { if let hir::VariantData::Tuple(_, hir_id) = *v { - self.set.insert(self.tcx.hir().local_def_id_from_hir_id(hir_id)); + self.set.insert(self.tcx.hir().local_def_id(hir_id)); } intravisit::walk_struct_def(self, v) } @@ -94,7 +95,7 @@ fn mir_keys<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx DefIdSet { tcx.arena.alloc(set) } -fn mir_built<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal> { +fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { let mir = build::mir_build(tcx, def_id); tcx.alloc_steal_mir(mir) } @@ -125,7 +126,7 @@ impl<'tcx> MirSource<'tcx> { /// Generates a default name for the pass based on the name of the /// type `T`. pub fn default_name() -> Cow<'static, str> { - let name = unsafe { ::std::intrinsics::type_name::() }; + let name = ::std::any::type_name::(); if let Some(tail) = name.rfind(":") { Cow::from(&name[tail+1..]) } else { @@ -137,7 +138,7 @@ pub fn default_name() -> Cow<'static, str> { /// pass will be named after the type, and it will consist of a main /// loop that goes over each available MIR and applies `run_pass`. pub trait MirPass { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { default_name::() } @@ -192,7 +193,7 @@ pub fn run_passes( } } -fn mir_const<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal> { +fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { // Unsafety check uses the raw mir, so make sure it is run let _ = tcx.unsafety_check_result(def_id); @@ -223,7 +224,7 @@ fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal> { tcx.alloc_steal_mir(body) } -fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Body<'tcx> { +fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { if tcx.is_constructor(def_id) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const @@ -270,8 +271,6 @@ fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Body<'tcx> { // From here on out, regions are gone. &erase_regions::EraseRegions, - &lower_128bit::Lower128Bit, - // Optimizations begin. &uniform_array_move_out::RestoreSubsliceArrayMoveOut, @@ -296,3 +295,8 @@ fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Body<'tcx> { ]); tcx.arena.alloc(body) } + +fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec> { + let body = tcx.optimized_mir(def_id); + &body.promoted +} diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index b1804fb0ab..3090b63a7e 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -60,6 +60,9 @@ pub enum Candidate { /// Borrow of a constant temporary. Ref(Location), + /// Promotion of the `x` in `[x; 32]`. + Repeat(Location), + /// Currently applied to function calls where the callee has the unstable /// `#[rustc_args_required_const]` attribute as well as the SIMD shuffle /// intrinsic. The intrinsic requires the arguments are indeed constant and @@ -297,9 +300,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let mut promoted_place = |ty, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); - Place::Base( - PlaceBase::Static(box Static{ kind: StaticKind::Promoted(promoted_id), ty }) - ) + Place { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(promoted_id), + ty + }), + projection: None, + } }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { @@ -307,21 +314,29 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let ref mut statement = blocks[loc.block].statements[loc.statement_index]; match statement.kind { StatementKind::Assign(_, box Rvalue::Ref(_, _, ref mut place)) => { - // Find the underlying local for this (necessarily interior) borrow. - let mut place = place; - while let Place::Projection(ref mut proj) = *place { - assert_ne!(proj.elem, ProjectionElem::Deref); - place = &mut proj.base; - }; - - let ty = place.ty(local_decls, self.tcx).ty; + // Use the underlying local for this (necessarily interior) borrow. + let ty = place.base.ty(local_decls).ty; let span = statement.source_info.span; - Operand::Move(mem::replace(place, promoted_place(ty, span))) + Operand::Move(Place { + base: mem::replace(&mut place.base, promoted_place(ty, span).base), + projection: None, + }) } _ => bug!() } } + Candidate::Repeat(loc) => { + let ref mut statement = blocks[loc.block].statements[loc.statement_index]; + match statement.kind { + StatementKind::Assign(_, box Rvalue::Repeat(ref mut operand, _)) => { + let ty = operand.ty(local_decls, self.tcx); + let span = statement.source_info.span; + mem::replace(operand, Operand::Copy(promoted_place(ty, span))) + } + _ => bug!() + } + }, Candidate::Argument { bb, index } => { let terminator = blocks[bb].terminator_mut(); match terminator.kind { @@ -380,9 +395,13 @@ pub fn promote_candidates<'tcx>( for candidate in candidates.into_iter().rev() { match candidate { + Candidate::Repeat(Location { block, statement_index }) | Candidate::Ref(Location { block, statement_index }) => { match body[block].statements[statement_index].kind { - StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _) => { + StatementKind::Assign(Place { + base: PlaceBase::Local(local), + projection: None, + }, _) => { if temps[local] == TempState::PromotedOut { // Already promoted. continue; @@ -429,7 +448,10 @@ pub fn promote_candidates<'tcx>( for block in body.basic_blocks_mut() { block.statements.retain(|statement| { match statement.kind { - StatementKind::Assign(Place::Base(PlaceBase::Local(index)), _) | + StatementKind::Assign(Place { + base: PlaceBase::Local(index), + projection: None, + }, _) | StatementKind::StorageLive(index) | StatementKind::StorageDead(index) => { !promoted(index) @@ -439,7 +461,10 @@ pub fn promote_candidates<'tcx>( }); let terminator = block.terminator_mut(); match terminator.kind { - TerminatorKind::Drop { location: Place::Base(PlaceBase::Local(index)), target, .. } => { + TerminatorKind::Drop { location: Place { + base: PlaceBase::Local(index), + projection: None, + }, target, .. } => { if promoted(index) { terminator.kind = TerminatorKind::Goto { target, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index f082b5e5a0..dcfc80968f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -142,6 +142,7 @@ impl<'a, 'tcx> ConstCx<'a, 'tcx> { #[derive(Copy, Clone, Debug)] enum ValueSource<'a, 'tcx> { Rvalue(&'a Rvalue<'tcx>), + DropAndReplace(&'a Operand<'tcx>), Call { callee: &'a Operand<'tcx>, args: &'a [Operand<'tcx>], @@ -181,12 +182,17 @@ trait Qualif { fn in_projection_structurally( cx: &ConstCx<'_, 'tcx>, - proj: &Projection<'tcx>, + place: PlaceRef<'_, 'tcx>, ) -> bool { - let base_qualif = Self::in_place(cx, &proj.base); + let proj = place.projection.as_ref().unwrap(); + + let base_qualif = Self::in_place(cx, PlaceRef { + base: place.base, + projection: &proj.base, + }); let qualif = base_qualif && Self::mask_for_ty( cx, - proj.base.ty(cx.body, cx.tcx) + Place::ty_from(place.base, &proj.base, cx.body, cx.tcx) .projection_ty(cx.tcx, &proj.elem) .ty, ); @@ -201,26 +207,43 @@ trait Qualif { } } - fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool { - Self::in_projection_structurally(cx, proj) + fn in_projection( + cx: &ConstCx<'_, 'tcx>, + place: PlaceRef<'_, 'tcx>, + ) -> bool { + Self::in_projection_structurally(cx, place) } - fn in_place(cx: &ConstCx<'_, 'tcx>, place: &Place<'tcx>) -> bool { - match *place { - Place::Base(PlaceBase::Local(local)) => Self::in_local(cx, local), - Place::Base(PlaceBase::Static(box Static {kind: StaticKind::Promoted(_), .. })) => - bug!("qualifying already promoted MIR"), - Place::Base(PlaceBase::Static(ref static_)) => { + fn in_place(cx: &ConstCx<'_, 'tcx>, place: PlaceRef<'_, 'tcx>) -> bool { + match place { + PlaceRef { + base: PlaceBase::Local(local), + projection: None, + } => Self::in_local(cx, *local), + PlaceRef { + base: PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }), + projection: None, + } => bug!("qualifying already promoted MIR"), + PlaceRef { + base: PlaceBase::Static(static_), + projection: None, + } => { Self::in_static(cx, static_) }, - Place::Projection(ref proj) => Self::in_projection(cx, proj), + PlaceRef { + base: _, + projection: Some(_), + } => Self::in_projection(cx, place), } } fn in_operand(cx: &ConstCx<'_, 'tcx>, operand: &Operand<'tcx>) -> bool { match *operand { Operand::Copy(ref place) | - Operand::Move(ref place) => Self::in_place(cx, place), + Operand::Move(ref place) => Self::in_place(cx, place.as_ref()), Operand::Constant(ref constant) => { if let ConstValue::Unevaluated(def_id, _) = constant.literal.val { @@ -249,7 +272,7 @@ trait Qualif { Rvalue::NullaryOp(..) => false, Rvalue::Discriminant(ref place) | - Rvalue::Len(ref place) => Self::in_place(cx, place), + Rvalue::Len(ref place) => Self::in_place(cx, place.as_ref()), Rvalue::Use(ref operand) | Rvalue::Repeat(ref operand, _) | @@ -263,16 +286,19 @@ trait Qualif { Rvalue::Ref(_, _, ref place) => { // Special-case reborrows to be more like a copy of the reference. - if let Place::Projection(ref proj) = *place { + if let Some(ref proj) = place.projection { if let ProjectionElem::Deref = proj.elem { - let base_ty = proj.base.ty(cx.body, cx.tcx).ty; + let base_ty = Place::ty_from(&place.base, &proj.base, cx.body, cx.tcx).ty; if let ty::Ref(..) = base_ty.sty { - return Self::in_place(cx, &proj.base); + return Self::in_place(cx, PlaceRef { + base: &place.base, + projection: &proj.base, + }); } } } - Self::in_place(cx, place) + Self::in_place(cx, place.as_ref()) } Rvalue::Aggregate(_, ref operands) => { @@ -298,6 +324,7 @@ trait Qualif { fn in_value(cx: &ConstCx<'_, 'tcx>, source: ValueSource<'_, 'tcx>) -> bool { match source { ValueSource::Rvalue(rvalue) => Self::in_rvalue(cx, rvalue), + ValueSource::DropAndReplace(source) => Self::in_operand(cx, source), ValueSource::Call { callee, args, return_ty } => { Self::in_call(cx, callee, args, return_ty) } @@ -340,7 +367,7 @@ impl Qualif for HasMutInterior { } else if let ty::Array(_, len) = ty.sty { // FIXME(eddyb) the `cx.mode == Mode::NonConstFn` condition // seems unnecessary, given that this is merely a ZST. - match len.assert_usize(cx.tcx) { + match len.try_eval_usize(cx.tcx, cx.param_env) { Some(0) if cx.mode == Mode::NonConstFn => {}, _ => return true, } @@ -419,7 +446,12 @@ impl Qualif for IsNotPromotable { } } - fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool { + fn in_projection( + cx: &ConstCx<'_, 'tcx>, + place: PlaceRef<'_, 'tcx>, + ) -> bool { + let proj = place.projection.as_ref().unwrap(); + match proj.elem { ProjectionElem::Deref | ProjectionElem::Downcast(..) => return true, @@ -430,7 +462,7 @@ impl Qualif for IsNotPromotable { ProjectionElem::Field(..) => { if cx.mode == Mode::NonConstFn { - let base_ty = proj.base.ty(cx.body, cx.tcx).ty; + let base_ty = Place::ty_from(place.base, &proj.base, cx.body, cx.tcx).ty; if let Some(def) = base_ty.ty_adt_def() { // No promotion of union field accesses. if def.is_union() { @@ -441,7 +473,7 @@ impl Qualif for IsNotPromotable { } } - Self::in_projection_structurally(cx, proj) + Self::in_projection_structurally(cx, place) } fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool { @@ -726,114 +758,128 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { let mut qualifs = self.qualifs_in_value(source); - if let ValueSource::Rvalue(&Rvalue::Ref(_, kind, ref place)) = source { - // Getting `true` from `HasMutInterior::in_rvalue` means - // the borrowed place is disallowed from being borrowed, - // due to either a mutable borrow (with some exceptions), - // or an shared borrow of a value with interior mutability. - // Then `HasMutInterior` is replaced with `IsNotPromotable`, - // to avoid duplicate errors (e.g. from reborrowing). - if qualifs[HasMutInterior] { - qualifs[HasMutInterior] = false; - qualifs[IsNotPromotable] = true; + match source { + ValueSource::Rvalue(&Rvalue::Ref(_, kind, ref place)) => { + // Getting `true` from `HasMutInterior::in_rvalue` means + // the borrowed place is disallowed from being borrowed, + // due to either a mutable borrow (with some exceptions), + // or an shared borrow of a value with interior mutability. + // Then `HasMutInterior` is replaced with `IsNotPromotable`, + // to avoid duplicate errors (e.g. from reborrowing). + if qualifs[HasMutInterior] { + qualifs[HasMutInterior] = false; + qualifs[IsNotPromotable] = true; - if self.mode.requires_const_checking() { - if !self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { - if let BorrowKind::Mut { .. } = kind { - let mut err = struct_span_err!(self.tcx.sess, self.span, E0017, - "references in {}s may only refer \ - to immutable values", self.mode); - err.span_label(self.span, format!("{}s require immutable values", - self.mode)); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("References in statics and constants may only refer to \ - immutable values.\n\n\ - Statics are shared everywhere, and if they refer to \ - mutable data one might violate memory safety since \ - holding multiple mutable references to shared data is \ - not allowed.\n\n\ - If you really want global mutable state, try using \ - static mut or a global UnsafeCell."); + if self.mode.requires_const_checking() { + if !self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { + if let BorrowKind::Mut { .. } = kind { + let mut err = struct_span_err!(self.tcx.sess, self.span, E0017, + "references in {}s may only refer \ + to immutable values", self.mode); + err.span_label(self.span, format!("{}s require immutable values", + self.mode)); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note("References in statics and constants may only refer \ + to immutable values.\n\n\ + Statics are shared everywhere, and if they refer to \ + mutable data one might violate memory safety since \ + holding multiple mutable references to shared data \ + is not allowed.\n\n\ + If you really want global mutable state, try using \ + static mut or a global UnsafeCell."); + } + err.emit(); + } else { + span_err!(self.tcx.sess, self.span, E0492, + "cannot borrow a constant which may contain \ + interior mutability, create a static instead"); } - err.emit(); - } else { - span_err!(self.tcx.sess, self.span, E0492, - "cannot borrow a constant which may contain \ - interior mutability, create a static instead"); } } - } - } else if let BorrowKind::Mut { .. } | BorrowKind::Shared = kind { - // Don't promote BorrowKind::Shallow borrows, as they don't - // reach codegen. - - // We might have a candidate for promotion. - let candidate = Candidate::Ref(location); - // Start by traversing to the "base", with non-deref projections removed. - let mut place = place; - while let Place::Projection(ref proj) = *place { - if proj.elem == ProjectionElem::Deref { - break; + } else if let BorrowKind::Mut { .. } | BorrowKind::Shared = kind { + // Don't promote BorrowKind::Shallow borrows, as they don't + // reach codegen. + + // We might have a candidate for promotion. + let candidate = Candidate::Ref(location); + // Start by traversing to the "base", with non-deref projections removed. + let mut place_projection = &place.projection; + while let Some(proj) = place_projection { + if proj.elem == ProjectionElem::Deref { + break; + } + place_projection = &proj.base; } - place = &proj.base; - } - debug!("qualify_consts: promotion candidate: place={:?}", place); - // We can only promote interior borrows of promotable temps (non-temps - // don't get promoted anyway). - // (If we bailed out of the loop due to a `Deref` above, we will definitely - // not enter the conditional here.) - if let Place::Base(PlaceBase::Local(local)) = *place { - if self.body.local_kind(local) == LocalKind::Temp { - debug!("qualify_consts: promotion candidate: local={:?}", local); - // The borrowed place doesn't have `HasMutInterior` - // (from `in_rvalue`), so we can safely ignore - // `HasMutInterior` from the local's qualifications. - // This allows borrowing fields which don't have - // `HasMutInterior`, from a type that does, e.g.: - // `let _: &'static _ = &(Cell::new(1), 2).1;` - let mut local_qualifs = self.qualifs_in_local(local); - // Any qualifications, except HasMutInterior (see above), disqualify - // from promotion. - // This is, in particular, the "implicit promotion" version of - // the check making sure that we don't run drop glue during const-eval. - local_qualifs[HasMutInterior] = false; - if !local_qualifs.0.iter().any(|&qualif| qualif) { - debug!("qualify_consts: promotion candidate: {:?}", candidate); - self.promotion_candidates.push(candidate); + + debug!( + "qualify_consts: promotion candidate: place={:?} {:?}", + place.base, place_projection + ); + // We can only promote interior borrows of promotable temps (non-temps + // don't get promoted anyway). + // (If we bailed out of the loop due to a `Deref` above, we will definitely + // not enter the conditional here.) + if let (PlaceBase::Local(local), None) = (&place.base, place_projection) { + if self.body.local_kind(*local) == LocalKind::Temp { + debug!("qualify_consts: promotion candidate: local={:?}", local); + // The borrowed place doesn't have `HasMutInterior` + // (from `in_rvalue`), so we can safely ignore + // `HasMutInterior` from the local's qualifications. + // This allows borrowing fields which don't have + // `HasMutInterior`, from a type that does, e.g.: + // `let _: &'static _ = &(Cell::new(1), 2).1;` + let mut local_qualifs = self.qualifs_in_local(*local); + // Any qualifications, except HasMutInterior (see above), disqualify + // from promotion. + // This is, in particular, the "implicit promotion" version of + // the check making sure that we don't run drop glue during const-eval. + local_qualifs[HasMutInterior] = false; + if !local_qualifs.0.iter().any(|&qualif| qualif) { + debug!("qualify_consts: promotion candidate: {:?}", candidate); + self.promotion_candidates.push(candidate); + } } } } - } + }, + ValueSource::Rvalue(&Rvalue::Repeat(ref operand, _)) => { + let candidate = Candidate::Repeat(location); + let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) || + IsNotPromotable::in_operand(self, operand); + debug!("assign: self.def_id={:?} operand={:?}", self.def_id, operand); + if !not_promotable && self.tcx.features().const_in_array_repeat_expressions { + debug!("assign: candidate={:?}", candidate); + self.promotion_candidates.push(candidate); + } + }, + _ => {}, } - let mut dest = dest; + let mut dest_projection = &dest.projection; let index = loop { - match dest { + match (&dest.base, dest_projection) { // We treat all locals equal in constants - Place::Base(PlaceBase::Local(index)) => break *index, + (&PlaceBase::Local(index), None) => break index, // projections are transparent for assignments // we qualify the entire destination at once, even if just a field would have // stricter qualification - Place::Projection(proj) => { + (base, Some(proj)) => { // Catch more errors in the destination. `visit_place` also checks various // projection rules like union field access and raw pointer deref - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - dest = &proj.base; + let context = PlaceContext::MutatingUse(MutatingUseContext::Store); + self.visit_place_base(base, context, location); + self.visit_projection(base, proj, context, location); + dest_projection = &proj.base; }, - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => - bug!("promoteds don't exist yet during promotion"), - Place::Base(PlaceBase::Static(box Static{ kind: _, .. })) => { + (&PlaceBase::Static(box Static { + kind: StaticKind::Promoted(_), + .. + }), None) => bug!("promoteds don't exist yet during promotion"), + (&PlaceBase::Static(box Static{ kind: _, .. }), None) => { // Catch more errors in the destination. `visit_place` also checks that we // do not try to access statics from constants or try to mutate statics - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); + let context = PlaceContext::MutatingUse(MutatingUseContext::Store); + self.visit_place_base(&dest.base, context, location); return; } } @@ -888,7 +934,9 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { let target = match body[bb].terminator().kind { TerminatorKind::Goto { target } | + TerminatorKind::FalseUnwind { real_target: target, .. } | TerminatorKind::Drop { target, .. } | + TerminatorKind::DropAndReplace { target, .. } | TerminatorKind::Assert { target, .. } | TerminatorKind::Call { destination: Some((_, target)), .. } => { Some(target) @@ -900,14 +948,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } TerminatorKind::SwitchInt {..} | - TerminatorKind::DropAndReplace { .. } | TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } | TerminatorKind::Unreachable | - TerminatorKind::FalseEdges { .. } | - TerminatorKind::FalseUnwind { .. } => None, + TerminatorKind::FalseEdges { .. } => None, TerminatorKind::Return => { break; @@ -933,15 +979,26 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { debug!("qualify_const: promotion_candidates={:?}", self.promotion_candidates); for candidate in &self.promotion_candidates { match *candidate { + Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => { + if let StatementKind::Assign(_, box Rvalue::Repeat( + Operand::Move(Place { + base: PlaceBase::Local(index), + projection: None, + }), + _ + )) = self.body[bb].statements[stmt_idx].kind { + promoted_temps.insert(index); + } + } Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => { - match self.body[bb].statements[stmt_idx].kind { - StatementKind::Assign( - _, - box Rvalue::Ref(_, _, Place::Base(PlaceBase::Local(index))) - ) => { - promoted_temps.insert(index); - } - _ => {} + if let StatementKind::Assign( + _, + box Rvalue::Ref(_, _, Place { + base: PlaceBase::Local(index), + projection: None, + }) + ) = self.body[bb].statements[stmt_idx].kind { + promoted_temps.insert(index); } } Candidate::Argument { .. } => {} @@ -1023,6 +1080,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { fn visit_projection( &mut self, + place_base: &PlaceBase<'tcx>, proj: &Projection<'tcx>, context: PlaceContext, location: Location, @@ -1031,14 +1089,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { "visit_place_projection: proj={:?} context={:?} location={:?}", proj, context, location, ); - self.super_projection(proj, context, location); + self.super_projection(place_base, proj, context, location); match proj.elem { ProjectionElem::Deref => { if context.is_mutating_use() { // `not_const` errors out in const contexts self.not_const() } - let base_ty = proj.base.ty(self.body, self.tcx).ty; + let base_ty = Place::ty_from(place_base, &proj.base, self.body, self.tcx).ty; match self.mode { Mode::NonConstFn => {}, _ => { @@ -1062,7 +1120,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { ProjectionElem::Subslice {..} | ProjectionElem::Field(..) | ProjectionElem::Index(_) => { - let base_ty = proj.base.ty(self.body, self.tcx).ty; + let base_ty = Place::ty_from(place_base, &proj.base, self.body, self.tcx).ty; if let Some(def) = base_ty.ty_adt_def() { if def.is_union() { match self.mode { @@ -1099,7 +1157,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { match *operand { Operand::Move(ref place) => { // Mark the consumed locals to indicate later drops are noops. - if let Place::Base(PlaceBase::Local(local)) = *place { + if let Place { + base: PlaceBase::Local(local), + projection: None, + } = *place { self.cx.per_local[NeedsDrop].remove(local); } } @@ -1115,16 +1176,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if let Rvalue::Ref(_, kind, ref place) = *rvalue { // Special-case reborrows. let mut reborrow_place = None; - if let Place::Projection(ref proj) = *place { + if let Some(ref proj) = place.projection { if let ProjectionElem::Deref = proj.elem { - let base_ty = proj.base.ty(self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.base, &proj.base, self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.sty { reborrow_place = Some(&proj.base); } } } - if let Some(place) = reborrow_place { + if let Some(proj) = reborrow_place { let ctx = match kind { BorrowKind::Shared => PlaceContext::NonMutatingUse( NonMutatingUseContext::SharedBorrow, @@ -1139,7 +1200,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { MutatingUseContext::Borrow, ), }; - self.visit_place(place, ctx, location); + self.visit_place_base(&place.base, ctx, location); + if let Some(proj) = proj { + self.visit_projection(&place.base, proj, ctx, location); + } } else { self.super_rvalue(rvalue, location); } @@ -1393,15 +1457,25 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { for arg in args { self.visit_operand(arg, location); } - } else if let TerminatorKind::Drop { location: ref place, .. } = *kind { - self.super_terminator_kind(kind, location); + } else if let TerminatorKind::Drop { + location: ref place, .. + } | TerminatorKind::DropAndReplace { + location: ref place, .. + } = *kind { + match *kind { + TerminatorKind::DropAndReplace { .. } => {} + _ => self.super_terminator_kind(kind, location), + } // Deny *any* live drops anywhere other than functions. if self.mode.requires_const_checking() { unleash_miri!(self); // HACK(eddyb): emulate a bit of dataflow analysis, // conservatively, that drop elaboration will do. - let needs_drop = if let Place::Base(PlaceBase::Local(local)) = *place { + let needs_drop = if let Place { + base: PlaceBase::Local(local), + projection: None, + } = *place { if NeedsDrop::in_local(self, local) { Some(self.body.local_decls[local].source_info.span) } else { @@ -1423,6 +1497,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { } } } + + match *kind { + TerminatorKind::DropAndReplace { ref value, .. } => { + self.assign(place, ValueSource::DropAndReplace(value), location); + self.visit_operand(value, location); + } + _ => {} + } } else { // Qualify any operands inside other terminators. self.super_terminator_kind(kind, location); @@ -1473,7 +1555,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn mir_const_qualif<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> (u8, &'tcx BitSet) { +fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet) { // N.B., this `borrow()` is guaranteed to be valid (i.e., the value // cannot yet be stolen), because `mir_validated()`, which steals // from `mir_const(), forces this query to execute before @@ -1545,7 +1627,7 @@ impl MirPass for QualifyAndPromoteConstants { diag.note("for more information, see issue \ https://github.com/rust-lang/rust/issues/57563"); diag.help( - "add #![feature(const_fn)] to the crate attributes to enable", + "add `#![feature(const_fn)]` to the crate attributes to enable", ); diag.emit(); } else { @@ -1623,7 +1705,10 @@ impl MirPass for QualifyAndPromoteConstants { let terminator = block.terminator_mut(); match terminator.kind { TerminatorKind::Drop { - location: Place::Base(PlaceBase::Local(index)), + location: Place { + base: PlaceBase::Local(index), + projection: None, + }, target, .. } => { diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 7b3cdc835e..adba9097d1 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -41,7 +41,10 @@ impl RemoveNoopLandingPads { // These are all nops in a landing pad } - StatementKind::Assign(Place::Base(PlaceBase::Local(_)), box Rvalue::Use(_)) => { + StatementKind::Assign(Place { + base: PlaceBase::Local(_), + projection: None, + }, box Rvalue::Use(_)) => { // Writing to a local (e.g., a drop flag) does not // turn a landing pad to a non-nop } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index f12309c1d0..7fe8480c81 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -118,8 +118,14 @@ fn each_block<'tcx, O>( }; assert!(args.len() == 1); let peek_arg_place = match args[0] { - mir::Operand::Copy(ref place @ mir::Place::Base(mir::PlaceBase::Local(_))) | - mir::Operand::Move(ref place @ mir::Place::Base(mir::PlaceBase::Local(_))) => Some(place), + mir::Operand::Copy(ref place @ mir::Place { + base: mir::PlaceBase::Local(_), + projection: None, + }) | + mir::Operand::Move(ref place @ mir::Place { + base: mir::PlaceBase::Local(_), + projection: None, + }) => Some(place), _ => None, }; @@ -162,7 +168,7 @@ fn each_block<'tcx, O>( if place == peek_arg_place { if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = **rvalue { // Okay, our search is over. - match move_data.rev_lookup.find(peeking_at_place) { + match move_data.rev_lookup.find(peeking_at_place.as_ref()) { LookupResult::Exact(peek_mpi) => { let bit_state = on_entry.contains(peek_mpi); debug!("rustc_peek({:?} = &{:?}) bit_state: {}", @@ -186,7 +192,7 @@ fn each_block<'tcx, O>( } } - let lhs_mpi = move_data.rev_lookup.find(place); + let lhs_mpi = move_data.rev_lookup.find(place.as_ref()); debug!("rustc_peek: computing effect on place: {:?} ({:?}) in stmt: {:?}", place, lhs_mpi, stmt); diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index f226f15c00..2eed9d453f 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -53,7 +53,7 @@ pub fn simplify_cfg(body: &mut Body<'_>) { } impl MirPass for SimplifyCfg { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { Cow::Borrowed(&self.label) } diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 0c63a8d9c9..9ffa3db4c2 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -1,6 +1,6 @@ //! A pass that simplifies branches when their condition is known. -use rustc::ty::{TyCtxt, ParamEnv}; +use rustc::ty::TyCtxt; use rustc::mir::*; use crate::transform::{MirPass, MirSource}; @@ -15,19 +15,19 @@ impl SimplifyBranches { } impl MirPass for SimplifyBranches { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { Cow::Borrowed(&self.label) } - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { + let param_env = tcx.param_env(src.def_id()); for block in body.basic_blocks_mut() { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { TerminatorKind::SwitchInt { discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, .. } => { - let switch_ty = ParamEnv::empty().and(switch_ty); - let constant = c.literal.assert_bits(tcx, switch_ty); + let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty); if let Some(constant) = constant { let (otherwise, targets) = targets.split_last().unwrap(); let mut ret = TerminatorKind::Goto { target: *otherwise }; @@ -44,7 +44,7 @@ impl MirPass for SimplifyBranches { }, TerminatorKind::Assert { target, cond: Operand::Constant(ref c), expected, .. - } if (c.literal.assert_bool(tcx) == Some(true)) == expected => + } if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected => TerminatorKind::Goto { target }, TerminatorKind::FalseEdges { real_target, .. } => { TerminatorKind::Goto { target: real_target } diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 6878eceb2a..60489e7fa3 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -37,10 +37,11 @@ use crate::util::patch::MirPatch; pub struct UniformArrayMoveOut; impl MirPass for UniformArrayMoveOut { - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { let mut patch = MirPatch::new(body); + let param_env = tcx.param_env(src.def_id()); { - let mut visitor = UniformArrayMoveOutVisitor{body, patch: &mut patch, tcx}; + let mut visitor = UniformArrayMoveOutVisitor{body, patch: &mut patch, tcx, param_env}; visitor.visit_body(body); } patch.apply(body); @@ -51,6 +52,7 @@ struct UniformArrayMoveOutVisitor<'a, 'tcx> { body: &'a Body<'tcx>, patch: &'a mut MirPatch<'tcx>, tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> { @@ -59,19 +61,27 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> { rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Use(Operand::Move(ref src_place)) = rvalue { - if let Place::Projection(ref proj) = *src_place { + if let Some(ref proj) = src_place.projection { if let ProjectionElem::ConstantIndex{offset: _, min_length: _, from_end: false} = proj.elem { // no need to transformation } else { - let place_ty = proj.base.ty(self.body, self.tcx).ty; + let place_ty = + Place::ty_from(&src_place.base, &proj.base, self.body, self.tcx).ty; if let ty::Array(item_ty, const_size) = place_ty.sty { - if let Some(size) = const_size.assert_usize(self.tcx) { + if let Some(size) = const_size.try_eval_usize(self.tcx, self.param_env) { assert!(size <= u32::max_value() as u64, "uniform array move out doesn't supported for array bigger then u32"); - self.uniform(location, dst_place, proj, item_ty, size as u32); + self.uniform( + location, + dst_place, + &src_place.base, + proj, + item_ty, + size as u32, + ); } } @@ -86,6 +96,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { fn uniform(&mut self, location: Location, dst_place: &Place<'tcx>, + base: &PlaceBase<'tcx>, proj: &Projection<'tcx>, item_ty: &'tcx ty::TyS<'tcx>, size: u32) { @@ -100,13 +111,20 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { Place::from(temp), Rvalue::Use( Operand::Move( - Place::Projection(box Projection{ - base: proj.base.clone(), - elem: ProjectionElem::ConstantIndex{ - offset: i, - min_length: size, - from_end: false} - })))); + Place { + base: base.clone(), + projection: Some(box Projection { + base: proj.base.clone(), + elem: ProjectionElem::ConstantIndex { + offset: i, + min_length: size, + from_end: false, + } + }), + } + ) + ) + ); temp }).collect(); self.patch.add_assign( @@ -130,12 +148,20 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { dst_place.clone(), Rvalue::Use( Operand::Move( - Place::Projection(box Projection{ - base: proj.base.clone(), - elem: ProjectionElem::ConstantIndex{ - offset: size - offset, - min_length: size, - from_end: false }})))); + Place { + base: base.clone(), + projection: Some(box Projection { + base: proj.base.clone(), + elem: ProjectionElem::ConstantIndex { + offset: size - offset, + min_length: size, + from_end: false, + }, + }), + } + ) + ) + ); } _ => {} } @@ -159,8 +185,9 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { pub struct RestoreSubsliceArrayMoveOut; impl MirPass for RestoreSubsliceArrayMoveOut { - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { let mut patch = MirPatch::new(body); + let param_env = tcx.param_env(src.def_id()); { let mut visitor = RestoreDataCollector { locals_use: IndexVec::from_elem(LocalUse::new(), &body.local_decls), @@ -173,7 +200,10 @@ impl MirPass for RestoreSubsliceArrayMoveOut { if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind { if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval { let items : Vec<_> = items.iter().map(|item| { - if let Operand::Move(Place::Base(PlaceBase::Local(local))) = item { + if let Operand::Move(Place { + base: PlaceBase::Local(local), + projection: None, + }) = item { let local_use = &visitor.locals_use[*local]; let opt_index_and_place = Self::try_get_item_source(local_use, body); @@ -189,9 +219,10 @@ impl MirPass for RestoreSubsliceArrayMoveOut { let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2); let opt_size = opt_src_place.and_then(|src_place| { - let src_ty = src_place.ty(body, tcx).ty; + let src_ty = + Place::ty_from(src_place.base, src_place.projection, body, tcx).ty; if let ty::Array(_, ref size_o) = src_ty.sty { - size_o.assert_usize(tcx) + size_o.try_eval_usize(tcx, param_env) } else { None } @@ -210,7 +241,7 @@ impl RestoreSubsliceArrayMoveOut { // indices is an integer interval. If all checks pass do the replacent. // items are Vec> fn check_and_patch<'tcx>(candidate: Location, - items: &[Option<(&LocalUse, u32, &Place<'tcx>)>], + items: &[Option<(&LocalUse, u32, PlaceRef<'_, 'tcx>)>], opt_size: Option, patch: &mut MirPatch<'tcx>, dst_place: &Place<'tcx>) { @@ -218,6 +249,7 @@ impl RestoreSubsliceArrayMoveOut { if opt_size.is_some() && items.iter().all( |l| l.is_some() && l.unwrap().2 == opt_src_place.unwrap()) { + let src_place = opt_src_place.unwrap(); let indices: Vec<_> = items.iter().map(|x| x.unwrap().1).collect(); for i in 1..indices.len() { @@ -241,25 +273,39 @@ impl RestoreSubsliceArrayMoveOut { dst_place.clone(), Rvalue::Use( Operand::Move( - Place::Projection(box Projection{ - base: opt_src_place.unwrap().clone(), - elem: ProjectionElem::Subslice{ - from: min, to: size - max - 1}})))); + Place { + base: src_place.base.clone(), + projection: Some(box Projection { + base: src_place.projection.clone(), + elem: ProjectionElem::Subslice{ + from: min, to: size - max - 1}})}))); } } fn try_get_item_source<'a, 'tcx>(local_use: &LocalUse, - body: &'a Body<'tcx>) -> Option<(u32, &'a Place<'tcx>)> { + body: &'a Body<'tcx>) -> Option<(u32, PlaceRef<'a, 'tcx>)> { if let Some(location) = local_use.first_use { let block = &body[location.block]; if block.statements.len() > location.statement_index { let statement = &block.statements[location.statement_index]; if let StatementKind::Assign( - Place::Base(PlaceBase::Local(_)), - box Rvalue::Use(Operand::Move(Place::Projection(box Projection{ - ref base, elem: ProjectionElem::ConstantIndex{ - offset, min_length: _, from_end: false}})))) = statement.kind { - return Some((offset, base)) + Place { + base: PlaceBase::Local(_), + projection: None, + }, + box Rvalue::Use(Operand::Move(Place { + base, + projection: Some(box Projection { + base: proj_base, + elem: ProjectionElem::ConstantIndex { + offset, min_length: _, from_end: false + } + }), + }))) = &statement.kind { + return Some((*offset, PlaceRef { + base, + projection: proj_base, + })) } } } diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index 6245d9c208..b8ef77da02 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -38,15 +38,14 @@ fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<' where L: HasLocalDecls<'tcx>, { - let mut place = place; - while let &Place::Projection(box Projection { - ref base, ref elem - }) = place { - match *elem { + let mut place_projection = &place.projection; + + while let Some(proj) = place_projection { + match proj.elem { // encountered a Deref, which is ABI-aligned ProjectionElem::Deref => break, ProjectionElem::Field(..) => { - let ty = base.ty(local_decls, tcx).ty; + let ty = Place::ty_from(&place.base, &proj.base, local_decls, tcx).ty; match ty.sty { ty::Adt(def, _) if def.repr.packed() => { return true @@ -56,7 +55,7 @@ where } _ => {} } - place = base; + place_projection = &proj.base; } false diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index f1aaa857dd..3359d1b3bb 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -1,87 +1,35 @@ -use rustc::session::config::BorrowckMode; use rustc::ty::{self, Ty, TyCtxt}; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use syntax_pos::{MultiSpan, Span}; -use std::fmt; - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum Origin { - Ast, - Mir, -} - -impl fmt::Display for Origin { - fn fmt(&self, _w: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(chrisvittal) remove Origin entirely - // Print no origin info - Ok(()) - } -} - -impl Origin { - /// Whether we should emit errors for the origin in the given mode - pub fn should_emit_errors(self, mode: BorrowckMode) -> bool { - match self { - Origin::Ast => mode.use_ast(), - Origin::Mir => true, - } - } -} - -pub trait BorrowckErrors<'cx>: Sized + Copy { - fn struct_span_err_with_code>( - self, - sp: S, - msg: &str, - code: DiagnosticId, - ) -> DiagnosticBuilder<'cx>; - - fn struct_span_err>(self, sp: S, msg: &str) -> DiagnosticBuilder<'cx>; - - /// Cancels the given error if we shouldn't emit errors for a given - /// origin in the current mode. - /// - /// Always make sure that the error gets passed through this function - /// before you return it. - fn cancel_if_wrong_origin( - self, - diag: DiagnosticBuilder<'cx>, - o: Origin, - ) -> DiagnosticBuilder<'cx>; - - fn cannot_move_when_borrowed( - self, +impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { + crate fn cannot_move_when_borrowed( + &self, span: Span, desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, span, E0505, - "cannot move out of `{}` because it is borrowed{OGN}", + "cannot move out of `{}` because it is borrowed", desc, - OGN = o - ); - self.cancel_if_wrong_origin(err, o) + ) } - fn cannot_use_when_mutably_borrowed( - self, + crate fn cannot_use_when_mutably_borrowed( + &self, span: Span, desc: &str, borrow_span: Span, borrow_desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, span, E0503, - "cannot use `{}` because it was mutably borrowed{OGN}", + "cannot use `{}` because it was mutably borrowed", desc, - OGN = o ); err.span_label( @@ -89,38 +37,33 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { format!("borrow of `{}` occurs here", borrow_desc), ); err.span_label(span, format!("use of borrowed `{}`", borrow_desc)); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_act_on_uninitialized_variable( - self, + crate fn cannot_act_on_uninitialized_variable( + &self, span: Span, verb: &str, desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, span, E0381, - "{} of possibly uninitialized variable: `{}`{OGN}", + "{} of possibly uninitialized variable: `{}`", verb, desc, - OGN = o - ); - self.cancel_if_wrong_origin(err, o) + ) } - fn cannot_mutably_borrow_multiply( - self, + crate fn cannot_mutably_borrow_multiply( + &self, new_loan_span: Span, desc: &str, opt_via: &str, old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - o: Origin, ) -> DiagnosticBuilder<'cx> { let via = |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) }; @@ -128,10 +71,9 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { self, new_loan_span, E0499, - "cannot borrow `{}`{} as mutable more than once at a time{OGN}", + "cannot borrow `{}`{} as mutable more than once at a time", desc, via(opt_via), - OGN = o ); if old_loan_span == new_loan_span { // Both borrows are happening in the same place @@ -160,24 +102,22 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { err.span_label(old_load_end_span, "first borrow ends here"); } } - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_uniquely_borrow_by_two_closures( - self, + crate fn cannot_uniquely_borrow_by_two_closures( + &self, new_loan_span: Span, desc: &str, old_loan_span: Span, old_load_end_span: Option, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, new_loan_span, E0524, - "two closures require unique access to `{}` at the same time{OGN}", + "two closures require unique access to `{}` at the same time", desc, - OGN = o ); if old_loan_span == new_loan_span { err.span_label( @@ -191,11 +131,11 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { if let Some(old_load_end_span) = old_load_end_span { err.span_label(old_load_end_span, "borrow from first closure ends here"); } - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_uniquely_borrow_by_one_closure( - self, + crate fn cannot_uniquely_borrow_by_one_closure( + &self, new_loan_span: Span, container_name: &str, desc_new: &str, @@ -204,17 +144,15 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, new_loan_span, E0500, - "closure requires unique access to `{}` but {} is already borrowed{}{OGN}", + "closure requires unique access to `{}` but {} is already borrowed{}", desc_new, noun_old, old_opt_via, - OGN = o ); err.span_label( new_loan_span, @@ -224,11 +162,11 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { if let Some(previous_end_span) = previous_end_span { err.span_label(previous_end_span, "borrow ends here"); } - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_reborrow_already_uniquely_borrowed( - self, + crate fn cannot_reborrow_already_uniquely_borrowed( + &self, new_loan_span: Span, container_name: &str, desc_new: &str, @@ -238,18 +176,16 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, new_loan_span, E0501, "cannot borrow `{}`{} as {} because previous closure \ - requires unique access{OGN}", + requires unique access", desc_new, opt_via, kind_new, - OGN = o ); err.span_label( new_loan_span, @@ -262,11 +198,11 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { if let Some(previous_end_span) = previous_end_span { err.span_label(previous_end_span, "borrow from closure ends here"); } - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_reborrow_already_borrowed( - self, + crate fn cannot_reborrow_already_borrowed( + &self, span: Span, desc_new: &str, msg_new: &str, @@ -276,7 +212,6 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { kind_old: &str, msg_old: &str, old_load_end_span: Option, - o: Origin, ) -> DiagnosticBuilder<'cx> { let via = |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) }; @@ -285,14 +220,13 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { span, E0502, "cannot borrow `{}`{} as {} because {} is also borrowed \ - as {}{}{OGN}", + as {}{}", desc_new, via(msg_new), kind_new, noun_old, kind_old, via(msg_old), - OGN = o ); if msg_new == "" { @@ -317,24 +251,21 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { if let Some(old_load_end_span) = old_load_end_span { err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old)); } - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_assign_to_borrowed( - self, + crate fn cannot_assign_to_borrowed( + &self, span: Span, borrow_span: Span, desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, span, E0506, - "cannot assign to `{}` because it is borrowed{OGN}", + "cannot assign to `{}` because it is borrowed", desc, - OGN = o ); err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc)); @@ -342,84 +273,56 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { span, format!("assignment to borrowed `{}` occurs here", desc), ); - - self.cancel_if_wrong_origin(err, o) - } - - fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( - self, - span, - E0504, - "cannot move `{}` into closure because it is borrowed{OGN}", - desc, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_reassign_immutable( - self, + crate fn cannot_reassign_immutable( + &self, span: Span, desc: &str, is_arg: bool, - o: Origin, ) -> DiagnosticBuilder<'cx> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; - let err = struct_span_err!( + struct_span_err!( self, span, E0384, - "cannot assign {} `{}`{OGN}", + "cannot assign {} `{}`", msg, desc, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + ) } - fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!(self, span, E0594, "cannot assign to {}{OGN}", desc, OGN = o); - self.cancel_if_wrong_origin(err, o) + crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> { + struct_span_err!(self, span, E0594, "cannot assign to {}", desc) } - fn cannot_assign_static(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> { - self.cannot_assign(span, &format!("immutable static item `{}`", desc), o) - } - - fn cannot_move_out_of( - self, + crate fn cannot_move_out_of( + &self, move_from_span: Span, move_from_desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, move_from_span, E0507, - "cannot move out of {}{OGN}", + "cannot move out of {}", move_from_desc, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + ) } /// Signal an error due to an attempt to move out of the interior /// of an array or slice. `is_index` is None when error origin /// didn't capture whether there was an indexing operation or not. - fn cannot_move_out_of_interior_noncopy( - self, + crate fn cannot_move_out_of_interior_noncopy( + &self, move_from_span: Span, ty: Ty<'_>, is_index: Option, - o: Origin, ) -> DiagnosticBuilder<'cx> { let type_name = match (&ty.sty, is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", @@ -430,218 +333,144 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { self, move_from_span, E0508, - "cannot move out of type `{}`, a non-copy {}{OGN}", + "cannot move out of type `{}`, a non-copy {}", ty, type_name, - OGN = o ); err.span_label(move_from_span, "cannot move out of here"); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_move_out_of_interior_of_drop( - self, + crate fn cannot_move_out_of_interior_of_drop( + &self, move_from_span: Span, container_ty: Ty<'_>, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, move_from_span, E0509, - "cannot move out of type `{}`, which implements the `Drop` trait{OGN}", + "cannot move out of type `{}`, which implements the `Drop` trait", container_ty, - OGN = o ); err.span_label(move_from_span, "cannot move out of here"); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_act_on_moved_value( - self, + crate fn cannot_act_on_moved_value( + &self, use_span: Span, verb: &str, optional_adverb_for_moved: &str, moved_path: Option, - o: Origin, ) -> DiagnosticBuilder<'cx> { let moved_path = moved_path .map(|mp| format!(": `{}`", mp)) .unwrap_or_default(); - let err = struct_span_err!( + struct_span_err!( self, use_span, E0382, - "{} of {}moved value{}{OGN}", + "{} of {}moved value{}", verb, optional_adverb_for_moved, moved_path, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) - } - - fn cannot_partially_reinit_an_uninit_struct( - self, - span: Span, - uninit_path: &str, - o: Origin, - ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( - self, - span, - E0383, - "partial reinitialization of uninitialized structure `{}`{OGN}", - uninit_path, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) - } - - fn closure_cannot_assign_to_borrowed( - self, - span: Span, - descr: &str, - o: Origin, - ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( - self, - span, - E0595, - "closure cannot assign to {}{OGN}", - descr, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + ) } - fn cannot_borrow_path_as_mutable_because( - self, + crate fn cannot_borrow_path_as_mutable_because( + &self, span: Span, path: &str, reason: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, span, E0596, - "cannot borrow {} as mutable{}{OGN}", + "cannot borrow {} as mutable{}", path, reason, - OGN = o, - ); - - self.cancel_if_wrong_origin(err, o) + ) } - fn cannot_borrow_path_as_mutable( - self, - span: Span, - path: &str, - o: Origin, - ) -> DiagnosticBuilder<'cx> { - self.cannot_borrow_path_as_mutable_because(span, path, "", o) - } - - fn cannot_mutate_in_match_guard( - self, + crate fn cannot_mutate_in_match_guard( + &self, mutate_span: Span, match_span: Span, match_place: &str, action: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, mutate_span, E0510, - "cannot {} `{}` in match guard{OGN}", + "cannot {} `{}` in match guard", action, match_place, - OGN = o ); err.span_label(mutate_span, format!("cannot {}", action)); err.span_label(match_span, String::from("value is immutable in match guard")); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_borrow_across_generator_yield( - self, + crate fn cannot_borrow_across_generator_yield( + &self, span: Span, yield_span: Span, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, span, E0626, - "borrow may still be in use when generator yields{OGN}", - OGN = o + "borrow may still be in use when generator yields", ); err.span_label(yield_span, "possible yield occurs here"); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_borrow_across_destructor( - self, + crate fn cannot_borrow_across_destructor( + &self, borrow_span: Span, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, borrow_span, E0713, - "borrow may still be in use when destructor runs{OGN}", - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + "borrow may still be in use when destructor runs", + ) } - fn path_does_not_live_long_enough( - self, + crate fn path_does_not_live_long_enough( + &self, span: Span, path: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, span, E0597, - "{} does not live long enough{OGN}", + "{} does not live long enough", path, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + ) } - fn cannot_return_reference_to_local( - self, + crate fn cannot_return_reference_to_local( + &self, span: Span, return_kind: &str, reference_desc: &str, path_desc: &str, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, span, E0515, - "cannot {RETURN} {REFERENCE} {LOCAL}{OGN}", + "cannot {RETURN} {REFERENCE} {LOCAL}", RETURN=return_kind, REFERENCE=reference_desc, LOCAL=path_desc, - OGN = o ); err.span_label( @@ -649,74 +478,14 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { format!("{}s a {} data owned by the current function", return_kind, reference_desc), ); - self.cancel_if_wrong_origin(err, o) - } - - fn lifetime_too_short_for_reborrow( - self, - span: Span, - path: &str, - o: Origin, - ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( - self, - span, - E0598, - "lifetime of {} is too short to guarantee \ - its contents can be safely reborrowed{OGN}", - path, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) - } - - fn cannot_act_on_capture_in_sharable_fn( - self, - span: Span, - bad_thing: &str, - help: (Span, &str), - o: Origin, - ) -> DiagnosticBuilder<'cx> { - let (help_span, help_msg) = help; - let mut err = struct_span_err!( - self, - span, - E0387, - "{} in a captured outer variable in an `Fn` closure{OGN}", - bad_thing, - OGN = o - ); - err.span_help(help_span, help_msg); - - self.cancel_if_wrong_origin(err, o) + err } - fn cannot_assign_into_immutable_reference( - self, - span: Span, - bad_thing: &str, - o: Origin, - ) -> DiagnosticBuilder<'cx> { - let mut err = struct_span_err!( - self, - span, - E0389, - "{} in a `&` reference{OGN}", - bad_thing, - OGN = o - ); - err.span_label(span, "assignment into an immutable reference"); - - self.cancel_if_wrong_origin(err, o) - } - - fn cannot_capture_in_long_lived_closure( - self, + crate fn cannot_capture_in_long_lived_closure( + &self, closure_span: Span, borrowed_path: &str, capture_span: Span, - o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( self, @@ -724,92 +493,61 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { E0373, "closure may outlive the current function, \ but it borrows {}, \ - which is owned by the current function{OGN}", + which is owned by the current function", borrowed_path, - OGN = o ); err.span_label(capture_span, format!("{} is borrowed here", borrowed_path)) .span_label( closure_span, format!("may outlive borrowed value {}", borrowed_path), ); - - self.cancel_if_wrong_origin(err, o) + err } - fn borrowed_data_escapes_closure( - self, - escape_span: Span, - escapes_from: &str, - o: Origin, - ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( - self, - escape_span, - E0521, - "borrowed data escapes outside of {}{OGN}", - escapes_from, - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) - } - - fn thread_local_value_does_not_live_long_enough( - self, + crate fn thread_local_value_does_not_live_long_enough( + &self, span: Span, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, span, E0712, - "thread-local variable borrowed past end of function{OGN}", - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + "thread-local variable borrowed past end of function", + ) } - fn temporary_value_borrowed_for_too_long( - self, + crate fn temporary_value_borrowed_for_too_long( + &self, span: Span, - o: Origin, ) -> DiagnosticBuilder<'cx> { - let err = struct_span_err!( + struct_span_err!( self, span, E0716, - "temporary value dropped while borrowed{OGN}", - OGN = o - ); - - self.cancel_if_wrong_origin(err, o) + "temporary value dropped while borrowed", + ) } -} -impl BorrowckErrors<'tcx> for TyCtxt<'tcx> { fn struct_span_err_with_code>( - self, + &self, sp: S, msg: &str, code: DiagnosticId, ) -> DiagnosticBuilder<'tcx> { - self.sess.struct_span_err_with_code(sp, msg, code) - } - - fn struct_span_err>(self, sp: S, msg: &str) -> DiagnosticBuilder<'tcx> { - self.sess.struct_span_err(sp, msg) + self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code) } +} - fn cancel_if_wrong_origin( - self, - mut diag: DiagnosticBuilder<'tcx>, - o: Origin, - ) -> DiagnosticBuilder<'tcx> { - if !o.should_emit_errors(self.borrowck_mode()) { - self.sess.diagnostic().cancel(&mut diag); - } - diag - } +crate fn borrowed_data_escapes_closure<'tcx>( + tcx: TyCtxt<'tcx>, + escape_span: Span, + escapes_from: &str, +) -> DiagnosticBuilder<'tcx> { + struct_span_err!( + tcx.sess, + escape_span, + E0521, + "borrowed data escapes outside of {}", + escapes_from, + ) } diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index fac752dbf0..59821440c6 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -31,7 +31,7 @@ impl DefUseAnalysis { self.clear(); let mut finder = DefUseFinder { - info: mem::replace(&mut self.info, IndexVec::new()), + info: mem::take(&mut self.info), }; finder.visit_body(body); self.info = finder.info diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index dac90d3727..52fd645e38 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -584,10 +584,13 @@ where (Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, - Place::Projection(Box::new(Projection { - base: Place::Base(PlaceBase::Local(cur)), - elem: ProjectionElem::Deref, - })) + Place { + base: PlaceBase::Local(cur), + projection: Some(Box::new(Projection { + base: None, + elem: ProjectionElem::Deref, + })), + } ), Rvalue::BinaryOp(BinOp::Offset, move_(&Place::from(cur)), one)) } else { @@ -801,8 +804,8 @@ where let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); self.open_drop_for_tuple(&tys) } - ty::Tuple(tys) => { - let tys: Vec<_> = tys.iter().map(|k| k.expect_ty()).collect(); + ty::Tuple(..) => { + let tys: Vec<_> = ty.tuple_fields().collect(); self.open_drop_for_tuple(&tys) } ty::Adt(def, substs) => { @@ -818,7 +821,7 @@ where self.complete_drop(Some(DropFlagMode::Deep), succ, unwind) } ty::Array(ety, size) => { - let size = size.assert_usize(self.tcx()); + let size = size.try_eval_usize(self.tcx(), self.elaborator.param_env()); self.open_drop_for_array(ety, size) }, ty::Slice(ety) => self.open_drop_for_array(ety, None), diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 1d876d7bdd..9d142d9b70 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -8,8 +8,8 @@ use std::io::{self, Write}; use super::pretty::dump_mir_def_ids; /// Write a graphviz DOT graph of a list of MIRs. -pub fn write_mir_graphviz<'tcx, W>( - tcx: TyCtxt<'tcx>, +pub fn write_mir_graphviz( + tcx: TyCtxt<'_>, single: Option, w: &mut W, ) -> io::Result<()> diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 8ead571d96..b42eebc7ee 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -56,8 +56,8 @@ pub struct LivenessResult { /// Computes which local variables are live within the given function /// `mir`, including drops. -pub fn liveness_of_locals<'tcx>( - body: &Body<'tcx>, +pub fn liveness_of_locals( + body: &Body<'_>, ) -> LivenessResult { let num_live_vars = body.local_decls.len(); @@ -243,8 +243,8 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor } } -fn block<'tcx>( - b: &BasicBlockData<'tcx>, +fn block( + b: &BasicBlockData<'_>, locals: usize, ) -> DefsUses { let mut visitor = DefsUsesVisitor { diff --git a/src/librustc_mir/util/mod.rs b/src/librustc_mir/util/mod.rs index 719029dbaa..c8a90a9891 100644 --- a/src/librustc_mir/util/mod.rs +++ b/src/librustc_mir/util/mod.rs @@ -1,7 +1,3 @@ -use core::unicode::property::Pattern_White_Space; -use rustc::ty::TyCtxt; -use syntax_pos::Span; - pub mod aggregate; pub mod borrowck_errors; pub mod elaborate_drops; @@ -19,16 +15,3 @@ pub use self::alignment::is_disaligned; pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz}; pub use self::graphviz::write_node_label as write_graphviz_node_label; - -/// If possible, suggest replacing `ref` with `ref mut`. -pub fn suggest_ref_mut<'tcx>(tcx: TyCtxt<'tcx>, binding_span: Span) -> Option<(String)> { - let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).unwrap(); - if hi_src.starts_with("ref") - && hi_src["ref".len()..].starts_with(Pattern_White_Space) - { - let replacement = format!("ref mut{}", &hi_src["ref".len()..]); - Some(replacement) - } else { - None - } -} diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index d66f35f82c..68880fc345 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -263,7 +263,7 @@ pub fn write_mir_pretty<'tcx>( write_mir_fn(tcx, MirSource::item(def_id), body, &mut |_, _| Ok(()), w)?; - for (i, body) in body.promoted.iter_enumerated() { + for (i, body) in tcx.promoted_mir(def_id).iter_enumerated() { writeln!(w, "")?; let src = MirSource { instance: ty::InstanceDef::Item(def_id), diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 3bdb86d313..d6c8e54c18 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -6,5 +6,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -#![deny(rust_2018_idioms)] diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 00bdcdc0cc..596ec6c19b 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -7,14 +7,11 @@ edition = "2018" [lib] name = "rustc_passes" path = "lib.rs" -crate-type = ["dylib"] [dependencies] log = "0.4" rustc = { path = "../librustc" } -rustc_mir = { path = "../librustc_mir"} rustc_data_structures = { path = "../librustc_data_structures" } syntax = { path = "../libsyntax" } -syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } errors = { path = "../librustc_errors", package = "rustc_errors" } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 5606359629..3c31bcef32 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -14,12 +14,12 @@ use rustc::session::Session; use rustc_data_structures::fx::FxHashMap; use syntax::ast::*; use syntax::attr; +use syntax::ext::proc_macro::is_proc_macro_attr; use syntax::feature_gate::is_builtin_attr; use syntax::source_map::Spanned; use syntax::symbol::{kw, sym}; use syntax::visit::{self, Visitor}; use syntax::{span_err, struct_span_err, walk_list}; -use syntax_ext::proc_macro_decls::is_proc_macro_attr; use syntax_pos::{Span, MultiSpan}; use errors::{Applicability, FatalError}; @@ -51,7 +51,6 @@ impl OuterImplTrait { struct AstValidator<'a> { session: &'a Session, has_proc_macro_decls: bool, - has_global_allocator: bool, /// Used to ban nested `impl Trait`, e.g., `impl Into`. /// Nested `impl Trait` _is_ allowed in associated type position, @@ -288,7 +287,7 @@ impl<'a> AstValidator<'a> { // ``` fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) { match expr.node { - ExprKind::Lit(..) => {} + ExprKind::Lit(..) | ExprKind::Err => {} ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, ref inner) if match inner.node { ExprKind::Lit(_) => true, _ => false } => {} @@ -539,10 +538,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.has_proc_macro_decls = true; } - if attr::contains_name(&item.attrs, sym::global_allocator) { - self.has_global_allocator = true; - } - match item.node { ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { self.invalid_visibility(&item.vis, None); @@ -672,7 +667,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { "unions cannot have zero fields"); } } - ItemKind::Existential(ref bounds, _) => { + ItemKind::OpaqueTy(ref bounds, _) => { if !bounds.iter() .any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) { let msp = MultiSpan::from_spans(bounds.iter() @@ -848,11 +843,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) { +pub fn check_crate(session: &Session, krate: &Crate) -> bool { let mut validator = AstValidator { session, has_proc_macro_decls: false, - has_global_allocator: false, outer_impl_trait: None, is_impl_trait_banned: false, is_assoc_ty_bound_banned: false, @@ -861,5 +855,5 @@ pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) { }; visit::walk_crate(&mut validator, krate); - (validator.has_proc_macro_decls, validator.has_global_allocator) + validator.has_proc_macro_decls } diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs index e3c6b16703..cd33943e77 100644 --- a/src/librustc_passes/error_codes.rs +++ b/src/librustc_passes/error_codes.rs @@ -1,6 +1,4 @@ -#![allow(non_snake_case)] - -use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; +use syntax::{register_diagnostics, register_long_diagnostics}; register_long_diagnostics! { /* diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 6936aedb9d..8fba3256ec 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -38,7 +38,7 @@ pub fn print_hir_stats(krate: &hir::Crate) { collector.print("HIR STATS"); } -pub fn print_ast_stats<'v>(krate: &'v ast::Crate, title: &str) { +pub fn print_ast_stats(krate: &ast::Crate, title: &str) { let mut collector = StatCollector { krate: None, data: FxHashMap::default(), @@ -94,6 +94,11 @@ impl<'k> StatCollector<'k> { } impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { + fn visit_arg(&mut self, arg: &'v hir::Arg) { + self.record("Arg", Id::Node(arg.hir_id), arg); + hir_visit::walk_arg(self, arg) + } + fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'v> { panic!("visit_nested_xxx must be manually implemented in this visitor") } diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 8f790d1328..45a185dccf 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -14,7 +14,7 @@ use rustc::ty::TyCtxt; use syntax::ast::Attribute; use syntax::symbol::sym; -pub fn test_layout<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn test_layout(tcx: TyCtxt<'_>) { if tcx.features().rustc_attrs { // if the `rustc_attrs` feature is not enabled, don't bother testing layout tcx.hir() @@ -29,9 +29,9 @@ struct VarianceTest<'tcx> { impl ItemLikeVisitor<'tcx> for VarianceTest<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let item_def_id = self.tcx.hir().local_def_id(item.hir_id); - if let ItemKind::Ty(..) = item.node { + if let ItemKind::TyAlias(..) = item.node { for attr in self.tcx.get_attrs(item_def_id).iter() { if attr.check_name(sym::rustc_layout) { self.dump_layout_of(item_def_id, item, attr); diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 5f3d7159be..5614b570b9 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -13,10 +13,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate rustc; diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index ed0a78b465..afe4c78dcf 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -12,27 +12,10 @@ use syntax::struct_span_err; use syntax_pos::Span; use errors::Applicability; -#[derive(Clone, Copy, Debug, PartialEq)] -enum LoopKind { - Loop(hir::LoopSource), - WhileLoop, -} - -impl LoopKind { - fn name(self) -> &'static str { - match self { - LoopKind::Loop(hir::LoopSource::Loop) => "loop", - LoopKind::Loop(hir::LoopSource::WhileLet) => "while let", - LoopKind::Loop(hir::LoopSource::ForLoop) => "for", - LoopKind::WhileLoop => "while", - } - } -} - #[derive(Clone, Copy, Debug, PartialEq)] enum Context { Normal, - Loop(LoopKind), + Loop(hir::LoopSource), Closure, LabeledBlock, AnonConst, @@ -45,7 +28,7 @@ struct CheckLoopVisitor<'a, 'hir> { cx: Context, } -fn check_mod_loops<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckLoopVisitor { sess: &tcx.sess, hir_map: &tcx.hir(), @@ -71,14 +54,8 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { fn visit_expr(&mut self, e: &'hir hir::Expr) { match e.node { - hir::ExprKind::While(ref e, ref b, _) => { - self.with_context(Loop(LoopKind::WhileLoop), |v| { - v.visit_expr(&e); - v.visit_block(&b); - }); - } hir::ExprKind::Loop(ref b, _, source) => { - self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b)); + self.with_context(Loop(source), |v| v.visit_block(&b)); } hir::ExprKind::Closure(_, ref function_decl, b, _, _) => { self.visit_fn_decl(&function_decl); @@ -117,15 +94,14 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { None } else { Some(match self.hir_map.expect_expr(loop_id).node { - hir::ExprKind::While(..) => LoopKind::WhileLoop, - hir::ExprKind::Loop(_, _, source) => LoopKind::Loop(source), + hir::ExprKind::Loop(_, _, source) => source, ref r => span_bug!(e.span, "break label resolved to a non-loop: {:?}", r), }) }; match loop_kind { None | - Some(LoopKind::Loop(hir::LoopSource::Loop)) => (), + Some(hir::LoopSource::Loop) => (), Some(kind) => { struct_span_err!(self.sess, e.span, E0571, "`break` with value from a `{}` loop", diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index bc1151974b..f2461f7016 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -39,7 +39,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn const_is_rvalue_promotable_to_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn const_is_rvalue_promotable_to_static(tcx: TyCtxt<'_>, def_id: DefId) -> bool { assert!(def_id.is_local()); let hir_id = tcx.hir().as_local_hir_id(def_id) @@ -48,7 +48,7 @@ fn const_is_rvalue_promotable_to_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) tcx.rvalue_promotable_map(def_id).contains(&body_id.hir_id.local_id) } -fn rvalue_promotable_map<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ItemLocalSet { +fn rvalue_promotable_map(tcx: TyCtxt<'_>, def_id: DefId) -> &ItemLocalSet { let outer_def_id = tcx.closure_base_def_id(def_id); if outer_def_id != def_id { return tcx.rvalue_promotable_map(outer_def_id); @@ -165,7 +165,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_nested_body(&mut self, body_id: hir::BodyId) -> Promotability { let item_id = self.tcx.hir().body_owner(body_id); - let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item_id); + let item_def_id = self.tcx.hir().local_def_id(item_id); let outer_in_fn = self.in_fn; let outer_tables = self.tables; @@ -311,7 +311,7 @@ fn check_expr_kind<'a, 'tcx>( } hir::ExprKind::Cast(ref from, _) => { let expr_promotability = v.check_expr(from); - debug!("Checking const cast(id={})", from.hir_id); + debug!("checking const cast(id={})", from.hir_id); let cast_in = CastTy::from_ty(v.tables.expr_ty(from)); let cast_out = CastTy::from_ty(v.tables.expr_ty(e)); match (cast_in, cast_out) { @@ -338,15 +338,15 @@ fn check_expr_kind<'a, 'tcx>( if v.in_static { for attr in &v.tcx.get_attrs(did)[..] { if attr.check_name(sym::thread_local) { - debug!("Reference to Static(id={:?}) is unpromotable \ - due to a #[thread_local] attribute", did); + debug!("reference to `Static(id={:?})` is unpromotable \ + due to a `#[thread_local]` attribute", did); return NotPromotable; } } Promotable } else { - debug!("Reference to Static(id={:?}) is unpromotable as it is not \ - referenced from a static", did); + debug!("reference to `Static(id={:?})` is unpromotable as it is not \ + referenced from a static", did); NotPromotable } } @@ -451,7 +451,7 @@ fn check_expr_kind<'a, 'tcx>( let nested_body_promotable = v.check_nested_body(body_id); // Paths in constant contexts cannot refer to local variables, // as there are none, and thus closures can't have upvars there. - let closure_def_id = v.tcx.hir().local_def_id_from_hir_id(e.hir_id); + let closure_def_id = v.tcx.hir().local_def_id(e.hir_id); if !v.tcx.upvars(closure_def_id).map_or(true, |v| v.is_empty()) { NotPromotable } else { @@ -520,13 +520,6 @@ fn check_expr_kind<'a, 'tcx>( NotPromotable } - // Loops (not very meaningful in constants). - hir::ExprKind::While(ref expr, ref box_block, ref _option_label) => { - let _ = v.check_expr(expr); - let _ = v.check_block(box_block); - NotPromotable - } - hir::ExprKind::Loop(ref box_block, ref _option_label, ref _loop_source) => { let _ = v.check_block(box_block); NotPromotable diff --git a/src/librustc_plugin/Cargo.toml b/src/librustc_plugin/Cargo.toml index 5e23aa0d7f..7486281c1e 100644 --- a/src/librustc_plugin/Cargo.toml +++ b/src/librustc_plugin/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" [lib] name = "rustc_plugin" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] rustc = { path = "../librustc" } diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs index d3ac597160..f1bf1111cf 100644 --- a/src/librustc_plugin/build.rs +++ b/src/librustc_plugin/build.rs @@ -30,11 +30,11 @@ impl<'v> ItemLikeVisitor<'v> for RegistrarFinder { } /// Finds the function marked with `#[plugin_registrar]`, if any. -pub fn find_plugin_registrar<'tcx>(tcx: TyCtxt<'tcx>) -> Option { +pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option { tcx.plugin_registrar_fn(LOCAL_CRATE) } -fn plugin_registrar_fn<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option { +fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option { assert_eq!(cnum, LOCAL_CRATE); let mut finder = RegistrarFinder { registrars: Vec::new() }; @@ -44,7 +44,7 @@ fn plugin_registrar_fn<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option 0 => None, 1 => { let (hir_id, _) = finder.registrars.pop().unwrap(); - Some(tcx.hir().local_def_id_from_hir_id(hir_id)) + Some(tcx.hir().local_def_id(hir_id)) }, _ => { let diagnostic = tcx.sess.diagnostic(); diff --git a/src/librustc_plugin/error_codes.rs b/src/librustc_plugin/error_codes.rs index 68462bd83e..b5f6a8d905 100644 --- a/src/librustc_plugin/error_codes.rs +++ b/src/librustc_plugin/error_codes.rs @@ -1,6 +1,4 @@ -#![allow(non_snake_case)] - -use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; +use syntax::{register_diagnostics, register_long_diagnostics}; register_long_diagnostics! { diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index cb6f8ebd82..25a7a8cdeb 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -17,6 +17,7 @@ //! #![feature(rustc_private)] //! //! extern crate rustc_plugin; +//! extern crate rustc_driver; //! extern crate syntax; //! extern crate syntax_pos; //! @@ -58,8 +59,6 @@ #![recursion_limit="256"] -#![deny(rust_2018_idioms)] - pub use registry::Registry; mod error_codes; diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 16d484e2a9..bb3c950eda 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -6,7 +6,7 @@ use rustc::util::nodemap::FxHashMap; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension}; use syntax::ext::base::MacroExpanderFn; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::Symbol; use syntax::ast; use syntax::feature_gate::AttributeType; use syntax_pos::Span; @@ -77,20 +77,14 @@ impl<'a> Registry<'a> { /// /// Returns empty slice in case the plugin was loaded /// with `--extra-plugins` - pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] { + pub fn args(&self) -> &[ast::NestedMetaItem] { self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[]) } /// Register a syntax extension of any kind. /// /// This is the most general hook into `libsyntax`'s expansion behavior. - pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { - if name == sym::macro_rules { - panic!("user-defined macros may not be named `macro_rules`"); - } - if extension.def_info.is_none() { - extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); - } + pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { self.syntax_exts.push((name, extension)); } diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 5bf8024c56..7cf3a5d6dc 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [lib] name = "rustc_privacy" path = "lib.rs" -crate-type = ["dylib"] [dependencies] rustc = { path = "../librustc" } diff --git a/src/librustc_privacy/error_codes.rs b/src/librustc_privacy/error_codes.rs index fa4df53e47..70a799d426 100644 --- a/src/librustc_privacy/error_codes.rs +++ b/src/librustc_privacy/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - register_long_diagnostics! { E0445: r##" diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 3e98200e53..673762ee4c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1,9 +1,5 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] @@ -29,6 +25,7 @@ use rustc_data_structures::fx::FxHashSet; use syntax::ast::Ident; use syntax::attr; use syntax::symbol::{kw, sym}; +use syntax_pos::hygiene::Transparency; use syntax_pos::Span; use std::{cmp, fmt, mem}; @@ -232,6 +229,13 @@ fn def_id_visibility<'tcx>( let vis = match tcx.hir().get(hir_id) { Node::Item(item) => &item.vis, Node::ForeignItem(foreign_item) => &foreign_item.vis, + Node::MacroDef(macro_def) => { + if attr::contains_name(¯o_def.attrs, sym::macro_export) { + return (ty::Visibility::Public, macro_def.span, "public"); + } else { + ¯o_def.vis + } + }, Node::TraitItem(..) | Node::Variant(..) => { return def_id_visibility(tcx, tcx.hir().get_parent_did(hir_id)); } @@ -250,13 +254,13 @@ fn def_id_visibility<'tcx>( let parent_hir_id = tcx.hir().get_parent_node(hir_id); match tcx.hir().get(parent_hir_id) { Node::Variant(..) => { - let parent_did = tcx.hir().local_def_id_from_hir_id(parent_hir_id); + let parent_did = tcx.hir().local_def_id(parent_hir_id); let (mut ctor_vis, mut span, mut descr) = def_id_visibility( tcx, parent_did, ); let adt_def = tcx.adt_def(tcx.hir().get_parent_did(hir_id)); - let ctor_did = tcx.hir().local_def_id_from_hir_id( + let ctor_did = tcx.hir().local_def_id( vdata.ctor_hir_id().unwrap()); let variant = adt_def.variant_with_ctor_id(ctor_did); @@ -333,11 +337,11 @@ fn item_tables<'a, 'tcx>( hir_id: hir::HirId, empty_tables: &'a ty::TypeckTables<'tcx>, ) -> &'a ty::TypeckTables<'tcx> { - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); if tcx.has_typeck_tables(def_id) { tcx.typeck_tables_of(def_id) } else { empty_tables } } -fn min<'tcx>(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'tcx>) -> ty::Visibility { +fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visibility { if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 } } @@ -384,17 +388,17 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> trait VisibilityLike: Sized { const MAX: Self; const SHALLOW: bool = false; - fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self; + fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self; // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // associated types for which we can't determine visibility precisely. - fn of_impl<'a, 'tcx>( + fn of_impl( hir_id: hir::HirId, - tcx: TyCtxt<'tcx>, - access_levels: &'a AccessLevels, + tcx: TyCtxt<'_>, + access_levels: &AccessLevels, ) -> Self { let mut find = FindMin { tcx, access_levels, min: Self::MAX }; - let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let def_id = tcx.hir().local_def_id(hir_id); find.visit(tcx.type_of(def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(def_id) { find.visit_trait(trait_ref); @@ -404,7 +408,7 @@ trait VisibilityLike: Sized { } impl VisibilityLike for ty::Visibility { const MAX: Self = ty::Visibility::Public; - fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self { + fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { min(def_id_visibility(find.tcx, def_id).0, find.min, find.tcx) } } @@ -420,7 +424,7 @@ impl VisibilityLike for Option { // both "shallow" version of its self type and "shallow" version of its trait if it exists // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; - fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self { + fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { cmp::min(if let Some(hir_id) = find.tcx.hir().as_local_hir_id(def_id) { find.access_levels.map.get(&hir_id).cloned() } else { @@ -436,11 +440,24 @@ impl VisibilityLike for Option { struct EmbargoVisitor<'tcx> { tcx: TyCtxt<'tcx>, - // Accessibility levels for reachable nodes. + /// Accessibility levels for reachable nodes. access_levels: AccessLevels, - // Previous accessibility level; `None` means unreachable. + /// A set of pairs corresponding to modules, where the first module is + /// reachable via a macro that's defined in the second module. This cannot + /// be represented as reachable because it can't handle the following case: + /// + /// pub mod n { // Should be `Public` + /// pub(crate) mod p { // Should *not* be accessible + /// pub fn f() -> i32 { 12 } // Must be `Reachable` + /// } + /// } + /// pub macro m() { + /// n::p::f() + /// } + macro_reachable: FxHashSet<(hir::HirId, DefId)>, + /// Previous accessibility level; `None` means unreachable. prev_level: Option, - // Has something changed in the level map? + /// Has something changed in the level map? changed: bool, } @@ -455,7 +472,7 @@ impl EmbargoVisitor<'tcx> { self.access_levels.map.get(&id).cloned() } - // Updates node level and returns the updated level. + /// Updates node level and returns the updated level. fn update(&mut self, id: hir::HirId, level: Option) -> Option { let old_level = self.get(id); // Accessibility levels can only grow. @@ -475,11 +492,132 @@ impl EmbargoVisitor<'tcx> { ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { ReachEverythingInTheInterfaceVisitor { access_level: cmp::min(access_level, Some(AccessLevel::Reachable)), - item_def_id: self.tcx.hir().local_def_id_from_hir_id(item_id), + item_def_id: self.tcx.hir().local_def_id(item_id), ev: self, } } + /// Updates the item as being reachable through a macro defined in the given + /// module. Returns `true` if the level has changed. + fn update_macro_reachable(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) -> bool { + if self.macro_reachable.insert((reachable_mod, defining_mod)) { + self.update_macro_reachable_mod(reachable_mod, defining_mod); + true + } else { + false + } + } + + fn update_macro_reachable_mod( + &mut self, + reachable_mod: hir::HirId, + defining_mod: DefId, + ) { + let module_def_id = self.tcx.hir().local_def_id(reachable_mod); + let module = self.tcx.hir().get_module(module_def_id).0; + for item_id in &module.item_ids { + let hir_id = item_id.id; + let item_def_id = self.tcx.hir().local_def_id(hir_id); + if let Some(def_kind) = self.tcx.def_kind(item_def_id) { + let item = self.tcx.hir().expect_item(hir_id); + let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx); + self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod); + } + } + + if let Some(exports) = self.tcx.module_exports(module_def_id) { + for export in exports { + if export.vis.is_accessible_from(defining_mod, self.tcx) { + if let Res::Def(def_kind, def_id) = export.res { + let vis = def_id_visibility(self.tcx, def_id).0; + if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) { + self.update_macro_reachable_def( + hir_id, + def_kind, + vis, + defining_mod, + ); + } + } + } + } + } + } + + fn update_macro_reachable_def( + &mut self, + hir_id: hir::HirId, + def_kind: DefKind, + vis: ty::Visibility, + module: DefId, + ) { + let level = Some(AccessLevel::Reachable); + if let ty::Visibility::Public = vis { + self.update(hir_id, level); + } + match def_kind { + // No type privacy, so can be directly marked as reachable. + DefKind::Const + | DefKind::Macro(_) + | DefKind::Static + | DefKind::TraitAlias + | DefKind::TyAlias => { + if vis.is_accessible_from(module, self.tcx) { + self.update(hir_id, level); + } + }, + + // We can't use a module name as the final segment of a path, except + // in use statements. Since re-export checking doesn't consider + // hygiene these don't need to be marked reachable. The contents of + // the module, however may be reachable. + DefKind::Mod => { + if vis.is_accessible_from(module, self.tcx) { + self.update_macro_reachable(hir_id, module); + } + } + + DefKind::Struct | DefKind::Union => { + // While structs and unions have type privacy, their fields do + // not. + if let ty::Visibility::Public = vis { + let item = self.tcx.hir().expect_item(hir_id); + if let hir::ItemKind::Struct(ref struct_def, _) + | hir::ItemKind::Union(ref struct_def, _) = item.node + { + for field in struct_def.fields() { + let field_vis = ty::Visibility::from_hir( + &field.vis, + field.hir_id, + self.tcx, + ); + if field_vis.is_accessible_from(module, self.tcx) { + self.reach(field.hir_id, level).ty(); + } + } + } else { + bug!("item {:?} with DefKind {:?}", item, def_kind); + } + } + } + + // These have type privacy, so are not reachable unless they're + // public + DefKind::AssocConst + | DefKind::AssocTy + | DefKind::AssocOpaqueTy + | DefKind::ConstParam + | DefKind::Ctor(_, _) + | DefKind::Enum + | DefKind::ForeignTy + | DefKind::Fn + | DefKind::OpaqueTy + | DefKind::Method + | DefKind::Trait + | DefKind::TyParam + | DefKind::Variant => (), + } + } /// Given the path segments of a `ItemKind::Use`, then we need /// to update the visibility of the intermediate use so that it isn't linted @@ -506,7 +644,7 @@ impl EmbargoVisitor<'tcx> { if let hir::ItemKind::Mod(m) = &item.node { for item_id in m.item_ids.as_ref() { let item = self.tcx.hir().expect_item(item_id.id); - let def_id = self.tcx.hir().local_def_id_from_hir_id(item_id.id); + let def_id = self.tcx.hir().local_def_id(item_id.id); if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; } if let hir::ItemKind::Use(..) = item.node { self.update(item.hir_id, Some(AccessLevel::Exported)); @@ -536,8 +674,8 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | - hir::ItemKind::Existential(..) | - hir::ItemKind::Ty(..) | hir::ItemKind::Union(..) | hir::ItemKind::Use(..) => { + hir::ItemKind::OpaqueTy(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Union(..) | hir::ItemKind::Use(..) => { if item.vis.node.is_pub() { self.prev_level } else { None } } }; @@ -587,12 +725,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Existential(..) | + hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Use(..) | hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::GlobalAsm(..) | - hir::ItemKind::Ty(..) | + hir::ItemKind::TyAlias(..) | hir::ItemKind::Mod(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Fn(..) | @@ -615,7 +753,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } // The interface is empty. hir::ItemKind::GlobalAsm(..) => {} - hir::ItemKind::Existential(..) => { + hir::ItemKind::OpaqueTy(..) => { // FIXME: This is some serious pessimization intended to workaround deficiencies // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time // reachable if they are returned via `impl Trait`, even from private functions. @@ -624,7 +762,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } // Visit everything. hir::ItemKind::Const(..) | hir::ItemKind::Static(..) | - hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => { + hir::ItemKind::Fn(..) | hir::ItemKind::TyAlias(..) => { if item_level.is_some() { self.reach(item.hir_id, item_level).generics().predicates().ty(); } @@ -726,7 +864,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { // This code is here instead of in visit_item so that the // crate module gets processed as well. if self.prev_level.is_some() { - let def_id = self.tcx.hir().local_def_id_from_hir_id(id); + let def_id = self.tcx.hir().local_def_id(id); if let Some(exports) = self.tcx.module_exports(def_id) { for export in exports.iter() { if export.vis == ty::Visibility::Public { @@ -744,45 +882,26 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) { - if md.legacy { + if attr::find_transparency(&md.attrs, md.legacy).0 != Transparency::Opaque { self.update(md.hir_id, Some(AccessLevel::Public)); return } - let module_did = ty::DefIdTree::parent( + let macro_module_def_id = ty::DefIdTree::parent( self.tcx, - self.tcx.hir().local_def_id_from_hir_id(md.hir_id) + self.tcx.hir().local_def_id(md.hir_id) ).unwrap(); - let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap(); + let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap(); let level = if md.vis.node.is_pub() { self.get(module_id) } else { None }; - let level = self.update(md.hir_id, level); - if level.is_none() { + let new_level = self.update(md.hir_id, level); + if new_level.is_none() { return } loop { - let module = if module_id == hir::CRATE_HIR_ID { - &self.tcx.hir().krate().module - } else if let hir::ItemKind::Mod(ref module) = - self.tcx.hir().expect_item(module_id).node { - module - } else { - unreachable!() - }; - for id in &module.item_ids { - self.update(id.id, level); - } - let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id); - if let Some(exports) = self.tcx.module_exports(def_id) { - for export in exports.iter() { - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.res.def_id()) { - self.update(hir_id, level); - } - } - } - - if module_id == hir::CRATE_HIR_ID { - break + let changed_reachability = self.update_macro_reachable(module_id, macro_module_def_id); + if changed_reachability || module_id == hir::CRATE_HIR_ID { + break; } module_id = self.tcx.hir().get_parent_node(module_id); } @@ -829,7 +948,12 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.ev.tcx } fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool { if let Some(hir_id) = self.ev.tcx.hir().as_local_hir_id(def_id) { - self.ev.update(hir_id, self.access_level); + if let ((ty::Visibility::Public, ..), _) + | (_, Some(AccessLevel::ReachableFromImplTrait)) + = (def_id_visibility(self.tcx(), def_id), self.access_level) + { + self.ev.update(hir_id, self.access_level); + } } false } @@ -1053,14 +1177,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { if !self.in_body { // Avoid calling `hir_trait_to_predicates` in bodies, it will ICE. // The traits' privacy in bodies is already checked as a part of trait object types. - let (principal, bounds) = rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref); - if self.visit_trait(*principal.skip_binder()) { - return; + let bounds = rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref); + + for (trait_predicate, _) in bounds.trait_bounds { + if self.visit_trait(*trait_predicate.skip_binder()) { + return; + } } + for (poly_predicate, _) in bounds.projection_bounds { let tcx = self.tcx; - if self.visit(poly_predicate.skip_binder().ty) || - self.visit_trait(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) { + if self.visit(poly_predicate.skip_binder().ty) + || self.visit_trait(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) + { return; } } @@ -1116,7 +1245,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { DefKind::Method | DefKind::AssocConst | DefKind::AssocTy - | DefKind::AssocExistential + | DefKind::AssocOpaqueTy | DefKind::Static => true, _ => false, } @@ -1130,7 +1259,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { hir::QPath::Resolved(_, ref path) => path.to_string(), hir::QPath::TypeRelative(_, ref segment) => segment.ident.to_string(), }; - let msg = format!("{} `{}` is private", kind.descr(), name); + let msg = format!("{} `{}` is private", kind.descr(def_id), name); self.tcx.sess.span_err(span, &msg); return; } @@ -1163,7 +1292,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { // Check types in item interfaces. fn visit_item(&mut self, item: &'tcx hir::Item) { let orig_current_item = mem::replace(&mut self.current_item, - self.tcx.hir().local_def_id_from_hir_id(item.hir_id)); + self.tcx.hir().local_def_id(item.hir_id)); let orig_in_body = mem::replace(&mut self.in_body, false); let orig_tables = mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables)); @@ -1373,8 +1502,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { self.access_levels.is_reachable( impl_item_ref.id.hir_id) } - hir::ImplItemKind::Existential(..) | - hir::ImplItemKind::Type(_) => false, + hir::ImplItemKind::OpaqueTy(..) | + hir::ImplItemKind::TyAlias(_) => false, } }); @@ -1400,7 +1529,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { { intravisit::walk_impl_item(self, impl_item) } - hir::ImplItemKind::Type(..) => { + hir::ImplItemKind::TyAlias(..) => { intravisit::walk_impl_item(self, impl_item) } _ => {} @@ -1426,7 +1555,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // Those in 3. are warned with this call. for impl_item_ref in impl_item_refs { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - if let hir::ImplItemKind::Type(ref ty) = impl_item.node { + if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.node { self.visit_ty(ty); } } @@ -1461,7 +1590,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // `type ... = ...;` can contain private types, because // we're introducing a new name. - hir::ItemKind::Ty(..) => return, + hir::ItemKind::TyAlias(..) => return, // Not at all public, so we don't care. _ if !self.item_is_public(&item.hir_id, &item.vis) => { @@ -1689,7 +1818,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { SearchInterfaceForPrivateItemsVisitor { tcx: self.tcx, item_id, - item_def_id: self.tcx.hir().local_def_id_from_hir_id(item_id), + item_def_id: self.tcx.hir().local_def_id(item_id), span: self.tcx.hir().span(item_id), required_visibility, has_pub_restricted: self.has_pub_restricted, @@ -1710,9 +1839,9 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { let (check_ty, is_assoc_ty) = match assoc_item_kind { AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false), AssocItemKind::Type => (defaultness.has_value(), true), - // `ty()` for existential types is the underlying type, + // `ty()` for opaque types is the underlying type, // it's not a part of interface, so we skip it. - AssocItemKind::Existential => (false, true), + AssocItemKind::OpaqueTy => (false, true), }; check.in_assoc_ty = is_assoc_ty; check.generics().predicates(); @@ -1742,11 +1871,11 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> hir::ItemKind::GlobalAsm(..) => {} // Subitems of these items have inherited publicity. hir::ItemKind::Const(..) | hir::ItemKind::Static(..) | - hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => { + hir::ItemKind::Fn(..) | hir::ItemKind::TyAlias(..) => { self.check(item.hir_id, item_visibility).generics().predicates().ty(); } - hir::ItemKind::Existential(..) => { - // `ty()` for existential types is the underlying type, + hir::ItemKind::OpaqueTy(..) => { + // `ty()` for opaque types is the underlying type, // it's not a part of interface, so we skip it. self.check(item.hir_id, item_visibility).generics().predicates(); } @@ -1828,7 +1957,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn check_mod_privacy<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); // Check privacy of names not checked in previous compilation stages. @@ -1855,7 +1984,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { intravisit::walk_mod(&mut visitor, module, hir_id); } -fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx AccessLevels { +fn privacy_access_levels(tcx: TyCtxt<'_>, krate: CrateNum) -> &AccessLevels { assert_eq!(krate, LOCAL_CRATE); // Build up a set of all exported items in the AST. This is a set of all @@ -1863,6 +1992,7 @@ fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx Acce let mut visitor = EmbargoVisitor { tcx, access_levels: Default::default(), + macro_reachable: Default::default(), prev_level: Some(AccessLevel::Public), changed: false, }; @@ -1879,7 +2009,7 @@ fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx Acce tcx.arena.alloc(visitor.access_levels) } -fn check_private_in_public<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) { +fn check_private_in_public(tcx: TyCtxt<'_>, krate: CrateNum) { assert_eq!(krate, LOCAL_CRATE); let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 8e3359c775..548f982fe3 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "rustc_resolve" path = "lib.rs" -crate-type = ["dylib"] test = false +doctest = false [dependencies] bitflags = "1.0" diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 616728d541..5dd7bc3054 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -3,17 +3,17 @@ //! Here we build the "reduced graph": the graph of the module tree without //! any imports resolved. -use crate::macros::{InvocationData, ParentScope, LegacyScope}; +use crate::macros::{InvocationData, LegacyBinding, LegacyScope}; use crate::resolve_imports::ImportDirective; use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; -use crate::{ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; +use crate::{ModuleOrUniformRoot, ParentScope, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; use crate::Namespace::{self, TypeNS, ValueNS, MacroNS}; -use crate::{resolve_error, resolve_struct_error, ResolutionError}; +use crate::{ResolutionError, Determinacy, PathResult, CrateLint}; use rustc::bug; use rustc::hir::def::{self, *}; -use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::ty; use rustc::middle::cstore::CrateStore; use rustc_metadata::cstore::LoadedMacro; @@ -30,13 +30,10 @@ use syntax::attr; use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant}; use syntax::ext::base::{MacroKind, SyntaxExtension}; -use syntax::ext::base::Determinacy::Undetermined; -use syntax::ext::hygiene::Mark; -use syntax::ext::tt::macro_rules; +use syntax::ext::hygiene::ExpnId; use syntax::feature_gate::is_builtin_attr; use syntax::parse::token::{self, Token}; -use syntax::span_err; -use syntax::std_inject::injected_crate_name; +use syntax::{span_err, struct_span_err}; use syntax::symbol::{kw, sym}; use syntax::visit::{self, Visitor}; @@ -46,7 +43,7 @@ use log::debug; type Res = def::Res; -impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) { +impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, ExpnId) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Module(self.0), @@ -58,7 +55,7 @@ impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) { } } -impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, Mark) { +impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Res(self.0, false), @@ -72,7 +69,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, Mark) { pub(crate) struct IsMacroExport; -impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, Mark, IsMacroExport) { +impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Res(self.0, true), @@ -96,6 +93,193 @@ impl<'a> Resolver<'a> { } } + pub fn get_module(&mut self, def_id: DefId) -> Module<'a> { + if def_id.krate == LOCAL_CRATE { + return self.module_map[&def_id] + } + + let macros_only = self.cstore.dep_kind_untracked(def_id.krate).macros_only(); + if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) { + return module; + } + + let (name, parent) = if def_id.index == CRATE_DEF_INDEX { + (self.cstore.crate_name_untracked(def_id.krate).as_interned_str(), None) + } else { + let def_key = self.cstore.def_key(def_id); + (def_key.disambiguated_data.data.get_opt_name().unwrap(), + Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) + }; + + let kind = ModuleKind::Def(DefKind::Mod, def_id, name.as_symbol()); + let module = self.arenas.alloc_module(ModuleData::new( + parent, kind, def_id, ExpnId::root(), DUMMY_SP + )); + self.extern_module_map.insert((def_id, macros_only), module); + module + } + + pub fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> { + let def_id = match self.macro_defs.get(&expn_id) { + Some(def_id) => *def_id, + None => return self.graph_root, + }; + if let Some(id) = self.definitions.as_local_node_id(def_id) { + self.local_macro_def_scopes[&id] + } else { + let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap(); + self.get_module(module_def_id) + } + } + + crate fn get_macro(&mut self, res: Res) -> Option> { + match res { + Res::Def(DefKind::Macro(..), def_id) => self.get_macro_by_def_id(def_id), + Res::NonMacroAttr(attr_kind) => + Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)), + _ => None, + } + } + + crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option> { + if let Some(ext) = self.macro_map.get(&def_id) { + return Some(ext.clone()); + } + + let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) { + LoadedMacro::MacroDef(macro_def) => macro_def, + LoadedMacro::ProcMacro(ext) => return Some(ext), + }; + + let ext = self.compile_macro(¯o_def, self.cstore.crate_edition_untracked(def_id.krate)); + self.macro_map.insert(def_id, ext.clone()); + Some(ext) + } + + /// Ensures that the reduced graph rooted at the given external module + /// is built, building it if it is not. + pub fn populate_module_if_necessary(&mut self, module: Module<'a>) { + if module.populated.get() { return } + let def_id = module.def_id().unwrap(); + for child in self.cstore.item_children_untracked(def_id, self.session) { + let child = child.map_id(|_| panic!("unexpected id")); + BuildReducedGraphVisitor { parent_scope: self.dummy_parent_scope(), r: self } + .build_reduced_graph_for_external_crate_res(module, child); + } + module.populated.set(true) + } +} + +pub struct BuildReducedGraphVisitor<'a, 'b> { + pub r: &'b mut Resolver<'a>, + pub parent_scope: ParentScope<'a>, +} + +impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { + fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { + let parent_scope = &self.parent_scope; + match vis.node { + ast::VisibilityKind::Public => ty::Visibility::Public, + ast::VisibilityKind::Crate(..) => { + ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + } + ast::VisibilityKind::Inherited => { + ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id) + } + ast::VisibilityKind::Restricted { ref path, id, .. } => { + // For visibilities we are not ready to provide correct implementation of "uniform + // paths" right now, so on 2018 edition we only allow module-relative paths for now. + // On 2015 edition visibilities are resolved as crate-relative by default, + // so we are prepending a root segment if necessary. + let ident = path.segments.get(0).expect("empty path in visibility").ident; + let crate_root = if ident.is_path_segment_keyword() { + None + } else if ident.span.rust_2018() { + let msg = "relative paths are not supported in visibilities on 2018 edition"; + self.r.session.struct_span_err(ident.span, msg) + .span_suggestion( + path.span, + "try", + format!("crate::{}", path), + Applicability::MaybeIncorrect, + ) + .emit(); + return ty::Visibility::Public; + } else { + let ctxt = ident.span.ctxt(); + Some(Segment::from_ident(Ident::new( + kw::PathRoot, path.span.shrink_to_lo().with_ctxt(ctxt) + ))) + }; + + let segments = crate_root.into_iter() + .chain(path.segments.iter().map(|seg| seg.into())).collect::>(); + let expected_found_error = |this: &Self, res: Res| { + let path_str = Segment::names_to_string(&segments); + struct_span_err!(this.r.session, path.span, E0577, + "expected module, found {} `{}`", res.descr(), path_str) + .span_label(path.span, "not a module").emit(); + }; + match self.r.resolve_path( + &segments, + Some(TypeNS), + parent_scope, + true, + path.span, + CrateLint::SimplePath(id), + ) { + PathResult::Module(ModuleOrUniformRoot::Module(module)) => { + let res = module.res().expect("visibility resolved to unnamed block"); + self.r.record_partial_res(id, PartialRes::new(res)); + if module.is_normal() { + if res == Res::Err { + ty::Visibility::Public + } else { + let vis = ty::Visibility::Restricted(res.def_id()); + if self.r.is_accessible_from(vis, parent_scope.module) { + vis + } else { + let msg = + "visibilities can only be restricted to ancestor modules"; + self.r.session.span_err(path.span, msg); + ty::Visibility::Public + } + } + } else { + expected_found_error(self, res); + ty::Visibility::Public + } + } + PathResult::Module(..) => { + self.r.session.span_err(path.span, "visibility must resolve to a module"); + ty::Visibility::Public + } + PathResult::NonModule(partial_res) => { + expected_found_error(self, partial_res.base_res()); + ty::Visibility::Public + } + PathResult::Failed { span, label, suggestion, .. } => { + self.r.report_error( + span, ResolutionError::FailedToResolve { label, suggestion } + ); + ty::Visibility::Public + } + PathResult::Indeterminate => { + span_err!(self.r.session, path.span, E0578, + "cannot determine resolution for the visibility"); + ty::Visibility::Public + } + } + } + } + } + + fn insert_field_names(&mut self, def_id: DefId, field_names: Vec) { + if !field_names.is_empty() { + self.r.field_names.insert(def_id, field_names); + } + } + fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { // If any statements are items, we need to create an anonymous module block.stmts.iter().any(|statement| match statement.node { @@ -104,9 +288,51 @@ impl<'a> Resolver<'a> { }) } - fn insert_field_names(&mut self, def_id: DefId, field_names: Vec) { - if !field_names.is_empty() { - self.field_names.insert(def_id, field_names); + // Add an import directive to the current module. + fn add_import_directive( + &mut self, + module_path: Vec, + subclass: ImportDirectiveSubclass<'a>, + span: Span, + id: NodeId, + item: &ast::Item, + root_span: Span, + root_id: NodeId, + vis: ty::Visibility, + ) { + let parent_scope = &self.parent_scope; + let current_module = parent_scope.module; + let directive = self.r.arenas.alloc_import_directive(ImportDirective { + parent_scope: parent_scope.clone(), + module_path, + imported_module: Cell::new(None), + subclass, + span, + id, + use_span: item.span, + use_span_with_attributes: item.span_with_attributes(), + has_attributes: !item.attrs.is_empty(), + root_span, + root_id, + vis: Cell::new(vis), + used: Cell::new(false), + }); + + debug!("add_import_directive({:?})", directive); + + self.r.indeterminate_imports.push(directive); + match directive.subclass { + SingleImport { target, type_ns_only, .. } => { + self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { + let mut resolution = this.resolution(current_module, target, ns).borrow_mut(); + resolution.add_single_import(directive); + }); + } + // We don't add prelude imports to the globs since they only affect lexical scopes, + // which are not relevant to import resolution. + GlobImport { is_prelude: true, .. } => {} + GlobImport { .. } => current_module.globs.borrow_mut().push(directive), + _ => unreachable!(), } } @@ -118,7 +344,6 @@ impl<'a> Resolver<'a> { parent_prefix: &[Segment], nested: bool, // The whole `use` item - parent_scope: ParentScope<'a>, item: &Item, vis: ty::Visibility, root_span: Span, @@ -166,8 +391,7 @@ impl<'a> Resolver<'a> { type_ns_only = true; if empty_for_self(&module_path) { - resolve_error( - self, + self.r.report_error( use_tree.span, ResolutionError:: SelfImportOnlyInImportListWithNonEmptyPrefix @@ -184,14 +408,14 @@ impl<'a> Resolver<'a> { } else { // Disallow `self` if source.ident.name == kw::SelfLower { - resolve_error(self, - use_tree.span, - ResolutionError::SelfImportsOnlyAllowedWithin); + self.r.report_error( + use_tree.span, ResolutionError::SelfImportsOnlyAllowedWithin + ); } // Disallow `use $crate;` if source.ident.name == kw::DollarCrate && module_path.is_empty() { - let crate_root = self.resolve_crate_root(source.ident); + let crate_root = self.r.resolve_crate_root(source.ident); let crate_name = match crate_root.kind { ModuleKind::Def(.., name) => name, ModuleKind::Block(..) => unreachable!(), @@ -206,7 +430,7 @@ impl<'a> Resolver<'a> { name: kw::PathRoot, span: source.ident.span, }, - id: Some(self.session.next_node_id()), + id: Some(self.r.session.next_node_id()), }); source.ident.name = crate_name; } @@ -214,7 +438,7 @@ impl<'a> Resolver<'a> { ident.name = crate_name; } - self.session.struct_span_warn(item.span, "`$crate` may not be imported") + self.r.session.struct_span_warn(item.span, "`$crate` may not be imported") .note("`use $crate;` was erroneously allowed and \ will become a hard error in a future release") .emit(); @@ -222,7 +446,7 @@ impl<'a> Resolver<'a> { } if ident.name == kw::Crate { - self.session.span_err(ident.span, + self.r.session.span_err(ident.span, "crate root imports need to be explicitly named: \ `use crate as name;`"); } @@ -231,9 +455,9 @@ impl<'a> Resolver<'a> { source: source.ident, target: ident, source_bindings: PerNS { - type_ns: Cell::new(Err(Undetermined)), - value_ns: Cell::new(Err(Undetermined)), - macro_ns: Cell::new(Err(Undetermined)), + type_ns: Cell::new(Err(Determinacy::Undetermined)), + value_ns: Cell::new(Err(Determinacy::Undetermined)), + macro_ns: Cell::new(Err(Determinacy::Undetermined)), }, target_bindings: PerNS { type_ns: Cell::new(None), @@ -252,7 +476,6 @@ impl<'a> Resolver<'a> { root_span, item.id, vis, - parent_scope, ); } ast::UseTreeKind::Glob => { @@ -269,7 +492,6 @@ impl<'a> Resolver<'a> { root_span, item.id, vis, - parent_scope, ); } ast::UseTreeKind::Nested(ref items) => { @@ -284,7 +506,7 @@ impl<'a> Resolver<'a> { None }).collect::>(); if self_spans.len() > 1 { - let mut e = resolve_struct_error(self, + let mut e = self.r.into_struct_error( self_spans[0], ResolutionError::SelfImportCanOnlyAppearOnceInTheList); @@ -300,7 +522,7 @@ impl<'a> Resolver<'a> { // This particular use tree tree, id, &prefix, true, // The whole `use` item - parent_scope.clone(), item, vis, root_span, + item, vis, root_span, ); } @@ -324,7 +546,7 @@ impl<'a> Resolver<'a> { // This particular use tree &tree, id, &prefix, true, // The whole `use` item - parent_scope, item, ty::Visibility::Invisible, root_span, + item, ty::Visibility::Invisible, root_span, ); } } @@ -332,7 +554,8 @@ impl<'a> Resolver<'a> { } /// Constructs the reduced graph for one item. - fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: ParentScope<'a>) { + fn build_reduced_graph_for_item(&mut self, item: &Item) { + let parent_scope = &self.parent_scope; let parent = parent_scope.module; let expansion = parent_scope.expansion; let ident = item.ident.gensym_if_underscore(); @@ -345,13 +568,13 @@ impl<'a> Resolver<'a> { // This particular use tree use_tree, item.id, &[], false, // The whole `use` item - parent_scope, item, vis, use_tree.span, + item, vis, use_tree.span, ); } ItemKind::ExternCrate(orig_name) => { let module = if orig_name.is_none() && ident.name == kw::SelfLower { - self.session + self.r.session .struct_span_err(item.span, "`extern crate self;` requires renaming") .span_suggestion( item.span, @@ -362,24 +585,23 @@ impl<'a> Resolver<'a> { .emit(); return; } else if orig_name == Some(kw::SelfLower) { - self.graph_root + self.r.graph_root } else { - let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions); - self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }) + let crate_id = self.r.crate_loader.process_extern_crate( + item, &self.r.definitions + ); + self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }) }; - self.populate_module_if_necessary(module); - if injected_crate_name().map_or(false, |name| ident.name.as_str() == name) { - self.injected_crate = Some(module); - } + self.r.populate_module_if_necessary(module); - let used = self.process_legacy_macro_imports(item, module, &parent_scope); + let used = self.process_legacy_macro_imports(item, module); let binding = - (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas); - let directive = self.arenas.alloc_import_directive(ImportDirective { + (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); + let directive = self.r.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope, + parent_scope: self.parent_scope.clone(), imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::ExternCrate { source: orig_name, @@ -394,18 +616,18 @@ impl<'a> Resolver<'a> { vis: Cell::new(vis), used: Cell::new(used), }); - self.potentially_unused_imports.push(directive); - let imported_binding = self.import(binding, directive); - if ptr::eq(self.current_module, self.graph_root) { - if let Some(entry) = self.extern_prelude.get(&ident.modern()) { - if expansion != Mark::root() && orig_name.is_some() && + self.r.potentially_unused_imports.push(directive); + let imported_binding = self.r.import(binding, directive); + if ptr::eq(parent, self.r.graph_root) { + if let Some(entry) = self.r.extern_prelude.get(&ident.modern()) { + if expansion != ExpnId::root() && orig_name.is_some() && entry.extern_crate_item.is_none() { - self.session.span_err(item.span, "macro-expanded `extern crate` items \ - cannot shadow names passed with \ - `--extern`"); + let msg = "macro-expanded `extern crate` items cannot \ + shadow names passed with `--extern`"; + self.r.session.span_err(item.span, msg); } } - let entry = self.extern_prelude.entry(ident.modern()) + let entry = self.r.extern_prelude.entry(ident.modern()) .or_insert(ExternPreludeEntry { extern_crate_item: None, introduced_by_item: true, @@ -415,7 +637,7 @@ impl<'a> Resolver<'a> { entry.introduced_by_item = true; } } - self.define(parent, ident, TypeNS, imported_binding); + self.r.define(parent, ident, TypeNS, imported_binding); } ItemKind::GlobalAsm(..) => {} @@ -423,19 +645,19 @@ impl<'a> Resolver<'a> { ItemKind::Mod(..) if ident.name == kw::Invalid => {} // Crate root ItemKind::Mod(..) => { - let def_id = self.definitions.local_def_id(item.id); + let def_id = self.r.definitions.local_def_id(item.id); let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name); - let module = self.arenas.alloc_module(ModuleData { + let module = self.r.arenas.alloc_module(ModuleData { no_implicit_prelude: parent.no_implicit_prelude || { attr::contains_name(&item.attrs, sym::no_implicit_prelude) }, ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span) }); - self.define(parent, ident, TypeNS, (module, vis, sp, expansion)); - self.module_map.insert(def_id, module); + self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.r.module_map.insert(def_id, module); // Descend into the module. - self.current_module = module; + self.parent_scope.module = module; } // Handled in `rustc_metadata::{native_libs,link_args}` @@ -443,61 +665,45 @@ impl<'a> Resolver<'a> { // These items live in the value namespace. ItemKind::Static(..) => { - let res = Res::Def(DefKind::Static, self.definitions.local_def_id(item.id)); - self.define(parent, ident, ValueNS, (res, vis, sp, expansion)); + let res = Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); } ItemKind::Const(..) => { - let res = Res::Def(DefKind::Const, self.definitions.local_def_id(item.id)); - self.define(parent, ident, ValueNS, (res, vis, sp, expansion)); + let res = Res::Def(DefKind::Const, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); } ItemKind::Fn(..) => { - let res = Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id)); - self.define(parent, ident, ValueNS, (res, vis, sp, expansion)); + let res = Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). - if attr::contains_name(&item.attrs, sym::proc_macro) || - attr::contains_name(&item.attrs, sym::proc_macro_attribute) { - let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id()); - self.define(parent, ident, MacroNS, (res, vis, sp, expansion)); - } - if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) { - if let Some(trait_attr) = - attr.meta_item_list().and_then(|list| list.get(0).cloned()) { - if let Some(ident) = trait_attr.ident() { - let res = Res::Def( - DefKind::Macro(MacroKind::ProcMacroStub), - res.def_id(), - ); - self.define(parent, ident, MacroNS, (res, vis, ident.span, expansion)); - } - } - } + self.define_macro(item); } // These items live in the type namespace. - ItemKind::Ty(..) => { - let res = Res::Def(DefKind::TyAlias, self.definitions.local_def_id(item.id)); - self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + ItemKind::TyAlias(..) => { + let res = Res::Def(DefKind::TyAlias, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } - ItemKind::Existential(_, _) => { - let res = Res::Def(DefKind::Existential, self.definitions.local_def_id(item.id)); - self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + ItemKind::OpaqueTy(_, _) => { + let res = Res::Def(DefKind::OpaqueTy, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } ItemKind::Enum(ref enum_definition, _) => { let module_kind = ModuleKind::Def( DefKind::Enum, - self.definitions.local_def_id(item.id), + self.r.definitions.local_def_id(item.id), ident.name, ); - let module = self.new_module(parent, + let module = self.r.new_module(parent, module_kind, parent.normal_ancestor_id, expansion, item.span); - self.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); for variant in &(*enum_definition).variants { self.build_reduced_graph_for_variant(variant, module, vis, expansion); @@ -505,16 +711,16 @@ impl<'a> Resolver<'a> { } ItemKind::TraitAlias(..) => { - let res = Res::Def(DefKind::TraitAlias, self.definitions.local_def_id(item.id)); - self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + let res = Res::Def(DefKind::TraitAlias, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } // These items live in both the type and value namespaces. ItemKind::Struct(ref struct_def, _) => { // Define a name in the type namespace. - let def_id = self.definitions.local_def_id(item.id); + let def_id = self.r.definitions.local_def_id(item.id); let res = Res::Def(DefKind::Struct, def_id); - self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); let mut ctor_vis = vis; @@ -529,12 +735,12 @@ impl<'a> Resolver<'a> { // Record field names for error reporting. let field_names = struct_def.fields().iter().filter_map(|field| { let field_vis = self.resolve_visibility(&field.vis); - if ctor_vis.is_at_least(field_vis, &*self) { + if ctor_vis.is_at_least(field_vis, &*self.r) { ctor_vis = field_vis; } field.ident.map(|ident| ident.name) }).collect(); - let item_def_id = self.definitions.local_def_id(item.id); + let item_def_id = self.r.definitions.local_def_id(item.id); self.insert_field_names(item_def_id, field_names); // If this is a tuple or unit struct, define a name @@ -542,40 +748,44 @@ impl<'a> Resolver<'a> { if let Some(ctor_node_id) = struct_def.ctor_id() { let ctor_res = Res::Def( DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(struct_def)), - self.definitions.local_def_id(ctor_node_id), + self.r.definitions.local_def_id(ctor_node_id), ); - self.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); - self.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis)); + self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); + self.r.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis)); } } ItemKind::Union(ref vdata, _) => { - let res = Res::Def(DefKind::Union, self.definitions.local_def_id(item.id)); - self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + let res = Res::Def(DefKind::Union, self.r.definitions.local_def_id(item.id)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); // Record field names for error reporting. let field_names = vdata.fields().iter().filter_map(|field| { self.resolve_visibility(&field.vis); field.ident.map(|ident| ident.name) }).collect(); - let item_def_id = self.definitions.local_def_id(item.id); + let item_def_id = self.r.definitions.local_def_id(item.id); self.insert_field_names(item_def_id, field_names); } - ItemKind::Impl(..) => {} + ItemKind::Impl(.., ref impl_items) => { + for impl_item in impl_items { + self.resolve_visibility(&impl_item.vis); + } + } ItemKind::Trait(..) => { - let def_id = self.definitions.local_def_id(item.id); + let def_id = self.r.definitions.local_def_id(item.id); // Add all the items within to a new module. let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name); - let module = self.new_module(parent, + let module = self.r.new_module(parent, module_kind, parent.normal_ancestor_id, expansion, item.span); - self.define(parent, ident, TypeNS, (module, vis, sp, expansion)); - self.current_module = module; + self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.parent_scope.module = module; } ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(), @@ -588,13 +798,13 @@ impl<'a> Resolver<'a> { variant: &Variant, parent: Module<'a>, vis: ty::Visibility, - expansion: Mark) { + expn_id: ExpnId) { let ident = variant.node.ident; // Define a name in the type namespace. - let def_id = self.definitions.local_def_id(variant.node.id); + let def_id = self.r.definitions.local_def_id(variant.node.id); let res = Res::Def(DefKind::Variant, def_id); - self.define(parent, ident, TypeNS, (res, vis, variant.span, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id)); // If the variant is marked as non_exhaustive then lower the visibility to within the // crate. @@ -610,41 +820,43 @@ impl<'a> Resolver<'a> { // It's ok to use the variant's id as a ctor id since an // error will be reported on any use of such resolution anyway. let ctor_node_id = variant.node.data.ctor_id().unwrap_or(variant.node.id); - let ctor_def_id = self.definitions.local_def_id(ctor_node_id); + let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id); let ctor_kind = CtorKind::from_ast(&variant.node.data); let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id); - self.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expansion)); + self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); } /// Constructs the reduced graph for one foreign item. - fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion: Mark) { + fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) { let (res, ns) = match item.node { ForeignItemKind::Fn(..) => { - (Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS) + (Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id)), ValueNS) } ForeignItemKind::Static(..) => { - (Res::Def(DefKind::Static, self.definitions.local_def_id(item.id)), ValueNS) + (Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id)), ValueNS) } ForeignItemKind::Ty => { - (Res::Def(DefKind::ForeignTy, self.definitions.local_def_id(item.id)), TypeNS) + (Res::Def(DefKind::ForeignTy, self.r.definitions.local_def_id(item.id)), TypeNS) } ForeignItemKind::Macro(_) => unreachable!(), }; - let parent = self.current_module; + let parent = self.parent_scope.module; + let expansion = self.parent_scope.expansion; let vis = self.resolve_visibility(&item.vis); - self.define(parent, item.ident, ns, (res, vis, item.span, expansion)); + self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion)); } - fn build_reduced_graph_for_block(&mut self, block: &Block, expansion: Mark) { - let parent = self.current_module; + fn build_reduced_graph_for_block(&mut self, block: &Block) { + let parent = self.parent_scope.module; + let expansion = self.parent_scope.expansion; if self.block_needs_anonymous_module(block) { - let module = self.new_module(parent, + let module = self.r.new_module(parent, ModuleKind::Block(block.id), parent.normal_ancestor_id, expansion, block.span); - self.block_map.insert(block.id, module); - self.current_module = module; // Descend into the block. + self.r.block_map.insert(block.id, module); + self.parent_scope.module = module; // Descend into the block. } } @@ -659,183 +871,109 @@ impl<'a> Resolver<'a> { // but metadata cannot encode gensyms currently, so we create it here. // This is only a guess, two equivalent idents may incorrectly get different gensyms here. let ident = ident.gensym_if_underscore(); - let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene + let expansion = ExpnId::root(); // FIXME(jseyfried) intercrate hygiene match res { Res::Def(kind @ DefKind::Mod, def_id) | Res::Def(kind @ DefKind::Enum, def_id) => { - let module = self.new_module(parent, + let module = self.r.new_module(parent, ModuleKind::Def(kind, def_id, ident.name), def_id, expansion, span); - self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); } Res::Def(DefKind::Variant, _) | Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::ForeignTy, _) - | Res::Def(DefKind::Existential, _) + | Res::Def(DefKind::OpaqueTy, _) | Res::Def(DefKind::TraitAlias, _) | Res::PrimTy(..) | Res::ToolMod => { - self.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)); } Res::Def(DefKind::Fn, _) | Res::Def(DefKind::Static, _) | Res::Def(DefKind::Const, _) | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _) => { - self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); } Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => { - self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); if let Some(struct_def_id) = - self.cstore.def_key(def_id).parent + self.r.cstore.def_key(def_id).parent .map(|index| DefId { krate: def_id.krate, index: index }) { - self.struct_constructors.insert(struct_def_id, (res, vis)); + self.r.struct_constructors.insert(struct_def_id, (res, vis)); } } Res::Def(DefKind::Trait, def_id) => { let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name); - let module = self.new_module(parent, + let module = self.r.new_module(parent, module_kind, parent.normal_ancestor_id, expansion, span); - self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); - for child in self.cstore.item_children_untracked(def_id, self.session) { + for child in self.r.cstore.item_children_untracked(def_id, self.r.session) { let res = child.res.map_id(|_| panic!("unexpected id")); let ns = if let Res::Def(DefKind::AssocTy, _) = res { TypeNS } else { ValueNS }; - self.define(module, child.ident, ns, + self.r.define(module, child.ident, ns, (res, ty::Visibility::Public, DUMMY_SP, expansion)); - if self.cstore.associated_item_cloned_untracked(child.res.def_id()) + if self.r.cstore.associated_item_cloned_untracked(child.res.def_id()) .method_has_self_argument { - self.has_self.insert(res.def_id()); + self.r.has_self.insert(res.def_id()); } } module.populated.set(true); } Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => { - self.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)); // Record field names for error reporting. - let field_names = self.cstore.struct_field_names_untracked(def_id); + let field_names = self.r.cstore.struct_field_names_untracked(def_id); self.insert_field_names(def_id, field_names); } Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { - self.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion)); + self.r.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion)); } _ => bug!("unexpected resolution: {:?}", res) } } - pub fn get_module(&mut self, def_id: DefId) -> Module<'a> { - if def_id.krate == LOCAL_CRATE { - return self.module_map[&def_id] - } - - let macros_only = self.cstore.dep_kind_untracked(def_id.krate).macros_only(); - if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) { - return module; - } - - let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore.crate_name_untracked(def_id.krate).as_interned_str(), None) - } else { - let def_key = self.cstore.def_key(def_id); - (def_key.disambiguated_data.data.get_opt_name().unwrap(), - Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) - }; - - let kind = ModuleKind::Def(DefKind::Mod, def_id, name.as_symbol()); - let module = - self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP)); - self.extern_module_map.insert((def_id, macros_only), module); - module - } - - pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> { - let def_id = self.macro_defs[&expansion]; - if let Some(id) = self.definitions.as_local_node_id(def_id) { - self.local_macro_def_scopes[&id] - } else if def_id.krate == CrateNum::BuiltinMacros { - self.injected_crate.unwrap_or(self.graph_root) - } else { - let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap(); - self.get_module(module_def_id) - } - } - - pub fn get_macro(&mut self, res: Res) -> Lrc { - let def_id = match res { - Res::Def(DefKind::Macro(..), def_id) => def_id, - Res::NonMacroAttr(attr_kind) => - return self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool), - _ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"), - }; - if let Some(ext) = self.macro_map.get(&def_id) { - return ext.clone(); - } - - let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) { - LoadedMacro::MacroDef(macro_def) => macro_def, - LoadedMacro::ProcMacro(ext) => return ext, - }; - - let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess, - &self.session.features_untracked(), - ¯o_def, - self.cstore.crate_edition_untracked(def_id.krate))); - self.macro_map.insert(def_id, ext.clone()); - ext - } - - /// Ensures that the reduced graph rooted at the given external module - /// is built, building it if it is not. - pub fn populate_module_if_necessary(&mut self, module: Module<'a>) { - if module.populated.get() { return } - let def_id = module.def_id().unwrap(); - for child in self.cstore.item_children_untracked(def_id, self.session) { - let child = child.map_id(|_| panic!("unexpected id")); - self.build_reduced_graph_for_external_crate_res(module, child); - } - module.populated.set(true) - } - fn legacy_import_macro(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span, allow_shadowing: bool) { - if self.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing { + if self.r.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing { let msg = format!("`{}` is already in scope", name); let note = "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)"; - self.session.struct_span_err(span, &msg).note(note).emit(); + self.r.session.struct_span_err(span, &msg).note(note).emit(); } } /// Returns `true` if we should consider the underlying `extern crate` to be used. - fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, - parent_scope: &ParentScope<'a>) -> bool { + fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>) -> bool { let mut import_all = None; let mut single_imports = Vec::new(); for attr in &item.attrs { if attr.check_name(sym::macro_use) { - if self.current_module.parent.is_some() { - span_err!(self.session, item.span, E0468, + if self.parent_scope.module.parent.is_some() { + span_err!(self.r.session, item.span, E0468, "an `extern crate` loading macros must be at the crate root"); } if let ItemKind::ExternCrate(Some(orig_name)) = item.node { if orig_name == kw::SelfLower { - self.session.span_err(attr.span, + self.r.session.span_err(attr.span, "`macro_use` is not supported on `extern crate self`"); } } - let ill_formed = |span| span_err!(self.session, span, E0466, "bad macro import"); + let ill_formed = |span| span_err!(self.r.session, span, E0466, "bad macro import"); match attr.meta() { Some(meta) => match meta.node { MetaItemKind::Word => { @@ -855,11 +993,11 @@ impl<'a> Resolver<'a> { } } - let arenas = self.arenas; - let macro_use_directive = |span| arenas.alloc_import_directive(ImportDirective { + let macro_use_directive = + |this: &Self, span| this.r.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope: parent_scope.clone(), + parent_scope: this.parent_scope.clone(), imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::MacroUse, use_span_with_attributes: item.span_with_attributes(), @@ -872,32 +1010,32 @@ impl<'a> Resolver<'a> { used: Cell::new(false), }); - let allow_shadowing = parent_scope.expansion == Mark::root(); + let allow_shadowing = self.parent_scope.expansion == ExpnId::root(); if let Some(span) = import_all { - let directive = macro_use_directive(span); - self.potentially_unused_imports.push(directive); + let directive = macro_use_directive(self, span); + self.r.potentially_unused_imports.push(directive); module.for_each_child(|ident, ns, binding| if ns == MacroNS { - let imported_binding = self.import(binding, directive); + let imported_binding = self.r.import(binding, directive); self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing); }); } else { for ident in single_imports.iter().cloned() { - let result = self.resolve_ident_in_module( + let result = self.r.resolve_ident_in_module( ModuleOrUniformRoot::Module(module), ident, MacroNS, - None, + &self.parent_scope, false, ident.span, ); if let Ok(binding) = result { - let directive = macro_use_directive(ident.span); - self.potentially_unused_imports.push(directive); - let imported_binding = self.import(binding, directive); + let directive = macro_use_directive(self, ident.span); + self.r.potentially_unused_imports.push(directive); + let imported_binding = self.r.import(binding, directive); self.legacy_import_macro(ident.name, imported_binding, ident.span, allow_shadowing); } else { - span_err!(self.session, ident.span, E0469, "imported macro not found"); + span_err!(self.r.session, ident.span, E0469, "imported macro not found"); } } } @@ -909,9 +1047,9 @@ impl<'a> Resolver<'a> { for attr in attrs { if attr.check_name(sym::macro_escape) { let msg = "macro_escape is a deprecated synonym for macro_use"; - let mut err = self.session.struct_span_warn(attr.span, msg); + let mut err = self.r.session.struct_span_warn(attr.span, msg); if let ast::AttrStyle::Inner = attr.style { - err.help("consider an outer attribute, #[macro_use] mod ...").emit(); + err.help("consider an outer attribute, `#[macro_use]` mod ...").emit(); } else { err.emit(); } @@ -920,35 +1058,106 @@ impl<'a> Resolver<'a> { } if !attr.is_word() { - self.session.span_err(attr.span, "arguments to macro_use are not allowed here"); + self.r.session.span_err(attr.span, "arguments to macro_use are not allowed here"); } return true; } false } -} -pub struct BuildReducedGraphVisitor<'a, 'b> { - pub resolver: &'a mut Resolver<'b>, - pub current_legacy_scope: LegacyScope<'b>, - pub expansion: Mark, -} + fn visit_invoc(&mut self, id: ast::NodeId) -> &'a InvocationData<'a> { + let invoc_id = id.placeholder_to_expn_id(); -impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { - fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> { - let mark = id.placeholder_to_mark(); - self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark); - let invocation = self.resolver.invocations[&mark]; - invocation.module.set(self.resolver.current_module); - invocation.parent_legacy_scope.set(self.current_legacy_scope); - invocation + self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); + + let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData { + module: self.parent_scope.module, + parent_legacy_scope: self.parent_scope.legacy, + output_legacy_scope: Cell::new(None), + }); + let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data); + assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation"); + + invocation_data + } + + fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> { + if attr::contains_name(&item.attrs, sym::proc_macro) { + return Some((MacroKind::Bang, item.ident, item.span)); + } else if attr::contains_name(&item.attrs, sym::proc_macro_attribute) { + return Some((MacroKind::Attr, item.ident, item.span)); + } else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) { + if let Some(nested_meta) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) { + if let Some(ident) = nested_meta.ident() { + return Some((MacroKind::Derive, ident, ident.span)); + } + } + } + None + } + + fn define_macro(&mut self, item: &ast::Item) -> LegacyScope<'a> { + let parent_scope = &self.parent_scope; + let expansion = parent_scope.expansion; + let (ext, ident, span, is_legacy) = match &item.node { + ItemKind::MacroDef(def) => { + let ext = self.r.compile_macro(item, self.r.session.edition()); + (ext, item.ident, item.span, def.legacy) + } + ItemKind::Fn(..) => match Self::proc_macro_stub(item) { + Some((macro_kind, ident, span)) => { + self.r.proc_macro_stubs.insert(item.id); + (self.r.dummy_ext(macro_kind), ident, span, false) + } + None => return parent_scope.legacy, + } + _ => unreachable!(), + }; + + let def_id = self.r.definitions.local_def_id(item.id); + let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id); + self.r.macro_map.insert(def_id, ext); + self.r.local_macro_def_scopes.insert(item.id, parent_scope.module); + + if is_legacy { + let ident = ident.modern(); + self.r.macro_names.insert(ident); + let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export); + let vis = if is_macro_export { + ty::Visibility::Public + } else { + ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + }; + let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); + self.r.set_binding_parent_module(binding, parent_scope.module); + self.r.all_macros.insert(ident.name, res); + if is_macro_export { + let module = self.r.graph_root; + self.r.define(module, ident, MacroNS, + (res, vis, span, expansion, IsMacroExport)); + } else { + self.r.check_reserved_macro_name(ident, res); + self.r.unused_macros.insert(item.id, span); + } + LegacyScope::Binding(self.r.arenas.alloc_legacy_binding(LegacyBinding { + parent_legacy_scope: parent_scope.legacy, binding, ident + })) + } else { + let module = parent_scope.module; + let vis = self.resolve_visibility(&item.vis); + if vis != ty::Visibility::Public { + self.r.unused_macros.insert(item.id, span); + } + self.r.define(module, ident, MacroNS, (res, vis, span, expansion)); + self.parent_scope.legacy + } } } macro_rules! method { ($visit:ident: $ty:ty, $invoc:path, $walk:ident) => { - fn $visit(&mut self, node: &'a $ty) { + fn $visit(&mut self, node: &'b $ty) { if let $invoc(..) = node.node { self.visit_invoc(node.id); } else { @@ -958,71 +1167,65 @@ macro_rules! method { } } -impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { +impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { method!(visit_impl_item: ast::ImplItem, ast::ImplItemKind::Macro, walk_impl_item); method!(visit_expr: ast::Expr, ast::ExprKind::Mac, walk_expr); method!(visit_pat: ast::Pat, ast::PatKind::Mac, walk_pat); method!(visit_ty: ast::Ty, ast::TyKind::Mac, walk_ty); - fn visit_item(&mut self, item: &'a Item) { + fn visit_item(&mut self, item: &'b Item) { let macro_use = match item.node { ItemKind::MacroDef(..) => { - self.resolver.define_macro(item, self.expansion, &mut self.current_legacy_scope); + self.parent_scope.legacy = self.define_macro(item); return } ItemKind::Mac(..) => { - self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(item.id)); + self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id)); return } - ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs), + ItemKind::Mod(..) => self.contains_macro_use(&item.attrs), _ => false, }; - let orig_current_module = self.resolver.current_module; - let orig_current_legacy_scope = self.current_legacy_scope; - let parent_scope = ParentScope { - module: self.resolver.current_module, - expansion: self.expansion, - legacy: self.current_legacy_scope, - derives: Vec::new(), - }; - self.resolver.build_reduced_graph_for_item(item, parent_scope); + let orig_current_module = self.parent_scope.module; + let orig_current_legacy_scope = self.parent_scope.legacy; + self.build_reduced_graph_for_item(item); visit::walk_item(self, item); - self.resolver.current_module = orig_current_module; + self.parent_scope.module = orig_current_module; if !macro_use { - self.current_legacy_scope = orig_current_legacy_scope; + self.parent_scope.legacy = orig_current_legacy_scope; } } - fn visit_stmt(&mut self, stmt: &'a ast::Stmt) { + fn visit_stmt(&mut self, stmt: &'b ast::Stmt) { if let ast::StmtKind::Mac(..) = stmt.node { - self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(stmt.id)); + self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id)); } else { visit::walk_stmt(self, stmt); } } - fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) { + fn visit_foreign_item(&mut self, foreign_item: &'b ForeignItem) { if let ForeignItemKind::Macro(_) = foreign_item.node { self.visit_invoc(foreign_item.id); return; } - self.resolver.build_reduced_graph_for_foreign_item(foreign_item, self.expansion); + self.build_reduced_graph_for_foreign_item(foreign_item); visit::walk_foreign_item(self, foreign_item); } - fn visit_block(&mut self, block: &'a Block) { - let orig_current_module = self.resolver.current_module; - let orig_current_legacy_scope = self.current_legacy_scope; - self.resolver.build_reduced_graph_for_block(block, self.expansion); + fn visit_block(&mut self, block: &'b Block) { + let orig_current_module = self.parent_scope.module; + let orig_current_legacy_scope = self.parent_scope.legacy; + self.build_reduced_graph_for_block(block); visit::walk_block(self, block); - self.resolver.current_module = orig_current_module; - self.current_legacy_scope = orig_current_legacy_scope; + self.parent_scope.module = orig_current_module; + self.parent_scope.legacy = orig_current_legacy_scope; } - fn visit_trait_item(&mut self, item: &'a TraitItem) { - let parent = self.resolver.current_module; + fn visit_trait_item(&mut self, item: &'b TraitItem) { + let parent = self.parent_scope.module; if let TraitItemKind::Macro(_) = item.node { self.visit_invoc(item.id); @@ -1030,12 +1233,12 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { } // Add the item to the trait info. - let item_def_id = self.resolver.definitions.local_def_id(item.id); + let item_def_id = self.r.definitions.local_def_id(item.id); let (res, ns) = match item.node { TraitItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), TraitItemKind::Method(ref sig, _) => { if sig.decl.has_self() { - self.resolver.has_self.insert(item_def_id); + self.r.has_self.insert(item_def_id); } (Res::Def(DefKind::Method, item_def_id), ValueNS) } @@ -1044,11 +1247,12 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { }; let vis = ty::Visibility::Public; - self.resolver.define(parent, item.ident, ns, (res, vis, item.span, self.expansion)); + let expansion = self.parent_scope.expansion; + self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion)); - self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor + self.parent_scope.module = parent.parent.unwrap(); // nearest normal ancestor visit::walk_trait_item(self, item); - self.resolver.current_module = parent; + self.parent_scope.module = parent; } fn visit_token(&mut self, t: Token) { @@ -1061,17 +1265,10 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { } } - fn visit_attribute(&mut self, attr: &'a ast::Attribute) { + fn visit_attribute(&mut self, attr: &'b ast::Attribute) { if !attr.is_sugared_doc && is_builtin_attr(attr) { - let parent_scope = ParentScope { - module: self.resolver.current_module.nearest_item_scope(), - expansion: self.expansion, - legacy: self.current_legacy_scope, - // Let's hope discerning built-in attributes from derive helpers is not necessary - derives: Vec::new(), - }; - parent_scope.module.builtin_attrs.borrow_mut().push(( - attr.path.segments[0].ident, parent_scope + self.parent_scope.module.builtin_attrs.borrow_mut().push(( + attr.path.segments[0].ident, self.parent_scope.clone() )); } visit::walk_attribute(self, attr); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 4fee15c59b..96d44b4b4c 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -23,8 +23,6 @@ // - `check_crate` finally emits the diagnostics based on the data generated // in the last step -use std::ops::{Deref, DerefMut}; - use crate::Resolver; use crate::resolve_imports::ImportDirectiveSubclass; @@ -49,7 +47,7 @@ impl<'a> UnusedImport<'a> { } struct UnusedImportCheckVisitor<'a, 'b> { - resolver: &'a mut Resolver<'b>, + r: &'a mut Resolver<'b>, /// All the (so far) unused imports, grouped path list unused_imports: NodeMap>, base_use_tree: Option<&'a ast::UseTree>, @@ -57,29 +55,14 @@ struct UnusedImportCheckVisitor<'a, 'b> { item_span: Span, } -// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver. -impl<'a, 'b> Deref for UnusedImportCheckVisitor<'a, 'b> { - type Target = Resolver<'b>; - - fn deref<'c>(&'c self) -> &'c Resolver<'b> { - &*self.resolver - } -} - -impl<'a, 'b> DerefMut for UnusedImportCheckVisitor<'a, 'b> { - fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> { - &mut *self.resolver - } -} - impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { // We have information about whether `use` (import) directives are actually // used now. If an import is not used at all, we signal a lint error. fn check_import(&mut self, id: ast::NodeId) { let mut used = false; - self.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns))); + self.r.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns))); if !used { - if self.maybe_unused_trait_imports.contains(&id) { + if self.r.maybe_unused_trait_imports.contains(&id) { // Check later. return; } @@ -87,7 +70,7 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { } else { // This trait import is definitely used, in a way other than // method resolution. - self.maybe_unused_trait_imports.remove(&id); + self.r.maybe_unused_trait_imports.remove(&id); if let Some(i) = self.unused_imports.get_mut(&self.base_id) { i.unused.remove(&id); } @@ -238,104 +221,102 @@ fn calc_unused_spans( } } -pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) { - for directive in resolver.potentially_unused_imports.iter() { - match directive.subclass { - _ if directive.used.get() || - directive.vis.get() == ty::Visibility::Public || - directive.span.is_dummy() => { - if let ImportDirectiveSubclass::MacroUse = directive.subclass { - if !directive.span.is_dummy() { - resolver.session.buffer_lint( - lint::builtin::MACRO_USE_EXTERN_CRATE, - directive.id, - directive.span, - "deprecated `#[macro_use]` directive used to \ - import macros should be replaced at use sites \ - with a `use` statement to import the macro \ - instead", - ); +impl Resolver<'_> { + crate fn check_unused(&mut self, krate: &ast::Crate) { + for directive in self.potentially_unused_imports.iter() { + match directive.subclass { + _ if directive.used.get() || + directive.vis.get() == ty::Visibility::Public || + directive.span.is_dummy() => { + if let ImportDirectiveSubclass::MacroUse = directive.subclass { + if !directive.span.is_dummy() { + self.session.buffer_lint( + lint::builtin::MACRO_USE_EXTERN_CRATE, + directive.id, + directive.span, + "deprecated `#[macro_use]` directive used to \ + import macros should be replaced at use sites \ + with a `use` statement to import the macro \ + instead", + ); + } } } + ImportDirectiveSubclass::ExternCrate { .. } => { + self.maybe_unused_extern_crates.push((directive.id, directive.span)); + } + ImportDirectiveSubclass::MacroUse => { + let lint = lint::builtin::UNUSED_IMPORTS; + let msg = "unused `#[macro_use]` import"; + self.session.buffer_lint(lint, directive.id, directive.span, msg); + } + _ => {} } - ImportDirectiveSubclass::ExternCrate { .. } => { - resolver.maybe_unused_extern_crates.push((directive.id, directive.span)); - } - ImportDirectiveSubclass::MacroUse => { - let lint = lint::builtin::UNUSED_IMPORTS; - let msg = "unused `#[macro_use]` import"; - resolver.session.buffer_lint(lint, directive.id, directive.span, msg); - } - _ => {} } - } - - for (id, span) in resolver.unused_labels.iter() { - resolver.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label"); - } - let mut visitor = UnusedImportCheckVisitor { - resolver, - unused_imports: Default::default(), - base_use_tree: None, - base_id: ast::DUMMY_NODE_ID, - item_span: DUMMY_SP, - }; - visit::walk_crate(&mut visitor, krate); - - for unused in visitor.unused_imports.values() { - let mut fixes = Vec::new(); - let mut spans = match calc_unused_spans(unused, unused.use_tree, unused.use_tree_id) { - UnusedSpanResult::Used => continue, - UnusedSpanResult::FlatUnused(span, remove) => { - fixes.push((remove, String::new())); - vec![span] - } - UnusedSpanResult::NestedFullUnused(spans, remove) => { - fixes.push((remove, String::new())); - spans - } - UnusedSpanResult::NestedPartialUnused(spans, remove) => { - for fix in &remove { - fixes.push((*fix, String::new())); - } - spans - } + let mut visitor = UnusedImportCheckVisitor { + r: self, + unused_imports: Default::default(), + base_use_tree: None, + base_id: ast::DUMMY_NODE_ID, + item_span: DUMMY_SP, }; + visit::walk_crate(&mut visitor, krate); - let len = spans.len(); - spans.sort(); - let ms = MultiSpan::from_spans(spans.clone()); - let mut span_snippets = spans.iter() - .filter_map(|s| { - match visitor.session.source_map().span_to_snippet(*s) { - Ok(s) => Some(format!("`{}`", s)), - _ => None, + for unused in visitor.unused_imports.values() { + let mut fixes = Vec::new(); + let mut spans = match calc_unused_spans(unused, unused.use_tree, unused.use_tree_id) { + UnusedSpanResult::Used => continue, + UnusedSpanResult::FlatUnused(span, remove) => { + fixes.push((remove, String::new())); + vec![span] } - }).collect::>(); - span_snippets.sort(); - let msg = format!("unused import{}{}", - if len > 1 { "s" } else { "" }, - if !span_snippets.is_empty() { - format!(": {}", span_snippets.join(", ")) - } else { - String::new() - }); + UnusedSpanResult::NestedFullUnused(spans, remove) => { + fixes.push((remove, String::new())); + spans + } + UnusedSpanResult::NestedPartialUnused(spans, remove) => { + for fix in &remove { + fixes.push((*fix, String::new())); + } + spans + } + }; - let fix_msg = if fixes.len() == 1 && fixes[0].0 == unused.item_span { - "remove the whole `use` item" - } else if spans.len() > 1 { - "remove the unused imports" - } else { - "remove the unused import" - }; + let len = spans.len(); + spans.sort(); + let ms = MultiSpan::from_spans(spans.clone()); + let mut span_snippets = spans.iter() + .filter_map(|s| { + match visitor.r.session.source_map().span_to_snippet(*s) { + Ok(s) => Some(format!("`{}`", s)), + _ => None, + } + }).collect::>(); + span_snippets.sort(); + let msg = format!("unused import{}{}", + if len > 1 { "s" } else { "" }, + if !span_snippets.is_empty() { + format!(": {}", span_snippets.join(", ")) + } else { + String::new() + }); - visitor.session.buffer_lint_with_diagnostic( - lint::builtin::UNUSED_IMPORTS, - unused.use_tree_id, - ms, - &msg, - lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), - ); + let fix_msg = if fixes.len() == 1 && fixes[0].0 == unused.item_span { + "remove the whole `use` item" + } else if spans.len() > 1 { + "remove the unused imports" + } else { + "remove the unused import" + }; + + visitor.r.session.buffer_lint_with_diagnostic( + lint::builtin::UNUSED_IMPORTS, + unused.use_tree_id, + ms, + &msg, + lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), + ); + } } } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index e93a2315ca..1de67edb95 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -2,442 +2,643 @@ use std::cmp::Reverse; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use log::debug; -use rustc::hir::def::{self, DefKind, CtorKind, Namespace::*}; +use rustc::bug; +use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; +use rustc::hir::def::Namespace::{self, *}; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; -use rustc::session::{Session, config::nightly_options}; -use syntax::ast::{self, Expr, ExprKind, Ident}; +use rustc::session::Session; +use rustc::ty::{self, DefIdTree}; +use rustc::util::nodemap::FxHashSet; +use syntax::ast::{self, Ident, Path}; use syntax::ext::base::MacroKind; +use syntax::feature_gate::BUILTIN_ATTRIBUTES; +use syntax::source_map::SourceMap; +use syntax::struct_span_err; use syntax::symbol::{Symbol, kw}; -use syntax_pos::{BytePos, Span}; +use syntax::util::lev_distance::find_best_match_for_name; +use syntax_pos::{BytePos, Span, MultiSpan}; + +use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; +use crate::{path_names_to_string, KNOWN_TOOLS}; +use crate::{BindingError, CrateLint, LegacyScope, Module, ModuleOrUniformRoot}; +use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment}; type Res = def::Res; -use crate::macros::ParentScope; -use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; -use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string}; -use crate::{AssocSuggestion, CrateLint, ImportSuggestion, ModuleOrUniformRoot, PathResult, - PathSource, Resolver, Segment, Suggestion}; +/// A vector of spans and replacements, a message and applicability. +crate type Suggestion = (Vec<(Span, String)>, String, Applicability); -impl<'a> Resolver<'a> { - /// Handles error reporting for `smart_resolve_path_fragment` function. - /// Creates base error and amends it with one short label and possibly some longer helps/notes. - pub(crate) fn smart_resolve_report_errors( - &mut self, - path: &[Segment], - span: Span, - source: PathSource<'_>, - res: Option, - ) -> (DiagnosticBuilder<'a>, Vec) { - let ident_span = path.last().map_or(span, |ident| ident.ident.span); - let ns = source.namespace(); - let is_expected = &|res| source.is_expected(res); - let is_enum_variant = &|res| { - if let Res::Def(DefKind::Variant, _) = res { true } else { false } - }; +crate struct TypoSuggestion { + pub candidate: Symbol, + pub res: Res, +} - // Make the base error. - let expected = source.descr_expected(); - let path_str = Segment::names_to_string(path); - let item_str = path.last().unwrap().ident; - let code = source.error_code(res.is_some()); - let (base_msg, fallback_label, base_span) = if let Some(res) = res { - (format!("expected {}, found {} `{}`", expected, res.descr(), path_str), - format!("not a {}", expected), - span) - } else { - let item_span = path.last().unwrap().ident.span; - let (mod_prefix, mod_str) = if path.len() == 1 { - (String::new(), "this scope".to_string()) - } else if path.len() == 2 && path[0].ident.name == kw::PathRoot { - (String::new(), "the crate root".to_string()) - } else { - let mod_path = &path[..path.len() - 1]; - let mod_prefix = match self.resolve_path_without_parent_scope( - mod_path, Some(TypeNS), false, span, CrateLint::No - ) { - PathResult::Module(ModuleOrUniformRoot::Module(module)) => - module.def_kind(), - _ => None, - }.map_or(String::new(), |kind| format!("{} ", kind.descr())); - (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) - }; - (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), - format!("not found in {}", mod_str), - item_span) - }; +impl TypoSuggestion { + crate fn from_res(candidate: Symbol, res: Res) -> TypoSuggestion { + TypoSuggestion { candidate, res } + } +} - let code = DiagnosticId::Error(code.into()); - let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code); +/// A free importable items suggested in case of resolution failure. +crate struct ImportSuggestion { + pub did: Option, + pub path: Path, +} - // Emit help message for fake-self from other languages (e.g., `this` in Javascript). - if ["this", "my"].contains(&&*item_str.as_str()) - && self.self_value_is_available(path[0].ident.span, span) { - err.span_suggestion( - span, - "did you mean", - "self".to_string(), - Applicability::MaybeIncorrect, - ); - } +/// Adjust the impl span so that just the `impl` keyword is taken by removing +/// everything after `<` (`"impl Iterator for A {}" -> "impl"`) and +/// everything after the first whitespace (`"impl Iterator for A" -> "impl"`). +/// +/// *Attention*: the method used is very fragile since it essentially duplicates the work of the +/// parser. If you need to use this function or something similar, please consider updating the +/// `source_map` functions and this function to something more robust. +fn reduce_impl_span_to_impl_keyword(cm: &SourceMap, impl_span: Span) -> Span { + let impl_span = cm.span_until_char(impl_span, '<'); + let impl_span = cm.span_until_whitespace(impl_span); + impl_span +} - // Emit special messages for unresolved `Self` and `self`. - if is_self_type(path, ns) { - __diagnostic_used!(E0411); - err.code(DiagnosticId::Error("E0411".into())); - err.span_label(span, format!("`Self` is only available in impls, traits, \ - and type definitions")); - return (err, Vec::new()); - } - if is_self_value(path, ns) { - debug!("smart_resolve_path_fragment: E0424, source={:?}", source); - - __diagnostic_used!(E0424); - err.code(DiagnosticId::Error("E0424".into())); - err.span_label(span, match source { - PathSource::Pat => { - format!("`self` value is a keyword \ - and may not be bound to \ - variables or shadowed") - } - _ => { - format!("`self` value is a keyword \ - only available in methods \ - with `self` parameter") - } - }); - return (err, Vec::new()); +crate fn add_typo_suggestion( + err: &mut DiagnosticBuilder<'_>, suggestion: Option, span: Span +) -> bool { + if let Some(suggestion) = suggestion { + let msg = format!( + "{} {} with a similar name exists", suggestion.res.article(), suggestion.res.descr() + ); + err.span_suggestion( + span, &msg, suggestion.candidate.to_string(), Applicability::MaybeIncorrect + ); + return true; + } + false +} + +crate fn add_module_candidates( + module: Module<'_>, names: &mut Vec, filter_fn: &impl Fn(Res) -> bool +) { + for (&(ident, _), resolution) in module.resolutions.borrow().iter() { + if let Some(binding) = resolution.borrow().binding { + let res = binding.res(); + if filter_fn(res) { + names.push(TypoSuggestion::from_res(ident.name, res)); + } } + } +} - // Try to lookup name in more relaxed fashion for better error reporting. - let ident = path.last().unwrap().ident; - let candidates = self.lookup_import_candidates(ident, ns, is_expected) - .drain(..) - .filter(|ImportSuggestion { did, .. }| { - match (did, res.and_then(|res| res.opt_def_id())) { - (Some(suggestion_did), Some(actual_did)) => *suggestion_did != actual_did, - _ => true, - } - }) - .collect::>(); - let crate_def_id = DefId::local(CRATE_DEF_INDEX); - if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) { - let enum_candidates = - self.lookup_import_candidates(ident, ns, is_enum_variant); - let mut enum_candidates = enum_candidates.iter() - .map(|suggestion| { - import_candidate_to_enum_paths(&suggestion) - }).collect::>(); - enum_candidates.sort(); - - if !enum_candidates.is_empty() { - // Contextualize for E0412 "cannot find type", but don't belabor the point - // (that it's a variant) for E0573 "expected type, found variant". - let preamble = if res.is_none() { - let others = match enum_candidates.len() { - 1 => String::new(), - 2 => " and 1 other".to_owned(), - n => format!(" and {} others", n) - }; - format!("there is an enum variant `{}`{}; ", - enum_candidates[0].0, others) - } else { - String::new() - }; - let msg = format!("{}try using the variant's enum", preamble); +impl<'a> Resolver<'a> { + /// Combines an error with provided span and emits it. + /// + /// This takes the error provided, combines it with the span and any additional spans inside the + /// error and emits it. + crate fn report_error(&self, span: Span, resolution_error: ResolutionError<'_>) { + self.into_struct_error(span, resolution_error).emit(); + } - err.span_suggestions( + crate fn into_struct_error( + &self, span: Span, resolution_error: ResolutionError<'_> + ) -> DiagnosticBuilder<'_> { + match resolution_error { + ResolutionError::GenericParamsFromOuterFunction(outer_res) => { + let mut err = struct_span_err!(self.session, span, - &msg, - enum_candidates.into_iter() - .map(|(_variant_path, enum_ty_path)| enum_ty_path) - // Variants re-exported in prelude doesn't mean `prelude::v1` is the - // type name! - // FIXME: is there a more principled way to do this that - // would work for other re-exports? - .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1") - // Also write `Option` rather than `std::prelude::v1::Option`. - .map(|enum_ty_path| { - // FIXME #56861: DRY-er prelude filtering. - enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned() - }), - Applicability::MachineApplicable, + E0401, + "can't use generic parameters from outer function", ); - } - } - if path.len() == 1 && self.self_type_is_available(span) { - if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { - let self_is_available = self.self_value_is_available(path[0].ident.span, span); - match candidate { - AssocSuggestion::Field => { - if self_is_available { - err.span_suggestion( - span, - "you might have meant to use the available field", - format!("self.{}", path_str), - Applicability::MachineApplicable, - ); - } else { + err.span_label(span, format!("use of generic parameter from outer function")); + + let cm = self.session.source_map(); + match outer_res { + Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => { + if let Some(impl_span) = maybe_impl_defid.and_then(|def_id| { + self.definitions.opt_span(def_id) + }) { err.span_label( - span, - "a field by this name exists in `Self`", + reduce_impl_span_to_impl_keyword(cm, impl_span), + "`Self` type implicitly declared here, by this `impl`", ); } + match (maybe_trait_defid, maybe_impl_defid) { + (Some(_), None) => { + err.span_label(span, "can't use `Self` here"); + } + (_, Some(_)) => { + err.span_label(span, "use a type here instead"); + } + (None, None) => bug!("`impl` without trait nor type?"), + } + return err; + }, + Res::Def(DefKind::TyParam, def_id) => { + if let Some(span) = self.definitions.opt_span(def_id) { + err.span_label(span, "type parameter from outer function"); + } } - AssocSuggestion::MethodWithSelf if self_is_available => { - err.span_suggestion( - span, - "try", - format!("self.{}", path_str), - Applicability::MachineApplicable, - ); + Res::Def(DefKind::ConstParam, def_id) => { + if let Some(span) = self.definitions.opt_span(def_id) { + err.span_label(span, "const parameter from outer function"); + } } - AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => { - err.span_suggestion( - span, - "try", - format!("Self::{}", path_str), - Applicability::MachineApplicable, - ); + _ => { + bug!("GenericParamsFromOuterFunction should only be used with Res::SelfTy, \ + DefKind::TyParam"); } } - return (err, candidates); - } - } - let mut levenshtein_worked = false; - - // Try Levenshtein algorithm. - let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span); - if let Some(suggestion) = suggestion { - let msg = format!( - "{} {} with a similar name exists", - suggestion.article, suggestion.kind - ); - err.span_suggestion( - ident_span, - &msg, - suggestion.candidate.to_string(), - Applicability::MaybeIncorrect, - ); - - levenshtein_worked = true; - } + // Try to retrieve the span of the function signature and generate a new message + // with a local type or const parameter. + let sugg_msg = &format!("try using a local generic parameter instead"); + if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) { + // Suggest the modification to the user + err.span_suggestion( + sugg_span, + sugg_msg, + new_snippet, + Applicability::MachineApplicable, + ); + } else if let Some(sp) = cm.generate_fn_name_span(span) { + err.span_label(sp, + format!("try adding a local generic parameter in this method instead")); + } else { + err.help(&format!("try using a local generic parameter instead")); + } - // Try context-dependent help if relaxed lookup didn't work. - if let Some(res) = res { - if self.smart_resolve_context_dependent_help(&mut err, - span, - source, - res, - &path_str, - &fallback_label) { - return (err, candidates); + err } - } + ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => { + let mut err = struct_span_err!(self.session, + span, + E0403, + "the name `{}` is already used for a generic \ + parameter in this list of generic parameters", + name); + err.span_label(span, "already used"); + err.span_label(first_use_span, format!("first use of `{}`", name)); + err + } + ResolutionError::MethodNotMemberOfTrait(method, trait_) => { + let mut err = struct_span_err!(self.session, + span, + E0407, + "method `{}` is not a member of trait `{}`", + method, + trait_); + err.span_label(span, format!("not a member of trait `{}`", trait_)); + err + } + ResolutionError::TypeNotMemberOfTrait(type_, trait_) => { + let mut err = struct_span_err!(self.session, + span, + E0437, + "type `{}` is not a member of trait `{}`", + type_, + trait_); + err.span_label(span, format!("not a member of trait `{}`", trait_)); + err + } + ResolutionError::ConstNotMemberOfTrait(const_, trait_) => { + let mut err = struct_span_err!(self.session, + span, + E0438, + "const `{}` is not a member of trait `{}`", + const_, + trait_); + err.span_label(span, format!("not a member of trait `{}`", trait_)); + err + } + ResolutionError::VariableNotBoundInPattern(binding_error) => { + let BindingError { name, target, origin, could_be_path } = binding_error; - // Fallback label. - if !levenshtein_worked { - err.span_label(base_span, fallback_label); - self.type_ascription_suggestion(&mut err, base_span); - } - (err, candidates) - } + let target_sp = target.iter().copied().collect::>(); + let origin_sp = origin.iter().copied().collect::>(); - fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) { - // HACK(estebank): find a better way to figure out that this was a - // parser issue where a struct literal is being used on an expression - // where a brace being opened means a block is being started. Look - // ahead for the next text to see if `span` is followed by a `{`. - let sm = self.session.source_map(); - let mut sp = span; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet.chars().any(|c| { !c.is_whitespace() }) { - break; - } + let msp = MultiSpan::from_spans(target_sp.clone()); + let msg = format!("variable `{}` is not bound in all patterns", name); + let mut err = self.session.struct_span_err_with_code( + msp, + &msg, + DiagnosticId::Error("E0408".into()), + ); + for sp in target_sp { + err.span_label(sp, format!("pattern doesn't bind `{}`", name)); + } + for sp in origin_sp { + err.span_label(sp, "variable not in all patterns"); + } + if *could_be_path { + let help_msg = format!( + "if you meant to match on a variant or a `const` item, consider \ + making the path in the pattern qualified: `?::{}`", + name, + ); + err.span_help(span, &help_msg); } - _ => break, + err } - } - let followed_by_brace = match sm.span_to_snippet(sp) { - Ok(ref snippet) if snippet == "{" => true, - _ => false, - }; - // In case this could be a struct literal that needs to be surrounded - // by parenthesis, find the appropriate span. - let mut i = 0; - let mut closing_brace = None; - loop { - sp = sm.next_point(sp); - match sm.span_to_snippet(sp) { - Ok(ref snippet) => { - if snippet == "}" { - let sp = span.to(sp); - if let Ok(snippet) = sm.span_to_snippet(sp) { - closing_brace = Some((sp, snippet)); - } - break; - } + ResolutionError::VariableBoundWithDifferentMode(variable_name, + first_binding_span) => { + let mut err = struct_span_err!(self.session, + span, + E0409, + "variable `{}` is bound in inconsistent \ + ways within the same match arm", + variable_name); + err.span_label(span, "bound in different ways"); + err.span_label(first_binding_span, "first binding"); + err + } + ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => { + let mut err = struct_span_err!(self.session, + span, + E0415, + "identifier `{}` is bound more than once in this parameter list", + identifier); + err.span_label(span, "used as parameter more than once"); + err + } + ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => { + let mut err = struct_span_err!(self.session, + span, + E0416, + "identifier `{}` is bound more than once in the same pattern", + identifier); + err.span_label(span, "used in a pattern more than once"); + err + } + ResolutionError::UndeclaredLabel(name, lev_candidate) => { + let mut err = struct_span_err!(self.session, + span, + E0426, + "use of undeclared label `{}`", + name); + if let Some(lev_candidate) = lev_candidate { + err.span_suggestion( + span, + "a label with a similar name exists in this scope", + lev_candidate.to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label(span, format!("undeclared label `{}`", name)); } - _ => break, + err } - i += 1; - // The bigger the span, the more likely we're incorrect -- - // bound it to 100 chars long. - if i > 100 { - break; + ResolutionError::SelfImportsOnlyAllowedWithin => { + struct_span_err!(self.session, + span, + E0429, + "{}", + "`self` imports are only allowed within a { } list") } - } - return (followed_by_brace, closing_brace) - } - - /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment` - /// function. - /// Returns `true` if able to provide context-dependent help. - fn smart_resolve_context_dependent_help( - &mut self, - err: &mut DiagnosticBuilder<'a>, - span: Span, - source: PathSource<'_>, - res: Res, - path_str: &str, - fallback_label: &str, - ) -> bool { - let ns = source.namespace(); - let is_expected = &|res| source.is_expected(res); - - let path_sep = |err: &mut DiagnosticBuilder<'_>, expr: &Expr| match expr.node { - ExprKind::Field(_, ident) => { - err.span_suggestion( - expr.span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, ident), - Applicability::MaybeIncorrect, - ); - true + ResolutionError::SelfImportCanOnlyAppearOnceInTheList => { + let mut err = struct_span_err!(self.session, span, E0430, + "`self` import can only appear once in an import list"); + err.span_label(span, "can only appear once in an import list"); + err } - ExprKind::MethodCall(ref segment, ..) => { - let span = expr.span.with_hi(segment.ident.span.hi()); - err.span_suggestion( - span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, segment.ident), - Applicability::MaybeIncorrect, - ); - true + ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => { + let mut err = struct_span_err!(self.session, span, E0431, + "`self` import can only appear in an import list with \ + a non-empty prefix"); + err.span_label(span, "can only appear in an import list with a non-empty prefix"); + err } - _ => false, - }; + ResolutionError::FailedToResolve { label, suggestion } => { + let mut err = struct_span_err!(self.session, span, E0433, + "failed to resolve: {}", &label); + err.span_label(span, label); - let mut bad_struct_syntax_suggestion = || { - let (followed_by_brace, closing_brace) = self.followed_by_brace(span); - let mut suggested = false; - match source { - PathSource::Expr(Some(parent)) => { - suggested = path_sep(err, &parent); + if let Some((suggestions, msg, applicability)) = suggestion { + err.multipart_suggestion(&msg, suggestions, applicability); } - PathSource::Expr(None) if followed_by_brace == true => { - if let Some((sp, snippet)) = closing_brace { - err.span_suggestion( - sp, - "surround the struct literal with parenthesis", - format!("({})", snippet), - Applicability::MaybeIncorrect, - ); - } else { - err.span_label( - span, // Note the parenthesis surrounding the suggestion below - format!("did you mean `({} {{ /* fields */ }})`?", path_str), - ); - } - suggested = true; - }, - _ => {} + + err + } + ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => { + let mut err = struct_span_err!(self.session, + span, + E0434, + "{}", + "can't capture dynamic environment in a fn item"); + err.help("use the `|| { ... }` closure form instead"); + err } - if !suggested { + ResolutionError::AttemptToUseNonConstantValueInConstant => { + let mut err = struct_span_err!(self.session, span, E0435, + "attempt to use a non-constant value in a constant"); + err.span_label(span, "non-constant value"); + err + } + ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => { + let res = binding.res(); + let shadows_what = res.descr(); + let mut err = struct_span_err!(self.session, span, E0530, "{}s cannot shadow {}s", + what_binding, shadows_what); + err.span_label(span, format!("cannot be named the same as {} {}", + res.article(), shadows_what)); + let participle = if binding.is_import() { "imported" } else { "defined" }; + let msg = format!("the {} `{}` is {} here", shadows_what, name, participle); + err.span_label(binding.span, msg); + err + } + ResolutionError::ForwardDeclaredTyParam => { + let mut err = struct_span_err!(self.session, span, E0128, + "type parameters with a default cannot use \ + forward declared identifiers"); err.span_label( + span, "defaulted type parameters cannot be forward declared".to_string()); + err + } + ResolutionError::ConstParamDependentOnTypeParam => { + let mut err = struct_span_err!( + self.session, span, - format!("did you mean `{} {{ /* fields */ }}`?", path_str), + E0671, + "const parameters cannot depend on type parameters" ); + err.span_label(span, format!("const parameter depends on type parameter")); + err } - }; + } + } - match (res, source) { - (Res::Def(DefKind::Macro(..), _), _) => { - err.span_suggestion( - span, - "use `!` to invoke the macro", - format!("{}!", path_str), - Applicability::MaybeIncorrect, - ); - if path_str == "try" && span.rust_2015() { - err.note("if you want the `try` keyword, you need to be in the 2018 edition"); + /// Lookup typo candidate in scope for a macro or import. + fn early_lookup_typo_candidate( + &mut self, + scope_set: ScopeSet, + parent_scope: &ParentScope<'a>, + ident: Ident, + filter_fn: &impl Fn(Res) -> bool, + ) -> Option { + let mut suggestions = Vec::new(); + self.visit_scopes(scope_set, parent_scope, ident, |this, scope, use_prelude, _| { + match scope { + Scope::DeriveHelpers => { + let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); + if filter_fn(res) { + for derive in &parent_scope.derives { + let parent_scope = + &ParentScope { derives: Vec::new(), ..*parent_scope }; + if let Ok((Some(ext), _)) = this.resolve_macro_path( + derive, Some(MacroKind::Derive), parent_scope, false, false + ) { + suggestions.extend(ext.helper_attrs.iter().map(|name| { + TypoSuggestion::from_res(*name, res) + })); + } + } + } } - } - (Res::Def(DefKind::TyAlias, _), PathSource::Trait(_)) => { - err.span_label(span, "type aliases cannot be used as traits"); - if nightly_options::is_nightly_build() { - err.note("did you mean to use a trait alias?"); + Scope::MacroRules(legacy_scope) => { + if let LegacyScope::Binding(legacy_binding) = legacy_scope { + let res = legacy_binding.binding.res(); + if filter_fn(res) { + suggestions.push( + TypoSuggestion::from_res(legacy_binding.ident.name, res) + ) + } + } } - } - (Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => { - if !path_sep(err, &parent) { - return false; + Scope::CrateRoot => { + let root_ident = Ident::new(kw::PathRoot, ident.span); + let root_module = this.resolve_crate_root(root_ident); + add_module_candidates(root_module, &mut suggestions, filter_fn); } - } - (Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct) - | (Res::Def(DefKind::Enum, def_id), PathSource::Expr(..)) => { - if let Some(variants) = self.collect_enum_variants(def_id) { - if !variants.is_empty() { - let msg = if variants.len() == 1 { - "try using the enum's variant" + Scope::Module(module) => { + add_module_candidates(module, &mut suggestions, filter_fn); + } + Scope::MacroUsePrelude => { + suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| { + let res = binding.res(); + if filter_fn(res) { + Some(TypoSuggestion::from_res(*name, res)) } else { - "try using one of the enum's variants" - }; - - err.span_suggestions( - span, - msg, - variants.iter().map(path_names_to_string), - Applicability::MaybeIncorrect, - ); + None + } + })); + } + Scope::BuiltinAttrs => { + let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin); + if filter_fn(res) { + suggestions.extend(BUILTIN_ATTRIBUTES.iter().map(|(name, ..)| { + TypoSuggestion::from_res(*name, res) + })); } - } else { - err.note("did you mean to use one of the enum's variants?"); } - }, - (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => { - if let Some((ctor_def, ctor_vis)) - = self.struct_constructors.get(&def_id).cloned() { - let accessible_ctor = self.is_accessible(ctor_vis); - if is_expected(ctor_def) && !accessible_ctor { - err.span_label( - span, - format!("constructor is not visible here due to private fields"), - ); + Scope::LegacyPluginHelpers => { + let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper); + if filter_fn(res) { + let plugin_attributes = this.session.plugin_attributes.borrow(); + suggestions.extend(plugin_attributes.iter().map(|(name, _)| { + TypoSuggestion::from_res(*name, res) + })); } - } else { - bad_struct_syntax_suggestion(); + } + Scope::ExternPrelude => { + suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| { + let res = Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)); + if filter_fn(res) { + Some(TypoSuggestion::from_res(ident.name, res)) + } else { + None + } + })); + } + Scope::ToolPrelude => { + let res = Res::NonMacroAttr(NonMacroAttrKind::Tool); + suggestions.extend(KNOWN_TOOLS.iter().map(|name| { + TypoSuggestion::from_res(*name, res) + })); + } + Scope::StdLibPrelude => { + if let Some(prelude) = this.prelude { + let mut tmp_suggestions = Vec::new(); + add_module_candidates(prelude, &mut tmp_suggestions, filter_fn); + suggestions.extend(tmp_suggestions.into_iter().filter(|s| { + use_prelude || this.is_builtin_macro(s.res.opt_def_id()) + })); + } + } + Scope::BuiltinTypes => { + let primitive_types = &this.primitive_type_table.primitive_types; + suggestions.extend( + primitive_types.iter().flat_map(|(name, prim_ty)| { + let res = Res::PrimTy(*prim_ty); + if filter_fn(res) { + Some(TypoSuggestion::from_res(*name, res)) + } else { + None + } + }) + ) } } - (Res::Def(DefKind::Union, _), _) | - (Res::Def(DefKind::Variant, _), _) | - (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => { - bad_struct_syntax_suggestion(); - } - (Res::SelfTy(..), _) if ns == ValueNS => { - err.span_label(span, fallback_label); - err.note("can't use `Self` as a constructor, you must use the implemented struct"); - } - (Res::Def(DefKind::TyAlias, _), _) - | (Res::Def(DefKind::AssocTy, _), _) if ns == ValueNS => { - err.note("can't use a type alias as a constructor"); + + None::<()> + }); + + // Make sure error reporting is deterministic. + suggestions.sort_by_cached_key(|suggestion| suggestion.candidate.as_str()); + + match find_best_match_for_name( + suggestions.iter().map(|suggestion| &suggestion.candidate), + &ident.as_str(), + None, + ) { + Some(found) if found != ident.name => suggestions + .into_iter() + .find(|suggestion| suggestion.candidate == found), + _ => None, + } + } + + fn lookup_import_candidates_from_module(&mut self, + lookup_ident: Ident, + namespace: Namespace, + start_module: Module<'a>, + crate_name: Ident, + filter_fn: FilterFn) + -> Vec + where FilterFn: Fn(Res) -> bool + { + let mut candidates = Vec::new(); + let mut seen_modules = FxHashSet::default(); + let not_local_module = crate_name.name != kw::Crate; + let mut worklist = vec![(start_module, Vec::::new(), not_local_module)]; + + while let Some((in_module, + path_segments, + in_module_is_extern)) = worklist.pop() { + self.populate_module_if_necessary(in_module); + + // We have to visit module children in deterministic order to avoid + // instabilities in reported imports (#43552). + in_module.for_each_child_stable(|ident, ns, name_binding| { + // avoid imports entirely + if name_binding.is_import() && !name_binding.is_extern_crate() { return; } + // avoid non-importable candidates as well + if !name_binding.is_importable() { return; } + + // collect results based on the filter function + if ident.name == lookup_ident.name && ns == namespace { + let res = name_binding.res(); + if filter_fn(res) { + // create the path + let mut segms = path_segments.clone(); + if lookup_ident.span.rust_2018() { + // crate-local absolute paths start with `crate::` in edition 2018 + // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660) + segms.insert( + 0, ast::PathSegment::from_ident(crate_name) + ); + } + + segms.push(ast::PathSegment::from_ident(ident)); + let path = Path { + span: name_binding.span, + segments: segms, + }; + // the entity is accessible in the following cases: + // 1. if it's defined in the same crate, it's always + // accessible (since private entities can be made public) + // 2. if it's defined in another crate, it's accessible + // only if both the module is public and the entity is + // declared as public (due to pruning, we don't explore + // outside crate private modules => no need to check this) + if !in_module_is_extern || name_binding.vis == ty::Visibility::Public { + let did = match res { + Res::Def(DefKind::Ctor(..), did) => self.parent(did), + _ => res.opt_def_id(), + }; + candidates.push(ImportSuggestion { did, path }); + } + } + } + + // collect submodules to explore + if let Some(module) = name_binding.module() { + // form the path + let mut path_segments = path_segments.clone(); + path_segments.push(ast::PathSegment::from_ident(ident)); + + let is_extern_crate_that_also_appears_in_prelude = + name_binding.is_extern_crate() && + lookup_ident.span.rust_2018(); + + let is_visible_to_user = + !in_module_is_extern || name_binding.vis == ty::Visibility::Public; + + if !is_extern_crate_that_also_appears_in_prelude && is_visible_to_user { + // add the module to the lookup + let is_extern = in_module_is_extern || name_binding.is_extern_crate(); + if seen_modules.insert(module.def_id().unwrap()) { + worklist.push((module, path_segments, is_extern)); + } + } + } + }) + } + + candidates + } + + /// When name resolution fails, this method can be used to look up candidate + /// entities with the expected name. It allows filtering them using the + /// supplied predicate (which should be used to only accept the types of + /// definitions expected, e.g., traits). The lookup spans across all crates. + /// + /// N.B., the method does not look into imports, but this is not a problem, + /// since we report the definitions (thus, the de-aliased imports). + crate fn lookup_import_candidates( + &mut self, lookup_ident: Ident, namespace: Namespace, filter_fn: FilterFn + ) -> Vec + where FilterFn: Fn(Res) -> bool + { + let mut suggestions = self.lookup_import_candidates_from_module( + lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn + ); + + if lookup_ident.span.rust_2018() { + let extern_prelude_names = self.extern_prelude.clone(); + for (ident, _) in extern_prelude_names.into_iter() { + if let Some(crate_id) = self.crate_loader.maybe_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); + + suggestions.extend(self.lookup_import_candidates_from_module( + lookup_ident, namespace, crate_root, ident, &filter_fn)); + } } - _ => return false, } - true + + suggestions + } + + crate fn unresolved_macro_suggestions( + &mut self, + err: &mut DiagnosticBuilder<'a>, + macro_kind: MacroKind, + parent_scope: &ParentScope<'a>, + ident: Ident, + ) { + let is_expected = &|res: Res| res.macro_kind() == Some(macro_kind); + let suggestion = self.early_lookup_typo_candidate( + ScopeSet::Macro(macro_kind), parent_scope, ident, is_expected + ); + add_typo_suggestion(err, suggestion, ident.span); + + if macro_kind == MacroKind::Derive && + (ident.as_str() == "Send" || ident.as_str() == "Sync") { + let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident); + err.span_note(ident.span, &msg); + } + if self.macro_names.contains(&ident.modern()) { + err.help("have you added the `#[macro_use]` on the module/import?"); + } } } @@ -486,7 +687,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ) -> Option<(Vec, Vec)> { // Replace first ident with `self` and check if that is valid. path[0].ident.name = kw::SelfLower; - let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, Vec::new())) @@ -510,7 +711,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ) -> Option<(Vec, Vec)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Crate; - let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some(( @@ -541,7 +742,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ) -> Option<(Vec, Vec)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Super; - let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, Vec::new())) @@ -574,13 +775,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // 1) some consistent ordering for emitted dignostics, and // 2) `std` suggestions before `core` suggestions. let mut extern_crate_names = - self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::>(); + self.r.extern_prelude.iter().map(|(ident, _)| ident.name).collect::>(); extern_crate_names.sort_by_key(|name| Reverse(name.as_str())); for name in extern_crate_names.into_iter() { // Replace first ident with a crate name and check if that is valid. path[0].ident.name = name; - let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); + let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result); if let PathResult::Module(..) = result { @@ -646,7 +847,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // ie. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( - self.resolver.session, directive.span, directive.use_span, + self.r.session, directive.span, directive.use_span, ); debug!("check_for_module_export_macro: found_closing_brace={:?} binding_span={:?}", found_closing_brace, binding_span); @@ -661,7 +862,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // ie. `use a::b::{c, d};` // ^^^ if let Some(previous_span) = extend_span_to_previous_binding( - self.resolver.session, binding_span, + self.r.session, binding_span, ) { debug!("check_for_module_export_macro: previous_span={:?}", previous_span); removal_span = removal_span.with_lo(previous_span.lo()); @@ -679,12 +880,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // or `use a::{b, c, d}};` // ^^^^^^^^^^^ let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( - self.resolver.session, module_name, directive.use_span, + self.r.session, module_name, directive.use_span, ); debug!("check_for_module_export_macro: has_nested={:?} after_crate_name={:?}", has_nested, after_crate_name); - let source_map = self.resolver.session.source_map(); + let source_map = self.r.session.source_map(); // Add the import to the start, with a `{` if required. let start_point = source_map.start_point(after_crate_name); @@ -871,3 +1072,55 @@ fn find_span_immediately_after_crate_name( (next_left_bracket == after_second_colon, from_second_colon) } + +/// When an entity with a given name is not available in scope, we search for +/// entities with that name in all crates. This method allows outputting the +/// results of this search in a programmer-friendly way +crate fn show_candidates( + err: &mut DiagnosticBuilder<'_>, + // This is `None` if all placement locations are inside expansions + span: Option, + candidates: &[ImportSuggestion], + better: bool, + found_use: bool, +) { + // we want consistent results across executions, but candidates are produced + // by iterating through a hash map, so make sure they are ordered: + let mut path_strings: Vec<_> = + candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect(); + path_strings.sort(); + + let better = if better { "better " } else { "" }; + let msg_diff = match path_strings.len() { + 1 => " is found in another module, you can import it", + _ => "s are found in other modules, you can import them", + }; + let msg = format!("possible {}candidate{} into scope", better, msg_diff); + + if let Some(span) = span { + for candidate in &mut path_strings { + // produce an additional newline to separate the new use statement + // from the directly following item. + let additional_newline = if found_use { + "" + } else { + "\n" + }; + *candidate = format!("use {};\n{}", candidate, additional_newline); + } + + err.span_suggestions( + span, + &msg, + path_strings.into_iter(), + Applicability::Unspecified, + ); + } else { + let mut msg = msg; + msg.push(':'); + for candidate in path_strings { + msg.push('\n'); + msg.push_str(&candidate); + } + } +} diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs index 7cd26dce14..e01f53786e 100644 --- a/src/librustc_resolve/error_codes.rs +++ b/src/librustc_resolve/error_codes.rs @@ -1,6 +1,4 @@ -#![allow(non_snake_case)] - -use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics}; +use syntax::{register_diagnostics, register_long_diagnostics}; // Error messages for EXXXX errors. Each message should start and end with a // new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs new file mode 100644 index 0000000000..358eaae11e --- /dev/null +++ b/src/librustc_resolve/late.rs @@ -0,0 +1,1994 @@ +use GenericParameters::*; +use RibKind::*; + +use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding}; +use crate::{Module, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult}; +use crate::{ResolutionError, Resolver, Segment, UseError}; + +use log::debug; +use rustc::{bug, lint, span_bug}; +use rustc::hir::def::{self, PartialRes, DefKind, CtorKind, PerNS}; +use rustc::hir::def::Namespace::{self, *}; +use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc::hir::TraitCandidate; +use rustc::util::nodemap::FxHashMap; +use smallvec::{smallvec, SmallVec}; +use syntax::{unwrap_or, walk_list}; +use syntax::ast::*; +use syntax::ptr::P; +use syntax::symbol::{kw, sym}; +use syntax::util::lev_distance::find_best_match_for_name; +use syntax::visit::{self, Visitor, FnKind}; +use syntax_pos::Span; + +use std::collections::BTreeSet; +use std::mem::replace; + +mod diagnostics; + +type Res = def::Res; + +/// Map from the name in a pattern to its binding mode. +type BindingMap = FxHashMap; + +#[derive(Copy, Clone, Debug)] +struct BindingInfo { + span: Span, + binding_mode: BindingMode, +} + +#[derive(Copy, Clone)] +enum GenericParameters<'a, 'b> { + NoGenericParams, + HasGenericParams(// Type parameters. + &'b Generics, + + // The kind of the rib used for type parameters. + RibKind<'a>), +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum PatternSource { + Match, + Let, + For, + FnParam, +} + +impl PatternSource { + fn descr(self) -> &'static str { + match self { + PatternSource::Match => "match binding", + PatternSource::Let => "let binding", + PatternSource::For => "for binding", + PatternSource::FnParam => "function parameter", + } + } +} + +/// The rib kind restricts certain accesses, +/// e.g. to a `Res::Local` of an outer item. +#[derive(Copy, Clone, Debug)] +crate enum RibKind<'a> { + /// No restriction needs to be applied. + NormalRibKind, + + /// We passed through an impl or trait and are now in one of its + /// methods or associated types. Allow references to ty params that impl or trait + /// binds. Disallow any other upvars (including other ty params that are + /// upvars). + AssocItemRibKind, + + /// We passed through a function definition. Disallow upvars. + /// Permit only those const parameters that are specified in the function's generics. + FnItemRibKind, + + /// We passed through an item scope. Disallow upvars. + ItemRibKind, + + /// We're in a constant item. Can't refer to dynamic stuff. + ConstantItemRibKind, + + /// We passed through a module. + ModuleRibKind(Module<'a>), + + /// We passed through a `macro_rules!` statement + MacroDefinition(DefId), + + /// All bindings in this rib are type parameters that can't be used + /// from the default of a type parameter because they're not declared + /// before said type parameter. Also see the `visit_generics` override. + ForwardTyParamBanRibKind, + + /// We forbid the use of type parameters as the types of const parameters. + TyParamAsConstParamTy, +} + +/// A single local scope. +/// +/// A rib represents a scope names can live in. Note that these appear in many places, not just +/// around braces. At any place where the list of accessible names (of the given namespace) +/// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a +/// stack. This may be, for example, a `let` statement (because it introduces variables), a macro, +/// etc. +/// +/// Different [rib kinds](enum.RibKind) are transparent for different names. +/// +/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When +/// resolving, the name is looked up from inside out. +#[derive(Debug)] +crate struct Rib<'a, R = Res> { + pub bindings: FxHashMap, + pub kind: RibKind<'a>, +} + +impl<'a, R> Rib<'a, R> { + fn new(kind: RibKind<'a>) -> Rib<'a, R> { + Rib { + bindings: Default::default(), + kind, + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +crate enum AliasPossibility { + No, + Maybe, +} + +#[derive(Copy, Clone, Debug)] +crate enum PathSource<'a> { + // Type paths `Path`. + Type, + // Trait paths in bounds or impls. + Trait(AliasPossibility), + // Expression paths `path`, with optional parent context. + Expr(Option<&'a Expr>), + // Paths in path patterns `Path`. + Pat, + // Paths in struct expressions and patterns `Path { .. }`. + Struct, + // Paths in tuple struct patterns `Path(..)`. + TupleStruct, + // `m::A::B` in `::B::C`. + TraitItem(Namespace), +} + +impl<'a> PathSource<'a> { + fn namespace(self) -> Namespace { + match self { + PathSource::Type | PathSource::Trait(_) | PathSource::Struct => TypeNS, + PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS, + PathSource::TraitItem(ns) => ns, + } + } + + fn defer_to_typeck(self) -> bool { + match self { + PathSource::Type | PathSource::Expr(..) | PathSource::Pat | + PathSource::Struct | PathSource::TupleStruct => true, + PathSource::Trait(_) | PathSource::TraitItem(..) => false, + } + } + + fn descr_expected(self) -> &'static str { + match self { + PathSource::Type => "type", + PathSource::Trait(_) => "trait", + PathSource::Pat => "unit struct/variant or constant", + PathSource::Struct => "struct, variant or union type", + PathSource::TupleStruct => "tuple struct/variant", + PathSource::TraitItem(ns) => match ns { + TypeNS => "associated type", + ValueNS => "method or associated constant", + MacroNS => bug!("associated macro"), + }, + PathSource::Expr(parent) => match parent.map(|p| &p.node) { + // "function" here means "anything callable" rather than `DefKind::Fn`, + // this is not precise but usually more helpful than just "value". + Some(&ExprKind::Call(..)) => "function", + _ => "value", + }, + } + } + + crate fn is_expected(self, res: Res) -> bool { + match self { + PathSource::Type => match res { + Res::Def(DefKind::Struct, _) + | Res::Def(DefKind::Union, _) + | Res::Def(DefKind::Enum, _) + | Res::Def(DefKind::Trait, _) + | Res::Def(DefKind::TraitAlias, _) + | Res::Def(DefKind::TyAlias, _) + | Res::Def(DefKind::AssocTy, _) + | Res::PrimTy(..) + | Res::Def(DefKind::TyParam, _) + | Res::SelfTy(..) + | Res::Def(DefKind::OpaqueTy, _) + | Res::Def(DefKind::ForeignTy, _) => true, + _ => false, + }, + PathSource::Trait(AliasPossibility::No) => match res { + Res::Def(DefKind::Trait, _) => true, + _ => false, + }, + PathSource::Trait(AliasPossibility::Maybe) => match res { + Res::Def(DefKind::Trait, _) => true, + Res::Def(DefKind::TraitAlias, _) => true, + _ => false, + }, + PathSource::Expr(..) => match res { + Res::Def(DefKind::Ctor(_, CtorKind::Const), _) + | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) + | Res::Def(DefKind::Const, _) + | Res::Def(DefKind::Static, _) + | Res::Local(..) + | Res::Def(DefKind::Fn, _) + | Res::Def(DefKind::Method, _) + | Res::Def(DefKind::AssocConst, _) + | Res::SelfCtor(..) + | Res::Def(DefKind::ConstParam, _) => true, + _ => false, + }, + PathSource::Pat => match res { + Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | + Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) | + Res::SelfCtor(..) => true, + _ => false, + }, + PathSource::TupleStruct => match res { + Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..) => true, + _ => false, + }, + PathSource::Struct => match res { + Res::Def(DefKind::Struct, _) + | Res::Def(DefKind::Union, _) + | Res::Def(DefKind::Variant, _) + | Res::Def(DefKind::TyAlias, _) + | Res::Def(DefKind::AssocTy, _) + | Res::SelfTy(..) => true, + _ => false, + }, + PathSource::TraitItem(ns) => match res { + Res::Def(DefKind::AssocConst, _) + | Res::Def(DefKind::Method, _) if ns == ValueNS => true, + Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true, + _ => false, + }, + } + } + + fn error_code(self, has_unexpected_resolution: bool) -> &'static str { + __diagnostic_used!(E0404); + __diagnostic_used!(E0405); + __diagnostic_used!(E0412); + __diagnostic_used!(E0422); + __diagnostic_used!(E0423); + __diagnostic_used!(E0425); + __diagnostic_used!(E0531); + __diagnostic_used!(E0532); + __diagnostic_used!(E0573); + __diagnostic_used!(E0574); + __diagnostic_used!(E0575); + __diagnostic_used!(E0576); + match (self, has_unexpected_resolution) { + (PathSource::Trait(_), true) => "E0404", + (PathSource::Trait(_), false) => "E0405", + (PathSource::Type, true) => "E0573", + (PathSource::Type, false) => "E0412", + (PathSource::Struct, true) => "E0574", + (PathSource::Struct, false) => "E0422", + (PathSource::Expr(..), true) => "E0423", + (PathSource::Expr(..), false) => "E0425", + (PathSource::Pat, true) | (PathSource::TupleStruct, true) => "E0532", + (PathSource::Pat, false) | (PathSource::TupleStruct, false) => "E0531", + (PathSource::TraitItem(..), true) => "E0575", + (PathSource::TraitItem(..), false) => "E0576", + } + } +} + +struct LateResolutionVisitor<'a, 'b> { + r: &'b mut Resolver<'a>, + + /// The module that represents the current item scope. + parent_scope: ParentScope<'a>, + + /// The current set of local scopes for types and values. + /// FIXME #4948: Reuse ribs to avoid allocation. + ribs: PerNS>>, + + /// The current set of local scopes, for labels. + label_ribs: Vec>, + + /// The trait that the current context can refer to. + current_trait_ref: Option<(Module<'a>, TraitRef)>, + + /// The current trait's associated types' ident, used for diagnostic suggestions. + current_trait_assoc_types: Vec, + + /// The current self type if inside an impl (used for better errors). + current_self_type: Option, + + /// The current self item if inside an ADT (used for better errors). + current_self_item: Option, + + /// A list of labels as of yet unused. Labels will be removed from this map when + /// they are used (in a `break` or `continue` statement) + unused_labels: FxHashMap, + + /// Only used for better errors on `fn(): fn()`. + current_type_ascription: Vec, +} + +/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes. +impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { + fn visit_item(&mut self, item: &'tcx Item) { + self.resolve_item(item); + } + fn visit_arm(&mut self, arm: &'tcx Arm) { + self.resolve_arm(arm); + } + fn visit_block(&mut self, block: &'tcx Block) { + self.resolve_block(block); + } + fn visit_anon_const(&mut self, constant: &'tcx AnonConst) { + debug!("visit_anon_const {:?}", constant); + self.with_constant_rib(|this| { + visit::walk_anon_const(this, constant); + }); + } + fn visit_expr(&mut self, expr: &'tcx Expr) { + self.resolve_expr(expr, None); + } + fn visit_local(&mut self, local: &'tcx Local) { + self.resolve_local(local); + } + fn visit_ty(&mut self, ty: &'tcx Ty) { + match ty.node { + TyKind::Path(ref qself, ref path) => { + self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); + } + TyKind::ImplicitSelf => { + let self_ty = Ident::with_empty_ctxt(kw::SelfUpper); + let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span) + .map_or(Res::Err, |d| d.res()); + self.r.record_partial_res(ty.id, PartialRes::new(res)); + } + _ => (), + } + visit::walk_ty(self, ty); + } + fn visit_poly_trait_ref(&mut self, + tref: &'tcx PolyTraitRef, + m: &'tcx TraitBoundModifier) { + self.smart_resolve_path(tref.trait_ref.ref_id, None, + &tref.trait_ref.path, PathSource::Trait(AliasPossibility::Maybe)); + visit::walk_poly_trait_ref(self, tref, m); + } + fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) { + let generic_params = match foreign_item.node { + ForeignItemKind::Fn(_, ref generics) => { + HasGenericParams(generics, ItemRibKind) + } + ForeignItemKind::Static(..) => NoGenericParams, + ForeignItemKind::Ty => NoGenericParams, + ForeignItemKind::Macro(..) => NoGenericParams, + }; + self.with_generic_param_rib(generic_params, |this| { + visit::walk_foreign_item(this, foreign_item); + }); + } + fn visit_fn(&mut self, + function_kind: FnKind<'tcx>, + declaration: &'tcx FnDecl, + _: Span, + _: NodeId) + { + debug!("(resolving function) entering function"); + let rib_kind = match function_kind { + FnKind::ItemFn(..) => FnItemRibKind, + FnKind::Method(..) | FnKind::Closure(_) => NormalRibKind, + }; + + // Create a value rib for the function. + self.ribs[ValueNS].push(Rib::new(rib_kind)); + + // Create a label rib for the function. + self.label_ribs.push(Rib::new(rib_kind)); + + // Add each argument to the rib. + let mut bindings_list = FxHashMap::default(); + for argument in &declaration.inputs { + self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list); + + self.visit_ty(&argument.ty); + + debug!("(resolving function) recorded argument"); + } + visit::walk_fn_ret_ty(self, &declaration.output); + + // Resolve the function body, potentially inside the body of an async closure + match function_kind { + FnKind::ItemFn(.., body) | + FnKind::Method(.., body) => { + self.visit_block(body); + } + FnKind::Closure(body) => { + self.visit_expr(body); + } + }; + + debug!("(resolving function) leaving function"); + + self.label_ribs.pop(); + self.ribs[ValueNS].pop(); + } + + fn visit_generics(&mut self, generics: &'tcx Generics) { + // For type parameter defaults, we have to ban access + // to following type parameters, as the InternalSubsts can only + // provide previous type parameters as they're built. We + // put all the parameters on the ban list and then remove + // them one by one as they are processed and become available. + let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind); + let mut found_default = false; + default_ban_rib.bindings.extend(generics.params.iter() + .filter_map(|param| match param.kind { + GenericParamKind::Const { .. } | + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { ref default, .. } => { + found_default |= default.is_some(); + if found_default { + Some((Ident::with_empty_ctxt(param.ident.name), Res::Err)) + } else { + None + } + } + })); + + // We also ban access to type parameters for use as the types of const parameters. + let mut const_ty_param_ban_rib = Rib::new(TyParamAsConstParamTy); + const_ty_param_ban_rib.bindings.extend(generics.params.iter() + .filter(|param| { + if let GenericParamKind::Type { .. } = param.kind { + true + } else { + false + } + }) + .map(|param| (Ident::with_empty_ctxt(param.ident.name), Res::Err))); + + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => self.visit_generic_param(param), + GenericParamKind::Type { ref default, .. } => { + for bound in ¶m.bounds { + self.visit_param_bound(bound); + } + + if let Some(ref ty) = default { + self.ribs[TypeNS].push(default_ban_rib); + self.visit_ty(ty); + default_ban_rib = self.ribs[TypeNS].pop().unwrap(); + } + + // Allow all following defaults to refer to this type parameter. + default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name)); + } + GenericParamKind::Const { ref ty } => { + self.ribs[TypeNS].push(const_ty_param_ban_rib); + + for bound in ¶m.bounds { + self.visit_param_bound(bound); + } + + self.visit_ty(ty); + + const_ty_param_ban_rib = self.ribs[TypeNS].pop().unwrap(); + } + } + } + for p in &generics.where_clause.predicates { + self.visit_where_predicate(p); + } + } +} + +impl<'a, 'b> LateResolutionVisitor<'a, '_> { + fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> { + // During late resolution we only track the module component of the parent scope, + // although it may be useful to track other components as well for diagnostics. + let parent_scope = resolver.dummy_parent_scope(); + let graph_root = resolver.graph_root; + LateResolutionVisitor { + r: resolver, + parent_scope, + ribs: PerNS { + value_ns: vec![Rib::new(ModuleRibKind(graph_root))], + type_ns: vec![Rib::new(ModuleRibKind(graph_root))], + macro_ns: vec![Rib::new(ModuleRibKind(graph_root))], + }, + label_ribs: Vec::new(), + current_trait_ref: None, + current_trait_assoc_types: Vec::new(), + current_self_type: None, + current_self_item: None, + unused_labels: Default::default(), + current_type_ascription: Vec::new(), + } + } + + fn resolve_ident_in_lexical_scope(&mut self, + ident: Ident, + ns: Namespace, + record_used_id: Option, + path_span: Span) + -> Option> { + self.r.resolve_ident_in_lexical_scope( + ident, ns, &self.parent_scope, record_used_id, path_span, &self.ribs[ns] + ) + } + + fn resolve_path( + &mut self, + path: &[Segment], + opt_ns: Option, // `None` indicates a module path in import + record_used: bool, + path_span: Span, + crate_lint: CrateLint, + ) -> PathResult<'a> { + self.r.resolve_path_with_ribs( + path, opt_ns, &self.parent_scope, record_used, path_span, crate_lint, Some(&self.ribs) + ) + } + + // AST resolution + // + // We maintain a list of value ribs and type ribs. + // + // Simultaneously, we keep track of the current position in the module + // graph in the `parent_scope.module` pointer. When we go to resolve a name in + // the value or type namespaces, we first look through all the ribs and + // then query the module graph. When we resolve a name in the module + // namespace, we can skip all the ribs (since nested modules are not + // allowed within blocks in Rust) and jump straight to the current module + // graph node. + // + // Named implementations are handled separately. When we find a method + // call, we consult the module node to find all of the implementations in + // scope. This information is lazily cached in the module node. We then + // generate a fake "implementation scope" containing all the + // implementations thus found, for compatibility with old resolve pass. + + fn with_scope(&mut self, id: NodeId, f: F) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T + { + let id = self.r.definitions.local_def_id(id); + let module = self.r.module_map.get(&id).cloned(); // clones a reference + if let Some(module) = module { + // Move down in the graph. + let orig_module = replace(&mut self.parent_scope.module, module); + self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module))); + self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module))); + + self.r.finalize_current_module_macro_resolutions(module); + let ret = f(self); + + self.parent_scope.module = orig_module; + self.ribs[ValueNS].pop(); + self.ribs[TypeNS].pop(); + ret + } else { + f(self) + } + } + + /// Searches the current set of local scopes for labels. Returns the first non-`None` label that + /// is returned by the given predicate function + /// + /// Stops after meeting a closure. + fn search_label(&self, mut ident: Ident, pred: P) -> Option + where P: Fn(&Rib<'_, NodeId>, Ident) -> Option + { + for rib in self.label_ribs.iter().rev() { + match rib.kind { + NormalRibKind => {} + // If an invocation of this macro created `ident`, give up on `ident` + // and switch to `ident`'s source from the macro definition. + MacroDefinition(def) => { + if def == self.r.macro_def(ident.span.ctxt()) { + ident.span.remove_mark(); + } + } + _ => { + // Do not resolve labels across function boundary + return None; + } + } + let r = pred(rib, ident); + if r.is_some() { + return r; + } + } + None + } + + fn resolve_adt(&mut self, item: &Item, generics: &Generics) { + debug!("resolve_adt"); + self.with_current_self_item(item, |this| { + this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { + let item_def_id = this.r.definitions.local_def_id(item.id); + this.with_self_rib(Res::SelfTy(None, Some(item_def_id)), |this| { + visit::walk_item(this, item); + }); + }); + }); + } + + fn future_proof_import(&mut self, use_tree: &UseTree) { + let segments = &use_tree.prefix.segments; + if !segments.is_empty() { + let ident = segments[0].ident; + if ident.is_path_segment_keyword() || ident.span.rust_2015() { + return; + } + + let nss = match use_tree.kind { + UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..], + _ => &[TypeNS], + }; + let report_error = |this: &Self, ns| { + let what = if ns == TypeNS { "type parameters" } else { "local variables" }; + this.r.session.span_err(ident.span, &format!("imports cannot refer to {}", what)); + }; + + for &ns in nss { + match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) { + Some(LexicalScopeBinding::Res(..)) => { + report_error(self, ns); + } + Some(LexicalScopeBinding::Item(binding)) => { + let orig_blacklisted_binding = + replace(&mut self.r.blacklisted_binding, Some(binding)); + if let Some(LexicalScopeBinding::Res(..)) = + self.resolve_ident_in_lexical_scope(ident, ns, None, + use_tree.prefix.span) { + report_error(self, ns); + } + self.r.blacklisted_binding = orig_blacklisted_binding; + } + None => {} + } + } + } else if let UseTreeKind::Nested(use_trees) = &use_tree.kind { + for (use_tree, _) in use_trees { + self.future_proof_import(use_tree); + } + } + } + + fn resolve_item(&mut self, item: &Item) { + let name = item.ident.name; + debug!("(resolving item) resolving {} ({:?})", name, item.node); + + match item.node { + ItemKind::TyAlias(_, ref generics) | + ItemKind::OpaqueTy(_, ref generics) | + ItemKind::Fn(_, _, ref generics, _) => { + self.with_generic_param_rib( + HasGenericParams(generics, ItemRibKind), + |this| visit::walk_item(this, item) + ); + } + + ItemKind::Enum(_, ref generics) | + ItemKind::Struct(_, ref generics) | + ItemKind::Union(_, ref generics) => { + self.resolve_adt(item, generics); + } + + ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => + self.resolve_implementation(generics, + opt_trait_ref, + &self_type, + item.id, + impl_items), + + ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => { + // Create a new rib for the trait-wide type parameters. + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { + let local_def_id = this.r.definitions.local_def_id(item.id); + this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| { + this.visit_generics(generics); + walk_list!(this, visit_param_bound, bounds); + + for trait_item in trait_items { + this.with_trait_items(trait_items, |this| { + let generic_params = HasGenericParams( + &trait_item.generics, + AssocItemRibKind, + ); + this.with_generic_param_rib(generic_params, |this| { + match trait_item.node { + TraitItemKind::Const(ref ty, ref default) => { + this.visit_ty(ty); + + // Only impose the restrictions of + // ConstRibKind for an actual constant + // expression in a provided default. + if let Some(ref expr) = *default{ + this.with_constant_rib(|this| { + this.visit_expr(expr); + }); + } + } + TraitItemKind::Method(_, _) => { + visit::walk_trait_item(this, trait_item) + } + TraitItemKind::Type(..) => { + visit::walk_trait_item(this, trait_item) + } + TraitItemKind::Macro(_) => { + panic!("unexpanded macro in resolve!") + } + }; + }); + }); + } + }); + }); + } + + ItemKind::TraitAlias(ref generics, ref bounds) => { + // Create a new rib for the trait-wide type parameters. + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { + let local_def_id = this.r.definitions.local_def_id(item.id); + this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| { + this.visit_generics(generics); + walk_list!(this, visit_param_bound, bounds); + }); + }); + } + + ItemKind::Mod(_) | ItemKind::ForeignMod(_) => { + self.with_scope(item.id, |this| { + visit::walk_item(this, item); + }); + } + + ItemKind::Static(ref ty, _, ref expr) | + ItemKind::Const(ref ty, ref expr) => { + debug!("resolve_item ItemKind::Const"); + self.with_item_rib(|this| { + this.visit_ty(ty); + this.with_constant_rib(|this| { + this.visit_expr(expr); + }); + }); + } + + ItemKind::Use(ref use_tree) => { + self.future_proof_import(use_tree); + } + + ItemKind::ExternCrate(..) | + ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) => { + // do nothing, these are just around to be encoded + } + + ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"), + } + } + + fn with_generic_param_rib<'c, F>(&'c mut self, generic_params: GenericParameters<'a, 'c>, f: F) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + { + debug!("with_generic_param_rib"); + match generic_params { + HasGenericParams(generics, rib_kind) => { + let mut function_type_rib = Rib::new(rib_kind); + let mut function_value_rib = Rib::new(rib_kind); + let mut seen_bindings = FxHashMap::default(); + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => {} + GenericParamKind::Type { .. } => { + let ident = param.ident.modern(); + debug!("with_generic_param_rib: {}", param.id); + + if seen_bindings.contains_key(&ident) { + let span = seen_bindings.get(&ident).unwrap(); + let err = ResolutionError::NameAlreadyUsedInParameterList( + ident.name, + *span, + ); + self.r.report_error(param.ident.span, err); + } + seen_bindings.entry(ident).or_insert(param.ident.span); + + // Plain insert (no renaming). + let res = Res::Def( + DefKind::TyParam, + self.r.definitions.local_def_id(param.id), + ); + function_type_rib.bindings.insert(ident, res); + self.r.record_partial_res(param.id, PartialRes::new(res)); + } + GenericParamKind::Const { .. } => { + let ident = param.ident.modern(); + debug!("with_generic_param_rib: {}", param.id); + + if seen_bindings.contains_key(&ident) { + let span = seen_bindings.get(&ident).unwrap(); + let err = ResolutionError::NameAlreadyUsedInParameterList( + ident.name, + *span, + ); + self.r.report_error(param.ident.span, err); + } + seen_bindings.entry(ident).or_insert(param.ident.span); + + let res = Res::Def( + DefKind::ConstParam, + self.r.definitions.local_def_id(param.id), + ); + function_value_rib.bindings.insert(ident, res); + self.r.record_partial_res(param.id, PartialRes::new(res)); + } + } + } + self.ribs[ValueNS].push(function_value_rib); + self.ribs[TypeNS].push(function_type_rib); + } + + NoGenericParams => { + // Nothing to do. + } + } + + f(self); + + if let HasGenericParams(..) = generic_params { + self.ribs[TypeNS].pop(); + self.ribs[ValueNS].pop(); + } + } + + fn with_label_rib(&mut self, f: F) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + { + self.label_ribs.push(Rib::new(NormalRibKind)); + f(self); + self.label_ribs.pop(); + } + + fn with_item_rib(&mut self, f: F) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + { + self.ribs[ValueNS].push(Rib::new(ItemRibKind)); + self.ribs[TypeNS].push(Rib::new(ItemRibKind)); + f(self); + self.ribs[TypeNS].pop(); + self.ribs[ValueNS].pop(); + } + + fn with_constant_rib(&mut self, f: F) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + { + debug!("with_constant_rib"); + self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind)); + self.label_ribs.push(Rib::new(ConstantItemRibKind)); + f(self); + self.label_ribs.pop(); + self.ribs[ValueNS].pop(); + } + + fn with_current_self_type(&mut self, self_type: &Ty, f: F) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T + { + // Handle nested impls (inside fn bodies) + let previous_value = replace(&mut self.current_self_type, Some(self_type.clone())); + let result = f(self); + self.current_self_type = previous_value; + result + } + + fn with_current_self_item(&mut self, self_item: &Item, f: F) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T + { + let previous_value = replace(&mut self.current_self_item, Some(self_item.id)); + let result = f(self); + self.current_self_item = previous_value; + result + } + + /// When evaluating a `trait` use its associated types' idents for suggestionsa in E0412. + fn with_trait_items(&mut self, trait_items: &Vec, f: F) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T + { + let trait_assoc_types = replace( + &mut self.current_trait_assoc_types, + trait_items.iter().filter_map(|item| match &item.node { + TraitItemKind::Type(bounds, _) if bounds.len() == 0 => Some(item.ident), + _ => None, + }).collect(), + ); + let result = f(self); + self.current_trait_assoc_types = trait_assoc_types; + result + } + + /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`). + fn with_optional_trait_ref(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>, Option) -> T + { + let mut new_val = None; + let mut new_id = None; + if let Some(trait_ref) = opt_trait_ref { + let path: Vec<_> = Segment::from_path(&trait_ref.path); + let res = self.smart_resolve_path_fragment( + trait_ref.ref_id, + None, + &path, + trait_ref.path.span, + PathSource::Trait(AliasPossibility::No), + CrateLint::SimplePath(trait_ref.ref_id), + ).base_res(); + if res != Res::Err { + new_id = Some(res.def_id()); + let span = trait_ref.path.span; + if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = + self.resolve_path( + &path, + Some(TypeNS), + false, + span, + CrateLint::SimplePath(trait_ref.ref_id), + ) + { + new_val = Some((module, trait_ref.clone())); + } + } + } + let original_trait_ref = replace(&mut self.current_trait_ref, new_val); + let result = f(self, new_id); + self.current_trait_ref = original_trait_ref; + result + } + + fn with_self_rib(&mut self, self_res: Res, f: F) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + { + let mut self_type_rib = Rib::new(NormalRibKind); + + // Plain insert (no renaming, since types are not currently hygienic) + self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res); + self.ribs[TypeNS].push(self_type_rib); + f(self); + self.ribs[TypeNS].pop(); + } + + fn with_self_struct_ctor_rib(&mut self, impl_id: DefId, f: F) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + { + let self_res = Res::SelfCtor(impl_id); + let mut self_type_rib = Rib::new(NormalRibKind); + self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res); + self.ribs[ValueNS].push(self_type_rib); + f(self); + self.ribs[ValueNS].pop(); + } + + fn resolve_implementation(&mut self, + generics: &Generics, + opt_trait_reference: &Option, + self_type: &Ty, + item_id: NodeId, + impl_items: &[ImplItem]) { + debug!("resolve_implementation"); + // If applicable, create a rib for the type parameters. + self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { + // Dummy self type for better errors if `Self` is used in the trait path. + this.with_self_rib(Res::SelfTy(None, None), |this| { + // Resolve the trait reference, if necessary. + this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| { + let item_def_id = this.r.definitions.local_def_id(item_id); + this.with_self_rib(Res::SelfTy(trait_id, Some(item_def_id)), |this| { + if let Some(trait_ref) = opt_trait_reference.as_ref() { + // Resolve type arguments in the trait path. + visit::walk_trait_ref(this, trait_ref); + } + // Resolve the self type. + this.visit_ty(self_type); + // Resolve the generic parameters. + this.visit_generics(generics); + // Resolve the items within the impl. + this.with_current_self_type(self_type, |this| { + this.with_self_struct_ctor_rib(item_def_id, |this| { + debug!("resolve_implementation with_self_struct_ctor_rib"); + for impl_item in impl_items { + // We also need a new scope for the impl item type parameters. + let generic_params = HasGenericParams(&impl_item.generics, + AssocItemRibKind); + this.with_generic_param_rib(generic_params, |this| { + use crate::ResolutionError::*; + match impl_item.node { + ImplItemKind::Const(..) => { + debug!( + "resolve_implementation ImplItemKind::Const", + ); + // If this is a trait impl, ensure the const + // exists in trait + this.check_trait_item( + impl_item.ident, + ValueNS, + impl_item.span, + |n, s| ConstNotMemberOfTrait(n, s), + ); + + this.with_constant_rib(|this| { + visit::walk_impl_item(this, impl_item) + }); + } + ImplItemKind::Method(..) => { + // If this is a trait impl, ensure the method + // exists in trait + this.check_trait_item(impl_item.ident, + ValueNS, + impl_item.span, + |n, s| MethodNotMemberOfTrait(n, s)); + + visit::walk_impl_item(this, impl_item); + } + ImplItemKind::TyAlias(ref ty) => { + // If this is a trait impl, ensure the type + // exists in trait + this.check_trait_item(impl_item.ident, + TypeNS, + impl_item.span, + |n, s| TypeNotMemberOfTrait(n, s)); + + this.visit_ty(ty); + } + ImplItemKind::OpaqueTy(ref bounds) => { + // If this is a trait impl, ensure the type + // exists in trait + this.check_trait_item(impl_item.ident, + TypeNS, + impl_item.span, + |n, s| TypeNotMemberOfTrait(n, s)); + + for bound in bounds { + this.visit_param_bound(bound); + } + } + ImplItemKind::Macro(_) => + panic!("unexpanded macro in resolve!"), + } + }); + } + }); + }); + }); + }); + }); + }); + } + + fn check_trait_item(&mut self, ident: Ident, ns: Namespace, span: Span, err: F) + where F: FnOnce(Name, &str) -> ResolutionError<'_> + { + // If there is a TraitRef in scope for an impl, then the method must be in the + // trait. + if let Some((module, _)) = self.current_trait_ref { + if self.r.resolve_ident_in_module( + ModuleOrUniformRoot::Module(module), + ident, + ns, + &self.parent_scope, + false, + span, + ).is_err() { + let path = &self.current_trait_ref.as_ref().unwrap().1.path; + self.r.report_error(span, err(ident.name, &path_names_to_string(path))); + } + } + } + + fn resolve_local(&mut self, local: &Local) { + // Resolve the type. + walk_list!(self, visit_ty, &local.ty); + + // Resolve the initializer. + walk_list!(self, visit_expr, &local.init); + + // Resolve the pattern. + self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap::default()); + } + + // build a map from pattern identifiers to binding-info's. + // this is done hygienically. This could arise for a macro + // that expands into an or-pattern where one 'x' was from the + // user and one 'x' came from the macro. + fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { + let mut binding_map = FxHashMap::default(); + + pat.walk(&mut |pat| { + if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node { + if sub_pat.is_some() || match self.r.partial_res_map.get(&pat.id) + .map(|res| res.base_res()) { + Some(Res::Local(..)) => true, + _ => false, + } { + let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode }; + binding_map.insert(ident, binding_info); + } + } + true + }); + + binding_map + } + + // Checks that all of the arms in an or-pattern have exactly the + // same set of bindings, with the same binding modes for each. + fn check_consistent_bindings(&mut self, pats: &[P]) { + let mut missing_vars = FxHashMap::default(); + let mut inconsistent_vars = FxHashMap::default(); + + for pat_outer in pats.iter() { + let map_outer = self.binding_mode_map(&pat_outer); + + for pat_inner in pats.iter().filter(|pat| pat.id != pat_outer.id) { + let map_inner = self.binding_mode_map(&pat_inner); + + for (&key_inner, &binding_inner) in map_inner.iter() { + match map_outer.get(&key_inner) { + None => { // missing binding + let binding_error = missing_vars + .entry(key_inner.name) + .or_insert(BindingError { + name: key_inner.name, + origin: BTreeSet::new(), + target: BTreeSet::new(), + could_be_path: + key_inner.name.as_str().starts_with(char::is_uppercase) + }); + binding_error.origin.insert(binding_inner.span); + binding_error.target.insert(pat_outer.span); + } + Some(binding_outer) => { // check consistent binding + if binding_outer.binding_mode != binding_inner.binding_mode { + inconsistent_vars + .entry(key_inner.name) + .or_insert((binding_inner.span, binding_outer.span)); + } + } + } + } + } + } + + let mut missing_vars = missing_vars.iter_mut().collect::>(); + missing_vars.sort(); + for (name, mut v) in missing_vars { + if inconsistent_vars.contains_key(name) { + v.could_be_path = false; + } + self.r.report_error( + *v.origin.iter().next().unwrap(), + ResolutionError::VariableNotBoundInPattern(v)); + } + + let mut inconsistent_vars = inconsistent_vars.iter().collect::>(); + inconsistent_vars.sort(); + for (name, v) in inconsistent_vars { + self.r.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1)); + } + } + + fn resolve_arm(&mut self, arm: &Arm) { + self.ribs[ValueNS].push(Rib::new(NormalRibKind)); + + self.resolve_pats(&arm.pats, PatternSource::Match); + + if let Some(ref expr) = arm.guard { + self.visit_expr(expr) + } + self.visit_expr(&arm.body); + + self.ribs[ValueNS].pop(); + } + + /// Arising from `source`, resolve a sequence of patterns (top level or-patterns). + fn resolve_pats(&mut self, pats: &[P], source: PatternSource) { + let mut bindings_list = FxHashMap::default(); + for pat in pats { + self.resolve_pattern(pat, source, &mut bindings_list); + } + // This has to happen *after* we determine which pat_idents are variants + if pats.len() > 1 { + self.check_consistent_bindings(pats); + } + } + + fn resolve_block(&mut self, block: &Block) { + debug!("(resolving block) entering block"); + // Move down in the graph, if there's an anonymous module rooted here. + let orig_module = self.parent_scope.module; + let anonymous_module = self.r.block_map.get(&block.id).cloned(); // clones a reference + + let mut num_macro_definition_ribs = 0; + if let Some(anonymous_module) = anonymous_module { + debug!("(resolving block) found anonymous module, moving down"); + self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module))); + self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module))); + self.parent_scope.module = anonymous_module; + self.r.finalize_current_module_macro_resolutions(anonymous_module); + } else { + self.ribs[ValueNS].push(Rib::new(NormalRibKind)); + } + + // Descend into the block. + for stmt in &block.stmts { + if let StmtKind::Item(ref item) = stmt.node { + if let ItemKind::MacroDef(..) = item.node { + num_macro_definition_ribs += 1; + let res = self.r.definitions.local_def_id(item.id); + self.ribs[ValueNS].push(Rib::new(MacroDefinition(res))); + self.label_ribs.push(Rib::new(MacroDefinition(res))); + } + } + + self.visit_stmt(stmt); + } + + // Move back up. + self.parent_scope.module = orig_module; + for _ in 0 .. num_macro_definition_ribs { + self.ribs[ValueNS].pop(); + self.label_ribs.pop(); + } + self.ribs[ValueNS].pop(); + if anonymous_module.is_some() { + self.ribs[TypeNS].pop(); + } + debug!("(resolving block) leaving block"); + } + + fn fresh_binding(&mut self, + ident: Ident, + pat_id: NodeId, + outer_pat_id: NodeId, + pat_src: PatternSource, + bindings: &mut FxHashMap) + -> Res { + // Add the binding to the local ribs, if it + // doesn't already exist in the bindings map. (We + // must not add it if it's in the bindings map + // because that breaks the assumptions later + // passes make about or-patterns.) + let ident = ident.modern_and_legacy(); + let mut res = Res::Local(pat_id); + match bindings.get(&ident).cloned() { + Some(id) if id == outer_pat_id => { + // `Variant(a, a)`, error + self.r.report_error( + ident.span, + ResolutionError::IdentifierBoundMoreThanOnceInSamePattern( + &ident.as_str()) + ); + } + Some(..) if pat_src == PatternSource::FnParam => { + // `fn f(a: u8, a: u8)`, error + self.r.report_error( + ident.span, + ResolutionError::IdentifierBoundMoreThanOnceInParameterList( + &ident.as_str()) + ); + } + Some(..) if pat_src == PatternSource::Match || + pat_src == PatternSource::Let => { + // `Variant1(a) | Variant2(a)`, ok + // Reuse definition from the first `a`. + res = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident]; + } + Some(..) => { + span_bug!(ident.span, "two bindings with the same name from \ + unexpected pattern source {:?}", pat_src); + } + None => { + // A completely fresh binding, add to the lists if it's valid. + if ident.name != kw::Invalid { + bindings.insert(ident, outer_pat_id); + self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident, res); + } + } + } + + res + } + + fn resolve_pattern(&mut self, + pat: &Pat, + pat_src: PatternSource, + // Maps idents to the node ID for the + // outermost pattern that binds them. + bindings: &mut FxHashMap) { + // Visit all direct subpatterns of this pattern. + let outer_pat_id = pat.id; + pat.walk(&mut |pat| { + debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node); + match pat.node { + PatKind::Ident(bmode, ident, ref opt_pat) => { + // First try to resolve the identifier as some existing + // entity, then fall back to a fresh binding. + let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, + None, pat.span) + .and_then(LexicalScopeBinding::item); + let res = binding.map(NameBinding::res).and_then(|res| { + let is_syntactic_ambiguity = opt_pat.is_none() && + bmode == BindingMode::ByValue(Mutability::Immutable); + match res { + Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | + Res::Def(DefKind::Const, _) if is_syntactic_ambiguity => { + // Disambiguate in favor of a unit struct/variant + // or constant pattern. + self.r.record_use(ident, ValueNS, binding.unwrap(), false); + Some(res) + } + Res::Def(DefKind::Ctor(..), _) + | Res::Def(DefKind::Const, _) + | Res::Def(DefKind::Static, _) => { + // This is unambiguously a fresh binding, either syntactically + // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves + // to something unusable as a pattern (e.g., constructor function), + // but we still conservatively report an error, see + // issues/33118#issuecomment-233962221 for one reason why. + self.r.report_error( + ident.span, + ResolutionError::BindingShadowsSomethingUnacceptable( + pat_src.descr(), ident.name, binding.unwrap()) + ); + None + } + Res::Def(DefKind::Fn, _) | Res::Err => { + // These entities are explicitly allowed + // to be shadowed by fresh bindings. + None + } + res => { + span_bug!(ident.span, "unexpected resolution for an \ + identifier in pattern: {:?}", res); + } + } + }).unwrap_or_else(|| { + self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings) + }); + + self.r.record_partial_res(pat.id, PartialRes::new(res)); + } + + PatKind::TupleStruct(ref path, ..) => { + self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct); + } + + PatKind::Path(ref qself, ref path) => { + self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat); + } + + PatKind::Struct(ref path, ..) => { + self.smart_resolve_path(pat.id, None, path, PathSource::Struct); + } + + _ => {} + } + true + }); + + visit::walk_pat(self, pat); + } + + // High-level and context dependent path resolution routine. + // Resolves the path and records the resolution into definition map. + // If resolution fails tries several techniques to find likely + // resolution candidates, suggest imports or other help, and report + // errors in user friendly way. + fn smart_resolve_path(&mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &Path, + source: PathSource<'_>) { + self.smart_resolve_path_fragment( + id, + qself, + &Segment::from_path(path), + path.span, + source, + CrateLint::SimplePath(id), + ); + } + + fn smart_resolve_path_fragment(&mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &[Segment], + span: Span, + source: PathSource<'_>, + crate_lint: CrateLint) + -> PartialRes { + let ns = source.namespace(); + let is_expected = &|res| source.is_expected(res); + + let report_errors = |this: &mut Self, res: Option| { + let (err, candidates) = this.smart_resolve_report_errors(path, span, source, res); + let def_id = this.parent_scope.module.normal_ancestor_id; + let node_id = this.r.definitions.as_local_node_id(def_id).unwrap(); + let better = res.is_some(); + this.r.use_injections.push(UseError { err, candidates, node_id, better }); + PartialRes::new(Res::Err) + }; + + let partial_res = match self.resolve_qpath_anywhere( + id, + qself, + path, + ns, + span, + source.defer_to_typeck(), + crate_lint, + ) { + Some(partial_res) if partial_res.unresolved_segments() == 0 => { + if is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err { + partial_res + } else { + // Add a temporary hack to smooth the transition to new struct ctor + // visibility rules. See #38932 for more details. + let mut res = None; + if let Res::Def(DefKind::Struct, def_id) = partial_res.base_res() { + if let Some((ctor_res, ctor_vis)) + = self.r.struct_constructors.get(&def_id).cloned() { + if is_expected(ctor_res) && + self.r.is_accessible_from(ctor_vis, self.parent_scope.module) { + let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY; + self.r.session.buffer_lint(lint, id, span, + "private struct constructors are not usable through \ + re-exports in outer modules", + ); + res = Some(PartialRes::new(ctor_res)); + } + } + } + + res.unwrap_or_else(|| report_errors(self, Some(partial_res.base_res()))) + } + } + Some(partial_res) if source.defer_to_typeck() => { + // Not fully resolved associated item `T::A::B` or `::A::B` + // or `::A::B`. If `B` should be resolved in value namespace then + // it needs to be added to the trait map. + if ns == ValueNS { + let item_name = path.last().unwrap().ident; + let traits = self.get_traits_containing_item(item_name, ns); + self.r.trait_map.insert(id, traits); + } + + let mut std_path = vec![Segment::from_ident(Ident::with_empty_ctxt(sym::std))]; + std_path.extend(path); + if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) { + let cl = CrateLint::No; + let ns = Some(ns); + if let PathResult::Module(_) | PathResult::NonModule(_) = + self.resolve_path(&std_path, ns, false, span, cl) { + // check if we wrote `str::from_utf8` instead of `std::str::from_utf8` + let item_span = path.iter().last().map(|segment| segment.ident.span) + .unwrap_or(span); + debug!("accessed item from `std` submodule as a bare type {:?}", std_path); + let mut hm = self.r.session.confused_type_with_std_module.borrow_mut(); + hm.insert(item_span, span); + // In some places (E0223) we only have access to the full path + hm.insert(span, span); + } + } + partial_res + } + _ => report_errors(self, None) + }; + + if let PathSource::TraitItem(..) = source {} else { + // Avoid recording definition of `A::B` in `::B::C`. + self.r.record_partial_res(id, partial_res); + } + partial_res + } + + fn self_type_is_available(&mut self, span: Span) -> bool { + let binding = self.resolve_ident_in_lexical_scope( + Ident::with_empty_ctxt(kw::SelfUpper), + TypeNS, + None, + span, + ); + if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false } + } + + fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool { + let ident = Ident::new(kw::SelfLower, self_span); + let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span); + if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false } + } + + // Resolve in alternative namespaces if resolution in the primary namespace fails. + fn resolve_qpath_anywhere( + &mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &[Segment], + primary_ns: Namespace, + span: Span, + defer_to_typeck: bool, + crate_lint: CrateLint, + ) -> Option { + let mut fin_res = None; + for (i, ns) in [primary_ns, TypeNS, ValueNS].iter().cloned().enumerate() { + if i == 0 || ns != primary_ns { + match self.resolve_qpath(id, qself, path, ns, span, crate_lint) { + // If defer_to_typeck, then resolution > no resolution, + // otherwise full resolution > partial resolution > no resolution. + Some(partial_res) if partial_res.unresolved_segments() == 0 || + defer_to_typeck => + return Some(partial_res), + partial_res => if fin_res.is_none() { fin_res = partial_res }, + } + } + } + + // `MacroNS` + assert!(primary_ns != MacroNS); + if qself.is_none() { + let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident); + let path = Path { segments: path.iter().map(path_seg).collect(), span }; + if let Ok((_, res)) = self.r.resolve_macro_path( + &path, None, &self.parent_scope, false, false + ) { + return Some(PartialRes::new(res)); + } + } + + fin_res + } + + /// Handles paths that may refer to associated items. + fn resolve_qpath( + &mut self, + id: NodeId, + qself: Option<&QSelf>, + path: &[Segment], + ns: Namespace, + span: Span, + crate_lint: CrateLint, + ) -> Option { + debug!( + "resolve_qpath(id={:?}, qself={:?}, path={:?}, ns={:?}, span={:?})", + id, + qself, + path, + ns, + span, + ); + + if let Some(qself) = qself { + if qself.position == 0 { + // This is a case like `::B`, where there is no + // trait to resolve. In that case, we leave the `B` + // segment to be resolved by type-check. + return Some(PartialRes::with_unresolved_segments( + Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)), path.len() + )); + } + + // Make sure `A::B` in `::C` is a trait item. + // + // Currently, `path` names the full item (`A::B::C`, in + // our example). so we extract the prefix of that that is + // the trait (the slice upto and including + // `qself.position`). And then we recursively resolve that, + // but with `qself` set to `None`. + // + // However, setting `qself` to none (but not changing the + // span) loses the information about where this path + // *actually* appears, so for the purposes of the crate + // lint we pass along information that this is the trait + // name from a fully qualified path, and this also + // contains the full span (the `CrateLint::QPathTrait`). + let ns = if qself.position + 1 == path.len() { ns } else { TypeNS }; + let partial_res = self.smart_resolve_path_fragment( + id, + None, + &path[..=qself.position], + span, + PathSource::TraitItem(ns), + CrateLint::QPathTrait { + qpath_id: id, + qpath_span: qself.path_span, + }, + ); + + // The remaining segments (the `C` in our example) will + // have to be resolved by type-check, since that requires doing + // trait resolution. + return Some(PartialRes::with_unresolved_segments( + partial_res.base_res(), + partial_res.unresolved_segments() + path.len() - qself.position - 1, + )); + } + + let result = match self.resolve_path(&path, Some(ns), true, span, crate_lint) { + PathResult::NonModule(path_res) => path_res, + PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => { + PartialRes::new(module.res().unwrap()) + } + // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we + // don't report an error right away, but try to fallback to a primitive type. + // So, we are still able to successfully resolve something like + // + // use std::u8; // bring module u8 in scope + // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 + // u8::max_value() // OK, resolves to associated function ::max_value, + // // not to non-existent std::u8::max_value + // } + // + // Such behavior is required for backward compatibility. + // The same fallback is used when `a` resolves to nothing. + PathResult::Module(ModuleOrUniformRoot::Module(_)) | + PathResult::Failed { .. } + if (ns == TypeNS || path.len() > 1) && + self.r.primitive_type_table.primitive_types + .contains_key(&path[0].ident.name) => { + let prim = self.r.primitive_type_table.primitive_types[&path[0].ident.name]; + PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1) + } + PathResult::Module(ModuleOrUniformRoot::Module(module)) => + PartialRes::new(module.res().unwrap()), + PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => { + self.r.report_error(span, ResolutionError::FailedToResolve { label, suggestion }); + PartialRes::new(Res::Err) + } + PathResult::Module(..) | PathResult::Failed { .. } => return None, + PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"), + }; + + if path.len() > 1 && result.base_res() != Res::Err && + path[0].ident.name != kw::PathRoot && + path[0].ident.name != kw::DollarCrate { + let unqualified_result = { + match self.resolve_path( + &[*path.last().unwrap()], + Some(ns), + false, + span, + CrateLint::No, + ) { + PathResult::NonModule(path_res) => path_res.base_res(), + PathResult::Module(ModuleOrUniformRoot::Module(module)) => + module.res().unwrap(), + _ => return Some(result), + } + }; + if result.base_res() == unqualified_result { + let lint = lint::builtin::UNUSED_QUALIFICATIONS; + self.r.session.buffer_lint(lint, id, span, "unnecessary qualification") + } + } + + Some(result) + } + + fn with_resolved_label(&mut self, label: Option

` (where P is one \ + of the previous types except `Self`)"; // Check that the method has a valid receiver type, given the type `Self`. debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty); @@ -804,7 +809,7 @@ fn check_method_receiver<'fcx, 'tcx>( fcx.tcx.sess.diagnostic().mut_span_err( span, &format!("invalid method receiver type: {:?}", receiver_ty) ).note("type of `self` must be `Self` or a type that dereferences to it") - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .help(HELP_FOR_SELF_TYPE) .code(DiagnosticId::Error("E0307".into())) .emit(); } @@ -822,14 +827,14 @@ fn check_method_receiver<'fcx, 'tcx>( the `arbitrary_self_types` feature", receiver_ty, ), - ).help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + ).help(HELP_FOR_SELF_TYPE) .emit(); } else { // Report error; would not have worked with `arbitrary_self_types`. fcx.tcx.sess.diagnostic().mut_span_err( span, &format!("invalid method receiver type: {:?}", receiver_ty) ).note("type must be `Self` or a type that dereferences to it") - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .help(HELP_FOR_SELF_TYPE) .code(DiagnosticId::Error("E0307".into())) .emit(); } @@ -943,7 +948,7 @@ fn check_variances_for_type_defn<'tcx>( item: &hir::Item, hir_generics: &hir::Generics, ) { - let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id); + let item_def_id = tcx.hir().local_def_id(item.hir_id); let ty = tcx.type_of(item_def_id); if tcx.has_error_field(ty) { return; @@ -980,7 +985,7 @@ fn check_variances_for_type_defn<'tcx>( } } -fn report_bivariance<'tcx>(tcx: TyCtxt<'tcx>, span: Span, param_name: ast::Name) { +fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) { let mut err = error_392(tcx, span, param_name); let suggested_marker_id = tcx.lang_items().phantom_data(); @@ -1023,10 +1028,10 @@ fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) { /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that /// aren't true. -fn check_false_global_bounds<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span: Span, id: hir::HirId) { +fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) { let empty_env = ty::ParamEnv::empty(); - let def_id = fcx.tcx.hir().local_def_id_from_hir_id(id); + let def_id = fcx.tcx.hir().local_def_id(id); let predicates = fcx.tcx.predicates_of(def_id).predicates .iter() .map(|(p, _)| *p) @@ -1069,19 +1074,19 @@ impl CheckTypeWellFormedVisitor<'tcx> { impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> { fn visit_item(&self, i: &'tcx hir::Item) { debug!("visit_item: {:?}", i); - let def_id = self.tcx.hir().local_def_id_from_hir_id(i.hir_id); + let def_id = self.tcx.hir().local_def_id(i.hir_id); self.tcx.ensure().check_item_well_formed(def_id); } fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem) { debug!("visit_trait_item: {:?}", trait_item); - let def_id = self.tcx.hir().local_def_id_from_hir_id(trait_item.hir_id); + let def_id = self.tcx.hir().local_def_id(trait_item.hir_id); self.tcx.ensure().check_trait_item_well_formed(def_id); } fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem) { debug!("visit_impl_item: {:?}", impl_item); - let def_id = self.tcx.hir().local_def_id_from_hir_id(impl_item.hir_id); + let def_id = self.tcx.hir().local_def_id(impl_item.hir_id); self.tcx.ensure().check_impl_item_well_formed(def_id); } } @@ -1101,9 +1106,11 @@ struct AdtField<'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> { let fields = struct_def.fields().iter().map(|field| { - let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id)); + let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id)); let field_ty = self.normalize_associated_types_in(field.span, &field_ty); + let field_ty = self.resolve_vars_if_possible(&field_ty); + debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty); AdtField { ty: field_ty, span: field.span } }) .collect(); @@ -1135,11 +1142,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -fn error_392<'tcx>( - tcx: TyCtxt<'tcx>, +fn error_392( + tcx: TyCtxt<'_>, span: Span, param_name: ast::Name, -) -> DiagnosticBuilder<'tcx> { +) -> DiagnosticBuilder<'_> { let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name); err.span_label(span, "unused parameter"); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 28711e32a4..67a8ecaf1d 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -9,10 +9,8 @@ use rustc::hir::def_id::{DefId, DefIndex}; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::infer::InferCtxt; use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast}; -use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; -use rustc::ty::subst::UnpackedKind; +use rustc::ty::fold::{TypeFoldable, TypeFolder}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::mir::interpret::ConstValue; use rustc::util::nodemap::DefIdSet; use rustc_data_structures::sync::Lrc; use std::mem; @@ -34,7 +32,7 @@ use syntax_pos::Span; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn resolve_type_vars_in_body(&self, body: &'tcx hir::Body) -> &'tcx ty::TypeckTables<'tcx> { let item_id = self.tcx.hir().body_owner(body.id()); - let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item_id); + let item_def_id = self.tcx.hir().local_def_id(item_id); // This attribute causes us to dump some writeback information // in the form of errors, which is uSymbolfor unit tests. @@ -440,172 +438,58 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { debug_assert!(!instantiated_ty.has_escaping_bound_vars()); - let generics = self.tcx().generics_of(def_id); + // Prevent: + // * `fn foo() -> Foo` + // * `fn foo() -> Foo` + // from being defining. - let definition_ty = if generics.parent.is_some() { - // `impl Trait` - self.fcx.infer_opaque_definition_from_instantiation( - def_id, - opaque_defn, - instantiated_ty, - ) - } else { - // Prevent: - // * `fn foo() -> Foo` - // * `fn foo() -> Foo` - // from being defining. - - // Also replace all generic params with the ones from the existential type - // definition so that - // ```rust - // existential type Foo: 'static; - // fn foo() -> Foo { .. } - // ``` - // figures out the concrete type with `U`, but the stored type is with `T`. - instantiated_ty.fold_with(&mut BottomUpFolder { - tcx: self.tcx().global_tcx(), - ty_op: |ty| { - trace!("checking type {:?}", ty); - // Find a type parameter. - if let ty::Param(..) = ty.sty { - // Look it up in the substitution list. - assert_eq!(opaque_defn.substs.len(), generics.params.len()); - for (subst, param) in opaque_defn.substs.iter().zip(&generics.params) { - if let UnpackedKind::Type(subst) = subst.unpack() { - if subst == ty { - // Found it in the substitution list; replace with the - // parameter from the existential type. - return self.tcx() - .global_tcx() - .mk_ty_param(param.index, param.name); - } - } - } - self.tcx() - .sess - .struct_span_err( - span, - &format!( - "type parameter `{}` is part of concrete type but not used \ - in parameter list for existential type", - ty, - ), - ) - .emit(); - return self.tcx().types.err; - } - ty - }, - lt_op: |region| { - match region { - // Skip static and bound regions: they don't require substitution. - ty::ReStatic | ty::ReLateBound(..) => region, - _ => { - trace!("checking {:?}", region); - for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) { - if let UnpackedKind::Lifetime(subst) = subst.unpack() { - if subst == region { - // Found it in the substitution list; replace with the - // parameter from the existential type. - let reg = ty::EarlyBoundRegion { - def_id: p.def_id, - index: p.index, - name: p.name, - }; - trace!("replace {:?} with {:?}", region, reg); - return self.tcx() - .global_tcx() - .mk_region(ty::ReEarlyBound(reg)); - } - } - } - trace!("opaque_defn: {:#?}", opaque_defn); - trace!("generics: {:#?}", generics); - self.tcx() - .sess - .struct_span_err( - span, - "non-defining existential type use in defining scope", - ) - .span_label( - span, - format!( - "lifetime `{}` is part of concrete type but not used \ - in parameter list of existential type", - region, - ), - ) - .emit(); - self.tcx().global_tcx().mk_region(ty::ReStatic) - } - } - }, - ct_op: |ct| { - trace!("checking const {:?}", ct); - // Find a const parameter - if let ConstValue::Param(..) = ct.val { - // look it up in the substitution list - assert_eq!(opaque_defn.substs.len(), generics.params.len()); - for (subst, param) in opaque_defn.substs.iter() - .zip(&generics.params) { - if let UnpackedKind::Const(subst) = subst.unpack() { - if subst == ct { - // found it in the substitution list, replace with the - // parameter from the existential type - return self.tcx() - .global_tcx() - .mk_const_param(param.index, param.name, ct.ty); - } - } - } - self.tcx() - .sess - .struct_span_err( - span, - &format!( - "const parameter `{}` is part of concrete type but not \ - used in parameter list for existential type", - ct, - ), - ) - .emit(); - return self.tcx().consts.err; - } - ct - } - }) - }; + // Also replace all generic params with the ones from the opaque type + // definition so that + // ```rust + // type Foo = impl Baz + 'static; + // fn foo() -> Foo { .. } + // ``` + // figures out the concrete type with `U`, but the stored type is with `T`. + let definition_ty = self.fcx.infer_opaque_definition_from_instantiation( + def_id, opaque_defn, instantiated_ty, span); + + let mut skip_add = false; if let ty::Opaque(defin_ty_def_id, _substs) = definition_ty.sty { if def_id == defin_ty_def_id { - // Concrete type resolved to the existential type itself. - // Force a cycle error. - // FIXME(oli-obk): we could just not insert it into `concrete_existential_types` - // which simply would make this use not a defining use. - self.tcx().at(span).type_of(defin_ty_def_id); + debug!("Skipping adding concrete definition for opaque type {:?} {:?}", + opaque_defn, defin_ty_def_id); + skip_add = true; } } if !opaque_defn.substs.has_local_value() { - let new = ty::ResolvedOpaqueTy { - concrete_type: definition_ty, - substs: opaque_defn.substs, - }; - - let old = self.tables - .concrete_existential_types - .insert(def_id, new); - if let Some(old) = old { - if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { - span_bug!( - span, - "visit_opaque_types tried to write \ - different types for the same existential type: {:?}, {:?}, {:?}, {:?}", - def_id, - definition_ty, - opaque_defn, - old, - ); + // We only want to add an entry into `concrete_opaque_types` + // if we actually found a defining usage of this opaque type. + // Otherwise, we do nothing - we'll either find a defining usage + // in some other location, or we'll end up emitting an error due + // to the lack of defining usage + if !skip_add { + let new = ty::ResolvedOpaqueTy { + concrete_type: definition_ty, + substs: opaque_defn.substs, + }; + + let old = self.tables + .concrete_opaque_types + .insert(def_id, new); + if let Some(old) = old { + if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { + span_bug!( + span, + "visit_opaque_types tried to write different types for the same \ + opaque type: {:?}, {:?}, {:?}, {:?}", + def_id, + definition_ty, + opaque_defn, + old, + ); + } } } } else { @@ -646,7 +530,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let n_ty = self.fcx.node_ty(hir_id); let n_ty = self.resolve(&n_ty, &span); self.write_ty_to_tables(hir_id, n_ty); - debug!("Node {:?} has type {:?}", hir_id, n_ty); + debug!("node {:?} has type {:?}", hir_id, n_ty); // Resolve any substitutions if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) { @@ -665,13 +549,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { .remove(hir_id); match adjustment { None => { - debug!("No adjustments for node {:?}", hir_id); + debug!("no adjustments for node {:?}", hir_id); } Some(adjustment) => { let resolved_adjustment = self.resolve(&adjustment, &span); debug!( - "Adjustments for node {:?}: {:?}", + "adjustments for node {:?}: {:?}", hir_id, resolved_adjustment ); self.tables @@ -689,7 +573,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { .remove(hir_id); match adjustment { None => { - debug!("No pat_adjustments for node {:?}", hir_id); + debug!("no pat_adjustments for node {:?}", hir_id); } Some(adjustment) => { diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 7e781eeec5..ffc66ec16d 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -13,7 +13,7 @@ use rustc::util::nodemap::DefIdSet; use rustc_data_structures::fx::FxHashMap; -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_crate(tcx: TyCtxt<'_>) { let mut used_trait_imports = DefIdSet::default(); for &body_id in tcx.hir().krate().bodies.keys() { let item_def_id = tcx.hir().body_owner_def_id(body_id); @@ -52,7 +52,7 @@ struct CheckVisitor<'tcx> { impl CheckVisitor<'tcx> { fn check_import(&self, id: hir::HirId, span: Span) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(id); + let def_id = self.tcx.hir().local_def_id(id); if !self.tcx.maybe_unused_trait_import(def_id) { return; } @@ -70,7 +70,7 @@ impl CheckVisitor<'tcx> { } } -fn unused_crates_lint<'tcx>(tcx: TyCtxt<'tcx>) { +fn unused_crates_lint(tcx: TyCtxt<'_>) { let lint = lint::builtin::UNUSED_EXTERN_CRATES; // Collect first the crates that are completely unused. These we @@ -219,7 +219,7 @@ struct ExternCrateToLint { impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { if let hir::ItemKind::ExternCrate(orig_name) = item.node { - let extern_crate_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let extern_crate_def_id = self.tcx.hir().local_def_id(item.hir_id); self.crates_to_lint.push( ExternCrateToLint { def_id: extern_crate_def_id, diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 42deeaf31f..a95b9a03dc 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -17,7 +17,7 @@ use rustc::hir::def_id::DefId; use hir::Node; use rustc::hir::{self, ItemKind}; -pub fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) { +pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) { Checker { tcx, trait_def_id } .check(tcx.lang_items().drop_trait(), visit_implementation_of_drop) .check(tcx.lang_items().copy_trait(), visit_implementation_of_copy) @@ -38,7 +38,7 @@ impl<'tcx> Checker<'tcx> { { if Some(self.trait_def_id) == trait_def_id { for &impl_id in self.tcx.hir().trait_impls(self.trait_def_id) { - let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(impl_id); + let impl_def_id = self.tcx.hir().local_def_id(impl_id); f(self.tcx, impl_def_id); } } @@ -46,7 +46,7 @@ impl<'tcx> Checker<'tcx> { } } -fn visit_implementation_of_drop<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { +fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) { if let ty::Adt(..) = tcx.type_of(impl_did).sty { /* do nothing */ } else { @@ -74,7 +74,7 @@ fn visit_implementation_of_drop<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { } } -fn visit_implementation_of_copy<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { +fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); let impl_hir_id = if let Some(n) = tcx.hir().as_local_hir_id(impl_did) { @@ -154,7 +154,7 @@ fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'tcx>, impl_did: DefId) { } } -fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { +fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) { debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); if impl_did.is_local() { diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 6088c03fc0..fb79a85ea2 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -7,7 +7,6 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. -use rustc::dep_graph::DepKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -17,10 +16,10 @@ use syntax::ast; use syntax_pos::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. -pub fn crate_inherent_impls<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn crate_inherent_impls( + tcx: TyCtxt<'_>, crate_num: CrateNum, -) -> &'tcx CrateInherentImpls { +) -> &CrateInherentImpls { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); @@ -33,38 +32,14 @@ pub fn crate_inherent_impls<'tcx>( } /// On-demand query: yields a vector of the inherent impls for a specific type. -pub fn inherent_impls<'tcx>(tcx: TyCtxt<'tcx>, ty_def_id: DefId) -> &'tcx [DefId] { +pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: DefId) -> &[DefId] { assert!(ty_def_id.is_local()); - // NB. Until we adopt the red-green dep-tracking algorithm (see - // [the plan] for details on that), we do some hackery here to get - // the dependencies correct. Basically, we use a `with_ignore` to - // read the result we want. If we didn't have the `with_ignore`, - // we would wind up with a dependency on the entire crate, which - // we don't want. Then we go and add dependencies on all the impls - // in the result (which is what we wanted). - // - // The result is a graph with an edge from `Hir(I)` for every impl - // `I` defined on some type `T` to `CoherentInherentImpls(T)`, - // thus ensuring that if any of those impls change, the set of - // inherent impls is considered dirty. - // - // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 - - let result = tcx.dep_graph.with_ignore(|| { - let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); - match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => &v[..], - None => &[], - } - }); - - for &impl_def_id in &result[..] { - let def_path_hash = tcx.def_path_hash(impl_def_id); - tcx.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir)); + let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); + match crate_map.inherent_impls.get(&ty_def_id) { + Some(v) => &v[..], + None => &[], } - - result } struct InherentCollect<'tcx> { @@ -79,7 +54,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { _ => return }; - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let self_ty = self.tcx.type_of(def_id); let lang_items = self.tcx.lang_items(); match self_ty.sty { @@ -282,7 +257,7 @@ impl InherentCollect<'tcx> { // Add the implementation to the mapping from implementation to base // type def ID, if there is a base type for this implementation and // the implementation does not have any associated traits. - let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let impl_def_id = self.tcx.hir().local_def_id(item.hir_id); let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); vec.push(impl_def_id); } else { diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index aae1b1777a..04b59a63e1 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -5,7 +5,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::traits::{self, IntercrateMode}; use rustc::ty::TyCtxt; -pub fn crate_inherent_impls_overlap_check<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) { +pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx }); @@ -89,7 +89,7 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> { hir::ItemKind::Struct(..) | hir::ItemKind::Trait(..) | hir::ItemKind::Union(..) => { - let type_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let type_def_id = self.tcx.hir().local_def_id(item.hir_id); self.check_for_overlapping_inherent_impls(type_def_id); } _ => {} diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 4336e861ce..1d0e433f07 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -18,8 +18,8 @@ mod inherent_impls_overlap; mod orphan; mod unsafety; -fn check_impl<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) { - let impl_def_id = tcx.hir().local_def_id_from_hir_id(hir_id); +fn check_impl(tcx: TyCtxt<'_>, hir_id: HirId) { + let impl_def_id = tcx.hir().local_def_id(hir_id); // If there are no traits, then this implementation must have a // base type. @@ -124,7 +124,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn coherent_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { let impls = tcx.hir().trait_impls(def_id); for &impl_id in impls { check_impl(tcx, impl_id); @@ -135,7 +135,7 @@ fn coherent_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { builtin::check_trait(tcx, def_id); } -pub fn check_coherence<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_coherence(tcx: TyCtxt<'_>) { for &trait_def_id in tcx.hir().krate().trait_impls.keys() { tcx.ensure().coherent_trait(trait_def_id); } @@ -152,7 +152,7 @@ pub fn check_coherence<'tcx>(tcx: TyCtxt<'tcx>) { /// same type. Likewise, no two inherent impls for a given type /// constructor provide a method with the same name. fn check_impl_overlap<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) { - let impl_def_id = tcx.hir().local_def_id_from_hir_id(hir_id); + let impl_def_id = tcx.hir().local_def_id(hir_id); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 4e6fcfe059..299e18337b 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -6,7 +6,7 @@ use rustc::ty::{self, TyCtxt}; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; -pub fn check<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check(tcx: TyCtxt<'_>) { let mut orphan = OrphanChecker { tcx }; tcx.hir().krate().visit_all_item_likes(&mut orphan); } @@ -22,7 +22,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { /// to prevent inundating the user with a bunch of similar error /// reports. fn visit_item(&mut self, item: &hir::Item) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); // "Trait" impl if let hir::ItemKind::Impl(.., Some(_), _, _) = item.node { debug!("coherence2::orphan check: trait impl {}", diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index c41a0e1514..07fbfddd96 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -5,7 +5,7 @@ use rustc::ty::TyCtxt; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::{self, Unsafety}; -pub fn check<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check(tcx: TyCtxt<'_>) { let mut unsafety = UnsafetyChecker { tcx }; tcx.hir().krate().visit_all_item_likes(&mut unsafety); } @@ -21,7 +21,7 @@ impl UnsafetyChecker<'tcx> { unsafety: hir::Unsafety, polarity: hir::ImplPolarity) { - let local_did = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let local_did = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(local_did) { let trait_def = self.tcx.trait_def(trait_ref.def_id); let unsafe_attr = impl_generics.and_then(|generics| { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 87e1166b7c..0f0568907c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -49,14 +49,12 @@ use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety}; use errors::{Applicability, DiagnosticId}; -use std::iter; - struct OnlySelfBounds(bool); /////////////////////////////////////////////////////////////////////////// // Main entry point -fn collect_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut CollectItemTypesVisitor { tcx }.as_deep_visitor() @@ -124,12 +122,12 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { hir::GenericParamKind::Type { default: Some(_), .. } => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id); + let def_id = self.tcx.hir().local_def_id(param.hir_id); self.tcx.type_of(def_id); } hir::GenericParamKind::Type { .. } => {} hir::GenericParamKind::Const { .. } => { - let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id); + let def_id = self.tcx.hir().local_def_id(param.hir_id); self.tcx.type_of(def_id); } } @@ -139,7 +137,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if let hir::ExprKind::Closure(..) = expr.node { - let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id); + let def_id = self.tcx.hir().local_def_id(expr.hir_id); self.tcx.generics_of(def_id); self.tcx.type_of(def_id); } @@ -160,6 +158,16 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { /////////////////////////////////////////////////////////////////////////// // Utility types and common code for the above passes. +fn bad_placeholder_type(tcx: TyCtxt<'tcx>, span: Span) -> errors::DiagnosticBuilder<'tcx> { + let mut diag = tcx.sess.struct_span_err_with_code( + span, + "the type placeholder `_` is not allowed within types on item signatures", + DiagnosticId::Error("E0121".into()), + ); + diag.span_label(span, "not allowed in type signatures"); + diag +} + impl ItemCtxt<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> ItemCtxt<'tcx> { ItemCtxt { tcx, item_def_id } @@ -191,12 +199,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { - self.tcx().sess.struct_span_err_with_code( - span, - "the type placeholder `_` is not allowed within types on item signatures", - DiagnosticId::Error("E0121".into()), - ).span_label(span, "not allowed in type signatures") - .emit(); + bad_placeholder_type(self.tcx(), span).emit(); self.tcx().types.err } @@ -207,12 +210,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { _: Option<&ty::GenericParamDef>, span: Span, ) -> &'tcx Const<'tcx> { - self.tcx().sess.struct_span_err_with_code( - span, - "the const placeholder `_` is not allowed within types on item signatures", - DiagnosticId::Error("E0121".into()), - ).span_label(span, "not allowed in type signatures") - .emit(); + bad_placeholder_type(self.tcx(), span).emit(); self.tcx().consts.err } @@ -226,7 +224,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { if let Some(trait_ref) = poly_trait_ref.no_bound_vars() { self.tcx().mk_projection(item_def_id, trait_ref.substs) } else { - // no late-bound regions, we can just ignore the binder + // There are no late-bound regions; we can just ignore the binder. span_err!( self.tcx().sess, span, @@ -239,33 +237,34 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { - // types in item signatures are not normalized, to avoid undue - // dependencies. + // Types in item signatures are not normalized to avoid undue dependencies. ty } fn set_tainted_by_errors(&self) { - // no obvious place to track this, so just let it go + // There's no obvious place to track this, so just let it go. } fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) { - // no place to record types from signatures? + // There's no place to record types from signatures? } } -fn type_param_predicates<'tcx>( - tcx: TyCtxt<'tcx>, +/// Returns the predicates defined on `item_def_id` of the form +/// `X: Foo` where `X` is the type parameter `def_id`. +fn type_param_predicates( + tcx: TyCtxt<'_>, (item_def_id, def_id): (DefId, DefId), -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { use rustc::hir::*; // In the AST, bounds can derive from two places. Either - // written inline like `` or in a where clause like - // `where T : Foo`. + // written inline like `` or in a where-clause like + // `where T: Foo`. let param_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let param_owner = tcx.hir().ty_param_owner(param_id); - let param_owner_def_id = tcx.hir().local_def_id_from_hir_id(param_owner); + let param_owner_def_id = tcx.hir().local_def_id(param_owner); let generics = tcx.generics_of(param_owner_def_id); let index = generics.param_def_id_to_index[&def_id]; let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id).as_interned_str()); @@ -293,8 +292,8 @@ fn type_param_predicates<'tcx>( match item.node { ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) - | ItemKind::Ty(_, ref generics) - | ItemKind::Existential(ExistTy { + | ItemKind::TyAlias(_, ref generics) + | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. @@ -325,16 +324,23 @@ fn type_param_predicates<'tcx>( let icx = ItemCtxt::new(tcx, item_def_id); let mut result = (*result).clone(); result.predicates.extend(extend.into_iter()); - result.predicates - .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, - OnlySelfBounds(true))); + result.predicates.extend( + icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true)) + .into_iter() + .filter(|(predicate, _)| { + match predicate { + ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index), + _ => false, + } + }) + ); tcx.arena.alloc(result) } impl ItemCtxt<'tcx> { /// Finds bounds from `hir::Generics`. This requires scanning through the /// AST. We do this to avoid having to convert *all* the bounds, which - /// would create artificial cycles. Instead we can only convert the + /// would create artificial cycles. Instead, we can only convert the /// bounds for a type parameter `X` if `X::Foo` is used. fn type_parameter_bounds_in_generics( &self, @@ -381,11 +387,11 @@ impl ItemCtxt<'tcx> { /// parameter with ID `param_id`. We use this so as to avoid running /// `ast_ty_to_ty`, because we want to avoid triggering an all-out /// conversion of the type to avoid inducing unnecessary cycles. -fn is_param<'tcx>(tcx: TyCtxt<'tcx>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool { +fn is_param(tcx: TyCtxt<'_>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool { if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node { match path.res { Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => { - def_id == tcx.hir().local_def_id_from_hir_id(param_id) + def_id == tcx.hir().local_def_id(param_id) } _ => false, } @@ -394,10 +400,10 @@ fn is_param<'tcx>(tcx: TyCtxt<'tcx>, ast_ty: &hir::Ty, param_id: hir::HirId) -> } } -fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { +fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) { let it = tcx.hir().expect_item(item_id); debug!("convert: item {} with id {}", it.ident, it.hir_id); - let def_id = tcx.hir().local_def_id_from_hir_id(item_id); + let def_id = tcx.hir().local_def_id(item_id); match it.node { // These don't define types. hir::ItemKind::ExternCrate(_) @@ -406,7 +412,7 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { | hir::ItemKind::GlobalAsm(_) => {} hir::ItemKind::ForeignMod(ref foreign_mod) => { for item in &foreign_mod.items { - let def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = tcx.hir().local_def_id(item.hir_id); tcx.generics_of(def_id); tcx.type_of(def_id); tcx.predicates_of(def_id); @@ -444,7 +450,7 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { tcx.predicates_of(def_id); for f in struct_def.fields() { - let def_id = tcx.hir().local_def_id_from_hir_id(f.hir_id); + let def_id = tcx.hir().local_def_id(f.hir_id); tcx.generics_of(def_id); tcx.type_of(def_id); tcx.predicates_of(def_id); @@ -456,13 +462,13 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { } // Desugared from `impl Trait`, so visited by the function's return type. - hir::ItemKind::Existential(hir::ExistTy { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => {} - hir::ItemKind::Existential(..) - | hir::ItemKind::Ty(..) + hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::TyAlias(..) | hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::Fn(..) => { @@ -476,9 +482,9 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { } } -fn convert_trait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_id: hir::HirId) { +fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { let trait_item = tcx.hir().expect_trait_item(trait_item_id); - let def_id = tcx.hir().local_def_id_from_hir_id(trait_item.hir_id); + let def_id = tcx.hir().local_def_id(trait_item.hir_id); tcx.generics_of(def_id); match trait_item.node { @@ -497,8 +503,8 @@ fn convert_trait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_id: hir::HirId) { tcx.predicates_of(def_id); } -fn convert_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item_id: hir::HirId) { - let def_id = tcx.hir().local_def_id_from_hir_id(impl_item_id); +fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { + let def_id = tcx.hir().local_def_id(impl_item_id); tcx.generics_of(def_id); tcx.type_of(def_id); tcx.predicates_of(def_id); @@ -507,8 +513,8 @@ fn convert_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item_id: hir::HirId) { } } -fn convert_variant_ctor<'tcx>(tcx: TyCtxt<'tcx>, ctor_id: hir::HirId) { - let def_id = tcx.hir().local_def_id_from_hir_id(ctor_id); +fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) { + let def_id = tcx.hir().local_def_id(ctor_id); tcx.generics_of(def_id); tcx.type_of(def_id); tcx.predicates_of(def_id); @@ -525,7 +531,7 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants: let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx)); prev_discr = Some( if let Some(ref e) = variant.node.disr_expr { - let expr_did = tcx.hir().local_def_id_from_hir_id(e.hir_id); + let expr_did = tcx.hir().local_def_id(e.hir_id); def.eval_explicit_discr(tcx, expr_did) } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) { Some(discr) @@ -548,7 +554,7 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants: ); for f in variant.node.data.fields() { - let def_id = tcx.hir().local_def_id_from_hir_id(f.hir_id); + let def_id = tcx.hir().local_def_id(f.hir_id); tcx.generics_of(def_id); tcx.type_of(def_id); tcx.predicates_of(def_id); @@ -562,8 +568,8 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants: } } -fn convert_variant<'tcx>( - tcx: TyCtxt<'tcx>, +fn convert_variant( + tcx: TyCtxt<'_>, variant_did: Option, ctor_did: Option, ident: Ident, @@ -578,7 +584,7 @@ fn convert_variant<'tcx>( .fields() .iter() .map(|f| { - let fid = tcx.hir().local_def_id_from_hir_id(f.hir_id); + let fid = tcx.hir().local_def_id(f.hir_id); let dup_span = seen_fields.get(&f.ident.modern()).cloned(); if let Some(prev_span) = dup_span { struct_span_err!( @@ -619,7 +625,7 @@ fn convert_variant<'tcx>( ) } -fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { +fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef { use rustc::hir::*; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -635,13 +641,13 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { let variants = def.variants .iter() .map(|v| { - let variant_did = Some(tcx.hir().local_def_id_from_hir_id(v.node.id)); + let variant_did = Some(tcx.hir().local_def_id(v.node.id)); let ctor_did = v.node.data.ctor_hir_id() - .map(|hir_id| tcx.hir().local_def_id_from_hir_id(hir_id)); + .map(|hir_id| tcx.hir().local_def_id(hir_id)); let discr = if let Some(ref e) = v.node.disr_expr { distance_from_explicit = 0; - ty::VariantDiscr::Explicit(tcx.hir().local_def_id_from_hir_id(e.hir_id)) + ty::VariantDiscr::Explicit(tcx.hir().local_def_id(e.hir_id)) } else { ty::VariantDiscr::Relative(distance_from_explicit) }; @@ -657,7 +663,7 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { ItemKind::Struct(ref def, _) => { let variant_did = None; let ctor_did = def.ctor_hir_id() - .map(|hir_id| tcx.hir().local_def_id_from_hir_id(hir_id)); + .map(|hir_id| tcx.hir().local_def_id(hir_id)); let variants = std::iter::once(convert_variant( tcx, variant_did, ctor_did, item.ident, ty::VariantDiscr::Relative(0), def, @@ -669,7 +675,7 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { ItemKind::Union(ref def, _) => { let variant_did = None; let ctor_did = def.ctor_hir_id() - .map(|hir_id| tcx.hir().local_def_id_from_hir_id(hir_id)); + .map(|hir_id| tcx.hir().local_def_id(hir_id)); let variants = std::iter::once(convert_variant( tcx, variant_did, ctor_did, item.ident, ty::VariantDiscr::Relative(0), def, @@ -686,10 +692,10 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { /// Ensures that the super-predicates of the trait with a `DefId` /// of `trait_def_id` are converted and stored. This also ensures that /// the transitive super-predicates are converted. -fn super_predicates_of<'tcx>( - tcx: TyCtxt<'tcx>, +fn super_predicates_of( + tcx: TyCtxt<'_>, trait_def_id: DefId, -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { debug!("super_predicates(trait_def_id={:?})", trait_def_id); let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap(); @@ -740,7 +746,7 @@ fn super_predicates_of<'tcx>( }) } -fn trait_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TraitDef { +fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item = tcx.hir().expect_item(hir_id); @@ -879,7 +885,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { +fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { use rustc::hir::*; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -889,14 +895,14 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { Node::ImplItem(_) | Node::TraitItem(_) | Node::Variant(_) | Node::Ctor(..) | Node::Field(_) => { let parent_id = tcx.hir().get_parent_item(hir_id); - Some(tcx.hir().local_def_id_from_hir_id(parent_id)) + Some(tcx.hir().local_def_id(parent_id)) } Node::Expr(&hir::Expr { node: hir::ExprKind::Closure(..), .. }) => Some(tcx.closure_base_def_id(def_id)), Node::Item(item) => match item.node { - ItemKind::Existential(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn, + ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => impl_trait_fn, _ => None, }, _ => None, @@ -917,10 +923,10 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { generics } - ItemKind::Ty(_, ref generics) + ItemKind::TyAlias(_, ref generics) | ItemKind::Enum(_, ref generics) | ItemKind::Struct(_, ref generics) - | ItemKind::Existential(hir::ExistTy { ref generics, .. }) + | ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, .. }) | ItemKind::Union(_, ref generics) => { allow_defaults = true; generics @@ -937,7 +943,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { opt_self = Some(ty::GenericParamDef { index: 0, name: kw::SelfUpper.as_interned_str(), - def_id: tcx.hir().local_def_id_from_hir_id(param_id), + def_id: tcx.hir().local_def_id(param_id), pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, @@ -983,7 +989,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { .map(|(i, param)| ty::GenericParamDef { name: param.name.ident().as_interned_str(), index: own_start + i as u32, - def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id), + def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind: ty::GenericParamDefKind::Lifetime, }), @@ -1050,7 +1056,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { let param_def = ty::GenericParamDef { index: type_start + i as u32, name: param.name.ident().as_interned_str(), - def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id), + def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind, }; @@ -1122,7 +1128,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { }) } -fn report_assoc_ty_on_inherent_impl<'tcx>(tcx: TyCtxt<'tcx>, span: Span) { +fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) { span_err!( tcx.sess, span, @@ -1131,15 +1137,35 @@ fn report_assoc_ty_on_inherent_impl<'tcx>(tcx: TyCtxt<'tcx>, span: Span) { ); } -fn type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { +fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { checked_type_of(tcx, def_id, true).unwrap() } +fn infer_placeholder_type( + tcx: TyCtxt<'_>, + def_id: DefId, + body_id: hir::BodyId, + span: Span, +) -> Ty<'_> { + let ty = tcx.typeck_tables_of(def_id).node_type(body_id.hir_id); + let mut diag = bad_placeholder_type(tcx, span); + if ty != tcx.types.err { + diag.span_suggestion( + span, + "replace `_` with the correct type", + ty.to_string(), + Applicability::MaybeIncorrect, + ); + } + diag.emit(); + ty +} + /// Same as [`type_of`] but returns [`Option`] instead of failing. /// /// If you want to fail anyway, you can set the `fail` parameter to true, but in this case, /// you'd better just call [`type_of`] directly. -pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Option> { +pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option> { use rustc::hir::*; let hir_id = match tcx.hir().as_local_hir_id(def_id) { @@ -1160,7 +1186,16 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_fn_def(def_id, substs) } - TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty), + TraitItemKind::Const(ref ty, body_id) => { + body_id.and_then(|body_id| { + if let hir::TyKind::Infer = ty.node { + Some(infer_placeholder_type(tcx, def_id, body_id, ty.span)) + } else { + None + } + }).unwrap_or_else(|| icx.to_ty(ty)) + }, + TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty), TraitItemKind::Type(_, None) => { if !fail { return None; @@ -1174,8 +1209,14 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_fn_def(def_id, substs) } - ImplItemKind::Const(ref ty, _) => icx.to_ty(ty), - ImplItemKind::Existential(_) => { + ImplItemKind::Const(ref ty, body_id) => { + if let hir::TyKind::Infer = ty.node { + infer_placeholder_type(tcx, def_id, body_id, ty.span) + } else { + icx.to_ty(ty) + } + }, + ImplItemKind::OpaqueTy(_) => { if tcx .impl_trait_ref(tcx.hir().get_parent_did(hir_id)) .is_none() @@ -1183,9 +1224,9 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op report_assoc_ty_on_inherent_impl(tcx, item.span); } - find_existential_constraints(tcx, def_id) + find_opaque_ty_constraints(tcx, def_id) } - ImplItemKind::Type(ref ty) => { + ImplItemKind::TyAlias(ref ty) => { if tcx .impl_trait_ref(tcx.hir().get_parent_did(hir_id)) .is_none() @@ -1199,10 +1240,16 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op Node::Item(item) => { match item.node { - ItemKind::Static(ref t, ..) - | ItemKind::Const(ref t, _) - | ItemKind::Ty(ref t, _) - | ItemKind::Impl(.., ref t, _) => icx.to_ty(t), + ItemKind::Static(ref ty, .., body_id) + | ItemKind::Const(ref ty, body_id) => { + if let hir::TyKind::Infer = ty.node { + infer_placeholder_type(tcx, def_id, body_id, ty.span) + } else { + icx.to_ty(ty) + } + }, + ItemKind::TyAlias(ref ty, _) + | ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty), ItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_fn_def(def_id, substs) @@ -1212,27 +1259,27 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_adt(def, substs) } - ItemKind::Existential(hir::ExistTy { + ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. - }) => find_existential_constraints(tcx, def_id), - // Existential types desugared from `impl Trait`. - ItemKind::Existential(hir::ExistTy { + }) => find_opaque_ty_constraints(tcx, def_id), + // Opaque types desugared from `impl Trait`. + ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(owner), .. }) => { tcx.typeck_tables_of(owner) - .concrete_existential_types + .concrete_opaque_types .get(&def_id) .map(|opaque| opaque.concrete_type) .unwrap_or_else(|| { // This can occur if some error in the // owner fn prevented us from populating - // the `concrete_existential_types` table. + // the `concrete_opaque_types` table. tcx.sess.delay_span_bug( DUMMY_SP, &format!( - "owner {:?} has no existential type for {:?} in its tables", + "owner {:?} has no opaque type for {:?} in its tables", owner, def_id, ), ); @@ -1353,7 +1400,7 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op None } } - Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(path), + Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(&**path), _ => None, }; @@ -1464,20 +1511,20 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op }) } -fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { +fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { use rustc::hir::{ImplItem, Item, TraitItem}; - debug!("find_existential_constraints({:?})", def_id); + debug!("find_opaque_ty_constraints({:?})", def_id); struct ConstraintLocator<'tcx> { tcx: TyCtxt<'tcx>, def_id: DefId, - // (first found type span, actual type, mapping from the existential type's generic + // (first found type span, actual type, mapping from the opaque type's generic // parameters to the concrete type's generic parameters) // // The mapping is an index for each use site of a generic parameter in the concrete type // - // The indices index into the generic parameters on the existential type. + // The indices index into the generic parameters on the opaque type. found: Option<(Span, Ty<'tcx>, Vec)>, } @@ -1486,7 +1533,7 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t // Don't try to check items that cannot possibly constrain the type. if !self.tcx.has_typeck_tables(def_id) { debug!( - "find_existential_constraints: no constraint for `{:?}` at `{:?}`: no tables", + "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no tables", self.def_id, def_id, ); @@ -1495,11 +1542,11 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t let ty = self .tcx .typeck_tables_of(def_id) - .concrete_existential_types + .concrete_opaque_types .get(&self.def_id); if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty { debug!( - "find_existential_constraints: found constraint for `{:?}` at `{:?}`: {:?}", + "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}", self.def_id, def_id, ty, @@ -1520,7 +1567,7 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t self.tcx.sess.span_err( span, &format!( - "defining existential type use restricts existential \ + "defining opaque type use restricts opaque \ type by using the generic parameter `{}` twice", p.name ), @@ -1531,14 +1578,14 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t self.tcx.sess.delay_span_bug( span, &format!( - "non-defining exist ty use in defining scope: {:?}, {:?}", + "non-defining opaque ty use in defining scope: {:?}, {:?}", concrete_type, substs, ), ); } } } - // Compute the index within the existential type for each generic parameter used in + // Compute the index within the opaque type for each generic parameter used in // the concrete type. let indices = concrete_type .subst(self.tcx, substs) @@ -1554,7 +1601,7 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t if !substs.types().all(is_param) { self.tcx.sess.span_err( span, - "defining existential type use does not fully define existential type", + "defining opaque type use does not fully define opaque type", ); } else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found { let mut ty = concrete_type.walk().fuse(); @@ -1567,11 +1614,11 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t _ => t == p, }); if !iter_eq || ty.next().is_some() || p_ty.next().is_some() { - debug!("find_existential_constraints: span={:?}", span); - // Found different concrete types for the existential type. + debug!("find_opaque_ty_constraints: span={:?}", span); + // Found different concrete types for the opaque type. let mut err = self.tcx.sess.struct_span_err( span, - "concrete type differs from previous defining existential type use", + "concrete type differs from previous defining opaque type use", ); err.span_label( span, @@ -1610,7 +1657,7 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t } } else { debug!( - "find_existential_constraints: no constraint for `{:?}` at `{:?}`", + "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`", self.def_id, def_id, ); @@ -1623,23 +1670,26 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t intravisit::NestedVisitorMap::All(&self.tcx.hir()) } fn visit_item(&mut self, it: &'tcx Item) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id); - // The existential type itself or its children are not within its reveal scope. + debug!("find_existential_constraints: visiting {:?}", it); + let def_id = self.tcx.hir().local_def_id(it.hir_id); + // The opaque type itself or its children are not within its reveal scope. if def_id != self.def_id { self.check(def_id); intravisit::walk_item(self, it); } } fn visit_impl_item(&mut self, it: &'tcx ImplItem) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id); - // The existential type itself or its children are not within its reveal scope. + debug!("find_existential_constraints: visiting {:?}", it); + let def_id = self.tcx.hir().local_def_id(it.hir_id); + // The opaque type itself or its children are not within its reveal scope. if def_id != self.def_id { self.check(def_id); intravisit::walk_impl_item(self, it); } } fn visit_trait_item(&mut self, it: &'tcx TraitItem) { - let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id); + debug!("find_existential_constraints: visiting {:?}", it); + let def_id = self.tcx.hir().local_def_id(it.hir_id); self.check(def_id); intravisit::walk_trait_item(self, it); } @@ -1655,18 +1705,32 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t found: None, }; - debug!("find_existential_constraints: scope={:?}", scope); + debug!("find_opaque_ty_constraints: scope={:?}", scope); if scope == hir::CRATE_HIR_ID { intravisit::walk_crate(&mut locator, tcx.hir().krate()); } else { - debug!("find_existential_constraints: scope={:?}", tcx.hir().get(scope)); + debug!("find_opaque_ty_constraints: scope={:?}", tcx.hir().get(scope)); match tcx.hir().get(scope) { - Node::Item(ref it) => intravisit::walk_item(&mut locator, it), - Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it), - Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it), + // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods + // This allows our visitor to process the defining item itself, causing + // it to pick up any 'sibling' defining uses. + // + // For example, this code: + // ``` + // fn foo() { + // type Blah = impl Debug; + // let my_closure = || -> Blah { true }; + // } + // ``` + // + // requires us to explicitly process `foo()` in order + // to notice the defining usage of `Blah`. + Node::Item(ref it) => locator.visit_item(it), + Node::ImplItem(ref it) => locator.visit_impl_item(it), + Node::TraitItem(ref it) => locator.visit_trait_item(it), other => bug!( - "{:?} is not a valid scope for an existential type item", + "{:?} is not a valid scope for an opaque type item", other ), } @@ -1682,7 +1746,16 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t } } -fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> { +pub fn get_infer_ret_ty(output: &'_ hir::FunctionRetTy) -> Option<&hir::Ty> { + if let hir::FunctionRetTy::Return(ref ty) = output { + if let hir::TyKind::Infer = ty.node { + return Some(&**ty) + } + } + None +} + +fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { use rustc::hir::*; use rustc::hir::Node::*; @@ -1692,18 +1765,41 @@ fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> { match tcx.hir().get(hir_id) { TraitItem(hir::TraitItem { - node: TraitItemKind::Method(sig, _), + node: TraitItemKind::Method(MethodSig { header, decl }, TraitMethod::Provided(_)), .. }) | ImplItem(hir::ImplItem { - node: ImplItemKind::Method(sig, _), + node: ImplItemKind::Method(MethodSig { header, decl }, _), .. - }) => AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl), - - Item(hir::Item { + }) + | Item(hir::Item { node: ItemKind::Fn(decl, header, _, _), .. - }) => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl), + }) => match get_infer_ret_ty(&decl.output) { + Some(ty) => { + let fn_sig = tcx.typeck_tables_of(def_id).liberated_fn_sigs()[hir_id]; + let mut diag = bad_placeholder_type(tcx, ty.span); + let ret_ty = fn_sig.output(); + if ret_ty != tcx.types.err { + diag.span_suggestion( + ty.span, + "replace `_` with the correct return type", + ret_ty.to_string(), + Applicability::MaybeIncorrect, + ); + } + diag.emit(); + ty::Binder::bind(fn_sig) + }, + None => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl) + }, + + TraitItem(hir::TraitItem { + node: TraitItemKind::Method(MethodSig { header, decl }, _), + .. + }) => { + AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl) + }, ForeignItem(&hir::ForeignItem { node: ForeignItemKind::Fn(ref fn_decl, _, _), @@ -1720,7 +1816,7 @@ fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> { let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id)); let inputs = data.fields() .iter() - .map(|f| tcx.type_of(tcx.hir().local_def_id_from_hir_id(f.hir_id))); + .map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id))); ty::Binder::bind(tcx.mk_fn_sig( inputs, ty, @@ -1758,7 +1854,7 @@ fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> { } } -fn impl_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option> { +fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let icx = ItemCtxt::new(tcx, def_id); let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -1773,7 +1869,7 @@ fn impl_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option(tcx: TyCtxt<'tcx>, def_id: DefId) -> hir::ImplPolarity { +fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> hir::ImplPolarity { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); match tcx.hir().expect_item(hir_id).node { hir::ItemKind::Impl(_, polarity, ..) => polarity, @@ -1804,10 +1900,10 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>( /// Returns a list of type predicates for the definition with ID `def_id`, including inferred /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus /// inferred constraints concerning which regions outlive other regions. -fn predicates_defined_on<'tcx>( - tcx: TyCtxt<'tcx>, +fn predicates_defined_on( + tcx: TyCtxt<'_>, def_id: DefId, -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); debug!( @@ -1834,7 +1930,7 @@ fn predicates_defined_on<'tcx>( /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus /// `Self: Trait` predicates for traits. -fn predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::GenericPredicates<'tcx> { +fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> { let mut result = tcx.predicates_defined_on(def_id); if tcx.is_trait(def_id) { @@ -1861,10 +1957,10 @@ fn predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::GenericPre /// Returns a list of user-specified type predicates for the definition with ID `def_id`. /// N.B., this does not include any implied/inferred constraints. -fn explicit_predicates_of<'tcx>( - tcx: TyCtxt<'tcx>, +fn explicit_predicates_of( + tcx: TyCtxt<'_>, def_id: DefId, -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { use rustc::hir::*; use rustc_data_structures::fx::FxHashSet; @@ -1920,7 +2016,7 @@ fn explicit_predicates_of<'tcx>( Node::TraitItem(item) => &item.generics, Node::ImplItem(item) => match item.node { - ImplItemKind::Existential(ref bounds) => { + ImplItemKind::OpaqueTy(ref bounds) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); let opaque_ty = tcx.mk_opaque(def_id, substs); @@ -1948,7 +2044,7 @@ fn explicit_predicates_of<'tcx>( generics } ItemKind::Fn(.., ref generics, _) - | ItemKind::Ty(_, ref generics) + | ItemKind::TyAlias(_, ref generics) | ItemKind::Enum(_, ref generics) | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) => generics, @@ -1961,7 +2057,7 @@ fn explicit_predicates_of<'tcx>( is_trait = Some((ty::TraitRef::identity(tcx, def_id), &empty_trait_items)); generics } - ItemKind::Existential(ExistTy { + ItemKind::OpaqueTy(OpaqueTy { ref bounds, impl_trait_fn, ref generics, @@ -1987,7 +2083,7 @@ fn explicit_predicates_of<'tcx>( predicates: bounds_predicates, }); } else { - // named existential types + // named opaque types predicates.extend(bounds_predicates); generics } @@ -2036,7 +2132,7 @@ fn explicit_predicates_of<'tcx>( let mut index = parent_count + has_own_self as u32; for param in early_bound_lifetimes_from_generics(tcx, ast_generics) { let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { - def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id), + def_id: tcx.hir().local_def_id(param.hir_id), index, name: param.name.ident().as_interned_str(), })); @@ -2102,15 +2198,12 @@ fn explicit_predicates_of<'tcx>( match bound { &hir::GenericBound::Trait(ref poly_trait_ref, _) => { let mut bounds = Bounds::default(); - - let (trait_ref, _) = AstConv::instantiate_poly_trait_ref( + let _ = AstConv::instantiate_poly_trait_ref( &icx, poly_trait_ref, ty, &mut bounds, ); - - predicates.push((trait_ref.to_predicate(), poly_trait_ref.span)); predicates.extend(bounds.predicates(tcx, ty)); } @@ -2154,7 +2247,7 @@ fn explicit_predicates_of<'tcx>( }; let assoc_ty = - tcx.mk_projection(tcx.hir().local_def_id_from_hir_id(trait_item.hir_id), + tcx.mk_projection(tcx.hir().local_def_id(trait_item.hir_id), self_trait_ref.substs); let bounds = AstConv::compute_bounds( @@ -2202,7 +2295,7 @@ fn explicit_predicates_of<'tcx>( /// Converts a specific `GenericBound` from the AST into a set of /// predicates that apply to the self type. A vector is returned /// because this can be anywhere from zero predicates (`T: ?Sized` adds no -/// predicates) to one (`T: Foo`) to many (`T: Bar` adds `T: Bar` +/// predicates) to one (`T: Foo`) to many (`T: Bar` adds `T: Bar` /// and `::X == i32`). fn predicates_from_bound<'tcx>( astconv: &dyn AstConv<'tcx>, @@ -2212,10 +2305,12 @@ fn predicates_from_bound<'tcx>( match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { let mut bounds = Bounds::default(); - let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut bounds); - iter::once((pred.to_predicate(), tr.span)) - .chain(bounds.predicates(astconv.tcx(), param_ty)) - .collect() + let _ = astconv.instantiate_poly_trait_ref( + tr, + param_ty, + &mut bounds, + ); + bounds.predicates(astconv.tcx(), param_ty) } hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); @@ -2256,7 +2351,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( tcx.hir().hir_to_pretty_string(ast_ty.hir_id) ), ) - .help("add #![feature(simd_ffi)] to the crate attributes to enable") + .help("add `#![feature(simd_ffi)]` to the crate attributes to enable") .emit(); } }; @@ -2271,7 +2366,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( fty } -fn is_foreign_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool { match tcx.hir().get_if_local(def_id) { Some(Node::ForeignItem(..)) => true, Some(_) => false, @@ -2279,7 +2374,7 @@ fn is_foreign_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { } } -fn static_mutability<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { +fn static_mutability(tcx: TyCtxt<'_>, def_id: DefId) -> Option { match tcx.hir().get_if_local(def_id) { Some(Node::Item(&hir::Item { node: hir::ItemKind::Static(_, mutbl, _), .. @@ -2387,7 +2482,7 @@ fn from_target_feature( } } -fn linkage_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Linkage { +fn linkage_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Linkage { use rustc::mir::mono::Linkage::*; // Use the names from src/llvm/docs/LangRef.rst here. Most types are only @@ -2422,7 +2517,7 @@ fn linkage_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Linkag } } -fn codegen_fn_attrs<'tcx>(tcx: TyCtxt<'tcx>, id: DefId) -> CodegenFnAttrs { +fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { let attrs = tcx.get_attrs(id); let mut codegen_fn_attrs = CodegenFnAttrs::new(); @@ -2479,7 +2574,7 @@ fn codegen_fn_attrs<'tcx>(tcx: TyCtxt<'tcx>, id: DefId) -> CodegenFnAttrs { } } else if attr.check_name(sym::target_feature) { if tcx.fn_sig(id).unsafety() == Unsafety::Normal { - let msg = "#[target_feature(..)] can only be applied to `unsafe` functions"; + let msg = "`#[target_feature(..)]` can only be applied to `unsafe` functions"; tcx.sess.struct_span_err(attr.span, msg) .span_label(attr.span, "can only be applied to `unsafe` functions") .span_label(tcx.def_span(id), "not an `unsafe` function") @@ -2593,8 +2688,8 @@ fn codegen_fn_attrs<'tcx>(tcx: TyCtxt<'tcx>, id: DefId) -> CodegenFnAttrs { if let Some(span) = inline_span { tcx.sess.span_err( span, - "cannot use #[inline(always)] with \ - #[target_feature]", + "cannot use `#[inline(always)]` with \ + `#[target_feature]`", ); } } diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index d61cef7f85..90118a9f19 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -1,7 +1,5 @@ // ignore-tidy-filelength -#![allow(non_snake_case)] - register_long_diagnostics! { E0023: r##" @@ -3497,8 +3495,8 @@ Example of erroneous code: let r = &[1, 2]; match r { - &[a, b, c, rest..] => { // error: pattern requires at least 3 - // elements but array has 2 + &[a, b, c, rest @ ..] => { // error: pattern requires at least 3 + // elements but array has 2 println!("a={}, b={}, c={} rest={:?}", a, b, c, rest); } } @@ -3512,7 +3510,7 @@ requires. You can match an arbitrary number of remaining elements with `..`: let r = &[1, 2, 3, 4, 5]; match r { - &[a, b, c, rest..] => { // ok! + &[a, b, c, rest @ ..] => { // ok! // prints `a=1, b=2, c=3 rest=[4, 5]` println!("a={}, b={}, c={} rest={:?}", a, b, c, rest); } @@ -4765,7 +4763,53 @@ assert_eq!(1, discriminant(&Enum::Struct{a: 7, b: 11})); ``` "##, +E0733: r##" +Recursion in an `async fn` requires boxing. For example, this will not compile: + +```edition2018,compile_fail,E0733 +#![feature(async_await)] +async fn foo(n: usize) { + if n > 0 { + foo(n - 1).await; + } +} +``` + +To achieve async recursion, the `async fn` needs to be desugared +such that the `Future` is explicit in the return type: + +```edition2018,compile_fail,E0720 +# #![feature(async_await)] +use std::future::Future; +fn foo_desugered(n: usize) -> impl Future { + async move { + if n > 0 { + foo_desugered(n - 1).await; + } + } +} +``` + +Finally, the future is wrapped in a pinned box: + +```edition2018 +# #![feature(async_await)] +use std::future::Future; +use std::pin::Pin; +fn foo_recursive(n: usize) -> Pin>> { + Box::pin(async move { + if n > 0 { + foo_recursive(n - 1).await; + } + }) } +``` + +The `Box<...>` ensures that the result is of known size, +and the pin is required to keep it in the same place in memory. +"##, + +} // (end of detailed error messages) register_diagnostics! { // E0035, merged into E0087/E0089 @@ -4848,6 +4892,6 @@ register_diagnostics! { E0641, // cannot cast to/from a pointer with an unknown kind E0645, // trait aliases not finished E0719, // duplicate values for associated type binding - E0722, // Malformed #[optimize] attribute + E0722, // Malformed `#[optimize]` attribute E0724, // `#[ffi_returns_twice]` is only allowed in foreign functions } diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index b833d8555e..fcfd9adef5 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -49,16 +49,16 @@ use syntax_pos::Span; /// impl<'a> Trait for Bar { type X = &'a i32; } /// // ^ 'a is unused and appears in assoc type, error /// ``` -pub fn impl_wf_check<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn impl_wf_check(tcx: TyCtxt<'_>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id_from_node_id(module)); } } -fn check_mod_impl_wf<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut ImplWfCheck { tcx } @@ -79,7 +79,7 @@ struct ImplWfCheck<'tcx> { impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.node { - let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let impl_def_id = self.tcx.hir().local_def_id(item.hir_id); enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_item_refs); @@ -92,8 +92,8 @@ impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { } } -fn enforce_impl_params_are_constrained<'tcx>( - tcx: TyCtxt<'tcx>, +fn enforce_impl_params_are_constrained( + tcx: TyCtxt<'_>, impl_def_id: DefId, impl_item_refs: &[hir::ImplItemRef], ) { @@ -109,7 +109,7 @@ fn enforce_impl_params_are_constrained<'tcx>( // Disallow unconstrained lifetimes, but only if they appear in assoc types. let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter() - .map(|item_ref| tcx.hir().local_def_id_from_hir_id(item_ref.id.hir_id)) + .map(|item_ref| tcx.hir().local_def_id(item_ref.id.hir_id)) .filter(|&def_id| { let item = tcx.associated_item(def_id); item.kind == ty::AssocKind::Type && item.defaultness.has_value() @@ -183,13 +183,13 @@ fn report_unused_parameter(tcx: TyCtxt<'_>, span: Span, kind: &str, name: &str) } /// Enforce that we do not have two items in an impl with the same name. -fn enforce_impl_items_are_distinct<'tcx>(tcx: TyCtxt<'tcx>, impl_item_refs: &[hir::ImplItemRef]) { +fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) { let mut seen_type_items = FxHashMap::default(); let mut seen_value_items = FxHashMap::default(); for impl_item_ref in impl_item_refs { let impl_item = tcx.hir().impl_item(impl_item_ref.id); let seen_items = match impl_item.node { - hir::ImplItemKind::Type(_) => &mut seen_type_items, + hir::ImplItemKind::TyAlias(_) => &mut seen_type_items, _ => &mut seen_value_items, }; match seen_items.entry(impl_item.ident.modern()) { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 85ae55b2dd..9d9a9d9b55 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -69,13 +69,10 @@ This API is completely unstable and subject to change. #![feature(slice_patterns)] #![feature(never_type)] #![feature(inner_deref)] +#![feature(mem_take)] #![recursion_limit="256"] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #[macro_use] extern crate log; #[macro_use] extern crate syntax; @@ -111,7 +108,7 @@ use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::query::Providers; use rustc::util; -use syntax_pos::Span; +use syntax_pos::{DUMMY_SP, Span}; use util::common::time; use std::iter; @@ -161,7 +158,7 @@ fn require_same_types<'tcx>( }) } -fn check_main_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, main_def_id: DefId) { +fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { let main_id = tcx.hir().as_local_hir_id(main_def_id).unwrap(); let main_span = tcx.def_span(main_def_id); let main_t = tcx.type_of(main_def_id); @@ -226,7 +223,7 @@ fn check_main_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, main_def_id: DefId) { } } -fn check_start_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, start_def_id: DefId) { +fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { let start_id = tcx.hir().as_local_hir_id(start_def_id).unwrap(); let start_span = tcx.def_span(start_def_id); let start_t = tcx.type_of(start_def_id); @@ -283,7 +280,7 @@ fn check_start_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, start_def_id: DefId) { } } -fn check_for_entry_fn<'tcx>(tcx: TyCtxt<'tcx>) { +fn check_for_entry_fn(tcx: TyCtxt<'_>) { match tcx.entry_fn(LOCAL_CRATE) { Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id), Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), @@ -300,7 +297,7 @@ pub fn provide(providers: &mut Providers<'_>) { impl_wf_check::provide(providers); } -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> { +pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { tcx.sess.profiler(|p| p.start_activity("type-check crate")); // this ensures that later parts of type checking can assume that items @@ -309,7 +306,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { time(tcx.sess, "type collecting", || { for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module)); + tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id_from_node_id(module)); } }); })?; @@ -344,7 +341,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> { time(tcx.sess, "item-types checking", || { for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module)); + tcx.ensure().check_mod_item_types(tcx.hir().local_def_id_from_node_id(module)); } }); @@ -369,7 +366,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty) -> Ty<'tcx> { // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id); - let env_def_id = tcx.hir().local_def_id_from_hir_id(env_node_id); + let env_def_id = tcx.hir().local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id); astconv::AstConv::ast_ty_to_ty(&item_cx, hir_ty) @@ -378,19 +375,19 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty) -> Ty<'tcx> { pub fn hir_trait_to_predicates<'tcx>( tcx: TyCtxt<'tcx>, hir_trait: &hir::TraitRef, -) -> (ty::PolyTraitRef<'tcx>, Bounds<'tcx>) { +) -> Bounds<'tcx> { // In case there are any projections, etc., find the "environment" // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. let env_hir_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id); - let env_def_id = tcx.hir().local_def_id_from_hir_id(env_hir_id); + let env_def_id = tcx.hir().local_def_id(env_hir_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id); let mut bounds = Bounds::default(); - let (principal, _) = AstConv::instantiate_poly_trait_ref_inner( - &item_cx, hir_trait, tcx.types.err, &mut bounds, true + let _ = AstConv::instantiate_poly_trait_ref_inner( + &item_cx, hir_trait, DUMMY_SP, tcx.types.err, &mut bounds, true ); - (principal, bounds) + bounds } __build_diagnostic_array! { librustc_typeck, DIAGNOSTICS } diff --git a/src/librustc_typeck/namespace.rs b/src/librustc_typeck/namespace.rs index 9b6c5bd9f4..1e1d3e7865 100644 --- a/src/librustc_typeck/namespace.rs +++ b/src/librustc_typeck/namespace.rs @@ -11,7 +11,7 @@ pub enum Namespace { impl From for Namespace { fn from(a_kind: ty::AssocKind) -> Self { match a_kind { - ty::AssocKind::Existential | + ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::Type, ty::AssocKind::Const | ty::AssocKind::Method => Namespace::Value, @@ -22,8 +22,8 @@ impl From for Namespace { impl<'a> From <&'a hir::ImplItemKind> for Namespace { fn from(impl_kind: &'a hir::ImplItemKind) -> Self { match *impl_kind { - hir::ImplItemKind::Existential(..) | - hir::ImplItemKind::Type(..) => Namespace::Type, + hir::ImplItemKind::OpaqueTy(..) | + hir::ImplItemKind::TyAlias(..) => Namespace::Type, hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => Namespace::Value, } diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index f2661b46b8..6b288347ad 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -52,7 +52,7 @@ pub struct InferVisitor<'cx, 'tcx> { impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { - let item_did = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let item_did = self.tcx.hir().local_def_id(item.hir_id); debug!("InferVisitor::visit_item(item={:?})", item_did); diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index 63e41e01fb..6b8f6fccd4 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -20,10 +20,10 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn inferred_outlives_of<'tcx>( - tcx: TyCtxt<'tcx>, +fn inferred_outlives_of( + tcx: TyCtxt<'_>, item_def_id: DefId, -) -> &'tcx [ty::Predicate<'tcx>] { +) -> &[ty::Predicate<'_>] { let id = tcx .hir() .as_local_hir_id(item_def_id) @@ -70,10 +70,10 @@ fn inferred_outlives_of<'tcx>( } } -fn inferred_outlives_crate<'tcx>( - tcx: TyCtxt<'tcx>, +fn inferred_outlives_crate( + tcx: TyCtxt<'_>, crate_num: CrateNum, -) -> &'tcx CratePredicatesMap<'tcx> { +) -> &CratePredicatesMap<'_> { assert_eq!(crate_num, LOCAL_CRATE); // Compute a map from each struct/enum/union S to the **explicit** diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs index 4690cb9ead..3ae646b3ac 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/src/librustc_typeck/outlives/test.rs @@ -3,7 +3,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; use syntax::symbol::sym; -pub fn test_inferred_outlives<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn test_inferred_outlives(tcx: TyCtxt<'_>) { tcx.hir() .krate() .visit_all_item_likes(&mut OutlivesTest { tcx }); @@ -15,7 +15,7 @@ struct OutlivesTest<'tcx> { impl ItemLikeVisitor<'tcx> for OutlivesTest<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let item_def_id = self.tcx.hir().local_def_id(item.hir_id); // For unit testing: check for a special "rustc_outlives" // attribute and report an error with various results if found. diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs index c6b0da3fe4..783890da63 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/src/librustc_typeck/outlives/utils.rs @@ -125,7 +125,7 @@ pub fn insert_outlives_predicate<'tcx>( } } -fn is_free_region<'tcx>(tcx: TyCtxt<'tcx>, region: Region<'_>) -> bool { +fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool { // First, screen for regions that might appear in a type header. match region { // These correspond to `T: 'a` relationships: diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 36f0dbcd2f..b75a091265 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -120,7 +120,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> { impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn visit_node_helper(&mut self, id: hir::HirId) { let tcx = self.terms_cx.tcx; - let def_id = tcx.hir().local_def_id_from_hir_id(id); + let def_id = tcx.hir().local_def_id(id); self.build_constraints_for_item(def_id); } diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 1a8871a3da..343d7ea656 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -34,7 +34,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn crate_variances<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx CrateVariancesMap<'tcx> { +fn crate_variances(tcx: TyCtxt<'_>, crate_num: CrateNum) -> &CrateVariancesMap<'_> { assert_eq!(crate_num, LOCAL_CRATE); let mut arena = arena::TypedArena::default(); let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena); @@ -42,7 +42,7 @@ fn crate_variances<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx CrateV tcx.arena.alloc(solve::solve_constraints(constraints_cx)) } -fn variances_of<'tcx>(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> &'tcx [ty::Variance] { +fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id"); let unsupported = || { // Variance not relevant. diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs index 3851b918c4..1176c5ebb3 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/src/librustc_typeck/variance/solve.rs @@ -64,7 +64,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { let old_value = self.solutions[inferred]; let new_value = glb(variance, old_value); if old_value != new_value { - debug!("Updating inferred {} \ + debug!("updating inferred {} \ from {:?} to {:?} due to {:?}", inferred, old_value, @@ -99,7 +99,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { let solutions = &self.solutions; self.terms_cx.inferred_starts.iter().map(|(&id, &InferredIndex(start))| { - let def_id = tcx.hir().local_def_id_from_hir_id(id); + let def_id = tcx.hir().local_def_id(id); let generics = tcx.generics_of(def_id); let count = generics.count(); diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index 3f6eadeac3..7af7c79bb3 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -103,7 +103,7 @@ fn lang_items(tcx: TyCtxt<'_>) -> Vec<(hir::HirId, Vec)> { impl<'a, 'tcx> TermsContext<'a, 'tcx> { fn add_inferreds_for_item(&mut self, id: hir::HirId) { let tcx = self.tcx; - let def_id = tcx.hir().local_def_id_from_hir_id(id); + let def_id = tcx.hir().local_def_id(id); let count = tcx.generics_of(def_id).count(); if count == 0 { diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs index cefc200f5c..9f6266b316 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/src/librustc_typeck/variance/test.rs @@ -3,7 +3,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; use syntax::symbol::sym; -pub fn test_variance<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn test_variance(tcx: TyCtxt<'_>) { tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx }); } @@ -13,7 +13,7 @@ struct VarianceTest<'tcx> { impl ItemLikeVisitor<'tcx> for VarianceTest<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let item_def_id = self.tcx.hir().local_def_id(item.hir_id); // For unit testing: check for a special "rustc_variance" // attribute and report an error with various results if found. diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 3158ec3832..0eb8b73016 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -9,8 +9,7 @@ name = "rustdoc" path = "lib.rs" [dependencies] -pulldown-cmark = { version = "0.5.2", default-features = false } -minifier = "0.0.30" +pulldown-cmark = { version = "0.5.3", default-features = false } +minifier = "0.0.33" rayon = { version = "0.2.0", package = "rustc-rayon" } tempfile = "3" -parking_lot = "0.7" diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 5c42d705bd..490d4107c5 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -3,10 +3,9 @@ use rustc::traits; use rustc::ty::ToPredicate; use rustc::ty::subst::Subst; use rustc::infer::InferOk; +use rustc::hir::def_id::LOCAL_CRATE; use syntax_pos::DUMMY_SP; -use crate::core::DocAccessLevels; - use super::*; pub struct BlanketImplFinder<'a, 'tcx> { @@ -29,8 +28,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { debug!("get_blanket_impls({:?})", ty); let mut impls = Vec::new(); - for &trait_def_id in self.cx.all_traits.iter() { - if !self.cx.renderinfo.borrow().access_levels.is_doc_reachable(trait_def_id) || + for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() { + if !self.cx.renderinfo.borrow().access_levels.is_public(trait_def_id) || self.cx.generated_synthetics .borrow_mut() .get(&(ty, trait_def_id)) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index ad211763a6..b9b3e621bb 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -16,6 +16,9 @@ use syntax_pos::Span; use crate::html::escape::Escape; +#[cfg(test)] +mod tests; + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum Cfg { /// Accepts all configurations. @@ -408,420 +411,3 @@ impl<'a> fmt::Display for Html<'a> { } } } - -#[cfg(test)] -mod test { - use super::Cfg; - - use syntax_pos::DUMMY_SP; - use syntax::ast::*; - use syntax::attr; - use syntax::source_map::dummy_spanned; - use syntax::symbol::Symbol; - use syntax::with_default_globals; - - fn word_cfg(s: &str) -> Cfg { - Cfg::Cfg(Symbol::intern(s), None) - } - - 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 { - path: Path::from_ident(Ident::from_str(name)), - node: MetaItemKind::Word, - span: DUMMY_SP, - } - } - - macro_rules! dummy_meta_item_list { - ($name:ident, [$($list:ident),* $(,)?]) => { - MetaItem { - path: Path::from_ident(Ident::from_str(stringify!($name))), - node: MetaItemKind::List(vec![ - $( - NestedMetaItem::MetaItem( - dummy_meta_item_word(stringify!($list)), - ), - )* - ]), - span: DUMMY_SP, - } - }; - - ($name:ident, [$($list:expr),* $(,)?]) => { - MetaItem { - path: Path::from_ident(Ident::from_str(stringify!($name))), - node: MetaItemKind::List(vec![ - $( - NestedMetaItem::MetaItem($list), - )* - ]), - span: DUMMY_SP, - } - }; - } - - #[test] - fn test_cfg_not() { - with_default_globals(|| { - assert_eq!(!Cfg::False, Cfg::True); - assert_eq!(!Cfg::True, Cfg::False); - assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); - assert_eq!( - !Cfg::All(vec![word_cfg("a"), word_cfg("b")]), - Cfg::Not(Box::new(Cfg::All(vec![word_cfg("a"), word_cfg("b")]))) - ); - assert_eq!( - !Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), - Cfg::Not(Box::new(Cfg::Any(vec![word_cfg("a"), word_cfg("b")]))) - ); - assert_eq!(!Cfg::Not(Box::new(word_cfg("test"))), word_cfg("test")); - }) - } - - #[test] - fn test_cfg_and() { - with_default_globals(|| { - let mut x = Cfg::False; - x &= Cfg::True; - assert_eq!(x, Cfg::False); - - x = word_cfg("test"); - x &= Cfg::False; - assert_eq!(x, Cfg::False); - - x = word_cfg("test2"); - x &= Cfg::True; - assert_eq!(x, word_cfg("test2")); - - x = Cfg::True; - x &= word_cfg("test3"); - assert_eq!(x, word_cfg("test3")); - - x &= word_cfg("test4"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); - - x &= word_cfg("test5"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); - - x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); - assert_eq!(x, Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - ])); - - let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]); - y &= x; - assert_eq!(y, Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), - ])); - - assert_eq!( - word_cfg("a") & word_cfg("b") & word_cfg("c"), - Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) - ); - }) - } - - #[test] - fn test_cfg_or() { - with_default_globals(|| { - let mut x = Cfg::True; - x |= Cfg::False; - assert_eq!(x, Cfg::True); - - x = word_cfg("test"); - x |= Cfg::True; - assert_eq!(x, Cfg::True); - - x = word_cfg("test2"); - x |= Cfg::False; - assert_eq!(x, word_cfg("test2")); - - x = Cfg::False; - x |= word_cfg("test3"); - assert_eq!(x, word_cfg("test3")); - - x |= word_cfg("test4"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); - - x |= word_cfg("test5"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); - - x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); - assert_eq!(x, Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - ])); - - let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]); - y |= x; - assert_eq!(y, Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - Cfg::All(vec![word_cfg("a"), word_cfg("b")]), - ])); - - assert_eq!( - word_cfg("a") | word_cfg("b") | word_cfg("c"), - Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) - ); - }) - } - - #[test] - fn test_parse_ok() { - with_default_globals(|| { - let mi = dummy_meta_item_word("all"); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); - - let mi = attr::mk_name_value_item_str( - Ident::from_str("all"), - dummy_spanned(Symbol::intern("done")) - ); - assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); - - let mi = dummy_meta_item_list!(all, [a, b]); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b"))); - - let mi = dummy_meta_item_list!(any, [a, b]); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b"))); - - let mi = dummy_meta_item_list!(not, [a]); - assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a"))); - - let mi = dummy_meta_item_list!(not, [ - dummy_meta_item_list!(any, [ - dummy_meta_item_word("a"), - dummy_meta_item_list!(all, [b, c]), - ]), - ]); - assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c"))))); - - 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"))); - }) - } - - #[test] - fn test_parse_err() { - with_default_globals(|| { - let mi = attr::mk_name_value_item( - DUMMY_SP, - Ident::from_str("foo"), - LitKind::Bool(false), - DUMMY_SP, - ); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(not, [a, b]); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(not, []); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(foo, []); - assert!(Cfg::parse(&mi).is_err()); - - 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 = dummy_meta_item_list!(any, [ - dummy_meta_item_word("a"), - dummy_meta_item_list!(foo, []), - ]); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(not, [ - dummy_meta_item_list!(foo, []), - ]); - assert!(Cfg::parse(&mi).is_err()); - }) - } - - #[test] - fn test_render_short_html() { - with_default_globals(|| { - assert_eq!( - word_cfg("unix").render_short_html(), - "Unix" - ); - assert_eq!( - name_value_cfg("target_os", "macos").render_short_html(), - "macOS" - ); - assert_eq!( - name_value_cfg("target_pointer_width", "16").render_short_html(), - "16-bit" - ); - assert_eq!( - name_value_cfg("target_endian", "little").render_short_html(), - "Little-endian" - ); - assert_eq!( - (!word_cfg("windows")).render_short_html(), - "Non-Windows" - ); - assert_eq!( - (word_cfg("unix") & word_cfg("windows")).render_short_html(), - "Unix and Windows" - ); - assert_eq!( - (word_cfg("unix") | word_cfg("windows")).render_short_html(), - "Unix or Windows" - ); - assert_eq!( - ( - word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") - ).render_short_html(), - "Unix and Windows and debug-assertions enabled" - ); - assert_eq!( - ( - word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") - ).render_short_html(), - "Unix or Windows or debug-assertions enabled" - ); - assert_eq!( - ( - !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) - ).render_short_html(), - "Neither Unix nor Windows nor debug-assertions enabled" - ); - assert_eq!( - ( - (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | - (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) - ).render_short_html(), - "Unix and x86-64, or Windows and 64-bit" - ); - assert_eq!( - (!(word_cfg("unix") & word_cfg("windows"))).render_short_html(), - "Not (Unix and Windows)" - ); - assert_eq!( - ( - (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") - ).render_short_html(), - "(Debug-assertions enabled or Windows) and Unix" - ); - assert_eq!( - name_value_cfg("target_feature", "sse2").render_short_html(), - "sse2" - ); - assert_eq!( - ( - name_value_cfg("target_arch", "x86_64") & - name_value_cfg("target_feature", "sse2") - ).render_short_html(), - "x86-64 and sse2" - ); - }) - } - - #[test] - fn test_render_long_html() { - with_default_globals(|| { - assert_eq!( - word_cfg("unix").render_long_html(), - "This is supported on Unix only." - ); - assert_eq!( - name_value_cfg("target_os", "macos").render_long_html(), - "This is supported on macOS only." - ); - assert_eq!( - name_value_cfg("target_pointer_width", "16").render_long_html(), - "This is supported on 16-bit only." - ); - assert_eq!( - name_value_cfg("target_endian", "little").render_long_html(), - "This is supported on little-endian only." - ); - assert_eq!( - (!word_cfg("windows")).render_long_html(), - "This is supported on non-Windows only." - ); - assert_eq!( - (word_cfg("unix") & word_cfg("windows")).render_long_html(), - "This is supported on Unix and Windows only." - ); - assert_eq!( - (word_cfg("unix") | word_cfg("windows")).render_long_html(), - "This is supported on Unix or Windows only." - ); - assert_eq!( - ( - word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") - ).render_long_html(), - "This is supported on Unix and Windows and debug-assertions enabled\ - only." - ); - assert_eq!( - ( - word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") - ).render_long_html(), - "This is supported on Unix or Windows or debug-assertions enabled\ - only." - ); - assert_eq!( - ( - !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) - ).render_long_html(), - "This is supported on neither Unix nor Windows nor debug-assertions \ - enabled." - ); - assert_eq!( - ( - (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | - (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) - ).render_long_html(), - "This is supported on Unix and x86-64, or Windows and 64-bit \ - only." - ); - assert_eq!( - (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(), - "This is supported on not (Unix and Windows)." - ); - assert_eq!( - ( - (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") - ).render_long_html(), - "This is supported on (debug-assertions enabled or Windows) and Unix\ - only." - ); - assert_eq!( - name_value_cfg("target_feature", "sse2").render_long_html(), - "This is supported with target feature sse2 only." - ); - assert_eq!( - ( - name_value_cfg("target_arch", "x86_64") & - name_value_cfg("target_feature", "sse2") - ).render_long_html(), - "This is supported on x86-64 and target feature \ - sse2 only." - ); - }) - } -} diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs new file mode 100644 index 0000000000..405144b444 --- /dev/null +++ b/src/librustdoc/clean/cfg/tests.rs @@ -0,0 +1,412 @@ +use super::*; + +use syntax_pos::DUMMY_SP; +use syntax::ast::*; +use syntax::attr; +use syntax::source_map::dummy_spanned; +use syntax::symbol::Symbol; +use syntax::with_default_globals; + +fn word_cfg(s: &str) -> Cfg { + Cfg::Cfg(Symbol::intern(s), None) +} + +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 { + path: Path::from_ident(Ident::from_str(name)), + node: MetaItemKind::Word, + span: DUMMY_SP, + } +} + +macro_rules! dummy_meta_item_list { + ($name:ident, [$($list:ident),* $(,)?]) => { + MetaItem { + path: Path::from_ident(Ident::from_str(stringify!($name))), + node: MetaItemKind::List(vec![ + $( + NestedMetaItem::MetaItem( + dummy_meta_item_word(stringify!($list)), + ), + )* + ]), + span: DUMMY_SP, + } + }; + + ($name:ident, [$($list:expr),* $(,)?]) => { + MetaItem { + path: Path::from_ident(Ident::from_str(stringify!($name))), + node: MetaItemKind::List(vec![ + $( + NestedMetaItem::MetaItem($list), + )* + ]), + span: DUMMY_SP, + } + }; +} + +#[test] +fn test_cfg_not() { + with_default_globals(|| { + assert_eq!(!Cfg::False, Cfg::True); + assert_eq!(!Cfg::True, Cfg::False); + assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); + assert_eq!( + !Cfg::All(vec![word_cfg("a"), word_cfg("b")]), + Cfg::Not(Box::new(Cfg::All(vec![word_cfg("a"), word_cfg("b")]))) + ); + assert_eq!( + !Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), + Cfg::Not(Box::new(Cfg::Any(vec![word_cfg("a"), word_cfg("b")]))) + ); + assert_eq!(!Cfg::Not(Box::new(word_cfg("test"))), word_cfg("test")); + }) +} + +#[test] +fn test_cfg_and() { + with_default_globals(|| { + let mut x = Cfg::False; + x &= Cfg::True; + assert_eq!(x, Cfg::False); + + x = word_cfg("test"); + x &= Cfg::False; + assert_eq!(x, Cfg::False); + + x = word_cfg("test2"); + x &= Cfg::True; + assert_eq!(x, word_cfg("test2")); + + x = Cfg::True; + x &= word_cfg("test3"); + assert_eq!(x, word_cfg("test3")); + + x &= word_cfg("test4"); + assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); + + x &= word_cfg("test5"); + assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); + + x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); + assert_eq!(x, Cfg::All(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + ])); + + let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]); + y &= x; + assert_eq!(y, Cfg::All(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), + ])); + + assert_eq!( + word_cfg("a") & word_cfg("b") & word_cfg("c"), + Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) + ); + }) +} + +#[test] +fn test_cfg_or() { + with_default_globals(|| { + let mut x = Cfg::True; + x |= Cfg::False; + assert_eq!(x, Cfg::True); + + x = word_cfg("test"); + x |= Cfg::True; + assert_eq!(x, Cfg::True); + + x = word_cfg("test2"); + x |= Cfg::False; + assert_eq!(x, word_cfg("test2")); + + x = Cfg::False; + x |= word_cfg("test3"); + assert_eq!(x, word_cfg("test3")); + + x |= word_cfg("test4"); + assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); + + x |= word_cfg("test5"); + assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); + + x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); + assert_eq!(x, Cfg::Any(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + ])); + + let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]); + y |= x; + assert_eq!(y, Cfg::Any(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + Cfg::All(vec![word_cfg("a"), word_cfg("b")]), + ])); + + assert_eq!( + word_cfg("a") | word_cfg("b") | word_cfg("c"), + Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) + ); + }) +} + +#[test] +fn test_parse_ok() { + with_default_globals(|| { + let mi = dummy_meta_item_word("all"); + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); + + let mi = attr::mk_name_value_item_str( + Ident::from_str("all"), + dummy_spanned(Symbol::intern("done")) + ); + assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); + + let mi = dummy_meta_item_list!(all, [a, b]); + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b"))); + + let mi = dummy_meta_item_list!(any, [a, b]); + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b"))); + + let mi = dummy_meta_item_list!(not, [a]); + assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a"))); + + let mi = dummy_meta_item_list!(not, [ + dummy_meta_item_list!(any, [ + dummy_meta_item_word("a"), + dummy_meta_item_list!(all, [b, c]), + ]), + ]); + assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c"))))); + + 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"))); + }) +} + +#[test] +fn test_parse_err() { + with_default_globals(|| { + let mi = attr::mk_name_value_item( + Ident::from_str("foo"), + LitKind::Bool(false), + DUMMY_SP, + ); + assert!(Cfg::parse(&mi).is_err()); + + let mi = dummy_meta_item_list!(not, [a, b]); + assert!(Cfg::parse(&mi).is_err()); + + let mi = dummy_meta_item_list!(not, []); + assert!(Cfg::parse(&mi).is_err()); + + let mi = dummy_meta_item_list!(foo, []); + assert!(Cfg::parse(&mi).is_err()); + + 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 = dummy_meta_item_list!(any, [ + dummy_meta_item_word("a"), + dummy_meta_item_list!(foo, []), + ]); + assert!(Cfg::parse(&mi).is_err()); + + let mi = dummy_meta_item_list!(not, [ + dummy_meta_item_list!(foo, []), + ]); + assert!(Cfg::parse(&mi).is_err()); + }) +} + +#[test] +fn test_render_short_html() { + with_default_globals(|| { + assert_eq!( + word_cfg("unix").render_short_html(), + "Unix" + ); + assert_eq!( + name_value_cfg("target_os", "macos").render_short_html(), + "macOS" + ); + assert_eq!( + name_value_cfg("target_pointer_width", "16").render_short_html(), + "16-bit" + ); + assert_eq!( + name_value_cfg("target_endian", "little").render_short_html(), + "Little-endian" + ); + assert_eq!( + (!word_cfg("windows")).render_short_html(), + "Non-Windows" + ); + assert_eq!( + (word_cfg("unix") & word_cfg("windows")).render_short_html(), + "Unix and Windows" + ); + assert_eq!( + (word_cfg("unix") | word_cfg("windows")).render_short_html(), + "Unix or Windows" + ); + assert_eq!( + ( + word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") + ).render_short_html(), + "Unix and Windows and debug-assertions enabled" + ); + assert_eq!( + ( + word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") + ).render_short_html(), + "Unix or Windows or debug-assertions enabled" + ); + assert_eq!( + ( + !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) + ).render_short_html(), + "Neither Unix nor Windows nor debug-assertions enabled" + ); + assert_eq!( + ( + (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | + (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) + ).render_short_html(), + "Unix and x86-64, or Windows and 64-bit" + ); + assert_eq!( + (!(word_cfg("unix") & word_cfg("windows"))).render_short_html(), + "Not (Unix and Windows)" + ); + assert_eq!( + ( + (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") + ).render_short_html(), + "(Debug-assertions enabled or Windows) and Unix" + ); + assert_eq!( + name_value_cfg("target_feature", "sse2").render_short_html(), + "sse2" + ); + assert_eq!( + ( + name_value_cfg("target_arch", "x86_64") & + name_value_cfg("target_feature", "sse2") + ).render_short_html(), + "x86-64 and sse2" + ); + }) +} + +#[test] +fn test_render_long_html() { + with_default_globals(|| { + assert_eq!( + word_cfg("unix").render_long_html(), + "This is supported on Unix only." + ); + assert_eq!( + name_value_cfg("target_os", "macos").render_long_html(), + "This is supported on macOS only." + ); + assert_eq!( + name_value_cfg("target_pointer_width", "16").render_long_html(), + "This is supported on 16-bit only." + ); + assert_eq!( + name_value_cfg("target_endian", "little").render_long_html(), + "This is supported on little-endian only." + ); + assert_eq!( + (!word_cfg("windows")).render_long_html(), + "This is supported on non-Windows only." + ); + assert_eq!( + (word_cfg("unix") & word_cfg("windows")).render_long_html(), + "This is supported on Unix and Windows only." + ); + assert_eq!( + (word_cfg("unix") | word_cfg("windows")).render_long_html(), + "This is supported on Unix or Windows only." + ); + assert_eq!( + ( + word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") + ).render_long_html(), + "This is supported on Unix and Windows and debug-assertions enabled\ + only." + ); + assert_eq!( + ( + word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") + ).render_long_html(), + "This is supported on Unix or Windows or debug-assertions enabled\ + only." + ); + assert_eq!( + ( + !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) + ).render_long_html(), + "This is supported on neither Unix nor Windows nor debug-assertions \ + enabled." + ); + assert_eq!( + ( + (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | + (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) + ).render_long_html(), + "This is supported on Unix and x86-64, or Windows and 64-bit \ + only." + ); + assert_eq!( + (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(), + "This is supported on not (Unix and Windows)." + ); + assert_eq!( + ( + (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") + ).render_long_html(), + "This is supported on (debug-assertions enabled or Windows) and Unix\ + only." + ); + assert_eq!( + name_value_cfg("target_feature", "sse2").render_long_html(), + "This is supported with target feature sse2 only." + ); + assert_eq!( + ( + name_value_cfg("target_arch", "x86_64") & + name_value_cfg("target_feature", "sse2") + ).render_long_html(), + "This is supported on x86-64 and target feature \ + sse2 only." + ); + }) +} diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9259b3b5d3..6f93c95ede 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -14,7 +14,7 @@ use rustc_metadata::cstore::LoadedMacro; use rustc::ty; use rustc::util::nodemap::FxHashSet; -use crate::core::{DocContext, DocAccessLevels}; +use crate::core::DocContext; use crate::doctree; use crate::clean::{ self, @@ -24,6 +24,8 @@ use crate::clean::{ use super::Clean; +type Attrs<'hir> = rustc::ty::Attributes<'hir>; + /// Attempt to inline a definition into this AST. /// /// This function will fetch the definition specified, and if it is @@ -40,6 +42,7 @@ pub fn try_inline( cx: &DocContext<'_>, res: Res, name: ast::Name, + attrs: Option>, visited: &mut FxHashSet ) -> Option> { let did = if let Some(did) = res.opt_def_id() { @@ -49,10 +52,13 @@ pub fn try_inline( }; if did.is_local() { return None } let mut ret = Vec::new(); + + let attrs_clone = attrs.clone(); + let inner = match res { Res::Def(DefKind::Trait, did) => { record_extern_fqn(cx, did, clean::TypeKind::Trait); - ret.extend(build_impls(cx, did)); + ret.extend(build_impls(cx, did, attrs)); clean::TraitItem(build_external_trait(cx, did)) } Res::Def(DefKind::Fn, did) => { @@ -61,27 +67,27 @@ pub fn try_inline( } Res::Def(DefKind::Struct, did) => { record_extern_fqn(cx, did, clean::TypeKind::Struct); - ret.extend(build_impls(cx, did)); + ret.extend(build_impls(cx, did, attrs)); clean::StructItem(build_struct(cx, did)) } Res::Def(DefKind::Union, did) => { record_extern_fqn(cx, did, clean::TypeKind::Union); - ret.extend(build_impls(cx, did)); + ret.extend(build_impls(cx, did, attrs)); clean::UnionItem(build_union(cx, did)) } Res::Def(DefKind::TyAlias, did) => { record_extern_fqn(cx, did, clean::TypeKind::Typedef); - ret.extend(build_impls(cx, did)); + ret.extend(build_impls(cx, did, attrs)); clean::TypedefItem(build_type_alias(cx, did), false) } Res::Def(DefKind::Enum, did) => { record_extern_fqn(cx, did, clean::TypeKind::Enum); - ret.extend(build_impls(cx, did)); + ret.extend(build_impls(cx, did, attrs)); clean::EnumItem(build_enum(cx, did)) } Res::Def(DefKind::ForeignTy, did) => { record_extern_fqn(cx, did, clean::TypeKind::Foreign); - ret.extend(build_impls(cx, did)); + ret.extend(build_impls(cx, did, attrs)); clean::ForeignTypeItem } // Never inline enum variants but leave them shown as re-exports. @@ -113,11 +119,15 @@ pub fn try_inline( } _ => return None, }; + + let target_attrs = load_attrs(cx, did); + let attrs = merge_attrs(cx, target_attrs, attrs_clone); + cx.renderinfo.borrow_mut().inlined.insert(did); ret.push(clean::Item { source: cx.tcx.def_span(did).clean(cx), name: Some(name.clean(cx)), - attrs: load_attrs(cx, did), + attrs, inner, visibility: Some(clean::Public), stability: cx.tcx.lookup_stability(did).clean(cx), @@ -144,8 +154,8 @@ pub fn try_inline_glob(cx: &DocContext<'_>, res: Res, visited: &mut FxHashSet, did: DefId) -> clean::Attributes { - cx.tcx.get_attrs(did).clean(cx) +pub fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { + cx.tcx.get_attrs(did) } /// Record an external fully qualified name in the external_paths cache. @@ -153,10 +163,7 @@ pub fn load_attrs(cx: &DocContext<'_>, did: DefId) -> clean::Attributes { /// These names are used later on by HTML rendering to generate things like /// source links back to the original item. pub fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKind) { - let mut crate_name = cx.tcx.crate_name(did.krate).to_string(); - if did.is_local() { - crate_name = cx.crate_name.clone().unwrap_or(crate_name); - } + let crate_name = cx.tcx.crate_name(did.krate).to_string(); let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| { // extern blocks have an empty name @@ -187,7 +194,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { let generics = (cx.tcx.generics_of(did), &predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); - let is_spotlight = load_attrs(cx, did).has_doc_flag(sym::spotlight); + let is_spotlight = load_attrs(cx, did).clean(cx).has_doc_flag(sym::spotlight); let is_auto = cx.tcx.trait_is_auto(did); clean::Trait { auto: auto_trait, @@ -274,23 +281,41 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef { } } -pub fn build_impls(cx: &DocContext<'_>, did: DefId) -> Vec { +pub fn build_impls(cx: &DocContext<'_>, did: DefId, attrs: Option>) -> Vec { let tcx = cx.tcx; let mut impls = Vec::new(); for &did in tcx.inherent_impls(did).iter() { - build_impl(cx, did, &mut impls); + build_impl(cx, did, attrs.clone(), &mut impls); } impls } -pub fn build_impl(cx: &DocContext<'_>, did: DefId, ret: &mut Vec) { +fn merge_attrs(cx: &DocContext<'_>, attrs: Attrs<'_>, other_attrs: Option> +) -> clean::Attributes { + let mut merged_attrs: Vec = Vec::with_capacity(attrs.len()); + // If we have additional attributes (from a re-export), + // always insert them first. This ensure that re-export + // doc comments show up before the original doc comments + // when we render them. + if let Some(a) = other_attrs { + merged_attrs.extend(a.iter().cloned()); + } + merged_attrs.extend(attrs.to_vec()); + merged_attrs.clean(cx) +} + +pub fn build_impl(cx: &DocContext<'_>, did: DefId, attrs: Option>, + ret: &mut Vec +) { if !cx.renderinfo.borrow_mut().inlined.insert(did) { return } - let attrs = load_attrs(cx, did); + let attrs = merge_attrs(cx, load_attrs(cx, did), attrs); + + let tcx = cx.tcx; let associated_trait = tcx.impl_trait_ref(did); @@ -298,7 +323,7 @@ pub fn build_impl(cx: &DocContext<'_>, did: DefId, ret: &mut Vec) { // reachable in rustdoc generated documentation if !did.is_local() { if let Some(traitref) = associated_trait { - if !cx.renderinfo.borrow().access_levels.is_doc_reachable(traitref.def_id) { + if !cx.renderinfo.borrow().access_levels.is_public(traitref.def_id) { return } } @@ -319,7 +344,7 @@ pub fn build_impl(cx: &DocContext<'_>, did: DefId, ret: &mut Vec) { // reachable in rustdoc generated documentation if !did.is_local() { if let Some(did) = for_.def_id() { - if !cx.renderinfo.borrow().access_levels.is_doc_reachable(did) { + if !cx.renderinfo.borrow().access_levels.is_public(did) { return } } @@ -416,7 +441,7 @@ fn build_module( let def_id = item.res.def_id(); if item.vis == ty::Visibility::Public { if did == def_id || !visited.insert(def_id) { continue } - if let Some(i) = try_inline(cx, item.res, item.ident.name, visited) { + if let Some(i) = try_inline(cx, item.res, item.ident.name, None, visited) { items.extend(i) } } @@ -549,22 +574,18 @@ pub fn record_extern_trait(cx: &DocContext<'_>, did: DefId) { } { - let external_traits = cx.external_traits.lock(); - if external_traits.borrow().contains_key(&did) || + if cx.external_traits.borrow().contains_key(&did) || cx.active_extern_traits.borrow().contains(&did) { return; } } - cx.active_extern_traits.borrow_mut().push(did); + cx.active_extern_traits.borrow_mut().insert(did); debug!("record_extern_trait: {:?}", did); let trait_ = build_external_trait(cx, did); - { - let external_traits = cx.external_traits.lock(); - external_traits.borrow_mut().insert(did, trait_); - } - cx.active_extern_traits.borrow_mut().remove_item(&did); + cx.external_traits.borrow_mut().insert(did, trait_); + cx.active_extern_traits.borrow_mut().remove(&did); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3fe048a698..b281505956 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,6 +20,7 @@ use rustc::mir::interpret::{GlobalId, ConstValue}; use rustc::hir; use rustc::hir::def::{CtorKind, DefKind, Res}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::ptr::P; use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind}; use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::fold::TypeFolder; @@ -29,7 +30,6 @@ use syntax::ast::{self, AttrStyle, Ident}; use syntax::attr; use syntax::ext::base::MacroKind; use syntax::source_map::{dummy_spanned, Spanned}; -use syntax::ptr::P; use syntax::symbol::{Symbol, kw, sym}; use syntax::symbol::InternedString; use syntax_pos::{self, Pos, FileName}; @@ -39,17 +39,14 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::default::Default; use std::{mem, slice, vec}; -use std::iter::{FromIterator, once}; +use std::iter::FromIterator; use std::rc::Rc; use std::cell::RefCell; use std::sync::Arc; use std::u32; -use parking_lot::ReentrantMutex; - use crate::core::{self, DocContext}; use crate::doctree; -use crate::visit_ast; use crate::html::render::{cache, ExternalLocation}; use crate::html::item_type::ItemType; @@ -134,14 +131,20 @@ pub struct Crate { pub primitives: Vec<(DefId, PrimitiveType, Attributes)>, // These are later on moved into `CACHEKEY`, leaving the map empty. // Only here so that they can be filtered through the rustdoc passes. - pub external_traits: Arc>>>, + pub external_traits: Rc>>, pub masked_crates: FxHashSet, + pub collapsed: bool, } -impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { +impl Clean for hir::Crate { + // note that self here is ignored in favor of `cx.tcx.hir().krate()` since + // that gets around tying self's lifetime to the '_ in cx. fn clean(&self, cx: &DocContext<'_>) -> Crate { use crate::visit_lib::LibEmbargoVisitor; + let v = crate::visit_ast::RustdocVisitor::new(&cx); + let module = v.visit(cx.tcx.hir().krate()); + { let mut r = cx.renderinfo.borrow_mut(); r.deref_trait_did = cx.tcx.lang_items().deref_trait(); @@ -159,7 +162,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { // Clean the crate, translating the entire libsyntax AST to one that is // understood by rustdoc. - let mut module = self.module.as_ref().unwrap().clean(cx); + let mut module = module.clean(cx); let mut masked_crates = FxHashSet::default(); match module.inner { @@ -169,7 +172,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { // `#[doc(masked)]` to the injected `extern crate` because it's unstable. if it.is_extern_crate() && (it.attrs.has_doc_flag(sym::masked) - || self.cx.tcx.is_compiler_builtins(it.def_id.krate)) + || cx.tcx.is_compiler_builtins(it.def_id.krate)) { masked_crates.insert(it.def_id.krate); } @@ -219,6 +222,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { primitives, external_traits: cx.external_traits.clone(), masked_crates, + collapsed: false, } } } @@ -281,14 +285,14 @@ impl Clean for CrateNum { hir::ItemKind::Mod(_) => { as_primitive(Res::Def( DefKind::Mod, - cx.tcx.hir().local_def_id_from_hir_id(id.id), + cx.tcx.hir().local_def_id(id.id), )) } hir::ItemKind::Use(ref path, hir::UseKind::Single) if item.vis.node.is_pub() => { as_primitive(path.res).map(|(_, prim, attrs)| { // Pretend the primitive is local. - (cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs) + (cx.tcx.hir().local_def_id(id.id), prim, attrs) }) } _ => None @@ -325,13 +329,13 @@ impl Clean for CrateNum { hir::ItemKind::Mod(_) => { as_keyword(Res::Def( DefKind::Mod, - cx.tcx.hir().local_def_id_from_hir_id(id.id), + cx.tcx.hir().local_def_id(id.id), )) } hir::ItemKind::Use(ref path, hir::UseKind::Single) if item.vis.node.is_pub() => { as_keyword(path.res).map(|(_, prim, attrs)| { - (cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs) + (cx.tcx.hir().local_def_id(id.id), prim, attrs) }) } _ => None @@ -392,7 +396,7 @@ impl fmt::Debug for Item { impl Item { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. - pub fn doc_value<'a>(&'a self) -> Option<&'a str> { + pub fn doc_value(&self) -> Option<&str> { self.attrs.doc_value() } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined @@ -538,7 +542,7 @@ pub enum ItemEnum { FunctionItem(Function), ModuleItem(Module), TypedefItem(Typedef, bool /* is associated type */), - ExistentialItem(Existential, bool /* is associated type */), + OpaqueTyItem(OpaqueTy, bool /* is associated type */), StaticItem(Static), ConstantItem(Constant), TraitItem(Trait), @@ -574,7 +578,7 @@ impl ItemEnum { ItemEnum::EnumItem(ref e) => &e.generics, ItemEnum::FunctionItem(ref f) => &f.generics, ItemEnum::TypedefItem(ref t, _) => &t.generics, - ItemEnum::ExistentialItem(ref t, _) => &t.generics, + ItemEnum::OpaqueTyItem(ref t, _) => &t.generics, ItemEnum::TraitItem(ref t) => &t.generics, ItemEnum::ImplItem(ref i) => &i.generics, ItemEnum::TyMethodItem(ref i) => &i.generics, @@ -623,7 +627,7 @@ impl Clean for doctree::Module<'_> { items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); items.extend(self.typedefs.iter().map(|x| x.clean(cx))); - items.extend(self.existentials.iter().map(|x| x.clean(cx))); + items.extend(self.opaque_tys.iter().map(|x| x.clean(cx))); items.extend(self.statics.iter().map(|x| x.clean(cx))); items.extend(self.constants.iter().map(|x| x.clean(cx))); items.extend(self.traits.iter().map(|x| x.clean(cx))); @@ -652,8 +656,8 @@ impl Clean for doctree::Module<'_> { attrs, source: whence.clean(cx), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), def_id: cx.tcx.hir().local_def_id(self.id), inner: ModuleItem(Module { is_crate: self.is_crate, @@ -699,11 +703,11 @@ impl<'a> Iterator for ListAttributesIter<'a> { pub trait AttributesExt { /// Finds an attribute as List and returns the list of attributes nested inside. - fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>; + fn lists(&self, name: Symbol) -> ListAttributesIter<'_>; } impl AttributesExt for [ast::Attribute] { - fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> { + fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), @@ -952,7 +956,7 @@ impl Attributes { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. - pub fn doc_value<'a>(&'a self) -> Option<&'a str> { + pub fn doc_value(&self) -> Option<&str> { self.doc_strings.first().map(|s| s.as_str()) } @@ -1037,7 +1041,7 @@ impl Hash for Attributes { } impl AttributesExt for Attributes { - fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> { + fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { self.other_attrs.lists(name) } } @@ -1319,7 +1323,7 @@ impl Clean> for ty::RegionKind { ty::ReEmpty | ty::ReClosureBound(_) | ty::ReErased => { - debug!("Cannot clean region {:?}", self); + debug!("cannot clean region {:?}", self); None } } @@ -1588,7 +1592,7 @@ impl Clean for hir::GenericParam { } hir::GenericParamKind::Type { ref default, synthetic } => { (self.name.ident().name.clean(cx), GenericParamDefKind::Type { - did: cx.tcx.hir().local_def_id_from_hir_id(self.hir_id), + did: cx.tcx.hir().local_def_id(self.hir_id), bounds: self.bounds.clean(cx), default: default.clean(cx), synthetic: synthetic, @@ -1596,7 +1600,7 @@ impl Clean for hir::GenericParam { } hir::GenericParamKind::Const { ref ty } => { (self.name.ident().name.clean(cx), GenericParamDefKind::Const { - did: cx.tcx.hir().local_def_id_from_hir_id(self.hir_id), + did: cx.tcx.hir().local_def_id(self.hir_id), ty: ty.clean(cx), }) } @@ -1926,7 +1930,7 @@ impl Clean for doctree::Function<'_> { (self.generics.clean(cx), (self.decl, self.body).clean(cx)) }); - let did = cx.tcx.hir().local_def_id_from_hir_id(self.id); + let did = cx.tcx.hir().local_def_id(self.id); let constness = if cx.tcx.is_min_const_fn(did) { hir::Constness::Const } else { @@ -1938,8 +1942,8 @@ impl Clean for doctree::Function<'_> { attrs: self.attrs.clean(cx), source: self.whence.clean(cx), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), def_id: did, inner: FunctionItem(Function { decl, @@ -2136,10 +2140,10 @@ impl Clean for doctree::Trait<'_> { name: Some(self.name.clean(cx)), attrs: attrs, source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: TraitItem(Trait { auto: self.is_auto.clean(cx), unsafety: self.unsafety, @@ -2166,10 +2170,10 @@ impl Clean for doctree::TraitAlias<'_> { name: Some(self.name.clean(cx)), attrs, source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: TraitAliasItem(TraitAlias { generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), @@ -2229,7 +2233,7 @@ impl Clean for hir::TraitItem { AssocTypeItem(bounds.clean(cx), default.clean(cx)) } }; - let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id); + let local_did = cx.tcx.hir().local_def_id(self.hir_id); Item { name: Some(self.ident.name.clean(cx)), attrs: self.attrs.clean(cx), @@ -2253,16 +2257,16 @@ impl Clean for hir::ImplItem { hir::ImplItemKind::Method(ref sig, body) => { MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) } - hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef { + hir::ImplItemKind::TyAlias(ref ty) => TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default(), }, true), - hir::ImplItemKind::Existential(ref bounds) => ExistentialItem(Existential { + hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default(), }, true), }; - let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id); + let local_did = cx.tcx.hir().local_def_id(self.hir_id); Item { name: Some(self.ident.name.clean(cx)), source: self.span.clean(cx), @@ -2415,7 +2419,7 @@ impl Clean for ty::AssocItem { }, true) } } - ty::AssocKind::Existential => unimplemented!(), + ty::AssocKind::OpaqueTy => unimplemented!(), }; let visibility = match self.container { @@ -2429,7 +2433,7 @@ impl Clean for ty::AssocItem { stability: get_stability(cx, self.def_id), deprecation: get_deprecation(cx, self.def_id), def_id: self.def_id, - attrs: inline::load_attrs(cx, self.def_id), + attrs: inline::load_attrs(cx, self.def_id).clean(cx), source: cx.tcx.def_span(self.def_id).clean(cx), inner, } @@ -2757,7 +2761,7 @@ impl Clean for hir::Ty { } TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), TyKind::Array(ref ty, ref length) => { - let def_id = cx.tcx.hir().local_def_id_from_hir_id(length.hir_id); + let def_id = cx.tcx.hir().local_def_id(length.hir_id); let param_env = cx.tcx.param_env(def_id); let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); let cid = GlobalId { @@ -2776,7 +2780,7 @@ impl Clean for hir::Ty { TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), TyKind::Def(item_id, _) => { let item = cx.tcx.hir().expect_item(item_id.id); - if let hir::ItemKind::Existential(ref ty) = item.node { + if let hir::ItemKind::OpaqueTy(ref ty) = item.node { ImplTrait(ty.bounds.clean(cx)) } else { unreachable!() @@ -2802,7 +2806,7 @@ impl Clean for hir::Ty { } }; - if let Some(&hir::ItemKind::Ty(ref ty, ref generics)) = alias { + if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias { let provided_params = &path.segments.last().expect("segments were empty"); let mut ty_substs = FxHashMap::default(); let mut lt_substs = FxHashMap::default(); @@ -2829,7 +2833,7 @@ impl Clean for hir::Ty { if let Some(lt) = lifetime.cloned() { if !lt.is_elided() { let lt_def_id = - cx.tcx.hir().local_def_id_from_hir_id(param.hir_id); + cx.tcx.hir().local_def_id(param.hir_id); lt_substs.insert(lt_def_id, lt.clean(cx)); } } @@ -2837,7 +2841,7 @@ impl Clean for hir::Ty { } hir::GenericParamKind::Type { ref default, .. } => { let ty_param_def_id = - cx.tcx.hir().local_def_id_from_hir_id(param.hir_id); + cx.tcx.hir().local_def_id(param.hir_id); let mut j = 0; let type_ = generic_args.args.iter().find_map(|arg| { match arg { @@ -2861,7 +2865,7 @@ impl Clean for hir::Ty { } hir::GenericParamKind::Const { .. } => { let const_param_def_id = - cx.tcx.hir().local_def_id_from_hir_id(param.hir_id); + cx.tcx.hir().local_def_id(param.hir_id); let mut j = 0; let const_ = generic_args.args.iter().find_map(|arg| { match arg { @@ -2982,10 +2986,11 @@ impl<'tcx> Clean for Ty<'tcx> { ty::FnPtr(_) => { let ty = cx.tcx.lift(self).expect("FnPtr lift failed"); let sig = ty.fn_sig(cx.tcx); + let local_def_id = cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID); BareFunction(box BareFunctionDecl { unsafety: sig.unsafety(), generic_params: Vec::new(), - decl: (cx.tcx.hir().local_def_id(ast::CRATE_NODE_ID), sig).clean(cx), + decl: (local_def_id, sig).clean(cx), abi: sig.abi(), }) } @@ -3158,7 +3163,7 @@ impl<'tcx> Clean for ty::Const<'tcx> { impl Clean for hir::StructField { fn clean(&self, cx: &DocContext<'_>) -> Item { - let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id); + let local_did = cx.tcx.hir().local_def_id(self.hir_id); Item { name: Some(self.ident.name).clean(cx), @@ -3239,10 +3244,10 @@ impl Clean for doctree::Struct<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: StructItem(Struct { struct_type: self.struct_type, generics: self.generics.clean(cx), @@ -3259,10 +3264,10 @@ impl Clean for doctree::Union<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: UnionItem(Union { struct_type: self.struct_type, generics: self.generics.clean(cx), @@ -3306,10 +3311,10 @@ impl Clean for doctree::Enum<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: EnumItem(Enum { variants: self.variants.iter().map(|v| v.clean(cx)).collect(), generics: self.generics.clean(cx), @@ -3331,9 +3336,9 @@ impl Clean for doctree::Variant<'_> { attrs: self.attrs.clean(cx), source: self.whence.clean(cx), visibility: None, - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + def_id: cx.tcx.hir().local_def_id(self.id), inner: VariantItem(Variant { kind: self.def.clean(cx), }), @@ -3371,7 +3376,7 @@ impl Clean for ty::VariantDef { }; Item { name: Some(self.ident.clean(cx)), - attrs: inline::load_attrs(cx, self.def_id), + attrs: inline::load_attrs(cx, self.def_id).clean(cx), source: cx.tcx.def_span(self.def_id).clean(cx), visibility: Some(Inherited), def_id: self.def_id, @@ -3634,10 +3639,10 @@ impl Clean for doctree::Typedef<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: TypedefItem(Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx), @@ -3647,24 +3652,24 @@ impl Clean for doctree::Typedef<'_> { } #[derive(Clone, Debug)] -pub struct Existential { +pub struct OpaqueTy { pub bounds: Vec, pub generics: Generics, } -impl Clean for doctree::Existential<'_> { +impl Clean for doctree::OpaqueTy<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), - inner: ExistentialItem(Existential { - bounds: self.exist_ty.bounds.clean(cx), - generics: self.exist_ty.generics.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: OpaqueTyItem(OpaqueTy { + bounds: self.opaque_ty.bounds.clean(cx), + generics: self.opaque_ty.generics.clean(cx), }, false), } } @@ -3709,10 +3714,10 @@ impl Clean for doctree::Static<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: StaticItem(Static { type_: self.type_.clean(cx), mutability: self.mutability.clean(cx), @@ -3734,10 +3739,10 @@ impl Clean for doctree::Constant<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: ConstantItem(Constant { type_: self.type_.clean(cx), expr: print_const_expr(cx, self.expr), @@ -3821,10 +3826,10 @@ impl Clean> for doctree::Impl<'_> { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner: ImplItem(Impl { unsafety: self.unsafety, generics: self.generics.clean(cx), @@ -3855,7 +3860,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>, let primitive = match *target { ResolvedPath { did, .. } if did.is_local() => continue, ResolvedPath { did, .. } => { - ret.extend(inline::build_impls(cx, did)); + ret.extend(inline::build_impls(cx, did, None)); continue } _ => match target.primitive_type() { @@ -3893,7 +3898,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>, }; if let Some(did) = did { if !did.is_local() { - inline::build_impl(cx, did, ret); + inline::build_impl(cx, did, None, ret); } } } @@ -3920,7 +3925,11 @@ impl Clean> for doctree::ExternCrate<'_> { }, ); - if let Some(items) = inline::try_inline(cx, res, self.name, &mut visited) { + if let Some(items) = inline::try_inline( + cx, res, self.name, + Some(rustc::ty::Attributes::Borrowed(self.attrs)), + &mut visited + ) { return items; } } @@ -3980,7 +3989,11 @@ impl Clean> for doctree::Import<'_> { } if !denied { let mut visited = FxHashSet::default(); - if let Some(items) = inline::try_inline(cx, path.res, name, &mut visited) { + if let Some(items) = inline::try_inline( + cx, path.res, name, + Some(rustc::ty::Attributes::Borrowed(self.attrs)), + &mut visited + ) { return items; } } @@ -3991,7 +4004,7 @@ impl Clean> for doctree::Import<'_> { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(ast::CRATE_NODE_ID), + def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID), visibility: self.vis.clean(cx), stability: None, deprecation: None, @@ -4052,10 +4065,10 @@ impl Clean for doctree::ForeignItem<'_> { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + def_id: cx.tcx.hir().local_def_id(self.id), visibility: self.vis.clean(cx), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), inner, } } @@ -4081,7 +4094,7 @@ impl ToSource for syntax_pos::Span { fn name_from_pat(p: &hir::Pat) -> String { use rustc::hir::*; - debug!("Trying to get a name from pattern: {:?}", p); + debug!("trying to get a name from pattern: {:?}", p); match p.node { PatKind::Wild => "_".to_string(), @@ -4198,7 +4211,6 @@ pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId { MacroKind::Bang => (i, TypeKind::Macro), MacroKind::Attr => (i, TypeKind::Attr), MacroKind::Derive => (i, TypeKind::Derive), - MacroKind::ProcMacroStub => unreachable!(), }, Res::Def(DefKind::TraitAlias, i) => (i, TypeKind::TraitAlias), Res::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait), @@ -4238,8 +4250,8 @@ impl Clean for doctree::Macro<'_> { attrs: self.attrs.clean(cx), source: self.whence.clean(cx), visibility: Some(Public), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), + stability: cx.stability(self.hid).clean(cx), + deprecation: cx.deprecation(self.hid).clean(cx), def_id: self.def_id, inner: MacroItem(Macro { source: format!("macro_rules! {} {{\n{}}}", @@ -4266,9 +4278,9 @@ impl Clean for doctree::ProcMacro<'_> { attrs: self.attrs.clean(cx), source: self.whence.clean(cx), visibility: Some(Public), - stability: self.stab.clean(cx), - deprecation: self.depr.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + def_id: cx.tcx.hir().local_def_id(self.id), inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx), @@ -4386,29 +4398,11 @@ impl Clean for hir::TypeBindingKind { } } -pub fn def_id_to_path( - cx: &DocContext<'_>, - did: DefId, - name: Option -) -> Vec { - let crate_name = name.unwrap_or_else(|| cx.tcx.crate_name(did.krate).to_string()); - let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| { - // extern blocks have an empty name - let s = elem.data.to_string(); - if !s.is_empty() { - Some(s) - } else { - None - } - }); - once(crate_name).chain(relative).collect() -} - pub fn enter_impl_trait(cx: &DocContext<'_>, f: F) -> R where F: FnOnce() -> R, { - let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default()); + let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut()); let r = f(); assert!(cx.impl_trait_bounds.borrow().is_empty()); *cx.impl_trait_bounds.borrow_mut() = old_bounds; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 36e6a6003d..e4fba73b82 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -131,7 +131,7 @@ pub fn ty_params(mut params: Vec) -> Vec { - *bounds = ty_bounds(mem::replace(bounds, Vec::new())); + *bounds = ty_bounds(mem::take(bounds)); } _ => panic!("expected only type parameters"), } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 67ca7f407d..98ab957ecb 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -3,10 +3,9 @@ use std::fmt; use std::path::PathBuf; use errors; -use errors::emitter::{ColorConfig, HumanReadableErrorType}; use getopts; use rustc::lint::Level; -use rustc::session::early_error; +use rustc::session; use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs}; use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options, get_cmd_lint_options, ExternEntry}; @@ -221,58 +220,31 @@ impl Options { println!("{:>20} - {}", pass.name, pass.description); } println!("\nDefault passes for rustdoc:"); - for &name in passes::DEFAULT_PASSES { - println!("{:>20}", name); + for pass in passes::DEFAULT_PASSES { + println!("{:>20}", pass.name); } println!("\nPasses run with `--document-private-items`:"); - for &name in passes::DEFAULT_PRIVATE_PASSES { - println!("{:>20}", name); + for pass in passes::DEFAULT_PRIVATE_PASSES { + println!("{:>20}", pass.name); } if nightly_options::is_nightly_build() { println!("\nPasses run with `--show-coverage`:"); - for &name in passes::DEFAULT_COVERAGE_PASSES { - println!("{:>20}", name); + for pass in passes::DEFAULT_COVERAGE_PASSES { + println!("{:>20}", pass.name); } println!("\nPasses run with `--show-coverage --document-private-items`:"); - for &name in passes::PRIVATE_COVERAGE_PASSES { - println!("{:>20}", name); + for pass in passes::PRIVATE_COVERAGE_PASSES { + println!("{:>20}", pass.name); } } return Err(0); } - let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) { - Some("auto") => ColorConfig::Auto, - Some("always") => ColorConfig::Always, - Some("never") => ColorConfig::Never, - None => ColorConfig::Auto, - Some(arg) => { - early_error(ErrorOutputType::default(), - &format!("argument for --color must be `auto`, `always` or `never` \ - (instead was `{}`)", arg)); - } - }; - // FIXME: deduplicate this code from the identical code in librustc/session/config.rs - let error_format = match matches.opt_str("error-format").as_ref().map(|s| &s[..]) { - None | - Some("human") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)), - Some("json") => ErrorOutputType::Json { - pretty: false, - json_rendered: HumanReadableErrorType::Default(ColorConfig::Never), - }, - Some("pretty-json") => ErrorOutputType::Json { - pretty: true, - json_rendered: HumanReadableErrorType::Default(ColorConfig::Never), - }, - Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)), - Some(arg) => { - early_error(ErrorOutputType::default(), - &format!("argument for --error-format must be `human`, `json` or \ - `short` (instead was `{}`)", arg)); - } - }; + let color = session::config::parse_color(&matches); + let (json_rendered, _artifacts) = session::config::parse_json(&matches); + let error_format = session::config::parse_error_format(&matches, color, json_rendered); let codegen_options = build_codegen_options(matches, error_format); let debugging_options = build_debugging_options(matches, error_format); @@ -351,6 +323,9 @@ impl Options { .unwrap_or_else(|| PathBuf::from("doc")); let mut cfgs = matches.opt_strs("cfg"); cfgs.push("rustdoc".to_string()); + if should_test { + cfgs.push("doctest".to_string()); + } let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s)); @@ -403,7 +378,7 @@ impl Options { &matches.opt_strs("html-after-content"), &matches.opt_strs("markdown-before-content"), &matches.opt_strs("markdown-after-content"), - &diag, &mut id_map, edition) { + &diag, &mut id_map, edition, &None) { Some(eh) => eh, None => return Err(3), }; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 29ee59d124..87381f224d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -16,20 +16,18 @@ use rustc_metadata::cstore::CStore; use rustc_target::spec::TargetTriple; use syntax::source_map; +use syntax::attr; use syntax::feature_gate::UnstableFeatures; use syntax::json::JsonEmitter; use syntax::symbol::sym; use errors; use errors::emitter::{Emitter, EmitterWriter}; -use parking_lot::ReentrantMutex; use std::cell::RefCell; use std::mem; use rustc_data_structures::sync::{self, Lrc}; -use std::sync::Arc; use std::rc::Rc; -use crate::visit_ast::RustdocVisitor; use crate::config::{Options as RustdocOptions, RenderOptions}; use crate::clean; use crate::clean::{Clean, MAX_DEF_ID, AttributesExt}; @@ -45,17 +43,15 @@ pub type ExternalPaths = FxHashMap, clean::TypeKind)>; pub struct DocContext<'tcx> { pub tcx: TyCtxt<'tcx>, - pub resolver: Rc>>, - /// The stack of module NodeIds up till this point - pub crate_name: Option, + pub resolver: Rc>, pub cstore: Lrc, /// Later on moved into `html::render::CACHE_KEY` pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` - pub external_traits: Arc>>>, + pub external_traits: Rc>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. - pub active_extern_traits: RefCell>, + pub active_extern_traits: RefCell>, // The current set of type and lifetime substitutions, // for expanding type aliases at the HIR level: @@ -72,7 +68,6 @@ pub struct DocContext<'tcx> { /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. pub generated_synthetics: RefCell, DefId)>>, - pub all_traits: Vec, pub auto_traits: Vec, } @@ -83,9 +78,7 @@ impl<'tcx> DocContext<'tcx> { pub fn enter_resolver(&self, f: F) -> R where F: FnOnce(&mut resolve::Resolver<'_>) -> R { - let resolver = &*self.resolver; - let resolver = resolver.as_ref().unwrap(); - resolver.borrow_mut().access(f) + self.resolver.borrow_mut().access(f) } /// Call the closure with the given parameters set as @@ -167,15 +160,15 @@ impl<'tcx> DocContext<'tcx> { self.tcx.hir().as_local_hir_id(def_id) } } -} -pub trait DocAccessLevels { - fn is_doc_reachable(&self, did: DefId) -> bool; -} + pub fn stability(&self, id: HirId) -> Option { + self.tcx.hir().opt_local_def_id(id) + .and_then(|def_id| self.tcx.lookup_stability(def_id)).cloned() + } -impl DocAccessLevels for AccessLevels { - fn is_doc_reachable(&self, did: DefId) -> bool { - self.is_public(did) + pub fn deprecation(&self, id: HirId) -> Option { + self.tcx.hir().opt_local_def_id(id) + .and_then(|def_id| self.tcx.lookup_deprecation(def_id)) } } @@ -229,7 +222,7 @@ pub fn new_handler(error_format: ErrorOutputType, ) } -pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions, Vec) { +pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) { // Parse, resolve, and typecheck the given crate. let RustdocOptions { @@ -334,7 +327,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt file_loader: None, diagnostic_output: DiagnosticOutput::Default, stderr: None, - crate_name: crate_name.clone(), + crate_name, lint_caps, }; @@ -344,7 +337,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt // We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. - let resolver = abort_on_err(compiler.expansion(), sess).peek().1.clone(); + let resolver = abort_on_err(compiler.expansion(), sess).peek().1.borrow().clone(); if sess.has_errors() { sess.fatal("Compilation failed, aborting rustdoc"); @@ -363,18 +356,16 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt // to the map from defid -> hirid let access_levels = AccessLevels { map: access_levels.map.iter() - .map(|(&k, &v)| (tcx.hir().local_def_id_from_hir_id(k), v)) + .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) .collect() }; let mut renderinfo = RenderInfo::default(); renderinfo.access_levels = access_levels; - let all_traits = tcx.all_traits(LOCAL_CRATE).to_vec(); let ctxt = DocContext { tcx, resolver, - crate_name, cstore: compiler.cstore().clone(), external_traits: Default::default(), active_extern_traits: Default::default(), @@ -386,18 +377,13 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt fake_def_ids: Default::default(), all_fake_def_ids: Default::default(), generated_synthetics: Default::default(), - auto_traits: all_traits.iter().cloned().filter(|trait_def_id| { + auto_traits: tcx.all_traits(LOCAL_CRATE).iter().cloned().filter(|trait_def_id| { tcx.trait_is_auto(*trait_def_id) }).collect(), - all_traits, }; debug!("crate: {:?}", tcx.hir().krate()); - let mut krate = { - let mut v = RustdocVisitor::new(&ctxt); - v.visit(tcx.hir().krate()); - v.clean(&ctxt) - }; + let mut krate = tcx.hir().krate().clean(&ctxt); fn report_deprecated_attr(name: &str, diag: &errors::Handler) { let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \ @@ -432,14 +418,14 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt }, sym::plugins => { report_deprecated_attr("plugins = \"...\"", diag); - eprintln!("WARNING: #![doc(plugins = \"...\")] no longer functions; \ + eprintln!("WARNING: `#![doc(plugins = \"...\")]` no longer functions; \ see CVE-2018-1000622"); continue }, _ => continue, }; - for p in value.as_str().split_whitespace() { - sink.push(p.to_string()); + for name in value.as_str().split_whitespace() { + sink.push(name.to_string()); } } @@ -450,25 +436,26 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt } } - let mut passes: Vec = - passes::defaults(default_passes).iter().map(|p| p.to_string()).collect(); - passes.extend(manual_passes); + let passes = passes::defaults(default_passes).iter().chain(manual_passes.into_iter() + .flat_map(|name| { + if let Some(pass) = passes::find_pass(&name) { + Some(pass) + } else { + error!("unknown pass {}, skipping", name); + None + } + })); info!("Executing passes"); - for pass_name in &passes { - match passes::find_pass(pass_name).map(|p| p.pass) { - Some(pass) => { - debug!("running pass {}", pass_name); - krate = pass(krate, &ctxt); - } - None => error!("unknown pass {}, skipping", *pass_name), - } + for pass in passes { + debug!("running pass {}", pass.name); + krate = (pass.pass)(krate, &ctxt); } ctxt.sess().abort_if_errors(); - (krate, ctxt.renderinfo.into_inner(), render_options, passes) + (krate, ctxt.renderinfo.into_inner(), render_options) }) }) } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 2557b8d162..6e453561f6 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -3,18 +3,17 @@ pub use self::StructType::*; use syntax::ast; -use syntax::ast::{Name, NodeId}; -use syntax::attr; +use syntax::ast::Name; use syntax::ext::base::MacroKind; -use syntax::ptr::P; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::def_id::CrateNum; +use rustc::hir::ptr::P; pub struct Module<'hir> { pub name: Option, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub where_outer: Span, pub where_inner: Span, pub extern_crates: Vec>, @@ -24,15 +23,13 @@ pub struct Module<'hir> { pub enums: Vec>, pub fns: Vec>, pub mods: Vec>, - pub id: NodeId, + pub id: hir::HirId, pub typedefs: Vec>, - pub existentials: Vec>, + pub opaque_tys: Vec>, pub statics: Vec>, pub constants: Vec>, pub traits: Vec>, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub impls: Vec>, pub foreigns: Vec>, pub macros: Vec>, @@ -44,15 +41,13 @@ pub struct Module<'hir> { impl Module<'hir> { pub fn new( name: Option, - attrs: &'hir hir::HirVec, + attrs: &'hir [ast::Attribute], vis: &'hir hir::Visibility, ) -> Module<'hir> { Module { name : name, - id: ast::CRATE_NODE_ID, + id: hir::CRATE_HIR_ID, vis, - stab: None, - depr: None, where_outer: syntax_pos::DUMMY_SP, where_inner: syntax_pos::DUMMY_SP, attrs, @@ -64,7 +59,7 @@ impl Module<'hir> { fns : Vec::new(), mods : Vec::new(), typedefs : Vec::new(), - existentials: Vec::new(), + opaque_tys : Vec::new(), statics : Vec::new(), constants : Vec::new(), traits : Vec::new(), @@ -90,37 +85,31 @@ pub enum StructType { pub struct Struct<'hir> { pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub id: hir::HirId, pub struct_type: StructType, pub name: Name, pub generics: &'hir hir::Generics, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub fields: &'hir [hir::StructField], pub whence: Span, } pub struct Union<'hir> { pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub id: hir::HirId, pub struct_type: StructType, pub name: Name, pub generics: &'hir hir::Generics, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub fields: &'hir [hir::StructField], pub whence: Span, } pub struct Enum<'hir> { pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub variants: Vec>, pub generics: &'hir hir::Generics, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub id: hir::HirId, pub whence: Span, pub name: Name, @@ -129,21 +118,17 @@ pub struct Enum<'hir> { pub struct Variant<'hir> { pub name: Name, pub id: hir::HirId, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub def: &'hir hir::VariantData, - pub stab: Option, - pub depr: Option, pub whence: Span, } pub struct Function<'hir> { pub decl: &'hir hir::FnDecl, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub id: hir::HirId, pub name: Name, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub header: hir::FnHeader, pub whence: Span, pub generics: &'hir hir::Generics, @@ -155,22 +140,18 @@ pub struct Typedef<'hir> { pub gen: &'hir hir::Generics, pub name: Name, pub id: hir::HirId, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, } -pub struct Existential<'hir> { - pub exist_ty: &'hir hir::ExistTy, +pub struct OpaqueTy<'hir> { + pub opaque_ty: &'hir hir::OpaqueTy, pub name: Name, pub id: hir::HirId, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, } #[derive(Debug)] @@ -179,10 +160,8 @@ pub struct Static<'hir> { pub mutability: hir::Mutability, pub expr: hir::BodyId, pub name: Name, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub id: hir::HirId, pub whence: Span, } @@ -191,10 +170,8 @@ pub struct Constant<'hir> { pub type_: &'hir P, pub expr: hir::BodyId, pub name: Name, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub id: hir::HirId, pub whence: Span, } @@ -205,25 +182,21 @@ pub struct Trait<'hir> { pub name: Name, pub items: Vec<&'hir hir::TraitItem>, pub generics: &'hir hir::Generics, - pub bounds: &'hir hir::HirVec, - pub attrs: &'hir hir::HirVec, + pub bounds: &'hir [hir::GenericBound], + pub attrs: &'hir [ast::Attribute], pub id: hir::HirId, pub whence: Span, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, } pub struct TraitAlias<'hir> { pub name: Name, pub generics: &'hir hir::Generics, - pub bounds: &'hir hir::HirVec, - pub attrs: &'hir hir::HirVec, + pub bounds: &'hir [hir::GenericBound], + pub attrs: &'hir [ast::Attribute], pub id: hir::HirId, pub whence: Span, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, } #[derive(Debug)] @@ -235,22 +208,18 @@ pub struct Impl<'hir> { pub trait_: &'hir Option, pub for_: &'hir P, pub items: Vec<&'hir hir::ImplItem>, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub id: hir::HirId, } pub struct ForeignItem<'hir> { pub vis: &'hir hir::Visibility, - pub stab: Option, - pub depr: Option, pub id: hir::HirId, pub name: Name, pub kind: &'hir hir::ForeignItemKind, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, } @@ -258,12 +227,11 @@ pub struct ForeignItem<'hir> { // these imported macro_rules (which only have a DUMMY_NODE_ID). pub struct Macro<'hir> { pub name: Name, + pub hid: hir::HirId, pub def_id: hir::def_id::DefId, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, pub matchers: hir::HirVec, - pub stab: Option, - pub depr: Option, pub imported_from: Option, } @@ -272,7 +240,7 @@ pub struct ExternCrate<'hir> { pub cnum: CrateNum, pub path: Option, pub vis: &'hir hir::Visibility, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, } @@ -280,7 +248,7 @@ pub struct Import<'hir> { pub name: Name, pub id: hir::HirId, pub vis: &'hir hir::Visibility, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub path: &'hir hir::Path, pub glob: bool, pub whence: Span, @@ -291,10 +259,8 @@ pub struct ProcMacro<'hir> { pub id: hir::HirId, pub kind: MacroKind, pub helpers: Vec, - pub attrs: &'hir hir::HirVec, + pub attrs: &'hir [ast::Attribute], pub whence: Span, - pub stab: Option, - pub depr: Option, } pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType { diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index d604ba11d4..56f1191fee 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -4,9 +4,7 @@ use std::str; use errors; use crate::syntax::feature_gate::UnstableFeatures; use crate::syntax::edition::Edition; -use crate::html::markdown::{IdMap, ErrorCodes, Markdown}; - -use std::cell::RefCell; +use crate::html::markdown::{IdMap, ErrorCodes, Markdown, Playground}; #[derive(Clone, Debug)] pub struct ExternalHtml { @@ -24,37 +22,23 @@ pub struct ExternalHtml { impl ExternalHtml { pub fn load(in_header: &[String], before_content: &[String], after_content: &[String], md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler, - id_map: &mut IdMap, edition: Edition) + id_map: &mut IdMap, edition: Edition, playground: &Option) -> Option { let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); - load_external_files(in_header, diag) - .and_then(|ih| - load_external_files(before_content, diag) - .map(|bc| (ih, bc)) - ) - .and_then(|(ih, bc)| - load_external_files(md_before_content, diag) - .map(|m_bc| (ih, - format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), - codes, edition)))) - ) - .and_then(|(ih, bc)| - load_external_files(after_content, diag) - .map(|ac| (ih, bc, ac)) - ) - .and_then(|(ih, bc, ac)| - load_external_files(md_after_content, diag) - .map(|m_ac| (ih, bc, - format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), - codes, edition)))) - ) - .map(|(ih, bc, ac)| - ExternalHtml { - in_header: ih, - before_content: bc, - after_content: ac, - } - ) + let ih = load_external_files(in_header, diag)?; + let bc = load_external_files(before_content, diag)?; + let m_bc = load_external_files(md_before_content, diag)?; + let bc = format!("{}{}", bc, Markdown(&m_bc, &[], id_map, + codes, edition, playground).to_string()); + let ac = load_external_files(after_content, diag)?; + let m_ac = load_external_files(md_after_content, diag)?; + let ac = format!("{}{}", ac, Markdown(&m_ac, &[], id_map, + codes, edition, playground).to_string()); + Some(ExternalHtml { + in_header: ih, + before_content: bc, + after_content: ac, + }) } } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index cfa22bc27b..5482239c7c 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -105,12 +105,12 @@ pub trait DocFolder : Sized { c.module = c.module.take().and_then(|module| self.fold_item(module)); { - let guard = c.external_traits.lock(); - let traits = guard.replace(Default::default()); - guard.borrow_mut().extend(traits.into_iter().map(|(k, mut v)| { + let mut guard = c.external_traits.borrow_mut(); + let external_traits = std::mem::replace(&mut *guard, Default::default()); + *guard = external_traits.into_iter().map(|(k, mut v)| { v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect(); (k, v) - })); + }).collect(); } c } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 9e5cc03b83..9c22837bda 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -14,7 +14,6 @@ use rustc_target::spec::abi::Abi; use rustc::hir; use crate::clean::{self, PrimitiveType}; -use crate::core::DocAccessLevels; use crate::html::item_type::ItemType; use crate::html::render::{self, cache, CURRENT_LOCATION_KEY}; @@ -404,7 +403,7 @@ impl fmt::Display for clean::Path { pub fn href(did: DefId) -> Option<(String, ItemType, Vec)> { let cache = cache(); - if !did.is_local() && !cache.access_levels.is_doc_reachable(did) { + if !did.is_local() && !cache.access_levels.is_public(did) { return None } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 99ca8c43cf..5d86ee9721 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -38,17 +38,17 @@ pub fn render_with_highlighting( FileName::Custom(String::from("rustdoc-highlighting")), src.to_owned(), ); - let highlight_result = - lexer::StringReader::new_or_buffered_errs(&sess, fm, None).and_then(|lexer| { - let mut classifier = Classifier::new(lexer, sess.source_map()); - - let mut highlighted_source = vec![]; - if classifier.write_source(&mut highlighted_source).is_err() { - Err(classifier.lexer.buffer_fatal_errors()) - } else { - Ok(String::from_utf8_lossy(&highlighted_source).into_owned()) - } - }); + let highlight_result = { + let lexer = lexer::StringReader::new(&sess, fm, None); + let mut classifier = Classifier::new(lexer, sess.source_map()); + + let mut highlighted_source = vec![]; + if classifier.write_source(&mut highlighted_source).is_err() { + Err(()) + } else { + Ok(String::from_utf8_lossy(&highlighted_source).into_owned()) + } + }; match highlight_result { Ok(highlighted_source) => { @@ -59,14 +59,9 @@ pub fn render_with_highlighting( } write_footer(&mut out).unwrap(); } - Err(errors) => { - // If errors are encountered while trying to highlight, cancel the errors and just emit - // the unhighlighted source. The errors will have already been reported in the - // `check-code-block-syntax` pass. - for mut error in errors { - error.cancel(); - } - + Err(()) => { + // If errors are encountered while trying to highlight, just emit + // the unhighlighted source. write!(out, "

{}
", src).unwrap(); } } @@ -79,6 +74,7 @@ pub fn render_with_highlighting( /// each span of text in sequence. struct Classifier<'a> { lexer: lexer::StringReader<'a>, + peek_token: Option, source_map: &'a SourceMap, // State of the classifier. @@ -178,6 +174,7 @@ impl<'a> Classifier<'a> { fn new(lexer: lexer::StringReader<'a>, source_map: &'a SourceMap) -> Classifier<'a> { Classifier { lexer, + peek_token: None, source_map, in_attribute: false, in_macro: false, @@ -187,10 +184,25 @@ impl<'a> Classifier<'a> { /// Gets the next token out of the lexer. fn try_next_token(&mut self) -> Result { - match self.lexer.try_next_token() { - Ok(token) => Ok(token), - Err(_) => Err(HighlightError::LexError), + if let Some(token) = self.peek_token.take() { + return Ok(token); + } + let token = self.lexer.next_token(); + if let token::Unknown(..) = &token.kind { + return Err(HighlightError::LexError); + } + Ok(token) + } + + fn peek(&mut self) -> Result<&Token, HighlightError> { + if self.peek_token.is_none() { + let token = self.lexer.next_token(); + if let token::Unknown(..) = &token.kind { + return Err(HighlightError::LexError); + } + self.peek_token = Some(token); } + Ok(self.peek_token.as_ref().unwrap()) } /// Exhausts the `lexer` writing the output into `out`. @@ -226,7 +238,7 @@ impl<'a> Classifier<'a> { return Ok(()); }, - token::Whitespace => Class::None, + token::Whitespace | token::Unknown(..) => Class::None, token::Comment => Class::Comment, token::DocComment(..) => Class::DocComment, @@ -234,7 +246,7 @@ impl<'a> Classifier<'a> { // reference or dereference operator or a reference or pointer type, instead of the // bit-and or multiplication operator. token::BinOp(token::And) | token::BinOp(token::Star) - if self.lexer.peek() != &token::Whitespace => Class::RefKeyWord, + if self.peek()? != &token::Whitespace => Class::RefKeyWord, // Consider this as part of a macro invocation if there was a // leading identifier. @@ -257,7 +269,7 @@ impl<'a> Classifier<'a> { token::Question => Class::QuestionMark, token::Dollar => { - if self.lexer.peek().is_ident() { + if self.peek()?.is_ident() { self.in_macro_nonterminal = true; Class::MacroNonTerminal } else { @@ -280,9 +292,9 @@ impl<'a> Classifier<'a> { // as an attribute. // Case 1: #![inner_attribute] - if self.lexer.peek() == &token::Not { + if self.peek()? == &token::Not { self.try_next_token()?; // NOTE: consumes `!` token! - if self.lexer.peek() == &token::OpenDelim(token::Bracket) { + if self.peek()? == &token::OpenDelim(token::Bracket) { self.in_attribute = true; out.enter_span(Class::Attribute)?; } @@ -292,7 +304,7 @@ impl<'a> Classifier<'a> { } // Case 2: #[outer_attribute] - if self.lexer.peek() == &token::OpenDelim(token::Bracket) { + if self.peek()? == &token::OpenDelim(token::Bracket) { self.in_attribute = true; out.enter_span(Class::Attribute)?; } @@ -341,7 +353,7 @@ impl<'a> Classifier<'a> { if self.in_macro_nonterminal { self.in_macro_nonterminal = false; Class::MacroNonTerminal - } else if self.lexer.peek() == &token::Not { + } else if self.peek()? == &token::Not { self.in_macro = true; Class::Macro } else { diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index 5f1a1b3161..cf51a4eb5a 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -39,7 +39,7 @@ pub enum ItemType { Union = 19, ForeignType = 20, Keyword = 21, - Existential = 22, + OpaqueTy = 22, ProcAttribute = 23, ProcDerive = 24, TraitAlias = 25, @@ -70,7 +70,7 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::EnumItem(..) => ItemType::Enum, clean::FunctionItem(..) => ItemType::Function, clean::TypedefItem(..) => ItemType::Typedef, - clean::ExistentialItem(..) => ItemType::Existential, + clean::OpaqueTyItem(..) => ItemType::OpaqueTy, clean::StaticItem(..) => ItemType::Static, clean::ConstantItem(..) => ItemType::Constant, clean::TraitItem(..) => ItemType::Trait, @@ -92,7 +92,6 @@ impl<'a> From<&'a clean::Item> for ItemType { MacroKind::Bang => ItemType::Macro, MacroKind::Attr => ItemType::ProcAttribute, MacroKind::Derive => ItemType::ProcDerive, - MacroKind::ProcMacroStub => unreachable!(), } clean::StrippedItem(..) => unreachable!(), } @@ -145,7 +144,7 @@ impl ItemType { ItemType::AssocConst => "associatedconstant", ItemType::ForeignType => "foreigntype", ItemType::Keyword => "keyword", - ItemType::Existential => "existential", + ItemType::OpaqueTy => "opaque", ItemType::ProcAttribute => "attr", ItemType::ProcDerive => "derive", ItemType::TraitAlias => "traitalias", @@ -162,7 +161,7 @@ impl ItemType { ItemType::Trait | ItemType::Primitive | ItemType::AssocType | - ItemType::Existential | + ItemType::OpaqueTy | ItemType::TraitAlias | ItemType::ForeignType => NameSpace::Type, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c698200039..5a7deb651b 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1,9 +1,6 @@ //! Markdown formatting for rustdoc. //! -//! This module implements markdown formatting through the pulldown-cmark -//! rust-library. This module exposes all of the -//! functionality through a unit struct, `Markdown`, which has an implementation -//! of `fmt::Display`. Example usage: +//! This module implements markdown formatting through the pulldown-cmark library. //! //! ``` //! #![feature(rustc_private)] @@ -12,12 +9,11 @@ //! //! use syntax::edition::Edition; //! use rustdoc::html::markdown::{IdMap, Markdown, ErrorCodes}; -//! use std::cell::RefCell; //! //! let s = "My *markdown* _text_"; //! let mut id_map = IdMap::new(); -//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map), -//! ErrorCodes::Yes, Edition::Edition2015)); +//! let md = Markdown(s, &[], &mut id_map, ErrorCodes::Yes, Edition::Edition2015, &None); +//! let html = md.to_string(); //! // ... something using html //! ``` @@ -27,7 +23,7 @@ use rustc_data_structures::fx::FxHashMap; use std::cell::RefCell; use std::collections::VecDeque; use std::default::Default; -use std::fmt::{self, Write}; +use std::fmt::Write; use std::borrow::Cow; use std::ops::Range; use std::str; @@ -39,33 +35,43 @@ use crate::test; use pulldown_cmark::{html, CowStr, Event, Options, Parser, Tag}; +#[cfg(test)] +mod tests; + fn opts() -> Options { Options::ENABLE_TABLES | Options::ENABLE_FOOTNOTES } -/// A tuple struct that has the `fmt::Display` trait implemented. -/// When formatted, this struct will emit the HTML corresponding to the rendered -/// version of the contained markdown string. +/// When `to_string` is called, this struct will emit the HTML corresponding to +/// the rendered version of the contained markdown string. pub struct Markdown<'a>( pub &'a str, /// A list of link replacements. pub &'a [(String, String)], /// The current list of used header IDs. - pub RefCell<&'a mut IdMap>, + pub &'a mut IdMap, /// Whether to allow the use of explicit error codes in doctest lang strings. pub ErrorCodes, /// Default edition to use when parsing doctests (to add a `fn main`). pub Edition, + pub &'a Option, ); /// A tuple struct like `Markdown` that renders the markdown with a table of contents. pub struct MarkdownWithToc<'a>( pub &'a str, - pub RefCell<&'a mut IdMap>, + pub &'a mut IdMap, pub ErrorCodes, pub Edition, + pub &'a Option, ); /// A tuple struct like `Markdown` that renders the markdown escaping HTML tags. -pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition); +pub struct MarkdownHtml<'a>( + pub &'a str, + pub &'a mut IdMap, + pub ErrorCodes, + pub Edition, + pub &'a Option, +); /// A tuple struct like `Markdown` that renders only the first paragraph. pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]); @@ -152,30 +158,39 @@ fn slugify(c: char) -> Option { } } -// Information about the playground if a URL has been specified, containing an -// optional crate name and the URL. -thread_local!(pub static PLAYGROUND: RefCell, String)>> = { - RefCell::new(None) -}); +#[derive(Clone, Debug)] +pub struct Playground { + pub crate_name: Option, + pub url: String, +} /// Adds syntax highlighting and playground Run buttons to Rust code blocks. -struct CodeBlocks<'a, I: Iterator>> { +struct CodeBlocks<'p, 'a, I: Iterator>> { inner: I, check_error_codes: ErrorCodes, edition: Edition, + // Information about the playground if a URL has been specified, containing an + // optional crate name and the URL. + playground: &'p Option, } -impl<'a, I: Iterator>> CodeBlocks<'a, I> { - fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self { +impl<'p, 'a, I: Iterator>> CodeBlocks<'p, 'a, I> { + fn new( + iter: I, + error_codes: ErrorCodes, + edition: Edition, + playground: &'p Option, + ) -> Self { CodeBlocks { inner: iter, check_error_codes: error_codes, edition, + playground, } } } -impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { +impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { type Item = Event<'a>; fn next(&mut self) -> Option { @@ -210,86 +225,86 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { } let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); let text = lines.collect::>>().join("\n"); - PLAYGROUND.with(|play| { - // insert newline to clearly separate it from the - // previous block so we can shorten the html output - let mut s = String::from("\n"); - let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| { - if url.is_empty() { - return None; - } - let test = origtext.lines() - .map(|l| map_line(l).for_code()) - .collect::>>().join("\n"); - let krate = krate.as_ref().map(|s| &**s); - let (test, _) = test::make_test(&test, krate, false, - &Default::default(), edition); - let channel = if test.contains("#![feature(") { - "&version=nightly" - } else { - "" - }; - - let edition_string = format!("&edition={}", edition); - - // These characters don't need to be escaped in a URI. - // FIXME: use a library function for percent encoding. - fn dont_escape(c: u8) -> bool { - (b'a' <= c && c <= b'z') || - (b'A' <= c && c <= b'Z') || - (b'0' <= c && c <= b'9') || - c == b'-' || c == b'_' || c == b'.' || - c == b'~' || c == b'!' || c == b'\'' || - c == b'(' || c == b')' || c == b'*' - } - let mut test_escaped = String::new(); - for b in test.bytes() { - if dont_escape(b) { - test_escaped.push(char::from(b)); - } else { - write!(test_escaped, "%{:02X}", b).unwrap(); - } - } - Some(format!( - r#"Run"#, - url, test_escaped, channel, edition_string - )) - }); - - let tooltip = if ignore { - Some(("This example is not tested".to_owned(), "ignore")) - } else if compile_fail { - Some(("This example deliberately fails to compile".to_owned(), "compile_fail")) - } else if explicit_edition { - Some((format!("This code runs with edition {}", edition), "edition")) + // insert newline to clearly separate it from the + // previous block so we can shorten the html output + let mut s = String::from("\n"); + let playground_button = self.playground.as_ref().and_then(|playground| { + let krate = &playground.crate_name; + let url = &playground.url; + if url.is_empty() { + return None; + } + let test = origtext.lines() + .map(|l| map_line(l).for_code()) + .collect::>>().join("\n"); + let krate = krate.as_ref().map(|s| &**s); + let (test, _) = test::make_test(&test, krate, false, + &Default::default(), edition); + let channel = if test.contains("#![feature(") { + "&version=nightly" } else { - None + "" }; - if let Some((s1, s2)) = tooltip { - s.push_str(&highlight::render_with_highlighting( - &text, - Some(&format!("rust-example-rendered{}", - if ignore { " ignore" } - else if compile_fail { " compile_fail" } - else if explicit_edition { " edition " } - else { "" })), - playground_button.as_ref().map(String::as_str), - Some((s1.as_str(), s2)))); - Some(Event::Html(s.into())) - } else { - s.push_str(&highlight::render_with_highlighting( - &text, - Some(&format!("rust-example-rendered{}", - if ignore { " ignore" } - else if compile_fail { " compile_fail" } - else if explicit_edition { " edition " } - else { "" })), - playground_button.as_ref().map(String::as_str), - None)); - Some(Event::Html(s.into())) + let edition_string = format!("&edition={}", edition); + + // These characters don't need to be escaped in a URI. + // FIXME: use a library function for percent encoding. + fn dont_escape(c: u8) -> bool { + (b'a' <= c && c <= b'z') || + (b'A' <= c && c <= b'Z') || + (b'0' <= c && c <= b'9') || + c == b'-' || c == b'_' || c == b'.' || + c == b'~' || c == b'!' || c == b'\'' || + c == b'(' || c == b')' || c == b'*' } - }) + let mut test_escaped = String::new(); + for b in test.bytes() { + if dont_escape(b) { + test_escaped.push(char::from(b)); + } else { + write!(test_escaped, "%{:02X}", b).unwrap(); + } + } + Some(format!( + r#"Run"#, + url, test_escaped, channel, edition_string + )) + }); + + let tooltip = if ignore { + Some(("This example is not tested".to_owned(), "ignore")) + } else if compile_fail { + Some(("This example deliberately fails to compile".to_owned(), "compile_fail")) + } else if explicit_edition { + Some((format!("This code runs with edition {}", edition), "edition")) + } else { + None + }; + + if let Some((s1, s2)) = tooltip { + s.push_str(&highlight::render_with_highlighting( + &text, + Some(&format!("rust-example-rendered{}", + if ignore { " ignore" } + else if compile_fail { " compile_fail" } + else if explicit_edition { " edition " } + else { "" })), + playground_button.as_ref().map(String::as_str), + Some((s1.as_str(), s2)))); + Some(Event::Html(s.into())) + } else { + s.push_str(&highlight::render_with_highlighting( + &text, + Some(&format!("rust-example-rendered{}", + if ignore { " ignore" } + else if compile_fail { " compile_fail" } + else if explicit_edition { " edition " } + else { "" })), + playground_button.as_ref().map(String::as_str), + None)); + Some(Event::Html(s.into())) + } } } @@ -671,13 +686,12 @@ impl LangString { } } -impl<'a> fmt::Display for Markdown<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let Markdown(md, links, ref ids, codes, edition) = *self; - let mut ids = ids.borrow_mut(); +impl Markdown<'_> { + pub fn to_string(self) -> String { + let Markdown(md, links, mut ids, codes, edition, playground) = self; // This is actually common enough to special-case - if md.is_empty() { return Ok(()) } + if md.is_empty() { return String::new(); } let replacer = |_: &str, s: &str| { if let Some(&(_, ref replace)) = links.into_iter().find(|link| &*link.0 == s) { Some((replace.clone(), s.to_owned())) @@ -692,18 +706,17 @@ impl<'a> fmt::Display for Markdown<'a> { let p = HeadingLinks::new(p, None, &mut ids); let p = LinkReplacer::new(p, links); - let p = CodeBlocks::new(p, codes, edition); + let p = CodeBlocks::new(p, codes, edition, playground); let p = Footnotes::new(p); html::push_html(&mut s, p); - fmt.write_str(&s) + s } } -impl<'a> fmt::Display for MarkdownWithToc<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let MarkdownWithToc(md, ref ids, codes, edition) = *self; - let mut ids = ids.borrow_mut(); +impl MarkdownWithToc<'_> { + pub fn to_string(self) -> String { + let MarkdownWithToc(md, mut ids, codes, edition, playground) = self; let p = Parser::new_ext(md, opts()); @@ -713,24 +726,21 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> { { let p = HeadingLinks::new(p, Some(&mut toc), &mut ids); - let p = CodeBlocks::new(p, codes, edition); + let p = CodeBlocks::new(p, codes, edition, playground); let p = Footnotes::new(p); html::push_html(&mut s, p); } - write!(fmt, "", toc.into_toc())?; - - fmt.write_str(&s) + format!("{}", toc.into_toc(), s) } } -impl<'a> fmt::Display for MarkdownHtml<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let MarkdownHtml(md, ref ids, codes, edition) = *self; - let mut ids = ids.borrow_mut(); +impl MarkdownHtml<'_> { + pub fn to_string(self) -> String { + let MarkdownHtml(md, mut ids, codes, edition, playground) = self; // This is actually common enough to special-case - if md.is_empty() { return Ok(()) } + if md.is_empty() { return String::new(); } let p = Parser::new_ext(md, opts()); // Treat inline HTML as plain text. @@ -742,19 +752,19 @@ impl<'a> fmt::Display for MarkdownHtml<'a> { let mut s = String::with_capacity(md.len() * 3 / 2); let p = HeadingLinks::new(p, None, &mut ids); - let p = CodeBlocks::new(p, codes, edition); + let p = CodeBlocks::new(p, codes, edition, playground); let p = Footnotes::new(p); html::push_html(&mut s, p); - fmt.write_str(&s) + s } } -impl<'a> fmt::Display for MarkdownSummaryLine<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let MarkdownSummaryLine(md, links) = *self; +impl MarkdownSummaryLine<'_> { + pub fn to_string(self) -> String { + let MarkdownSummaryLine(md, links) = self; // This is actually common enough to special-case - if md.is_empty() { return Ok(()) } + if md.is_empty() { return String::new(); } let replacer = |_: &str, s: &str| { if let Some(&(_, ref replace)) = links.into_iter().find(|link| &*link.0 == s) { @@ -770,7 +780,7 @@ impl<'a> fmt::Display for MarkdownSummaryLine<'a> { html::push_html(&mut s, LinkReplacer::new(SummaryLine::new(p), links)); - fmt.write_str(&s) + s } } @@ -1032,27 +1042,3 @@ impl IdMap { id } } - -#[cfg(test)] -#[test] -fn test_unique_id() { - let input = ["foo", "examples", "examples", "method.into_iter","examples", - "method.into_iter", "foo", "main", "search", "methods", - "examples", "method.into_iter", "assoc_type.Item", "assoc_type.Item"]; - let expected = ["foo", "examples", "examples-1", "method.into_iter", "examples-2", - "method.into_iter-1", "foo-1", "main", "search", "methods", - "examples-3", "method.into_iter-2", "assoc_type.Item", "assoc_type.Item-1"]; - - let map = RefCell::new(IdMap::new()); - let test = || { - let mut map = map.borrow_mut(); - let actual: Vec = input.iter().map(|s| map.derive(s.to_string())).collect(); - assert_eq!(&actual[..], expected); - }; - test(); - map.borrow_mut().reset(); - test(); -} - -#[cfg(test)] -mod tests; diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index f470e649d8..a95c29038d 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -3,6 +3,26 @@ use super::plain_summary_line; use std::cell::RefCell; use syntax::edition::{Edition, DEFAULT_EDITION}; +#[test] +fn test_unique_id() { + let input = ["foo", "examples", "examples", "method.into_iter","examples", + "method.into_iter", "foo", "main", "search", "methods", + "examples", "method.into_iter", "assoc_type.Item", "assoc_type.Item"]; + let expected = ["foo", "examples", "examples-1", "method.into_iter", "examples-2", + "method.into_iter-1", "foo-1", "main", "search", "methods", + "examples-3", "method.into_iter-2", "assoc_type.Item", "assoc_type.Item-1"]; + + let map = RefCell::new(IdMap::new()); + let test = || { + let mut map = map.borrow_mut(); + let actual: Vec = input.iter().map(|s| map.derive(s.to_string())).collect(); + assert_eq!(&actual[..], expected); + }; + test(); + map.borrow_mut().reset(); + test(); +} + #[test] fn test_lang_string_parse() { fn t(s: &str, @@ -53,8 +73,8 @@ fn test_lang_string_parse() { fn test_header() { fn t(input: &str, expect: &str) { let mut map = IdMap::new(); - let output = Markdown(input, &[], RefCell::new(&mut map), - ErrorCodes::Yes, DEFAULT_EDITION).to_string(); + let output = Markdown( + input, &[], &mut map, ErrorCodes::Yes, DEFAULT_EDITION, &None).to_string(); assert_eq!(output, expect, "original: {}", input); } @@ -76,8 +96,8 @@ fn test_header() { fn test_header_ids_multiple_blocks() { let mut map = IdMap::new(); fn t(map: &mut IdMap, input: &str, expect: &str) { - let output = Markdown(input, &[], RefCell::new(map), - ErrorCodes::Yes, DEFAULT_EDITION).to_string(); + let output = Markdown(input, &[], map, + ErrorCodes::Yes, DEFAULT_EDITION, &None).to_string(); assert_eq!(output, expect, "original: {}", input); } @@ -114,8 +134,8 @@ fn test_plain_summary_line() { fn test_markdown_html_escape() { fn t(input: &str, expect: &str) { let mut idmap = IdMap::new(); - let output = MarkdownHtml(input, RefCell::new(&mut idmap), - ErrorCodes::Yes, DEFAULT_EDITION).to_string(); + let output = MarkdownHtml(input, &mut idmap, + ErrorCodes::Yes, DEFAULT_EDITION, &None).to_string(); assert_eq!(output, expect, "original: {}", input); } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2080637ecb..ea97cea942 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -75,6 +75,9 @@ use crate::html::{highlight, layout, static_files}; use minifier; +#[cfg(test)] +mod tests; + /// A pair of name and its optional document. pub type NameDoc = (String, Option); @@ -167,6 +170,7 @@ struct Context { /// The map used to ensure all generated 'id=' attributes are unique. id_map: Rc>, pub shared: Arc, + playground: Option, } struct SharedContext { @@ -182,8 +186,8 @@ struct SharedContext { pub include_sources: bool, /// The local file sources we've emitted and their respective url-paths. pub local_sources: FxHashMap, - /// All the passes that were run on this crate. - pub passes: FxHashSet, + /// Whether the collapsed pass ran + pub collapsed: bool, /// The base-URL of the issue tracker for when an item has been tagged with /// an issue number. pub issue_tracker_base_url: Option, @@ -226,15 +230,10 @@ impl SharedContext { } impl SharedContext { - /// Returns `true` if the `collapse-docs` pass was run on this crate. - pub fn was_collapsed(&self) -> bool { - self.passes.contains("collapse-docs") - } - /// Based on whether the `collapse-docs` pass was run, return either the `doc_value` or the /// `collapsed_doc_value` of the given item. pub fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option> { - if self.was_collapsed() { + if self.collapsed { item.collapsed_doc_value().map(|s| s.into()) } else { item.doc_value().map(|s| s.into()) @@ -523,7 +522,6 @@ pub fn initial_ids() -> Vec { /// Generates the documentation for `crate` into the directory `dst` pub fn run(mut krate: clean::Crate, options: RenderOptions, - passes: FxHashSet, renderinfo: RenderInfo, diag: &errors::Handler, edition: Edition) -> Result<(), Error> { @@ -554,8 +552,8 @@ pub fn run(mut krate: clean::Crate, }; let mut errors = Arc::new(ErrorStorage::new()); let mut scx = SharedContext { + collapsed: krate.collapsed, src_root, - passes, include_sources: true, local_sources: Default::default(), issue_tracker_base_url: None, @@ -577,9 +575,11 @@ pub fn run(mut krate: clean::Crate, }; // If user passed in `--playground-url` arg, we fill in crate name here + let mut playground = None; if let Some(url) = playground_url { - markdown::PLAYGROUND.with(|slot| { - *slot.borrow_mut() = Some((Some(krate.name.clone()), url)); + playground = Some(markdown::Playground { + crate_name: Some(krate.name.clone()), + url, }); } @@ -595,9 +595,9 @@ pub fn run(mut krate: clean::Crate, scx.layout.logo = s.to_string(); } (sym::html_playground_url, Some(s)) => { - markdown::PLAYGROUND.with(|slot| { - let name = krate.name.clone(); - *slot.borrow_mut() = Some((Some(name), s.to_string())); + playground = Some(markdown::Playground { + crate_name: Some(krate.name.clone()), + url: s.to_string(), }); } (sym::issue_tracker_base_url, Some(s)) => { @@ -621,6 +621,7 @@ pub fn run(mut krate: clean::Crate, edition, id_map: Rc::new(RefCell::new(id_map)), shared: Arc::new(scx), + playground, }; // Crawl the crate to build various caches used for the output @@ -656,11 +657,11 @@ pub fn run(mut krate: clean::Crate, crate_version: krate.version.take(), orphan_impl_items: Vec::new(), orphan_trait_impls: Vec::new(), - traits: krate.external_traits.lock().replace(Default::default()), + traits: krate.external_traits.replace(Default::default()), deref_trait_did, deref_mut_trait_did, owned_box_did, - masked_crates: mem::replace(&mut krate.masked_crates, Default::default()), + masked_crates: mem::take(&mut krate.masked_crates), param_names: external_param_names, aliases: Default::default(), }; @@ -874,15 +875,23 @@ fn write_shared( r#"var themes = document.getElementById("theme-choices"); var themePicker = document.getElementById("theme-picker"); +function showThemeButtonState() {{ + themes.style.display = "none"; + themePicker.style.borderBottomRightRadius = "3px"; + themePicker.style.borderBottomLeftRadius = "3px"; +}} + +function hideThemeButtonState() {{ + themes.style.display = "block"; + themePicker.style.borderBottomRightRadius = "0"; + themePicker.style.borderBottomLeftRadius = "0"; +}} + function switchThemeButtonState() {{ if (themes.style.display === "block") {{ - themes.style.display = "none"; - themePicker.style.borderBottomRightRadius = "3px"; - themePicker.style.borderBottomLeftRadius = "3px"; + showThemeButtonState(); }} else {{ - themes.style.display = "block"; - themePicker.style.borderBottomRightRadius = "0"; - themePicker.style.borderBottomLeftRadius = "0"; + hideThemeButtonState(); }} }}; @@ -895,7 +904,7 @@ function handleThemeButtonsBlur(e) {{ (!related || (related.id !== "themePicker" && (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{ - switchThemeButtonState(); + hideThemeButtonState(); }} }} @@ -1173,7 +1182,7 @@ themePicker.onblur = handleThemeButtonsBlur; title: "Index of crates", css_class: "mod", root_path: "./", - static_root_path: cx.shared.static_root_path.deref(), + static_root_path: cx.shared.static_root_path.as_deref(), description: "List of crates", keywords: BASIC_KEYWORDS, resource_suffix: &cx.shared.resource_suffix, @@ -1322,13 +1331,13 @@ fn write_minify_replacer( { let tokens: Tokens<'_> = simple_minify(contents) .into_iter() - .filter(|f| { + .filter(|(f, next)| { // We keep backlines. - minifier::js::clean_token_except(f, &|c: &Token<'_>| { + minifier::js::clean_token_except(f, next, &|c: &Token<'_>| { c.get_char() != Some(ReservedChar::Backline) }) }) - .map(|f| { + .map(|(f, _)| { minifier::js::replace_token_with(f, &|t: &Token<'_>| { match *t { Token::Keyword(Keyword::Null) => Some(Token::Other("N")), @@ -1363,7 +1372,7 @@ fn write_minify_replacer( // shouldn't be aggregated. |tokens, pos| { pos < 2 || - !tokens[pos - 1].is_char(ReservedChar::OpenBracket) || + !tokens[pos - 1].eq_char(ReservedChar::OpenBracket) || tokens[pos - 2].get_other() != Some("searchIndex") } ) @@ -1513,7 +1522,7 @@ impl<'a> SourceCollector<'a> { title: &title, css_class: "source", root_path: &root_path, - static_root_path: self.scx.static_root_path.deref(), + static_root_path: self.scx.static_root_path.as_deref(), description: &desc, keywords: BASIC_KEYWORDS, resource_suffix: &self.scx.resource_suffix, @@ -1883,7 +1892,7 @@ struct AllTypes { macros: FxHashSet, functions: FxHashSet, typedefs: FxHashSet, - existentials: FxHashSet, + opaque_tys: FxHashSet, statics: FxHashSet, constants: FxHashSet, keywords: FxHashSet, @@ -1904,7 +1913,7 @@ impl AllTypes { macros: new_set(100), functions: new_set(100), typedefs: new_set(100), - existentials: new_set(100), + opaque_tys: new_set(100), statics: new_set(100), constants: new_set(100), keywords: new_set(100), @@ -1929,7 +1938,7 @@ impl AllTypes { ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)), ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)), ItemType::Typedef => self.typedefs.insert(ItemEntry::new(new_url, name)), - ItemType::Existential => self.existentials.insert(ItemEntry::new(new_url, name)), + ItemType::OpaqueTy => self.opaque_tys.insert(ItemEntry::new(new_url, name)), ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)), ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)), ItemType::ProcAttribute => self.attributes.insert(ItemEntry::new(new_url, name)), @@ -1979,7 +1988,7 @@ impl fmt::Display for AllTypes { print_entries(f, &self.functions, "Functions", "functions")?; print_entries(f, &self.typedefs, "Typedefs", "typedefs")?; print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?; - print_entries(f, &self.existentials, "Existentials", "existentials")?; + print_entries(f, &self.opaque_tys, "Opaque Types", "opaque-types")?; print_entries(f, &self.statics, "Statics", "statics")?; print_entries(f, &self.constants, "Constants", "constants") } @@ -2110,7 +2119,7 @@ impl Context { title: "List of all items in this crate", css_class: "mod", root_path: "../", - static_root_path: self.shared.static_root_path.deref(), + static_root_path: self.shared.static_root_path.as_deref(), description: "List of all items in this crate", keywords: BASIC_KEYWORDS, resource_suffix: &self.shared.resource_suffix, @@ -2137,7 +2146,7 @@ impl Context { self.shared.fs.write(&final_file, &v)?; // Generating settings page. - let settings = Settings::new(self.shared.static_root_path.deref().unwrap_or("./"), + let settings = Settings::new(self.shared.static_root_path.as_deref().unwrap_or("./"), &self.shared.resource_suffix); page.title = "Rustdoc settings"; page.description = "Settings of Rustdoc"; @@ -2195,7 +2204,7 @@ impl Context { let page = layout::Page { css_class: tyname, root_path: &self.root_path(), - static_root_path: self.shared.static_root_path.deref(), + static_root_path: self.shared.static_root_path.as_deref(), title: &title, description: &desc, keywords: &keywords, @@ -2471,14 +2480,13 @@ impl<'a> fmt::Display for Item<'a> { MacroKind::Bang => write!(fmt, "Macro ")?, MacroKind::Attr => write!(fmt, "Attribute Macro ")?, MacroKind::Derive => write!(fmt, "Derive Macro ")?, - MacroKind::ProcMacroStub => unreachable!(), } clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?, clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?, clean::ConstantItem(..) => write!(fmt, "Constant ")?, clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?, clean::KeywordItem(..) => write!(fmt, "Keyword ")?, - clean::ExistentialItem(..) => write!(fmt, "Existential Type ")?, + clean::OpaqueTyItem(..) => write!(fmt, "Opaque Type ")?, clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?, _ => { // We don't generate pages for any other type. @@ -2517,7 +2525,7 @@ impl<'a> fmt::Display for Item<'a> { clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c), clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item), clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k), - clean::ExistentialItem(ref e, _) => item_existential(fmt, self.cx, self.item, e), + clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, self.cx, self.item, e), clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta), _ => { // We don't generate pages for any other type. @@ -2541,7 +2549,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String { s } -fn shorter<'a>(s: Option<&'a str>) -> String { +fn shorter(s: Option<&str>) -> String { match s { Some(s) => s.lines() .skip_while(|s| s.chars().all(|c| c.is_whitespace())) @@ -2587,8 +2595,8 @@ fn render_markdown(w: &mut fmt::Formatter<'_>, write!(w, "
{}{}
", if is_hidden { " hidden" } else { "" }, prefix, - Markdown(md_text, &links, RefCell::new(&mut ids), - cx.codes, cx.edition)) + Markdown(md_text, &links, &mut ids, + cx.codes, cx.edition, &cx.playground).to_string()) } fn document_short( @@ -2858,7 +2866,7 @@ fn item_module(w: &mut fmt::Formatter<'_>, cx: &Context, ", name = *myitem.name.as_ref().unwrap(), stab_tags = stability_tags(myitem), - docs = MarkdownSummaryLine(doc_value, &myitem.links()), + docs = MarkdownSummaryLine(doc_value, &myitem.links()).to_string(), class = myitem.type_(), add = add, stab = stab.unwrap_or_else(|| String::new()), @@ -2953,8 +2961,8 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { if let Some(note) = note { let mut ids = cx.id_map.borrow_mut(); - let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes, cx.edition); - message.push_str(&format!(": {}", html)); + let html = MarkdownHtml(¬e, &mut ids, error_codes, cx.edition, &cx.playground); + message.push_str(&format!(": {}", html.to_string())); } stability.push(format!("
{}
", message)); } @@ -3002,7 +3010,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { message = format!( "
{}{}
", message, - MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes, cx.edition) + MarkdownHtml( + &unstable_reason, + &mut ids, + error_codes, + cx.edition, + &cx.playground, + ).to_string() ); } @@ -3810,7 +3824,6 @@ const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[ sym::must_use, sym::no_mangle, sym::repr, - sym::unsafe_destructor_blind_to_params, sym::non_exhaustive ]; @@ -4233,8 +4246,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { let mut ids = cx.id_map.borrow_mut(); write!(w, "
{}
", - Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids), - cx.codes, cx.edition))?; + Markdown(&*dox, &i.impl_item.links(), &mut ids, + cx.codes, cx.edition, &cx.playground).to_string())?; } } @@ -4389,15 +4402,15 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt Ok(()) } -fn item_existential( +fn item_opaque_ty( w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, - t: &clean::Existential, + t: &clean::OpaqueTy, ) -> fmt::Result { - write!(w, "
")?;
+    write!(w, "
")?;
     render_attributes(w, it, false)?;
-    write!(w, "existential type {}{}{where_clause}: {bounds};
", + write!(w, "type {}{}{where_clause} = impl {bounds};
", it.name.as_ref().unwrap(), t.generics, where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, @@ -4578,12 +4591,13 @@ fn get_methods( i: &clean::Impl, for_deref: bool, used_links: &mut FxHashSet, + deref_mut: bool, ) -> Vec { i.items.iter().filter_map(|item| { match item.name { // Maybe check with clean::Visibility::Public as well? Some(ref name) if !name.is_empty() && item.visibility.is_some() && item.is_method() => { - if !for_deref || should_render_item(item, false) { + if !for_deref || should_render_item(item, deref_mut) { Some(format!("{}", get_next_url(used_links, format!("method.{}", name)), name)) @@ -4624,7 +4638,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_none()) .flat_map(move |i| get_methods(i.inner_impl(), false, - &mut used_links_bor.borrow_mut())) + &mut used_links_bor.borrow_mut(), false)) .collect::>(); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); @@ -4658,7 +4672,8 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_none()) .flat_map(|i| get_methods(i.inner_impl(), true, - &mut used_links)) + &mut used_links, + true)) .collect::>(); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); @@ -4985,7 +5000,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) { ItemType::AssocConst => ("associated-consts", "Associated Constants"), ItemType::ForeignType => ("foreign-types", "Foreign Types"), ItemType::Keyword => ("keywords", "Keywords"), - ItemType::Existential => ("existentials", "Existentials"), + ItemType::OpaqueTy => ("opaque-types", "Opaque Types"), ItemType::ProcAttribute => ("attributes", "Attribute Macros"), ItemType::ProcDerive => ("derives", "Derive Macros"), ItemType::TraitAlias => ("trait-aliases", "Trait aliases"), @@ -5009,7 +5024,8 @@ fn sidebar_module(fmt: &mut fmt::Formatter<'_>, _it: &clean::Item, ItemType::Enum, ItemType::Constant, ItemType::Static, ItemType::Trait, ItemType::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl, ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant, - ItemType::AssocType, ItemType::AssocConst, ItemType::ForeignType] { + ItemType::AssocType, ItemType::AssocConst, ItemType::ForeignType, + ItemType::Keyword] { if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) { let (short, name) = item_ty_to_strs(&myty); sidebar.push_str(&format!("
  • {name}
  • ", @@ -5092,7 +5108,6 @@ fn item_proc_macro(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, m } write!(w, "")?; } - _ => {} } document(w, cx, it) } @@ -5240,33 +5255,3 @@ fn get_generics(clean_type: &clean::Type) -> Option> { pub fn cache() -> Arc { CACHE_KEY.with(|c| c.borrow().clone()) } - -#[cfg(test)] -#[test] -fn test_name_key() { - assert_eq!(name_key("0"), ("", 0, 1)); - assert_eq!(name_key("123"), ("", 123, 0)); - assert_eq!(name_key("Fruit"), ("Fruit", 0, 0)); - assert_eq!(name_key("Fruit0"), ("Fruit", 0, 1)); - assert_eq!(name_key("Fruit0000"), ("Fruit", 0, 4)); - assert_eq!(name_key("Fruit01"), ("Fruit", 1, 1)); - assert_eq!(name_key("Fruit10"), ("Fruit", 10, 0)); - assert_eq!(name_key("Fruit123"), ("Fruit", 123, 0)); -} - -#[cfg(test)] -#[test] -fn test_name_sorting() { - let names = ["Apple", - "Banana", - "Fruit", "Fruit0", "Fruit00", - "Fruit1", "Fruit01", - "Fruit2", "Fruit02", - "Fruit20", - "Fruit30x", - "Fruit100", - "Pear"]; - let mut sorted = names.to_owned(); - sorted.sort_by_key(|&s| name_key(s)); - assert_eq!(names, sorted); -} diff --git a/src/librustdoc/html/render/tests.rs b/src/librustdoc/html/render/tests.rs new file mode 100644 index 0000000000..1848b575e4 --- /dev/null +++ b/src/librustdoc/html/render/tests.rs @@ -0,0 +1,29 @@ +use super::*; + +#[test] +fn test_name_key() { + assert_eq!(name_key("0"), ("", 0, 1)); + assert_eq!(name_key("123"), ("", 123, 0)); + assert_eq!(name_key("Fruit"), ("Fruit", 0, 0)); + assert_eq!(name_key("Fruit0"), ("Fruit", 0, 1)); + assert_eq!(name_key("Fruit0000"), ("Fruit", 0, 4)); + assert_eq!(name_key("Fruit01"), ("Fruit", 1, 1)); + assert_eq!(name_key("Fruit10"), ("Fruit", 10, 0)); + assert_eq!(name_key("Fruit123"), ("Fruit", 123, 0)); +} + +#[test] +fn test_name_sorting() { + let names = ["Apple", + "Banana", + "Fruit", "Fruit0", "Fruit00", + "Fruit1", "Fruit01", + "Fruit2", "Fruit02", + "Fruit20", + "Fruit30x", + "Fruit100", + "Pear"]; + let mut sorted = names.to_owned(); + sorted.sort_by_key(|&s| name_key(s)); + assert_eq!(names, sorted); +} diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 0493bf7c5c..59d10668f1 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -146,6 +146,10 @@ img { max-width: 100%; } +li { + position: relative; +} + .source .content { margin-top: 50px; max-width: none; @@ -635,6 +639,7 @@ a { margin-top: 5px; padding: 6px; padding-right: 19px; + flex: none; border: 0; border-right: 0; border-radius: 4px 0 0 4px; diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index d5dea247d2..e3927350d1 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -64,13 +64,11 @@ function usableLocalStorage() { // preferences deny access to localStorage, e.g., to prevent storage of // "cookies" (or cookie-likes, as is the case here). try { - window.localStorage; + return window.localStorage !== null && window.localStorage !== undefined; } catch(err) { // Storage is supported, but browser preferences deny access to it. return false; } - - return true; } function updateLocalStorage(name, value) { diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs index 2564c611e5..2da7aceae8 100644 --- a/src/librustdoc/html/toc.rs +++ b/src/librustdoc/html/toc.rs @@ -119,7 +119,7 @@ impl TocBuilder { /// Push a level `level` heading into the appropriate place in the /// hierarchy, returning a string containing the section number in /// `..` format. - pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str { + pub fn push(&mut self, level: u32, name: String, id: String) -> &str { assert!(level >= 1); // collapse all previous sections into their parents until we diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ba423300e0..e30b35937d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,7 +1,3 @@ -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/")] @@ -21,6 +17,8 @@ #![feature(drain_filter)] #![feature(inner_deref)] #![feature(never_type)] +#![feature(mem_take)] +#![feature(unicode_internals)] #![recursion_limit="256"] @@ -46,7 +44,6 @@ use std::default::Default; use std::env; use std::panic; use std::process; -use std::sync::mpsc::channel; use rustc::session::{early_warn, early_error}; use rustc::session::config::{ErrorOutputType, RustcOptGroup}; @@ -82,7 +79,6 @@ struct Output { krate: clean::Crate, renderinfo: html::render::RenderInfo, renderopts: config::RenderOptions, - passes: Vec, } pub fn main() { @@ -288,6 +284,12 @@ fn opts() -> Vec { "How errors and other messages are produced", "human|json|short") }), + stable("json", |o| { + o.optopt("", + "json", + "Configure the structure of JSON diagnostics", + "CONFIG") + }), unstable("disable-minification", |o| { o.optflag("", "disable-minification", @@ -415,14 +417,13 @@ fn main_options(options: config::Options) -> i32 { return rustc_driver::EXIT_SUCCESS; } - let Output { krate, passes, renderinfo, renderopts } = out; + let Output { krate, renderinfo, renderopts } = out; info!("going to format"); let (error_format, treat_err_as_bug, ui_testing, edition) = diag_opts; let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing); match html::render::run( krate, renderopts, - passes.into_iter().collect(), renderinfo, &diag, edition, @@ -450,12 +451,10 @@ where R: 'static + Send, // First, parse the crate and extract all relevant information. info!("starting to run rustc"); - let (tx, rx) = channel(); - let result = rustc_driver::report_ices_to_stderr_if_any(move || { let crate_name = options.crate_name.clone(); let crate_version = options.crate_version.clone(); - let (mut krate, renderinfo, renderopts, passes) = core::run_core(options); + let (mut krate, renderinfo, renderopts) = core::run_core(options); info!("finished with rustc"); @@ -465,16 +464,15 @@ where R: 'static + Send, krate.version = crate_version; - tx.send(f(Output { + f(Output { krate: krate, renderinfo: renderinfo, renderopts, - passes: passes - })).unwrap(); + }) }); match result { - Ok(()) => rx.recv().unwrap(), + Ok(output) => output, Err(_) => panic::resume_unwind(Box::new(errors::FatalErrorMarker)), } } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index b0a37ea9c8..eaaae3261c 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -1,7 +1,6 @@ use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; -use std::cell::RefCell; use errors; use testing; @@ -17,7 +16,7 @@ use crate::html::markdown::{ErrorCodes, IdMap, Markdown, MarkdownWithToc, find_t use crate::test::{TestOptions, Collector}; /// Separate any lines at the start of the file that begin with `# ` or `%`. -fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) { +fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) { let mut metadata = Vec::new(); let mut count = 0; @@ -60,9 +59,10 @@ pub fn render( }; let playground_url = options.markdown_playground_url .or(options.playground_url); - if let Some(playground) = playground_url { - markdown::PLAYGROUND.with(|s| { *s.borrow_mut() = Some((None, playground)); }); - } + let playground = playground_url.map(|url| markdown::Playground { + crate_name: None, + url, + }); let mut out = match File::create(&output) { Err(e) => { @@ -82,9 +82,9 @@ pub fn render( let mut ids = IdMap::new(); let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); let text = if !options.markdown_no_toc { - MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition).to_string() + MarkdownWithToc(text, &mut ids, error_codes, edition, &playground).to_string() } else { - Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition).to_string() + Markdown(text, &[], &mut ids, error_codes, edition, &playground).to_string() }; let err = write!( diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index f6ab1290da..67aa014a78 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -32,23 +32,20 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { dox[code_block.code].to_owned(), ); - let errors = Lexer::new_or_buffered_errs(&sess, source_file, None).and_then(|mut lexer| { - while let Ok(token::Token { kind, .. }) = lexer.try_next_token() { - if kind == token::Eof { - break; + let has_errors = { + let mut has_errors = false; + let mut lexer = Lexer::new(&sess, source_file, None); + loop { + match lexer.next_token().kind { + token::Eof => break, + token::Unknown(..) => has_errors = true, + _ => (), } } + has_errors + }; - let errors = lexer.buffer_fatal_errors(); - - if !errors.is_empty() { - Err(errors) - } else { - Ok(()) - } - }); - - if let Err(errors) = errors { + if has_errors { let mut diag = if let Some(sp) = super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs) { @@ -57,11 +54,6 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { .sess() .struct_span_warn(sp, "could not parse code block as Rust code"); - for mut err in errors { - diag.note(&format!("error from rustc: {}", err.message())); - err.cancel(); - } - if code_block.syntax.is_none() && code_block.is_fenced { let sp = sp.from_inner(InnerSpan::new(0, 3)); diag.span_suggestion( @@ -77,15 +69,10 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { // We couldn't calculate the span of the markdown block that had the error, so our // diagnostics are going to be a bit lacking. let mut diag = self.cx.sess().struct_span_warn( - super::span_of_attrs(&item.attrs), + super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()), "doc comment contains an invalid Rust code block", ); - for mut err in errors { - // Don't bother reporting the error, because we can't show where it happened. - err.cancel(); - } - if code_block.syntax.is_none() && code_block.is_fenced { diag.help("mark blocks that do not contain Rust code as text: ```text"); } diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index 8666ba357b..31288345ce 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -4,7 +4,7 @@ use crate::fold; use crate::fold::{DocFolder}; use crate::passes::Pass; -use std::mem::replace; +use std::mem::take; pub const COLLAPSE_DOCS: Pass = Pass { name: "collapse-docs", @@ -30,7 +30,9 @@ impl DocFragment { } pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate { - Collapser.fold_crate(krate) + let mut krate = Collapser.fold_crate(krate); + krate.collapsed = true; + krate } struct Collapser; @@ -46,7 +48,7 @@ fn collapse(doc_strings: &mut Vec) { let mut docs = vec![]; let mut last_frag: Option = None; - for frag in replace(doc_strings, vec![]) { + for frag in take(doc_strings) { if let Some(mut curr_frag) = last_frag.take() { let curr_kind = curr_frag.kind(); let new_kind = frag.kind(); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index bb85fe898d..7f4a17225e 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -6,6 +6,7 @@ use rustc::lint as lint; use rustc::ty; use syntax; use syntax::ast::{self, Ident}; +use syntax::ext::base::SyntaxExtensionKind; use syntax::feature_gate::UnstableFeatures; use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; @@ -60,16 +61,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { { let cx = self.cx; - // In case we're in a module, try to resolve the relative - // path. - if let Some(id) = parent_id.or(self.mod_ids.last().cloned()) { - // FIXME: `with_scope` requires the `NodeId` of a module. - let node_id = cx.tcx.hir().hir_to_node_id(id); + // In case we're in a module, try to resolve the relative path. + if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) { + let module_id = cx.tcx.hir().hir_to_node_id(module_id); let result = cx.enter_resolver(|resolver| { - resolver.with_scope(node_id, |resolver| { - resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns == ValueNS) - }) + resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id) }); + let result = match result { + Ok((_, Res::Err)) => Err(()), + _ => result, + }; if let Ok((_, res)) = result { let res = res.map_id(|_| panic!("unexpected node_id")); @@ -80,6 +81,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { Res::Def(DefKind::AssocTy, _) => false, Res::Def(DefKind::Variant, _) => return handle_variant(cx, res), // Not a trait item; just return what we found. + Res::PrimTy(..) => return Ok((res, Some(path_str.to_owned()))), _ => return Ok((res, None)) }; @@ -128,11 +130,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .ok_or(()); } - // FIXME: `with_scope` requires the `NodeId` of a module. - let node_id = cx.tcx.hir().hir_to_node_id(id); - let (_, ty_res) = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| { - resolver.resolve_str_path_error(DUMMY_SP, &path, false) - }))?; + let (_, ty_res) = cx.enter_resolver(|resolver| { + resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id) + })?; + if let Res::Err = ty_res { + return Err(()); + } let ty_res = ty_res.map_id(|_| panic!("unexpected node_id")); match ty_res { Res::Def(DefKind::Struct, did) @@ -425,19 +428,13 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { /// Resolves a string as a macro. fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { - use syntax::ext::base::{MacroKind, SyntaxExtensionKind}; - let segment = ast::PathSegment::from_ident(Ident::from_str(path_str)); - let path = ast::Path { segments: vec![segment], span: DUMMY_SP }; + let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { - let parent_scope = resolver.dummy_parent_scope(); - if let Ok(res) = resolver.resolve_macro_to_res_inner(&path, MacroKind::Bang, - &parent_scope, false, false) { - if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res { - // skip proc-macro stubs, they'll cause `get_macro` to crash - } else { - if let SyntaxExtensionKind::LegacyBang(..) = resolver.get_macro(res).kind { - return Some(res.map_id(|_| panic!("unexpected id"))); - } + if let Ok((Some(ext), res)) = resolver.resolve_macro_path( + &path, None, &resolver.dummy_parent_scope(), false, false + ) { + if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { + return Some(res.map_id(|_| panic!("unexpected id"))); } } if let Some(res) = resolver.all_macros.get(&Symbol::intern(path_str)) { @@ -467,7 +464,7 @@ fn resolution_failure( } }; let attrs = &item.attrs; - let sp = span_of_attrs(attrs); + let sp = span_of_attrs(attrs).unwrap_or(item.source.span()); let mut diag = cx.tcx.struct_span_lint_hir( lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, @@ -519,7 +516,7 @@ fn ambiguity_error( } }; let attrs = &item.attrs; - let sp = span_of_attrs(attrs); + let sp = span_of_attrs(attrs).unwrap_or(item.source.span()); let mut msg = format!("`{}` is ", path_str); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 70cd4b7219..86e4e9fd95 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -4,7 +4,7 @@ use crate::fold::DocFolder; use super::Pass; use rustc::util::nodemap::FxHashSet; -use rustc::hir::def_id::DefId; +use rustc::hir::def_id::{LOCAL_CRATE, DefId}; use syntax::symbol::sym; pub const COLLECT_TRAIT_IMPLS: Pass = Pass { @@ -30,7 +30,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { for &cnum in cx.tcx.crates().iter() { for &did in cx.tcx.all_trait_implementations(cnum).iter() { - inline::build_impl(cx, did, &mut new_items); + inline::build_impl(cx, did, None, &mut new_items); } } @@ -66,7 +66,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { if !def_id.is_local() { - inline::build_impl(cx, def_id, &mut new_items); + inline::build_impl(cx, def_id, None, &mut new_items); // FIXME(eddyb) is this `doc(hidden)` check needed? if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) { @@ -116,10 +116,10 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations` // doesn't work with it anyway, so pull them from the HIR map instead - for &trait_did in cx.all_traits.iter() { + for &trait_did in cx.tcx.all_traits(LOCAL_CRATE).iter() { for &impl_node in cx.tcx.hir().trait_impls(trait_did) { - let impl_did = cx.tcx.hir().local_def_id_from_hir_id(impl_node); - inline::build_impl(cx, impl_did, &mut new_items); + let impl_did = cx.tcx.hir().local_def_id(impl_node); + inline::build_impl(cx, impl_did, None, &mut new_items); } } diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 8fc6b9fdbe..49a34c7e46 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -10,7 +10,7 @@ use syntax_pos::{DUMMY_SP, InnerSpan, Span}; use std::ops::Range; use crate::clean::{self, GetDefId, Item}; -use crate::core::{DocContext, DocAccessLevels}; +use crate::core::DocContext; use crate::fold::{DocFolder, StripItem}; use crate::html::markdown::{find_testable_code, ErrorCodes, LangString}; @@ -57,8 +57,9 @@ pub struct Pass { pub description: &'static str, } + /// The full list of passes. -pub const PASSES: &'static [Pass] = &[ +pub const PASSES: &[Pass] = &[ CHECK_PRIVATE_ITEMS_DOC_TESTS, STRIP_HIDDEN, UNINDENT_COMMENTS, @@ -73,43 +74,43 @@ pub const PASSES: &'static [Pass] = &[ ]; /// The list of passes run by default. -pub const DEFAULT_PASSES: &[&str] = &[ - "collect-trait-impls", - "collapse-docs", - "unindent-comments", - "check-private-items-doc-tests", - "strip-hidden", - "strip-private", - "collect-intra-doc-links", - "check-code-block-syntax", - "propagate-doc-cfg", +pub const DEFAULT_PASSES: &[Pass] = &[ + COLLECT_TRAIT_IMPLS, + COLLAPSE_DOCS, + UNINDENT_COMMENTS, + CHECK_PRIVATE_ITEMS_DOC_TESTS, + STRIP_HIDDEN, + STRIP_PRIVATE, + COLLECT_INTRA_DOC_LINKS, + CHECK_CODE_BLOCK_SYNTAX, + PROPAGATE_DOC_CFG, ]; /// The list of default passes run with `--document-private-items` is passed to rustdoc. -pub const DEFAULT_PRIVATE_PASSES: &[&str] = &[ - "collect-trait-impls", - "collapse-docs", - "unindent-comments", - "check-private-items-doc-tests", - "strip-priv-imports", - "collect-intra-doc-links", - "check-code-block-syntax", - "propagate-doc-cfg", +pub const DEFAULT_PRIVATE_PASSES: &[Pass] = &[ + COLLECT_TRAIT_IMPLS, + COLLAPSE_DOCS, + UNINDENT_COMMENTS, + CHECK_PRIVATE_ITEMS_DOC_TESTS, + STRIP_PRIV_IMPORTS, + COLLECT_INTRA_DOC_LINKS, + CHECK_CODE_BLOCK_SYNTAX, + PROPAGATE_DOC_CFG, ]; /// The list of default passes run when `--doc-coverage` is passed to rustdoc. -pub const DEFAULT_COVERAGE_PASSES: &'static [&'static str] = &[ - "collect-trait-impls", - "strip-hidden", - "strip-private", - "calculate-doc-coverage", +pub const DEFAULT_COVERAGE_PASSES: &[Pass] = &[ + COLLECT_TRAIT_IMPLS, + STRIP_HIDDEN, + STRIP_PRIVATE, + CALCULATE_DOC_COVERAGE, ]; /// The list of default passes run when `--doc-coverage --document-private-items` is passed to /// rustdoc. -pub const PRIVATE_COVERAGE_PASSES: &'static [&'static str] = &[ - "collect-trait-impls", - "calculate-doc-coverage", +pub const PRIVATE_COVERAGE_PASSES: &[Pass] = &[ + COLLECT_TRAIT_IMPLS, + CALCULATE_DOC_COVERAGE, ]; /// A shorthand way to refer to which set of passes to use, based on the presence of @@ -124,7 +125,7 @@ pub enum DefaultPassOption { } /// Returns the given default set of passes. -pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] { +pub fn defaults(default_set: DefaultPassOption) -> &'static [Pass] { match default_set { DefaultPassOption::Default => DEFAULT_PASSES, DefaultPassOption::Private => DEFAULT_PRIVATE_PASSES, @@ -159,7 +160,7 @@ impl<'a> DocFolder for Stripper<'a> { return ret; } // These items can all get re-exported - clean::ExistentialItem(..) + clean::OpaqueTyItem(..) | clean::TypedefItem(..) | clean::StaticItem(..) | clean::StructItem(..) @@ -338,7 +339,7 @@ pub fn look_for_tests<'tcx>( find_testable_code(&dox, &mut tests, ErrorCodes::No); if check_missing_code == true && tests.found_tests == 0 { - let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span()); + let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); let mut diag = cx.tcx.struct_span_lint_hir( lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id, @@ -347,24 +348,27 @@ pub fn look_for_tests<'tcx>( diag.emit(); } else if check_missing_code == false && tests.found_tests > 0 && - !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) { + !cx.renderinfo.borrow().access_levels.is_public(item.def_id) { let mut diag = cx.tcx.struct_span_lint_hir( lint::builtin::PRIVATE_DOC_TESTS, hir_id, - span_of_attrs(&item.attrs), + span_of_attrs(&item.attrs).unwrap_or(item.source.span()), "Documentation test in private item"); diag.emit(); } } /// Returns a span encompassing all the given attributes. -crate fn span_of_attrs(attrs: &clean::Attributes) -> Span { +crate fn span_of_attrs(attrs: &clean::Attributes) -> Option { if attrs.doc_strings.is_empty() { - return DUMMY_SP; + return None; } let start = attrs.doc_strings[0].span(); + if start == DUMMY_SP { + return None; + } let end = attrs.doc_strings.last().expect("No doc strings provided").span(); - start.to(end) + Some(start.to(end)) } /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. @@ -390,7 +394,7 @@ crate fn source_span_for_markdown_range( let snippet = cx .sess() .source_map() - .span_to_snippet(span_of_attrs(attrs)) + .span_to_snippet(span_of_attrs(attrs)?) .ok()?; let starting_line = markdown[..md_range.start].matches('\n').count(); @@ -440,10 +444,8 @@ crate fn source_span_for_markdown_range( } } - let sp = span_of_attrs(attrs).from_inner(InnerSpan::new( + Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new( md_range.start + start_bytes, md_range.end + start_bytes + end_bytes, - )); - - Some(sp) + ))) } diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index 95e322f70b..7ad98242fd 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -7,6 +7,9 @@ use crate::core::DocContext; use crate::fold::{self, DocFolder}; use crate::passes::Pass; +#[cfg(test)] +mod tests; + pub const UNINDENT_COMMENTS: Pass = Pass { name: "unindent-comments", pass: unindent_comments, @@ -102,79 +105,3 @@ fn unindent(s: &str) -> String { s.to_string() } } - -#[cfg(test)] -mod unindent_tests { - use super::unindent; - - #[test] - fn should_unindent() { - let s = " line1\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); - } - - #[test] - fn should_unindent_multiple_paragraphs() { - let s = " line1\n\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\n\nline2"); - } - - #[test] - fn should_leave_multiple_indent_levels() { - // Line 2 is indented another level beyond the - // base indentation and should be preserved - let s = " line1\n\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\n\n line2"); - } - - #[test] - fn should_ignore_first_line_indent() { - // The first line of the first paragraph may not be indented as - // far due to the way the doc string was written: - // - // #[doc = "Start way over here - // and continue here"] - let s = "line1\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); - } - - #[test] - fn should_not_ignore_first_line_indent_in_a_single_line_para() { - let s = "line1\n\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\n\n line2"); - } - - #[test] - fn should_unindent_tabs() { - let s = "\tline1\n\tline2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); - } - - #[test] - fn should_trim_mixed_indentation() { - let s = "\t line1\n\t line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); - - let s = " \tline1\n \tline2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); - } - - #[test] - fn should_not_trim() { - let s = "\t line1 \n\t line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1 \nline2"); - - let s = " \tline1 \n \tline2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1 \nline2"); - } -} diff --git a/src/librustdoc/passes/unindent_comments/tests.rs b/src/librustdoc/passes/unindent_comments/tests.rs new file mode 100644 index 0000000000..c39c03e124 --- /dev/null +++ b/src/librustdoc/passes/unindent_comments/tests.rs @@ -0,0 +1,72 @@ +use super::*; + +#[test] +fn should_unindent() { + let s = " line1\n line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\nline2"); +} + +#[test] +fn should_unindent_multiple_paragraphs() { + let s = " line1\n\n line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\n\nline2"); +} + +#[test] +fn should_leave_multiple_indent_levels() { + // Line 2 is indented another level beyond the + // base indentation and should be preserved + let s = " line1\n\n line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\n\n line2"); +} + +#[test] +fn should_ignore_first_line_indent() { + // The first line of the first paragraph may not be indented as + // far due to the way the doc string was written: + // + // #[doc = "Start way over here + // and continue here"] + let s = "line1\n line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\nline2"); +} + +#[test] +fn should_not_ignore_first_line_indent_in_a_single_line_para() { + let s = "line1\n\n line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\n\n line2"); +} + +#[test] +fn should_unindent_tabs() { + let s = "\tline1\n\tline2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\nline2"); +} + +#[test] +fn should_trim_mixed_indentation() { + let s = "\t line1\n\t line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\nline2"); + + let s = " \tline1\n \tline2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1\nline2"); +} + +#[test] +fn should_not_trim() { + let s = "\t line1 \n\t line2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1 \nline2"); + + let s = " \tline1 \n \tline2".to_string(); + let r = unindent(&s); + assert_eq!(r, "line1 \nline2"); +} diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 63545ab45b..462e21b8f6 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -730,7 +730,7 @@ impl Tester for Collector { let edition = config.edition.unwrap_or(self.edition); let persist_doctests = self.persist_doctests.clone(); - debug!("Creating test {}: {}", name, test); + debug!("creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { desc: testing::TestDesc { name: testing::DynTestName(name), diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index 7220a05df4..7037a146c5 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -5,6 +5,9 @@ use std::path::Path; use errors::Handler; +#[cfg(test)] +mod tests; + macro_rules! try_something { ($e:expr, $diag:expr, $out:expr) => ({ match $e { @@ -275,109 +278,3 @@ pub fn test_theme_against>( get_differences(against, &paths, &mut ret); (true, ret) } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_comments_in_rules() { - let text = r#" -rule a {} - -rule b, c -// a line comment -{} - -rule d -// another line comment -e {} - -rule f/* a multine - -comment*/{} - -rule g/* another multine - -comment*/h - -i {} - -rule j/*commeeeeent - -you like things like "{}" in there? :) -*/ -end {}"#; - - let against = r#" -rule a {} - -rule b, c {} - -rule d e {} - -rule f {} - -rule gh i {} - -rule j end {} -"#; - - let mut ret = Vec::new(); - get_differences(&load_css_paths(against.as_bytes()), - &load_css_paths(text.as_bytes()), - &mut ret); - assert!(ret.is_empty()); - } - - #[test] - fn test_text() { - let text = r#" -a -/* sdfs -*/ b -c // sdf -d {} -"#; - let paths = load_css_paths(text.as_bytes()); - assert!(paths.children.contains(&CssPath::new("a b c d".to_owned()))); - } - - #[test] - fn test_comparison() { - let x = r#" -a { - b { - c {} - } -} -"#; - - let y = r#" -a { - b {} -} -"#; - - let against = load_css_paths(y.as_bytes()); - let other = load_css_paths(x.as_bytes()); - - let mut ret = Vec::new(); - get_differences(&against, &other, &mut ret); - assert!(ret.is_empty()); - get_differences(&other, &against, &mut ret); - assert_eq!(ret, vec![" Missing \"c\" rule".to_owned()]); - } - - #[test] - fn check_empty_css() { - let events = load_css_events(&[]); - assert_eq!(events.len(), 0); - } - - #[test] - fn check_invalid_css() { - let events = load_css_events(b"*"); - assert_eq!(events.len(), 0); - } -} diff --git a/src/librustdoc/theme/tests.rs b/src/librustdoc/theme/tests.rs new file mode 100644 index 0000000000..ab0935bc49 --- /dev/null +++ b/src/librustdoc/theme/tests.rs @@ -0,0 +1,102 @@ +use super::*; + +#[test] +fn test_comments_in_rules() { + let text = r#" +rule a {} + +rule b, c +// a line comment +{} + +rule d +// another line comment +e {} + +rule f/* a multine + +comment*/{} + +rule g/* another multine + +comment*/h + +i {} + +rule j/*commeeeeent + +you like things like "{}" in there? :) +*/ +end {}"#; + + let against = r#" +rule a {} + +rule b, c {} + +rule d e {} + +rule f {} + +rule gh i {} + +rule j end {} +"#; + + let mut ret = Vec::new(); + get_differences(&load_css_paths(against.as_bytes()), + &load_css_paths(text.as_bytes()), + &mut ret); + assert!(ret.is_empty()); +} + +#[test] +fn test_text() { + let text = r#" +a +/* sdfs +*/ b +c // sdf +d {} +"#; + let paths = load_css_paths(text.as_bytes()); + assert!(paths.children.contains(&CssPath::new("a b c d".to_owned()))); +} + +#[test] +fn test_comparison() { + let x = r#" +a { + b { + c {} + } +} +"#; + + let y = r#" +a { + b {} +} +"#; + + let against = load_css_paths(y.as_bytes()); + let other = load_css_paths(x.as_bytes()); + + let mut ret = Vec::new(); + get_differences(&against, &other, &mut ret); + assert!(ret.is_empty()); + get_differences(&other, &against, &mut ret); + assert_eq!(ret, vec![" Missing \"c\" rule".to_owned()]); +} + +#[test] +fn check_empty_css() { + let events = load_css_events(&[]); + assert_eq!(events.len(), 0); +} + +#[test] +fn check_invalid_css() { + let events = load_css_events(b"*"); + assert_eq!(events.len(), 0); +} diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 781e62c3b2..35b6d9972d 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -6,8 +6,8 @@ use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::privacy::AccessLevel; use rustc::util::nodemap::{FxHashSet, FxHashMap}; +use rustc::ty::TyCtxt; use syntax::ast; -use syntax::attr; use syntax::ext::base::MacroKind; use syntax::source_map::Spanned; use syntax::symbol::sym; @@ -16,26 +16,37 @@ use syntax_pos::{self, Span}; use std::mem; use crate::core; -use crate::clean::{self, AttributesExt, NestedAttributesExt, def_id_to_path}; +use crate::clean::{self, AttributesExt, NestedAttributesExt}; use crate::doctree::*; - -// Looks to me like the first two of these are actually -// output parameters, maybe only mutated once; perhaps -// better simply to have the visit method return a tuple -// containing them? +// FIXME: Should this be replaced with tcx.def_path_str? +fn def_id_to_path( + tcx: TyCtxt<'_>, + did: DefId, +) -> Vec { + let crate_name = tcx.crate_name(did.krate).to_string(); + let relative = tcx.def_path(did).data.into_iter().filter_map(|elem| { + // extern blocks have an empty name + let s = elem.data.to_string(); + if !s.is_empty() { + Some(s) + } else { + None + } + }); + std::iter::once(crate_name).chain(relative).collect() +} // Also, is there some reason that this doesn't use the 'visit' // framework from syntax?. pub struct RustdocVisitor<'a, 'tcx> { - pub module: Option>, - pub cx: &'a core::DocContext<'tcx>, + cx: &'a core::DocContext<'tcx>, view_item_stack: FxHashSet, inlining: bool, /// Are the current module and all of its parents public? inside_public_path: bool, - exact_paths: Option>>, + exact_paths: FxHashMap>, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -46,36 +57,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let mut stack = FxHashSet::default(); stack.insert(hir::CRATE_HIR_ID); RustdocVisitor { - module: None, cx, view_item_stack: stack, inlining: false, inside_public_path: true, - exact_paths: Some(FxHashMap::default()), + exact_paths: FxHashMap::default(), } } fn store_path(&mut self, did: DefId) { - // We can't use the entry API, as that keeps the mutable borrow of `self` active - // when we try to use `cx`. - let exact_paths = self.exact_paths.as_mut().unwrap(); - if exact_paths.get(&did).is_none() { - let path = def_id_to_path(self.cx, did, self.cx.crate_name.clone()); - exact_paths.insert(did, path); - } - } - - fn stability(&self, id: hir::HirId) -> Option { - self.cx.tcx.hir().opt_local_def_id_from_hir_id(id) - .and_then(|def_id| self.cx.tcx.lookup_stability(def_id)).cloned() - } - - fn deprecation(&self, id: hir::HirId) -> Option { - self.cx.tcx.hir().opt_local_def_id_from_hir_id(id) - .and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id)) + let tcx = self.cx.tcx; + self.exact_paths.entry(did).or_insert_with(|| def_id_to_path(tcx, did)); } - pub fn visit(&mut self, krate: &'tcx hir::Crate) { + pub fn visit(mut self, krate: &'tcx hir::Crate) -> Module<'tcx> { let mut module = self.visit_mod_contents(krate.span, &krate.attrs, &Spanned { span: syntax_pos::DUMMY_SP, @@ -88,23 +83,22 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)), ); module.is_crate = true; - self.module = Some(module); - self.cx.renderinfo.borrow_mut().exact_paths = self.exact_paths.take().unwrap(); + self.cx.renderinfo.borrow_mut().exact_paths = self.exact_paths; + + module } - pub fn visit_variant_data(&mut self, item: &'tcx hir::Item, + fn visit_variant_data(&mut self, item: &'tcx hir::Item, name: ast::Name, sd: &'tcx hir::VariantData, generics: &'tcx hir::Generics) -> Struct<'tcx> { - debug!("Visiting struct"); + debug!("visiting struct"); let struct_type = struct_type_from_def(&*sd); Struct { id: item.hir_id, struct_type, name, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), attrs: &item.attrs, generics, fields: sd.fields(), @@ -112,18 +106,16 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } - pub fn visit_union_data(&mut self, item: &'tcx hir::Item, + fn visit_union_data(&mut self, item: &'tcx hir::Item, name: ast::Name, sd: &'tcx hir::VariantData, generics: &'tcx hir::Generics) -> Union<'tcx> { - debug!("Visiting union"); + debug!("visiting union"); let struct_type = struct_type_from_def(&*sd); Union { id: item.hir_id, struct_type, name, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), attrs: &item.attrs, generics, fields: sd.fields(), @@ -131,24 +123,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } - pub fn visit_enum_def(&mut self, it: &'tcx hir::Item, + fn visit_enum_def(&mut self, it: &'tcx hir::Item, name: ast::Name, def: &'tcx hir::EnumDef, generics: &'tcx hir::Generics) -> Enum<'tcx> { - debug!("Visiting enum"); + debug!("visiting enum"); Enum { name, variants: def.variants.iter().map(|v| Variant { name: v.node.ident.name, id: v.node.id, attrs: &v.node.attrs, - stab: self.stability(v.node.id), - depr: self.deprecation(v.node.id), def: &v.node.data, whence: v.span, }).collect(), vis: &it.vis, - stab: self.stability(it.hir_id), - depr: self.deprecation(it.hir_id), generics, attrs: &it.attrs, id: it.hir_id, @@ -156,12 +144,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } - pub fn visit_fn(&mut self, om: &mut Module<'tcx>, item: &'tcx hir::Item, + fn visit_fn(&mut self, om: &mut Module<'tcx>, item: &'tcx hir::Item, name: ast::Name, decl: &'tcx hir::FnDecl, header: hir::FnHeader, generics: &'tcx hir::Generics, body: hir::BodyId) { - debug!("Visiting fn"); + debug!("visiting fn"); let macro_kind = item.attrs.iter().filter_map(|a| { if a.check_name(sym::proc_macro) { Some(MacroKind::Bang) @@ -207,16 +195,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { helpers, attrs: &item.attrs, whence: item.span, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }); } None => { om.fns.push(Function { id: item.hir_id, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), attrs: &item.attrs, decl, name, @@ -229,16 +213,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } - pub fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx hir::HirVec, + fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx hir::HirVec, vis: &'tcx hir::Visibility, id: hir::HirId, m: &'tcx hir::Mod, name: Option) -> Module<'tcx> { let mut om = Module::new(name, attrs, vis); om.where_outer = span; om.where_inner = m.inner; - om.stab = self.stability(id); - om.depr = self.deprecation(id); - om.id = self.cx.tcx.hir().hir_to_node_id(id); + om.id = id; // Keep track of if there were any private modules in the path. let orig_inside_public_path = self.inside_public_path; self.inside_public_path &= vis.node.is_pub(); @@ -369,13 +351,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { ret } - pub fn visit_item(&mut self, item: &'tcx hir::Item, + fn visit_item(&mut self, item: &'tcx hir::Item, renamed: Option, om: &mut Module<'tcx>) { - debug!("Visiting item {:?}", item); + debug!("visiting item {:?}", item); let ident = renamed.unwrap_or(item.ident); if item.vis.node.is_pub() { - let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.cx.tcx.hir().local_def_id(item.hir_id); self.store_path(def_id); } @@ -389,7 +371,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { _ if self.inlining && !item.vis.node.is_pub() => {} hir::ItemKind::GlobalAsm(..) => {} hir::ItemKind::ExternCrate(orig_name) => { - let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(item.hir_id); + let def_id = self.cx.tcx.hir().local_def_id(item.hir_id); om.extern_crates.push(ExternCrate { cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id) .unwrap_or(LOCAL_CRATE), @@ -406,11 +388,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // Struct and variant constructors and proc macro stubs always show up alongside // their definitions, we've already processed them so just discard these. - match path.res { - Res::Def(DefKind::Ctor(..), _) - | Res::SelfCtor(..) - | Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) => return, - _ => {} + if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res { + return; } // If there was a private module in the current path then don't bother inlining @@ -461,7 +440,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.unions.push(self.visit_union_data(item, ident.name, sd, gen)), hir::ItemKind::Fn(ref fd, header, ref gen, body) => self.visit_fn(om, item, ident.name, &**fd, header, gen, body), - hir::ItemKind::Ty(ref ty, ref gen) => { + hir::ItemKind::TyAlias(ref ty, ref gen) => { let t = Typedef { ty, gen, @@ -470,23 +449,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { attrs: &item.attrs, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; om.typedefs.push(t); }, - hir::ItemKind::Existential(ref exist_ty) => { - let t = Existential { - exist_ty, + hir::ItemKind::OpaqueTy(ref opaque_ty) => { + let t = OpaqueTy { + opaque_ty, name: ident.name, id: item.hir_id, attrs: &item.attrs, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; - om.existentials.push(t); + om.opaque_tys.push(t); }, hir::ItemKind::Static(ref type_, mutability, expr) => { let s = Static { @@ -498,8 +473,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { attrs: &item.attrs, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; om.statics.push(s); }, @@ -512,8 +485,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { attrs: &item.attrs, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; om.constants.push(s); }, @@ -532,8 +503,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { attrs: &item.attrs, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; om.traits.push(t); }, @@ -546,8 +515,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { attrs: &item.attrs, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; om.trait_aliases.push(t); }, @@ -577,8 +544,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { id: item.hir_id, whence: item.span, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), }; om.impls.push(i); } @@ -598,8 +563,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { name: renamed.unwrap_or(item.ident).name, kind: &item.node, vis: &item.vis, - stab: self.stability(item.hir_id), - depr: self.deprecation(item.hir_id), attrs: &item.attrs, whence: item.span }); @@ -617,14 +580,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect(); Macro { - - def_id: self.cx.tcx.hir().local_def_id_from_hir_id(def.hir_id), + hid: def.hir_id, + def_id: self.cx.tcx.hir().local_def_id(def.hir_id), attrs: &def.attrs, name: renamed.unwrap_or(def.name), whence: def.span, matchers, - stab: self.stability(def.hir_id), - depr: self.deprecation(def.hir_id), imported_from: None, } } diff --git a/src/libserialize/Cargo.toml b/src/libserialize/Cargo.toml index fa31a68a75..c302bcf95d 100644 --- a/src/libserialize/Cargo.toml +++ b/src/libserialize/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [lib] name = "serialize" path = "lib.rs" -crate-type = ["dylib", "rlib"] [dependencies] indexmap = "1" diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index 80aeecb84d..d981740780 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -9,10 +9,7 @@ use std::sync::Arc; use smallvec::{Array, SmallVec}; -impl Encodable for SmallVec - where A: Array, - A::Item: Encodable -{ +impl> Encodable for SmallVec { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { @@ -23,10 +20,7 @@ impl Encodable for SmallVec } } -impl Decodable for SmallVec - where A: Array, - A::Item: Decodable -{ +impl> Decodable for SmallVec { fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { let mut vec = SmallVec::with_capacity(len); diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index a7e7c09f9a..d0007074a8 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -103,8 +103,8 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! extern crate serialize; -//! use serialize::json::{self, ToJson, Json}; +//! extern crate serialize as rustc_serialize; +//! use rustc_serialize::json::{self, ToJson, Json}; //! //! // A custom data structure //! struct ComplexNum { @@ -120,7 +120,7 @@ //! } //! //! // Only generate `RustcEncodable` trait implementation -//! #[derive(Encodable)] +//! #[derive(RustcEncodable)] //! pub struct ComplexNumRecord { //! uid: u8, //! dsc: String, @@ -143,12 +143,12 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! extern crate serialize; +//! extern crate serialize as rustc_serialize; //! use std::collections::BTreeMap; -//! use serialize::json::{self, Json, ToJson}; +//! use rustc_serialize::json::{self, Json, ToJson}; //! -//! // Only generate `Decodable` trait implementation -//! #[derive(Decodable)] +//! // Only generate `RustcDecodable` trait implementation +//! #[derive(RustcDecodable)] //! pub struct TestStruct { //! data_int: u8, //! data_str: String, @@ -1031,7 +1031,7 @@ impl Json { /// If the Json value is an Object, returns the value associated with the provided key. /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ + pub fn find(&self, key: &str) -> Option<&Json> { match *self { Json::Object(ref map) => map.get(key), _ => None @@ -1052,7 +1052,7 @@ impl Json { /// If the Json value is an Object, performs a depth-first search until /// a value associated with the provided key is found. If no value is found /// or the Json value is not an Object, returns `None`. - pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { + pub fn search(&self, key: &str) -> Option<&Json> { match self { &Json::Object(ref map) => { match map.get(key) { diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs index f9d80842d7..88ce6d81d7 100644 --- a/src/libserialize/leb128.rs +++ b/src/libserialize/leb128.rs @@ -138,47 +138,3 @@ pub fn read_signed_leb128(data: &[u8], start_position: usize) -> (i128, usize) { (result, position - start_position) } - -macro_rules! impl_test_unsigned_leb128 { - ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => ( - #[test] - fn $test_name() { - let mut stream = Vec::new(); - - for x in 0..62 { - $write_fn_name(&mut stream, (3u64 << x) as $int_ty); - } - - let mut position = 0; - for x in 0..62 { - let expected = (3u64 << x) as $int_ty; - let (actual, bytes_read) = $read_fn_name(&stream[position ..]); - assert_eq!(expected, actual); - position += bytes_read; - } - assert_eq!(stream.len(), position); - } - ) -} - -impl_test_unsigned_leb128!(test_u16_leb128, write_u16_leb128, read_u16_leb128, u16); -impl_test_unsigned_leb128!(test_u32_leb128, write_u32_leb128, read_u32_leb128, u32); -impl_test_unsigned_leb128!(test_u64_leb128, write_u64_leb128, read_u64_leb128, u64); -impl_test_unsigned_leb128!(test_u128_leb128, write_u128_leb128, read_u128_leb128, u128); -impl_test_unsigned_leb128!(test_usize_leb128, write_usize_leb128, read_usize_leb128, usize); - -#[test] -fn test_signed_leb128() { - let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect(); - let mut stream = Vec::new(); - for &x in &values { - write_signed_leb128(&mut stream, x); - } - let mut pos = 0; - for &x in &values { - let (value, bytes_read) = read_signed_leb128(&mut stream, pos); - pos += bytes_read; - assert_eq!(x, value); - } - assert_eq!(pos, stream.len()); -} diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index b8eeb4d2b3..67a48ca4af 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -8,13 +8,12 @@ Core encoding and decoding interfaces. html_playground_url = "https://play.rust-lang.org/", test(attr(allow(unused_variables), deny(warnings))))] -#![deny(rust_2018_idioms)] - #![feature(box_syntax)] #![feature(core_intrinsics)] #![feature(specialization)] #![feature(never_type)] #![feature(nll)] +#![feature(associated_type_bounds)] #![cfg_attr(test, feature(test))] pub use self::serialize::{Decoder, Encoder, Decodable, Encodable}; diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 2def2a455f..a5f7b4898a 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -4,8 +4,8 @@ Core encoding and decoding interfaces. */ +use std::any; use std::borrow::Cow; -use std::intrinsics; use std::marker::PhantomData; use std::path; use std::rc::Rc; @@ -849,9 +849,9 @@ pub trait SpecializationError { impl SpecializationError for E { default fn not_found(trait_name: &'static str, method_name: &'static str) -> E { panic!("missing specialization: `<{} as {}<{}>>::{}` not overridden", - unsafe { intrinsics::type_name::() }, + any::type_name::(), trait_name, - unsafe { intrinsics::type_name::() }, + any::type_name::(), method_name); } } diff --git a/src/libserialize/tests/json.rs b/src/libserialize/tests/json.rs index 0fe3d4cfd6..3fb6bda679 100644 --- a/src/libserialize/tests/json.rs +++ b/src/libserialize/tests/json.rs @@ -1,4 +1,3 @@ -#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; use rustc_serialize::{Encodable, Decodable}; diff --git a/src/libserialize/tests/leb128.rs b/src/libserialize/tests/leb128.rs new file mode 100644 index 0000000000..4eb4397fec --- /dev/null +++ b/src/libserialize/tests/leb128.rs @@ -0,0 +1,46 @@ +extern crate serialize as rustc_serialize; +use rustc_serialize::leb128::*; + +macro_rules! impl_test_unsigned_leb128 { + ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => ( + #[test] + fn $test_name() { + let mut stream = Vec::new(); + + for x in 0..62 { + $write_fn_name(&mut stream, (3u64 << x) as $int_ty); + } + + let mut position = 0; + for x in 0..62 { + let expected = (3u64 << x) as $int_ty; + let (actual, bytes_read) = $read_fn_name(&stream[position ..]); + assert_eq!(expected, actual); + position += bytes_read; + } + assert_eq!(stream.len(), position); + } + ) +} + +impl_test_unsigned_leb128!(test_u16_leb128, write_u16_leb128, read_u16_leb128, u16); +impl_test_unsigned_leb128!(test_u32_leb128, write_u32_leb128, read_u32_leb128, u32); +impl_test_unsigned_leb128!(test_u64_leb128, write_u64_leb128, read_u64_leb128, u64); +impl_test_unsigned_leb128!(test_u128_leb128, write_u128_leb128, read_u128_leb128, u128); +impl_test_unsigned_leb128!(test_usize_leb128, write_usize_leb128, read_usize_leb128, usize); + +#[test] +fn test_signed_leb128() { + let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect(); + let mut stream = Vec::new(); + for &x in &values { + write_signed_leb128(&mut stream, x); + } + let mut pos = 0; + for &x in &values { + let (value, bytes_read) = read_signed_leb128(&mut stream, pos); + pos += bytes_read; + assert_eq!(x, value); + } + assert_eq!(pos, stream.len()); +} diff --git a/src/libserialize/tests/opaque.rs b/src/libserialize/tests/opaque.rs index 62a8f25124..fff6fc69e7 100644 --- a/src/libserialize/tests/opaque.rs +++ b/src/libserialize/tests/opaque.rs @@ -1,4 +1,3 @@ -#[allow(unused_extern_crates)] extern crate serialize as rustc_serialize; use rustc_serialize::{Encodable, Decodable}; diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 38df1f26d9..5334c4dfc6 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -26,7 +26,7 @@ unwind = { path = "../libunwind" } hashbrown = { version = "0.4.0", features = ['rustc-dep-of-std'] } [dependencies.backtrace] -version = "0.3.29" +version = "0.3.34" default-features = false # don't use coresymbolication on OSX features = [ "rustc-dep-of-std", # enable build support for integrating into libstd @@ -75,13 +75,8 @@ panic_immediate_abort = ["core/panic_immediate_abort"] # requires rebuilding the standard library to use it. wasm_syscall = [] -# An off-by-default features to enable libstd to assume that wasm-bindgen is in -# the environment for hooking up some thread-related information like the -# current thread id and accessing/getting the current thread's TCB -wasm-bindgen-threads = [] - -# Enable std_detect default features for stdsimd: -# https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/Cargo.toml +# Enable std_detect default features for stdarch/crates/std_detect: +# https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml std_detect_file_io = [] std_detect_dlsym_getauxval = [] diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 7a6c97ebaa..8db7bc12cd 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -1,5 +1,3 @@ -#![deny(warnings)] - use std::env; fn main() { @@ -39,6 +37,10 @@ fn main() { println!("cargo:rustc-link-lib=framework=Security"); println!("cargo:rustc-link-lib=framework=Foundation"); println!("cargo:rustc-link-lib=resolv"); + } else if target.contains("uwp") { + println!("cargo:rustc-link-lib=ws2_32"); + // For BCryptGenRandom + println!("cargo:rustc-link-lib=bcrypt"); } else if target.contains("windows") { println!("cargo:rustc-link-lib=advapi32"); println!("cargo:rustc-link-lib=ws2_32"); diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 2925d8362c..1e28ee8da2 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -3138,13 +3138,15 @@ mod test_map { #[test] fn test_from_iter() { - let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; let map: HashMap<_, _> = xs.iter().cloned().collect(); for &(k, v) in &xs { assert_eq!(map.get(&k), Some(&v)); } + + assert_eq!(map.iter().len(), xs.len() - 1); } #[test] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 403914c070..d243412405 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -1782,13 +1782,15 @@ mod test_set { #[test] fn test_from_iter() { - let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]; let set: HashSet<_> = xs.iter().cloned().collect(); for x in &xs { assert!(set.contains(x)); } + + assert_eq!(set.iter().len(), xs.len() - 1); } #[test] diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 00e840a53e..eca93399e5 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -182,6 +182,12 @@ impl fmt::Debug for VarsOs { /// * Environment variable is not present /// * Environment variable is not valid unicode /// +/// # Panics +/// +/// This function may panic if `key` is empty, contains an ASCII equals sign +/// `'='` or the NUL character `'\0'`, or when the value contains the NUL +/// character. +/// /// # Examples /// /// ``` @@ -210,6 +216,12 @@ fn _var(key: &OsStr) -> Result { /// /// [`None`]: ../option/enum.Option.html#variant.None /// +/// # Panics +/// +/// This function may panic if `key` is empty, contains an ASCII equals sign +/// `'='` or the NUL character `'\0'`, or when the value contains the NUL +/// character. +/// /// # Examples /// /// ``` @@ -975,6 +987,11 @@ mod arch { pub const ARCH: &str = "wasm32"; } +#[cfg(target_arch = "hexagon")] +mod arch { + pub const ARCH: &'static str = "hexagon"; +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 5b1e78a113..117a430eec 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -254,8 +254,8 @@ impl<'a, E: Error + 'a> From for Box { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, E: Error + Send + Sync + 'a> From for Box { - /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] + - /// [`Send`] + [`Sync`]. + /// Converts a type of [`Error`] + [`trait@Send`] + [`trait@Sync`] into a box of + /// dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. /// /// [`Error`]: ../error/trait.Error.html /// @@ -298,7 +298,7 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box for Box { - /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. + /// Converts a [`String`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. /// /// [`Error`]: ../error/trait.Error.html /// @@ -362,7 +362,7 @@ impl From for Box { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> From<&str> for Box { - /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. + /// Converts a [`str`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. /// /// [`Error`]: ../error/trait.Error.html /// @@ -405,7 +405,7 @@ impl From<&str> for Box { #[stable(feature = "cow_box_error", since = "1.22.0")] impl<'a, 'b> From> for Box { - /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. + /// Converts a [`Cow`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. /// /// [`Cow`]: ../borrow/enum.Cow.html /// [`Error`]: ../error/trait.Error.html diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 7254c62161..f649170c40 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -256,7 +256,6 @@ impl f32 { /// # Examples /// /// ``` - /// #![feature(euclidean_division)] /// let a: f32 = 7.0; /// let b = 4.0; /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0 @@ -265,7 +264,7 @@ impl f32 { /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0 /// ``` #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] pub fn div_euclid(self, rhs: f32) -> f32 { let q = (self / rhs).trunc(); if self % rhs < 0.0 { @@ -288,7 +287,6 @@ impl f32 { /// # Examples /// /// ``` - /// #![feature(euclidean_division)] /// let a: f32 = 7.0; /// let b = 4.0; /// assert_eq!(a.rem_euclid(b), 3.0); @@ -299,7 +297,7 @@ impl f32 { /// assert!((-std::f32::EPSILON).rem_euclid(3.0) != 0.0); /// ``` #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] pub fn rem_euclid(self, rhs: f32) -> f32 { let r = self % rhs; if r < 0.0 { diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index f8bb36ad0a..f61630997d 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -232,7 +232,6 @@ impl f64 { /// # Examples /// /// ``` - /// #![feature(euclidean_division)] /// let a: f64 = 7.0; /// let b = 4.0; /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0 @@ -241,7 +240,7 @@ impl f64 { /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0 /// ``` #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] pub fn div_euclid(self, rhs: f64) -> f64 { let q = (self / rhs).trunc(); if self % rhs < 0.0 { @@ -264,7 +263,6 @@ impl f64 { /// # Examples /// /// ``` - /// #![feature(euclidean_division)] /// let a: f64 = 7.0; /// let b = 4.0; /// assert_eq!(a.rem_euclid(b), 3.0); @@ -275,7 +273,7 @@ impl f64 { /// assert!((-std::f64::EPSILON).rem_euclid(3.0) != 0.0); /// ``` #[inline] - #[unstable(feature = "euclidean_division", issue = "49048")] + #[stable(feature = "euclidean_division", since = "1.38.0")] pub fn rem_euclid(self, rhs: f64) -> f64 { let r = self % rhs; if r < 0.0 { diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 5c6c43017c..512839a12c 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -195,6 +195,12 @@ pub struct CString { /// [`from_ptr`]: #method.from_ptr #[derive(Hash)] #[stable(feature = "rust1", since = "1.0.0")] +// FIXME: +// `fn from` in `impl From<&CStr> for Box` current implementation relies +// on `CStr` being layout-compatible with `[u8]`. +// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`. +// Anyway, `CStr` representation and layout are considered implementation detail, are +// not documented and must not be relied upon. pub struct CStr { // FIXME: this should not be represented with a DST slice but rather with // just a raw `c_char` along with some form of marker to make @@ -599,11 +605,12 @@ impl CString { /// /// [`Drop`]: ../ops/trait.Drop.html fn into_inner(self) -> Box<[u8]> { - unsafe { - let result = ptr::read(&self.inner); - mem::forget(self); - result - } + // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)` + // so we use `ManuallyDrop` to ensure `self` is not dropped. + // Then we can return the box directly without invalidating it. + // See https://github.com/rust-lang/rust/issues/62553. + let this = mem::ManuallyDrop::new(self); + unsafe { ptr::read(&this.inner) } } } @@ -1054,7 +1061,7 @@ impl CStr { /// /// ```no_run /// # #![allow(unused_must_use)] - /// use std::ffi::{CString}; + /// use std::ffi::CString; /// /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); /// unsafe { @@ -1070,7 +1077,7 @@ impl CStr { /// /// ```no_run /// # #![allow(unused_must_use)] - /// use std::ffi::{CString}; + /// use std::ffi::CString; /// /// let hello = CString::new("Hello").expect("CString::new failed"); /// let ptr = hello.as_ptr(); diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index c7c5849a00..1f384cbada 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -32,7 +32,7 @@ use crate::sys_common::{AsInner, IntoInner, FromInner}; /// in each pair are owned strings; the latter are borrowed /// references. /// -/// Note, `OsString` and `OsStr` internally do not necessarily hold strings in +/// Note, `OsString` and [`OsStr`] internally do not necessarily hold strings in /// the form native to the platform; While on Unix, strings are stored as a /// sequence of 8-bit values, on Windows, where strings are 16-bit value based /// as just discussed, strings are also actually stored as a sequence of 8-bit @@ -97,6 +97,12 @@ pub struct OsString { /// [`String`]: ../string/struct.String.html /// [conversions]: index.html#conversions #[stable(feature = "rust1", since = "1.0.0")] +// FIXME: +// `OsStr::from_inner` current implementation relies +// on `OsStr` being layout-compatible with `Slice`. +// When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`. +// Anyway, `OsStr` representation and layout are considered implementation detail, are +// not documented and must not be relied upon. pub struct OsStr { inner: Slice } @@ -667,10 +673,11 @@ impl From<&OsStr> for Box { #[stable(feature = "os_string_from_box", since = "1.18.0")] impl From> for OsString { - /// Converts a `Box` into a `OsString` without copying or allocating. + /// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or + /// allocating. /// /// [`Box`]: ../boxed/struct.Box.html - /// [`OsString`]: ../ffi/struct.OsString.html + /// [`OsStr`]: ../ffi/struct.OsStr.html fn from(boxed: Box) -> OsString { boxed.into_os_string() } diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index d41b3a3a12..5f76875bd6 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -468,6 +468,8 @@ impl File { /// # Errors /// /// This function will return an error if the file is not opened for writing. + /// Also, std::io::ErrorKind::InvalidInput will be returned if the desired + /// length would cause an overflow due to the implementation specifics. /// /// # Examples /// @@ -3316,11 +3318,11 @@ mod tests { fs::create_dir_all(&d).unwrap(); File::create(&f).unwrap(); if cfg!(not(windows)) { - symlink_dir("../d/e", &c).unwrap(); + symlink_file("../d/e", &c).unwrap(); symlink_file("../f", &e).unwrap(); } if cfg!(windows) { - symlink_dir(r"..\d\e", &c).unwrap(); + symlink_file(r"..\d\e", &c).unwrap(); symlink_file(r"..\f", &e).unwrap(); } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 3d0568c16c..f2b6ce6feb 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -511,8 +511,8 @@ pub trait Read { /// /// Correspondingly, however, *callers* of this method may not assume any guarantees /// about how the implementation uses `buf`. The trait is safe to implement, - // so it is possible that the code that's supposed to write to the buffer might also read - // from it. It is your responsibility to make sure that `buf` is initialized + /// so it is possible that the code that's supposed to write to the buffer might also read + /// from it. It is your responsibility to make sure that `buf` is initialized /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one /// obtains via [`MaybeUninit`]) is not safe, and can lead to undefined behavior. /// @@ -942,6 +942,62 @@ impl<'a> IoSliceMut<'a> { pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { IoSliceMut(sys::io::IoSliceMut::new(buf)) } + + /// Advance the internal cursor of the slice. + /// + /// # Notes + /// + /// Elements in the slice may be modified if the cursor is not advanced to + /// the end of the slice. For example if we have a slice of buffers with 2 + /// `IoSliceMut`s, both of length 8, and we advance the cursor by 10 bytes + /// the first `IoSliceMut` will be untouched however the second will be + /// modified to remove the first 2 bytes (10 - 8). + /// + /// # Examples + /// + /// ``` + /// #![feature(io_slice_advance)] + /// + /// use std::io::IoSliceMut; + /// use std::mem; + /// use std::ops::Deref; + /// + /// let mut buf1 = [1; 8]; + /// let mut buf2 = [2; 16]; + /// let mut buf3 = [3; 8]; + /// let mut bufs = &mut [ + /// IoSliceMut::new(&mut buf1), + /// IoSliceMut::new(&mut buf2), + /// IoSliceMut::new(&mut buf3), + /// ][..]; + /// + /// // Mark 10 bytes as read. + /// bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 10); + /// assert_eq!(bufs[0].deref(), [2; 14].as_ref()); + /// assert_eq!(bufs[1].deref(), [3; 8].as_ref()); + /// ``` + #[unstable(feature = "io_slice_advance", issue = "62726")] + #[inline] + pub fn advance<'b>(bufs: &'b mut [IoSliceMut<'a>], n: usize) -> &'b mut [IoSliceMut<'a>] { + // Number of buffers to remove. + let mut remove = 0; + // Total length of all the to be removed buffers. + let mut accumulated_len = 0; + for buf in bufs.iter() { + if accumulated_len + buf.len() > n { + break; + } else { + accumulated_len += buf.len(); + remove += 1; + } + } + + let bufs = &mut bufs[remove..]; + if !bufs.is_empty() { + bufs[0].0.advance(n - accumulated_len) + } + bufs + } } #[stable(feature = "iovec", since = "1.36.0")] @@ -989,6 +1045,61 @@ impl<'a> IoSlice<'a> { pub fn new(buf: &'a [u8]) -> IoSlice<'a> { IoSlice(sys::io::IoSlice::new(buf)) } + + /// Advance the internal cursor of the slice. + /// + /// # Notes + /// + /// Elements in the slice may be modified if the cursor is not advanced to + /// the end of the slice. For example if we have a slice of buffers with 2 + /// `IoSlice`s, both of length 8, and we advance the cursor by 10 bytes the + /// first `IoSlice` will be untouched however the second will be modified to + /// remove the first 2 bytes (10 - 8). + /// + /// # Examples + /// + /// ``` + /// #![feature(io_slice_advance)] + /// + /// use std::io::IoSlice; + /// use std::mem; + /// use std::ops::Deref; + /// + /// let mut buf1 = [1; 8]; + /// let mut buf2 = [2; 16]; + /// let mut buf3 = [3; 8]; + /// let mut bufs = &mut [ + /// IoSlice::new(&mut buf1), + /// IoSlice::new(&mut buf2), + /// IoSlice::new(&mut buf3), + /// ][..]; + /// + /// // Mark 10 bytes as written. + /// bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 10); + /// assert_eq!(bufs[0].deref(), [2; 14].as_ref()); + /// assert_eq!(bufs[1].deref(), [3; 8].as_ref()); + #[unstable(feature = "io_slice_advance", issue = "62726")] + #[inline] + pub fn advance<'b>(bufs: &'b mut [IoSlice<'a>], n: usize) -> &'b mut [IoSlice<'a>] { + // Number of buffers to remove. + let mut remove = 0; + // Total length of all the to be removed buffers. + let mut accumulated_len = 0; + for buf in bufs.iter() { + if accumulated_len + buf.len() > n { + break; + } else { + accumulated_len += buf.len(); + remove += 1; + } + } + + let bufs = &mut bufs[remove..]; + if !bufs.is_empty() { + bufs[0].0.advance(n - accumulated_len) + } + bufs + } } #[stable(feature = "iovec", since = "1.36.0")] @@ -1105,7 +1216,7 @@ pub trait Write { /// an [`Err`] variant. /// /// If the return value is [`Ok(n)`] then it must be guaranteed that - /// `0 <= n <= buf.len()`. A return value of `0` typically means that the + /// `n <= buf.len()`. A return value of `0` typically means that the /// underlying object is no longer able to accept bytes and will likely not /// be able to in the future as well, or that the buffer provided is empty. /// @@ -1144,7 +1255,7 @@ pub trait Write { /// Like `write`, except that it writes from a slice of buffers. /// - /// Data is copied to from each buffer in order, with the final buffer + /// Data is copied from each buffer in order, with the final buffer /// read from possibly being only partially consumed. This method must /// behave as a call to `write` with the buffers concatenated would. /// @@ -1923,7 +2034,7 @@ impl Read for Chain { fn read(&mut self, buf: &mut [u8]) -> Result { if !self.done_first { match self.first.read(buf)? { - 0 if buf.len() != 0 => self.done_first = true, + 0 if !buf.is_empty() => self.done_first = true, n => return Ok(n), } } @@ -1955,7 +2066,7 @@ impl BufRead for Chain { fn fill_buf(&mut self) -> Result<&[u8]> { if !self.done_first { match self.first.fill_buf()? { - buf if buf.len() == 0 => { self.done_first = true; } + buf if buf.is_empty() => { self.done_first = true; } buf => return Ok(buf), } } @@ -2268,8 +2379,10 @@ impl Iterator for Lines { #[cfg(test)] mod tests { use crate::io::prelude::*; - use crate::io; use super::{Cursor, SeekFrom, repeat}; + use crate::io::{self, IoSlice, IoSliceMut}; + use crate::mem; + use crate::ops::Deref; #[test] #[cfg_attr(target_os = "emscripten", ignore)] @@ -2537,4 +2650,89 @@ mod tests { Ok(()) } + + #[test] + fn io_slice_mut_advance() { + let mut buf1 = [1; 8]; + let mut buf2 = [2; 16]; + let mut buf3 = [3; 8]; + let mut bufs = &mut [ + IoSliceMut::new(&mut buf1), + IoSliceMut::new(&mut buf2), + IoSliceMut::new(&mut buf3), + ][..]; + + // Only in a single buffer.. + bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 1); + assert_eq!(bufs[0].deref(), [1; 7].as_ref()); + assert_eq!(bufs[1].deref(), [2; 16].as_ref()); + assert_eq!(bufs[2].deref(), [3; 8].as_ref()); + + // Removing a buffer, leaving others as is. + bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 7); + assert_eq!(bufs[0].deref(), [2; 16].as_ref()); + assert_eq!(bufs[1].deref(), [3; 8].as_ref()); + + // Removing a buffer and removing from the next buffer. + bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 18); + assert_eq!(bufs[0].deref(), [3; 6].as_ref()); + } + + #[test] + fn io_slice_mut_advance_empty_slice() { + let mut empty_bufs = &mut [][..]; + // Shouldn't panic. + IoSliceMut::advance(&mut empty_bufs, 1); + } + + #[test] + fn io_slice_mut_advance_beyond_total_length() { + let mut buf1 = [1; 8]; + let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; + + // Going beyond the total length should be ok. + bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 9); + assert!(bufs.is_empty()); + } + + #[test] + fn io_slice_advance() { + let mut buf1 = [1; 8]; + let mut buf2 = [2; 16]; + let mut buf3 = [3; 8]; + let mut bufs = + &mut [IoSlice::new(&mut buf1), IoSlice::new(&mut buf2), IoSlice::new(&mut buf3)][..]; + + // Only in a single buffer.. + bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 1); + assert_eq!(bufs[0].deref(), [1; 7].as_ref()); + assert_eq!(bufs[1].deref(), [2; 16].as_ref()); + assert_eq!(bufs[2].deref(), [3; 8].as_ref()); + + // Removing a buffer, leaving others as is. + bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 7); + assert_eq!(bufs[0].deref(), [2; 16].as_ref()); + assert_eq!(bufs[1].deref(), [3; 8].as_ref()); + + // Removing a buffer and removing from the next buffer. + bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 18); + assert_eq!(bufs[0].deref(), [3; 6].as_ref()); + } + + #[test] + fn io_slice_advance_empty_slice() { + let mut empty_bufs = &mut [][..]; + // Shouldn't panic. + IoSlice::advance(&mut empty_bufs, 1); + } + + #[test] + fn io_slice_advance_beyond_total_length() { + let mut buf1 = [1; 8]; + let mut bufs = &mut [IoSlice::new(&mut buf1)][..]; + + // Going beyond the total length should be ok. + bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 9); + assert!(bufs.is_empty()); + } } diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 7c4eae6512..33cc87eb79 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -2,7 +2,7 @@ use crate::fmt; use crate::io::{self, Read, Initializer, Write, ErrorKind, BufRead, IoSlice, IoSliceMut}; -use crate::mem; +use crate::mem::MaybeUninit; /// Copies the entire contents of a reader into a writer. /// @@ -43,21 +43,23 @@ use crate::mem; pub fn copy(reader: &mut R, writer: &mut W) -> io::Result where R: Read, W: Write { - let mut buf = unsafe { - let mut buf: [u8; super::DEFAULT_BUF_SIZE] = mem::uninitialized(); - reader.initializer().initialize(&mut buf); - buf - }; + let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit(); + // FIXME(#53491): This is calling `get_mut` and `get_ref` on an uninitialized + // `MaybeUninit`. Revisit this once we decided whether that is valid or not. + // This is still technically undefined behavior due to creating a reference + // to uninitialized data, but within libstd we can rely on more guarantees + // than if this code were in an external lib. + unsafe { reader.initializer().initialize(buf.get_mut()); } let mut written = 0; loop { - let len = match reader.read(&mut buf) { + let len = match reader.read(unsafe { buf.get_mut() }) { Ok(0) => return Ok(written), Ok(len) => len, Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, Err(e) => return Err(e), }; - writer.write_all(&buf[..len])?; + writer.write_all(unsafe { &buf.get_ref()[..len] })?; written += len as u64; } } diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index d133c2f5cb..f5018485ef 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -119,7 +119,7 @@ mod continue_keyword { } /// The `as` keyword can be used to change what the crate is referred to as in your project. If a /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. /// -/// `crate` is also used as in conjunction with `pub` to signify that the item it's attached to +/// `crate` can also be used as in conjunction with `pub` to signify that the item it's attached to /// is public only to other members of the same crate it's in. /// /// ```rust @@ -131,6 +131,10 @@ mod continue_keyword { } /// } /// ``` /// +/// `crate` is also used to represent the absolute path of a module, where `crate` refers to the +/// root of the current crate. For instance, `crate::foo::bar` refers to the name `bar` inside the +/// module `foo`, from anywhere else in the same crate. +/// /// [Reference]: ../reference/items/extern-crates.html mod crate_keyword { } @@ -608,6 +612,62 @@ mod in_keyword { } /// [Reference]: ../reference/statements.html#let-statements mod let_keyword { } +#[doc(keyword = "while")] +// +/// Loop while a condition is upheld. +/// +/// A `while` expression is used for predicate loops. The `while` expression runs the conditional +/// expression before running the loop body, then runs the loop body if the conditional +/// expression evaluates to `true`, or exits the loop otherwise. +/// +/// ```rust +/// let mut counter = 0; +/// +/// while counter < 10 { +/// println!("{}", counter); +/// counter += 1; +/// } +/// ``` +/// +/// Like the [`for`] expression, we can use `break` and `continue`. A `while` expression +/// cannot break with a value and always evaluates to `()` unlike [`loop`]. +/// +/// ```rust +/// let mut i = 1; +/// +/// while i < 100 { +/// i *= 2; +/// if i == 64 { +/// break; // Exit when `i` is 64. +/// } +/// } +/// ``` +/// +/// As `if` expressions have their pattern matching variant in `if let`, so too do `while` +/// expressions with `while let`. The `while let` expression matches the pattern against the +/// expression, then runs the loop body if pattern matching succeeds, or exits the loop otherwise. +/// We can use `break` and `continue` in `while let` expressions just like in `while`. +/// +/// ```rust +/// let mut counter = Some(0); +/// +/// while let Some(i) = counter { +/// if i == 10 { +/// counter = None; +/// } else { +/// println!("{}", i); +/// counter = Some (i + 1); +/// } +/// } +/// ``` +/// +/// For more information on `while` and loops in general, see the [reference]. +/// +/// [`for`]: keyword.for.html +/// [`loop`]: keyword.loop.html +/// [reference]: ../reference/expressions/loop-expr.html#predicate-loops +mod while_keyword { } + #[doc(keyword = "loop")] // /// Loop indefinitely. @@ -922,15 +982,6 @@ mod use_keyword { } /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601 mod where_keyword { } -#[doc(keyword = "while")] -// -/// Loop while a condition is upheld. -/// -/// The documentation for this keyword is [not yet complete]. Pull requests welcome! -/// -/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601 -mod while_keyword { } - // 2018 Edition keywords #[unstable(feature = "async_await", issue = "50547")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 60e06139eb..ba80d1b700 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -205,13 +205,12 @@ // Don't link to std. We are std. #![no_std] -//#![warn(deprecated_in_future)] // FIXME: std still has quite a few uses of `mem::uninitialized` +#![warn(deprecated_in_future)] #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings - -#![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] +#![allow(unused_lifetimes)] // Tell the compiler to link to either panic_abort or panic_unwind #![needs_panic_runtime] @@ -219,16 +218,17 @@ // std may use features in a platform-specific way #![allow(unused_features)] -#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))] +#![cfg_attr(test, feature(print_internals, set_stdio, update_panic_count))] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, slice_index_methods, - decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] + feature(slice_index_methods, decl_macro, coerce_unsized, + sgx_platform, ptr_wrapping_offset_from))] #![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"), feature(fixed_size_array, maybe_uninit_extra))] // std is implemented with unstable features, many of which are internal // compiler details that will never be stable // NB: the following list is sorted to minimize merge conflicts. +#![cfg_attr(not(bootstrap), feature(__rust_unstable_column))] #![feature(alloc_error_handler)] #![feature(alloc_layout_extra)] #![feature(allocator_api)] @@ -238,6 +238,7 @@ #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] +#![feature(associated_type_bounds)] #![feature(bind_by_move_pattern_guards)] #![feature(box_syntax)] #![feature(c_variadic)] @@ -251,6 +252,7 @@ #![feature(const_cstr_unchecked)] #![feature(const_raw_ptr_deref)] #![feature(core_intrinsics)] +#![feature(custom_test_frameworks)] #![feature(doc_alias)] #![feature(doc_cfg)] #![feature(doc_keyword)] @@ -262,7 +264,9 @@ #![feature(exhaustive_patterns)] #![feature(external_doc)] #![feature(fn_traits)] +#![feature(format_args_nl)] #![feature(generator_trait)] +#![feature(global_asm)] #![feature(hash_raw_entry)] #![feature(hashmap_internals)] #![feature(int_error_internals)] @@ -272,6 +276,10 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![feature(log_syntax)] +#![feature(maybe_uninit_ref)] +#![feature(maybe_uninit_slice)] +#![feature(mem_take)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] @@ -297,9 +305,11 @@ #![feature(stdsimd)] #![feature(stmt_expr_attributes)] #![feature(str_internals)] +#![feature(test)] #![feature(thread_local)] #![feature(todo_macro)] #![feature(toowned_clone_into)] +#![feature(trace_macros)] #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(untagged_unions)] @@ -317,12 +327,6 @@ use prelude::v1::*; // Access to Bencher, etc. #[cfg(test)] extern crate test; -// 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, r#try, todo}; - #[allow(unused_imports)] // macros from `alloc` are not used on all platforms #[macro_use] extern crate alloc as alloc_crate; @@ -491,12 +495,12 @@ mod memchr; pub mod rt; // Pull in the `std_detect` crate directly into libstd. The contents of -// `std_detect` are in a different repository: rust-lang-nursery/stdsimd. +// `std_detect` are in a different repository: rust-lang/stdarch. // // `std_detect` depends on libstd, but the contents of this module are // set up in such a way that directly pulling it here works such that the // crate uses the this crate as its libstd. -#[path = "../stdsimd/crates/std_detect/src/mod.rs"] +#[path = "../stdarch/crates/std_detect/src/mod.rs"] #[allow(missing_debug_implementations, missing_docs, dead_code)] #[unstable(feature = "stdsimd", issue = "48556")] #[cfg(not(test))] @@ -507,6 +511,55 @@ mod std_detect; #[cfg(not(test))] pub use std_detect::detect; +// Re-export macros defined in libcore. +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated_in_future)] +pub use core::{ + // Stable + assert_eq, + assert_ne, + debug_assert_eq, + debug_assert_ne, + debug_assert, + r#try, + unimplemented, + unreachable, + write, + writeln, + // Unstable + todo, +}; + +// Re-export built-in macros defined through libcore. +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +pub use core::{ + // Stable + assert, + cfg, + column, + compile_error, + concat, + env, + file, + format_args, + include, + include_bytes, + include_str, + line, + module_path, + option_env, + stringify, + // Unstable + __rust_unstable_column, + asm, + concat_idents, + format_args_nl, + global_asm, + log_syntax, + trace_macros, +}; + // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` // because rustdoc only looks for these modules at the crate level. diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index d695141bef..f2000936b9 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -119,7 +119,7 @@ macro_rules! print { /// Prints to the standard output, with a newline. /// /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone -/// (no additional CARRIAGE RETURN (`\r`/`U+000D`). +/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)). /// /// Use the [`format!`] syntax to write data to the standard output. /// See [`std::fmt`] for more information. @@ -365,534 +365,3 @@ macro_rules! assert_approx_eq { "{} is not approximately equal to {}", *a, *b); }) } - -/// Built-in macros to the compiler itself. -/// -/// These macros do not have any corresponding definition with a `macro_rules!` -/// macro, but are documented here. Their implementations can be found hardcoded -/// into libsyntax itself. -#[cfg(rustdoc)] -mod builtin { - - /// Causes compilation to fail with the given error message when encountered. - /// - /// This macro should be used when a crate uses a conditional compilation strategy to provide - /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`], - /// which emits an error at *runtime*, rather than during compilation. - /// - /// # Examples - /// - /// Two such examples are macros and `#[cfg]` environments. - /// - /// Emit better compiler error if a macro is passed invalid values. Without the final branch, - /// the compiler would still emit an error, but the error's message would not mention the two - /// valid values. - /// - /// ```compile_fail - /// macro_rules! give_me_foo_or_bar { - /// (foo) => {}; - /// (bar) => {}; - /// ($x:ident) => { - /// compile_error!("This macro only accepts `foo` or `bar`"); - /// } - /// } - /// - /// give_me_foo_or_bar!(neither); - /// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`" - /// ``` - /// - /// Emit compiler error if one of a number of features isn't available. - /// - /// ```compile_fail - /// #[cfg(not(any(feature = "foo", feature = "bar")))] - /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate."); - /// ``` - /// - /// [`panic!`]: ../std/macro.panic.html - #[stable(feature = "compile_error_macro", since = "1.20.0")] - #[rustc_doc_only_macro] - macro_rules! compile_error { - ($msg:expr) => ({ /* compiler built-in */ }); - ($msg:expr,) => ({ /* compiler built-in */ }); - } - - /// Constructs parameters for the other string-formatting macros. - /// - /// This macro functions by taking a formatting string literal containing - /// `{}` for each additional argument passed. `format_args!` prepares the - /// additional parameters to ensure the output can be interpreted as a string - /// and canonicalizes the arguments into a single type. Any value that implements - /// the [`Display`] trait can be passed to `format_args!`, as can any - /// [`Debug`] implementation be passed to a `{:?}` within the formatting string. - /// - /// This macro produces a value of type [`fmt::Arguments`]. This value can be - /// passed to the macros within [`std::fmt`] for performing useful redirection. - /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are - /// proxied through this one. `format_args!`, unlike its derived macros, avoids - /// heap allocations. - /// - /// You can use the [`fmt::Arguments`] value that `format_args!` returns - /// in `Debug` and `Display` contexts as seen below. The example also shows - /// that `Debug` and `Display` format to the same thing: the interpolated - /// format string in `format_args!`. - /// - /// ```rust - /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); - /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2)); - /// assert_eq!("1 foo 2", display); - /// assert_eq!(display, debug); - /// ``` - /// - /// For more information, see the documentation in [`std::fmt`]. - /// - /// [`Display`]: ../std/fmt/trait.Display.html - /// [`Debug`]: ../std/fmt/trait.Debug.html - /// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html - /// [`std::fmt`]: ../std/fmt/index.html - /// [`format!`]: ../std/macro.format.html - /// [`write!`]: ../std/macro.write.html - /// [`println!`]: ../std/macro.println.html - /// - /// # Examples - /// - /// ``` - /// use std::fmt; - /// - /// let s = fmt::format(format_args!("hello {}", "world")); - /// assert_eq!(s, format!("hello {}", "world")); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! format_args { - ($fmt:expr) => ({ /* compiler built-in */ }); - ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); - } - - /// Inspects an environment variable at compile time. - /// - /// This macro will expand to the value of the named environment variable at - /// compile time, yielding an expression of type `&'static str`. - /// - /// If the environment variable is not defined, then a compilation error - /// will be emitted. To not emit a compile error, use the [`option_env!`] - /// macro instead. - /// - /// [`option_env!`]: ../std/macro.option_env.html - /// - /// # Examples - /// - /// ``` - /// let path: &'static str = env!("PATH"); - /// println!("the $PATH variable at the time of compiling was: {}", path); - /// ``` - /// - /// You can customize the error message by passing a string as the second - /// parameter: - /// - /// ```compile_fail - /// let doc: &'static str = env!("documentation", "what's that?!"); - /// ``` - /// - /// If the `documentation` environment variable is not defined, you'll get - /// the following error: - /// - /// ```text - /// error: what's that?! - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! env { - ($name:expr) => ({ /* compiler built-in */ }); - ($name:expr,) => ({ /* compiler built-in */ }); - } - - /// Optionally inspects an environment variable at compile time. - /// - /// If the named environment variable is present at compile time, this will - /// expand into an expression of type `Option<&'static str>` whose value is - /// `Some` of the value of the environment variable. If the environment - /// variable is not present, then this will expand to `None`. See - /// [`Option`][option] for more information on this type. - /// - /// A compile time error is never emitted when using this macro regardless - /// of whether the environment variable is present or not. - /// - /// [option]: ../std/option/enum.Option.html - /// - /// # Examples - /// - /// ``` - /// let key: Option<&'static str> = option_env!("SECRET_KEY"); - /// println!("the secret key might be: {:?}", key); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! option_env { - ($name:expr) => ({ /* compiler built-in */ }); - ($name:expr,) => ({ /* compiler built-in */ }); - } - - /// Concatenates identifiers into one identifier. - /// - /// This macro takes any number of comma-separated identifiers, and - /// concatenates them all into one, yielding an expression which is a new - /// identifier. Note that hygiene makes it such that this macro cannot - /// capture local variables. Also, as a general rule, macros are only - /// allowed in item, statement or expression position. That means while - /// you may use this macro for referring to existing variables, functions or - /// modules etc, you cannot define a new one with it. - /// - /// # Examples - /// - /// ``` - /// #![feature(concat_idents)] - /// - /// # fn main() { - /// fn foobar() -> u32 { 23 } - /// - /// let f = concat_idents!(foo, bar); - /// println!("{}", f()); - /// - /// // fn concat_idents!(new, fun, name) { } // not usable in this way! - /// # } - /// ``` - #[unstable(feature = "concat_idents_macro", issue = "29599")] - #[rustc_doc_only_macro] - macro_rules! concat_idents { - ($($e:ident),+) => ({ /* compiler built-in */ }); - ($($e:ident,)+) => ({ /* compiler built-in */ }); - } - - /// Concatenates literals into a static string slice. - /// - /// This macro takes any number of comma-separated literals, yielding an - /// expression of type `&'static str` which represents all of the literals - /// concatenated left-to-right. - /// - /// Integer and floating point literals are stringified in order to be - /// concatenated. - /// - /// # Examples - /// - /// ``` - /// let s = concat!("test", 10, 'b', true); - /// assert_eq!(s, "test10btrue"); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! concat { - ($($e:expr),*) => ({ /* compiler built-in */ }); - ($($e:expr,)*) => ({ /* compiler built-in */ }); - } - - /// Expands to the line number on which it was invoked. - /// - /// With [`column!`] and [`file!`], these macros provide debugging information for - /// developers about the location within the source. - /// - /// The expanded expression has type `u32` and is 1-based, so the first line - /// in each file evaluates to 1, the second to 2, etc. This is consistent - /// with error messages by common compilers or popular editors. - /// The returned line is *not necessarily* the line of the `line!` invocation itself, - /// but rather the first macro invocation leading up to the invocation - /// of the `line!` macro. - /// - /// [`column!`]: macro.column.html - /// [`file!`]: macro.file.html - /// - /// # Examples - /// - /// ``` - /// let current_line = line!(); - /// println!("defined on line: {}", current_line); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! line { () => ({ /* compiler built-in */ }) } - - /// Expands to the column number at which it was invoked. - /// - /// With [`line!`] and [`file!`], these macros provide debugging information for - /// developers about the location within the source. - /// - /// The expanded expression has type `u32` and is 1-based, so the first column - /// in each line evaluates to 1, the second to 2, etc. This is consistent - /// with error messages by common compilers or popular editors. - /// The returned column is *not necessarily* the line of the `column!` invocation itself, - /// but rather the first macro invocation leading up to the invocation - /// of the `column!` macro. - /// - /// [`line!`]: macro.line.html - /// [`file!`]: macro.file.html - /// - /// # Examples - /// - /// ``` - /// let current_col = column!(); - /// println!("defined on column: {}", current_col); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! column { () => ({ /* compiler built-in */ }) } - - /// Expands to the file name in which it was invoked. - /// - /// With [`line!`] and [`column!`], these macros provide debugging information for - /// developers about the location within the source. - /// - /// - /// The expanded expression has type `&'static str`, and the returned file - /// is not the invocation of the `file!` macro itself, but rather the - /// first macro invocation leading up to the invocation of the `file!` - /// macro. - /// - /// [`line!`]: macro.line.html - /// [`column!`]: macro.column.html - /// - /// # Examples - /// - /// ``` - /// let this_file = file!(); - /// println!("defined in file: {}", this_file); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! file { () => ({ /* compiler built-in */ }) } - - /// Stringifies its arguments. - /// - /// This macro will yield an expression of type `&'static str` which is the - /// stringification of all the tokens passed to the macro. No restrictions - /// are placed on the syntax of the macro invocation itself. - /// - /// Note that the expanded results of the input tokens may change in the - /// future. You should be careful if you rely on the output. - /// - /// # Examples - /// - /// ``` - /// let one_plus_one = stringify!(1 + 1); - /// assert_eq!(one_plus_one, "1 + 1"); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) } - - /// Includes a utf8-encoded file as a string. - /// - /// The file is located relative to the current file. (similarly to how - /// modules are found) - /// - /// This macro will yield an expression of type `&'static str` which is the - /// contents of the file. - /// - /// # Examples - /// - /// Assume there are two files in the same directory with the following - /// contents: - /// - /// File 'spanish.in': - /// - /// ```text - /// adiós - /// ``` - /// - /// File 'main.rs': - /// - /// ```ignore (cannot-doctest-external-file-dependency) - /// fn main() { - /// let my_str = include_str!("spanish.in"); - /// assert_eq!(my_str, "adiós\n"); - /// print!("{}", my_str); - /// } - /// ``` - /// - /// Compiling 'main.rs' and running the resulting binary will print "adiós". - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! include_str { - ($file:expr) => ({ /* compiler built-in */ }); - ($file:expr,) => ({ /* compiler built-in */ }); - } - - /// Includes a file as a reference to a byte array. - /// - /// The file is located relative to the current file. (similarly to how - /// modules are found) - /// - /// This macro will yield an expression of type `&'static [u8; N]` which is - /// the contents of the file. - /// - /// # Examples - /// - /// Assume there are two files in the same directory with the following - /// contents: - /// - /// File 'spanish.in': - /// - /// ```text - /// adiós - /// ``` - /// - /// File 'main.rs': - /// - /// ```ignore (cannot-doctest-external-file-dependency) - /// fn main() { - /// let bytes = include_bytes!("spanish.in"); - /// assert_eq!(bytes, b"adi\xc3\xb3s\n"); - /// print!("{}", String::from_utf8_lossy(bytes)); - /// } - /// ``` - /// - /// Compiling 'main.rs' and running the resulting binary will print "adiós". - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! include_bytes { - ($file:expr) => ({ /* compiler built-in */ }); - ($file:expr,) => ({ /* compiler built-in */ }); - } - - /// Expands to a string that represents the current module path. - /// - /// The current module path can be thought of as the hierarchy of modules - /// leading back up to the crate root. The first component of the path - /// returned is the name of the crate currently being compiled. - /// - /// # Examples - /// - /// ``` - /// mod test { - /// pub fn foo() { - /// assert!(module_path!().ends_with("test")); - /// } - /// } - /// - /// test::foo(); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! module_path { () => ({ /* compiler built-in */ }) } - - /// Evaluates boolean combinations of configuration flags at compile-time. - /// - /// In addition to the `#[cfg]` attribute, this macro is provided to allow - /// boolean expression evaluation of configuration flags. This frequently - /// leads to less duplicated code. - /// - /// The syntax given to this macro is the same syntax as the [`cfg`] - /// attribute. - /// - /// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute - /// - /// # Examples - /// - /// ``` - /// let my_directory = if cfg!(windows) { - /// "windows-specific-directory" - /// } else { - /// "unix-directory" - /// }; - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) } - - /// Parses a file as an expression or an item according to the context. - /// - /// The file is located relative to the current file (similarly to how - /// modules are found). - /// - /// Using this macro is often a bad idea, because if the file is - /// parsed as an expression, it is going to be placed in the - /// surrounding code unhygienically. This could result in variables - /// or functions being different from what the file expected if - /// there are variables or functions that have the same name in - /// the current file. - /// - /// # Examples - /// - /// Assume there are two files in the same directory with the following - /// contents: - /// - /// File 'monkeys.in': - /// - /// ```ignore (only-for-syntax-highlight) - /// ['🙈', '🙊', '🙉'] - /// .iter() - /// .cycle() - /// .take(6) - /// .collect::() - /// ``` - /// - /// File 'main.rs': - /// - /// ```ignore (cannot-doctest-external-file-dependency) - /// fn main() { - /// let my_string = include!("monkeys.in"); - /// assert_eq!("🙈🙊🙉🙈🙊🙉", my_string); - /// println!("{}", my_string); - /// } - /// ``` - /// - /// Compiling 'main.rs' and running the resulting binary will print - /// "🙈🙊🙉🙈🙊🙉". - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! include { - ($file:expr) => ({ /* compiler built-in */ }); - ($file:expr,) => ({ /* compiler built-in */ }); - } - - /// Asserts that a boolean expression is `true` at runtime. - /// - /// This will invoke the [`panic!`] macro if the provided expression cannot be - /// evaluated to `true` at runtime. - /// - /// # Uses - /// - /// Assertions are always checked in both debug and release builds, and cannot - /// be disabled. See [`debug_assert!`] for assertions that are not enabled in - /// release builds by default. - /// - /// Unsafe code relies on `assert!` to enforce run-time invariants that, if - /// violated could lead to unsafety. - /// - /// Other use-cases of `assert!` include testing and enforcing run-time - /// invariants in safe code (whose violation cannot result in unsafety). - /// - /// # Custom Messages - /// - /// This macro has a second form, where a custom panic message can - /// be provided with or without arguments for formatting. See [`std::fmt`] - /// for syntax for this form. - /// - /// [`panic!`]: macro.panic.html - /// [`debug_assert!`]: macro.debug_assert.html - /// [`std::fmt`]: ../std/fmt/index.html - /// - /// # Examples - /// - /// ``` - /// // the panic message for these assertions is the stringified value of the - /// // expression given. - /// assert!(true); - /// - /// fn some_computation() -> bool { true } // a very simple function - /// - /// assert!(some_computation()); - /// - /// // assert with a custom message - /// let x = true; - /// assert!(x, "x wasn't true!"); - /// - /// let a = 3; let b = 27; - /// assert!(a + b == 30, "a = {}, b = {}", a, b); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_doc_only_macro] - macro_rules! assert { - ($cond:expr) => ({ /* compiler built-in */ }); - ($cond:expr,) => ({ /* compiler built-in */ }); - ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }); - } -} diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 61d9149952..c430e10395 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -422,7 +422,7 @@ impl UdpSocket { /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket. /// /// If enabled, multicast packets will be looped back to the local socket. - /// Note that this may not have any affect on IPv6 sockets. + /// Note that this may not have any effect on IPv6 sockets. /// /// # Examples /// @@ -464,7 +464,7 @@ impl UdpSocket { /// this socket. The default value is 1 which means that multicast packets /// don't leave the local network unless explicitly requested. /// - /// Note that this may not have any affect on IPv6 sockets. + /// Note that this may not have any effect on IPv6 sockets. /// /// # Examples /// diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs index ec5e983707..78321ac318 100644 --- a/src/libstd/os/linux/fs.rs +++ b/src/libstd/os/linux/fs.rs @@ -34,9 +34,10 @@ pub trait MetadataExt { /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] - #[rustc_deprecated(since = "1.8.0", - reason = "deprecated in favor of the accessor \ - methods of this trait")] + #[rustc_deprecated( + since = "1.8.0", + reason = "other methods of this trait are now prefered" + )] #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat; diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs index 77eeacb4b4..21e1cf8a22 100644 --- a/src/libstd/os/linux/raw.rs +++ b/src/libstd/os/linux/raw.rs @@ -147,6 +147,62 @@ mod arch { } } +#[cfg(target_arch = "hexagon")] +mod arch { + use crate::os::raw::{c_long, c_int, c_longlong, culonglong}; + + #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = c_longlong; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = c_long; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = c_ulonglong; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = c_uint; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = c_longlong; + #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long; + + #[repr(C)] + #[derive(Clone)] + #[stable(feature = "raw_ext", since = "1.1.0")] + pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: ::dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ::c_ulonglong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: ::c_uint, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: ::c_ulonglong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __pad1: ::c_ulong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: ::c_longlong, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: ::blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __pad2: ::c_int, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: ::blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: ::time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: ::c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: ::time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: ::c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: ::time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: ::c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __pad3: [::c_int;2], + } +} + #[cfg(any(target_arch = "mips64", target_arch = "s390x", target_arch = "sparc64"))] diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 94e8b7805c..fcd81f0a1b 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -24,7 +24,7 @@ cfg_if::cfg_if! { // If we're not documenting libstd then we just expose the main modules // as we otherwise would. - #[cfg(any(target_os = "redox", unix))] + #[cfg(any(target_os = "redox", unix, target_os = "vxworks"))] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::sys::ext as unix; @@ -50,7 +50,9 @@ cfg_if::cfg_if! { #[cfg(target_os = "emscripten")] pub mod emscripten; #[cfg(target_os = "fuchsia")] pub mod fuchsia; #[cfg(target_os = "hermit")] pub mod hermit; +#[cfg(target_os = "redox")] pub mod redox; #[cfg(target_os = "wasi")] pub mod wasi; +#[cfg(target_os = "vxworks")] pub mod vxworks; #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] pub mod fortanix_sgx; pub mod raw; diff --git a/src/libstd/os/raw/mod.rs b/src/libstd/os/raw/mod.rs index e9043b4b40..0761c50f4b 100644 --- a/src/libstd/os/raw/mod.rs +++ b/src/libstd/os/raw/mod.rs @@ -8,9 +8,11 @@ #![stable(feature = "raw_os", since = "1.1.0")] -#[doc(include = "os/raw/char.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/char.md"))] +#[cfg_attr(not(bootstrap), doc(include = "char.md"))] #[cfg(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", + target_arch = "hexagon", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "s390x")), @@ -25,11 +27,17 @@ target_arch = "arm", target_arch = "powerpc")), all(target_os = "openbsd", target_arch = "aarch64"), + all(target_os = "vxworks", any(target_arch = "aarch64", + target_arch = "arm", + target_arch = "powerpc64", + target_arch = "powerpc")), all(target_os = "fuchsia", target_arch = "aarch64")))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; -#[doc(include = "os/raw/char.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/char.md"))] +#[cfg_attr(not(bootstrap), doc(include = "char.md"))] #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", + target_arch = "hexagon", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "s390x")), @@ -44,39 +52,57 @@ target_arch = "arm", target_arch = "powerpc")), all(target_os = "openbsd", target_arch = "aarch64"), + all(target_os = "vxworks", any(target_arch = "aarch64", + target_arch = "arm", + target_arch = "powerpc64", + target_arch = "powerpc")), all(target_os = "fuchsia", target_arch = "aarch64"))))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; -#[doc(include = "os/raw/schar.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/schar.md"))] +#[cfg_attr(not(bootstrap), doc(include = "schar.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; -#[doc(include = "os/raw/uchar.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/uchar.md"))] +#[cfg_attr(not(bootstrap), doc(include = "uchar.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8; -#[doc(include = "os/raw/short.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/short.md"))] +#[cfg_attr(not(bootstrap), doc(include = "short.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16; -#[doc(include = "os/raw/ushort.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/ushort.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ushort.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16; -#[doc(include = "os/raw/int.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/int.md"))] +#[cfg_attr(not(bootstrap), doc(include = "int.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32; -#[doc(include = "os/raw/uint.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/uint.md"))] +#[cfg_attr(not(bootstrap), doc(include = "uint.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32; -#[doc(include = "os/raw/long.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/long.md"))] +#[cfg_attr(not(bootstrap), doc(include = "long.md"))] #[cfg(any(target_pointer_width = "32", windows))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32; -#[doc(include = "os/raw/ulong.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/ulong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ulong.md"))] #[cfg(any(target_pointer_width = "32", windows))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32; -#[doc(include = "os/raw/long.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/long.md"))] +#[cfg_attr(not(bootstrap), doc(include = "long.md"))] #[cfg(all(target_pointer_width = "64", not(windows)))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64; -#[doc(include = "os/raw/ulong.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/ulong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ulong.md"))] #[cfg(all(target_pointer_width = "64", not(windows)))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64; -#[doc(include = "os/raw/longlong.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/longlong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "longlong.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64; -#[doc(include = "os/raw/ulonglong.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/ulonglong.md"))] +#[cfg_attr(not(bootstrap), doc(include = "ulonglong.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64; -#[doc(include = "os/raw/float.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/float.md"))] +#[cfg_attr(not(bootstrap), doc(include = "float.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32; -#[doc(include = "os/raw/double.md")] +#[cfg_attr(bootstrap, doc(include = "os/raw/double.md"))] +#[cfg_attr(not(bootstrap), doc(include = "double.md"))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64; #[stable(feature = "raw_os", since = "1.1.0")] diff --git a/src/libstd/os/redox/fs.rs b/src/libstd/os/redox/fs.rs new file mode 100644 index 0000000000..80a1290761 --- /dev/null +++ b/src/libstd/os/redox/fs.rs @@ -0,0 +1,383 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use crate::fs::Metadata; +use crate::sys_common::AsInner; + +#[allow(deprecated)] +use crate::os::redox::raw; + +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + /// Gain a reference to the underlying `stat` structure which contains + /// the raw information returned by the OS. + /// + /// The contents of the returned [`stat`] are **not** consistent across + /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the + /// cross-Unix abstractions contained within the raw stat. + /// + /// [`stat`]: ../../../../std/os/redox/raw/struct.stat.html + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let stat = meta.as_raw_stat(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + #[rustc_deprecated(since = "1.8.0", + reason = "deprecated in favor of the accessor \ + methods of this trait")] + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat; + + /// Returns the device ID on which this file resides. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_dev()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + /// Returns the inode number. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ino()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + /// Returns the file type and mode. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mode()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + /// Returns the number of hard links to file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_nlink()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + /// Returns the user ID of the file owner. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_uid()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + /// Returns the group ID of the file owner. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_gid()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + /// Returns the device ID that this file represents. Only relevant for special file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_rdev()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes. + /// + /// The size of a symbolic link is the length of the pathname it contains, + /// without a terminating null byte. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_size()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + /// Returns the last access time of the file, in seconds since Unix Epoch. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_atime()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + /// Returns the last access time of the file, in nanoseconds since [`st_atime`]. + /// + /// [`st_atime`]: #tymethod.st_atime + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_atime_nsec()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + /// Returns the last modification time of the file, in seconds since Unix Epoch. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mtime()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`]. + /// + /// [`st_mtime`]: #tymethod.st_mtime + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mtime_nsec()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + /// Returns the last status change time of the file, in seconds since Unix Epoch. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ctime()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`]. + /// + /// [`st_ctime`]: #tymethod.st_ctime + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ctime_nsec()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + /// Returns the "preferred" blocksize for efficient filesystem I/O. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_blksize()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + /// Returns the number of blocks allocated to the file, 512-byte units. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_blocks()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat { + unsafe { + &*(self.as_inner().as_inner() as *const libc::stat + as *const raw::stat) + } + } + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atime_nsec as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtime_nsec as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctime_nsec as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } +} diff --git a/src/libstd/os/redox/mod.rs b/src/libstd/os/redox/mod.rs new file mode 100644 index 0000000000..c60da5926d --- /dev/null +++ b/src/libstd/os/redox/mod.rs @@ -0,0 +1,6 @@ +//! Redox-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod raw; +pub mod fs; diff --git a/src/libstd/os/redox/raw.rs b/src/libstd/os/redox/raw.rs new file mode 100644 index 0000000000..23d8ff7694 --- /dev/null +++ b/src/libstd/os/redox/raw.rs @@ -0,0 +1,67 @@ +//! Redox-specific raw type definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] +#![rustc_deprecated(since = "1.8.0", + reason = "these type aliases are no longer supported by \ + the standard library, the `libc` crate on \ + crates.io should be used instead for the correct \ + definitions")] +#![allow(deprecated)] +#![allow(missing_debug_implementations)] + +use crate::os::raw::{c_char, c_int, c_long, c_ulong, c_void}; + +#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = c_long; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type gid_t = c_int; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = c_int; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type uid_t = c_int; + +#[stable(feature = "pthread_t", since = "1.8.0")] +pub type pthread_t = *mut c_void; + +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = c_long; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long; + +#[repr(C)] +#[derive(Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub _pad: [c_char; 24], +} diff --git a/src/libstd/os/vxworks/fs.rs b/src/libstd/os/vxworks/fs.rs new file mode 100644 index 0000000000..57ab4fb943 --- /dev/null +++ b/src/libstd/os/vxworks/fs.rs @@ -0,0 +1,84 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use crate::fs::Metadata; +use crate::sys_common::AsInner; + +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_attrib(&self) -> u8; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } + fn st_attrib(&self) -> u8 { + self.as_inner().as_inner().st_attrib as u8 + } +} diff --git a/src/libstd/os/vxworks/mod.rs b/src/libstd/os/vxworks/mod.rs new file mode 100644 index 0000000000..2255a103d3 --- /dev/null +++ b/src/libstd/os/vxworks/mod.rs @@ -0,0 +1,6 @@ +//! VxWorks-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod raw; +pub mod fs; diff --git a/src/libstd/os/vxworks/raw.rs b/src/libstd/os/vxworks/raw.rs new file mode 100644 index 0000000000..ae0560a5a9 --- /dev/null +++ b/src/libstd/os/vxworks/raw.rs @@ -0,0 +1,7 @@ +//! VxWorks-specific raw type definitions +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use crate::os::raw::{c_ulong}; + +#[stable(feature = "pthread_t", since = "1.8.0")] +pub type pthread_t = c_ulong; diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 797d85e941..952fd9ebfd 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -364,7 +364,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! { unsafe impl<'a> BoxMeUp for PanicPayload<'a> { fn box_me_up(&mut self) -> *mut (dyn Any + Send) { - let contents = mem::replace(self.fill(), String::new()); + let contents = mem::take(self.fill()); Box::into_raw(Box::new(contents)) } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 126bc3754d..fd6ff1032b 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -317,7 +317,7 @@ unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr { // Detect scheme on Redox fn has_redox_scheme(s: &[u8]) -> bool { - cfg!(target_os = "redox") && s.split(|b| *b == b'/').next().unwrap_or(b"").contains(&b':') + cfg!(target_os = "redox") && s.contains(&b':') } //////////////////////////////////////////////////////////////////////////////// @@ -1123,6 +1123,12 @@ impl FusedIterator for Ancestors<'_> {} /// Which method works best depends on what kind of situation you're in. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] +// FIXME: +// `PathBuf::as_mut_vec` current implementation relies +// on `PathBuf` being layout-compatible with `Vec`. +// When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`. +// Anyway, `PathBuf` representation and layout are considered implementation detail, are +// not documented and must not be relied upon. pub struct PathBuf { inner: OsString, } @@ -1745,6 +1751,12 @@ impl AsRef for PathBuf { /// assert_eq!(extension, Some(OsStr::new("txt"))); /// ``` #[stable(feature = "rust1", since = "1.0.0")] +// FIXME: +// `Path::new` current implementation relies +// on `Path` being layout-compatible with `OsStr`. +// When attribute privacy is implemented, `Path` should be annotated as `#[repr(transparent)]`. +// Anyway, `Path` representation and layout are considered implementation detail, are +// not documented and must not be relied upon. pub struct Path { inner: OsStr, } @@ -1819,6 +1831,8 @@ impl Path { /// Yields a [`&str`] slice if the `Path` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. + /// Note that validation is performed because non-UTF-8 strings are + /// perfectly valid for some OS. /// /// [`&str`]: ../primitive.str.html /// diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 551e982a3c..3085c3d829 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -71,9 +71,6 @@ //! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions //! that may succeed or fail. Like [`Option`], its variants are exported as //! well. -//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical -//! reasons, but shouldn't have to exist. It provides a few useful methods on -//! slices. //! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings. //! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated //! vector. diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index ce1e8e3319..1c61f21f7d 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -7,9 +7,13 @@ #![stable(feature = "rust1", since = "1.0.0")] // Re-exported core operators +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use crate::marker::{Copy, Send, Sized, Sync, Unpin}; +pub use crate::marker::Copy; +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(no_inline)] +pub use crate::marker::{Send, Sized, Sync, Unpin}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; @@ -20,15 +24,18 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; pub use crate::mem::drop; // Re-exported types and traits +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::clone::Clone; +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::cmp::{PartialEq, PartialOrd, Eq, Ord}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::convert::{AsRef, AsMut, Into, From}; +#[cfg(bootstrap)] #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::default::Default; @@ -45,6 +52,58 @@ pub use crate::option::Option::{self, Some, None}; #[doc(no_inline)] pub use crate::result::Result::{self, Ok, Err}; +// Re-exported built-in macros +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use core::prelude::v1::{ + __rust_unstable_column, + asm, + assert, + cfg, + column, + compile_error, + concat, + concat_idents, + env, + file, + format_args, + format_args_nl, + global_asm, + include, + include_bytes, + include_str, + line, + log_syntax, + module_path, + option_env, + stringify, + trace_macros, +}; + +// FIXME: Attribute and derive macros are not documented because for them rustdoc generates +// dead links which fail link checker testing. +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow(deprecated)] +#[doc(hidden)] +pub use core::prelude::v1::{ + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + RustcDecodable, + RustcEncodable, + bench, + global_allocator, + test, + test_case, +}; // The file so far is equivalent to src/libcore/prelude/v1.rs, // and below to src/liballoc/prelude.rs. @@ -60,9 +119,6 @@ pub use crate::boxed::Box; pub use crate::borrow::ToOwned; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use crate::slice::SliceConcatExt; -#[stable(feature = "rust1", since = "1.0.0")] -#[doc(no_inline)] pub use crate::string::{String, ToString}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 65fd8c83e1..d9a3da66a6 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -362,8 +362,13 @@ mod prim_unit { } /// /// *[See also the `std::ptr` module](ptr/index.html).* /// -/// Working with raw pointers in Rust is uncommon, -/// typically limited to a few patterns. +/// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. +/// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is +/// dereferenced (using the `*` operator), it must be non-null and aligned. +/// +/// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so +/// [`write`] must be used if the type has drop glue and memory is not already +/// initialized - otherwise `drop` would be called on the uninitialized memory. /// /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the /// [`is_null`] method of the `*const T` and `*mut T` types to check for null. @@ -442,6 +447,7 @@ mod prim_unit { } /// [`offset`]: ../std/primitive.pointer.html#method.offset /// [`into_raw`]: ../std/boxed/struct.Box.html#method.into_raw /// [`drop`]: ../std/mem/fn.drop.html +/// [`write`]: ../std/ptr/fn.write.html #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer { } @@ -891,9 +897,13 @@ mod prim_usize { } /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` /// operators on a value, or by using a `ref` or `ref mut` pattern. /// -/// For those familiar with pointers, a reference is just a pointer that is assumed to not be null. -/// In fact, `Option<&T>` has the same memory representation as a nullable pointer, and can be -/// passed across FFI boundaries as such. +/// For those familiar with pointers, a reference is just a pointer that is assumed to be +/// aligned, not null, and pointing to memory containing a valid value of `T` - for example, +/// `&bool` can only point to an allocation containing the integer values `1` (`true`) or `0` +/// (`false`), but creating a `&bool` that points to an allocation containing +/// the value `3` causes undefined behaviour. +/// In fact, `Option<&T>` has the same memory representation as a +/// nullable but aligned pointer, and can be passed across FFI boundaries as such. /// /// In most cases, references can be used much like the original value. Field access, method /// calling, and indexing work the same (save for mutability rules, of course). In addition, the @@ -1036,6 +1046,11 @@ mod prim_ref { } /// [`FnMut`]: ops/trait.FnMut.html /// [`FnOnce`]: ops/trait.FnOnce.html /// +/// Function pointers are pointers that point to *code*, not data. They can be called +/// just like functions. Like references, function pointers are, among other things, assumed to +/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null +/// pointers, make your type `Option` with your required signature. +/// /// Plain function pointers are obtained by casting either plain functions, or closures that don't /// capture an environment: /// @@ -1091,10 +1106,6 @@ mod prim_ref { } /// /// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type. /// -/// Like references in rust, function pointers are assumed to not be null, so if you want to pass a -/// function pointer over FFI and be able to accommodate null pointers, make your type -/// `Option` with your required signature. -/// /// Function pointers implement the following traits: /// /// * [`Clone`] diff --git a/src/libstd/process.rs b/src/libstd/process.rs index a568f46663..000f80f99e 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1765,33 +1765,6 @@ mod tests { assert_eq!(out, "foobar\n"); } - - #[test] - #[cfg_attr(target_os = "android", ignore)] - #[cfg(unix)] - fn uid_works() { - use crate::os::unix::prelude::*; - - let mut p = Command::new("/bin/sh") - .arg("-c").arg("true") - .uid(unsafe { libc::getuid() }) - .gid(unsafe { libc::getgid() }) - .spawn().unwrap(); - assert!(p.wait().unwrap().success()); - } - - #[test] - #[cfg_attr(target_os = "android", ignore)] - #[cfg(unix)] - fn uid_to_root_fails() { - use crate::os::unix::prelude::*; - - // if we're already root, this isn't a valid test. Most of the bots run - // as non-root though (android is an exception). - if unsafe { libc::getuid() == 0 } { return } - assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err()); - } - #[test] #[cfg_attr(target_os = "android", ignore)] fn test_process_status() { diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index ffb9ce1c81..aeff57716e 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -36,7 +36,7 @@ impl WaitTimeoutResult { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// /// // Let's wait 20 milliseconds before notifying the condvar. /// thread::sleep(Duration::from_millis(20)); @@ -48,7 +48,7 @@ impl WaitTimeoutResult { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// loop { /// // Let's put a timeout on the condvar's wait. @@ -94,7 +94,7 @@ impl WaitTimeoutResult { /// /// // Inside of our lock, spawn a new thread, and then wait for it to start. /// thread::spawn(move|| { -/// let &(ref lock, ref cvar) = &*pair2; +/// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -102,7 +102,7 @@ impl WaitTimeoutResult { /// }); /// /// // Wait for the thread to start up. -/// let &(ref lock, ref cvar) = &*pair; +/// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// while !*started { /// started = cvar.wait(started).unwrap(); @@ -180,7 +180,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -188,7 +188,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { @@ -245,7 +245,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -253,7 +253,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` @@ -301,7 +301,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -309,7 +309,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { @@ -374,7 +374,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -382,7 +382,7 @@ impl Condvar { /// }); /// /// // wait for the thread to start up - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { @@ -449,7 +449,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -457,7 +457,7 @@ impl Condvar { /// }); /// /// // wait for the thread to start up - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let result = cvar.wait_timeout_until( /// lock.lock().unwrap(), /// Duration::from_millis(100), @@ -508,7 +508,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -516,7 +516,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { @@ -548,7 +548,7 @@ impl Condvar { /// let pair2 = pair.clone(); /// /// thread::spawn(move|| { - /// let &(ref lock, ref cvar) = &*pair2; + /// let (lock, cvar) = &*pair2; /// let mut started = lock.lock().unwrap(); /// *started = true; /// // We notify the condvar that the value has changed. @@ -556,7 +556,7 @@ impl Condvar { /// }); /// /// // Wait for the thread to start up. - /// let &(ref lock, ref cvar) = &*pair; + /// let (lock, cvar) = &*pair; /// let mut started = lock.lock().unwrap(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index fd6e46fd61..e29faf18d8 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -163,6 +163,7 @@ pub use self::condvar::{Condvar, WaitTimeoutResult}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::mutex::{Mutex, MutexGuard}; #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(bootstrap, allow(deprecated_in_future))] #[allow(deprecated)] pub use self::once::{Once, OnceState, ONCE_INIT}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 3c4f8e077c..58a4b716af 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -140,7 +140,7 @@ fn wait_timeout_receiver<'a, 'b, T>(lock: &'a Mutex>, new_guard } -fn abort_selection<'a, T>(guard: &mut MutexGuard<'a , State>) -> bool { +fn abort_selection(guard: &mut MutexGuard<'_, State>) -> bool { match mem::replace(&mut guard.blocker, NoneBlocked) { NoneBlocked => true, BlockedSender(token) => { @@ -160,20 +160,20 @@ fn wakeup(token: SignalToken, guard: MutexGuard<'_, State>) { } impl Packet { - pub fn new(cap: usize) -> Packet { + pub fn new(capacity: usize) -> Packet { Packet { channels: AtomicUsize::new(1), lock: Mutex::new(State { disconnected: false, blocker: NoneBlocked, - cap, + cap: capacity, canceled: None, queue: Queue { head: ptr::null_mut(), tail: ptr::null_mut(), }, buf: Buffer { - buf: (0..cap + if cap == 0 {1} else {0}).map(|_| None).collect(), + buf: (0..capacity + if capacity == 0 {1} else {0}).map(|_| None).collect(), start: 0, size: 0, }, @@ -188,7 +188,7 @@ impl Packet { loop { let mut guard = self.lock.lock().unwrap(); // are we ready to go? - if guard.disconnected || guard.buf.size() < guard.buf.cap() { + if guard.disconnected || guard.buf.size() < guard.buf.capacity() { return guard; } // no room; actually block @@ -230,7 +230,7 @@ impl Packet { let mut guard = self.lock.lock().unwrap(); if guard.disconnected { Err(super::TrySendError::Disconnected(t)) - } else if guard.buf.size() == guard.buf.cap() { + } else if guard.buf.size() == guard.buf.capacity() { Err(super::TrySendError::Full(t)) } else if guard.cap == 0 { // With capacity 0, even though we have buffer space we can't @@ -248,7 +248,7 @@ impl Packet { // If the buffer has some space and the capacity isn't 0, then we // just enqueue the data for later retrieval, ensuring to wake up // any blocked receiver if there is one. - assert!(guard.buf.size() < guard.buf.cap()); + assert!(guard.buf.size() < guard.buf.capacity()); guard.buf.enqueue(t); match mem::replace(&mut guard.blocker, NoneBlocked) { BlockedReceiver(token) => wakeup(token, guard), @@ -383,7 +383,7 @@ impl Packet { // needs to be careful to destroy the data *outside* of the lock to // prevent deadlock. let _data = if guard.cap != 0 { - mem::replace(&mut guard.buf.buf, Vec::new()) + mem::take(&mut guard.buf.buf) } else { Vec::new() }; @@ -438,7 +438,7 @@ impl Buffer { } fn size(&self) -> usize { self.size } - fn cap(&self) -> usize { self.buf.len() } + fn capacity(&self) -> usize { self.buf.len() } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libstd/sys/cloudabi/abi/cloudabi.rs b/src/libstd/sys/cloudabi/abi/cloudabi.rs index 2307e2167c..9addba8b61 100644 --- a/src/libstd/sys/cloudabi/abi/cloudabi.rs +++ b/src/libstd/sys/cloudabi/abi/cloudabi.rs @@ -1884,7 +1884,7 @@ pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> /// **time**: /// The time value of the clock. #[inline] -pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno { +pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: *mut timestamp) -> errno { cloudabi_sys_clock_time_get(clock_id_, precision_, time_) } @@ -2643,7 +2643,7 @@ pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno { /// **nevents**: /// The number of events stored. #[inline] -pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno { +pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: *mut usize) -> errno { cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_) } diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs index 7aa0b0b6f4..ec1fca7805 100644 --- a/src/libstd/sys/cloudabi/condvar.rs +++ b/src/libstd/sys/cloudabi/condvar.rs @@ -79,16 +79,21 @@ impl Condvar { }, ..mem::zeroed() }; - let mut event: abi::event = mem::uninitialized(); - let mut nevents: usize = mem::uninitialized(); - let ret = abi::poll(&subscription, &mut event, 1, &mut nevents); + let mut event: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let mut nevents: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::poll( + &subscription, + event.as_mut_ptr(), + 1, + nevents.as_mut_ptr() + ); assert_eq!( ret, abi::errno::SUCCESS, "Failed to wait on condition variable" ); assert_eq!( - event.error, + event.assume_init().error, abi::errno::SUCCESS, "Failed to wait on condition variable" ); @@ -131,21 +136,27 @@ impl Condvar { ..mem::zeroed() }, ]; - let mut events: [abi::event; 2] = mem::uninitialized(); - let mut nevents: usize = mem::uninitialized(); - let ret = abi::poll(subscriptions.as_ptr(), events.as_mut_ptr(), 2, &mut nevents); + let mut events: [mem::MaybeUninit; 2] = [mem::MaybeUninit::uninit(); 2]; + let mut nevents: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::poll( + subscriptions.as_ptr(), + mem::MaybeUninit::first_ptr_mut(&mut events), + 2, + nevents.as_mut_ptr() + ); assert_eq!( ret, abi::errno::SUCCESS, "Failed to wait on condition variable" ); + let nevents = nevents.assume_init(); for i in 0..nevents { assert_eq!( - events[i].error, + events[i].assume_init().error, abi::errno::SUCCESS, "Failed to wait on condition variable" ); - if events[i].type_ == abi::eventtype::CONDVAR { + if events[i].assume_init().type_ == abi::eventtype::CONDVAR { return true; } } diff --git a/src/libstd/sys/cloudabi/io.rs b/src/libstd/sys/cloudabi/io.rs index 4b423a5cbc..976e122463 100644 --- a/src/libstd/sys/cloudabi/io.rs +++ b/src/libstd/sys/cloudabi/io.rs @@ -1,3 +1,5 @@ +use crate::mem; + pub struct IoSlice<'a>(&'a [u8]); impl<'a> IoSlice<'a> { @@ -6,6 +8,11 @@ impl<'a> IoSlice<'a> { IoSlice(buf) } + #[inline] + pub fn advance(&mut self, n: usize) { + self.0 = &self.0[n..] + } + #[inline] pub fn as_slice(&self) -> &[u8] { self.0 @@ -20,6 +27,13 @@ impl<'a> IoSliceMut<'a> { IoSliceMut(buf) } + #[inline] + pub fn advance(&mut self, n: usize) { + let slice = mem::replace(&mut self.0, &mut []); + let (_, remaining) = slice.split_at_mut(n); + self.0 = remaining; + } + #[inline] pub fn as_slice(&self) -> &[u8] { self.0 diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs index c3b8bbd042..6e147612eb 100644 --- a/src/libstd/sys/cloudabi/mod.rs +++ b/src/libstd/sys/cloudabi/mod.rs @@ -1,3 +1,5 @@ +#![allow(deprecated_in_future)] // mem::uninitialized; becomes `deprecated` when nightly is 1.39 + use crate::io::ErrorKind; use crate::mem; @@ -59,8 +61,11 @@ pub use libc::strlen; pub fn hashmap_random_keys() -> (u64, u64) { unsafe { - let mut v = mem::uninitialized(); - libc::arc4random_buf(&mut v as *mut _ as *mut libc::c_void, mem::size_of_val(&v)); - v + let mut v: mem::MaybeUninit<(u64, u64)> = mem::MaybeUninit::uninit(); + libc::arc4random_buf( + v.as_mut_ptr() as *mut libc::c_void, + mem::size_of_val(&v) + ); + v.assume_init() } } diff --git a/src/libstd/sys/cloudabi/mutex.rs b/src/libstd/sys/cloudabi/mutex.rs index 5e191e31d5..d3ff0077b2 100644 --- a/src/libstd/sys/cloudabi/mutex.rs +++ b/src/libstd/sys/cloudabi/mutex.rs @@ -1,5 +1,6 @@ use crate::cell::UnsafeCell; use crate::mem; +use crate::mem::MaybeUninit; use crate::sync::atomic::{AtomicU32, Ordering}; use crate::sys::cloudabi::abi; use crate::sys::rwlock::{self, RWLock}; @@ -47,24 +48,27 @@ impl Mutex { } pub struct ReentrantMutex { - lock: UnsafeCell, - recursion: UnsafeCell, + lock: UnsafeCell>, + recursion: UnsafeCell>, } impl ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex { - mem::uninitialized() + ReentrantMutex { + lock: UnsafeCell::new(MaybeUninit::uninit()), + recursion: UnsafeCell::new(MaybeUninit::uninit()) + } } pub unsafe fn init(&mut self) { - self.lock = UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)); - self.recursion = UnsafeCell::new(0); + self.lock = UnsafeCell::new(MaybeUninit::new(AtomicU32::new(abi::LOCK_UNLOCKED.0))); + self.recursion = UnsafeCell::new(MaybeUninit::new(0)); } pub unsafe fn try_lock(&self) -> bool { // Attempt to acquire the lock. - let lock = self.lock.get(); - let recursion = self.recursion.get(); + let lock = (*self.lock.get()).as_mut_ptr(); + let recursion = (*self.recursion.get()).as_mut_ptr(); if let Err(old) = (*lock).compare_exchange( abi::LOCK_UNLOCKED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, @@ -109,8 +113,8 @@ impl ReentrantMutex { } pub unsafe fn unlock(&self) { - let lock = self.lock.get(); - let recursion = self.recursion.get(); + let lock = (*self.lock.get()).as_mut_ptr(); + let recursion = (*self.recursion.get()).as_mut_ptr(); assert_eq!( (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, @@ -136,8 +140,8 @@ impl ReentrantMutex { } pub unsafe fn destroy(&self) { - let lock = self.lock.get(); - let recursion = self.recursion.get(); + let lock = (*self.lock.get()).as_mut_ptr(); + let recursion = (*self.recursion.get()).as_mut_ptr(); assert_eq!( (*lock).load(Ordering::Relaxed), abi::LOCK_UNLOCKED.0, diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index 49a234e115..5e502dcb2b 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -18,10 +18,10 @@ pub fn checked_dur2intervals(dur: &Duration) -> Option { impl Instant { pub fn now() -> Instant { unsafe { - let mut t = mem::uninitialized(); - let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, &mut t); + let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.as_mut_ptr()); assert_eq!(ret, abi::errno::SUCCESS); - Instant { t } + Instant { t: t.assume_init() } } } @@ -59,10 +59,10 @@ pub struct SystemTime { impl SystemTime { pub fn now() -> SystemTime { unsafe { - let mut t = mem::uninitialized(); - let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, &mut t); + let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.as_mut_ptr()); assert_eq!(ret, abi::errno::SUCCESS); - SystemTime { t } + SystemTime { t: t.assume_init() } } } diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 21360e2e0f..5a5859a6ad 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -23,7 +23,10 @@ #![allow(missing_debug_implementations)] cfg_if::cfg_if! { - if #[cfg(unix)] { + if #[cfg(target_os = "vxworks")] { + mod vxworks; + pub use self::vxworks::*; + } else if #[cfg(unix)] { mod unix; pub use self::unix::*; } else if #[cfg(windows)] { @@ -32,9 +35,6 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "cloudabi")] { mod cloudabi; pub use self::cloudabi::*; - } else if #[cfg(target_os = "redox")] { - mod redox; - pub use self::redox::*; } else if #[cfg(target_os = "wasi")] { mod wasi; pub use self::wasi::*; @@ -55,7 +55,7 @@ cfg_if::cfg_if! { #[cfg(rustdoc)] cfg_if::cfg_if! { - if #[cfg(any(unix, target_os = "redox"))] { + if #[cfg(unix)] { // On unix we'll document what's already available #[stable(feature = "rust1", since = "1.0.0")] pub use self::ext as unix_ext; diff --git a/src/libstd/sys/redox/condvar.rs b/src/libstd/sys/redox/condvar.rs deleted file mode 100644 index a6365cac23..0000000000 --- a/src/libstd/sys/redox/condvar.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::intrinsics::{atomic_cxchg, atomic_load, atomic_xadd, atomic_xchg}; -use crate::ptr; -use crate::time::Duration; - -use crate::sys::mutex::{mutex_unlock, Mutex}; -use crate::sys::syscall::{futex, TimeSpec, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE}; - -pub struct Condvar { - lock: UnsafeCell<*mut i32>, - seq: UnsafeCell -} - -impl Condvar { - pub const fn new() -> Condvar { - Condvar { - lock: UnsafeCell::new(ptr::null_mut()), - seq: UnsafeCell::new(0) - } - } - - #[inline] - pub unsafe fn init(&self) { - *self.lock.get() = ptr::null_mut(); - *self.seq.get() = 0; - } - - #[inline] - pub fn notify_one(&self) { - unsafe { - let seq = self.seq.get(); - - atomic_xadd(seq, 1); - - let _ = futex(seq, FUTEX_WAKE, 1, 0, ptr::null_mut()); - } - } - - #[inline] - pub fn notify_all(&self) { - unsafe { - let lock = self.lock.get(); - let seq = self.seq.get(); - - if *lock == ptr::null_mut() { - return; - } - - atomic_xadd(seq, 1); - - let _ = futex(seq, FUTEX_REQUEUE, 1, crate::usize::MAX, *lock); - } - } - - #[inline] - unsafe fn wait_inner(&self, mutex: &Mutex, timeout_ptr: *const TimeSpec) -> bool { - let lock = self.lock.get(); - let seq = self.seq.get(); - - if *lock != mutex.lock.get() { - if *lock != ptr::null_mut() { - panic!("Condvar used with more than one Mutex"); - } - - atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize); - } - - mutex_unlock(*lock); - - let seq_before = atomic_load(seq); - - let _ = futex(seq, FUTEX_WAIT, seq_before, timeout_ptr as usize, ptr::null_mut()); - - let seq_after = atomic_load(seq); - - while atomic_xchg(*lock, 2) != 0 { - let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut()); - } - - seq_before != seq_after - } - - #[inline] - pub fn wait(&self, mutex: &Mutex) { - unsafe { - assert!(self.wait_inner(mutex, ptr::null())); - } - } - - #[inline] - pub fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - unsafe { - let timeout = TimeSpec { - tv_sec: dur.as_secs() as i64, - tv_nsec: dur.subsec_nanos() as i32 - }; - - self.wait_inner(mutex, &timeout as *const TimeSpec) - } - } - - #[inline] - pub unsafe fn destroy(&self) { - *self.lock.get() = ptr::null_mut(); - *self.seq.get() = 0; - } -} - -unsafe impl Send for Condvar {} - -unsafe impl Sync for Condvar {} diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs deleted file mode 100644 index 4ddc1f09a3..0000000000 --- a/src/libstd/sys/redox/ext/fs.rs +++ /dev/null @@ -1,339 +0,0 @@ -//! Redox-specific extensions to primitives in the `std::fs` module. - -#![stable(feature = "rust1", since = "1.0.0")] - -use crate::fs::{self, Permissions, OpenOptions}; -use crate::io; -use crate::path::Path; -use crate::sys; -use crate::sys_common::{FromInner, AsInner, AsInnerMut}; - -/// Redox-specific extensions to [`fs::Permissions`]. -/// -/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html -#[stable(feature = "fs_ext", since = "1.1.0")] -pub trait PermissionsExt { - /// Returns the underlying raw `mode_t` bits that are the standard Redox - /// permissions for this file. - /// - /// # Examples - /// - /// ```no_run - /// use std::fs::File; - /// use std::os::redox::fs::PermissionsExt; - /// - /// fn main() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let permissions = metadata.permissions(); - /// - /// println!("permissions: {:o}", permissions.mode()); - /// Ok(()) - /// } - /// ``` - #[stable(feature = "fs_ext", since = "1.1.0")] - fn mode(&self) -> u32; - - /// Sets the underlying raw bits for this set of permissions. - /// - /// # Examples - /// - /// ```no_run - /// use std::fs::File; - /// use std::os::redox::fs::PermissionsExt; - /// - /// fn main() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let mut permissions = metadata.permissions(); - /// - /// permissions.set_mode(0o644); // Read/write for owner and read for others. - /// assert_eq!(permissions.mode(), 0o644); - /// Ok(()) - /// } - /// ``` - #[stable(feature = "fs_ext", since = "1.1.0")] - fn set_mode(&mut self, mode: u32); - - /// Creates a new instance of `Permissions` from the given set of Redox - /// permission bits. - /// - /// # Examples - /// - /// ``` - /// use std::fs::Permissions; - /// use std::os::redox::fs::PermissionsExt; - /// - /// // Read/write for owner and read for others. - /// let permissions = Permissions::from_mode(0o644); - /// assert_eq!(permissions.mode(), 0o644); - /// ``` - #[stable(feature = "fs_ext", since = "1.1.0")] - fn from_mode(mode: u32) -> Self; -} - -#[stable(feature = "fs_ext", since = "1.1.0")] -impl PermissionsExt for Permissions { - fn mode(&self) -> u32 { - self.as_inner().mode() - } - - fn set_mode(&mut self, mode: u32) { - *self = Permissions::from_inner(FromInner::from_inner(mode)); - } - - fn from_mode(mode: u32) -> Permissions { - Permissions::from_inner(FromInner::from_inner(mode)) - } -} - -/// Redox-specific extensions to [`fs::OpenOptions`]. -/// -/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html -#[stable(feature = "fs_ext", since = "1.1.0")] -pub trait OpenOptionsExt { - /// Sets the mode bits that a new file will be created with. - /// - /// If a new file is created as part of a `File::open_opts` call then this - /// specified `mode` will be used as the permission bits for the new file. - /// If no `mode` is set, the default of `0o666` will be used. - /// The operating system masks out bits with the systems `umask`, to produce - /// the final permissions. - /// - /// # Examples - /// - /// ```no_run - /// # #![feature(libc)] - /// extern crate libc; - /// use std::fs::OpenOptions; - /// use std::os::redox::fs::OpenOptionsExt; - /// - /// # fn main() { - /// let mut options = OpenOptions::new(); - /// options.mode(0o644); // Give read/write for owner and read for others. - /// let file = options.open("foo.txt"); - /// # } - /// ``` - #[stable(feature = "fs_ext", since = "1.1.0")] - fn mode(&mut self, mode: u32) -> &mut Self; - - /// Passes custom flags to the `flags` argument of `open`. - /// - /// The bits that define the access mode are masked out with `O_ACCMODE`, to - /// ensure they do not interfere with the access mode set by Rusts options. - /// - /// Custom flags can only set flags, not remove flags set by Rusts options. - /// This options overwrites any previously set custom flags. - /// - /// # Examples - /// - /// ```no_run - /// # #![feature(libc)] - /// extern crate libc; - /// use std::fs::OpenOptions; - /// use std::os::redox::fs::OpenOptionsExt; - /// - /// # fn main() { - /// let mut options = OpenOptions::new(); - /// options.write(true); - /// if cfg!(target_os = "redox") { - /// options.custom_flags(libc::O_NOFOLLOW); - /// } - /// let file = options.open("foo.txt"); - /// # } - /// ``` - #[stable(feature = "open_options_ext", since = "1.10.0")] - fn custom_flags(&mut self, flags: i32) -> &mut Self; -} - -#[stable(feature = "fs_ext", since = "1.1.0")] -impl OpenOptionsExt for OpenOptions { - fn mode(&mut self, mode: u32) -> &mut OpenOptions { - self.as_inner_mut().mode(mode); self - } - - fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions { - self.as_inner_mut().custom_flags(flags); self - } -} - -/// Redox-specific extensions to [`fs::Metadata`]. -/// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html -#[stable(feature = "metadata_ext", since = "1.1.0")] -pub trait MetadataExt { - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn dev(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn ino(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn mode(&self) -> u32; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn nlink(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn uid(&self) -> u32; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn gid(&self) -> u32; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn size(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn atime(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn atime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn mtime(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn mtime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn ctime(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn ctime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn blksize(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn blocks(&self) -> u64; -} - -// Hm, why are there casts here to the returned type, shouldn't the types always -// be the same? Right you are! Turns out, however, on android at least the types -// in the raw `stat` structure are not the same as the types being returned. Who -// knew! -// -// As a result to make sure this compiles for all platforms we do the manual -// casts and rely on manual lowering to `stat` if the raw type is desired. -#[stable(feature = "metadata_ext", since = "1.1.0")] -impl MetadataExt for fs::Metadata { - fn dev(&self) -> u64 { - self.as_inner().as_inner().st_dev as u64 - } - fn ino(&self) -> u64 { - self.as_inner().as_inner().st_ino as u64 - } - fn mode(&self) -> u32 { - self.as_inner().as_inner().st_mode as u32 - } - fn nlink(&self) -> u64 { - self.as_inner().as_inner().st_nlink as u64 - } - fn uid(&self) -> u32 { - self.as_inner().as_inner().st_uid as u32 - } - fn gid(&self) -> u32 { - self.as_inner().as_inner().st_gid as u32 - } - fn size(&self) -> u64 { - self.as_inner().as_inner().st_size as u64 - } - fn atime(&self) -> i64 { - self.as_inner().as_inner().st_atime as i64 - } - fn atime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_atime_nsec as i64 - } - fn mtime(&self) -> i64 { - self.as_inner().as_inner().st_mtime as i64 - } - fn mtime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_mtime_nsec as i64 - } - fn ctime(&self) -> i64 { - self.as_inner().as_inner().st_ctime as i64 - } - fn ctime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_ctime_nsec as i64 - } - fn blksize(&self) -> u64 { - self.as_inner().as_inner().st_blksize as u64 - } - fn blocks(&self) -> u64 { - self.as_inner().as_inner().st_blocks as u64 - } -} - -/// Redox-specific extensions for [`FileType`]. -/// -/// Adds support for special Unix file types such as block/character devices, -/// pipes, and sockets. -/// -/// [`FileType`]: ../../../../std/fs/struct.FileType.html -#[stable(feature = "file_type_ext", since = "1.5.0")] -pub trait FileTypeExt { - /// Returns whether this file type is a block device. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_block_device(&self) -> bool; - /// Returns whether this file type is a char device. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_char_device(&self) -> bool; - /// Returns whether this file type is a fifo. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_fifo(&self) -> bool; - /// Returns whether this file type is a socket. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_socket(&self) -> bool; -} - -#[stable(feature = "file_type_ext", since = "1.5.0")] -impl FileTypeExt for fs::FileType { - fn is_block_device(&self) -> bool { false /*FIXME: Implement block device mode*/ } - fn is_char_device(&self) -> bool { false /*FIXME: Implement char device mode*/ } - fn is_fifo(&self) -> bool { false /*FIXME: Implement fifo mode*/ } - fn is_socket(&self) -> bool { false /*FIXME: Implement socket mode*/ } -} - -/// Creates a new symbolic link on the filesystem. -/// -/// The `dst` path will be a symbolic link pointing to the `src` path. -/// -/// # Note -/// -/// On Windows, you must specify whether a symbolic link points to a file -/// or directory. Use `os::windows::fs::symlink_file` to create a -/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a -/// symbolic link to a directory. Additionally, the process must have -/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a -/// symbolic link. -/// -/// # Examples -/// -/// ```no_run -/// use std::os::redox::fs; -/// -/// fn main() -> std::io::Result<()> { -/// fs::symlink("a.txt", "b.txt")?; -/// Ok(()) -/// } -/// ``` -#[stable(feature = "symlink", since = "1.1.0")] -pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> -{ - sys::fs::symlink(src.as_ref(), dst.as_ref()) -} - -/// Redox-specific extensions to [`fs::DirBuilder`]. -/// -/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html -#[stable(feature = "dir_builder", since = "1.6.0")] -pub trait DirBuilderExt { - /// Sets the mode to create new directories with. This option defaults to - /// 0o777. - /// - /// # Examples - /// - /// ```no_run - /// use std::fs::DirBuilder; - /// use std::os::redox::fs::DirBuilderExt; - /// - /// let mut builder = DirBuilder::new(); - /// builder.mode(0o755); - /// ``` - #[stable(feature = "dir_builder", since = "1.6.0")] - fn mode(&mut self, mode: u32) -> &mut Self; -} - -#[stable(feature = "dir_builder", since = "1.6.0")] -impl DirBuilderExt for fs::DirBuilder { - fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder { - self.as_inner_mut().set_mode(mode); - self - } -} diff --git a/src/libstd/sys/redox/ext/mod.rs b/src/libstd/sys/redox/ext/mod.rs deleted file mode 100644 index 8a2d243c7f..0000000000 --- a/src/libstd/sys/redox/ext/mod.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Experimental extensions to `std` for Unix platforms. -//! -//! For now, this module is limited to extracting file descriptors, -//! but its functionality will grow over time. -//! -//! # Examples -//! -//! ```no_run -//! use std::fs::File; -//! use std::os::unix::prelude::*; -//! -//! fn main() { -//! let f = File::create("foo.txt").unwrap(); -//! let fd = f.as_raw_fd(); -//! -//! // use fd with native unix bindings -//! } -//! ``` - -#![stable(feature = "rust1", since = "1.0.0")] -#![doc(cfg(target_os = "redox"))] - -pub mod ffi; -pub mod fs; -pub mod io; -pub mod net; -pub mod process; -pub mod thread; - -/// A prelude for conveniently writing platform-specific code. -/// -/// Includes all extension traits, and some important type definitions. -#[stable(feature = "rust1", since = "1.0.0")] -pub mod prelude { - #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd}; - #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::ffi::{OsStrExt, OsStringExt}; - #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::fs::{FileTypeExt, PermissionsExt, OpenOptionsExt, MetadataExt}; - #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::thread::JoinHandleExt; - #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] - pub use super::process::{CommandExt, ExitStatusExt}; -} diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs deleted file mode 100644 index b3ef5f3064..0000000000 --- a/src/libstd/sys/redox/ext/net.rs +++ /dev/null @@ -1,759 +0,0 @@ -#![stable(feature = "unix_socket_redox", since = "1.29.0")] - -//! Unix-specific networking functionality - -use crate::fmt; -use crate::io::{self, Error, ErrorKind, Initializer}; -use crate::net::Shutdown; -use crate::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd}; -use crate::path::Path; -use crate::time::Duration; -use crate::sys::{cvt, fd::FileDesc, syscall}; - -/// An address associated with a Unix socket. -/// -/// # Examples -/// -/// ``` -/// use std::os::unix::net::UnixListener; -/// -/// let socket = match UnixListener::bind("/tmp/sock") { -/// Ok(sock) => sock, -/// Err(e) => { -/// println!("Couldn't bind: {:?}", e); -/// return -/// } -/// }; -/// let addr = socket.local_addr().expect("Couldn't get local address"); -/// ``` -#[derive(Clone)] -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -pub struct SocketAddr(()); - -impl SocketAddr { - /// Returns the contents of this address if it is a `pathname` address. - /// - /// # Examples - /// - /// With a pathname: - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// use std::path::Path; - /// - /// let socket = UnixListener::bind("/tmp/sock").unwrap(); - /// let addr = socket.local_addr().expect("Couldn't get local address"); - /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock"))); - /// ``` - /// - /// Without a pathname: - /// - /// ``` - /// use std::os::unix::net::UnixDatagram; - /// - /// let socket = UnixDatagram::unbound().unwrap(); - /// let addr = socket.local_addr().expect("Couldn't get local address"); - /// assert_eq!(addr.as_pathname(), None); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn as_pathname(&self) -> Option<&Path> { - None - } - - /// Returns `true` if the address is unnamed. - /// - /// # Examples - /// - /// A named address: - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let socket = UnixListener::bind("/tmp/sock").unwrap(); - /// let addr = socket.local_addr().expect("Couldn't get local address"); - /// assert_eq!(addr.is_unnamed(), false); - /// ``` - /// - /// An unnamed address: - /// - /// ``` - /// use std::os::unix::net::UnixDatagram; - /// - /// let socket = UnixDatagram::unbound().unwrap(); - /// let addr = socket.local_addr().expect("Couldn't get local address"); - /// assert_eq!(addr.is_unnamed(), true); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn is_unnamed(&self) -> bool { - false - } -} -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl fmt::Debug for SocketAddr { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "SocketAddr") - } -} - -/// A Unix stream socket. -/// -/// # Examples -/// -/// ```no_run -/// use std::os::unix::net::UnixStream; -/// use std::io::prelude::*; -/// -/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap(); -/// stream.write_all(b"hello world").unwrap(); -/// let mut response = String::new(); -/// stream.read_to_string(&mut response).unwrap(); -/// println!("{}", response); -/// ``` -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -pub struct UnixStream(FileDesc); - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl fmt::Debug for UnixStream { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut builder = fmt.debug_struct("UnixStream"); - builder.field("fd", &self.0.raw()); - if let Ok(addr) = self.local_addr() { - builder.field("local", &addr); - } - if let Ok(addr) = self.peer_addr() { - builder.field("peer", &addr); - } - builder.finish() - } -} - -impl UnixStream { - /// Connects to the socket named by `path`. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let socket = match UnixStream::connect("/tmp/sock") { - /// Ok(sock) => sock, - /// Err(e) => { - /// println!("Couldn't connect: {:?}", e); - /// return - /// } - /// }; - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn connect>(path: P) -> io::Result { - if let Some(s) = path.as_ref().to_str() { - cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC)) - .map(FileDesc::new) - .map(UnixStream) - } else { - Err(Error::new( - ErrorKind::Other, - "UnixStream::connect: non-utf8 paths not supported on redox" - )) - } - } - - /// Creates an unnamed pair of connected sockets. - /// - /// Returns two `UnixStream`s which are connected to each other. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let (sock1, sock2) = match UnixStream::pair() { - /// Ok((sock1, sock2)) => (sock1, sock2), - /// Err(e) => { - /// println!("Couldn't create a pair of sockets: {:?}", e); - /// return - /// } - /// }; - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn pair() -> io::Result<(UnixStream, UnixStream)> { - let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC)) - .map(FileDesc::new)?; - let client = server.duplicate_path(b"connect")?; - let stream = server.duplicate_path(b"listen")?; - Ok((UnixStream(client), UnixStream(stream))) - } - - /// Creates a new independently owned handle to the underlying socket. - /// - /// The returned `UnixStream` is a reference to the same stream that this - /// object references. Both handles will read and write the same stream of - /// data, and options set on one stream will be propagated to the other - /// stream. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// let sock_copy = socket.try_clone().expect("Couldn't clone socket"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn try_clone(&self) -> io::Result { - self.0.duplicate().map(UnixStream) - } - - /// Returns the socket address of the local half of this connection. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// let addr = socket.local_addr().expect("Couldn't get local address"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn local_addr(&self) -> io::Result { - Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox")) - } - - /// Returns the socket address of the remote half of this connection. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// let addr = socket.peer_addr().expect("Couldn't get peer address"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn peer_addr(&self) -> io::Result { - Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox")) - } - - /// Sets the read timeout for the socket. - /// - /// If the provided value is [`None`], then [`read`] calls will block - /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this - /// method. - /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err - /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read - /// [`Duration`]: ../../../../std/time/struct.Duration.html - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// use std::time::Duration; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); - /// ``` - /// - /// An [`Err`] is returned if the zero [`Duration`] is passed to this - /// method: - /// - /// ```no_run - /// use std::io; - /// use std::os::unix::net::UnixStream; - /// use std::time::Duration; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// let result = socket.set_read_timeout(Some(Duration::new(0, 0))); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn set_read_timeout(&self, _timeout: Option) -> io::Result<()> { - Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox")) - } - - /// Sets the write timeout for the socket. - /// - /// If the provided value is [`None`], then [`write`] calls will block - /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is - /// passed to this method. - /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err - /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write - /// [`Duration`]: ../../../../std/time/struct.Duration.html - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// use std::time::Duration; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout"); - /// ``` - /// - /// An [`Err`] is returned if the zero [`Duration`] is passed to this - /// method: - /// - /// ```no_run - /// use std::io; - /// use std::net::UdpSocket; - /// use std::time::Duration; - /// - /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap(); - /// let result = socket.set_write_timeout(Some(Duration::new(0, 0))); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn set_write_timeout(&self, _timeout: Option) -> io::Result<()> { - Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox")) - } - - /// Returns the read timeout of this socket. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// use std::time::Duration; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); - /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0))); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn read_timeout(&self) -> io::Result> { - Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox")) - } - - /// Returns the write timeout of this socket. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// use std::time::Duration; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout"); - /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0))); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn write_timeout(&self) -> io::Result> { - Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox")) - } - - /// Moves the socket into or out of nonblocking mode. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// socket.set_nonblocking(true).expect("Couldn't set nonblocking"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - self.0.set_nonblocking(nonblocking) - } - - /// Returns the value of the `SO_ERROR` option. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// if let Ok(Some(err)) = socket.take_error() { - /// println!("Got error: {:?}", err); - /// } - /// ``` - /// - /// # Platform specific - /// On Redox this always returns `None`. - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn take_error(&self) -> io::Result> { - Ok(None) - } - - /// Shuts down the read, write, or both halves of this connection. - /// - /// This function will cause all pending and future I/O calls on the - /// specified portions to immediately return with an appropriate value - /// (see the documentation of [`Shutdown`]). - /// - /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixStream; - /// use std::net::Shutdown; - /// - /// let socket = UnixStream::connect("/tmp/sock").unwrap(); - /// socket.shutdown(Shutdown::Both).expect("shutdown function failed"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> { - Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox")) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl io::Read for UnixStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - io::Read::read(&mut &*self, buf) - } - - #[inline] - unsafe fn initializer(&self) -> Initializer { - Initializer::nop() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> io::Read for &'a UnixStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - #[inline] - unsafe fn initializer(&self) -> Initializer { - Initializer::nop() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl io::Write for UnixStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - io::Write::write(&mut &*self, buf) - } - - fn flush(&mut self) -> io::Result<()> { - io::Write::flush(&mut &*self) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> io::Write for &'a UnixStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl AsRawFd for UnixStream { - fn as_raw_fd(&self) -> RawFd { - self.0.raw() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl FromRawFd for UnixStream { - unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { - UnixStream(FileDesc::new(fd)) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl IntoRawFd for UnixStream { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw() - } -} - -/// A structure representing a Unix domain socket server. -/// -/// # Examples -/// -/// ```no_run -/// use std::thread; -/// use std::os::unix::net::{UnixStream, UnixListener}; -/// -/// fn handle_client(stream: UnixStream) { -/// // ... -/// } -/// -/// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); -/// -/// // accept connections and process them, spawning a new thread for each one -/// for stream in listener.incoming() { -/// match stream { -/// Ok(stream) => { -/// /* connection succeeded */ -/// thread::spawn(|| handle_client(stream)); -/// } -/// Err(err) => { -/// /* connection failed */ -/// break; -/// } -/// } -/// } -/// ``` -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -pub struct UnixListener(FileDesc); - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl fmt::Debug for UnixListener { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut builder = fmt.debug_struct("UnixListener"); - builder.field("fd", &self.0.raw()); - if let Ok(addr) = self.local_addr() { - builder.field("local", &addr); - } - builder.finish() - } -} - -impl UnixListener { - /// Creates a new `UnixListener` bound to the specified socket. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let listener = match UnixListener::bind("/path/to/the/socket") { - /// Ok(sock) => sock, - /// Err(e) => { - /// println!("Couldn't connect: {:?}", e); - /// return - /// } - /// }; - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn bind>(path: P) -> io::Result { - if let Some(s) = path.as_ref().to_str() { - cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC)) - .map(FileDesc::new) - .map(UnixListener) - } else { - Err(Error::new( - ErrorKind::Other, - "UnixListener::bind: non-utf8 paths not supported on redox" - )) - } - } - - /// Accepts a new incoming connection to this listener. - /// - /// This function will block the calling thread until a new Unix connection - /// is established. When established, the corresponding [`UnixStream`] and - /// the remote peer's address will be returned. - /// - /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); - /// - /// match listener.accept() { - /// Ok((socket, addr)) => println!("Got a client: {:?}", addr), - /// Err(e) => println!("accept function failed: {:?}", e), - /// } - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { - self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(()))) - } - - /// Creates a new independently owned handle to the underlying socket. - /// - /// The returned `UnixListener` is a reference to the same socket that this - /// object references. Both handles can be used to accept incoming - /// connections and options set on one listener will affect the other. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); - /// - /// let listener_copy = listener.try_clone().expect("try_clone failed"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn try_clone(&self) -> io::Result { - self.0.duplicate().map(UnixListener) - } - - /// Returns the local socket address of this listener. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); - /// - /// let addr = listener.local_addr().expect("Couldn't get local address"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn local_addr(&self) -> io::Result { - Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox")) - } - - /// Moves the socket into or out of nonblocking mode. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); - /// - /// listener.set_nonblocking(true).expect("Couldn't set non blocking"); - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - self.0.set_nonblocking(nonblocking) - } - - /// Returns the value of the `SO_ERROR` option. - /// - /// # Examples - /// - /// ```no_run - /// use std::os::unix::net::UnixListener; - /// - /// let listener = UnixListener::bind("/tmp/sock").unwrap(); - /// - /// if let Ok(Some(err)) = listener.take_error() { - /// println!("Got error: {:?}", err); - /// } - /// ``` - /// - /// # Platform specific - /// On Redox this always returns `None`. - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn take_error(&self) -> io::Result> { - Ok(None) - } - - /// Returns an iterator over incoming connections. - /// - /// The iterator will never return [`None`] and will also not yield the - /// peer's [`SocketAddr`] structure. - /// - /// [`None`]: ../../../../std/option/enum.Option.html#variant.None - /// [`SocketAddr`]: struct.SocketAddr.html - /// - /// # Examples - /// - /// ```no_run - /// use std::thread; - /// use std::os::unix::net::{UnixStream, UnixListener}; - /// - /// fn handle_client(stream: UnixStream) { - /// // ... - /// } - /// - /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); - /// - /// for stream in listener.incoming() { - /// match stream { - /// Ok(stream) => { - /// thread::spawn(|| handle_client(stream)); - /// } - /// Err(err) => { - /// break; - /// } - /// } - /// } - /// ``` - #[stable(feature = "unix_socket_redox", since = "1.29.0")] - pub fn incoming<'a>(&'a self) -> Incoming<'a> { - Incoming { listener: self } - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl AsRawFd for UnixListener { - fn as_raw_fd(&self) -> RawFd { - self.0.raw() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl FromRawFd for UnixListener { - unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { - UnixListener(FileDesc::new(fd)) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl IntoRawFd for UnixListener { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> IntoIterator for &'a UnixListener { - type Item = io::Result; - type IntoIter = Incoming<'a>; - - fn into_iter(self) -> Incoming<'a> { - self.incoming() - } -} - -/// An iterator over incoming connections to a [`UnixListener`]. -/// -/// It will never return [`None`]. -/// -/// [`None`]: ../../../../std/option/enum.Option.html#variant.None -/// [`UnixListener`]: struct.UnixListener.html -/// -/// # Examples -/// -/// ```no_run -/// use std::thread; -/// use std::os::unix::net::{UnixStream, UnixListener}; -/// -/// fn handle_client(stream: UnixStream) { -/// // ... -/// } -/// -/// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); -/// -/// for stream in listener.incoming() { -/// match stream { -/// Ok(stream) => { -/// thread::spawn(|| handle_client(stream)); -/// } -/// Err(err) => { -/// break; -/// } -/// } -/// } -/// ``` -#[derive(Debug)] -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -pub struct Incoming<'a> { - listener: &'a UnixListener, -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> Iterator for Incoming<'a> { - type Item = io::Result; - - fn next(&mut self) -> Option> { - Some(self.listener.accept().map(|s| s.0)) - } - - fn size_hint(&self) -> (usize, Option) { - (usize::max_value(), None) - } -} diff --git a/src/libstd/sys/redox/ext/thread.rs b/src/libstd/sys/redox/ext/thread.rs deleted file mode 100644 index 629eaef04c..0000000000 --- a/src/libstd/sys/redox/ext/thread.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Redox-specific extensions to primitives in the `std::thread` module. - -#![stable(feature = "thread_extensions", since = "1.9.0")] - -use crate::sys_common::{AsInner, IntoInner}; -use crate::thread::JoinHandle; - -#[stable(feature = "thread_extensions", since = "1.9.0")] -#[allow(deprecated)] -pub type RawPthread = usize; - -/// Redox-specific extensions to [`thread::JoinHandle`]. -/// -/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html -#[stable(feature = "thread_extensions", since = "1.9.0")] -pub trait JoinHandleExt { - /// Extracts the raw pthread_t without taking ownership - #[stable(feature = "thread_extensions", since = "1.9.0")] - fn as_pthread_t(&self) -> RawPthread; - - /// Consumes the thread, returning the raw pthread_t - /// - /// This function **transfers ownership** of the underlying pthread_t to - /// the caller. Callers are then the unique owners of the pthread_t and - /// must either detach or join the pthread_t once it's no longer needed. - #[stable(feature = "thread_extensions", since = "1.9.0")] - fn into_pthread_t(self) -> RawPthread; -} - -#[stable(feature = "thread_extensions", since = "1.9.0")] -impl JoinHandleExt for JoinHandle { - fn as_pthread_t(&self) -> RawPthread { - self.as_inner().id() as RawPthread - } - - fn into_pthread_t(self) -> RawPthread { - self.into_inner().into_id() as RawPthread - } -} diff --git a/src/libstd/sys/redox/fast_thread_local.rs b/src/libstd/sys/redox/fast_thread_local.rs deleted file mode 100644 index 05464787a0..0000000000 --- a/src/libstd/sys/redox/fast_thread_local.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![cfg(target_thread_local)] -#![unstable(feature = "thread_local_internals", issue = "0")] - -pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; diff --git a/src/libstd/sys/redox/fd.rs b/src/libstd/sys/redox/fd.rs deleted file mode 100644 index a42e486db2..0000000000 --- a/src/libstd/sys/redox/fd.rs +++ /dev/null @@ -1,88 +0,0 @@ -#![unstable(reason = "not public", issue = "0", feature = "fd")] - -use crate::io::{self, Read}; -use crate::mem; -use crate::sys::{cvt, syscall}; -use crate::sys_common::AsInner; - -pub struct FileDesc { - fd: usize, -} - -impl FileDesc { - pub fn new(fd: usize) -> FileDesc { - FileDesc { fd } - } - - pub fn raw(&self) -> usize { self.fd } - - /// Extracts the actual file descriptor without closing it. - pub fn into_raw(self) -> usize { - let fd = self.fd; - mem::forget(self); - fd - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - cvt(syscall::read(self.fd, buf)) - } - - pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { - let mut me = self; - (&mut me).read_to_end(buf) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - cvt(syscall::write(self.fd, buf)) - } - - pub fn duplicate(&self) -> io::Result { - self.duplicate_path(&[]) - } - pub fn duplicate_path(&self, path: &[u8]) -> io::Result { - let new_fd = cvt(syscall::dup(self.fd, path))?; - Ok(FileDesc::new(new_fd)) - } - - pub fn nonblocking(&self) -> io::Result { - let flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?; - Ok(flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK) - } - - pub fn set_cloexec(&self) -> io::Result<()> { - let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFD, 0))?; - flags |= syscall::O_CLOEXEC; - cvt(syscall::fcntl(self.fd, syscall::F_SETFD, flags)).and(Ok(())) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?; - if nonblocking { - flags |= syscall::O_NONBLOCK; - } else { - flags &= !syscall::O_NONBLOCK; - } - cvt(syscall::fcntl(self.fd, syscall::F_SETFL, flags)).and(Ok(())) - } -} - -impl<'a> Read for &'a FileDesc { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - (**self).read(buf) - } -} - -impl AsInner for FileDesc { - fn as_inner(&self) -> &usize { &self.fd } -} - -impl Drop for FileDesc { - fn drop(&mut self) { - // Note that errors are ignored when closing a file descriptor. The - // reason for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file descriptor - // (opened after we closed ours. - let _ = syscall::close(self.fd); - } -} diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs deleted file mode 100644 index b80a1a349e..0000000000 --- a/src/libstd/sys/redox/fs.rs +++ /dev/null @@ -1,447 +0,0 @@ -use crate::os::unix::prelude::*; - -use crate::ffi::{OsString, OsStr}; -use crate::fmt; -use crate::io::{self, Error, SeekFrom, IoSlice, IoSliceMut}; -use crate::path::{Path, PathBuf}; -use crate::sync::Arc; -use crate::sys::fd::FileDesc; -use crate::sys::time::SystemTime; -use crate::sys::{cvt, syscall}; -use crate::sys_common::{AsInner, FromInner}; - -pub use crate::sys_common::fs::copy; -pub use crate::sys_common::fs::remove_dir_all; - -pub struct File(FileDesc); - -#[derive(Clone)] -pub struct FileAttr { - stat: syscall::Stat, -} - -pub struct ReadDir { - data: Vec, - i: usize, - root: Arc, -} - -struct Dir(FileDesc); - -unsafe impl Send for Dir {} -unsafe impl Sync for Dir {} - -pub struct DirEntry { - root: Arc, - name: Box<[u8]> -} - -#[derive(Clone, Debug)] -pub struct OpenOptions { - // generic - read: bool, - write: bool, - append: bool, - truncate: bool, - create: bool, - create_new: bool, - // system-specific - custom_flags: i32, - mode: u16, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct FilePermissions { mode: u16 } - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct FileType { mode: u16 } - -#[derive(Debug)] -pub struct DirBuilder { mode: u16 } - -impl FileAttr { - pub fn size(&self) -> u64 { self.stat.st_size as u64 } - pub fn perm(&self) -> FilePermissions { - FilePermissions { mode: (self.stat.st_mode as u16) & 0o777 } - } - - pub fn file_type(&self) -> FileType { - FileType { mode: self.stat.st_mode as u16 } - } -} - -impl FileAttr { - pub fn modified(&self) -> io::Result { - Ok(SystemTime::from(syscall::TimeSpec { - tv_sec: self.stat.st_mtime as i64, - tv_nsec: self.stat.st_mtime_nsec as i32, - })) - } - - pub fn accessed(&self) -> io::Result { - Ok(SystemTime::from(syscall::TimeSpec { - tv_sec: self.stat.st_atime as i64, - tv_nsec: self.stat.st_atime_nsec as i32, - })) - } - - pub fn created(&self) -> io::Result { - Ok(SystemTime::from(syscall::TimeSpec { - tv_sec: self.stat.st_ctime as i64, - tv_nsec: self.stat.st_ctime_nsec as i32, - })) - } -} - -impl AsInner for FileAttr { - fn as_inner(&self) -> &syscall::Stat { &self.stat } -} - -impl FilePermissions { - pub fn readonly(&self) -> bool { self.mode & 0o222 == 0 } - pub fn set_readonly(&mut self, readonly: bool) { - if readonly { - self.mode &= !0o222; - } else { - self.mode |= 0o222; - } - } - pub fn mode(&self) -> u32 { self.mode as u32 } -} - -impl FileType { - pub fn is_dir(&self) -> bool { self.is(syscall::MODE_DIR) } - pub fn is_file(&self) -> bool { self.is(syscall::MODE_FILE) } - pub fn is_symlink(&self) -> bool { self.is(syscall::MODE_SYMLINK) } - - pub fn is(&self, mode: u16) -> bool { - self.mode & syscall::MODE_TYPE == mode - } -} - -impl FromInner for FilePermissions { - fn from_inner(mode: u32) -> FilePermissions { - FilePermissions { mode: mode as u16 } - } -} - -impl fmt::Debug for ReadDir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame. - // Thus the result will be e g 'ReadDir("/home")' - fmt::Debug::fmt(&*self.root, f) - } -} - -impl Iterator for ReadDir { - type Item = io::Result; - - fn next(&mut self) -> Option> { - loop { - let start = self.i; - let mut i = self.i; - while i < self.data.len() { - self.i += 1; - if self.data[i] == b'\n' { - break; - } - i += 1; - } - if start < self.i { - let ret = DirEntry { - name: self.data[start .. i].to_owned().into_boxed_slice(), - root: self.root.clone() - }; - if ret.name_bytes() != b"." && ret.name_bytes() != b".." { - return Some(Ok(ret)) - } - } else { - return None; - } - } - } -} - -impl DirEntry { - pub fn path(&self) -> PathBuf { - self.root.join(OsStr::from_bytes(self.name_bytes())) - } - - pub fn file_name(&self) -> OsString { - OsStr::from_bytes(self.name_bytes()).to_os_string() - } - - pub fn metadata(&self) -> io::Result { - lstat(&self.path()) - } - - pub fn file_type(&self) -> io::Result { - lstat(&self.path()).map(|m| m.file_type()) - } - - fn name_bytes(&self) -> &[u8] { - &*self.name - } -} - -impl OpenOptions { - pub fn new() -> OpenOptions { - OpenOptions { - // generic - read: false, - write: false, - append: false, - truncate: false, - create: false, - create_new: false, - // system-specific - custom_flags: 0, - mode: 0o666, - } - } - - pub fn read(&mut self, read: bool) { self.read = read; } - pub fn write(&mut self, write: bool) { self.write = write; } - pub fn append(&mut self, append: bool) { self.append = append; } - pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; } - pub fn create(&mut self, create: bool) { self.create = create; } - pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; } - - pub fn custom_flags(&mut self, flags: i32) { self.custom_flags = flags; } - pub fn mode(&mut self, mode: u32) { self.mode = mode as u16; } - - fn get_access_mode(&self) -> io::Result { - match (self.read, self.write, self.append) { - (true, false, false) => Ok(syscall::O_RDONLY), - (false, true, false) => Ok(syscall::O_WRONLY), - (true, true, false) => Ok(syscall::O_RDWR), - (false, _, true) => Ok(syscall::O_WRONLY | syscall::O_APPEND), - (true, _, true) => Ok(syscall::O_RDWR | syscall::O_APPEND), - (false, false, false) => Err(Error::from_raw_os_error(syscall::EINVAL)), - } - } - - fn get_creation_mode(&self) -> io::Result { - match (self.write, self.append) { - (true, false) => {} - (false, false) => - if self.truncate || self.create || self.create_new { - return Err(Error::from_raw_os_error(syscall::EINVAL)); - }, - (_, true) => - if self.truncate && !self.create_new { - return Err(Error::from_raw_os_error(syscall::EINVAL)); - }, - } - - Ok(match (self.create, self.truncate, self.create_new) { - (false, false, false) => 0, - (true, false, false) => syscall::O_CREAT, - (false, true, false) => syscall::O_TRUNC, - (true, true, false) => syscall::O_CREAT | syscall::O_TRUNC, - (_, _, true) => syscall::O_CREAT | syscall::O_EXCL, - }) - } -} - -impl File { - pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { - let flags = syscall::O_CLOEXEC | - opts.get_access_mode()? as usize | - opts.get_creation_mode()? as usize | - (opts.custom_flags as usize & !syscall::O_ACCMODE); - let fd = cvt(syscall::open(path.to_str().unwrap(), flags | opts.mode as usize))?; - Ok(File(FileDesc::new(fd))) - } - - pub fn file_attr(&self) -> io::Result { - let mut stat = syscall::Stat::default(); - cvt(syscall::fstat(self.0.raw(), &mut stat))?; - Ok(FileAttr { stat }) - } - - pub fn fsync(&self) -> io::Result<()> { - cvt(syscall::fsync(self.0.raw()))?; - Ok(()) - } - - pub fn datasync(&self) -> io::Result<()> { - self.fsync() - } - - pub fn truncate(&self, size: u64) -> io::Result<()> { - cvt(syscall::ftruncate(self.0.raw(), size as usize))?; - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - crate::io::default_read_vectored(|buf| self.read(buf), bufs) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - crate::io::default_write_vectored(|buf| self.write(buf), bufs) - } - - pub fn flush(&self) -> io::Result<()> { Ok(()) } - - pub fn seek(&self, pos: SeekFrom) -> io::Result { - let (whence, pos) = match pos { - // Casting to `i64` is fine, too large values will end up as - // negative which will cause an error in `lseek64`. - SeekFrom::Start(off) => (syscall::SEEK_SET, off as i64), - SeekFrom::End(off) => (syscall::SEEK_END, off), - SeekFrom::Current(off) => (syscall::SEEK_CUR, off), - }; - let n = cvt(syscall::lseek(self.0.raw(), pos as isize, whence))?; - Ok(n as u64) - } - - pub fn duplicate(&self) -> io::Result { - self.0.duplicate().map(File) - } - - pub fn dup(&self, buf: &[u8]) -> io::Result { - let fd = cvt(syscall::dup(*self.fd().as_inner() as usize, buf))?; - Ok(File(FileDesc::new(fd))) - } - - pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { - set_perm(&self.path()?, perm) - } - - pub fn path(&self) -> io::Result { - let mut buf: [u8; 4096] = [0; 4096]; - let count = cvt(syscall::fpath(*self.fd().as_inner() as usize, &mut buf))?; - Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) })) - } - - pub fn fd(&self) -> &FileDesc { &self.0 } - - pub fn into_fd(self) -> FileDesc { self.0 } -} - -impl DirBuilder { - pub fn new() -> DirBuilder { - DirBuilder { mode: 0o777 } - } - - pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let flags = syscall::O_CREAT | syscall::O_CLOEXEC | syscall::O_DIRECTORY | syscall::O_EXCL; - let fd = cvt(syscall::open(p.to_str().unwrap(), flags | (self.mode as usize & 0o777)))?; - let _ = syscall::close(fd); - Ok(()) - } - - pub fn set_mode(&mut self, mode: u32) { - self.mode = mode as u16; - } -} - -impl FromInner for File { - fn from_inner(fd: usize) -> File { - File(FileDesc::new(fd)) - } -} - -impl fmt::Debug for File { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut b = f.debug_struct("File"); - b.field("fd", &self.0.raw()); - if let Ok(path) = self.path() { - b.field("path", &path); - } - /* - if let Some((read, write)) = get_mode(fd) { - b.field("read", &read).field("write", &write); - } - */ - b.finish() - } -} - -pub fn readdir(p: &Path) -> io::Result { - let root = Arc::new(p.to_path_buf()); - - let flags = syscall::O_CLOEXEC | syscall::O_RDONLY | syscall::O_DIRECTORY; - let fd = cvt(syscall::open(p.to_str().unwrap(), flags))?; - let file = FileDesc::new(fd); - let mut data = Vec::new(); - file.read_to_end(&mut data)?; - - Ok(ReadDir { data: data, i: 0, root: root }) -} - -pub fn unlink(p: &Path) -> io::Result<()> { - cvt(syscall::unlink(p.to_str().unwrap()))?; - Ok(()) -} - -pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let fd = cvt(syscall::open(old.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?; - let res = cvt(syscall::frename(fd, new.to_str().unwrap())); - cvt(syscall::close(fd))?; - res?; - Ok(()) -} - -pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { - cvt(syscall::chmod(p.to_str().unwrap(), perm.mode as usize))?; - Ok(()) -} - -pub fn rmdir(p: &Path) -> io::Result<()> { - cvt(syscall::rmdir(p.to_str().unwrap()))?; - Ok(()) -} - -pub fn readlink(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_SYMLINK | syscall::O_RDONLY))?; - let mut buf: [u8; 4096] = [0; 4096]; - let res = cvt(syscall::read(fd, &mut buf)); - cvt(syscall::close(fd))?; - let count = res?; - Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) })) -} - -pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let fd = cvt(syscall::open(dst.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_SYMLINK | - syscall::O_CREAT | syscall::O_WRONLY | 0o777))?; - let res = cvt(syscall::write(fd, src.to_str().unwrap().as_bytes())); - cvt(syscall::close(fd))?; - res?; - Ok(()) -} - -pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { - Err(Error::from_raw_os_error(syscall::ENOSYS)) -} - -pub fn stat(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_CLOEXEC | syscall::O_STAT))?; - let file = File(FileDesc::new(fd)); - file.file_attr() -} - -pub fn lstat(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?; - let file = File(FileDesc::new(fd)); - file.file_attr() -} - -pub fn canonicalize(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_CLOEXEC | syscall::O_STAT))?; - let file = File(FileDesc::new(fd)); - file.path() -} diff --git a/src/libstd/sys/redox/io.rs b/src/libstd/sys/redox/io.rs deleted file mode 100644 index 4b423a5cbc..0000000000 --- a/src/libstd/sys/redox/io.rs +++ /dev/null @@ -1,32 +0,0 @@ -pub struct IoSlice<'a>(&'a [u8]); - -impl<'a> IoSlice<'a> { - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - IoSlice(buf) - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - self.0 - } -} - -pub struct IoSliceMut<'a>(&'a mut [u8]); - -impl<'a> IoSliceMut<'a> { - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - IoSliceMut(buf) - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - self.0 - } - - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - self.0 - } -} diff --git a/src/libstd/sys/redox/memchr.rs b/src/libstd/sys/redox/memchr.rs deleted file mode 100644 index d2bfcce86f..0000000000 --- a/src/libstd/sys/redox/memchr.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Original implementation taken from rust-memchr. -// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch - -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/src/libstd/sys/redox/mod.rs b/src/libstd/sys/redox/mod.rs deleted file mode 100644 index 354184f8af..0000000000 --- a/src/libstd/sys/redox/mod.rs +++ /dev/null @@ -1,96 +0,0 @@ -#![allow(dead_code, missing_docs, nonstandard_style)] - -use crate::io::ErrorKind; - -pub use libc::strlen; -pub use self::rand::hashmap_random_keys; - -#[path = "../unix/alloc.rs"] -pub mod alloc; -pub mod args; -pub mod cmath; -pub mod condvar; -pub mod env; -pub mod ext; -pub mod fast_thread_local; -pub mod fd; -pub mod fs; -pub mod io; -pub mod memchr; -pub mod mutex; -pub mod net; -pub mod os; -pub mod path; -pub mod pipe; -pub mod process; -pub mod rand; -pub mod rwlock; -pub mod stack_overflow; -pub mod stdio; -pub mod syscall; -pub mod thread; -pub mod thread_local; -pub mod time; - -pub use crate::sys_common::os_str_bytes as os_str; - -#[cfg(not(test))] -pub fn init() {} - -pub fn decode_error_kind(errno: i32) -> ErrorKind { - match errno { - syscall::ECONNREFUSED => ErrorKind::ConnectionRefused, - syscall::ECONNRESET => ErrorKind::ConnectionReset, - syscall::EPERM | syscall::EACCES => ErrorKind::PermissionDenied, - syscall::EPIPE => ErrorKind::BrokenPipe, - syscall::ENOTCONN => ErrorKind::NotConnected, - syscall::ECONNABORTED => ErrorKind::ConnectionAborted, - syscall::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, - syscall::EADDRINUSE => ErrorKind::AddrInUse, - syscall::ENOENT => ErrorKind::NotFound, - syscall::EINTR => ErrorKind::Interrupted, - syscall::EINVAL => ErrorKind::InvalidInput, - syscall::ETIMEDOUT => ErrorKind::TimedOut, - syscall::EEXIST => ErrorKind::AlreadyExists, - - // These two constants can have the same value on some systems, - // but different values on others, so we can't use a match - // clause - x if x == syscall::EAGAIN || x == syscall::EWOULDBLOCK => - ErrorKind::WouldBlock, - - _ => ErrorKind::Other, - } -} - -pub fn cvt(result: Result) -> crate::io::Result { - result.map_err(|err| crate::io::Error::from_raw_os_error(err.errno)) -} - -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -pub fn cvt_libc(t: T) -> crate::io::Result { - if t.is_minus_one() { - Err(crate::io::Error::last_os_error()) - } else { - Ok(t) - } -} - -/// On Redox, use an illegal instruction to abort -pub unsafe fn abort_internal() -> ! { - core::intrinsics::abort(); -} diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs deleted file mode 100644 index 59399df029..0000000000 --- a/src/libstd/sys/redox/mutex.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::intrinsics::{atomic_cxchg, atomic_xchg}; -use crate::ptr; - -use crate::sys::syscall::{futex, getpid, FUTEX_WAIT, FUTEX_WAKE}; - -pub unsafe fn mutex_try_lock(m: *mut i32) -> bool { - atomic_cxchg(m, 0, 1).0 == 0 -} - -pub unsafe fn mutex_lock(m: *mut i32) { - let mut c = 0; - //Set to larger value for longer spin test - for _i in 0..100 { - c = atomic_cxchg(m, 0, 1).0; - if c == 0 { - break; - } - //cpu_relax() - } - if c == 1 { - c = atomic_xchg(m, 2); - } - while c != 0 { - let _ = futex(m, FUTEX_WAIT, 2, 0, ptr::null_mut()); - c = atomic_xchg(m, 2); - } -} - -pub unsafe fn mutex_unlock(m: *mut i32) { - if *m == 2 { - *m = 0; - } else if atomic_xchg(m, 0) == 1 { - return; - } - //Set to larger value for longer spin test - for _i in 0..100 { - if *m != 0 { - if atomic_cxchg(m, 1, 2).0 != 0 { - return; - } - } - //cpu_relax() - } - let _ = futex(m, FUTEX_WAKE, 1, 0, ptr::null_mut()); -} - -pub struct Mutex { - pub lock: UnsafeCell, -} - -impl Mutex { - /// Creates a new mutex. - pub const fn new() -> Self { - Mutex { - lock: UnsafeCell::new(0), - } - } - - #[inline] - pub unsafe fn init(&self) { - *self.lock.get() = 0; - } - - /// Try to lock the mutex - #[inline] - pub unsafe fn try_lock(&self) -> bool { - mutex_try_lock(self.lock.get()) - } - - /// Lock the mutex - #[inline] - pub unsafe fn lock(&self) { - mutex_lock(self.lock.get()); - } - - /// Unlock the mutex - #[inline] - pub unsafe fn unlock(&self) { - mutex_unlock(self.lock.get()); - } - - #[inline] - pub unsafe fn destroy(&self) { - *self.lock.get() = 0; - } -} - -unsafe impl Send for Mutex {} - -unsafe impl Sync for Mutex {} - -pub struct ReentrantMutex { - pub lock: UnsafeCell, - pub owner: UnsafeCell, - pub own_count: UnsafeCell, -} - -impl ReentrantMutex { - pub const fn uninitialized() -> Self { - ReentrantMutex { - lock: UnsafeCell::new(0), - owner: UnsafeCell::new(0), - own_count: UnsafeCell::new(0), - } - } - - #[inline] - pub unsafe fn init(&mut self) { - *self.lock.get() = 0; - *self.owner.get() = 0; - *self.own_count.get() = 0; - } - - /// Try to lock the mutex - #[inline] - pub unsafe fn try_lock(&self) -> bool { - let pid = getpid().unwrap(); - if *self.own_count.get() > 0 && *self.owner.get() == pid { - *self.own_count.get() += 1; - true - } else { - if mutex_try_lock(self.lock.get()) { - *self.owner.get() = pid; - *self.own_count.get() = 1; - true - } else { - false - } - } - } - - /// Lock the mutex - #[inline] - pub unsafe fn lock(&self) { - let pid = getpid().unwrap(); - if *self.own_count.get() > 0 && *self.owner.get() == pid { - *self.own_count.get() += 1; - } else { - mutex_lock(self.lock.get()); - *self.owner.get() = pid; - *self.own_count.get() = 1; - } - } - - /// Unlock the mutex - #[inline] - pub unsafe fn unlock(&self) { - let pid = getpid().unwrap(); - if *self.own_count.get() > 0 && *self.owner.get() == pid { - *self.own_count.get() -= 1; - if *self.own_count.get() == 0 { - *self.owner.get() = 0; - mutex_unlock(self.lock.get()); - } - } - } - - #[inline] - pub unsafe fn destroy(&self) { - *self.lock.get() = 0; - *self.owner.get() = 0; - *self.own_count.get() = 0; - } -} - -unsafe impl Send for ReentrantMutex {} - -unsafe impl Sync for ReentrantMutex {} diff --git a/src/libstd/sys/redox/net/dns/answer.rs b/src/libstd/sys/redox/net/dns/answer.rs deleted file mode 100644 index e9b406bc68..0000000000 --- a/src/libstd/sys/redox/net/dns/answer.rs +++ /dev/null @@ -1,12 +0,0 @@ -use crate::string::String; -use crate::vec::Vec; - -#[derive(Clone, Debug)] -pub struct DnsAnswer { - pub name: String, - pub a_type: u16, - pub a_class: u16, - pub ttl_a: u16, - pub ttl_b: u16, - pub data: Vec -} diff --git a/src/libstd/sys/redox/net/dns/mod.rs b/src/libstd/sys/redox/net/dns/mod.rs deleted file mode 100644 index 6533e0d5ef..0000000000 --- a/src/libstd/sys/redox/net/dns/mod.rs +++ /dev/null @@ -1,205 +0,0 @@ -pub use self::answer::DnsAnswer; -pub use self::query::DnsQuery; - -use crate::slice; -use crate::u16; -use crate::string::String; -use crate::vec::Vec; - -mod answer; -mod query; - -#[unstable(feature = "n16", issue="0")] -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, Default)] -#[repr(packed)] -pub struct n16 { - inner: u16 -} - -impl n16 { - #[unstable(feature = "n16", issue="0")] - pub fn as_bytes(&self) -> &[u8] { - unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) } - } - - #[unstable(feature = "n16", issue="0")] - pub fn from_bytes(bytes: &[u8]) -> Self { - n16 { - inner: unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len()/2)[0] } - } - } -} - -#[unstable(feature = "n16", issue="0")] -impl From for n16 { - fn from(value: u16) -> Self { - n16 { - inner: value.to_be() - } - } -} - -#[unstable(feature = "n16", issue="0")] -impl From for u16 { - fn from(value: n16) -> Self { - u16::from_be(value.inner) - } -} - -#[derive(Clone, Debug)] -pub struct Dns { - pub transaction_id: u16, - pub flags: u16, - pub queries: Vec, - pub answers: Vec -} - -impl Dns { - pub fn compile(&self) -> Vec { - let mut data = Vec::new(); - - macro_rules! push_u8 { - ($value:expr) => { - data.push($value); - }; - }; - - macro_rules! push_n16 { - ($value:expr) => { - data.extend_from_slice(n16::from($value).as_bytes()); - }; - }; - - push_n16!(self.transaction_id); - push_n16!(self.flags); - push_n16!(self.queries.len() as u16); - push_n16!(self.answers.len() as u16); - push_n16!(0); - push_n16!(0); - - for query in self.queries.iter() { - for part in query.name.split('.') { - push_u8!(part.len() as u8); - data.extend_from_slice(part.as_bytes()); - } - push_u8!(0); - push_n16!(query.q_type); - push_n16!(query.q_class); - } - - data - } - - pub fn parse(data: &[u8]) -> Result { - let name_ind = 0b11000000; - let mut i = 0; - - macro_rules! pop_u8 { - () => { - { - i += 1; - if i > data.len() { - return Err(format!("{}: {}: pop_u8", file!(), line!())); - } - data[i - 1] - } - }; - }; - - macro_rules! pop_n16 { - () => { - { - i += 2; - if i > data.len() { - return Err(format!("{}: {}: pop_n16", file!(), line!())); - } - u16::from(n16::from_bytes(&data[i - 2 .. i])) - } - }; - }; - - macro_rules! pop_data { - () => { - { - let mut data = Vec::new(); - - let data_len = pop_n16!(); - for _data_i in 0..data_len { - data.push(pop_u8!()); - } - - data - } - }; - }; - - macro_rules! pop_name { - () => { - { - let mut name = String::new(); - let old_i = i; - - loop { - let name_len = pop_u8!(); - if name_len & name_ind == name_ind { - i -= 1; - i = (pop_n16!() - ((name_ind as u16) << 8)) as usize; - continue; - } - if name_len == 0 { - break; - } - if ! name.is_empty() { - name.push('.'); - } - for _name_i in 0..name_len { - name.push(pop_u8!() as char); - } - } - - if i <= old_i { - i = old_i + 2; - } - - name - } - }; - }; - - let transaction_id = pop_n16!(); - let flags = pop_n16!(); - let queries_len = pop_n16!(); - let answers_len = pop_n16!(); - pop_n16!(); - pop_n16!(); - - let mut queries = Vec::new(); - for _query_i in 0..queries_len { - queries.push(DnsQuery { - name: pop_name!(), - q_type: pop_n16!(), - q_class: pop_n16!() - }); - } - - let mut answers = Vec::new(); - for _answer_i in 0..answers_len { - answers.push(DnsAnswer { - name: pop_name!(), - a_type: pop_n16!(), - a_class: pop_n16!(), - ttl_a: pop_n16!(), - ttl_b: pop_n16!(), - data: pop_data!() - }); - } - - Ok(Dns { - transaction_id, - flags, - queries, - answers, - }) - } -} diff --git a/src/libstd/sys/redox/net/dns/query.rs b/src/libstd/sys/redox/net/dns/query.rs deleted file mode 100644 index 65fb241b03..0000000000 --- a/src/libstd/sys/redox/net/dns/query.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::string::String; - -#[derive(Clone, Debug)] -pub struct DnsQuery { - pub name: String, - pub q_type: u16, - pub q_class: u16 -} diff --git a/src/libstd/sys/redox/net/mod.rs b/src/libstd/sys/redox/net/mod.rs deleted file mode 100644 index dbaa140ed8..0000000000 --- a/src/libstd/sys/redox/net/mod.rs +++ /dev/null @@ -1,140 +0,0 @@ -use crate::fs::File; -use crate::io::{Error, Read, self}; -use crate::iter::Iterator; -use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; -use crate::str::FromStr; -use crate::string::{String, ToString}; -use crate::sys::syscall::EINVAL; -use crate::time::{self, Duration}; -use crate::vec::{IntoIter, Vec}; -use crate::convert::{TryFrom, TryInto}; - -use self::dns::{Dns, DnsQuery}; - -pub use self::tcp::{TcpStream, TcpListener}; -pub use self::udp::UdpSocket; - -pub mod netc; - -mod dns; -mod tcp; -mod udp; - -pub struct LookupHost(IntoIter, u16); - -impl LookupHost { - pub fn port(&self) -> u16 { - self.1 - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option { - self.0.next() - } -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(s: &str) -> io::Result { - macro_rules! try_opt { - ($e:expr, $msg:expr) => ( - match $e { - Some(r) => r, - None => return Err(io::Error::new(io::ErrorKind::InvalidInput, - $msg)), - } - ) - } - - // split the string by ':' and convert the second part to u16 - let mut parts_iter = s.rsplitn(2, ':'); - let port_str = try_opt!(parts_iter.next(), "invalid socket address"); - let host = try_opt!(parts_iter.next(), "invalid socket address"); - let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); - - (host, port).try_into() - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from((host, port): (&'a str, u16)) -> io::Result { - let mut ip_string = String::new(); - File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?; - let ip: Vec = ip_string.trim().split('.').map(|part| part.parse::() - .unwrap_or(0)).collect(); - - let mut dns_string = String::new(); - File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?; - let dns: Vec = dns_string.trim().split('.').map(|part| part.parse::() - .unwrap_or(0)).collect(); - - if ip.len() == 4 && dns.len() == 4 { - let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); - let tid = (time.subsec_nanos() >> 16) as u16; - - let packet = Dns { - transaction_id: tid, - flags: 0x0100, - queries: vec![DnsQuery { - name: host.to_string(), - q_type: 0x0001, - q_class: 0x0001, - }], - answers: vec![] - }; - - let packet_data = packet.compile(); - - let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]); - let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]); - let socket = UdpSocket::bind(Ok(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0))))?; - socket.set_read_timeout(Some(Duration::new(5, 0)))?; - socket.set_write_timeout(Some(Duration::new(5, 0)))?; - socket.connect(Ok(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53))))?; - socket.send(&packet_data)?; - - let mut buf = [0; 65536]; - let count = socket.recv(&mut buf)?; - - match Dns::parse(&buf[.. count]) { - Ok(response) => { - let mut addrs = vec![]; - for answer in response.answers.iter() { - if answer.a_type == 0x0001 && answer.a_class == 0x0001 - && answer.data.len() == 4 - { - let answer_ip = Ipv4Addr::new(answer.data[0], - answer.data[1], - answer.data[2], - answer.data[3]); - addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0))); - } - } - Ok(LookupHost(addrs.into_iter(), port)) - }, - Err(_err) => Err(Error::from_raw_os_error(EINVAL)) - } - } else { - Err(Error::from_raw_os_error(EINVAL)) - } - } -} - -fn path_to_peer_addr(path_str: &str) -> SocketAddr { - let mut parts = path_str.split('/').next().unwrap_or("").split(':').skip(1); - let host = Ipv4Addr::from_str(parts.next().unwrap_or("")).unwrap_or(Ipv4Addr::new(0, 0, 0, 0)); - let port = parts.next().unwrap_or("").parse::().unwrap_or(0); - SocketAddr::V4(SocketAddrV4::new(host, port)) -} - -fn path_to_local_addr(path_str: &str) -> SocketAddr { - let mut parts = path_str.split('/').nth(1).unwrap_or("").split(':'); - let host = Ipv4Addr::from_str(parts.next().unwrap_or("")).unwrap_or(Ipv4Addr::new(0, 0, 0, 0)); - let port = parts.next().unwrap_or("").parse::().unwrap_or(0); - SocketAddr::V4(SocketAddrV4::new(host, port)) -} diff --git a/src/libstd/sys/redox/net/netc.rs b/src/libstd/sys/redox/net/netc.rs deleted file mode 100644 index 420a15a406..0000000000 --- a/src/libstd/sys/redox/net/netc.rs +++ /dev/null @@ -1,47 +0,0 @@ -pub type in_addr_t = u32; -pub type in_port_t = u16; - -pub type socklen_t = u32; -pub type sa_family_t = u16; - -pub const AF_INET: sa_family_t = 2; -pub const AF_INET6: sa_family_t = 23; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct in_addr { - pub s_addr: in_addr_t, -} - -#[derive(Copy, Clone)] -#[repr(align(4))] -#[repr(C)] -pub struct in6_addr { - pub s6_addr: [u8; 16], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct sockaddr { - pub sa_family: sa_family_t, - pub sa_data: [u8; 14], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct sockaddr_in { - pub sin_family: sa_family_t, - pub sin_port: in_port_t, - pub sin_addr: in_addr, - pub sin_zero: [u8; 8], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct sockaddr_in6 { - pub sin6_family: sa_family_t, - pub sin6_port: in_port_t, - pub sin6_flowinfo: u32, - pub sin6_addr: in6_addr, - pub sin6_scope_id: u32, -} diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs deleted file mode 100644 index 494f943c96..0000000000 --- a/src/libstd/sys/redox/net/tcp.rs +++ /dev/null @@ -1,251 +0,0 @@ -use crate::cmp; -use crate::io::{self, Error, ErrorKind, Result, IoSlice, IoSliceMut}; -use crate::mem; -use crate::net::{SocketAddr, Shutdown}; -use crate::path::Path; -use crate::sys::fs::{File, OpenOptions}; -use crate::sys::syscall::TimeSpec; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::Duration; - -use super::{path_to_peer_addr, path_to_local_addr}; - -#[derive(Debug)] -pub struct TcpStream(File); - -impl TcpStream { - pub fn connect(addr: Result<&SocketAddr>) -> Result { - let path = format!("tcp:{}", addr?); - let mut options = OpenOptions::new(); - options.read(true); - options.write(true); - Ok(TcpStream(File::open(Path::new(path.as_str()), &options)?)) - } - - pub fn connect_timeout(_addr: &SocketAddr, _timeout: Duration) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::connect_timeout not implemented")) - } - - pub fn duplicate(&self) -> Result { - Ok(TcpStream(self.0.dup(&[])?)) - } - - pub fn read(&self, buf: &mut [u8]) -> Result { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - io::default_read_vectored(|b| self.read(b), bufs) - } - - pub fn write(&self, buf: &[u8]) -> Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - io::default_write_vectored(|b| self.write(b), bufs) - } - - pub fn take_error(&self) -> Result> { - Ok(None) - } - - pub fn peer_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_peer_addr(path.to_str().unwrap_or(""))) - } - - pub fn socket_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_local_addr(path.to_str().unwrap_or(""))) - } - - pub fn peek(&self, _buf: &mut [u8]) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::peek not implemented")) - } - - pub fn shutdown(&self, _how: Shutdown) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::shutdown not implemented")) - } - - pub fn nodelay(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::nodelay not implemented")) - } - - pub fn nonblocking(&self) -> Result { - self.0.fd().nonblocking() - } - - pub fn only_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::only_v6 not implemented")) - } - - pub fn ttl(&self) -> Result { - let mut ttl = [0]; - let file = self.0.dup(b"ttl")?; - file.read(&mut ttl)?; - Ok(ttl[0] as u32) - } - - pub fn read_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"read_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn write_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"write_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_nodelay not implemented")) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> { - self.0.fd().set_nonblocking(nonblocking) - } - - pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented")) - } - - pub fn set_ttl(&self, ttl: u32) -> Result<()> { - let file = self.0.dup(b"ttl")?; - file.write(&[cmp::min(ttl, 255) as u8])?; - Ok(()) - } - - pub fn set_read_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"read_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } - - pub fn set_write_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"write_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } -} - -impl AsInner for TcpStream { - fn as_inner(&self) -> &File { &self.0 } -} - -impl FromInner for TcpStream { - fn from_inner(file: File) -> TcpStream { - TcpStream(file) - } -} - -impl IntoInner for TcpStream { - fn into_inner(self) -> File { self.0 } -} - -#[derive(Debug)] -pub struct TcpListener(File); - -impl TcpListener { - pub fn bind(addr: Result<&SocketAddr>) -> Result { - let path = format!("tcp:/{}", addr?); - let mut options = OpenOptions::new(); - options.read(true); - options.write(true); - Ok(TcpListener(File::open(Path::new(path.as_str()), &options)?)) - } - - pub fn accept(&self) -> Result<(TcpStream, SocketAddr)> { - let file = self.0.dup(b"listen")?; - let path = file.path()?; - let peer_addr = path_to_peer_addr(path.to_str().unwrap_or("")); - Ok((TcpStream(file), peer_addr)) - } - - pub fn duplicate(&self) -> Result { - Ok(TcpListener(self.0.dup(&[])?)) - } - - pub fn take_error(&self) -> Result> { - Ok(None) - } - - pub fn socket_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_local_addr(path.to_str().unwrap_or(""))) - } - - pub fn nonblocking(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpListener::nonblocking not implemented")) - } - - pub fn only_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpListener::only_v6 not implemented")) - } - - pub fn ttl(&self) -> Result { - let mut ttl = [0]; - let file = self.0.dup(b"ttl")?; - file.read(&mut ttl)?; - Ok(ttl[0] as u32) - } - - pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpListener::set_nonblocking not implemented")) - } - - pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented")) - } - - pub fn set_ttl(&self, ttl: u32) -> Result<()> { - let file = self.0.dup(b"ttl")?; - file.write(&[cmp::min(ttl, 255) as u8])?; - Ok(()) - } -} - -impl AsInner for TcpListener { - fn as_inner(&self) -> &File { &self.0 } -} - -impl FromInner for TcpListener { - fn from_inner(file: File) -> TcpListener { - TcpListener(file) - } -} - -impl IntoInner for TcpListener { - fn into_inner(self) -> File { self.0 } -} diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs deleted file mode 100644 index 274123dce4..0000000000 --- a/src/libstd/sys/redox/net/udp.rs +++ /dev/null @@ -1,237 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::cmp; -use crate::io::{self, Error, ErrorKind, Result}; -use crate::mem; -use crate::net::{SocketAddr, Ipv4Addr, Ipv6Addr}; -use crate::path::Path; -use crate::sys::fs::{File, OpenOptions}; -use crate::sys::syscall::TimeSpec; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::Duration; - -use super::{path_to_peer_addr, path_to_local_addr}; - -#[derive(Debug)] -pub struct UdpSocket(File, UnsafeCell>); - -impl UdpSocket { - pub fn bind(addr: Result<&SocketAddr>) -> Result { - let path = format!("udp:/{}", addr?); - let mut options = OpenOptions::new(); - options.read(true); - options.write(true); - Ok(UdpSocket(File::open(Path::new(path.as_str()), &options)?, UnsafeCell::new(None))) - } - - fn get_conn(&self) -> &mut Option { - unsafe { &mut *(self.1.get()) } - } - - pub fn connect(&self, addr: Result<&SocketAddr>) -> Result<()> { - unsafe { *self.1.get() = Some(*addr?) }; - Ok(()) - } - - pub fn duplicate(&self) -> Result { - let new_bind = self.0.dup(&[])?; - let new_conn = *self.get_conn(); - Ok(UdpSocket(new_bind, UnsafeCell::new(new_conn))) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> { - let from = self.0.dup(b"listen")?; - let path = from.path()?; - let peer_addr = path_to_peer_addr(path.to_str().unwrap_or("")); - let count = from.read(buf)?; - Ok((count, peer_addr)) - } - - pub fn recv(&self, buf: &mut [u8]) -> Result { - if let Some(addr) = *self.get_conn() { - let from = self.0.dup(addr.to_string().as_bytes())?; - from.read(buf) - } else { - Err(Error::new(ErrorKind::Other, "UdpSocket::recv not connected")) - } - } - - pub fn send_to(&self, buf: &[u8], addr: &SocketAddr) -> Result { - let to = self.0.dup(format!("{}", addr).as_bytes())?; - to.write(buf) - } - - pub fn send(&self, buf: &[u8]) -> Result { - if let Some(addr) = *self.get_conn() { - self.send_to(buf, &addr) - } else { - Err(Error::new(ErrorKind::Other, "UdpSocket::send not connected")) - } - } - - pub fn take_error(&self) -> Result> { - Ok(None) - } - - pub fn peer_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_peer_addr(path.to_str().unwrap_or(""))) - } - - pub fn socket_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_local_addr(path.to_str().unwrap_or(""))) - } - - pub fn peek(&self, _buf: &mut [u8]) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::peek not implemented")) - } - - pub fn peek_from(&self, _buf: &mut [u8]) -> Result<(usize, SocketAddr)> { - Err(Error::new(ErrorKind::Other, "UdpSocket::peek_from not implemented")) - } - - pub fn broadcast(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::broadcast not implemented")) - } - - pub fn multicast_loop_v4(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_loop_v4 not implemented")) - } - - pub fn multicast_loop_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_loop_v6 not implemented")) - } - - pub fn multicast_ttl_v4(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_ttl_v4 not implemented")) - } - - pub fn nonblocking(&self) -> Result { - self.0.fd().nonblocking() - } - - pub fn only_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::only_v6 not implemented")) - } - - pub fn ttl(&self) -> Result { - let mut ttl = [0]; - let file = self.0.dup(b"ttl")?; - file.read(&mut ttl)?; - Ok(ttl[0] as u32) - } - - pub fn read_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"read_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn write_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"write_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_broadcast not implemented")) - } - - pub fn set_multicast_loop_v4(&self, _multicast_loop_v4: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_loop_v4 not implemented")) - } - - pub fn set_multicast_loop_v6(&self, _multicast_loop_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_loop_v6 not implemented")) - } - - pub fn set_multicast_ttl_v4(&self, _multicast_ttl_v4: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_ttl_v4 not implemented")) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> { - self.0.fd().set_nonblocking(nonblocking) - } - - pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented")) - } - - pub fn set_ttl(&self, ttl: u32) -> Result<()> { - let file = self.0.dup(b"ttl")?; - file.write(&[cmp::min(ttl, 255) as u8])?; - Ok(()) - } - - pub fn set_read_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"read_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } - - pub fn set_write_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"write_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } - - pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::join_multicast_v4 not implemented")) - } - - pub fn join_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::join_multicast_v6 not implemented")) - } - - pub fn leave_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::leave_multicast_v4 not implemented")) - } - - pub fn leave_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::leave_multicast_v6 not implemented")) - } -} - -impl AsInner for UdpSocket { - fn as_inner(&self) -> &File { &self.0 } -} - -impl FromInner for UdpSocket { - fn from_inner(file: File) -> UdpSocket { - UdpSocket(file, UnsafeCell::new(None)) - } -} - -impl IntoInner for UdpSocket { - fn into_inner(self) -> File { self.0 } -} diff --git a/src/libstd/sys/redox/path.rs b/src/libstd/sys/redox/path.rs deleted file mode 100644 index b62d6c9878..0000000000 --- a/src/libstd/sys/redox/path.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::ffi::OsStr; -use crate::path::Prefix; - -#[inline] -pub fn is_sep_byte(b: u8) -> bool { - b == b'/' -} - -#[inline] -pub fn is_verbatim_sep(b: u8) -> bool { - b == b'/' -} - -pub fn parse_prefix(path: &OsStr) -> Option> { - if let Some(path_str) = path.to_str() { - if let Some(_i) = path_str.find(':') { - // FIXME: Redox specific prefix - // Some(Prefix::Verbatim(OsStr::new(&path_str[..i]))) - None - } else { - None - } - } else { - None - } -} - -pub const MAIN_SEP_STR: &str = "/"; -pub const MAIN_SEP: char = '/'; diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs deleted file mode 100644 index 29cacb6d56..0000000000 --- a/src/libstd/sys/redox/pipe.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::sys::{cvt, syscall}; -use crate::sys::fd::FileDesc; - -//////////////////////////////////////////////////////////////////////////////// -// Anonymous pipes -//////////////////////////////////////////////////////////////////////////////// - -pub struct AnonPipe(FileDesc); - -pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { - let mut fds = [0; 2]; - cvt(syscall::pipe2(&mut fds, syscall::O_CLOEXEC))?; - Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1])))) -} - -impl AnonPipe { - pub fn from_fd(fd: FileDesc) -> io::Result { - fd.set_cloexec()?; - Ok(AnonPipe(fd)) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - crate::io::default_read_vectored(|buf| self.read(buf), bufs) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - crate::io::default_write_vectored(|buf| self.write(buf), bufs) - } - - pub fn fd(&self) -> &FileDesc { &self.0 } - pub fn into_fd(self) -> FileDesc { self.0 } -} - -pub fn read2(p1: AnonPipe, - v1: &mut Vec, - p2: AnonPipe, - v2: &mut Vec) -> io::Result<()> { - //FIXME: Use event based I/O multiplexing - //unimplemented!() - - p1.0.read_to_end(v1)?; - p2.0.read_to_end(v2)?; - - Ok(()) - - /* - // Set both pipes into nonblocking mode as we're gonna be reading from both - // in the `select` loop below, and we wouldn't want one to block the other! - let p1 = p1.into_fd(); - let p2 = p2.into_fd(); - p1.set_nonblocking(true)?; - p2.set_nonblocking(true)?; - - loop { - // wait for either pipe to become readable using `select` - cvt_r(|| unsafe { - let mut read: libc::fd_set = mem::zeroed(); - libc::FD_SET(p1.raw(), &mut read); - libc::FD_SET(p2.raw(), &mut read); - libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(), - ptr::null_mut()) - })?; - - // Read as much as we can from each pipe, ignoring EWOULDBLOCK or - // EAGAIN. If we hit EOF, then this will happen because the underlying - // reader will return Ok(0), in which case we'll see `Ok` ourselves. In - // this case we flip the other fd back into blocking mode and read - // whatever's leftover on that file descriptor. - let read = |fd: &FileDesc, dst: &mut Vec| { - match fd.read_to_end(dst) { - Ok(_) => Ok(true), - Err(e) => { - if e.raw_os_error() == Some(libc::EWOULDBLOCK) || - e.raw_os_error() == Some(libc::EAGAIN) { - Ok(false) - } else { - Err(e) - } - } - } - }; - if read(&p1, v1)? { - p2.set_nonblocking(false)?; - return p2.read_to_end(v2).map(|_| ()); - } - if read(&p2, v2)? { - p1.set_nonblocking(false)?; - return p1.read_to_end(v1).map(|_| ()); - } - } - */ -} diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs deleted file mode 100644 index 2a553b2c93..0000000000 --- a/src/libstd/sys/redox/process.rs +++ /dev/null @@ -1,609 +0,0 @@ -use crate::env::{self, split_paths}; -use crate::ffi::{CStr, OsStr}; -use crate::fmt; -use crate::fs::File; -use crate::io::{self, prelude::*, BufReader, Error, ErrorKind, SeekFrom}; -use crate::os::unix::ffi::OsStrExt; -use crate::path::{Path, PathBuf}; -use crate::ptr; -use crate::sys::ext::fs::MetadataExt; -use crate::sys::ext::io::AsRawFd; -use crate::sys::fd::FileDesc; -use crate::sys::fs::{File as SysFile, OpenOptions}; -use crate::sys::os::{ENV_LOCK, environ}; -use crate::sys::pipe::{self, AnonPipe}; -use crate::sys::{cvt, syscall}; -use crate::sys_common::process::{CommandEnv, DefaultEnvKey}; - -use libc::{EXIT_SUCCESS, EXIT_FAILURE}; - -//////////////////////////////////////////////////////////////////////////////// -// Command -//////////////////////////////////////////////////////////////////////////////// - -pub struct Command { - // Currently we try hard to ensure that the call to `.exec()` doesn't - // actually allocate any memory. While many platforms try to ensure that - // memory allocation works after a fork in a multithreaded process, it's - // been observed to be buggy and somewhat unreliable, so we do our best to - // just not do it at all! - // - // Along those lines, the `argv` and `envp` raw pointers here are exactly - // what's gonna get passed to `execvp`. The `argv` array starts with the - // `program` and ends with a NULL, and the `envp` pointer, if present, is - // also null-terminated. - // - // Right now we don't support removing arguments, so there's no much fancy - // support there, but we support adding and removing environment variables, - // so a side table is used to track where in the `envp` array each key is - // located. Whenever we add a key we update it in place if it's already - // present, and whenever we remove a key we update the locations of all - // other keys. - program: String, - args: Vec, - env: CommandEnv, - - cwd: Option, - uid: Option, - gid: Option, - saw_nul: bool, - closures: Vec io::Result<()> + Send + Sync>>, - stdin: Option, - stdout: Option, - stderr: Option, -} - -// passed back to std::process with the pipes connected to the child, if any -// were requested -pub struct StdioPipes { - pub stdin: Option, - pub stdout: Option, - pub stderr: Option, -} - -// passed to do_exec() with configuration of what the child stdio should look -// like -struct ChildPipes { - stdin: ChildStdio, - stdout: ChildStdio, - stderr: ChildStdio, -} - -enum ChildStdio { - Inherit, - Explicit(usize), - Owned(FileDesc), -} - -pub enum Stdio { - Inherit, - Null, - MakePipe, - Fd(FileDesc), -} - -impl Command { - pub fn new(program: &OsStr) -> Command { - Command { - program: program.to_str().unwrap().to_owned(), - args: Vec::new(), - env: Default::default(), - cwd: None, - uid: None, - gid: None, - saw_nul: false, - closures: Vec::new(), - stdin: None, - stdout: None, - stderr: None, - } - } - - pub fn arg(&mut self, arg: &OsStr) { - self.args.push(arg.to_str().unwrap().to_owned()); - } - - pub fn env_mut(&mut self) -> &mut CommandEnv { - &mut self.env - } - - pub fn cwd(&mut self, dir: &OsStr) { - self.cwd = Some(dir.to_str().unwrap().to_owned()); - } - pub fn uid(&mut self, id: u32) { - self.uid = Some(id); - } - pub fn gid(&mut self, id: u32) { - self.gid = Some(id); - } - - pub unsafe fn pre_exec( - &mut self, - f: Box io::Result<()> + Send + Sync>, - ) { - self.closures.push(f); - } - - pub fn stdin(&mut self, stdin: Stdio) { - self.stdin = Some(stdin); - } - pub fn stdout(&mut self, stdout: Stdio) { - self.stdout = Some(stdout); - } - pub fn stderr(&mut self, stderr: Stdio) { - self.stderr = Some(stderr); - } - - pub fn spawn(&mut self, default: Stdio, needs_stdin: bool) - -> io::Result<(Process, StdioPipes)> { - const CLOEXEC_MSG_FOOTER: &[u8] = b"NOEX"; - - if self.saw_nul { - return Err(io::Error::new(ErrorKind::InvalidInput, - "nul byte found in provided data")); - } - - let (ours, theirs) = self.setup_io(default, needs_stdin)?; - let (input, output) = pipe::anon_pipe()?; - - let pid = unsafe { - match cvt(syscall::clone(0))? { - 0 => { - drop(input); - let Err(err) = self.do_exec(theirs); - let errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32; - let bytes = [ - (errno >> 24) as u8, - (errno >> 16) as u8, - (errno >> 8) as u8, - (errno >> 0) as u8, - CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1], - CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3] - ]; - // pipe I/O up to PIPE_BUF bytes should be atomic, and then - // we want to be sure we *don't* run at_exit destructors as - // we're being torn down regardless - assert!(output.write(&bytes).is_ok()); - let _ = syscall::exit(1); - panic!("failed to exit"); - } - n => n, - } - }; - - let mut p = Process { pid: pid, status: None }; - drop(output); - let mut bytes = [0; 8]; - - // loop to handle EINTR - loop { - match input.read(&mut bytes) { - Ok(0) => return Ok((p, ours)), - Ok(8) => { - assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]), - "Validation on the CLOEXEC pipe failed: {:?}", bytes); - let errno = combine(&bytes[0.. 4]); - assert!(p.wait().is_ok(), - "wait() should either return Ok or panic"); - return Err(Error::from_raw_os_error(errno)) - } - Err(ref e) if e.kind() == ErrorKind::Interrupted => {} - Err(e) => { - assert!(p.wait().is_ok(), - "wait() should either return Ok or panic"); - panic!("the CLOEXEC pipe failed: {:?}", e) - }, - Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic - assert!(p.wait().is_ok(), - "wait() should either return Ok or panic"); - panic!("short read on the CLOEXEC pipe") - } - } - } - - fn combine(arr: &[u8]) -> i32 { - let a = arr[0] as u32; - let b = arr[1] as u32; - let c = arr[2] as u32; - let d = arr[3] as u32; - - ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32 - } - } - - pub fn exec(&mut self, default: Stdio) -> io::Error { - if self.saw_nul { - return io::Error::new(ErrorKind::InvalidInput, - "nul byte found in provided data") - } - - match self.setup_io(default, true) { - Ok((_, theirs)) => unsafe { - let Err(e) = self.do_exec(theirs); - e - }, - Err(e) => e, - } - } - - // And at this point we've reached a special time in the life of the - // child. The child must now be considered hamstrung and unable to - // do anything other than syscalls really. Consider the following - // scenario: - // - // 1. Thread A of process 1 grabs the malloc() mutex - // 2. Thread B of process 1 forks(), creating thread C - // 3. Thread C of process 2 then attempts to malloc() - // 4. The memory of process 2 is the same as the memory of - // process 1, so the mutex is locked. - // - // This situation looks a lot like deadlock, right? It turns out - // that this is what pthread_atfork() takes care of, which is - // presumably implemented across platforms. The first thing that - // threads to *before* forking is to do things like grab the malloc - // mutex, and then after the fork they unlock it. - // - // Despite this information, libnative's spawn has been witnessed to - // deadlock on both macOS and FreeBSD. I'm not entirely sure why, but - // all collected backtraces point at malloc/free traffic in the - // child spawned process. - // - // For this reason, the block of code below should contain 0 - // invocations of either malloc of free (or their related friends). - // - // As an example of not having malloc/free traffic, we don't close - // this file descriptor by dropping the FileDesc (which contains an - // allocation). Instead we just close it manually. This will never - // have the drop glue anyway because this code never returns (the - // child will either exec() or invoke syscall::exit) - unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result { - if let Some(fd) = stdio.stderr.fd() { - cvt(syscall::dup2(fd, 2, &[]))?; - let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?; - flags &= ! syscall::O_CLOEXEC; - cvt(syscall::fcntl(2, syscall::F_SETFD, flags))?; - } - if let Some(fd) = stdio.stdout.fd() { - cvt(syscall::dup2(fd, 1, &[]))?; - let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?; - flags &= ! syscall::O_CLOEXEC; - cvt(syscall::fcntl(1, syscall::F_SETFD, flags))?; - } - if let Some(fd) = stdio.stdin.fd() { - cvt(syscall::dup2(fd, 0, &[]))?; - let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?; - flags &= ! syscall::O_CLOEXEC; - cvt(syscall::fcntl(0, syscall::F_SETFD, flags))?; - } - - if let Some(g) = self.gid { - cvt(syscall::setregid(g as usize, g as usize))?; - } - if let Some(u) = self.uid { - cvt(syscall::setreuid(u as usize, u as usize))?; - } - if let Some(ref cwd) = self.cwd { - cvt(syscall::chdir(cwd))?; - } - - for callback in self.closures.iter_mut() { - callback()?; - } - - self.env.apply(); - - let program = if self.program.contains(':') || self.program.contains('/') { - Some(PathBuf::from(&self.program)) - } else if let Ok(path_env) = env::var("PATH") { - let mut program = None; - for mut path in split_paths(&path_env) { - path.push(&self.program); - if path.exists() { - program = Some(path); - break; - } - } - program - } else { - None - }; - - let mut file = if let Some(program) = program { - File::open(program.as_os_str())? - } else { - return Err(io::Error::from_raw_os_error(syscall::ENOENT)); - }; - - // Push all the arguments - let mut args: Vec<[usize; 2]> = Vec::with_capacity(1 + self.args.len()); - - let interpreter = { - let mut reader = BufReader::new(&file); - - let mut shebang = [0; 2]; - let mut read = 0; - loop { - match reader.read(&mut shebang[read..])? { - 0 => break, - n => read += n, - } - } - - if &shebang == b"#!" { - // This is an interpreted script. - // First of all, since we'll be passing another file to - // fexec(), we need to manually check that we have permission - // to execute this file: - let uid = cvt(syscall::getuid())?; - let gid = cvt(syscall::getgid())?; - let meta = file.metadata()?; - - let mode = if uid == meta.uid() as usize { - meta.mode() >> 3*2 & 0o7 - } else if gid == meta.gid() as usize { - meta.mode() >> 3*1 & 0o7 - } else { - meta.mode() & 0o7 - }; - if mode & 1 == 0 { - return Err(io::Error::from_raw_os_error(syscall::EPERM)); - } - - // Second of all, we need to actually read which interpreter it wants - let mut interpreter = Vec::new(); - reader.read_until(b'\n', &mut interpreter)?; - // Pop one trailing newline, if any - if interpreter.ends_with(&[b'\n']) { - interpreter.pop().unwrap(); - } - - // FIXME: Here we could just reassign `file` directly, if it - // wasn't for lexical lifetimes. Remove the whole `let - // interpreter = { ... };` hack once NLL lands. - // NOTE: Although DO REMEMBER to make sure the interpreter path - // still lives long enough to reach fexec. - Some(interpreter) - } else { - None - } - }; - if let Some(ref interpreter) = interpreter { - let path: &OsStr = OsStr::from_bytes(&interpreter); - file = File::open(path)?; - - args.push([interpreter.as_ptr() as usize, interpreter.len()]); - } else { - file.seek(SeekFrom::Start(0))?; - } - - args.push([self.program.as_ptr() as usize, self.program.len()]); - args.extend(self.args.iter().map(|arg| [arg.as_ptr() as usize, arg.len()])); - - // Push all the variables - let mut vars: Vec<[usize; 2]> = Vec::new(); - { - let _guard = ENV_LOCK.lock(); - let mut environ = *environ(); - while *environ != ptr::null() { - let var = CStr::from_ptr(*environ).to_bytes(); - vars.push([var.as_ptr() as usize, var.len()]); - environ = environ.offset(1); - } - } - - if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) { - Err(io::Error::from_raw_os_error(err.errno as i32)) - } else { - panic!("return from exec without err"); - } - } - - fn setup_io(&self, default: Stdio, needs_stdin: bool) - -> io::Result<(StdioPipes, ChildPipes)> { - let null = Stdio::Null; - let default_stdin = if needs_stdin {&default} else {&null}; - let stdin = self.stdin.as_ref().unwrap_or(default_stdin); - let stdout = self.stdout.as_ref().unwrap_or(&default); - let stderr = self.stderr.as_ref().unwrap_or(&default); - let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?; - let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?; - let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?; - let ours = StdioPipes { - stdin: our_stdin, - stdout: our_stdout, - stderr: our_stderr, - }; - let theirs = ChildPipes { - stdin: their_stdin, - stdout: their_stdout, - stderr: their_stderr, - }; - Ok((ours, theirs)) - } -} - -impl Stdio { - fn to_child_stdio(&self, readable: bool) - -> io::Result<(ChildStdio, Option)> { - match *self { - Stdio::Inherit => Ok((ChildStdio::Inherit, None)), - - // Make sure that the source descriptors are not an stdio - // descriptor, otherwise the order which we set the child's - // descriptors may blow away a descriptor which we are hoping to - // save. For example, suppose we want the child's stderr to be the - // parent's stdout, and the child's stdout to be the parent's - // stderr. No matter which we dup first, the second will get - // overwritten prematurely. - Stdio::Fd(ref fd) => { - if fd.raw() <= 2 { - Ok((ChildStdio::Owned(fd.duplicate()?), None)) - } else { - Ok((ChildStdio::Explicit(fd.raw()), None)) - } - } - - Stdio::MakePipe => { - let (reader, writer) = pipe::anon_pipe()?; - let (ours, theirs) = if readable { - (writer, reader) - } else { - (reader, writer) - }; - Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours))) - } - - Stdio::Null => { - let mut opts = OpenOptions::new(); - opts.read(readable); - opts.write(!readable); - let fd = SysFile::open(Path::new("null:"), &opts)?; - Ok((ChildStdio::Owned(fd.into_fd()), None)) - } - } - } -} - -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { - Stdio::Fd(pipe.into_fd()) - } -} - -impl From for Stdio { - fn from(file: SysFile) -> Stdio { - Stdio::Fd(file.into_fd()) - } -} - -impl ChildStdio { - fn fd(&self) -> Option { - match *self { - ChildStdio::Inherit => None, - ChildStdio::Explicit(fd) => Some(fd), - ChildStdio::Owned(ref fd) => Some(fd.raw()), - } - } -} - -impl fmt::Debug for Command { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.program)?; - for arg in &self.args { - write!(f, " {:?}", arg)?; - } - Ok(()) - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Processes -//////////////////////////////////////////////////////////////////////////////// - -/// Unix exit statuses -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatus(i32); - -impl ExitStatus { - fn exited(&self) -> bool { - self.0 & 0x7F == 0 - } - - pub fn success(&self) -> bool { - self.code() == Some(0) - } - - pub fn code(&self) -> Option { - if self.exited() { - Some((self.0 >> 8) & 0xFF) - } else { - None - } - } - - pub fn signal(&self) -> Option { - if !self.exited() { - Some(self.0 & 0x7F) - } else { - None - } - } -} - -impl From for ExitStatus { - fn from(a: i32) -> ExitStatus { - ExitStatus(a) - } -} - -impl fmt::Display for ExitStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(code) = self.code() { - write!(f, "exit code: {}", code) - } else { - let signal = self.signal().unwrap(); - write!(f, "signal: {}", signal) - } - } -} - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitCode(u8); - -impl ExitCode { - pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); - pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _); - - pub fn as_i32(&self) -> i32 { - self.0 as i32 - } -} - -/// The unique ID of the process (this should never be negative). -pub struct Process { - pid: usize, - status: Option, -} - -impl Process { - pub fn id(&self) -> u32 { - self.pid as u32 - } - - pub fn kill(&mut self) -> io::Result<()> { - // If we've already waited on this process then the pid can be recycled - // and used for another process, and we probably shouldn't be killing - // random processes, so just return an error. - if self.status.is_some() { - Err(Error::new(ErrorKind::InvalidInput, - "invalid argument: can't kill an exited process")) - } else { - cvt(syscall::kill(self.pid, syscall::SIGKILL))?; - Ok(()) - } - } - - pub fn wait(&mut self) -> io::Result { - if let Some(status) = self.status { - return Ok(status) - } - let mut status = 0; - cvt(syscall::waitpid(self.pid, &mut status, 0))?; - self.status = Some(ExitStatus(status as i32)); - Ok(ExitStatus(status as i32)) - } - - pub fn try_wait(&mut self) -> io::Result> { - if let Some(status) = self.status { - return Ok(Some(status)) - } - let mut status = 0; - let pid = cvt(syscall::waitpid(self.pid, &mut status, syscall::WNOHANG))?; - if pid == 0 { - Ok(None) - } else { - self.status = Some(ExitStatus(status as i32)); - Ok(Some(ExitStatus(status as i32))) - } - } -} diff --git a/src/libstd/sys/redox/rand.rs b/src/libstd/sys/redox/rand.rs deleted file mode 100644 index 5b58d1782b..0000000000 --- a/src/libstd/sys/redox/rand.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn hashmap_random_keys() -> (u64, u64) { - (0, 0) -} diff --git a/src/libstd/sys/redox/rwlock.rs b/src/libstd/sys/redox/rwlock.rs deleted file mode 100644 index 990e755111..0000000000 --- a/src/libstd/sys/redox/rwlock.rs +++ /dev/null @@ -1,51 +0,0 @@ -use super::mutex::Mutex; - -pub struct RWLock { - mutex: Mutex -} - -unsafe impl Send for RWLock {} -unsafe impl Sync for RWLock {} - -impl RWLock { - pub const fn new() -> RWLock { - RWLock { - mutex: Mutex::new() - } - } - - #[inline] - pub unsafe fn read(&self) { - self.mutex.lock(); - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - self.mutex.try_lock() - } - - #[inline] - pub unsafe fn write(&self) { - self.mutex.lock(); - } - - #[inline] - pub unsafe fn try_write(&self) -> bool { - self.mutex.try_lock() - } - - #[inline] - pub unsafe fn read_unlock(&self) { - self.mutex.unlock(); - } - - #[inline] - pub unsafe fn write_unlock(&self) { - self.mutex.unlock(); - } - - #[inline] - pub unsafe fn destroy(&self) { - self.mutex.destroy(); - } -} diff --git a/src/libstd/sys/redox/syscall/arch/arm.rs b/src/libstd/sys/redox/syscall/arch/arm.rs deleted file mode 100644 index e640f7ed37..0000000000 --- a/src/libstd/sys/redox/syscall/arch/arm.rs +++ /dev/null @@ -1,73 +0,0 @@ -use super::error::{Error, Result}; - -pub unsafe fn syscall0(mut a: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b) - : "memory" - : "volatile"); - - Error::demux(a) -} - -// Clobbers all registers - special for clone -pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b) - : "memory", "r0", "r1", "r2", "r3", "r4" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e), "{r4}"(f) - : "memory" - : "volatile"); - - Error::demux(a) -} diff --git a/src/libstd/sys/redox/syscall/arch/x86.rs b/src/libstd/sys/redox/syscall/arch/x86.rs deleted file mode 100644 index 0cd6409bb0..0000000000 --- a/src/libstd/sys/redox/syscall/arch/x86.rs +++ /dev/null @@ -1,73 +0,0 @@ -use super::error::{Error, Result}; - -pub unsafe fn syscall0(mut a: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -// Clobbers all registers - special for clone -pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b) - : "memory", "ebx", "ecx", "edx", "esi", "edi" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e), "{edi}"(f) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} diff --git a/src/libstd/sys/redox/syscall/arch/x86_64.rs b/src/libstd/sys/redox/syscall/arch/x86_64.rs deleted file mode 100644 index 52ad01bd4a..0000000000 --- a/src/libstd/sys/redox/syscall/arch/x86_64.rs +++ /dev/null @@ -1,74 +0,0 @@ -use super::error::{Error, Result}; - -pub unsafe fn syscall0(mut a: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -// Clobbers all registers - special for clone -pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b) - : "memory", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", - "r9", "r10", "r11", "r12", "r13", "r14", "r15" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e), "{rdi}"(f) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs deleted file mode 100644 index b9abb48a8d..0000000000 --- a/src/libstd/sys/redox/syscall/call.rs +++ /dev/null @@ -1,348 +0,0 @@ -use super::arch::*; -use super::data::{SigAction, Stat, StatVfs, TimeSpec}; -use super::error::Result; -use super::number::*; - -use core::{mem, ptr}; - -// Signal restorer -extern "C" fn restorer() -> ! { - sigreturn().unwrap(); - unreachable!(); -} - -/// Set the end of the process's heap -/// -/// When `addr` is `0`, this function will return the current break. -/// -/// When `addr` is nonzero, this function will attempt to set the end of the process's -/// heap to `addr` and return the new program break. The new program break should be -/// checked by the allocator, it may not be exactly `addr`, as it may be aligned to a page -/// boundary. -/// -/// On error, `Err(ENOMEM)` will be returned indicating that no memory is available -pub unsafe fn brk(addr: usize) -> Result { - syscall1(SYS_BRK, addr) -} - -/// Changes the process's working directory. -/// -/// This function will attempt to set the process's working directory to `path`, which can be -/// either a relative, scheme relative, or absolute path. -/// -/// On success, `Ok(0)` will be returned. On error, one of the following errors will be returned. -/// -/// # Errors -/// -/// * `EACCES` - permission is denied for one of the components of `path`, or `path` -/// * `EFAULT` - `path` does not point to the process's addressable memory -/// * `EIO` - an I/O error occurred -/// * `ENOENT` - `path` does not exit -/// * `ENOTDIR` - `path` is not a directory -pub fn chdir>(path: T) -> Result { - unsafe { syscall2(SYS_CHDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -pub fn chmod>(path: T, mode: usize) -> Result { - unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) } -} - -/// Produces a fork of the current process, or a new process thread. -pub unsafe fn clone(flags: usize) -> Result { - syscall1_clobber(SYS_CLONE, flags) -} - -/// Closes a file. -pub fn close(fd: usize) -> Result { - unsafe { syscall1(SYS_CLOSE, fd) } -} - -/// Gets the current system time. -pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result { - unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) } -} - -/// Copies and transforms a file descriptor. -pub fn dup(fd: usize, buf: &[u8]) -> Result { - unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) } -} - -/// Copies and transforms a file descriptor. -pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result { - unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) } -} - -/// Exits the current process. -pub fn exit(status: usize) -> Result { - unsafe { syscall1(SYS_EXIT, status) } -} - -/// Changes file permissions. -pub fn fchmod(fd: usize, mode: u16) -> Result { - unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) } - -} - -/// Changes file ownership. -pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result { - unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) } - -} - -/// Changes file descriptor flags. -pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result { - unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) } -} - -/// Replaces the current process with a new executable. -pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result { - unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), - vars.as_ptr() as usize, vars.len()) } -} - -/// Maps a file into memory. -pub unsafe fn fmap(fd: usize, offset: usize, size: usize) -> Result { - syscall3(SYS_FMAP, fd, offset, size) -} - -/// Unmaps a memory-mapped file. -pub unsafe fn funmap(addr: usize) -> Result { - syscall1(SYS_FUNMAP, addr) -} - -/// Retrieves the canonical path of a file. -pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { - unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) } -} - -/// Renames a file. -pub fn frename>(fd: usize, path: T) -> Result { - unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -/// Gets metadata about a file. -pub fn fstat(fd: usize, stat: &mut Stat) -> Result { - unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::()) } -} - -/// Gets metadata about a filesystem. -pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result { - unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::()) } -} - -/// Syncs a file descriptor to its underlying medium. -pub fn fsync(fd: usize) -> Result { - unsafe { syscall1(SYS_FSYNC, fd) } -} - -/// Truncate or extend a file to a specified length -pub fn ftruncate(fd: usize, len: usize) -> Result { - unsafe { syscall2(SYS_FTRUNCATE, fd, len) } -} - -// Change modify and/or access times -pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { - unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, - times.len() * mem::size_of::()) } -} - -/// Fast userspace mutex -pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32) - -> Result { - syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize) -} - -/// Gets the current working directory. -pub fn getcwd(buf: &mut [u8]) -> Result { - unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) } -} - -/// Gets the effective group ID. -pub fn getegid() -> Result { - unsafe { syscall0(SYS_GETEGID) } -} - -/// Gets the effective namespace. -pub fn getens() -> Result { - unsafe { syscall0(SYS_GETENS) } -} - -/// Gets the effective user ID. -pub fn geteuid() -> Result { - unsafe { syscall0(SYS_GETEUID) } -} - -/// Gets the current group ID. -pub fn getgid() -> Result { - unsafe { syscall0(SYS_GETGID) } -} - -/// Gets the current namespace. -pub fn getns() -> Result { - unsafe { syscall0(SYS_GETNS) } -} - -/// Gets the current process ID. -pub fn getpid() -> Result { - unsafe { syscall0(SYS_GETPID) } -} - -/// Gets the process group ID. -pub fn getpgid(pid: usize) -> Result { - unsafe { syscall1(SYS_GETPGID, pid) } -} - -/// Gets the parent process ID. -pub fn getppid() -> Result { - unsafe { syscall0(SYS_GETPPID) } -} - -/// Gets the current user ID. -pub fn getuid() -> Result { - unsafe { syscall0(SYS_GETUID) } -} - -/// Sets the I/O privilege level -pub unsafe fn iopl(level: usize) -> Result { - syscall1(SYS_IOPL, level) -} - -/// Sends a signal `sig` to the process identified by `pid`. -pub fn kill(pid: usize, sig: usize) -> Result { - unsafe { syscall2(SYS_KILL, pid, sig) } -} - -/// Creates a link to a file. -pub unsafe fn link(old: *const u8, new: *const u8) -> Result { - syscall2(SYS_LINK, old as usize, new as usize) -} - -/// Seeks to `offset` bytes in a file descriptor. -pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result { - unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) } -} - -/// Makes a new scheme namespace. -pub fn mkns(schemes: &[[usize; 2]]) -> Result { - unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) } -} - -/// Sleeps for the time specified in `req`. -pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result { - unsafe { syscall2(SYS_NANOSLEEP, req as *const TimeSpec as usize, - rem as *mut TimeSpec as usize) } -} - -/// Opens a file. -pub fn open>(path: T, flags: usize) -> Result { - unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) } -} - -/// Allocates pages, linearly in physical memory. -pub unsafe fn physalloc(size: usize) -> Result { - syscall1(SYS_PHYSALLOC, size) -} - -/// Frees physically allocated pages. -pub unsafe fn physfree(physical_address: usize, size: usize) -> Result { - syscall2(SYS_PHYSFREE, physical_address, size) -} - -/// Maps physical memory to virtual memory. -pub unsafe fn physmap(physical_address: usize, size: usize, flags: usize) -> Result { - syscall3(SYS_PHYSMAP, physical_address, size, flags) -} - -/// Unmaps previously mapped physical memory. -pub unsafe fn physunmap(virtual_address: usize) -> Result { - syscall1(SYS_PHYSUNMAP, virtual_address) -} - -/// Creates a pair of file descriptors referencing the read and write ends of a pipe. -pub fn pipe2(fds: &mut [usize; 2], flags: usize) -> Result { - unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) } -} - -/// Read from a file descriptor into a buffer -pub fn read(fd: usize, buf: &mut [u8]) -> Result { - unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) } -} - -/// Removes a directory. -pub fn rmdir>(path: T) -> Result { - unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -/// Sets the process group ID. -pub fn setpgid(pid: usize, pgid: usize) -> Result { - unsafe { syscall2(SYS_SETPGID, pid, pgid) } -} - -/// Sets the current process group IDs. -pub fn setregid(rgid: usize, egid: usize) -> Result { - unsafe { syscall2(SYS_SETREGID, rgid, egid) } -} - -/// Makes a new scheme namespace. -pub fn setrens(rns: usize, ens: usize) -> Result { - unsafe { syscall2(SYS_SETRENS, rns, ens) } -} - -/// Sets the current process user IDs. -pub fn setreuid(ruid: usize, euid: usize) -> Result { - unsafe { syscall2(SYS_SETREUID, ruid, euid) } -} - -/// Sets up a signal handler. -pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) --> Result { - unsafe { syscall4(SYS_SIGACTION, sig, - act.map(|x| x as *const _).unwrap_or_else(ptr::null) as usize, - oldact.map(|x| x as *mut _).unwrap_or_else(ptr::null_mut) as usize, - restorer as usize) } -} - -/// Returns from signal handler. -pub fn sigreturn() -> Result { - unsafe { syscall0(SYS_SIGRETURN) } -} - -/// Removes a file. -pub fn unlink>(path: T) -> Result { - unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -/// Converts a virtual address to a physical one. -pub unsafe fn virttophys(virtual_address: usize) -> Result { - syscall1(SYS_VIRTTOPHYS, virtual_address) -} - -/// Checks if a child process has exited or received a signal. -pub fn waitpid(pid: usize, status: &mut usize, options: usize) -> Result { - unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options) } -} - -/// Writes a buffer to a file descriptor. -/// -/// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning -/// either an `Err`, explained below, or `Ok(count)` where `count` is the number of bytes which -/// were written. -/// -/// # Errors -/// -/// * `EAGAIN` - the file descriptor was opened with `O_NONBLOCK` and writing would block -/// * `EBADF` - the file descriptor is not valid or is not open for writing -/// * `EFAULT` - `buf` does not point to the process's addressable memory -/// * `EIO` - an I/O error occurred -/// * `ENOSPC` - the device containing the file descriptor has no room for data -/// * `EPIPE` - the file descriptor refers to a pipe or socket whose reading end is closed -pub fn write(fd: usize, buf: &[u8]) -> Result { - unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) } -} - -/// Yields the process's time slice to the kernel. -/// -/// This function will return Ok(0) on success -pub fn sched_yield() -> Result { - unsafe { syscall0(SYS_YIELD) } -} diff --git a/src/libstd/sys/redox/syscall/data.rs b/src/libstd/sys/redox/syscall/data.rs deleted file mode 100644 index 0b458ea89b..0000000000 --- a/src/libstd/sys/redox/syscall/data.rs +++ /dev/null @@ -1,191 +0,0 @@ -use core::ops::{Deref, DerefMut}; -use core::{mem, slice}; - -#[derive(Copy, Clone, Debug, Default)] -pub struct Event { - pub id: usize, - pub flags: usize, - pub data: usize -} - -impl Deref for Event { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const Event as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for Event { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut Event as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct Packet { - pub id: u64, - pub pid: usize, - pub uid: u32, - pub gid: u32, - pub a: usize, - pub b: usize, - pub c: usize, - pub d: usize -} - -impl Deref for Packet { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const Packet as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for Packet { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut Packet as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug)] -#[repr(C)] -pub struct SigAction { - pub sa_handler: extern "C" fn(usize), - pub sa_mask: [u64; 2], - pub sa_flags: usize, -} - -impl Default for SigAction { - fn default() -> Self { - Self { - sa_handler: unsafe { mem::transmute(0usize) }, - sa_mask: [0; 2], - sa_flags: 0, - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct Stat { - pub st_dev: u64, - pub st_ino: u64, - pub st_mode: u16, - pub st_nlink: u32, - pub st_uid: u32, - pub st_gid: u32, - pub st_size: u64, - pub st_blksize: u32, - pub st_blocks: u64, - pub st_mtime: u64, - pub st_mtime_nsec: u32, - pub st_atime: u64, - pub st_atime_nsec: u32, - pub st_ctime: u64, - pub st_ctime_nsec: u32, -} - -impl Deref for Stat { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const Stat as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for Stat { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut Stat as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct StatVfs { - pub f_bsize: u32, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, -} - -impl Deref for StatVfs { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const StatVfs as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for StatVfs { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut StatVfs as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct TimeSpec { - pub tv_sec: i64, - pub tv_nsec: i32, -} - -impl Deref for TimeSpec { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const TimeSpec as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for TimeSpec { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut TimeSpec as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} diff --git a/src/libstd/sys/redox/syscall/error.rs b/src/libstd/sys/redox/syscall/error.rs deleted file mode 100644 index da84ffb042..0000000000 --- a/src/libstd/sys/redox/syscall/error.rs +++ /dev/null @@ -1,315 +0,0 @@ -use core::{fmt, result}; - -#[derive(Eq, PartialEq)] -pub struct Error { - pub errno: i32, -} - -pub type Result = result::Result; - -impl Error { - pub fn new(errno: i32) -> Error { - Error { errno } - } - - pub fn mux(result: Result) -> usize { - match result { - Ok(value) => value, - Err(error) => -error.errno as usize, - } - } - - pub fn demux(value: usize) -> Result { - let errno = -(value as i32); - if errno >= 1 && errno < STR_ERROR.len() as i32 { - Err(Error::new(errno)) - } else { - Ok(value) - } - } - - pub fn text(&self) -> &str { - if let Some(description) = STR_ERROR.get(self.errno as usize) { - description - } else { - "Unknown Error" - } - } -} - -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.text()) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.text()) - } -} - -pub const EPERM: i32 = 1; /* Operation not permitted */ -pub const ENOENT: i32 = 2; /* No such file or directory */ -pub const ESRCH: i32 = 3; /* No such process */ -pub const EINTR: i32 = 4; /* Interrupted system call */ -pub const EIO: i32 = 5; /* I/O error */ -pub const ENXIO: i32 = 6; /* No such device or address */ -pub const E2BIG: i32 = 7; /* Argument list too long */ -pub const ENOEXEC: i32 = 8; /* Exec format error */ -pub const EBADF: i32 = 9; /* Bad file number */ -pub const ECHILD: i32 = 10; /* No child processes */ -pub const EAGAIN: i32 = 11; /* Try again */ -pub const ENOMEM: i32 = 12; /* Out of memory */ -pub const EACCES: i32 = 13; /* Permission denied */ -pub const EFAULT: i32 = 14; /* Bad address */ -pub const ENOTBLK: i32 = 15; /* Block device required */ -pub const EBUSY: i32 = 16; /* Device or resource busy */ -pub const EEXIST: i32 = 17; /* File exists */ -pub const EXDEV: i32 = 18; /* Cross-device link */ -pub const ENODEV: i32 = 19; /* No such device */ -pub const ENOTDIR: i32 = 20; /* Not a directory */ -pub const EISDIR: i32 = 21; /* Is a directory */ -pub const EINVAL: i32 = 22; /* Invalid argument */ -pub const ENFILE: i32 = 23; /* File table overflow */ -pub const EMFILE: i32 = 24; /* Too many open files */ -pub const ENOTTY: i32 = 25; /* Not a typewriter */ -pub const ETXTBSY: i32 = 26; /* Text file busy */ -pub const EFBIG: i32 = 27; /* File too large */ -pub const ENOSPC: i32 = 28; /* No space left on device */ -pub const ESPIPE: i32 = 29; /* Illegal seek */ -pub const EROFS: i32 = 30; /* Read-only file system */ -pub const EMLINK: i32 = 31; /* Too many links */ -pub const EPIPE: i32 = 32; /* Broken pipe */ -pub const EDOM: i32 = 33; /* Math argument out of domain of func */ -pub const ERANGE: i32 = 34; /* Math result not representable */ -pub const EDEADLK: i32 = 35; /* Resource deadlock would occur */ -pub const ENAMETOOLONG: i32 = 36; /* File name too long */ -pub const ENOLCK: i32 = 37; /* No record locks available */ -pub const ENOSYS: i32 = 38; /* Function not implemented */ -pub const ENOTEMPTY: i32 = 39; /* Directory not empty */ -pub const ELOOP: i32 = 40; /* Too many symbolic links encountered */ -pub const EWOULDBLOCK: i32 = 41; /* Operation would block */ -pub const ENOMSG: i32 = 42; /* No message of desired type */ -pub const EIDRM: i32 = 43; /* Identifier removed */ -pub const ECHRNG: i32 = 44; /* Channel number out of range */ -pub const EL2NSYNC: i32 = 45; /* Level 2 not synchronized */ -pub const EL3HLT: i32 = 46; /* Level 3 halted */ -pub const EL3RST: i32 = 47; /* Level 3 reset */ -pub const ELNRNG: i32 = 48; /* Link number out of range */ -pub const EUNATCH: i32 = 49; /* Protocol driver not attached */ -pub const ENOCSI: i32 = 50; /* No CSI structure available */ -pub const EL2HLT: i32 = 51; /* Level 2 halted */ -pub const EBADE: i32 = 52; /* Invalid exchange */ -pub const EBADR: i32 = 53; /* Invalid request descriptor */ -pub const EXFULL: i32 = 54; /* Exchange full */ -pub const ENOANO: i32 = 55; /* No anode */ -pub const EBADRQC: i32 = 56; /* Invalid request code */ -pub const EBADSLT: i32 = 57; /* Invalid slot */ -pub const EDEADLOCK: i32 = 58; /* Resource deadlock would occur */ -pub const EBFONT: i32 = 59; /* Bad font file format */ -pub const ENOSTR: i32 = 60; /* Device not a stream */ -pub const ENODATA: i32 = 61; /* No data available */ -pub const ETIME: i32 = 62; /* Timer expired */ -pub const ENOSR: i32 = 63; /* Out of streams resources */ -pub const ENONET: i32 = 64; /* Machine is not on the network */ -pub const ENOPKG: i32 = 65; /* Package not installed */ -pub const EREMOTE: i32 = 66; /* Object is remote */ -pub const ENOLINK: i32 = 67; /* Link has been severed */ -pub const EADV: i32 = 68; /* Advertise error */ -pub const ESRMNT: i32 = 69; /* Srmount error */ -pub const ECOMM: i32 = 70; /* Communication error on send */ -pub const EPROTO: i32 = 71; /* Protocol error */ -pub const EMULTIHOP: i32 = 72; /* Multihop attempted */ -pub const EDOTDOT: i32 = 73; /* RFS specific error */ -pub const EBADMSG: i32 = 74; /* Not a data message */ -pub const EOVERFLOW: i32 = 75; /* Value too large for defined data type */ -pub const ENOTUNIQ: i32 = 76; /* Name not unique on network */ -pub const EBADFD: i32 = 77; /* File descriptor in bad state */ -pub const EREMCHG: i32 = 78; /* Remote address changed */ -pub const ELIBACC: i32 = 79; /* Can not access a needed shared library */ -pub const ELIBBAD: i32 = 80; /* Accessing a corrupted shared library */ -pub const ELIBSCN: i32 = 81; /* .lib section in a.out corrupted */ -pub const ELIBMAX: i32 = 82; /* Attempting to link in too many shared libraries */ -pub const ELIBEXEC: i32 = 83; /* Cannot exec a shared library directly */ -pub const EILSEQ: i32 = 84; /* Illegal byte sequence */ -pub const ERESTART: i32 = 85; /* Interrupted system call should be restarted */ -pub const ESTRPIPE: i32 = 86; /* Streams pipe error */ -pub const EUSERS: i32 = 87; /* Too many users */ -pub const ENOTSOCK: i32 = 88; /* Socket operation on non-socket */ -pub const EDESTADDRREQ: i32 = 89; /* Destination address required */ -pub const EMSGSIZE: i32 = 90; /* Message too long */ -pub const EPROTOTYPE: i32 = 91; /* Protocol wrong type for socket */ -pub const ENOPROTOOPT: i32 = 92; /* Protocol not available */ -pub const EPROTONOSUPPORT: i32 = 93; /* Protocol not supported */ -pub const ESOCKTNOSUPPORT: i32 = 94; /* Socket type not supported */ -pub const EOPNOTSUPP: i32 = 95; /* Operation not supported on transport endpoint */ -pub const EPFNOSUPPORT: i32 = 96; /* Protocol family not supported */ -pub const EAFNOSUPPORT: i32 = 97; /* Address family not supported by protocol */ -pub const EADDRINUSE: i32 = 98; /* Address already in use */ -pub const EADDRNOTAVAIL: i32 = 99; /* Cannot assign requested address */ -pub const ENETDOWN: i32 = 100; /* Network is down */ -pub const ENETUNREACH: i32 = 101; /* Network is unreachable */ -pub const ENETRESET: i32 = 102; /* Network dropped connection because of reset */ -pub const ECONNABORTED: i32 = 103; /* Software caused connection abort */ -pub const ECONNRESET: i32 = 104; /* Connection reset by peer */ -pub const ENOBUFS: i32 = 105; /* No buffer space available */ -pub const EISCONN: i32 = 106; /* Transport endpoint is already connected */ -pub const ENOTCONN: i32 = 107; /* Transport endpoint is not connected */ -pub const ESHUTDOWN: i32 = 108; /* Cannot send after transport endpoint shutdown */ -pub const ETOOMANYREFS: i32 = 109; /* Too many references: cannot splice */ -pub const ETIMEDOUT: i32 = 110; /* Connection timed out */ -pub const ECONNREFUSED: i32 = 111; /* Connection refused */ -pub const EHOSTDOWN: i32 = 112; /* Host is down */ -pub const EHOSTUNREACH: i32 = 113; /* No route to host */ -pub const EALREADY: i32 = 114; /* Operation already in progress */ -pub const EINPROGRESS: i32 = 115; /* Operation now in progress */ -pub const ESTALE: i32 = 116; /* Stale NFS file handle */ -pub const EUCLEAN: i32 = 117; /* Structure needs cleaning */ -pub const ENOTNAM: i32 = 118; /* Not a XENIX named type file */ -pub const ENAVAIL: i32 = 119; /* No XENIX semaphores available */ -pub const EISNAM: i32 = 120; /* Is a named type file */ -pub const EREMOTEIO: i32 = 121; /* Remote I/O error */ -pub const EDQUOT: i32 = 122; /* Quota exceeded */ -pub const ENOMEDIUM: i32 = 123; /* No medium found */ -pub const EMEDIUMTYPE: i32 = 124; /* Wrong medium type */ -pub const ECANCELED: i32 = 125; /* Operation Canceled */ -pub const ENOKEY: i32 = 126; /* Required key not available */ -pub const EKEYEXPIRED: i32 = 127; /* Key has expired */ -pub const EKEYREVOKED: i32 = 128; /* Key has been revoked */ -pub const EKEYREJECTED: i32 = 129; /* Key was rejected by service */ -pub const EOWNERDEAD: i32 = 130; /* Owner died */ -pub const ENOTRECOVERABLE: i32 = 131; /* State not recoverable */ - -pub static STR_ERROR: [&'static str; 132] = ["Success", - "Operation not permitted", - "No such file or directory", - "No such process", - "Interrupted system call", - "I/O error", - "No such device or address", - "Argument list too long", - "Exec format error", - "Bad file number", - "No child processes", - "Try again", - "Out of memory", - "Permission denied", - "Bad address", - "Block device required", - "Device or resource busy", - "File exists", - "Cross-device link", - "No such device", - "Not a directory", - "Is a directory", - "Invalid argument", - "File table overflow", - "Too many open files", - "Not a typewriter", - "Text file busy", - "File too large", - "No space left on device", - "Illegal seek", - "Read-only file system", - "Too many links", - "Broken pipe", - "Math argument out of domain of func", - "Math result not representable", - "Resource deadlock would occur", - "File name too long", - "No record locks available", - "Function not implemented", - "Directory not empty", - "Too many symbolic links encountered", - "Operation would block", - "No message of desired type", - "Identifier removed", - "Channel number out of range", - "Level 2 not synchronized", - "Level 3 halted", - "Level 3 reset", - "Link number out of range", - "Protocol driver not attached", - "No CSI structure available", - "Level 2 halted", - "Invalid exchange", - "Invalid request descriptor", - "Exchange full", - "No anode", - "Invalid request code", - "Invalid slot", - "Resource deadlock would occur", - "Bad font file format", - "Device not a stream", - "No data available", - "Timer expired", - "Out of streams resources", - "Machine is not on the network", - "Package not installed", - "Object is remote", - "Link has been severed", - "Advertise error", - "Srmount error", - "Communication error on send", - "Protocol error", - "Multihop attempted", - "RFS specific error", - "Not a data message", - "Value too large for defined data type", - "Name not unique on network", - "File descriptor in bad state", - "Remote address changed", - "Can not access a needed shared library", - "Accessing a corrupted shared library", - ".lib section in a.out corrupted", - "Attempting to link in too many shared libraries", - "Cannot exec a shared library directly", - "Illegal byte sequence", - "Interrupted system call should be restarted", - "Streams pipe error", - "Too many users", - "Socket operation on non-socket", - "Destination address required", - "Message too long", - "Protocol wrong type for socket", - "Protocol not available", - "Protocol not supported", - "Socket type not supported", - "Operation not supported on transport endpoint", - "Protocol family not supported", - "Address family not supported by protocol", - "Address already in use", - "Cannot assign requested address", - "Network is down", - "Network is unreachable", - "Network dropped connection because of reset", - "Software caused connection abort", - "Connection reset by peer", - "No buffer space available", - "Transport endpoint is already connected", - "Transport endpoint is not connected", - "Cannot send after transport endpoint shutdown", - "Too many references: cannot splice", - "Connection timed out", - "Connection refused", - "Host is down", - "No route to host", - "Operation already in progress", - "Operation now in progress", - "Stale NFS file handle", - "Structure needs cleaning", - "Not a XENIX named type file", - "No XENIX semaphores available", - "Is a named type file", - "Remote I/O error", - "Quota exceeded", - "No medium found", - "Wrong medium type", - "Operation Canceled", - "Required key not available", - "Key has expired", - "Key has been revoked", - "Key was rejected by service", - "Owner died", - "State not recoverable"]; diff --git a/src/libstd/sys/redox/syscall/flag.rs b/src/libstd/sys/redox/syscall/flag.rs deleted file mode 100644 index 5820f1ad03..0000000000 --- a/src/libstd/sys/redox/syscall/flag.rs +++ /dev/null @@ -1,148 +0,0 @@ -pub const CLONE_VM: usize = 0x100; -pub const CLONE_FS: usize = 0x200; -pub const CLONE_FILES: usize = 0x400; -pub const CLONE_SIGHAND: usize = 0x800; -pub const CLONE_VFORK: usize = 0x4000; -pub const CLONE_THREAD: usize = 0x10000; - -pub const CLOCK_REALTIME: usize = 1; -pub const CLOCK_MONOTONIC: usize = 4; - -pub const EVENT_NONE: usize = 0; -pub const EVENT_READ: usize = 1; -pub const EVENT_WRITE: usize = 2; - -pub const F_DUPFD: usize = 0; -pub const F_GETFD: usize = 1; -pub const F_SETFD: usize = 2; -pub const F_GETFL: usize = 3; -pub const F_SETFL: usize = 4; - -pub const FUTEX_WAIT: usize = 0; -pub const FUTEX_WAKE: usize = 1; -pub const FUTEX_REQUEUE: usize = 2; - -pub const MAP_WRITE: usize = 1; -pub const MAP_WRITE_COMBINE: usize = 2; - -pub const MODE_TYPE: u16 = 0xF000; -pub const MODE_DIR: u16 = 0x4000; -pub const MODE_FILE: u16 = 0x8000; -pub const MODE_SYMLINK: u16 = 0xA000; -pub const MODE_FIFO: u16 = 0x1000; -pub const MODE_CHR: u16 = 0x2000; - -pub const MODE_PERM: u16 = 0x0FFF; -pub const MODE_SETUID: u16 = 0o4000; -pub const MODE_SETGID: u16 = 0o2000; - -pub const O_RDONLY: usize = 0x0001_0000; -pub const O_WRONLY: usize = 0x0002_0000; -pub const O_RDWR: usize = 0x0003_0000; -pub const O_NONBLOCK: usize = 0x0004_0000; -pub const O_APPEND: usize = 0x0008_0000; -pub const O_SHLOCK: usize = 0x0010_0000; -pub const O_EXLOCK: usize = 0x0020_0000; -pub const O_ASYNC: usize = 0x0040_0000; -pub const O_FSYNC: usize = 0x0080_0000; -pub const O_CLOEXEC: usize = 0x0100_0000; -pub const O_CREAT: usize = 0x0200_0000; -pub const O_TRUNC: usize = 0x0400_0000; -pub const O_EXCL: usize = 0x0800_0000; -pub const O_DIRECTORY: usize = 0x1000_0000; -pub const O_STAT: usize = 0x2000_0000; -pub const O_SYMLINK: usize = 0x4000_0000; -pub const O_NOFOLLOW: usize = 0x8000_0000; -pub const O_ACCMODE: usize = O_RDONLY | O_WRONLY | O_RDWR; - -pub const SEEK_SET: usize = 0; -pub const SEEK_CUR: usize = 1; -pub const SEEK_END: usize = 2; - -pub const SIGHUP: usize = 1; -pub const SIGINT: usize = 2; -pub const SIGQUIT: usize = 3; -pub const SIGILL: usize = 4; -pub const SIGTRAP: usize = 5; -pub const SIGABRT: usize = 6; -pub const SIGBUS: usize = 7; -pub const SIGFPE: usize = 8; -pub const SIGKILL: usize = 9; -pub const SIGUSR1: usize = 10; -pub const SIGSEGV: usize = 11; -pub const SIGUSR2: usize = 12; -pub const SIGPIPE: usize = 13; -pub const SIGALRM: usize = 14; -pub const SIGTERM: usize = 15; -pub const SIGSTKFLT: usize= 16; -pub const SIGCHLD: usize = 17; -pub const SIGCONT: usize = 18; -pub const SIGSTOP: usize = 19; -pub const SIGTSTP: usize = 20; -pub const SIGTTIN: usize = 21; -pub const SIGTTOU: usize = 22; -pub const SIGURG: usize = 23; -pub const SIGXCPU: usize = 24; -pub const SIGXFSZ: usize = 25; -pub const SIGVTALRM: usize= 26; -pub const SIGPROF: usize = 27; -pub const SIGWINCH: usize = 28; -pub const SIGIO: usize = 29; -pub const SIGPWR: usize = 30; -pub const SIGSYS: usize = 31; - -pub const SIG_DFL: usize = 0; -pub const SIG_IGN: usize = 1; - -pub const SA_NOCLDSTOP: usize = 0x00000001; -pub const SA_NOCLDWAIT: usize = 0x00000002; -pub const SA_SIGINFO: usize = 0x00000004; -pub const SA_RESTORER: usize = 0x04000000; -pub const SA_ONSTACK: usize = 0x08000000; -pub const SA_RESTART: usize = 0x10000000; -pub const SA_NODEFER: usize = 0x40000000; -pub const SA_RESETHAND: usize = 0x80000000; - -pub const WNOHANG: usize = 0x01; -pub const WUNTRACED: usize = 0x02; -pub const WCONTINUED: usize = 0x08; - -/// Returns `true` if status indicates the child is stopped. -pub fn wifstopped(status: usize) -> bool { - (status & 0xff) == 0x7f -} - -/// If wifstopped(status), returns the signal that stopped the child. -pub fn wstopsig(status: usize) -> usize { - (status >> 8) & 0xff -} - -/// Returns `true` if status indicates the child continued after a stop. -pub fn wifcontinued(status: usize) -> bool { - status == 0xffff -} - -/// Returns `true` if status indicates termination by a signal. -pub fn wifsignaled(status: usize) -> bool { - ((status & 0x7f) + 1) as i8 >= 2 -} - -/// If wifsignaled(status), returns the terminating signal. -pub fn wtermsig(status: usize) -> usize { - status & 0x7f -} - -/// Returns `true` if status indicates normal termination. -pub fn wifexited(status: usize) -> bool { - wtermsig(status) == 0 -} - -/// If wifexited(status), returns the exit status. -pub fn wexitstatus(status: usize) -> usize { - (status >> 8) & 0xff -} - -/// Returns `true` if status indicates a core dump was created. -pub fn wcoredump(status: usize) -> bool { - (status & 0x80) != 0 -} diff --git a/src/libstd/sys/redox/syscall/mod.rs b/src/libstd/sys/redox/syscall/mod.rs deleted file mode 100644 index b16f5dbd91..0000000000 --- a/src/libstd/sys/redox/syscall/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -pub use self::arch::*; -pub use self::call::*; -pub use self::data::*; -pub use self::error::*; -pub use self::flag::*; -pub use self::number::*; - -#[cfg(target_arch = "arm")] -#[path="arch/arm.rs"] -mod arch; - -#[cfg(target_arch = "x86")] -#[path="arch/x86.rs"] -mod arch; - -#[cfg(target_arch = "x86_64")] -#[path="arch/x86_64.rs"] -mod arch; - -/// Function definitions -pub mod call; - -/// Complex structures that are used for some system calls -pub mod data; - -/// All errors that can be generated by a system call -pub mod error; - -/// Flags used as an argument to many system calls -pub mod flag; - -/// Call numbers used by each system call -pub mod number; diff --git a/src/libstd/sys/redox/syscall/number.rs b/src/libstd/sys/redox/syscall/number.rs deleted file mode 100644 index f8884aa2ed..0000000000 --- a/src/libstd/sys/redox/syscall/number.rs +++ /dev/null @@ -1,73 +0,0 @@ -pub const SYS_CLASS: usize = 0xF000_0000; -pub const SYS_CLASS_PATH: usize=0x1000_0000; -pub const SYS_CLASS_FILE: usize=0x2000_0000; - -pub const SYS_ARG: usize = 0x0F00_0000; -pub const SYS_ARG_SLICE: usize =0x0100_0000; -pub const SYS_ARG_MSLICE: usize=0x0200_0000; -pub const SYS_ARG_PATH: usize = 0x0300_0000; - -pub const SYS_RET: usize = 0x00F0_0000; -pub const SYS_RET_FILE: usize = 0x0010_0000; - -pub const SYS_LINK: usize = SYS_CLASS_PATH | SYS_ARG_PATH | 9; -pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5; -pub const SYS_CHMOD: usize = SYS_CLASS_PATH | 15; -pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84; -pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10; - -pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6; -pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41; -pub const SYS_DUP2: usize = SYS_CLASS_FILE | SYS_RET_FILE | 63; -pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3; -pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4; -pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19; -pub const SYS_FCHMOD: usize = SYS_CLASS_FILE | 94; -pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207; -pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55; -pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927; -pub const SYS_FEXEC: usize = SYS_CLASS_FILE | 11; -pub const SYS_FMAP: usize = SYS_CLASS_FILE | 90; -pub const SYS_FUNMAP: usize = SYS_CLASS_FILE | 91; -pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928; -pub const SYS_FRENAME: usize = SYS_CLASS_FILE | SYS_ARG_PATH | 38; -pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28; -pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100; -pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118; -pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93; -pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320; - -pub const SYS_BRK: usize = 45; -pub const SYS_CHDIR: usize = 12; -pub const SYS_CLOCK_GETTIME: usize = 265; -pub const SYS_CLONE: usize = 120; -pub const SYS_EXIT: usize = 1; -pub const SYS_FUTEX: usize = 240; -pub const SYS_GETCWD: usize = 183; -pub const SYS_GETEGID: usize = 202; -pub const SYS_GETENS: usize = 951; -pub const SYS_GETEUID: usize = 201; -pub const SYS_GETGID: usize = 200; -pub const SYS_GETNS: usize = 950; -pub const SYS_GETPID: usize = 20; -pub const SYS_GETPGID: usize = 132; -pub const SYS_GETPPID: usize = 64; -pub const SYS_GETUID: usize = 199; -pub const SYS_IOPL: usize = 110; -pub const SYS_KILL: usize = 37; -pub const SYS_MKNS: usize = 984; -pub const SYS_NANOSLEEP: usize =162; -pub const SYS_PHYSALLOC: usize =945; -pub const SYS_PHYSFREE: usize = 946; -pub const SYS_PHYSMAP: usize = 947; -pub const SYS_PHYSUNMAP: usize =948; -pub const SYS_VIRTTOPHYS: usize=949; -pub const SYS_PIPE2: usize = 331; -pub const SYS_SETPGID: usize = 57; -pub const SYS_SETREGID: usize = 204; -pub const SYS_SETRENS: usize = 952; -pub const SYS_SETREUID: usize = 203; -pub const SYS_SIGACTION: usize =67; -pub const SYS_SIGRETURN: usize =119; -pub const SYS_WAITPID: usize = 7; -pub const SYS_YIELD: usize = 158; diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs deleted file mode 100644 index 9d40a7e8bb..0000000000 --- a/src/libstd/sys/redox/thread.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::ffi::CStr; -use crate::io; -use crate::mem; -use crate::sys_common::thread::start_thread; -use crate::sys::{cvt, syscall}; -use crate::time::Duration; - -pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; - -pub struct Thread { - id: usize, -} - -// Some platforms may have pthread_t as a pointer in which case we still want -// a thread to be Send/Sync -unsafe impl Send for Thread {} -unsafe impl Sync for Thread {} - -impl Thread { - // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(_stack: usize, p: Box) -> io::Result { - let p = box p; - - let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?; - if id == 0 { - start_thread(&*p as *const _ as *mut _); - let _ = syscall::exit(0); - panic!("thread failed to exit"); - } else { - mem::forget(p); - Ok(Thread { id }) - } - } - - pub fn yield_now() { - let ret = syscall::sched_yield().expect("failed to sched_yield"); - debug_assert_eq!(ret, 0); - } - - pub fn set_name(_name: &CStr) { - - } - - pub fn sleep(dur: Duration) { - let mut secs = dur.as_secs(); - let mut nsecs = dur.subsec_nanos() as i32; - - // If we're awoken with a signal then the return value will be -1 and - // nanosleep will fill in `ts` with the remaining time. - while secs > 0 || nsecs > 0 { - let req = syscall::TimeSpec { - tv_sec: secs as i64, - tv_nsec: nsecs, - }; - secs -= req.tv_sec as u64; - let mut rem = syscall::TimeSpec::default(); - if syscall::nanosleep(&req, &mut rem).is_err() { - secs += rem.tv_sec as u64; - nsecs = rem.tv_nsec; - } else { - nsecs = 0; - } - } - } - - pub fn join(self) { - let mut status = 0; - syscall::waitpid(self.id, &mut status, 0).unwrap(); - } - - pub fn id(&self) -> usize { self.id } - - pub fn into_id(self) -> usize { - let id = self.id; - mem::forget(self); - id - } -} - -pub mod guard { - pub type Guard = !; - pub unsafe fn current() -> Option { None } - pub unsafe fn init() -> Option { None } -} diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs deleted file mode 100644 index 4bc8c4d588..0000000000 --- a/src/libstd/sys/redox/thread_local.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![allow(dead_code)] // not used on all platforms - -use crate::collections::BTreeMap; -use crate::ptr; -use crate::sync::atomic::{AtomicUsize, Ordering}; - -pub type Key = usize; - -type Dtor = unsafe extern fn(*mut u8); - -static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); - -static mut KEYS: *mut BTreeMap> = ptr::null_mut(); - -#[thread_local] -static mut LOCALS: *mut BTreeMap = ptr::null_mut(); - -unsafe fn keys() -> &'static mut BTreeMap> { - if KEYS == ptr::null_mut() { - KEYS = Box::into_raw(Box::new(BTreeMap::new())); - } - &mut *KEYS -} - -unsafe fn locals() -> &'static mut BTreeMap { - if LOCALS == ptr::null_mut() { - LOCALS = Box::into_raw(Box::new(BTreeMap::new())); - } - &mut *LOCALS -} - -#[inline] -pub unsafe fn create(dtor: Option) -> Key { - let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst); - keys().insert(key, dtor); - key -} - -#[inline] -pub unsafe fn get(key: Key) -> *mut u8 { - if let Some(&entry) = locals().get(&key) { - entry - } else { - ptr::null_mut() - } -} - -#[inline] -pub unsafe fn set(key: Key, value: *mut u8) { - locals().insert(key, value); -} - -#[inline] -pub unsafe fn destroy(key: Key) { - keys().remove(&key); -} - -#[inline] -pub fn requires_synchronized_create() -> bool { - false -} diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs deleted file mode 100644 index 081437459c..0000000000 --- a/src/libstd/sys/redox/time.rs +++ /dev/null @@ -1,207 +0,0 @@ -use crate::cmp::Ordering; -use crate::fmt; -use crate::sys::{cvt, syscall}; -use crate::time::Duration; -use crate::convert::TryInto; - -use core::hash::{Hash, Hasher}; - -const NSEC_PER_SEC: u64 = 1_000_000_000; - -#[derive(Copy, Clone)] -struct Timespec { - t: syscall::TimeSpec, -} - -impl Timespec { - fn sub_timespec(&self, other: &Timespec) -> Result { - if self >= other { - Ok(if self.t.tv_nsec >= other.t.tv_nsec { - Duration::new((self.t.tv_sec - other.t.tv_sec) as u64, - (self.t.tv_nsec - other.t.tv_nsec) as u32) - } else { - Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64, - self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - - other.t.tv_nsec as u32) - }) - } else { - match other.sub_timespec(self) { - Ok(d) => Err(d), - Err(d) => Ok(d), - } - } - } - - fn checked_add_duration(&self, other: &Duration) -> Option { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `i64` - .ok() - .and_then(|secs| self.t.tv_sec.checked_add(secs))?; - - // Nano calculations can't overflow because nanos are <1B which fit - // in a u32. - let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32; - if nsec >= NSEC_PER_SEC as u32 { - nsec -= NSEC_PER_SEC as u32; - secs = secs.checked_add(1)?; - } - Some(Timespec { - t: syscall::TimeSpec { - tv_sec: secs, - tv_nsec: nsec as i32, - }, - }) - } - - fn checked_sub_duration(&self, other: &Duration) -> Option { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `i64` - .ok() - .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; - - // Similar to above, nanos can't overflow. - let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; - if nsec < 0 { - nsec += NSEC_PER_SEC as i32; - secs = secs.checked_sub(1)?; - } - Some(Timespec { - t: syscall::TimeSpec { - tv_sec: secs, - tv_nsec: nsec as i32, - }, - }) - } -} - -impl PartialEq for Timespec { - fn eq(&self, other: &Timespec) -> bool { - self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec - } -} - -impl Eq for Timespec {} - -impl PartialOrd for Timespec { - fn partial_cmp(&self, other: &Timespec) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Timespec { - fn cmp(&self, other: &Timespec) -> Ordering { - let me = (self.t.tv_sec, self.t.tv_nsec); - let other = (other.t.tv_sec, other.t.tv_nsec); - me.cmp(&other) - } -} - -impl Hash for Timespec { - fn hash(&self, state: &mut H) { - self.t.tv_sec.hash(state); - self.t.tv_nsec.hash(state); - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Instant { - t: Timespec, -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct SystemTime { - t: Timespec, -} - -pub const UNIX_EPOCH: SystemTime = SystemTime { - t: Timespec { - t: syscall::TimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - }, -}; - -impl Instant { - pub fn now() -> Instant { - Instant { t: now(syscall::CLOCK_MONOTONIC) } - } - - pub const fn zero() -> Instant { - Instant { t: Timespec { t: syscall::TimeSpec { tv_sec: 0, tv_nsec: 0 } } } - } - - pub fn actually_monotonic() -> bool { - false - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option { - self.t.sub_timespec(&other.t).ok() - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(Instant { t: self.t.checked_add_duration(other)? }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(Instant { t: self.t.checked_sub_duration(other)? }) - } -} - -impl fmt::Debug for Instant { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Instant") - .field("tv_sec", &self.t.t.tv_sec) - .field("tv_nsec", &self.t.t.tv_nsec) - .finish() - } -} - -impl SystemTime { - pub fn now() -> SystemTime { - SystemTime { t: now(syscall::CLOCK_REALTIME) } - } - - pub fn sub_time(&self, other: &SystemTime) - -> Result { - self.t.sub_timespec(&other.t) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(SystemTime { t: self.t.checked_add_duration(other)? }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(SystemTime { t: self.t.checked_sub_duration(other)? }) - } -} - -impl From for SystemTime { - fn from(t: syscall::TimeSpec) -> SystemTime { - SystemTime { t: Timespec { t } } - } -} - -impl fmt::Debug for SystemTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SystemTime") - .field("tv_sec", &self.t.t.tv_sec) - .field("tv_nsec", &self.t.t.tv_nsec) - .finish() - } -} - -pub type clock_t = usize; - -fn now(clock: clock_t) -> Timespec { - let mut t = Timespec { - t: syscall::TimeSpec { - tv_sec: 0, - tv_nsec: 0, - } - }; - cvt(syscall::clock_gettime(clock, &mut t.t)).unwrap(); - t -} diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs index c9ff53d0a4..75dd0d429c 100644 --- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs +++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs @@ -522,7 +522,11 @@ impl Drop for User where T: UserSafe { impl, U> CoerceUnsized> for UserRef {} #[unstable(feature = "sgx_platform", issue = "56975")] -impl> Index for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe { +impl Index for UserRef<[T]> +where + [T]: UserSafe, + I: SliceIndex<[T], Output: UserSafe>, +{ type Output = UserRef; #[inline] @@ -538,7 +542,11 @@ impl> Index for UserRef<[T]> where [T]: UserSafe, I::Ou } #[unstable(feature = "sgx_platform", issue = "56975")] -impl> IndexMut for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe { +impl IndexMut for UserRef<[T]> +where + [T]: UserSafe, + I: SliceIndex<[T], Output: UserSafe>, +{ #[inline] fn index_mut(&mut self, index: I) -> &mut UserRef { unsafe { diff --git a/src/libstd/sys/sgx/io.rs b/src/libstd/sys/sgx/io.rs index 4b423a5cbc..976e122463 100644 --- a/src/libstd/sys/sgx/io.rs +++ b/src/libstd/sys/sgx/io.rs @@ -1,3 +1,5 @@ +use crate::mem; + pub struct IoSlice<'a>(&'a [u8]); impl<'a> IoSlice<'a> { @@ -6,6 +8,11 @@ impl<'a> IoSlice<'a> { IoSlice(buf) } + #[inline] + pub fn advance(&mut self, n: usize) { + self.0 = &self.0[n..] + } + #[inline] pub fn as_slice(&self) -> &[u8] { self.0 @@ -20,6 +27,13 @@ impl<'a> IoSliceMut<'a> { IoSliceMut(buf) } + #[inline] + pub fn advance(&mut self, n: usize) { + let slice = mem::replace(&mut self.0, &mut []); + let (_, remaining) = slice.split_at_mut(n); + self.0 = remaining; + } + #[inline] pub fn as_slice(&self) -> &[u8] { self.0 diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index 01f5536ed7..601957acd5 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -140,7 +140,7 @@ pub unsafe extern "C" fn __rust_abort() { pub fn hashmap_random_keys() -> (u64, u64) { fn rdrand64() -> u64 { unsafe { - let mut ret: u64 = crate::mem::uninitialized(); + let mut ret: u64 = 0; for _ in 0..10 { if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 { return ret; diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs index 8e8f5017da..f47dc92d2d 100644 --- a/src/libstd/sys/unix/alloc.rs +++ b/src/libstd/sys/unix/alloc.rs @@ -6,6 +6,10 @@ use crate::alloc::{GlobalAlloc, Layout, System}; unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // jemalloc provides alignment less than MIN_ALIGN for small allocations. + // So only rely on MIN_ALIGN if size >= align. + // Also see and + // . if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { libc::malloc(layout.size()) as *mut u8 } else { @@ -21,10 +25,11 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + // See the comment above in `alloc` for why this check looks the way it does. if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { libc::calloc(layout.size(), 1) as *mut u8 } else { - let ptr = self.alloc(layout.clone()); + let ptr = self.alloc(layout); if !ptr.is_null() { ptr::write_bytes(ptr, 0, layout.size()); } @@ -80,7 +85,10 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); - let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); + // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. + // Since these are all powers of 2, we can just use max. + let align = layout.align().max(crate::mem::size_of::()); + let ret = libc::posix_memalign(&mut out, align, layout.size()); if ret != 0 { ptr::null_mut() } else { diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 3b4de56f2c..288e9b5c12 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -56,7 +56,8 @@ impl DoubleEndedIterator for Args { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] mod imp { use crate::os::unix::prelude::*; use crate::ptr; diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 4201de794b..0a93fbf8ea 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -31,14 +31,16 @@ impl Condvar { target_os = "ios", target_os = "l4re", target_os = "android", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] pub unsafe fn init(&mut self) {} #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "l4re", target_os = "android", - target_os = "hermit")))] + target_os = "hermit", + target_os = "redox")))] pub unsafe fn init(&mut self) { use crate::mem::MaybeUninit; let mut attr = MaybeUninit::::uninit(); diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index 891013406a..d724eeb8b3 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -162,3 +162,14 @@ pub mod os { pub const EXE_SUFFIX: &str = ""; pub const EXE_EXTENSION: &str = ""; } + +#[cfg(target_os = "redox")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "redox"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 41090caee8..42edd5dbbe 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -198,7 +198,7 @@ impl SocketAddr { } } - fn address<'a>(&'a self) -> AddressKind<'a> { + fn address(&self) -> AddressKind<'_> { let len = self.len as usize - sun_path_offset(&self.addr); let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; @@ -894,7 +894,7 @@ impl UnixListener { /// } /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] - pub fn incoming<'a>(&'a self) -> Incoming<'a> { + pub fn incoming(&self) -> Incoming<'_> { Incoming { listener: self } } } diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs index c34c2e6e78..952ba40ee8 100644 --- a/src/libstd/sys/unix/fast_thread_local.rs +++ b/src/libstd/sys/unix/fast_thread_local.rs @@ -10,7 +10,7 @@ // fallback implementation to use as well. // // Due to rust-lang/rust#18804, make sure this is not generic! -#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit"))] +#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox"))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) { use crate::mem; use crate::sys_common::thread_local::register_dtor_fallback; diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 6d23963e14..ac43526b50 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -175,7 +175,9 @@ impl FileDesc { target_os = "emscripten", target_os = "fuchsia", target_os = "l4re", - target_os = "haiku")))] + target_os = "linux", + target_os = "haiku", + target_os = "redox")))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { cvt(libc::ioctl(self.fd, libc::FIOCLEX))?; @@ -187,7 +189,9 @@ impl FileDesc { target_os = "emscripten", target_os = "fuchsia", target_os = "l4re", - target_os = "haiku"))] + target_os = "linux", + target_os = "haiku", + target_os = "redox"))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?; diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index cc1f0790d4..3b1eb86b84 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -33,7 +33,8 @@ use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off_t as off64_t, target_os = "emscripten", target_os = "solaris", target_os = "l4re", - target_os = "fuchsia")))] + target_os = "fuchsia", + target_os = "redox")))] use libc::{readdir_r as readdir64_r}; pub use crate::sys_common::fs::remove_dir_all; @@ -69,7 +70,7 @@ pub struct DirEntry { // on Solaris and Fuchsia because a) it uses a zero-length // array to store the name, b) its lifetime between readdir // calls is not guaranteed. - #[cfg(any(target_os = "solaris", target_os = "fuchsia"))] + #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] name: Box<[u8]> } @@ -216,7 +217,7 @@ impl fmt::Debug for ReadDir { impl Iterator for ReadDir { type Item = io::Result; - #[cfg(any(target_os = "solaris", target_os = "fuchsia"))] + #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] fn next(&mut self) -> Option> { use crate::slice; @@ -253,7 +254,7 @@ impl Iterator for ReadDir { } } - #[cfg(not(any(target_os = "solaris", target_os = "fuchsia")))] + #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))] fn next(&mut self) -> Option> { if self.end_of_stream { return None; @@ -346,7 +347,8 @@ impl DirEntry { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 } @@ -384,7 +386,8 @@ impl DirEntry { } } #[cfg(any(target_os = "solaris", - target_os = "fuchsia"))] + target_os = "fuchsia", + target_os = "redox"))] fn name_bytes(&self) -> &[u8] { &*self.name } @@ -554,9 +557,15 @@ impl File { return crate::sys::android::ftruncate64(self.0.raw(), size); #[cfg(not(target_os = "android"))] - return cvt_r(|| unsafe { - ftruncate64(self.0.raw(), size as off64_t) - }).map(|_| ()); + { + use crate::convert::TryInto; + let size: off64_t = size + .try_into() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?; + cvt_r(|| unsafe { + ftruncate64(self.0.raw(), size) + }).map(|_| ()) + } } pub fn read(&self, buf: &mut [u8]) -> io::Result { diff --git a/src/libstd/sys/unix/io.rs b/src/libstd/sys/unix/io.rs index 72954ff20e..a3a7291917 100644 --- a/src/libstd/sys/unix/io.rs +++ b/src/libstd/sys/unix/io.rs @@ -21,6 +21,18 @@ impl<'a> IoSlice<'a> { } } + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.iov_len < n { + panic!("advancing IoSlice beyond its length"); + } + + unsafe { + self.vec.iov_len -= n; + self.vec.iov_base = self.vec.iov_base.add(n); + } + } + #[inline] pub fn as_slice(&self) -> &[u8] { unsafe { @@ -29,6 +41,7 @@ impl<'a> IoSlice<'a> { } } +#[repr(transparent)] pub struct IoSliceMut<'a> { vec: iovec, _p: PhantomData<&'a mut [u8]>, @@ -46,6 +59,18 @@ impl<'a> IoSliceMut<'a> { } } + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.iov_len < n { + panic!("advancing IoSliceMut beyond its length"); + } + + unsafe { + self.vec.iov_len -= n; + self.vec.iov_base = self.vec.iov_base.add(n); + } + } + #[inline] pub fn as_slice(&self) -> &[u8] { unsafe { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 821623db27..b1f7aac8b4 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -17,6 +17,7 @@ use crate::io::ErrorKind; #[cfg(all(not(rustdoc), target_os = "fuchsia"))] pub use crate::os::fuchsia as platform; #[cfg(all(not(rustdoc), target_os = "l4re"))] pub use crate::os::linux as platform; #[cfg(all(not(rustdoc), target_os = "hermit"))] pub use crate::os::hermit as platform; +#[cfg(all(not(rustdoc), target_os = "redox"))] pub use crate::os::redox as platform; pub use self::rand::hashmap_random_keys; pub use libc::strlen; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index dad19eabf7..169bb57ef7 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -25,6 +25,13 @@ use libc::{c_int, c_char, c_void}; const TMPBUF_SZ: usize = 128; +cfg_if::cfg_if! { + if #[cfg(target_os = "redox")] { + const PATH_SEPARATOR: u8 = b';'; + } else { + const PATH_SEPARATOR: u8 = b':'; + } +} extern { #[cfg(not(target_os = "dragonfly"))] @@ -37,6 +44,7 @@ extern { target_os = "openbsd", target_os = "android", target_os = "hermit", + target_os = "redox", target_env = "newlib"), link_name = "__errno")] #[cfg_attr(target_os = "solaris", link_name = "___errno")] @@ -155,10 +163,10 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> { fn bytes_to_path(b: &[u8]) -> PathBuf { PathBuf::from(::from_bytes(b)) } - fn is_colon(b: &u8) -> bool { *b == b':' } + fn is_separator(b: &u8) -> bool { *b == PATH_SEPARATOR } let unparsed = unparsed.as_bytes(); SplitPaths { - iter: unparsed.split(is_colon as fn(&u8) -> bool) + iter: unparsed.split(is_separator as fn(&u8) -> bool) .map(bytes_to_path as fn(&[u8]) -> PathBuf) } } @@ -176,12 +184,11 @@ pub fn join_paths(paths: I) -> Result where I: Iterator, T: AsRef { let mut joined = Vec::new(); - let sep = b':'; for (i, path) in paths.enumerate() { let path = path.as_ref().as_bytes(); - if i > 0 { joined.push(sep) } - if path.contains(&sep) { + if i > 0 { joined.push(PATH_SEPARATOR) } + if path.contains(&PATH_SEPARATOR) { return Err(JoinPathsError) } joined.extend_from_slice(path); @@ -191,7 +198,7 @@ pub fn join_paths(paths: I) -> Result impl fmt::Display for JoinPathsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "path segment contains separator `:`".fmt(f) + write!(f, "path segment contains separator `{}`", PATH_SEPARATOR) } } @@ -382,6 +389,11 @@ pub fn current_exe() -> io::Result { } } +#[cfg(target_os = "redox")] +pub fn current_exe() -> io::Result { + crate::fs::read_to_string("sys:exe").map(PathBuf::from) +} + #[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))] pub fn current_exe() -> io::Result { use crate::io::ErrorKind; @@ -511,11 +523,13 @@ pub fn home_dir() -> Option { #[cfg(any(target_os = "android", target_os = "ios", - target_os = "emscripten"))] + target_os = "emscripten", + target_os = "redox"))] unsafe fn fallback() -> Option { None } #[cfg(not(any(target_os = "android", target_os = "ios", - target_os = "emscripten")))] + target_os = "emscripten", + target_os = "redox")))] unsafe fn fallback() -> Option { let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { n if n < 0 => 512 as usize, diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index d36e94df63..029f4216b7 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -26,7 +26,8 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { target_os = "freebsd", target_os = "linux", target_os = "netbsd", - target_os = "openbsd")) && + target_os = "openbsd", + target_os = "redox")) && !INVALID.load(Ordering::SeqCst) { diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 3ff4f194cd..6bb20bbe08 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -12,6 +12,14 @@ use crate::collections::BTreeMap; use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; +cfg_if::cfg_if! { + if #[cfg(target_os = "redox")] { + const DEV_NULL: &'static str = "null:\0"; + } else { + const DEV_NULL: &'static str = "/dev/null\0"; + } +} + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// @@ -298,7 +306,7 @@ impl Stdio { opts.read(readable); opts.write(!readable); let path = unsafe { - CStr::from_ptr("/dev/null\0".as_ptr() as *const _) + CStr::from_ptr(DEV_NULL.as_ptr() as *const _) }; let fd = File::open_c(&path, &opts)?; Ok((ChildStdio::Owned(fd.into_fd()), None)) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index be38a1334e..327d82e60c 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -183,14 +183,17 @@ impl Command { cvt(libc::setgid(u as gid_t))?; } if let Some(u) = self.get_uid() { - // When dropping privileges from root, the `setgroups` call - // will remove any extraneous groups. If we don't call this, - // then even though our uid has dropped, we may still have - // groups that enable us to do super-user things. This will - // fail if we aren't root, so don't bother checking the - // return value, this is just done as an optimistic - // privilege dropping function. - let _ = libc::setgroups(0, ptr::null()); + //FIXME: Redox kernel does not support setgroups yet + if cfg!(not(target_os = "redox")) { + // When dropping privileges from root, the `setgroups` call + // will remove any extraneous groups. If we don't call this, + // then even though our uid has dropped, we may still have + // groups that enable us to do super-user things. This will + // fail if we aren't root, so don't bother checking the + // return value, this is just done as an optimistic + // privilege dropping function. + let _ = libc::setgroups(0, ptr::null()); + } cvt(libc::setuid(u as uid_t))?; } @@ -277,7 +280,7 @@ impl Command { if self.get_gid().is_some() || self.get_uid().is_some() || self.env_saw_path() || - self.get_closures().len() != 0 { + !self.get_closures().is_empty() { return Ok(None) } diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index 71c62461ee..c5be176330 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -15,7 +15,8 @@ pub fn hashmap_random_keys() -> (u64, u64) { not(target_os = "ios"), not(target_os = "openbsd"), not(target_os = "freebsd"), - not(target_os = "fuchsia")))] + not(target_os = "fuchsia"), + not(target_os = "redox")))] mod imp { use crate::fs::File; use crate::io::Read; @@ -174,3 +175,15 @@ mod imp { unsafe { zx_cprng_draw(v.as_mut_ptr(), v.len()) } } } + +#[cfg(target_os = "redox")] +mod imp { + use crate::fs::File; + use crate::io::Read; + + pub fn fill_bytes(v: &mut [u8]) { + // Open rand:, read from it, and close it again. + let mut file = File::open("rand:").expect("failed to open rand:"); + file.read_exact(v).expect("failed to read rand:") + } +} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index f4a1783ce8..988881e359 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -122,12 +122,26 @@ impl Thread { name.as_ptr() as *mut libc::c_void); } } + + #[cfg(target_os = "solaris")] + pub fn set_name(name: &CStr) { + weak! { + fn pthread_setname_np( + libc::pthread_t, *const libc::c_char + ) -> libc::c_int + } + + if let Some(f) = pthread_setname_np.get() { + unsafe { f(libc::pthread_self(), name.as_ptr()); } + } + } + #[cfg(any(target_env = "newlib", - target_os = "solaris", target_os = "haiku", target_os = "l4re", target_os = "emscripten", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] pub fn set_name(_name: &CStr) { // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name. } diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index e21c32cd91..02f377d55c 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -137,9 +137,21 @@ mod inner { t: Timespec::zero(), }; + #[repr(C)] + #[derive(Copy, Clone)] + struct mach_timebase_info { + numer: u32, + denom: u32, + } + type mach_timebase_info_t = *mut mach_timebase_info; + type kern_return_t = libc::c_int; + impl Instant { pub fn now() -> Instant { - Instant { t: unsafe { libc::mach_absolute_time() } } + extern "C" { + fn mach_absolute_time() -> u64; + } + Instant { t: unsafe { mach_absolute_time() } } } pub const fn zero() -> Instant { @@ -230,8 +242,8 @@ mod inner { Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64)) } - fn info() -> libc::mach_timebase_info { - static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info { + fn info() -> mach_timebase_info { + static mut INFO: mach_timebase_info = mach_timebase_info { numer: 0, denom: 0, }; @@ -245,7 +257,12 @@ mod inner { // ... otherwise learn for ourselves ... let mut info = mem::zeroed(); - libc::mach_timebase_info(&mut info); + extern "C" { + fn mach_timebase_info(info: mach_timebase_info_t) + -> kern_return_t; + } + + mach_timebase_info(&mut info); // ... and attempt to be the one thread that stores it globally for // all other threads diff --git a/src/libstd/sys/vxworks/alloc.rs b/src/libstd/sys/vxworks/alloc.rs new file mode 100644 index 0000000000..e0c560b921 --- /dev/null +++ b/src/libstd/sys/vxworks/alloc.rs @@ -0,0 +1,53 @@ +use crate::ptr; +use crate::sys_common::alloc::{MIN_ALIGN, realloc_fallback}; +use crate::alloc::{GlobalAlloc, Layout, System}; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::malloc(layout.size()) as *mut u8 + } else { + aligned_malloc(&layout) + } + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::calloc(layout.size(), 1) as *mut u8 + } else { + let ptr = self.alloc(layout.clone()); + if !ptr.is_null() { + ptr::write_bytes(ptr, 0, layout.size()); + } + ptr + } + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + libc::free(ptr as *mut libc::c_void) + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= new_size { + libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 + } else { + realloc_fallback(self, ptr, layout, new_size) + } + } +} + +#[inline] +unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { + let mut out = ptr::null_mut(); + let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); + if ret != 0 { + ptr::null_mut() + } else { + out as *mut u8 + } +} diff --git a/src/libstd/sys/redox/args.rs b/src/libstd/sys/vxworks/args.rs similarity index 58% rename from src/libstd/sys/redox/args.rs rename to src/libstd/sys/vxworks/args.rs index f9e2f5ba31..11c3cb7881 100644 --- a/src/libstd/sys/redox/args.rs +++ b/src/libstd/sys/vxworks/args.rs @@ -1,10 +1,4 @@ -//! Global initialization and retrieval of command line arguments. -//! -//! On some platforms these are stored during runtime startup, -//! and on some they are retrieved from the system on demand. - #![allow(dead_code)] // runtime init functions not used during testing - use crate::ffi::OsString; use crate::marker::PhantomData; use crate::vec; @@ -46,51 +40,46 @@ impl DoubleEndedIterator for Args { } mod imp { - use crate::os::unix::prelude::*; - use crate::mem; + use crate::ptr; use crate::ffi::{CStr, OsString}; use crate::marker::PhantomData; + use libc; use super::Args; use crate::sys_common::mutex::Mutex; - static mut GLOBAL_ARGS_PTR: usize = 0; + static mut ARGC: isize = 0; + static mut ARGV: *const *const u8 = ptr::null(); static LOCK: Mutex = Mutex::new(); pub unsafe fn init(argc: isize, argv: *const *const u8) { - let args = (0..argc).map(|i| { - CStr::from_ptr(*argv.offset(i) as *const libc::c_char).to_bytes().to_vec() - }).collect(); - let _guard = LOCK.lock(); - let ptr = get_global_ptr(); - assert!((*ptr).is_none()); - (*ptr) = Some(box args); + ARGC = argc; + ARGV = argv; } pub unsafe fn cleanup() { let _guard = LOCK.lock(); - *get_global_ptr() = None; + ARGC = 0; + ARGV = ptr::null(); } pub fn args() -> Args { - let bytes = clone().unwrap_or_default(); - let v: Vec = bytes.into_iter().map(|v| { - OsStringExt::from_vec(v) - }).collect(); - Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData } + Args { + iter: clone().into_iter(), + _dont_send_or_sync_me: PhantomData + } } - fn clone() -> Option>> { + fn clone() -> Vec { unsafe { let _guard = LOCK.lock(); - let ptr = get_global_ptr(); - (*ptr).as_ref().map(|s| (**s).clone()) + let ret = (0..ARGC).map(|i| { + let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char); + use crate::sys::vxworks::ext::ffi::OsStringExt; + OsStringExt::from_vec(cstr.to_bytes().to_vec()) + }).collect(); + return ret } } - - unsafe fn get_global_ptr() -> *mut Option>>> { - mem::transmute(&GLOBAL_ARGS_PTR) - } - } diff --git a/src/libstd/sys/vxworks/backtrace/mod.rs b/src/libstd/sys/vxworks/backtrace/mod.rs new file mode 100644 index 0000000000..0887e5a4df --- /dev/null +++ b/src/libstd/sys/vxworks/backtrace/mod.rs @@ -0,0 +1,110 @@ +/// Backtrace support built on libgcc with some extra OS-specific support +/// +/// Some methods of getting a backtrace: +/// +/// * The backtrace() functions on unix. It turns out this doesn't work very +/// well for green threads on macOS, and the address to symbol portion of it +/// suffers problems that are described below. +/// +/// * Using libunwind. This is more difficult than it sounds because libunwind +/// isn't installed everywhere by default. It's also a bit of a hefty library, +/// so possibly not the best option. When testing, libunwind was excellent at +/// getting both accurate backtraces and accurate symbols across platforms. +/// This route was not chosen in favor of the next option, however. +/// +/// * We're already using libgcc_s for exceptions in rust (triggering thread +/// unwinding and running destructors on the stack), and it turns out that it +/// conveniently comes with a function that also gives us a backtrace. All of +/// these functions look like _Unwind_*, but it's not quite the full +/// repertoire of the libunwind API. Due to it already being in use, this was +/// the chosen route of getting a backtrace. +/// +/// After choosing libgcc_s for backtraces, the sad part is that it will only +/// give us a stack trace of instruction pointers. Thankfully these instruction +/// pointers are accurate (they work for green and native threads), but it's +/// then up to us again to figure out how to translate these addresses to +/// symbols. As with before, we have a few options. Before, that, a little bit +/// of an interlude about symbols. This is my very limited knowledge about +/// symbol tables, and this information is likely slightly wrong, but the +/// general idea should be correct. +/// +/// When talking about symbols, it's helpful to know a few things about where +/// symbols are located. Some symbols are located in the dynamic symbol table +/// of the executable which in theory means that they're available for dynamic +/// linking and lookup. Other symbols end up only in the local symbol table of +/// the file. This loosely corresponds to pub and priv functions in Rust. +/// +/// Armed with this knowledge, we know that our solution for address to symbol +/// translation will need to consult both the local and dynamic symbol tables. +/// With that in mind, here's our options of translating an address to +/// a symbol. +/// +/// * Use dladdr(). The original backtrace()-based idea actually uses dladdr() +/// behind the scenes to translate, and this is why backtrace() was not used. +/// Conveniently, this method works fantastically on macOS. It appears dladdr() +/// uses magic to consult the local symbol table, or we're putting everything +/// in the dynamic symbol table anyway. Regardless, for macOS, this is the +/// method used for translation. It's provided by the system and easy to do.o +/// +/// Sadly, all other systems have a dladdr() implementation that does not +/// consult the local symbol table. This means that most functions are blank +/// because they don't have symbols. This means that we need another solution. +/// +/// * Use unw_get_proc_name(). This is part of the libunwind api (not the +/// libgcc_s version of the libunwind api), but involves taking a dependency +/// to libunwind. We may pursue this route in the future if we bundle +/// libunwind, but libunwind was unwieldy enough that it was not chosen at +/// this time to provide this functionality. +/// +/// * Shell out to a utility like `readelf`. Crazy though it may sound, it's a +/// semi-reasonable solution. The stdlib already knows how to spawn processes, +/// so in theory it could invoke readelf, parse the output, and consult the +/// local/dynamic symbol tables from there. This ended up not getting chosen +/// due to the craziness of the idea plus the advent of the next option. +/// +/// * Use `libbacktrace`. It turns out that this is a small library bundled in +/// the gcc repository which provides backtrace and symbol translation +/// functionality. All we really need from it is the backtrace functionality, +/// and we only really need this on everything that's not macOS, so this is the +/// chosen route for now. +/// +/// In summary, the current situation uses libgcc_s to get a trace of stack +/// pointers, and we use dladdr() or libbacktrace to translate these addresses +/// to symbols. This is a bit of a hokey implementation as-is, but it works for +/// all unix platforms we support right now, so it at least gets the job done. + +pub use self::tracing::unwind_backtrace; +pub use self::printing::{foreach_symbol_fileline, resolve_symname}; + +// tracing impls: +mod tracing; +// symbol resolvers: +mod printing; + +#[cfg(not(target_os = "emscripten"))] +pub mod gnu { + use crate::io; + use crate::fs; + + use libc::c_char; + + #[cfg(not(any(target_os = "macos", target_os = "ios")))] + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) + } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + use crate::env; + use crate::os::unix::ffi::OsStrExt; + + let filename = env::current_exe()?; + let file = fs::File::open(&filename)?; + let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter() + .map(|&x| x as c_char).collect(); + filename_cstr.push(0); // Null terminate + Ok((filename_cstr, file)) + } +} + +pub struct BacktraceContext; diff --git a/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs b/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs new file mode 100644 index 0000000000..202164dd3c --- /dev/null +++ b/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs @@ -0,0 +1,35 @@ +use crate::io; +use crate::intrinsics; +use crate::ffi::CStr; +use crate::sys::backtrace::BacktraceContext; +use crate::sys_common::backtrace::Frame; + +pub fn resolve_symname(frame: Frame, + callback: F, + _: &BacktraceContext) -> io::Result<()> + where F: FnOnce(Option<&str>) -> io::Result<()> +{ + unsafe { + let mut info: Dl_info = intrinsics::init(); + let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 || + info.dli_sname.is_null() { + None + } else { + CStr::from_ptr(info.dli_sname).to_str().ok() + }; + callback(symname) + } +} + +#[repr(C)] +struct Dl_info { + dli_fname: *const libc::c_char, + dli_fbase: *mut libc::c_void, + dli_sname: *const libc::c_char, + dli_saddr: *mut libc::c_void, +} + +extern { + #[ link_name = "_rtld_dladdr" ] + fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int; +} diff --git a/src/libstd/sys/vxworks/backtrace/printing/mod.rs b/src/libstd/sys/vxworks/backtrace/printing/mod.rs new file mode 100644 index 0000000000..d090caede4 --- /dev/null +++ b/src/libstd/sys/vxworks/backtrace/printing/mod.rs @@ -0,0 +1,33 @@ +mod dladdr; + +use crate::sys::backtrace::BacktraceContext; +use crate::sys_common::backtrace::Frame; +use crate::io; + +#[cfg(target_os = "emscripten")] +pub use self::dladdr::resolve_symname; + +#[cfg(target_os = "emscripten")] +pub fn foreach_symbol_fileline(_: Frame, _: F, _: &BacktraceContext) -> io::Result +where + F: FnMut(&[u8], u32) -> io::Result<()> +{ + Ok(false) +} + +#[cfg(not(target_os = "emscripten"))] +pub use crate::sys_common::gnu::libbacktrace::foreach_symbol_fileline; + +#[cfg(not(target_os = "emscripten"))] +pub fn resolve_symname(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()> +where + F: FnOnce(Option<&str>) -> io::Result<()> +{ + crate::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| { + if symname.is_some() { + callback(symname) + } else { + dladdr::resolve_symname(frame, callback, bc) + } + }, bc) +} diff --git a/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs new file mode 100644 index 0000000000..a628d107ad --- /dev/null +++ b/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs @@ -0,0 +1,39 @@ +/// As always - iOS on arm uses SjLj exceptions and +/// _Unwind_Backtrace is even not available there. Still, +/// backtraces could be extracted using a backtrace function, +/// which thanks god is public +/// +/// As mentioned in a huge comment block in `super::super`, backtrace +/// doesn't play well with green threads, so while it is extremely nice and +/// simple to use it should be used only on iOS devices as the only viable +/// option. + +use crate::io; +use crate::ptr; +use crate::sys::backtrace::BacktraceContext; +use crate::sys_common::backtrace::Frame; + +#[inline(never)] // if we know this is a function call, we can skip it when + // tracing +pub fn unwind_backtrace(frames: &mut [Frame]) + -> io::Result<(usize, BacktraceContext)> +{ + const FRAME_LEN: usize = 100; + assert!(FRAME_LEN >= frames.len()); + let mut raw_frames = [ptr::null_mut(); FRAME_LEN]; + let nb_frames = unsafe { + backtrace(raw_frames.as_mut_ptr(), raw_frames.len() as libc::c_int) + } as usize; + for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) { + *to = Frame { + exact_position: *from as *mut u8, + symbol_addr: *from as *mut u8, + inline_context: 0, + }; + } + Ok((nb_frames as usize, BacktraceContext)) +} + +extern { + fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int; +} diff --git a/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs b/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs new file mode 100644 index 0000000000..e6379132ba --- /dev/null +++ b/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs @@ -0,0 +1,99 @@ +use crate::error::Error; +use crate::fmt; +use crate::io; +use crate::sys::backtrace::BacktraceContext; +use crate::sys_common::backtrace::Frame; + +use unwind as uw; + +struct Context<'a> { + idx: usize, + frames: &'a mut [Frame], +} + +#[derive(Debug)] +struct UnwindError(uw::_Unwind_Reason_Code); + +impl Error for UnwindError { + fn description(&self) -> &'static str { + "unexpected return value while unwinding" + } +} + +impl fmt::Display for UnwindError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}: {:?}", self.description(), self.0) + } +} + +#[inline(never)] // if we know this is a function call, we can skip it when + // tracing +pub fn unwind_backtrace(frames: &mut [Frame]) + -> io::Result<(usize, BacktraceContext)> +{ + let mut cx = Context { + idx: 0, + frames, + }; + let result_unwind = unsafe { + uw::_Unwind_Backtrace(trace_fn, + &mut cx as *mut Context<'_> + as *mut libc::c_void) + }; + // See libunwind:src/unwind/Backtrace.c for the return values. + // No, there is no doc. + match result_unwind { + // These return codes seem to be benign and need to be ignored for backtraces + // to show up properly on all tested platforms. + uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => { + Ok((cx.idx, BacktraceContext)) + } + _ => { + Err(io::Error::new(io::ErrorKind::Other, + UnwindError(result_unwind))) + } + } +} + +extern fn trace_fn(ctx: *mut uw::_Unwind_Context, + arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code { + let cx = unsafe { &mut *(arg as *mut Context<'_>) }; + if cx.idx >= cx.frames.len() { + return uw::_URC_NORMAL_STOP; + } + + let mut ip_before_insn = 0; + let mut ip = unsafe { + uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void + }; + if !ip.is_null() && ip_before_insn == 0 { + // this is a non-signaling frame, so `ip` refers to the address + // after the calling instruction. account for that. + ip = (ip as usize - 1) as *mut _; + } + + // dladdr() on osx gets whiny when we use FindEnclosingFunction, and + // it appears to work fine without it, so we only use + // FindEnclosingFunction on non-osx platforms. In doing so, we get a + // slightly more accurate stack trace in the process. + // + // This is often because panic involves the last instruction of a + // function being "call std::rt::begin_unwind", with no ret + // instructions after it. This means that the return instruction + // pointer points *outside* of the calling function, and by + // unwinding it we go back to the original function. + let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") { + ip + } else { + unsafe { uw::_Unwind_FindEnclosingFunction(ip) } + }; + + cx.frames[cx.idx] = Frame { + symbol_addr: symaddr as *mut u8, + exact_position: ip as *mut u8, + inline_context: 0, + }; + cx.idx += 1; + + uw::_URC_NO_REASON +} diff --git a/src/libstd/sys/vxworks/backtrace/tracing/mod.rs b/src/libstd/sys/vxworks/backtrace/tracing/mod.rs new file mode 100644 index 0000000000..11863e6454 --- /dev/null +++ b/src/libstd/sys/vxworks/backtrace/tracing/mod.rs @@ -0,0 +1,8 @@ +pub use self::imp::*; + +#[cfg(not(all(target_os = "ios", target_arch = "arm")))] +#[path = "gcc_s.rs"] +mod imp; +#[cfg(all(target_os = "ios", target_arch = "arm"))] +#[path = "backtrace_fn.rs"] +mod imp; diff --git a/src/libstd/sys/redox/cmath.rs b/src/libstd/sys/vxworks/cmath.rs similarity index 100% rename from src/libstd/sys/redox/cmath.rs rename to src/libstd/sys/vxworks/cmath.rs diff --git a/src/libstd/sys/vxworks/condvar.rs b/src/libstd/sys/vxworks/condvar.rs new file mode 100644 index 0000000000..783c3eb7c7 --- /dev/null +++ b/src/libstd/sys/vxworks/condvar.rs @@ -0,0 +1,96 @@ +use crate::cell::UnsafeCell; +use crate::sys::mutex::{self, Mutex}; +use crate::time::Duration; + +pub struct Condvar { inner: UnsafeCell } + +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + +const TIMESPEC_MAX: libc::timespec = libc::timespec { + tv_sec: ::max_value(), + tv_nsec: 1_000_000_000 - 1, +}; + +fn saturating_cast_to_time_t(value: u64) -> libc::time_t { + if value > ::max_value() as u64 { + ::max_value() + } else { + value as libc::time_t + } +} + +impl Condvar { + pub const fn new() -> Condvar { + // Might be moved and address is changing it is better to avoid + // initialization of potentially opaque OS data before it landed + Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) } + } + + pub unsafe fn init(&mut self) { + use crate::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + let r = libc::pthread_condattr_init(attr.as_mut_ptr()); + assert_eq!(r, 0); + let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC); + assert_eq!(r, 0); + let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr()); + assert_eq!(r, 0); + let r = libc::pthread_condattr_destroy(attr.as_mut_ptr()); + assert_eq!(r, 0); + } + + #[inline] + pub unsafe fn notify_one(&self) { + let r = libc::pthread_cond_signal(self.inner.get()); + debug_assert_eq!(r, 0); + } + + #[inline] + pub unsafe fn notify_all(&self) { + let r = libc::pthread_cond_broadcast(self.inner.get()); + debug_assert_eq!(r, 0); + } + + #[inline] + pub unsafe fn wait(&self, mutex: &Mutex) { + let r = libc::pthread_cond_wait(self.inner.get(), mutex::raw(mutex)); + debug_assert_eq!(r, 0); + } + + // This implementation is used on systems that support pthread_condattr_setclock + // where we configure condition variable to use monotonic clock (instead of + // default system clock). This approach avoids all problems that result + // from changes made to the system time. + pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { + use crate::mem; + + let mut now: libc::timespec = mem::zeroed(); + let r = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut now); + assert_eq!(r, 0); + + // Nanosecond calculations can't overflow because both values are below 1e9. + let nsec = dur.subsec_nanos() + now.tv_nsec as u32; + + let sec = saturating_cast_to_time_t(dur.as_secs()) + .checked_add((nsec / 1_000_000_000) as libc::time_t) + .and_then(|s| s.checked_add(now.tv_sec)); + let nsec = nsec % 1_000_000_000; + + let timeout = sec.map(|s| { + libc::timespec { tv_sec: s, tv_nsec: nsec as _} + }).unwrap_or(TIMESPEC_MAX); + + let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), + &timeout); + assert!(r == libc::ETIMEDOUT || r == 0); + r == 0 + } + + + #[inline] + pub unsafe fn destroy(&self) { + let r = libc::pthread_cond_destroy(self.inner.get()); + debug_assert_eq!(r, 0); + } +} diff --git a/src/libstd/sys/redox/env.rs b/src/libstd/sys/vxworks/env.rs similarity index 73% rename from src/libstd/sys/redox/env.rs rename to src/libstd/sys/vxworks/env.rs index bcc0e126b9..fe1aedd585 100644 --- a/src/libstd/sys/redox/env.rs +++ b/src/libstd/sys/vxworks/env.rs @@ -1,6 +1,6 @@ pub mod os { - pub const FAMILY: &str = "redox"; - pub const OS: &str = "redox"; + pub const FAMILY: &str = "vxworks"; + pub const OS: &str = "vxworks"; pub const DLL_PREFIX: &str = "lib"; pub const DLL_SUFFIX: &str = ".so"; pub const DLL_EXTENSION: &str = "so"; diff --git a/src/libstd/sys/redox/ext/ffi.rs b/src/libstd/sys/vxworks/ext/ffi.rs similarity index 83% rename from src/libstd/sys/redox/ext/ffi.rs rename to src/libstd/sys/vxworks/ext/ffi.rs index 974d7b82c1..76b34a6b5d 100644 --- a/src/libstd/sys/redox/ext/ffi.rs +++ b/src/libstd/sys/vxworks/ext/ffi.rs @@ -1,10 +1,10 @@ -//! Redox-specific extension to the primitives in the `std::ffi` module. +//! Unix-specific extension to the primitives in the `std::ffi` module //! //! # Examples //! //! ``` //! use std::ffi::OsString; -//! use std::os::redox::ffi::OsStringExt; +//! use std::os::unix::ffi::OsStringExt; //! //! let bytes = b"foo".to_vec(); //! @@ -19,7 +19,7 @@ //! //! ``` //! use std::ffi::OsStr; -//! use std::os::redox::ffi::OsStrExt; +//! use std::os::unix::ffi::OsStrExt; //! //! let bytes = b"foo"; //! diff --git a/src/libstd/sys/vxworks/ext/fs.rs b/src/libstd/sys/vxworks/ext/fs.rs new file mode 100644 index 0000000000..7ab7f2a1a2 --- /dev/null +++ b/src/libstd/sys/vxworks/ext/fs.rs @@ -0,0 +1,801 @@ +#![stable(feature = "rust1", since = "1.0.0")] + +use crate::fs::{self, Permissions}; +use crate::io; +use libc; +use crate::path::Path; +use crate::sys; +use crate::sys_common::{FromInner, AsInner, AsInnerMut}; +use crate::sys::platform::fs::MetadataExt as UnixMetadataExt; + +/// Unix-specific extensions to [`File`]. +/// +/// [`File`]: ../../../../std/fs/struct.File.html +#[stable(feature = "file_offset", since = "1.15.0")] +pub trait FileExt { + /// Reads a number of bytes starting from a given offset. + /// + /// Returns the number of bytes read. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// Note that similar to [`File::read`], it is not an error to return with a + /// short read. + /// + /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read + /// + /// # Examples + /// + /// ```no_run + /// use std::io; + /// use std::fs::File; + /// use std::os::unix::prelude::FileExt; + /// + /// fn main() -> io::Result<()> { + /// let mut buf = [0u8; 8]; + /// let file = File::open("foo.txt")?; + /// + /// // We now read 8 bytes from the offset 10. + /// let num_bytes_read = file.read_at(&mut buf, 10)?; + /// println!("read {} bytes: {:?}", num_bytes_read, buf); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "file_offset", since = "1.15.0")] + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result; + + /// Reads the exact number of byte required to fill `buf` from the given offset. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`. + /// + /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact + /// [`read_at`]: #tymethod.read_at + /// + /// # Errors + /// + /// If this function encounters an error of the kind + /// [`ErrorKind::Interrupted`] then the error is ignored and the operation + /// will continue. + /// + /// If this function encounters an "end of file" before completely filling + /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`]. + /// The contents of `buf` are unspecified in this case. + /// + /// If any other read error is encountered then this function immediately + /// returns. The contents of `buf` are unspecified in this case. + /// + /// If this function returns an error, it is unspecified how many bytes it + /// has read, but it will never read more than would be necessary to + /// completely fill the buffer. + /// + /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted + /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof + /// + /// # Examples + /// + /// ```no_run + /// #![feature(rw_exact_all_at)] + /// use std::io; + /// use std::fs::File; + /// use std::os::unix::prelude::FileExt; + /// + /// fn main() -> io::Result<()> { + /// let mut buf = [0u8; 8]; + /// let file = File::open("foo.txt")?; + /// + /// // We now read exactly 8 bytes from the offset 10. + /// file.read_exact_at(&mut buf, 10)?; + /// println!("read {} bytes: {:?}", buf.len(), buf); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "rw_exact_all_at", since = "1.33.0")] + fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + match self.read_at(buf, offset) { + Ok(0) => break, + Ok(n) => { + let tmp = buf; + buf = &mut tmp[n..]; + offset += n as u64; + } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + if !buf.is_empty() { + Err(io::Error::new(io::ErrorKind::UnexpectedEof, + "failed to fill whole buffer")) + } else { + Ok(()) + } + } + + /// Writes a number of bytes starting from a given offset. + /// + /// Returns the number of bytes written. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// When writing beyond the end of the file, the file is appropriately + /// extended and the intermediate bytes are initialized with the value 0. + /// + /// Note that similar to [`File::write`], it is not an error to return a + /// short write. + /// + /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// use std::io; + /// use std::os::unix::prelude::FileExt; + /// + /// fn main() -> io::Result<()> { + /// let file = File::open("foo.txt")?; + /// + /// // We now write at the offset 10. + /// file.write_at(b"sushi", 10)?; + /// Ok(()) + /// } + /// ``` + #[stable(feature = "file_offset", since = "1.15.0")] + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result; + + /// Attempts to write an entire buffer starting from a given offset. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// This method will continuously call [`write_at`] until there is no more data + /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is + /// returned. This method will not return until the entire buffer has been + /// successfully written or such an error occurs. The first error that is + /// not of [`ErrorKind::Interrupted`] kind generated from this method will be + /// returned. + /// + /// # Errors + /// + /// This function will return the first error of + /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns. + /// + /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted + /// [`write_at`]: #tymethod.write_at + /// + /// # Examples + /// + /// ```no_run + /// #![feature(rw_exact_all_at)] + /// use std::fs::File; + /// use std::io; + /// use std::os::unix::prelude::FileExt; + /// + /// fn main() -> io::Result<()> { + /// let file = File::open("foo.txt")?; + /// + /// // We now write at the offset 10. + /// file.write_all_at(b"sushi", 10)?; + /// Ok(()) + /// } + /// ``` + #[stable(feature = "rw_exact_all_at", since = "1.33.0")] + fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + match self.write_at(buf, offset) { + Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero, + "failed to write whole buffer")), + Ok(n) => { + buf = &buf[n..]; + offset += n as u64 + } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + Ok(()) + } +} + +#[stable(feature = "file_offset", since = "1.15.0")] +impl FileExt for fs::File { + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { + self.as_inner().read_at(buf, offset) + } + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { + self.as_inner().write_at(buf, offset) + } +} + +/// Unix-specific extensions to [`fs::Permissions`]. +/// +/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html +#[stable(feature = "fs_ext", since = "1.1.0")] +pub trait PermissionsExt { + /// Returns the underlying raw `st_mode` bits that contain the standard + /// Unix permissions for this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// use std::os::unix::fs::PermissionsExt; + /// + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let permissions = metadata.permissions(); + /// + /// println!("permissions: {}", permissions.mode()); + /// Ok(()) } + /// ``` + #[stable(feature = "fs_ext", since = "1.1.0")] + fn mode(&self) -> u32; + + /// Sets the underlying raw bits for this set of permissions. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// use std::os::unix::fs::PermissionsExt; + /// + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let mut permissions = metadata.permissions(); + /// + /// permissions.set_mode(0o644); // Read/write for owner and read for others. + /// assert_eq!(permissions.mode(), 0o644); + /// Ok(()) } + /// ``` + #[stable(feature = "fs_ext", since = "1.1.0")] + fn set_mode(&mut self, mode: u32); + + /// Creates a new instance of `Permissions` from the given set of Unix + /// permission bits. + /// + /// # Examples + /// + /// ``` + /// use std::fs::Permissions; + /// use std::os::unix::fs::PermissionsExt; + /// + /// // Read/write for owner and read for others. + /// let permissions = Permissions::from_mode(0o644); + /// assert_eq!(permissions.mode(), 0o644); + /// ``` + #[stable(feature = "fs_ext", since = "1.1.0")] + fn from_mode(mode: u32) -> Self; +} + +#[stable(feature = "fs_ext", since = "1.1.0")] +impl PermissionsExt for Permissions { + fn mode(&self) -> u32 { + self.as_inner().mode() + } + + fn set_mode(&mut self, mode: u32) { + *self = Permissions::from_inner(FromInner::from_inner(mode)); + } + + fn from_mode(mode: u32) -> Permissions { + Permissions::from_inner(FromInner::from_inner(mode)) + } +} + +/// Unix-specific extensions to [`fs::OpenOptions`]. +/// +/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html +#[stable(feature = "fs_ext", since = "1.1.0")] +pub trait OpenOptionsExt { + /// Sets the mode bits that a new file will be created with. + /// + /// If a new file is created as part of a `File::open_opts` call then this + /// specified `mode` will be used as the permission bits for the new file. + /// If no `mode` is set, the default of `0o666` will be used. + /// The operating system masks out bits with the systems `umask`, to produce + /// the final permissions. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::OpenOptions; + /// use std::os::unix::fs::OpenOptionsExt; + /// + /// # fn main() { + /// let mut options = OpenOptions::new(); + /// options.mode(0o644); // Give read/write for owner and read for others. + /// let file = options.open("foo.txt"); + /// # } + /// ``` + #[stable(feature = "fs_ext", since = "1.1.0")] + fn mode(&mut self, mode: u32) -> &mut Self; + + /// Pass custom flags to the `flags` argument of `open`. + /// + /// The bits that define the access mode are masked out with `O_ACCMODE`, to + /// ensure they do not interfere with the access mode set by Rusts options. + /// + /// Custom flags can only set flags, not remove flags set by Rusts options. + /// This options overwrites any previously set custom flags. + /// + /// # Examples + /// + /// ```no_run + /// # #![feature(libc)] + /// extern crate libc; + /// use std::fs::OpenOptions; + /// use std::os::unix::fs::OpenOptionsExt; + /// + /// # fn main() { + /// let mut options = OpenOptions::new(); + /// options.write(true); + /// if cfg!(unix) { + /// options.custom_flags(libc::O_NOFOLLOW); + /// } + /// let file = options.open("foo.txt"); + /// # } + /// ``` + #[stable(feature = "open_options_ext", since = "1.10.0")] + fn custom_flags(&mut self, flags: i32) -> &mut Self; +} + +/*#[stable(feature = "fs_ext", since = "1.1.0")] +impl OpenOptionsExt for OpenOptions { + fn mode(&mut self, mode: u32) -> &mut OpenOptions { + self.as_inner_mut().mode(mode); self + } + + fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions { + self.as_inner_mut().custom_flags(flags); self + } +} +*/ + +/// Unix-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + /// Returns the ID of the device containing the file. + /// + /// # Examples + /// + /// ```no_run + /// use std::io; + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let dev_id = meta.dev(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn dev(&self) -> u64; + /// Returns the inode number. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let inode = meta.ino(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn ino(&self) -> u64; + /// Returns the rights applied to this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let mode = meta.mode(); + /// let user_has_write_access = mode & 0o200; + /// let user_has_read_write_access = mode & 0o600; + /// let group_has_read_access = mode & 0o040; + /// let others_have_exec_access = mode & 0o001; + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn mode(&self) -> u32; + /// Returns the number of hard links pointing to this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nb_hard_links = meta.nlink(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn nlink(&self) -> u64; + /// Returns the user ID of the owner of this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let user_id = meta.uid(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn uid(&self) -> u32; + /// Returns the group ID of the owner of this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let group_id = meta.gid(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn gid(&self) -> u32; + /// Returns the device ID of this file (if it is a special one). + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let device_id = meta.rdev(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn rdev(&self) -> u64; + /// Returns the total size of this file in bytes. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let file_size = meta.size(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn size(&self) -> u64; + /// Returns the time of the last access to the file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_access_time = meta.atime(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn atime(&self) -> i64; + /// Returns the time of the last access to the file in nanoseconds. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_access_time = meta.atime_nsec(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn mtime(&self) -> i64; + /// Returns the time of the last modification of the file in nanoseconds. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_modification_time = meta.mtime_nsec(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn ctime(&self) -> i64; + /// Returns the time of the last status change of the file in nanoseconds. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_status_change_time = meta.ctime_nsec(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn blksize(&self) -> u64; + /// Returns the number of blocks allocated to the file, in 512-byte units. + /// + /// Please note that this may be smaller than `st_size / 512` when the file has holes. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let blocks = meta.blocks(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn blocks(&self) -> u64; + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn attrib(&self) -> u8; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for fs::Metadata { + fn dev(&self) -> u64 { self.st_dev() } + fn ino(&self) -> u64 { self.st_ino() } + fn mode(&self) -> u32 { self.st_mode() } + fn nlink(&self) -> u64 { self.st_nlink() } + fn uid(&self) -> u32 { self.st_uid() } + fn gid(&self) -> u32 { self.st_gid() } + fn rdev(&self) -> u64 { self.st_rdev() } + fn size(&self) -> u64 { self.st_size() } + fn atime(&self) -> i64 { self.st_atime() } + fn mtime(&self) -> i64 { self.st_mtime() } + fn ctime(&self) -> i64 { self.st_ctime() } + fn blksize(&self) -> u64 { self.st_blksize() } + fn blocks(&self) -> u64 { self.st_blocks() } + fn attrib(&self) -> u8 {self.st_attrib() } +} + +/// Unix-specific extensions for [`FileType`]. +/// +/// Adds support for special Unix file types such as block/character devices, +/// pipes, and sockets. +/// +/// [`FileType`]: ../../../../std/fs/struct.FileType.html +#[stable(feature = "file_type_ext", since = "1.5.0")] +pub trait FileTypeExt { + /// Returns whether this file type is a block device. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::FileTypeExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("block_device_file")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_block_device()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "file_type_ext", since = "1.5.0")] + fn is_block_device(&self) -> bool; + /// Returns whether this file type is a char device. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::FileTypeExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("char_device_file")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_char_device()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "file_type_ext", since = "1.5.0")] + fn is_char_device(&self) -> bool; + /// Returns whether this file type is a fifo. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::FileTypeExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("fifo_file")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_fifo()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "file_type_ext", since = "1.5.0")] + fn is_fifo(&self) -> bool; + /// Returns whether this file type is a socket. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::FileTypeExt; + /// use std::io; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("unix.socket")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_socket()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "file_type_ext", since = "1.5.0")] + fn is_socket(&self) -> bool; +} + +#[stable(feature = "file_type_ext", since = "1.5.0")] +impl FileTypeExt for fs::FileType { + fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) } + fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) } + fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) } + fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) } +} + +/// Unix-specific extension methods for [`fs::DirEntry`]. +/// +/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html +#[stable(feature = "dir_entry_ext", since = "1.1.0")] +pub trait DirEntryExt { + /// Returns the underlying `d_ino` field in the contained `dirent` + /// structure. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// use std::os::unix::fs::DirEntryExt; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// println!("{:?}: {}", entry.file_name(), entry.ino()); + /// } + /// } + /// } + /// ``` + #[stable(feature = "dir_entry_ext", since = "1.1.0")] + fn ino(&self) -> u64; +} + +#[stable(feature = "dir_entry_ext", since = "1.1.0")] +impl DirEntryExt for fs::DirEntry { + fn ino(&self) -> u64 { self.as_inner().ino() } +} + +/// Creates a new symbolic link on the filesystem. +/// +/// The `dst` path will be a symbolic link pointing to the `src` path. +/// +/// # Note +/// +/// On Windows, you must specify whether a symbolic link points to a file +/// or directory. Use `os::windows::fs::symlink_file` to create a +/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a +/// symbolic link to a directory. Additionally, the process must have +/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a +/// symbolic link. +/// +/// # Examples +/// +/// ```no_run +/// use std::os::unix::fs; +/// +/// fn main() -> std::io::Result<()> { +/// fs::symlink("a.txt", "b.txt")?; +/// Ok(()) +/// } +/// ``` +#[stable(feature = "symlink", since = "1.1.0")] +pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> +{ + sys::fs::symlink(src.as_ref(), dst.as_ref()) +} + +/// Unix-specific extensions to [`fs::DirBuilder`]. +/// +/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html +#[stable(feature = "dir_builder", since = "1.6.0")] +pub trait DirBuilderExt { + /// Sets the mode to create new directories with. This option defaults to + /// 0o777. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::DirBuilder; + /// use std::os::unix::fs::DirBuilderExt; + /// + /// let mut builder = DirBuilder::new(); + /// builder.mode(0o755); + /// ``` + #[stable(feature = "dir_builder", since = "1.6.0")] + fn mode(&mut self, mode: u32) -> &mut Self; +} + +#[stable(feature = "dir_builder", since = "1.6.0")] +impl DirBuilderExt for fs::DirBuilder { + fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder { + self.as_inner_mut().set_mode(mode); + self + } +} diff --git a/src/libstd/sys/redox/ext/io.rs b/src/libstd/sys/vxworks/ext/io.rs similarity index 59% rename from src/libstd/sys/redox/ext/io.rs rename to src/libstd/sys/vxworks/ext/io.rs index c21d216478..6bcc59495e 100644 --- a/src/libstd/sys/redox/ext/io.rs +++ b/src/libstd/sys/vxworks/ext/io.rs @@ -3,14 +3,14 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fs; -use crate::net; +use crate::os::raw; use crate::sys; use crate::io; -use crate::sys_common::{self, AsInner, FromInner, IntoInner}; +use crate::sys_common::{AsInner, FromInner, IntoInner}; /// Raw file descriptors. #[stable(feature = "rust1", since = "1.0.0")] -pub type RawFd = usize; +pub type RawFd = raw::c_int; /// A trait to extract the raw unix file descriptor from an underlying /// object. @@ -33,7 +33,7 @@ pub trait AsRawFd { /// descriptor. #[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawFd { - /// Constructs a new instances of `Self` from the given raw file + /// Constructs a new instance of `Self` from the given raw file /// descriptor. /// /// This function **consumes ownership** of the specified file @@ -81,92 +81,32 @@ impl IntoRawFd for fs::File { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl AsRawFd for net::TcpStream { - fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_inner().fd().raw() - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl AsRawFd for net::TcpListener { - fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_inner().fd().raw() - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl AsRawFd for net::UdpSocket { - fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_inner().fd().raw() - } -} - #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawFd for io::Stdin { - fn as_raw_fd(&self) -> RawFd { 0 } + fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO } } #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawFd for io::Stdout { - fn as_raw_fd(&self) -> RawFd { 1 } + fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO } } #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawFd for io::Stderr { - fn as_raw_fd(&self) -> RawFd { 2 } + fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO } } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawFd for io::StdinLock<'a> { - fn as_raw_fd(&self) -> RawFd { 0 } + fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO } } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawFd for io::StdoutLock<'a> { - fn as_raw_fd(&self) -> RawFd { 1 } + fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO } } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawFd for io::StderrLock<'a> { - fn as_raw_fd(&self) -> RawFd { 2 } -} - -#[stable(feature = "from_raw_os", since = "1.1.0")] -impl FromRawFd for net::TcpStream { - unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream { - let file = sys::fs::File::from_inner(fd); - net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(file)) - } -} -#[stable(feature = "from_raw_os", since = "1.1.0")] -impl FromRawFd for net::TcpListener { - unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener { - let file = sys::fs::File::from_inner(fd); - net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(file)) - } -} -#[stable(feature = "from_raw_os", since = "1.1.0")] -impl FromRawFd for net::UdpSocket { - unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket { - let file = sys::fs::File::from_inner(fd); - net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(file)) - } -} - -#[stable(feature = "into_raw_os", since = "1.4.0")] -impl IntoRawFd for net::TcpStream { - fn into_raw_fd(self) -> RawFd { - self.into_inner().into_inner().into_fd().into_raw() - } -} -#[stable(feature = "into_raw_os", since = "1.4.0")] -impl IntoRawFd for net::TcpListener { - fn into_raw_fd(self) -> RawFd { - self.into_inner().into_inner().into_fd().into_raw() - } -} -#[stable(feature = "into_raw_os", since = "1.4.0")] -impl IntoRawFd for net::UdpSocket { - fn into_raw_fd(self) -> RawFd { - self.into_inner().into_inner().into_fd().into_raw() - } + fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO } } diff --git a/src/libstd/sys/vxworks/ext/mod.rs b/src/libstd/sys/vxworks/ext/mod.rs new file mode 100644 index 0000000000..c2ebc38c30 --- /dev/null +++ b/src/libstd/sys/vxworks/ext/mod.rs @@ -0,0 +1,20 @@ +// Uhhh +#![stable(feature = "rust1", since = "1.0.0")] +#![allow(missing_docs)] + +pub mod io; +pub mod ffi; +pub mod fs; +pub mod raw; +pub mod process; +pub mod net; + +#[stable(feature = "rust1", since = "1.0.0")] +pub mod prelude { + #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] + pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd}; + #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] + pub use super::ffi::{OsStrExt, OsStringExt}; + #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] + pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt}; +} diff --git a/src/libstd/sys/vxworks/ext/net.rs b/src/libstd/sys/vxworks/ext/net.rs new file mode 100644 index 0000000000..3f0a7e9e84 --- /dev/null +++ b/src/libstd/sys/vxworks/ext/net.rs @@ -0,0 +1,1825 @@ +#![stable(feature = "unix_socket", since = "1.10.0")] + +//! Unix-specific networking functionality + +#[cfg(unix)] +use libc; + +use crate::ascii; +use crate::ffi::OsStr; +use crate::fmt; +use crate::io::{self, Initializer, IoSlice, IoSliceMut}; +use crate::mem; +use crate::net::{self, Shutdown}; +use crate::os::unix::ffi::OsStrExt; +use crate::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd}; +use crate::path::Path; +use crate::time::Duration; +use crate::sys::{self, cvt}; +use crate::sys::net::Socket; +use crate::sys_common::{self, AsInner, FromInner, IntoInner}; + +const MSG_NOSIGNAL: libc::c_int = 0x0; + +fn sun_path_offset(addr: &libc::sockaddr_un) -> usize { + // Work with an actual instance of the type since using a null pointer is UB + let base = addr as *const _ as usize; + let path = &addr.sun_path as *const _ as usize; + path - base +} + +unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> { + let mut addr: libc::sockaddr_un = mem::zeroed(); + addr.sun_family = libc::AF_UNIX as libc::sa_family_t; + + let bytes = path.as_os_str().as_bytes(); + + if bytes.contains(&0) { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "paths may not contain interior null bytes")); + } + + if bytes.len() >= addr.sun_path.len() { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "path must be shorter than SUN_LEN")); + } + for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) { + *dst = *src as libc::c_char; + } + // null byte for pathname addresses is already there because we zeroed the + // struct + + let mut len = sun_path_offset(&addr) + bytes.len(); + match bytes.get(0) { + Some(&0) | None => {} + Some(_) => len += 1, + } + Ok((addr, len as libc::socklen_t)) +} + +enum AddressKind<'a> { + Unnamed, + Pathname(&'a Path), + Abstract(&'a [u8]), +} + +/// An address associated with a Unix socket. +/// +/// # Examples +/// +/// ``` +/// use std::os::unix::net::UnixListener; +/// +/// let socket = match UnixListener::bind("/tmp/sock") { +/// Ok(sock) => sock, +/// Err(e) => { +/// println!("Couldn't bind: {:?}", e); +/// return +/// } +/// }; +/// let addr = socket.local_addr().expect("Couldn't get local address"); +/// ``` +#[derive(Clone)] +#[stable(feature = "unix_socket", since = "1.10.0")] +pub struct SocketAddr { + addr: libc::sockaddr_un, + len: libc::socklen_t, +} + +impl SocketAddr { + fn new(f: F) -> io::Result + where F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int + { + unsafe { + let mut addr: libc::sockaddr_un = mem::zeroed(); + let mut len = mem::size_of::() as libc::socklen_t; + cvt(f(&mut addr as *mut _ as *mut _, &mut len))?; + SocketAddr::from_parts(addr, len) + } + } + + fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result { + if len == 0 { + // When there is a datagram from unnamed unix socket + // linux returns zero bytes of address + len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address + } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "file descriptor did not correspond to a Unix socket")); + } + + Ok(SocketAddr { + addr, + len, + }) + } + + /// Returns `true` if the address is unnamed. + /// + /// # Examples + /// + /// A named address: + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let socket = UnixListener::bind("/tmp/sock").unwrap(); + /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// assert_eq!(addr.is_unnamed(), false); + /// ``` + /// + /// An unnamed address: + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// + /// let socket = UnixDatagram::unbound().unwrap(); + /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// assert_eq!(addr.is_unnamed(), true); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn is_unnamed(&self) -> bool { + if let AddressKind::Unnamed = self.address() { + true + } else { + false + } + } + + /// Returns the contents of this address if it is a `pathname` address. + /// + /// # Examples + /// + /// With a pathname: + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// use std::path::Path; + /// + /// let socket = UnixListener::bind("/tmp/sock").unwrap(); + /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock"))); + /// ``` + /// + /// Without a pathname: + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// + /// let socket = UnixDatagram::unbound().unwrap(); + /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// assert_eq!(addr.as_pathname(), None); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn as_pathname(&self) -> Option<&Path> { + if let AddressKind::Pathname(path) = self.address() { + Some(path) + } else { + None + } + } + + fn address<'a>(&'a self) -> AddressKind<'a> { + let len = self.len as usize - sun_path_offset(&self.addr); + let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; + + if self.addr.sun_path[0] == 0 { + AddressKind::Abstract(&path[1..len]) + } else { + AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref()) + } + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl fmt::Debug for SocketAddr { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.address() { + AddressKind::Unnamed => write!(fmt, "(unnamed)"), + AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)), + AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path), + } + } +} + +struct AsciiEscaped<'a>(&'a [u8]); + +impl<'a> fmt::Display for AsciiEscaped<'a> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "\"")?; + for byte in self.0.iter().cloned().flat_map(ascii::escape_default) { + write!(fmt, "{}", byte as char)?; + } + write!(fmt, "\"") + } +} + +/// A Unix stream socket. +/// +/// # Examples +/// +/// ```no_run +/// use std::os::unix::net::UnixStream; +/// use std::io::prelude::*; +/// +/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap(); +/// stream.write_all(b"hello world").unwrap(); +/// let mut response = String::new(); +/// stream.read_to_string(&mut response).unwrap(); +/// println!("{}", response); +/// ``` +#[stable(feature = "unix_socket", since = "1.10.0")] +pub struct UnixStream(Socket); + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl fmt::Debug for UnixStream { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut builder = fmt.debug_struct("UnixStream"); + builder.field("fd", self.0.as_inner()); + if let Ok(addr) = self.local_addr() { + builder.field("local", &addr); + } + if let Ok(addr) = self.peer_addr() { + builder.field("peer", &addr); + } + builder.finish() + } +} + +impl UnixStream { + /// Connects to the socket named by `path`. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let socket = match UnixStream::connect("/tmp/sock") { + /// Ok(sock) => sock, + /// Err(e) => { + /// println!("Couldn't connect: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn connect>(path: P) -> io::Result { + fn inner(path: &Path) -> io::Result { + unsafe { + let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?; + let (addr, len) = sockaddr_un(path)?; + + cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?; + Ok(UnixStream(inner)) + } + } + inner(path.as_ref()) + } + + /// Creates an unnamed pair of connected sockets. + /// + /// Returns two `UnixStream`s which are connected to each other. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let (sock1, sock2) = match UnixStream::pair() { + /// Ok((sock1, sock2)) => (sock1, sock2), + /// Err(e) => { + /// println!("Couldn't create a pair of sockets: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn pair() -> io::Result<(UnixStream, UnixStream)> { + let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?; + Ok((UnixStream(i1), UnixStream(i2))) + } + + /// Creates a new independently owned handle to the underlying socket. + /// + /// The returned `UnixStream` is a reference to the same stream that this + /// object references. Both handles will read and write the same stream of + /// data, and options set on one stream will be propagated to the other + /// stream. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// let sock_copy = socket.try_clone().expect("Couldn't clone socket"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn try_clone(&self) -> io::Result { + self.0.duplicate().map(UnixStream) + } + + /// Returns the socket address of the local half of this connection. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn local_addr(&self) -> io::Result { + SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }) + } + + /// Returns the socket address of the remote half of this connection. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// let addr = socket.peer_addr().expect("Couldn't get peer address"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn peer_addr(&self) -> io::Result { + SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }) + } + + /// Sets the read timeout for the socket. + /// + /// If the provided value is [`None`], then [`read`] calls will block + /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method. + /// + /// [`None`]: ../../../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err + /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read + /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// use std::time::Duration; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); + /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::os::unix::net::UnixStream; + /// use std::time::Duration; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// let result = socket.set_read_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_read_timeout(&self, timeout: Option) -> io::Result<()> { + self.0.set_timeout(timeout, libc::SO_RCVTIMEO) + } + + /// Sets the write timeout for the socket. + /// + /// If the provided value is [`None`], then [`write`] calls will block + /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is + /// passed to this method. + /// + /// [`None`]: ../../../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err + /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write + /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// use std::time::Duration; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout"); + /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::net::UdpSocket; + /// use std::time::Duration; + /// + /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap(); + /// let result = socket.set_write_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_write_timeout(&self, timeout: Option) -> io::Result<()> { + self.0.set_timeout(timeout, libc::SO_SNDTIMEO) + } + + /// Returns the read timeout of this socket. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// use std::time::Duration; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); + /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0))); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn read_timeout(&self) -> io::Result> { + self.0.timeout(libc::SO_RCVTIMEO) + } + + /// Returns the write timeout of this socket. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// use std::time::Duration; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout"); + /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0))); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn write_timeout(&self) -> io::Result> { + self.0.timeout(libc::SO_SNDTIMEO) + } + + /// Moves the socket into or out of nonblocking mode. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// socket.set_nonblocking(true).expect("Couldn't set nonblocking"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + self.0.set_nonblocking(nonblocking) + } + + /// Returns the value of the `SO_ERROR` option. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// if let Ok(Some(err)) = socket.take_error() { + /// println!("Got error: {:?}", err); + /// } + /// ``` + /// + /// # Platform specific + /// On Redox this always returns `None`. + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn take_error(&self) -> io::Result> { + self.0.take_error() + } + + /// Shuts down the read, write, or both halves of this connection. + /// + /// This function will cause all pending and future I/O calls on the + /// specified portions to immediately return with an appropriate value + /// (see the documentation of [`Shutdown`]). + /// + /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixStream; + /// use std::net::Shutdown; + /// + /// let socket = UnixStream::connect("/tmp/sock").unwrap(); + /// socket.shutdown(Shutdown::Both).expect("shutdown function failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { + self.0.shutdown(how) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl io::Read for UnixStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + io::Read::read(&mut &*self, buf) + } + + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + io::Read::read_vectored(&mut &*self, bufs) + } + + #[inline] + unsafe fn initializer(&self) -> Initializer { + Initializer::nop() + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl<'a> io::Read for &'a UnixStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + + #[inline] + unsafe fn initializer(&self) -> Initializer { + Initializer::nop() + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl io::Write for UnixStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + io::Write::write(&mut &*self, buf) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + io::Write::write_vectored(&mut &*self, bufs) + } + + fn flush(&mut self) -> io::Result<()> { + io::Write::flush(&mut &*self) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl<'a> io::Write for &'a UnixStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl AsRawFd for UnixStream { + fn as_raw_fd(&self) -> RawFd { + *self.0.as_inner() + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl FromRawFd for UnixStream { + unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { + UnixStream(Socket::from_inner(fd)) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl IntoRawFd for UnixStream { + fn into_raw_fd(self) -> RawFd { + self.0.into_inner() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRawFd for net::TcpStream { + fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRawFd for net::TcpListener { + fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRawFd for net::UdpSocket { + fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() } +} + +#[stable(feature = "from_raw_os", since = "1.1.0")] +impl FromRawFd for net::TcpStream { + unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream { + let socket = sys::net::Socket::from_inner(fd); + net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket)) + } +} + +#[stable(feature = "from_raw_os", since = "1.1.0")] +impl FromRawFd for net::TcpListener { + unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener { + let socket = sys::net::Socket::from_inner(fd); + net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket)) + } +} + +#[stable(feature = "from_raw_os", since = "1.1.0")] +impl FromRawFd for net::UdpSocket { + unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket { + let socket = sys::net::Socket::from_inner(fd); + net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket)) + } +} + +#[stable(feature = "into_raw_os", since = "1.4.0")] +impl IntoRawFd for net::TcpStream { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner() + } +} +#[stable(feature = "into_raw_os", since = "1.4.0")] +impl IntoRawFd for net::TcpListener { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner() + } +} +#[stable(feature = "into_raw_os", since = "1.4.0")] +impl IntoRawFd for net::UdpSocket { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner() + } +} + +/// A structure representing a Unix domain socket server. +/// +/// # Examples +/// +/// ```no_run +/// use std::thread; +/// use std::os::unix::net::{UnixStream, UnixListener}; +/// +/// fn handle_client(stream: UnixStream) { +/// // ... +/// } +/// +/// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); +/// +/// // accept connections and process them, spawning a new thread for each one +/// for stream in listener.incoming() { +/// match stream { +/// Ok(stream) => { +/// /* connection succeeded */ +/// thread::spawn(|| handle_client(stream)); +/// } +/// Err(err) => { +/// /* connection failed */ +/// break; +/// } +/// } +/// } +/// ``` +#[stable(feature = "unix_socket", since = "1.10.0")] +pub struct UnixListener(Socket); + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl fmt::Debug for UnixListener { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut builder = fmt.debug_struct("UnixListener"); + builder.field("fd", self.0.as_inner()); + if let Ok(addr) = self.local_addr() { + builder.field("local", &addr); + } + builder.finish() + } +} + +impl UnixListener { + /// Creates a new `UnixListener` bound to the specified socket. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let listener = match UnixListener::bind("/path/to/the/socket") { + /// Ok(sock) => sock, + /// Err(e) => { + /// println!("Couldn't connect: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn bind>(path: P) -> io::Result { + fn inner(path: &Path) -> io::Result { + unsafe { + let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?; + let (addr, len) = sockaddr_un(path)?; + + cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?; + cvt(libc::listen(*inner.as_inner(), 128))?; + + Ok(UnixListener(inner)) + } + } + inner(path.as_ref()) + } + + /// Accepts a new incoming connection to this listener. + /// + /// This function will block the calling thread until a new Unix connection + /// is established. When established, the corresponding [`UnixStream`] and + /// the remote peer's address will be returned. + /// + /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); + /// + /// match listener.accept() { + /// Ok((socket, addr)) => println!("Got a client: {:?}", addr), + /// Err(e) => println!("accept function failed: {:?}", e), + /// } + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { + let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() }; + let mut len = mem::size_of_val(&storage) as libc::socklen_t; + let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?; + let addr = SocketAddr::from_parts(storage, len)?; + Ok((UnixStream(sock), addr)) + } + + /// Creates a new independently owned handle to the underlying socket. + /// + /// The returned `UnixListener` is a reference to the same socket that this + /// object references. Both handles can be used to accept incoming + /// connections and options set on one listener will affect the other. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); + /// + /// let listener_copy = listener.try_clone().expect("try_clone failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn try_clone(&self) -> io::Result { + self.0.duplicate().map(UnixListener) + } + + /// Returns the local socket address of this listener. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); + /// + /// let addr = listener.local_addr().expect("Couldn't get local address"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn local_addr(&self) -> io::Result { + SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }) + } + + /// Moves the socket into or out of nonblocking mode. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); + /// + /// listener.set_nonblocking(true).expect("Couldn't set non blocking"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + self.0.set_nonblocking(nonblocking) + } + + /// Returns the value of the `SO_ERROR` option. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixListener; + /// + /// let listener = UnixListener::bind("/tmp/sock").unwrap(); + /// + /// if let Ok(Some(err)) = listener.take_error() { + /// println!("Got error: {:?}", err); + /// } + /// ``` + /// + /// # Platform specific + /// On Redox this always returns `None`. + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn take_error(&self) -> io::Result> { + self.0.take_error() + } + + /// Returns an iterator over incoming connections. + /// + /// The iterator will never return [`None`] and will also not yield the + /// peer's [`SocketAddr`] structure. + /// + /// [`None`]: ../../../../std/option/enum.Option.html#variant.None + /// [`SocketAddr`]: struct.SocketAddr.html + /// + /// # Examples + /// + /// ```no_run + /// use std::thread; + /// use std::os::unix::net::{UnixStream, UnixListener}; + /// + /// fn handle_client(stream: UnixStream) { + /// // ... + /// } + /// + /// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); + /// + /// for stream in listener.incoming() { + /// match stream { + /// Ok(stream) => { + /// thread::spawn(|| handle_client(stream)); + /// } + /// Err(err) => { + /// break; + /// } + /// } + /// } + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn incoming<'a>(&'a self) -> Incoming<'a> { + Incoming { listener: self } + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl AsRawFd for UnixListener { + fn as_raw_fd(&self) -> RawFd { + *self.0.as_inner() + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl FromRawFd for UnixListener { + unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { + UnixListener(Socket::from_inner(fd)) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl IntoRawFd for UnixListener { + fn into_raw_fd(self) -> RawFd { + self.0.into_inner() + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl<'a> IntoIterator for &'a UnixListener { + type Item = io::Result; + type IntoIter = Incoming<'a>; + + fn into_iter(self) -> Incoming<'a> { + self.incoming() + } +} + +/// An iterator over incoming connections to a [`UnixListener`]. +/// +/// It will never return [`None`]. +/// +/// [`None`]: ../../../../std/option/enum.Option.html#variant.None +/// [`UnixListener`]: struct.UnixListener.html +/// +/// # Examples +/// +/// ```no_run +/// use std::thread; +/// use std::os::unix::net::{UnixStream, UnixListener}; +/// +/// fn handle_client(stream: UnixStream) { +/// // ... +/// } +/// +/// let listener = UnixListener::bind("/path/to/the/socket").unwrap(); +/// +/// for stream in listener.incoming() { +/// match stream { +/// Ok(stream) => { +/// thread::spawn(|| handle_client(stream)); +/// } +/// Err(err) => { +/// break; +/// } +/// } +/// } +/// ``` +#[derive(Debug)] +#[stable(feature = "unix_socket", since = "1.10.0")] +pub struct Incoming<'a> { + listener: &'a UnixListener, +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl<'a> Iterator for Incoming<'a> { + type Item = io::Result; + + fn next(&mut self) -> Option> { + Some(self.listener.accept().map(|s| s.0)) + } + + fn size_hint(&self) -> (usize, Option) { + (usize::max_value(), None) + } +} + +/// A Unix datagram socket. +/// +/// # Examples +/// +/// ```no_run +/// use std::os::unix::net::UnixDatagram; +/// +/// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap(); +/// socket.send_to(b"hello world", "/path/to/other/socket").unwrap(); +/// let mut buf = [0; 100]; +/// let (count, address) = socket.recv_from(&mut buf).unwrap(); +/// println!("socket {:?} sent {:?}", address, &buf[..count]); +/// ``` +#[stable(feature = "unix_socket", since = "1.10.0")] +pub struct UnixDatagram(Socket); + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl fmt::Debug for UnixDatagram { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut builder = fmt.debug_struct("UnixDatagram"); + builder.field("fd", self.0.as_inner()); + if let Ok(addr) = self.local_addr() { + builder.field("local", &addr); + } + if let Ok(addr) = self.peer_addr() { + builder.field("peer", &addr); + } + builder.finish() + } +} + +impl UnixDatagram { + /// Creates a Unix datagram socket bound to the given path. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = match UnixDatagram::bind("/path/to/the/socket") { + /// Ok(sock) => sock, + /// Err(e) => { + /// println!("Couldn't bind: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn bind>(path: P) -> io::Result { + fn inner(path: &Path) -> io::Result { + unsafe { + let socket = UnixDatagram::unbound()?; + let (addr, len) = sockaddr_un(path)?; + + cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?; + + Ok(socket) + } + } + inner(path.as_ref()) + } + + /// Creates a Unix Datagram socket which is not bound to any address. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = match UnixDatagram::unbound() { + /// Ok(sock) => sock, + /// Err(e) => { + /// println!("Couldn't unbound: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn unbound() -> io::Result { + let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?; + Ok(UnixDatagram(inner)) + } + + /// Creates an unnamed pair of connected sockets. + /// + /// Returns two `UnixDatagrams`s which are connected to each other. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let (sock1, sock2) = match UnixDatagram::pair() { + /// Ok((sock1, sock2)) => (sock1, sock2), + /// Err(e) => { + /// println!("Couldn't unbound: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> { + let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?; + Ok((UnixDatagram(i1), UnixDatagram(i2))) + } + + /// Connects the socket to the specified address. + /// + /// The [`send`] method may be used to send data to the specified address. + /// [`recv`] and [`recv_from`] will only receive data from that address. + /// + /// [`send`]: #method.send + /// [`recv`]: #method.recv + /// [`recv_from`]: #method.recv_from + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// match sock.connect("/path/to/the/socket") { + /// Ok(sock) => sock, + /// Err(e) => { + /// println!("Couldn't connect: {:?}", e); + /// return + /// } + /// }; + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn connect>(&self, path: P) -> io::Result<()> { + fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> { + unsafe { + let (addr, len) = sockaddr_un(path)?; + + cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?; + + Ok(()) + } + } + inner(self, path.as_ref()) + } + + /// Creates a new independently owned handle to the underlying socket. + /// + /// The returned `UnixDatagram` is a reference to the same socket that this + /// object references. Both handles can be used to accept incoming + /// connections and options set on one side will affect the other. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap(); + /// + /// let sock_copy = sock.try_clone().expect("try_clone failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn try_clone(&self) -> io::Result { + self.0.duplicate().map(UnixDatagram) + } + + /// Returns the address of this socket. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap(); + /// + /// let addr = sock.local_addr().expect("Couldn't get local address"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn local_addr(&self) -> io::Result { + SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }) + } + + /// Returns the address of this socket's peer. + /// + /// The [`connect`] method will connect the socket to a peer. + /// + /// [`connect`]: #method.connect + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.connect("/path/to/the/socket").unwrap(); + /// + /// let addr = sock.peer_addr().expect("Couldn't get peer address"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn peer_addr(&self) -> io::Result { + SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }) + } + + /// Receives data from the socket. + /// + /// On success, returns the number of bytes read and the address from + /// whence the data came. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// let mut buf = vec![0; 10]; + /// match sock.recv_from(buf.as_mut_slice()) { + /// Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender), + /// Err(e) => println!("recv_from function failed: {:?}", e), + /// } + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + let mut count = 0; + let addr = SocketAddr::new(|addr, len| { + unsafe { + count = libc::recvfrom(*self.0.as_inner(), + buf.as_mut_ptr() as *mut _, + buf.len(), + 0, + addr, + len); + if count > 0 { + 1 + } else if count == 0 { + 0 + } else { + -1 + } + } + })?; + + Ok((count as usize, addr)) + } + + /// Receives data from the socket. + /// + /// On success, returns the number of bytes read. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap(); + /// let mut buf = vec![0; 10]; + /// sock.recv(buf.as_mut_slice()).expect("recv function failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn recv(&self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + + /// Sends data on the socket to the specified address. + /// + /// On success, returns the number of bytes written. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn send_to>(&self, buf: &[u8], path: P) -> io::Result { + fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result { + unsafe { + let (addr, len) = sockaddr_un(path)?; + + let count = cvt(libc::sendto(*d.0.as_inner(), + buf.as_ptr() as *const _, + buf.len(), + MSG_NOSIGNAL, + &addr as *const _ as *const _, + len))?; + Ok(count as usize) + } + } + inner(self, buf, path.as_ref()) + } + + /// Sends data on the socket to the socket's peer. + /// + /// The peer address may be set by the `connect` method, and this method + /// will return an error if the socket has not already been connected. + /// + /// On success, returns the number of bytes written. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.connect("/some/sock").expect("Couldn't connect"); + /// sock.send(b"omelette au fromage").expect("send_to function failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn send(&self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + /// Sets the read timeout for the socket. + /// + /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will + /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] + /// is passed to this method. + /// + /// [`None`]: ../../../../std/option/enum.Option.html#variant.None + /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err + /// [`recv`]: #method.recv + /// [`recv_from`]: #method.recv_from + /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// + /// # Examples + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// use std::time::Duration; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed"); + /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::os::unix::net::UnixDatagram; + /// use std::time::Duration; + /// + /// let socket = UnixDatagram::unbound().unwrap(); + /// let result = socket.set_read_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_read_timeout(&self, timeout: Option) -> io::Result<()> { + self.0.set_timeout(timeout, libc::SO_RCVTIMEO) + } + + /// Sets the write timeout for the socket. + /// + /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will + /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method. + /// + /// [`None`]: ../../../../std/option/enum.Option.html#variant.None + /// [`send`]: #method.send + /// [`send_to`]: #method.send_to + /// [`Duration`]: ../../../../std/time/struct.Duration.html + /// + /// # Examples + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// use std::time::Duration; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.set_write_timeout(Some(Duration::new(1, 0))) + /// .expect("set_write_timeout function failed"); + /// ``` + /// + /// An [`Err`] is returned if the zero [`Duration`] is passed to this + /// method: + /// + /// ```no_run + /// use std::io; + /// use std::os::unix::net::UnixDatagram; + /// use std::time::Duration; + /// + /// let socket = UnixDatagram::unbound().unwrap(); + /// let result = socket.set_write_timeout(Some(Duration::new(0, 0))); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_write_timeout(&self, timeout: Option) -> io::Result<()> { + self.0.set_timeout(timeout, libc::SO_SNDTIMEO) + } + + /// Returns the read timeout of this socket. + /// + /// # Examples + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// use std::time::Duration; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed"); + /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0))); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn read_timeout(&self) -> io::Result> { + self.0.timeout(libc::SO_RCVTIMEO) + } + + /// Returns the write timeout of this socket. + /// + /// # Examples + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// use std::time::Duration; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.set_write_timeout(Some(Duration::new(1, 0))) + /// .expect("set_write_timeout function failed"); + /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0))); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn write_timeout(&self) -> io::Result> { + self.0.timeout(libc::SO_SNDTIMEO) + } + + /// Moves the socket into or out of nonblocking mode. + /// + /// # Examples + /// + /// ``` + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.set_nonblocking(true).expect("set_nonblocking function failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + self.0.set_nonblocking(nonblocking) + } + + /// Returns the value of the `SO_ERROR` option. + /// + /// # Examples + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// if let Ok(Some(err)) = sock.take_error() { + /// println!("Got error: {:?}", err); + /// } + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn take_error(&self) -> io::Result> { + self.0.take_error() + } + + /// Shut down the read, write, or both halves of this connection. + /// + /// This function will cause all pending and future I/O calls on the + /// specified portions to immediately return with an appropriate value + /// (see the documentation of [`Shutdown`]). + /// + /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html + /// + /// ```no_run + /// use std::os::unix::net::UnixDatagram; + /// use std::net::Shutdown; + /// + /// let sock = UnixDatagram::unbound().unwrap(); + /// sock.shutdown(Shutdown::Both).expect("shutdown function failed"); + /// ``` + #[stable(feature = "unix_socket", since = "1.10.0")] + pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { + self.0.shutdown(how) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl AsRawFd for UnixDatagram { + fn as_raw_fd(&self) -> RawFd { + *self.0.as_inner() + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl FromRawFd for UnixDatagram { + unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram { + UnixDatagram(Socket::from_inner(fd)) + } +} + +#[stable(feature = "unix_socket", since = "1.10.0")] +impl IntoRawFd for UnixDatagram { + fn into_raw_fd(self) -> RawFd { + self.0.into_inner() + } +} + +#[cfg(all(test, not(target_os = "emscripten")))] +mod test { + use crate::thread; + use crate::io::{self, ErrorKind}; + use crate::io::prelude::*; + use crate::time::Duration; + use crate::sys_common::io::test::tmpdir; + + use super::*; + + macro_rules! or_panic { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{}", e), + } + } + } + + #[test] + fn basic() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + let msg1 = b"hello"; + let msg2 = b"world!"; + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let thread = thread::spawn(move || { + let mut stream = or_panic!(listener.accept()).0; + let mut buf = [0; 5]; + or_panic!(stream.read(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(stream.write_all(msg2)); + }); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + assert_eq!(Some(&*socket_path), + stream.peer_addr().unwrap().as_pathname()); + or_panic!(stream.write_all(msg1)); + let mut buf = vec![]; + or_panic!(stream.read_to_end(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + drop(stream); + + thread.join().unwrap(); + } + + #[test] + fn vectored() { + let (mut s1, mut s2) = or_panic!(UnixStream::pair()); + + let len = or_panic!(s1.write_vectored( + &[IoSlice::new(b"hello"), IoSlice::new(b" "), IoSlice::new(b"world!")], + )); + assert_eq!(len, 12); + + let mut buf1 = [0; 6]; + let mut buf2 = [0; 7]; + let len = or_panic!(s2.read_vectored( + &mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)], + )); + assert_eq!(len, 12); + assert_eq!(&buf1, b"hello "); + assert_eq!(&buf2, b"world!\0"); + } + + #[test] + fn pair() { + let msg1 = b"hello"; + let msg2 = b"world!"; + + let (mut s1, mut s2) = or_panic!(UnixStream::pair()); + let thread = thread::spawn(move || { + // s1 must be moved in or the test will hang! + let mut buf = [0; 5]; + or_panic!(s1.read(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(s1.write_all(msg2)); + }); + + or_panic!(s2.write_all(msg1)); + let mut buf = vec![]; + or_panic!(s2.read_to_end(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + drop(s2); + + thread.join().unwrap(); + } + + #[test] + fn try_clone() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + let msg1 = b"hello"; + let msg2 = b"world"; + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let thread = thread::spawn(move || { + let mut stream = or_panic!(listener.accept()).0; + or_panic!(stream.write_all(msg1)); + or_panic!(stream.write_all(msg2)); + }); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + let mut stream2 = or_panic!(stream.try_clone()); + + let mut buf = [0; 5]; + or_panic!(stream.read(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(stream2.read(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + + thread.join().unwrap(); + } + + #[test] + fn iter() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let thread = thread::spawn(move || { + for stream in listener.incoming().take(2) { + let mut stream = or_panic!(stream); + let mut buf = [0]; + or_panic!(stream.read(&mut buf)); + } + }); + + for _ in 0..2 { + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + or_panic!(stream.write_all(&[0])); + } + + thread.join().unwrap(); + } + + #[test] + fn long_path() { + let dir = tmpdir(); + let socket_path = dir.path() + .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\ + sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf"); + match UnixStream::connect(&socket_path) { + Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} + Err(e) => panic!("unexpected error {}", e), + Ok(_) => panic!("unexpected success"), + } + + match UnixListener::bind(&socket_path) { + Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} + Err(e) => panic!("unexpected error {}", e), + Ok(_) => panic!("unexpected success"), + } + + match UnixDatagram::bind(&socket_path) { + Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} + Err(e) => panic!("unexpected error {}", e), + Ok(_) => panic!("unexpected success"), + } + } + + #[test] + fn timeouts() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let _listener = or_panic!(UnixListener::bind(&socket_path)); + + let stream = or_panic!(UnixStream::connect(&socket_path)); + let dur = Duration::new(15410, 0); + + assert_eq!(None, or_panic!(stream.read_timeout())); + + or_panic!(stream.set_read_timeout(Some(dur))); + assert_eq!(Some(dur), or_panic!(stream.read_timeout())); + + assert_eq!(None, or_panic!(stream.write_timeout())); + + or_panic!(stream.set_write_timeout(Some(dur))); + assert_eq!(Some(dur), or_panic!(stream.write_timeout())); + + or_panic!(stream.set_read_timeout(None)); + assert_eq!(None, or_panic!(stream.read_timeout())); + + or_panic!(stream.set_write_timeout(None)); + assert_eq!(None, or_panic!(stream.write_timeout())); + } + + #[test] + fn test_read_timeout() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let _listener = or_panic!(UnixListener::bind(&socket_path)); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut buf = [0; 10]; + let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); + assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", kind); + } + + #[test] + fn test_read_with_timeout() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let listener = or_panic!(UnixListener::bind(&socket_path)); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut other_end = or_panic!(listener.accept()).0; + or_panic!(other_end.write_all(b"hello world")); + + let mut buf = [0; 11]; + or_panic!(stream.read(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + + let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); + assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", kind); + } + + // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors + // when passed zero Durations + #[test] + fn test_unix_stream_timeout_zero_duration() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let stream = or_panic!(UnixStream::connect(&socket_path)); + + let result = stream.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = stream.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + drop(listener); + } + + #[test] + fn test_unix_datagram() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + let path2 = dir.path().join("sock2"); + + let sock1 = or_panic!(UnixDatagram::bind(&path1)); + let sock2 = or_panic!(UnixDatagram::bind(&path2)); + + let msg = b"hello world"; + or_panic!(sock1.send_to(msg, &path2)); + let mut buf = [0; 11]; + or_panic!(sock2.recv_from(&mut buf)); + assert_eq!(msg, &buf[..]); + } + + #[test] + fn test_unnamed_unix_datagram() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + + let sock1 = or_panic!(UnixDatagram::bind(&path1)); + let sock2 = or_panic!(UnixDatagram::unbound()); + + let msg = b"hello world"; + or_panic!(sock2.send_to(msg, &path1)); + let mut buf = [0; 11]; + let (usize, addr) = or_panic!(sock1.recv_from(&mut buf)); + assert_eq!(usize, 11); + assert!(addr.is_unnamed()); + assert_eq!(msg, &buf[..]); + } + + #[test] + fn test_connect_unix_datagram() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + let path2 = dir.path().join("sock2"); + + let bsock1 = or_panic!(UnixDatagram::bind(&path1)); + let bsock2 = or_panic!(UnixDatagram::bind(&path2)); + let sock = or_panic!(UnixDatagram::unbound()); + or_panic!(sock.connect(&path1)); + + // Check send() + let msg = b"hello there"; + or_panic!(sock.send(msg)); + let mut buf = [0; 11]; + let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf)); + assert_eq!(usize, 11); + assert!(addr.is_unnamed()); + assert_eq!(msg, &buf[..]); + + // Changing default socket works too + or_panic!(sock.connect(&path2)); + or_panic!(sock.send(msg)); + or_panic!(bsock2.recv_from(&mut buf)); + } + + #[test] + fn test_unix_datagram_recv() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + + let sock1 = or_panic!(UnixDatagram::bind(&path1)); + let sock2 = or_panic!(UnixDatagram::unbound()); + or_panic!(sock2.connect(&path1)); + + let msg = b"hello world"; + or_panic!(sock2.send(msg)); + let mut buf = [0; 11]; + let size = or_panic!(sock1.recv(&mut buf)); + assert_eq!(size, 11); + assert_eq!(msg, &buf[..]); + } + + #[test] + fn datagram_pair() { + let msg1 = b"hello"; + let msg2 = b"world!"; + + let (s1, s2) = or_panic!(UnixDatagram::pair()); + let thread = thread::spawn(move || { + // s1 must be moved in or the test will hang! + let mut buf = [0; 5]; + or_panic!(s1.recv(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(s1.send(msg2)); + }); + + or_panic!(s2.send(msg1)); + let mut buf = [0; 6]; + or_panic!(s2.recv(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + drop(s2); + + thread.join().unwrap(); + } + + // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors + // when passed zero Durations + #[test] + fn test_unix_datagram_timeout_zero_duration() { + let dir = tmpdir(); + let path = dir.path().join("sock"); + + let datagram = or_panic!(UnixDatagram::bind(&path)); + + let result = datagram.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = datagram.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + } + + #[test] + fn abstract_namespace_not_allowed() { + assert!(UnixStream::connect("\0asdf").is_err()); + } +} diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/vxworks/ext/process.rs similarity index 83% rename from src/libstd/sys/redox/ext/process.rs rename to src/libstd/sys/vxworks/ext/process.rs index e981cb93d4..4de72fa181 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/vxworks/ext/process.rs @@ -1,14 +1,14 @@ -//! Redox-specific extensions to primitives in the `std::process` module. +//! Unix-specific extensions to primitives in the `std::process` module. #![stable(feature = "rust1", since = "1.0.0")] use crate::io; -use crate::os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd}; +use crate::sys::vxworks::ext::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd}; use crate::process; use crate::sys; use crate::sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; -/// Redox-specific extensions to the [`process::Command`] builder, +/// Unix-specific extensions to the [`process::Command`] builder. /// /// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "rust1", since = "1.0.0")] @@ -17,12 +17,12 @@ pub trait CommandExt { /// `setuid` call in the child process. Failure in the `setuid` /// call will cause the spawn to fail. #[stable(feature = "rust1", since = "1.0.0")] - fn uid(&mut self, id: u32) -> &mut process::Command; + fn uid(&mut self, id: u16) -> &mut process::Command; /// Similar to `uid`, but sets the group ID of the child process. This has /// the same semantics as the `uid` field. #[stable(feature = "rust1", since = "1.0.0")] - fn gid(&mut self, id: u32) -> &mut process::Command; + fn gid(&mut self, id: u16) -> &mut process::Command; /// Schedules a closure to be run just before the `exec` function is /// invoked. @@ -79,10 +79,20 @@ pub trait CommandExt { /// an error indicating why the exec (or another part of the setup of the /// `Command`) failed. /// + /// `exec` not returning has the same implications as calling + /// [`process::exit`] – no destructors on the current stack or any other + /// thread’s stack will be run. Therefore, it is recommended to only call + /// `exec` at a point where it is fine to not run any destructors. Note, + /// that the `execvp` syscall independently guarantees that all memory is + /// freed and all file descriptors with the `CLOEXEC` option (set by default + /// on all file descriptors opened by the standard library) are closed. + /// /// This function, unlike `spawn`, will **not** `fork` the process to create /// a new child. Like spawn, however, the default behavior for the stdio /// descriptors will be to inherited from the current process. /// + /// [`process::exit`]: ../../../process/fn.exit.html + /// /// # Notes /// /// The process may be in a "broken state" if this function returns in @@ -97,12 +107,12 @@ pub trait CommandExt { #[stable(feature = "rust1", since = "1.0.0")] impl CommandExt for process::Command { - fn uid(&mut self, id: u32) -> &mut process::Command { + fn uid(&mut self, id: u16) -> &mut process::Command { self.as_inner_mut().uid(id); self } - fn gid(&mut self, id: u32) -> &mut process::Command { + fn gid(&mut self, id: u16) -> &mut process::Command { self.as_inner_mut().gid(id); self } @@ -119,7 +129,7 @@ impl CommandExt for process::Command { } } -/// Redox-specific extensions to [`process::ExitStatus`]. +/// Unix-specific extensions to [`process::ExitStatus`]. /// /// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html #[stable(feature = "rust1", since = "1.0.0")] @@ -195,3 +205,9 @@ impl IntoRawFd for process::ChildStderr { self.into_inner().into_fd().into_raw() } } + +/// Returns the OS-assigned process identifier associated with this process's parent. +#[stable(feature = "unix_ppid", since = "1.27.0")] +pub fn parent_id() -> u32 { + crate::sys::os::getppid() +} diff --git a/src/libstd/sys/vxworks/ext/raw.rs b/src/libstd/sys/vxworks/ext/raw.rs new file mode 100644 index 0000000000..1f134f4e2d --- /dev/null +++ b/src/libstd/sys/vxworks/ext/raw.rs @@ -0,0 +1,5 @@ +#![stable(feature = "raw_ext", since = "1.1.0")] + +#[doc(inline)] +#[stable(feature = "pthread_t", since = "1.8.0")] +pub use crate::sys::platform::raw::pthread_t; diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/fast_thread_local.rs new file mode 100644 index 0000000000..f5a2e263d2 --- /dev/null +++ b/src/libstd/sys/vxworks/fast_thread_local.rs @@ -0,0 +1,36 @@ +#![cfg(target_thread_local)] +#![unstable(feature = "thread_local_internals", issue = "0")] + +// Since what appears to be glibc 2.18 this symbol has been shipped which +// GCC and clang both use to invoke destructors in thread_local globals, so +// let's do the same! +// +// Note, however, that we run on lots older linuxes, as well as cross +// compiling from a newer linux to an older linux, so we also have a +// fallback implementation to use as well. +// +// Due to rust-lang/rust#18804, make sure this is not generic! +pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) { + use crate::mem; + use crate::sys_common::thread_local::register_dtor_fallback; + + extern { + #[linkage = "extern_weak"] + static __dso_handle: *mut u8; + #[linkage = "extern_weak"] + static __cxa_thread_atexit_impl: *const libc::c_void; + } + if !__cxa_thread_atexit_impl.is_null() { + type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8), + arg: *mut u8, + dso_handle: *mut u8) -> libc::c_int; + mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl) + (dtor, t, &__dso_handle as *const _ as *mut _); + return + } + register_dtor_fallback(t, dtor); +} + +pub fn requires_move_before_drop() -> bool { + false +} diff --git a/src/libstd/sys/vxworks/fd.rs b/src/libstd/sys/vxworks/fd.rs new file mode 100644 index 0000000000..db2865d252 --- /dev/null +++ b/src/libstd/sys/vxworks/fd.rs @@ -0,0 +1,188 @@ +#![unstable(reason = "not public", issue = "0", feature = "fd")] + +use crate::cmp; +use crate::io::{self, Read, Initializer, IoSlice, IoSliceMut}; +use crate::mem; +use crate::sys::cvt; +use crate::sys_common::AsInner; + +use libc::{self, c_int, c_void, ssize_t}; + +#[derive(Debug)] +pub struct FileDesc { + fd: c_int, +} + +fn max_len() -> usize { + // The maximum read limit on most posix-like systems is `SSIZE_MAX`, + // with the man page quoting that if the count of bytes to read is + // greater than `SSIZE_MAX` the result is "unspecified". + ::max_value() as usize +} + +impl FileDesc { + pub fn new(fd: c_int) -> FileDesc { + FileDesc { fd: fd } + } + + pub fn raw(&self) -> c_int { self.fd } + + /// Extracts the actual filedescriptor without closing it. + pub fn into_raw(self) -> c_int { + let fd = self.fd; + mem::forget(self); + fd + } + + pub fn read(&self, buf: &mut [u8]) -> io::Result { + let ret = cvt(unsafe { + libc::read(self.fd, + buf.as_mut_ptr() as *mut c_void, + cmp::min(buf.len(), max_len())) + })?; + Ok(ret as usize) + } + + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + let ret = cvt(unsafe { + libc::readv(self.fd, + bufs.as_ptr() as *const libc::iovec, + cmp::min(bufs.len(), c_int::max_value() as usize) as c_int) + })?; + Ok(ret as usize) + } + + pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { + let mut me = self; + (&mut me).read_to_end(buf) + } + + pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { + unsafe fn cvt_pread(fd: c_int, buf: *mut c_void, count: usize, offset: i64) + -> io::Result + { + use libc::pread; + cvt(pread(fd, buf, count, offset)) + } + + unsafe { + cvt_pread(self.fd, + buf.as_mut_ptr() as *mut c_void, + cmp::min(buf.len(), max_len()), + offset as i64) + .map(|n| n as usize) + } + } + + pub fn write(&self, buf: &[u8]) -> io::Result { + let ret = cvt(unsafe { + libc::write(self.fd, + buf.as_ptr() as *const c_void, + cmp::min(buf.len(), max_len())) + })?; + Ok(ret as usize) + } + + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + let ret = cvt(unsafe { + libc::writev(self.fd, + bufs.as_ptr() as *const libc::iovec, + cmp::min(bufs.len(), c_int::max_value() as usize) as c_int) + })?; + Ok(ret as usize) + } + + pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { + unsafe fn cvt_pwrite(fd: c_int, buf: *const c_void, count: usize, offset: i64) + -> io::Result + { + use libc::pwrite; + cvt(pwrite(fd, buf, count, offset)) + } + + unsafe { + cvt_pwrite(self.fd, + buf.as_ptr() as *const c_void, + cmp::min(buf.len(), max_len()), + offset as i64) + .map(|n| n as usize) + } + } + + pub fn get_cloexec(&self) -> io::Result { + unsafe { + Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) + } + } + + pub fn set_cloexec(&self) -> io::Result<()> { + unsafe { + let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?; + let new = previous | libc::FD_CLOEXEC; + if new != previous { + cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?; + } + Ok(()) + } + } + + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + unsafe { + let v = nonblocking as c_int; + cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?; + Ok(()) + } + } + + // refer to pxPipeDrv library documentation. + // VxWorks uses fcntl to set O_NONBLOCK to the pipes + pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> { + unsafe { + let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?; + flags = if nonblocking { + flags | libc::O_NONBLOCK + } else { + flags & !libc::O_NONBLOCK + }; + cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?; + Ok(()) + } + } + + + pub fn duplicate(&self) -> io::Result { + let fd = self.raw(); + match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) { + Ok(newfd) => { + Ok(FileDesc::new(newfd)) + } + Err(e) => return Err(e), + } + } +} + +impl<'a> Read for &'a FileDesc { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (**self).read(buf) + } + + #[inline] + unsafe fn initializer(&self) -> Initializer { + Initializer::nop() + } +} + +impl AsInner for FileDesc { + fn as_inner(&self) -> &c_int { &self.fd } +} + +impl Drop for FileDesc { + fn drop(&mut self) { + // Note that errors are ignored when closing a file descriptor. The + // reason for this is that if an error occurs we don't actually know if + // the file descriptor was closed or not, and if we retried (for + // something like EINTR), we might close another valid file descriptor + // (opened after we closed ours. + let _ = unsafe { libc::close(self.fd) }; + } +} diff --git a/src/libstd/sys/vxworks/fs.rs b/src/libstd/sys/vxworks/fs.rs new file mode 100644 index 0000000000..d537d2258f --- /dev/null +++ b/src/libstd/sys/vxworks/fs.rs @@ -0,0 +1,575 @@ +// copies from linuxx +use crate::ffi::{CString, CStr, OsString, OsStr}; +use crate::sys::vxworks::ext::ffi::OsStrExt; +use crate::fmt; +use crate::io::{self, Error, ErrorKind, SeekFrom, IoSlice, IoSliceMut}; +use crate::mem; +use crate::path::{Path, PathBuf}; +use crate::ptr; +use crate::sync::Arc; +use crate::sys::fd::FileDesc; +use crate::sys::time::SystemTime; +use crate::sys::{cvt, cvt_r}; +use crate::sys_common::{AsInner, FromInner}; +use libc::{self, c_int, mode_t, stat64, off_t}; +use libc::{ftruncate, lseek, dirent, readdir_r as readdir64_r, open}; +use crate::sys::vxworks::ext::ffi::OsStringExt; +pub struct File(FileDesc); + +#[derive(Clone)] +pub struct FileAttr { + stat: stat64, +} + +// all DirEntry's will have a reference to this struct +struct InnerReadDir { + dirp: Dir, + root: PathBuf, +} + +#[derive(Clone)] +pub struct ReadDir { + inner: Arc, + end_of_stream: bool, +} + +struct Dir(*mut libc::DIR); + +unsafe impl Send for Dir {} +unsafe impl Sync for Dir {} + +pub struct DirEntry { + entry: dirent, + dir: ReadDir, +} + +#[derive(Clone, Debug)] +pub struct OpenOptions { + // generic + read: bool, + write: bool, + append: bool, + truncate: bool, + create: bool, + create_new: bool, + // system-specific + custom_flags: i32, + mode: mode_t, +} + +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct FilePermissions { mode: mode_t } + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct FileType { mode: mode_t } + +#[derive(Debug)] +pub struct DirBuilder { mode: mode_t } + +impl FileAttr { + pub fn size(&self) -> u64 { self.stat.st_size as u64 } + pub fn perm(&self) -> FilePermissions { + FilePermissions { mode: (self.stat.st_mode as mode_t) } + } + + pub fn file_type(&self) -> FileType { + FileType { mode: self.stat.st_mode as mode_t } + } + + pub fn modified(&self) -> io::Result { + Ok(SystemTime::from(libc::timespec { + tv_sec: self.stat.st_mtime as libc::time_t, + tv_nsec: 0, // hack 2.0; + })) + } + + pub fn accessed(&self) -> io::Result { + Ok(SystemTime::from(libc::timespec { + tv_sec: self.stat.st_atime as libc::time_t, + tv_nsec: 0, // hack - a proper fix would be better + })) + } + + pub fn created(&self) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, + "creation time is not available on this platform currently")) + } + +} + +impl AsInner for FileAttr { + fn as_inner(&self) -> &stat64 { &self.stat } +} + +impl FilePermissions { + pub fn readonly(&self) -> bool { + // check if any class (owner, group, others) has write permission + self.mode & 0o222 == 0 + } + + pub fn set_readonly(&mut self, readonly: bool) { + if readonly { + // remove write permission for all classes; equivalent to `chmod a-w ` + self.mode &= !0o222; + } else { + // add write permission for all classes; equivalent to `chmod a+w ` + self.mode |= 0o222; + } + } + pub fn mode(&self) -> u32 { self.mode as u32 } +} + +impl FileType { + pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) } + pub fn is_file(&self) -> bool { self.is(libc::S_IFREG) } + pub fn is_symlink(&self) -> bool { self.is(libc::S_IFLNK) } + + pub fn is(&self, mode: mode_t) -> bool { self.mode & libc::S_IFMT == mode } +} + +impl FromInner for FilePermissions { + fn from_inner(mode: u32) -> FilePermissions { + FilePermissions { mode: mode as mode_t } + } +} + +impl fmt::Debug for ReadDir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame. + // Thus the result will be e g 'ReadDir("/home")' + fmt::Debug::fmt(&*self.inner.root, f) + } +} + +impl Iterator for ReadDir { + type Item = io::Result; + fn next(&mut self) -> Option> { + if self.end_of_stream { + return None; + } + + unsafe { + let mut ret = DirEntry { + entry: mem::zeroed(), + dir: self.clone(), + }; + let mut entry_ptr = ptr::null_mut(); + loop { + if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { + if entry_ptr.is_null() { + // We encountered an error (which will be returned in this iteration), but + // we also reached the end of the directory stream. The `end_of_stream` + // flag is enabled to make sure that we return `None` in the next iteration + // (instead of looping forever) + self.end_of_stream = true; + } + return Some(Err(Error::last_os_error())) + } + if entry_ptr.is_null() { + return None + } + if ret.name_bytes() != b"." && ret.name_bytes() != b".." { + return Some(Ok(ret)) + } + } + } + } +} + +impl Drop for Dir { + fn drop(&mut self) { + let r = unsafe { libc::closedir(self.0) }; + debug_assert_eq!(r, 0); + } +} + +impl DirEntry { + pub fn path(&self) -> PathBuf { + use crate::sys::vxworks::ext::ffi::OsStrExt; + self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes())) + } + + pub fn file_name(&self) -> OsString { + OsStr::from_bytes(self.name_bytes()).to_os_string() + } + + + pub fn metadata(&self) -> io::Result { + lstat(&self.path()) + } + + pub fn file_type(&self) -> io::Result { + lstat(&self.path()).map(|m| m.file_type()) + + } + + pub fn ino(&self) -> u64 { + self.entry.d_ino as u64 + } + + fn name_bytes(&self) -> &[u8] { + unsafe { + //&*self.name + CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() + } + } +} + +impl OpenOptions { + pub fn new() -> OpenOptions { + OpenOptions { + // generic + read: false, + write: false, + append: false, + truncate: false, + create: false, + create_new: false, + // system-specific + custom_flags: 0, + mode: 0o666, + } + } + + pub fn read(&mut self, read: bool) { self.read = read; } + pub fn write(&mut self, write: bool) { self.write = write; } + pub fn append(&mut self, append: bool) { self.append = append; } + pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; } + pub fn create(&mut self, create: bool) { self.create = create; } + pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; } + pub fn mode(&mut self, mode: u32) { self.mode = mode as mode_t; } + + fn get_access_mode(&self) -> io::Result { + match (self.read, self.write, self.append) { + (true, false, false) => Ok(libc::O_RDONLY), + (false, true, false) => Ok(libc::O_WRONLY), + (true, true, false) => Ok(libc::O_RDWR), + (false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND), + (true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND), + (false, false, false) => Err(Error::from_raw_os_error(libc::EINVAL)), + } + } + + fn get_creation_mode(&self) -> io::Result { + match (self.write, self.append) { + (true, false) => {} + (false, false) => + if self.truncate || self.create || self.create_new { + return Err(Error::from_raw_os_error(libc::EINVAL)); + }, + (_, true) => + if self.truncate && !self.create_new { + return Err(Error::from_raw_os_error(libc::EINVAL)); + }, + } + + Ok(match (self.create, self.truncate, self.create_new) { + (false, false, false) => 0, + (true, false, false) => libc::O_CREAT, + (false, true, false) => libc::O_TRUNC, + (true, true, false) => libc::O_CREAT | libc::O_TRUNC, + (_, _, true) => libc::O_CREAT | libc::O_EXCL, + }) + } +} + +impl File { + pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { + let path = cstr(path)?; + File::open_c(&path, opts) + } + + pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result { + let flags = libc::O_CLOEXEC | + opts.get_access_mode()? | + opts.get_creation_mode()? | + (opts.custom_flags as c_int & !libc::O_ACCMODE); + let fd = cvt_r(|| unsafe { + open(path.as_ptr(), flags, opts.mode as c_int) + })?; + Ok(File(FileDesc::new(fd))) + } + + pub fn file_attr(&self) -> io::Result { + let mut stat: stat64 = unsafe { mem::zeroed() }; + cvt(unsafe { + ::libc::fstat(self.0.raw(), &mut stat) + })?; + Ok(FileAttr { stat: stat }) + } + + pub fn fsync(&self) -> io::Result<()> { + cvt_r(|| unsafe { libc::fsync(self.0.raw()) })?; + Ok(()) + } + + pub fn datasync(&self) -> io::Result<()> { + cvt_r(|| unsafe { os_datasync(self.0.raw()) })?; + return Ok(()); + unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) } //not supported + } + + pub fn truncate(&self, size: u64) -> io::Result<()> { + return cvt_r(|| unsafe { + ftruncate(self.0.raw(), size as off_t) + }).map(|_| ()); + } + + pub fn read(&self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + + pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { + self.0.read_at(buf, offset) + } + + pub fn write(&self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { + self.0.write_at(buf, offset) + } + + pub fn flush(&self) -> io::Result<()> { Ok(()) } + + pub fn seek(&self, pos: SeekFrom) -> io::Result { + let (whence, pos) = match pos { + // Casting to `i64` is fine, too large values will end up as + // negative which will cause an error in `"lseek64"`. + SeekFrom::Start(off) => (libc::SEEK_SET, off as i64), + SeekFrom::End(off) => (libc::SEEK_END, off), + SeekFrom::Current(off) => (libc::SEEK_CUR, off), + }; + let n = cvt(unsafe { lseek(self.0.raw(), pos, whence) })?; + Ok(n as u64) + } + + pub fn duplicate(&self) -> io::Result { + self.0.duplicate().map(File) + } + + pub fn fd(&self) -> &FileDesc { &self.0 } + + pub fn into_fd(self) -> FileDesc { self.0 } + + pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { + cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?; + Ok(()) + } + + pub fn diverge(&self) -> ! { + panic!() + } +} + +impl DirBuilder { + pub fn new() -> DirBuilder { + DirBuilder { mode: 0o777 } + } + + pub fn mkdir(&self, p: &Path) -> io::Result<()> { + let p = cstr(p)?; + cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) })?; + Ok(()) + } + + pub fn set_mode(&mut self, mode: u32) { + self.mode = mode as mode_t; + } +} + +fn cstr(path: &Path) -> io::Result { + use crate::sys::vxworks::ext::ffi::OsStrExt; + Ok(CString::new(path.as_os_str().as_bytes())?) +} + +impl FromInner for File { + fn from_inner(fd: c_int) -> File { + File(FileDesc::new(fd)) + } +} + +impl fmt::Debug for File { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn get_path(_fd: c_int) -> Option { + // FIXME(#:(): implement this for VxWorks + None + } + fn get_mode(_fd: c_int) -> Option<(bool, bool)> { + // FIXME(#:(): implement this for VxWorks + None + } + + let fd = self.0.raw(); + let mut b = f.debug_struct("File"); + b.field("fd", &fd); + if let Some(path) = get_path(fd) { + b.field("path", &path); + } + if let Some((read, write)) = get_mode(fd) { + b.field("read", &read).field("write", &write); + } + b.finish() + } +} + +pub fn readdir(p: &Path) -> io::Result { + let root = p.to_path_buf(); + let p = cstr(p)?; + unsafe { + let ptr = libc::opendir(p.as_ptr()); + if ptr.is_null() { + Err(Error::last_os_error()) + } else { + let inner = InnerReadDir { dirp: Dir(ptr), root }; + Ok(ReadDir{ + inner: Arc::new(inner), + end_of_stream: false, + }) + } + } +} + +pub fn unlink(p: &Path) -> io::Result<()> { + let p = cstr(p)?; + cvt(unsafe { libc::unlink(p.as_ptr()) })?; + Ok(()) +} + +pub fn rename(old: &Path, new: &Path) -> io::Result<()> { + let old = cstr(old)?; + let new = cstr(new)?; + cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })?; + Ok(()) +} + +pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { + let p = cstr(p)?; + cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })?; + Ok(()) +} + +pub fn rmdir(p: &Path) -> io::Result<()> { + let p = cstr(p)?; + cvt(unsafe { libc::rmdir(p.as_ptr()) })?; + Ok(()) +} + +pub fn remove_dir_all(path: &Path) -> io::Result<()> { + let filetype = lstat(path)?.file_type(); + if filetype.is_symlink() { + unlink(path) + } else { + remove_dir_all_recursive(path) + } +} + +fn remove_dir_all_recursive(path: &Path) -> io::Result<()> { + for child in readdir(path)? { + let child = child?; + if child.file_type()?.is_dir() { + remove_dir_all_recursive(&child.path())?; + } else { + unlink(&child.path())?; + } + } + rmdir(path) +} + +pub fn readlink(p: &Path) -> io::Result { + let c_path = cstr(p)?; + let p = c_path.as_ptr(); + + let mut buf = Vec::with_capacity(256); + + loop { + let buf_read = cvt(unsafe { + libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) + })? as usize; + + unsafe { buf.set_len(buf_read); } + + if buf_read != buf.capacity() { + buf.shrink_to_fit(); + + return Ok(PathBuf::from(OsString::from_vec(buf))); + } + + // Trigger the internal buffer resizing logic of `Vec` by requiring + // more space than the current capacity. The length is guaranteed to be + // the same as the capacity due to the if statement above. + buf.reserve(1); + } +} + +pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { + let src = cstr(src)?; + let dst = cstr(dst)?; + cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })?; + Ok(()) +} + +pub fn link(src: &Path, dst: &Path) -> io::Result<()> { + let src = cstr(src)?; + let dst = cstr(dst)?; + cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?; + Ok(()) +} + +pub fn stat(p: &Path) -> io::Result { + let p = cstr(p)?; + let mut stat: stat64 = unsafe { mem::zeroed() }; + cvt(unsafe { + libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _) + })?; + Ok(FileAttr { stat }) +} + +pub fn lstat(p: &Path) -> io::Result { + let p = cstr(p)?; + let mut stat: stat64 = unsafe { mem::zeroed() }; + cvt(unsafe { + ::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _) + })?; + Ok(FileAttr { stat }) +} + +pub fn canonicalize(p: &Path) -> io::Result { + use crate::sys::vxworks::ext::ffi::OsStrExt; + let path = CString::new(p.as_os_str().as_bytes())?; + let buf; + unsafe { + let r = libc::realpath(path.as_ptr(), ptr::null_mut()); + if r.is_null() { + return Err(io::Error::last_os_error()) + } + buf = CStr::from_ptr(r).to_bytes().to_vec(); + libc::free(r as *mut _); + } + Ok(PathBuf::from(OsString::from_vec(buf))) +} + +pub fn copy(from: &Path, to: &Path) -> io::Result { + use crate::fs::File; + if !from.is_file() { + return Err(Error::new(ErrorKind::InvalidInput, + "the source path is not an existing regular file")) + } + + let mut reader = File::open(from)?; + let mut writer = File::create(to)?; + let perm = reader.metadata()?.permissions(); + + let ret = io::copy(&mut reader, &mut writer)?; + writer.set_permissions(perm)?; + Ok(ret) +} diff --git a/src/libstd/sys/vxworks/io.rs b/src/libstd/sys/vxworks/io.rs new file mode 100644 index 0000000000..8cd11cbf5d --- /dev/null +++ b/src/libstd/sys/vxworks/io.rs @@ -0,0 +1,86 @@ +use crate::marker::PhantomData; +use crate::slice; + +use libc::{iovec, c_void}; + +#[repr(transparent)] +pub struct IoSlice<'a> { + vec: iovec, + _p: PhantomData<&'a [u8]>, +} + +impl<'a> IoSlice<'a> { + #[inline] + pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + IoSlice { + vec: iovec { + iov_base: buf.as_ptr() as *mut u8 as *mut c_void, + iov_len: buf.len() + }, + _p: PhantomData, + } + } + + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.iov_len < n { + panic!("advancing IoSlice beyond its length"); + } + + unsafe { + self.vec.iov_len -= n; + self.vec.iov_base = self.vec.iov_base.add(n); + } + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) + } + } +} + +pub struct IoSliceMut<'a> { + vec: iovec, + _p: PhantomData<&'a mut [u8]>, +} + +impl<'a> IoSliceMut<'a> { + #[inline] + pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + IoSliceMut { + vec: iovec { + iov_base: buf.as_mut_ptr() as *mut c_void, + iov_len: buf.len() + }, + _p: PhantomData, + } + } + + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.iov_len < n { + panic!("advancing IoSliceMut beyond its length"); + } + + unsafe { + self.vec.iov_len -= n; + self.vec.iov_base = self.vec.iov_base.add(n); + } + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) + } + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) + } + } +} diff --git a/src/libstd/sys/vxworks/memchr.rs b/src/libstd/sys/vxworks/memchr.rs new file mode 100644 index 0000000000..b5b4e6d9c1 --- /dev/null +++ b/src/libstd/sys/vxworks/memchr.rs @@ -0,0 +1,24 @@ +// Original implementation taken from rust-memchr. +// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch + +pub fn memchr(needle: u8, haystack: &[u8]) -> Option { + let p = unsafe { + libc::memchr( + haystack.as_ptr() as *const libc::c_void, + needle as libc::c_int, + haystack.len()) + }; + if p.is_null() { + None + } else { + Some(p as usize - (haystack.as_ptr() as usize)) + } +} + +pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { + fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option { + core::slice::memchr::memrchr(needle, haystack) + } + + memrchr_specific(needle, haystack) +} diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs new file mode 100644 index 0000000000..1eff4fbcd8 --- /dev/null +++ b/src/libstd/sys/vxworks/mod.rs @@ -0,0 +1,125 @@ +#![allow(dead_code)] +#![allow(missing_docs, nonstandard_style)] + +use crate::io::ErrorKind; + +pub use crate::os::vxworks as platform; +pub use self::rand::hashmap_random_keys; +pub use libc::strlen; + +pub mod alloc; +pub mod args; +pub mod cmath; +pub mod condvar; +pub mod env; +pub mod ext; +pub mod fast_thread_local; +pub mod fd; +pub mod fs; +pub mod memchr; +pub mod io; +pub mod mutex; +pub mod net; +pub mod os; +pub mod path; +pub mod pipe; +pub mod process; +pub mod rand; +pub mod rwlock; +pub mod stack_overflow; +pub mod thread; +pub mod thread_local; +pub mod time; +pub mod stdio; + +pub use crate::sys_common::os_str_bytes as os_str; + +#[cfg(not(test))] +pub fn init() { + // By default, some platforms will send a *signal* when an EPIPE error + // would otherwise be delivered. This runtime doesn't install a SIGPIPE + // handler, causing it to kill the program, which isn't exactly what we + // want! + // + // Hence, we set SIGPIPE to ignore when the program starts up in order + // to prevent this problem. + unsafe { + reset_sigpipe(); + } + + unsafe fn reset_sigpipe() { } +} + +pub use libc::signal; + +pub fn decode_error_kind(errno: i32) -> ErrorKind { + match errno as libc::c_int { + libc::ECONNREFUSED => ErrorKind::ConnectionRefused, + libc::ECONNRESET => ErrorKind::ConnectionReset, + libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied, + libc::EPIPE => ErrorKind::BrokenPipe, + libc::ENOTCONN => ErrorKind::NotConnected, + libc::ECONNABORTED => ErrorKind::ConnectionAborted, + libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, + libc::EADDRINUSE => ErrorKind::AddrInUse, + libc::ENOENT => ErrorKind::NotFound, + libc::EINTR => ErrorKind::Interrupted, + libc::EINVAL => ErrorKind::InvalidInput, + libc::ETIMEDOUT => ErrorKind::TimedOut, + libc::EEXIST => ErrorKind::AlreadyExists, + + // These two constants can have the same value on some systems, + // but different values on others, so we can't use a match + // clause + x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => + ErrorKind::WouldBlock, + + _ => ErrorKind::Other, + } +} + +#[doc(hidden)] +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) +} + +impl_is_minus_one! { i8 i16 i32 i64 isize } + +pub fn cvt(t: T) -> crate::io::Result { + if t.is_minus_one() { + Err(crate::io::Error::last_os_error()) + } else { + Ok(t) + } +} + +pub fn cvt_r(mut f: F) -> crate::io::Result + where T: IsMinusOne, + F: FnMut() -> T +{ + loop { + match cvt(f()) { + Err(ref e) if e.kind() == ErrorKind::Interrupted => {} + other => return other, + } + } +} + +// On Unix-like platforms, libc::abort will unregister signal handlers +// including the SIGABRT handler, preventing the abort from being blocked, and +// fclose streams, with the side effect of flushing them so libc bufferred +// output will be printed. Additionally the shell will generally print a more +// understandable error message like "Abort trap" rather than "Illegal +// instruction" that intrinsics::abort would cause, as intrinsics::abort is +// implemented as an illegal instruction. +pub unsafe fn abort_internal() -> ! { + libc::abort() +} diff --git a/src/libstd/sys/vxworks/mutex.rs b/src/libstd/sys/vxworks/mutex.rs new file mode 100644 index 0000000000..b43af8fdca --- /dev/null +++ b/src/libstd/sys/vxworks/mutex.rs @@ -0,0 +1,127 @@ +use crate::cell::UnsafeCell; +use crate::mem::MaybeUninit; + +pub struct Mutex { inner: UnsafeCell } + +#[inline] +pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t { + m.inner.get() +} + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +#[allow(dead_code)] // sys isn't exported yet +impl Mutex { + pub const fn new() -> Mutex { + // Might be moved to a different address, so it is better to avoid + // initialization of potentially opaque OS data before it landed. + // Be very careful using this newly constructed `Mutex`, reentrant + // locking is undefined behavior until `init` is called! + Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) } + } + #[inline] + pub unsafe fn init(&mut self) { + // Issue #33770 + // + // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have + // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you + // try to re-lock it from the same thread when you already hold a lock. + // + // In practice, glibc takes advantage of this undefined behavior to + // implement hardware lock elision, which uses hardware transactional + // memory to avoid acquiring the lock. While a transaction is in + // progress, the lock appears to be unlocked. This isn't a problem for + // other threads since the transactional memory will abort if a conflict + // is detected, however no abort is generated if re-locking from the + // same thread. + // + // Since locking the same mutex twice will result in two aliasing &mut + // references, we instead create the mutex with type + // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to + // re-lock it from the same thread, thus avoiding undefined behavior. + let mut attr = MaybeUninit::::uninit(); + let r = libc::pthread_mutexattr_init(attr.as_mut_ptr()); + debug_assert_eq!(r, 0); + let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL); + debug_assert_eq!(r, 0); + let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr()); + debug_assert_eq!(r, 0); + let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); + debug_assert_eq!(r, 0); + } + #[inline] + pub unsafe fn lock(&self) { + let r = libc::pthread_mutex_lock(self.inner.get()); + debug_assert_eq!(r, 0); + } + #[inline] + pub unsafe fn unlock(&self) { + let r = libc::pthread_mutex_unlock(self.inner.get()); + debug_assert_eq!(r, 0); + } + #[inline] + pub unsafe fn try_lock(&self) -> bool { + libc::pthread_mutex_trylock(self.inner.get()) == 0 + } + #[inline] + #[cfg(not(target_os = "dragonfly"))] + pub unsafe fn destroy(&self) { + let r = libc::pthread_mutex_destroy(self.inner.get()); + debug_assert_eq!(r, 0); + } + #[inline] + #[cfg(target_os = "dragonfly")] + pub unsafe fn destroy(&self) { + let r = libc::pthread_mutex_destroy(self.inner.get()); + // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a + // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. + // Once it is used (locked/unlocked) or pthread_mutex_init() is called, + // this behaviour no longer occurs. + debug_assert!(r == 0 || r == libc::EINVAL); + } +} + +pub struct ReentrantMutex { inner: UnsafeCell } + +unsafe impl Send for ReentrantMutex {} +unsafe impl Sync for ReentrantMutex {} + +impl ReentrantMutex { + pub unsafe fn uninitialized() -> ReentrantMutex { + ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) } + } + + pub unsafe fn init(&mut self) { + let mut attr = MaybeUninit::::uninit(); + let result = libc::pthread_mutexattr_init(attr.as_mut_ptr()); + debug_assert_eq!(result, 0); + let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), + libc::PTHREAD_MUTEX_RECURSIVE); + debug_assert_eq!(result, 0); + let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr()); + debug_assert_eq!(result, 0); + let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); + debug_assert_eq!(result, 0); + } + + pub unsafe fn lock(&self) { + let result = libc::pthread_mutex_lock(self.inner.get()); + debug_assert_eq!(result, 0); + } + + #[inline] + pub unsafe fn try_lock(&self) -> bool { + libc::pthread_mutex_trylock(self.inner.get()) == 0 + } + + pub unsafe fn unlock(&self) { + let result = libc::pthread_mutex_unlock(self.inner.get()); + debug_assert_eq!(result, 0); + } + + pub unsafe fn destroy(&self) { + let result = libc::pthread_mutex_destroy(self.inner.get()); + debug_assert_eq!(result, 0); + } +} diff --git a/src/libstd/sys/vxworks/net.rs b/src/libstd/sys/vxworks/net.rs new file mode 100644 index 0000000000..56962e11dc --- /dev/null +++ b/src/libstd/sys/vxworks/net.rs @@ -0,0 +1,357 @@ +use crate::ffi::CStr; +use crate::io; +use crate::io::{IoSlice, IoSliceMut}; +use libc::{self, c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK}; +use crate::mem; +use crate::net::{SocketAddr, Shutdown}; +use crate::str; +use crate::sys::fd::FileDesc; +use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; +use crate::time::{Duration, Instant}; +use crate::cmp; + +pub use crate::sys::{cvt, cvt_r}; + +#[allow(unused_extern_crates)] +pub extern crate libc as netc; + +pub type wrlen_t = size_t; + + +const SOCK_CLOEXEC: c_int = 0; +const SO_NOSIGPIPE: c_int = 0; + +pub struct Socket(FileDesc); + +pub fn init() {} + +pub fn cvt_gai(err: c_int) -> io::Result<()> { + if err == 0 { + return Ok(()) + } + + // We may need to trigger a glibc workaround. See on_resolver_failure() for details. + on_resolver_failure(); + + if err == EAI_SYSTEM { + return Err(io::Error::last_os_error()) + } + + let detail = unsafe { + str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap() + .to_owned() + }; + Err(io::Error::new(io::ErrorKind::Other, + &format!("failed to lookup address information: {}", + detail)[..])) +} + +impl Socket { + pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result { + let fam = match *addr { + SocketAddr::V4(..) => libc::AF_INET, + SocketAddr::V6(..) => libc::AF_INET6, + }; + Socket::new_raw(fam, ty) + } + + pub fn new_raw(fam: c_int, ty: c_int) -> io::Result { + unsafe { + let fd = cvt(libc::socket(fam, ty, 0))?; + let fd = FileDesc::new(fd); + fd.set_cloexec()?; + let socket = Socket(fd); + Ok(socket) + } + } + + pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> { + unimplemented!(); + } + + pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { + self.set_nonblocking(true)?; + let r = unsafe { + let (addrp, len) = addr.into_inner(); + cvt(libc::connect(self.0.raw(), addrp, len)) + }; + self.set_nonblocking(false)?; + + match r { + Ok(_) => return Ok(()), + // there's no ErrorKind for EINPROGRESS :( + Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {} + Err(e) => return Err(e), + } + + let mut pollfd = libc::pollfd { + fd: self.0.raw(), + events: libc::POLLOUT, + revents: 0, + }; + + if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout")); + } + + let start = Instant::now(); + + loop { + let elapsed = start.elapsed(); + if elapsed >= timeout { + return Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")); + } + + let timeout = timeout - elapsed; + let mut timeout = timeout.as_secs() + .saturating_mul(1_000) + .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); + if timeout == 0 { + timeout = 1; + } + + let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int; + + match unsafe { libc::poll(&mut pollfd, 1, timeout) } { + -1 => { + let err = io::Error::last_os_error(); + if err.kind() != io::ErrorKind::Interrupted { + return Err(err); + } + } + 0 => {} + _ => { + // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look + // for POLLHUP rather than read readiness + if pollfd.revents & libc::POLLHUP != 0 { + let e = self.take_error()? + .unwrap_or_else(|| { + io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP") + }); + return Err(e); + } + + return Ok(()); + } + } + } + } + + pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) + -> io::Result { + let fd = cvt_r(|| unsafe { + libc::accept(self.0.raw(), storage, len) + })?; + let fd = FileDesc::new(fd); + fd.set_cloexec()?; + Ok(Socket(fd)) + } + + pub fn duplicate(&self) -> io::Result { + self.0.duplicate().map(Socket) + } + + fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result { + let ret = cvt(unsafe { + libc::recv(self.0.raw(), + buf.as_mut_ptr() as *mut c_void, + buf.len(), + flags) + })?; + Ok(ret as usize) + } + + pub fn read(&self, buf: &mut [u8]) -> io::Result { + self.recv_with_flags(buf, 0) + } + + pub fn peek(&self, buf: &mut [u8]) -> io::Result { + self.recv_with_flags(buf, MSG_PEEK) + } + + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + + fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int) + -> io::Result<(usize, SocketAddr)> { + let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() }; + let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t; + + let n = cvt(unsafe { + libc::recvfrom(self.0.raw(), + buf.as_mut_ptr() as *mut c_void, + buf.len(), + flags, + &mut storage as *mut _ as *mut _, + &mut addrlen) + })?; + Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) + } + + pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.recv_from_with_flags(buf, 0) + } + + pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.recv_from_with_flags(buf, MSG_PEEK) + } + + pub fn write(&self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + pub fn set_timeout(&self, dur: Option, kind: libc::c_int) -> io::Result<()> { + let timeout = match dur { + Some(dur) => { + if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout")); + } + + let secs = if dur.as_secs() > libc::time_t::max_value() as u64 { + libc::time_t::max_value() + } else { + dur.as_secs() as libc::time_t + }; + let mut timeout = libc::timeval { + tv_sec: secs, + tv_usec: (dur.subsec_nanos() / 1000) as libc::suseconds_t, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => { + libc::timeval { + tv_sec: 0, + tv_usec: 0, + } + } + }; + setsockopt(self, libc::SOL_SOCKET, kind, timeout) + } + + pub fn timeout(&self, kind: libc::c_int) -> io::Result> { + let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?; + if raw.tv_sec == 0 && raw.tv_usec == 0 { + Ok(None) + } else { + let sec = raw.tv_sec as u64; + let nsec = (raw.tv_usec as u32) * 1000; + Ok(Some(Duration::new(sec, nsec))) + } + } + + pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { + let how = match how { + Shutdown::Write => libc::SHUT_WR, + Shutdown::Read => libc::SHUT_RD, + Shutdown::Both => libc::SHUT_RDWR, + }; + cvt(unsafe { libc::shutdown(self.0.raw(), how) })?; + Ok(()) + } + + pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { + setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int) + } + + pub fn nodelay(&self) -> io::Result { + let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?; + Ok(raw != 0) + } + + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + let mut nonblocking = nonblocking as libc::c_int; + cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(|_| ()) + } + + pub fn take_error(&self) -> io::Result> { + let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; + if raw == 0 { + Ok(None) + } else { + Ok(Some(io::Error::from_raw_os_error(raw as i32))) + } + } +} + +impl AsInner for Socket { + fn as_inner(&self) -> &c_int { self.0.as_inner() } +} + +impl FromInner for Socket { + fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) } +} + +impl IntoInner for Socket { + fn into_inner(self) -> c_int { self.0.into_raw() } +} + +// In versions of glibc prior to 2.26, there's a bug where the DNS resolver +// will cache the contents of /etc/resolv.conf, so changes to that file on disk +// can be ignored by a long-running program. That can break DNS lookups on e.g. +// laptops where the network comes and goes. See +// https://sourceware.org/bugzilla/show_bug.cgi?id=984. Note however that some +// distros including Debian have patched glibc to fix this for a long time. +// +// A workaround for this bug is to call the res_init libc function, to clear +// the cached configs. Unfortunately, while we believe glibc's implementation +// of res_init is thread-safe, we know that other implementations are not +// (https://github.com/rust-lang/rust/issues/43592). Code here in libstd could +// try to synchronize its res_init calls with a Mutex, but that wouldn't +// protect programs that call into libc in other ways. So instead of calling +// res_init unconditionally, we call it only when we detect we're linking +// against glibc version < 2.26. (That is, when we both know its needed and +// believe it's thread-safe). +#[cfg(target_env = "gnu")] +fn on_resolver_failure() { +/* + use crate::sys; + + // If the version fails to parse, we treat it the same as "not glibc". + if let Some(version) = sys::os::glibc_version() { + if version < (2, 26) { + unsafe { libc::res_init() }; + } + } + */ +} + +#[cfg(not(target_env = "gnu"))] +fn on_resolver_failure() {} + +#[cfg(all(test, taget_env = "gnu"))] +mod test { + use super::*; + + #[test] + fn test_res_init() { + // This mostly just tests that the weak linkage doesn't panic wildly... + res_init_if_glibc_before_2_26().unwrap(); + } + + #[test] + fn test_parse_glibc_version() { + let cases = [ + ("0.0", Some((0, 0))), + ("01.+2", Some((1, 2))), + ("3.4.5.six", Some((3, 4))), + ("1", None), + ("1.-2", None), + ("1.foo", None), + ("foo.1", None), + ]; + for &(version_str, parsed) in cases.iter() { + assert_eq!(parsed, parse_glibc_version(version_str)); + } + } +} diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/vxworks/os.rs similarity index 52% rename from src/libstd/sys/redox/os.rs rename to src/libstd/sys/vxworks/os.rs index 3ae201f698..5dc35a6176 100644 --- a/src/libstd/sys/redox/os.rs +++ b/src/libstd/sys/vxworks/os.rs @@ -1,72 +1,136 @@ -//! Implementation of `std::os` functionality for unix systems - -#![allow(unused_imports)] // lots of cfg code here - -use libc::c_char; - -use crate::os::unix::prelude::*; - use crate::error::Error as StdError; -use crate::ffi::{CStr, CString, OsStr, OsString}; +use crate::ffi::{CString, CStr, OsString, OsStr}; use crate::fmt; -use crate::io::{self, Read, Write}; +use crate::io; use crate::iter; +use libc::{self, c_int, c_char /*,c_void */}; use crate::marker::PhantomData; use crate::mem; use crate::memchr; -use crate::path::{self, PathBuf}; +use crate::path::{self, PathBuf, Path}; use crate::ptr; use crate::slice; use crate::str; use crate::sys_common::mutex::Mutex; -use crate::sys::{cvt, cvt_libc, fd, syscall}; +use crate::sys::cvt; +/*use sys::fd; this one is probably important */ use crate::vec; -extern { - #[link_name = "__errno_location"] - fn errno_location() -> *mut i32; +const TMPBUF_SZ: usize = 128; +static ENV_LOCK: Mutex = Mutex::new(); + + +// This is a terrible fix +use crate::sys::os_str::Buf; +use crate::sys_common::{FromInner, IntoInner, AsInner}; + +pub trait OsStringExt { + fn from_vec(vec: Vec) -> Self; + fn into_vec(self) -> Vec; } -/// Returns the platform-specific value of errno -pub fn errno() -> i32 { - unsafe { - (*errno_location()) +impl OsStringExt for OsString { + fn from_vec(vec: Vec) -> OsString { + FromInner::from_inner(Buf { inner: vec }) } + fn into_vec(self) -> Vec { + self.into_inner().inner + } +} + +pub trait OsStrExt { + fn from_bytes(slice: &[u8]) -> &Self; + fn as_bytes(&self) -> &[u8]; +} + +impl OsStrExt for OsStr { + fn from_bytes(slice: &[u8]) -> &OsStr { + unsafe { mem::transmute(slice) } + } + fn as_bytes(&self) -> &[u8] { + &self.as_inner().inner + } +} + +pub fn errno() -> i32 { + unsafe { libc::errnoGet() } +} + +pub fn set_errno(e: i32) { + unsafe { libc::errnoSet(e as c_int); } } /// Gets a detailed string description for the given error number. pub fn error_string(errno: i32) -> String { - if let Some(string) = syscall::STR_ERROR.get(errno as usize) { - string.to_string() - } else { - "unknown error".to_string() + let mut buf = [0 as c_char; TMPBUF_SZ]; + extern { + fn strerror_r( + errnum: c_int, + buf: *mut c_char, + buflen: libc::size_t + ) -> c_int; + } + + let p = buf.as_mut_ptr(); + unsafe { + if strerror_r(errno as c_int, p, buf.len()) < 0 { + panic!("strerror_r failure"); + } + let p = p as *const _; + str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() } } pub fn getcwd() -> io::Result { - let mut buf = [0; 4096]; - let count = cvt(syscall::getcwd(&mut buf))?; - Ok(PathBuf::from(OsString::from_vec(buf[.. count].to_vec()))) + let mut buf = Vec::with_capacity(512); + loop { + unsafe { + let ptr = buf.as_mut_ptr() as *mut libc::c_char; + if !libc::getcwd(ptr, buf.capacity() as libc::size_t).is_null() { + let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len(); + buf.set_len(len); + buf.shrink_to_fit(); + return Ok(PathBuf::from(OsString::from_vec(buf))); + } else { + let error = io::Error::last_os_error(); + if error.raw_os_error() != Some(libc::ERANGE) { + return Err(error); + } + } + // Trigger the internal buffer resizing logic of `Vec` by requiring + // more space than the current capacity. + let cap = buf.capacity(); + buf.set_len(cap); + buf.reserve(1); + } + } } pub fn chdir(p: &path::Path) -> io::Result<()> { - cvt(syscall::chdir(p.to_str().unwrap())).and(Ok(())) + let p: &OsStr = p.as_ref(); + let p = CString::new(p.as_bytes())?; + unsafe { + match libc::chdir(p.as_ptr()) == (0 as c_int) { + true => Ok(()), + false => Err(io::Error::last_os_error()), + } + } } pub struct SplitPaths<'a> { iter: iter::Map bool>, - fn(&'a [u8]) -> PathBuf>, + fn(&'a [u8]) -> PathBuf>, } pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> { fn bytes_to_path(b: &[u8]) -> PathBuf { PathBuf::from(::from_bytes(b)) } - fn is_semicolon(b: &u8) -> bool { *b == b';' } + fn is_colon(b: &u8) -> bool { *b == b':' } let unparsed = unparsed.as_bytes(); SplitPaths { - iter: unparsed.split(is_semicolon as fn(&u8) -> bool) - .map(bytes_to_path as fn(&[u8]) -> PathBuf) + iter: unparsed.split(is_colon as fn(&u8) -> bool) + .map(bytes_to_path as fn(&[u8]) -> PathBuf) } } @@ -83,11 +147,13 @@ pub fn join_paths(paths: I) -> Result where I: Iterator, T: AsRef { let mut joined = Vec::new(); - let sep = b';'; + let sep = b':'; for (i, path) in paths.enumerate() { let path = path.as_ref().as_bytes(); - if i > 0 { joined.push(sep) } + if i > 0 { + joined.push(sep) + } if path.contains(&sep) { return Err(JoinPathsError) } @@ -107,22 +173,17 @@ impl StdError for JoinPathsError { } pub fn current_exe() -> io::Result { - use crate::fs::File; - - let mut file = File::open("sys:exe")?; + #[cfg(test)] + use realstd::env; - let mut path = String::new(); - file.read_to_string(&mut path)?; + #[cfg(not(test))] + use crate::env; - if path.ends_with('\n') { - path.pop(); - } - - Ok(PathBuf::from(path)) + let exe_path = env::args().next().unwrap(); + let path = Path::new(&exe_path); + path.canonicalize() } -pub static ENV_LOCK: Mutex = Mutex::new(); - pub struct Env { iter: vec::IntoIter<(OsString, OsString)>, _dont_send_or_sync_me: PhantomData<*mut ()>, @@ -147,7 +208,7 @@ pub fn env() -> Env { let mut environ = *environ(); if environ == ptr::null() { panic!("os::env() failure getting env string from OS: {}", - io::Error::last_os_error()); + io::Error::last_os_error()); } let mut result = Vec::new(); while *environ != ptr::null() { @@ -200,7 +261,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { unsafe { let _guard = ENV_LOCK.lock(); - cvt_libc(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ()) + cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ()) } } @@ -209,12 +270,14 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> { unsafe { let _guard = ENV_LOCK.lock(); - cvt_libc(libc::unsetenv(nbuf.as_ptr())).map(|_| ()) + cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ()) } } pub fn page_size() -> usize { - 4096 + unsafe { + libc::sysconf(libc::_SC_PAGESIZE) as usize + } } pub fn temp_dir() -> PathBuf { @@ -224,18 +287,38 @@ pub fn temp_dir() -> PathBuf { } pub fn home_dir() -> Option { - return crate::env::var_os("HOME").map(PathBuf::from); + return crate::env::var_os("HOME").or_else(|| unsafe { + fallback() + }).map(PathBuf::from); + + unsafe fn fallback() -> Option { + let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { + n if n < 0 => 512 as usize, + n => n as usize, + }; + let mut buf = Vec::with_capacity(amt); + let mut passwd: libc::passwd = mem::zeroed(); + let mut result = ptr::null_mut(); + match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(), + buf.capacity(), &mut result) { + 0 if !result.is_null() => { + let ptr = passwd.pw_dir as *const _; + let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); + Some(OsStringExt::from_vec(bytes)) + }, + _ => None, + } + } } pub fn exit(code: i32) -> ! { - let _ = syscall::exit(code as usize); - unreachable!(); + unsafe { libc::exit(code as c_int) } } pub fn getpid() -> u32 { - syscall::getpid().unwrap() as u32 + unsafe { libc::getpid() as u32 } } pub fn getppid() -> u32 { - syscall::getppid().unwrap() as u32 + unsafe { libc::getppid() as u32 } } diff --git a/src/libstd/sys/vxworks/path.rs b/src/libstd/sys/vxworks/path.rs new file mode 100644 index 0000000000..7a18395610 --- /dev/null +++ b/src/libstd/sys/vxworks/path.rs @@ -0,0 +1,19 @@ +use crate::path::Prefix; +use crate::ffi::OsStr; + +#[inline] +pub fn is_sep_byte(b: u8) -> bool { + b == b'/' +} + +#[inline] +pub fn is_verbatim_sep(b: u8) -> bool { + b == b'/' +} + +pub fn parse_prefix(_: &OsStr) -> Option> { + None +} + +pub const MAIN_SEP_STR: &str = "/"; +pub const MAIN_SEP: char = '/'; diff --git a/src/libstd/sys/vxworks/pipe.rs b/src/libstd/sys/vxworks/pipe.rs new file mode 100644 index 0000000000..e09dbe6e99 --- /dev/null +++ b/src/libstd/sys/vxworks/pipe.rs @@ -0,0 +1,95 @@ +use crate::io::{self, IoSlice, IoSliceMut}; +use libc::{self /*, c_int apparently not used? */}; +use crate::mem; +use crate::sync::atomic::{AtomicBool}; +use crate::sys::fd::FileDesc; +use crate::sys::{cvt, cvt_r}; + +pub struct AnonPipe(FileDesc); + +pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { + static INVALID: AtomicBool = AtomicBool::new(false); + + let mut fds = [0; 2]; + cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?; + + let fd0 = FileDesc::new(fds[0]); + let fd1 = FileDesc::new(fds[1]); + fd0.set_cloexec()?; + fd1.set_cloexec()?; + Ok((AnonPipe(fd0), AnonPipe(fd1))) +} + +impl AnonPipe { + pub fn read(&self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + + pub fn write(&self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + pub fn fd(&self) -> &FileDesc { &self.0 } + pub fn into_fd(self) -> FileDesc { self.0 } + pub fn diverge(&self) -> ! { + panic!() + } +} + +pub fn read2(p1: AnonPipe, + v1: &mut Vec, + p2: AnonPipe, + v2: &mut Vec) -> io::Result<()> { + + // Set both pipes into nonblocking mode as we're gonna be reading from both + // in the `select` loop below, and we wouldn't want one to block the other! + let p1 = p1.into_fd(); + let p2 = p2.into_fd(); + p1.set_nonblocking_pipe(true)?; + p2.set_nonblocking_pipe(true)?; + + let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() }; + fds[0].fd = p1.raw(); + fds[0].events = libc::POLLIN; + fds[1].fd = p2.raw(); + fds[1].events = libc::POLLIN; + loop { + // wait for either pipe to become readable using `poll` + cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?; + + if fds[0].revents != 0 && read(&p1, v1)? { + p2.set_nonblocking_pipe(false)?; + return p2.read_to_end(v2).map(|_| ()); + } + if fds[1].revents != 0 && read(&p2, v2)? { + p1.set_nonblocking_pipe(false)?; + return p1.read_to_end(v1).map(|_| ()); + } + } + + // Read as much as we can from each pipe, ignoring EWOULDBLOCK or + // EAGAIN. If we hit EOF, then this will happen because the underlying + // reader will return Ok(0), in which case we'll see `Ok` ourselves. In + // this case we flip the other fd back into blocking mode and read + // whatever's leftover on that file descriptor. + fn read(fd: &FileDesc, dst: &mut Vec) -> Result { + match fd.read_to_end(dst) { + Ok(_) => Ok(true), + Err(e) => { + if e.raw_os_error() == Some(libc::EWOULDBLOCK) || + e.raw_os_error() == Some(libc::EAGAIN) { + Ok(false) + } else { + Err(e) + } + } + } + } +} diff --git a/src/libstd/sys/vxworks/process/mod.rs b/src/libstd/sys/vxworks/process/mod.rs new file mode 100644 index 0000000000..4dc706006f --- /dev/null +++ b/src/libstd/sys/vxworks/process/mod.rs @@ -0,0 +1,7 @@ +pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes}; +pub use self::process_inner::Process; + +mod process_common; +#[path = "process_vxworks.rs"] +mod process_inner; +mod rtp; diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs new file mode 100644 index 0000000000..397200c39c --- /dev/null +++ b/src/libstd/sys/vxworks/process/process_common.rs @@ -0,0 +1,405 @@ +use crate::os::unix::prelude::*; + +use crate::ffi::{OsString, OsStr, CString, CStr}; +use crate::fmt; +use crate::io; +use crate::ptr; +use crate::sys::fd::FileDesc; +use crate::sys::fs::{File, OpenOptions}; +use crate::sys::pipe::{self, AnonPipe}; +use crate::sys_common::process::{CommandEnv, DefaultEnvKey}; +use crate::collections::BTreeMap; + +use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; + +//////////////////////////////////////////////////////////////////////////////// +// Command +//////////////////////////////////////////////////////////////////////////////// + +pub struct Command { + // Currently we try hard to ensure that the call to `.exec()` doesn't + // actually allocate any memory. While many platforms try to ensure that + // memory allocation works after a fork in a multithreaded process, it's + // been observed to be buggy and somewhat unreliable, so we do our best to + // just not do it at all! + // + // Along those lines, the `argv` and `envp` raw pointers here are exactly + // what's gonna get passed to `execvp`. The `argv` array starts with the + // `program` and ends with a NULL, and the `envp` pointer, if present, is + // also null-terminated. + // + // Right now we don't support removing arguments, so there's no much fancy + // support there, but we support adding and removing environment variables, + // so a side table is used to track where in the `envp` array each key is + // located. Whenever we add a key we update it in place if it's already + // present, and whenever we remove a key we update the locations of all + // other keys. + program: CString, + args: Vec, + argv: Argv, + env: CommandEnv, + + cwd: Option, + uid: Option, + gid: Option, + saw_nul: bool, + closures: Vec io::Result<()> + Send + Sync>>, + stdin: Option, + stdout: Option, + stderr: Option, +} + +// Create a new type for argv, so that we can make it `Send` +struct Argv(Vec<*const c_char>); + +// It is safe to make Argv Send, because it contains pointers to memory owned by `Command.args` +unsafe impl Send for Argv {} + +// passed back to std::process with the pipes connected to the child, if any +// were requested +pub struct StdioPipes { + pub stdin: Option, + pub stdout: Option, + pub stderr: Option, +} + +// passed to do_exec() with configuration of what the child stdio should look +// like +pub struct ChildPipes { + pub stdin: ChildStdio, + pub stdout: ChildStdio, + pub stderr: ChildStdio, +} + +pub enum ChildStdio { + Inherit, + Explicit(c_int), + Owned(FileDesc), +} + +pub enum Stdio { + Inherit, + Null, + MakePipe, + Fd(FileDesc), +} + +impl Command { + pub fn new(program: &OsStr) -> Command { + let mut saw_nul = false; + let program = os2c(program, &mut saw_nul); + Command { + argv: Argv(vec![program.as_ptr(), ptr::null()]), + program, + args: Vec::new(), + env: Default::default(), + cwd: None, + uid: None, + gid: None, + saw_nul, + closures: Vec::new(), + stdin: None, + stdout: None, + stderr: None, + } + } + + pub fn arg(&mut self, arg: &OsStr) { + // Overwrite the trailing NULL pointer in `argv` and then add a new null + // pointer. + let arg = os2c(arg, &mut self.saw_nul); + self.argv.0[self.args.len() + 1] = arg.as_ptr(); + self.argv.0.push(ptr::null()); + + // Also make sure we keep track of the owned value to schedule a + // destructor for this memory. + self.args.push(arg); + } + + pub fn cwd(&mut self, dir: &OsStr) { + self.cwd = Some(os2c(dir, &mut self.saw_nul)); + } + pub fn uid(&mut self, id: uid_t) { + self.uid = Some(id); + } + pub fn gid(&mut self, id: gid_t) { + self.gid = Some(id); + } + + pub fn saw_nul(&self) -> bool { + self.saw_nul + } + pub fn get_argv(&self) -> &Vec<*const c_char> { + &self.argv.0 + } + + #[allow(dead_code)] + pub fn get_cwd(&self) -> &Option { + &self.cwd + } + #[allow(dead_code)] + pub fn get_uid(&self) -> Option { + self.uid + } + #[allow(dead_code)] + pub fn get_gid(&self) -> Option { + self.gid + } + + pub fn get_closures(&mut self) -> &mut Vec io::Result<()> + Send + Sync>> { + &mut self.closures + } + + pub unsafe fn pre_exec( + &mut self, + _f: Box io::Result<()> + Send + Sync>, + ) { + // Fork() is not supported in vxWorks so no way to run the closure in the new procecss. + unimplemented!();; + } + + pub fn stdin(&mut self, stdin: Stdio) { + self.stdin = Some(stdin); + } + + pub fn stdout(&mut self, stdout: Stdio) { + self.stdout = Some(stdout); + } + + pub fn stderr(&mut self, stderr: Stdio) { + self.stderr = Some(stderr); + } + + pub fn env_mut(&mut self) -> &mut CommandEnv { + &mut self.env + } + + pub fn capture_env(&mut self) -> Option { + let maybe_env = self.env.capture_if_changed(); + maybe_env.map(|env| construct_envp(env, &mut self.saw_nul)) + } + #[allow(dead_code)] + pub fn env_saw_path(&self) -> bool { + self.env.have_changed_path() + } + + pub fn setup_io(&self, default: Stdio, needs_stdin: bool) + -> io::Result<(StdioPipes, ChildPipes)> { + let null = Stdio::Null; + let default_stdin = if needs_stdin {&default} else {&null}; + let stdin = self.stdin.as_ref().unwrap_or(default_stdin); + let stdout = self.stdout.as_ref().unwrap_or(&default); + let stderr = self.stderr.as_ref().unwrap_or(&default); + let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?; + let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?; + let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?; + let ours = StdioPipes { + stdin: our_stdin, + stdout: our_stdout, + stderr: our_stderr, + }; + let theirs = ChildPipes { + stdin: their_stdin, + stdout: their_stdout, + stderr: their_stderr, + }; + Ok((ours, theirs)) + } +} + +fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString { + CString::new(s.as_bytes()).unwrap_or_else(|_e| { + *saw_nul = true; + CString::new("").unwrap() + }) +} + +// Helper type to manage ownership of the strings within a C-style array. +pub struct CStringArray { + items: Vec, + ptrs: Vec<*const c_char> +} + +impl CStringArray { + pub fn with_capacity(capacity: usize) -> Self { + let mut result = CStringArray { + items: Vec::with_capacity(capacity), + ptrs: Vec::with_capacity(capacity+1) + }; + result.ptrs.push(ptr::null()); + result + } + pub fn push(&mut self, item: CString) { + let l = self.ptrs.len(); + self.ptrs[l-1] = item.as_ptr(); + self.ptrs.push(ptr::null()); + self.items.push(item); + } + pub fn as_ptr(&self) -> *const *const c_char { + self.ptrs.as_ptr() + } +} + +fn construct_envp(env: BTreeMap, saw_nul: &mut bool) -> CStringArray { + let mut result = CStringArray::with_capacity(env.len()); + for (k, v) in env { + let mut k: OsString = k.into(); + + // Reserve additional space for '=' and null terminator + k.reserve_exact(v.len() + 2); + k.push("="); + k.push(&v); + + // Add the new entry into the array + if let Ok(item) = CString::new(k.into_vec()) { + result.push(item); + } else { + *saw_nul = true; + } + } + + result +} + +impl Stdio { + pub fn to_child_stdio(&self, readable: bool) + -> io::Result<(ChildStdio, Option)> { + match *self { + Stdio::Inherit => { + Ok((ChildStdio::Inherit, None)) + }, + + // Make sure that the source descriptors are not an stdio + // descriptor, otherwise the order which we set the child's + // descriptors may blow away a descriptor which we are hoping to + // save. For example, suppose we want the child's stderr to be the + // parent's stdout, and the child's stdout to be the parent's + // stderr. No matter which we dup first, the second will get + // overwritten prematurely. + Stdio::Fd(ref fd) => { + if fd.raw() >= 0 && fd.raw() <= libc::STDERR_FILENO { + Ok((ChildStdio::Owned(fd.duplicate()?), None)) + } else { + Ok((ChildStdio::Explicit(fd.raw()), None)) + } + } + + Stdio::MakePipe => { + let (reader, writer) = pipe::anon_pipe()?; + let (ours, theirs) = if readable { + (writer, reader) + } else { + (reader, writer) + }; + Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours))) + } + + Stdio::Null => { + let mut opts = OpenOptions::new(); + opts.read(readable); + opts.write(!readable); + let path = unsafe { + CStr::from_ptr("/null\0".as_ptr() as *const _) + }; + let fd = File::open_c(&path, &opts)?; + Ok((ChildStdio::Owned(fd.into_fd()), None)) + } + } + } +} + +impl From for Stdio { + fn from(pipe: AnonPipe) -> Stdio { + Stdio::Fd(pipe.into_fd()) + } +} + +impl From for Stdio { + fn from(file: File) -> Stdio { + Stdio::Fd(file.into_fd()) + } +} + +impl ChildStdio { + pub fn fd(&self) -> Option { + match *self { + ChildStdio::Inherit => None, + ChildStdio::Explicit(fd) => Some(fd), + ChildStdio::Owned(ref fd) => Some(fd.raw()), + } + } +} + +impl fmt::Debug for Command { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.program)?; + for arg in &self.args { + write!(f, " {:?}", arg)?; + } + Ok(()) + } +} + +/// Unix exit statuses +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitStatus(c_int); + +impl ExitStatus { + pub fn new(status: c_int) -> ExitStatus { + ExitStatus(status) + } + + fn exited(&self) -> bool { + /*unsafe*/ { libc::WIFEXITED(self.0) } + } + + pub fn success(&self) -> bool { + self.code() == Some(0) + } + + pub fn code(&self) -> Option { + if self.exited() { + Some(/*unsafe*/ { libc::WEXITSTATUS(self.0) }) + } else { + None + } + } + + pub fn signal(&self) -> Option { + if !self.exited() { + Some(/*unsafe*/ { libc::WTERMSIG(self.0) }) + } else { + None + } + } +} + +impl From for ExitStatus { + fn from(a: c_int) -> ExitStatus { + ExitStatus(a) + } +} + +impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(code) = self.code() { + write!(f, "exit code: {}", code) + } else { + let signal = self.signal().unwrap(); + write!(f, "signal: {}", signal) + } + } +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(u8); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); + pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _); + + #[inline] + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs new file mode 100644 index 0000000000..b07966fa20 --- /dev/null +++ b/src/libstd/sys/vxworks/process/process_vxworks.rs @@ -0,0 +1,156 @@ +use crate::io::{self, Error, ErrorKind}; +use libc::{self, c_int, c_char}; +use libc::{RTP_ID}; +use crate::sys; +use crate::sys::cvt; +use crate::sys::process::rtp; +use crate::sys::process::process_common::*; + +//////////////////////////////////////////////////////////////////////////////// +// Command +//////////////////////////////////////////////////////////////////////////////// + +impl Command { + pub fn spawn(&mut self, default: Stdio, needs_stdin: bool) + -> io::Result<(Process, StdioPipes)> { + use crate::sys::{cvt_r}; + const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX"; + + if self.saw_nul() { + return Err(io::Error::new(ErrorKind::InvalidInput, + "nul byte found in provided data")); + } + let (ours, theirs) = self.setup_io(default, needs_stdin)?; + let mut p = Process { pid: 0, status: None }; + + unsafe { + macro_rules! t { + ($e:expr) => (match $e { + Ok(e) => e, + Err(e) => return Err(e.into()), + }) + } + + let mut orig_stdin = libc::STDIN_FILENO; + let mut orig_stdout = libc::STDOUT_FILENO; + let mut orig_stderr = libc::STDERR_FILENO; + + if let Some(fd) = theirs.stdin.fd() { + orig_stdin = t!(cvt_r(|| libc::dup(libc::STDIN_FILENO))); + t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))); + } + if let Some(fd) = theirs.stdout.fd() { + orig_stdout = t!(cvt_r(|| libc::dup(libc::STDOUT_FILENO))); + t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))); + } + if let Some(fd) = theirs.stderr.fd() { + orig_stderr = t!(cvt_r(|| libc::dup(libc::STDERR_FILENO))); + t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); + } + + if let Some(ref cwd) = *self.get_cwd() { + t!(cvt(libc::chdir(cwd.as_ptr()))); + } + + let ret = rtp::rtpSpawn( + self.get_argv()[0], // executing program + self.get_argv().as_ptr() as *const _, // argv + *sys::os::environ() as *const *const c_char, + 100 as c_int, // initial priority + 0x16000, // initial stack size. 0 defaults + // to 0x4000 in 32 bit and 0x8000 in 64 bit + 0, // options + 0 // task options + ); + + // Because FileDesc was not used, each duplicated file descriptor + // needs to be closed manually + if orig_stdin != libc::STDIN_FILENO { + t!(cvt_r(|| libc::dup2(orig_stdin, libc::STDIN_FILENO))); + libc::close(orig_stdin); + } + if orig_stdout != libc::STDOUT_FILENO { + t!(cvt_r(|| libc::dup2(orig_stdout, libc::STDOUT_FILENO))); + libc::close(orig_stdout); + } + if orig_stderr != libc::STDERR_FILENO { + t!(cvt_r(|| libc::dup2(orig_stderr, libc::STDERR_FILENO))); + libc::close(orig_stderr); + } + + if ret != rtp::RTP_ID_ERROR { + p.pid = ret; + Ok((p, ours)) + } else { + Err(io::Error::last_os_error()) + } + } + } + + pub fn exec(&mut self, default: Stdio) -> io::Error { + let ret = Command::spawn(self, default, false); + match ret { + Ok(t) => unsafe { + let mut status = 0 as c_int; + libc::waitpid(t.0.pid, &mut status, 0); + libc::exit(0); + }, + Err(e) => e, + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Processes +//////////////////////////////////////////////////////////////////////////////// + +/// The unique id of the process (this should never be negative). +pub struct Process { + pid: RTP_ID, + status: Option, +} + +impl Process { + pub fn id(&self) -> u32 { + self.pid as u32 + } + + pub fn kill(&mut self) -> io::Result<()> { + // If we've already waited on this process then the pid can be recycled + // and used for another process, and we probably shouldn't be killing + // random processes, so just return an error. + if self.status.is_some() { + Err(Error::new(ErrorKind::InvalidInput, + "invalid argument: can't kill an exited process")) + } else { + cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(|_| ()) + } + } + + pub fn wait(&mut self) -> io::Result { + use crate::sys::cvt_r; + if let Some(status) = self.status { + return Ok(status) + } + let mut status = 0 as c_int; + cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) })?; + self.status = Some(ExitStatus::new(status)); + Ok(ExitStatus::new(status)) + } + + pub fn try_wait(&mut self) -> io::Result> { + if let Some(status) = self.status { + return Ok(Some(status)) + } + let mut status = 0 as c_int; + let pid = cvt(unsafe { + libc::waitpid(self.pid, &mut status, libc::WNOHANG) + })?; + if pid == 0 { + Ok(None) + } else { + self.status = Some(ExitStatus::new(status)); + Ok(Some(ExitStatus::new(status))) + } + } +} diff --git a/src/libstd/sys/vxworks/process/rtp.rs b/src/libstd/sys/vxworks/process/rtp.rs new file mode 100644 index 0000000000..3e6e0017ab --- /dev/null +++ b/src/libstd/sys/vxworks/process/rtp.rs @@ -0,0 +1,298 @@ +#![allow(non_camel_case_types, unused)] + +use libc::{self, c_int, size_t, c_char, BOOL, RTP_DESC, RTP_ID, TASK_ID}; + + +// Copied directly from rtpLibCommon.h, rtpLib.h, signal.h and taskLibCommon.h (for task options) + +// **** definitions for rtpLibCommon.h **** + +pub const RTP_GLOBAL_SYMBOLS : c_int = 0x01; // register global symbols for RTP +pub const RTP_LOCAL_SYMBOLS : c_int = 0x02; // idem for local symbols +pub const RTP_ALL_SYMBOLS : c_int = (RTP_GLOBAL_SYMBOLS | RTP_LOCAL_SYMBOLS); +pub const RTP_DEBUG : c_int = 0x10; // set RTP in debug mode when created +pub const RTP_BUFFER_VAL_OFF : c_int = 0x20; // disable buffer validation for all + // system calls issued from the RTP +pub const RTP_LOADED_WAIT : c_int = 0x40; // Wait until the RTP is loaded +pub const RTP_CPU_AFFINITY_NONE : c_int = 0x80; // Remove any CPU affinity (SMP) + +// Error Status codes + +pub const M_rtpLib : c_int = 178 << 16; + +pub const S_rtpLib_INVALID_FILE : c_int = (M_rtpLib | 1); +pub const S_rtpLib_INVALID_OPTION : c_int = (M_rtpLib | 2); +pub const S_rtpLib_ACCESS_DENIED : c_int = (M_rtpLib | 3); +pub const S_rtpLib_INVALID_RTP_ID : c_int = (M_rtpLib | 4); +pub const S_rtpLib_NO_SYMBOL_TABLE : c_int = (M_rtpLib | 5); +pub const S_rtpLib_INVALID_SEGMENT_START_ADDRESS : c_int = (M_rtpLib | 6); +pub const S_rtpLib_INVALID_SYMBOL_REGISTR_POLICY : c_int = (M_rtpLib | 7); +pub const S_rtpLib_INSTANTIATE_FAILED : c_int = (M_rtpLib | 8); +pub const S_rtpLib_INVALID_TASK_OPTION : c_int = (M_rtpLib | 9); +pub const S_rtpLib_RTP_NAME_LENGTH_EXCEEDED : c_int = (M_rtpLib | 10); // rtpInfoGet + +pub const VX_RTP_NAME_LENGTH : c_int = 255; // max name length for diplay + + +// The 'status' field (32 bit integer) of a RTP holds the RTP state and status. +// +// NOTE: RTP_STATE_GET() : read the RTP state(s) +// RTP_STATE_PUT() : write the RTP state(s) +// RTP_STATE_SET() : set a RTP state +// RTP_STATE_UNSET() : unset a RTP state +// +// RTP_STATUS_GET() : read the RTP status +// RTP_STATUS_PUT() : write the RTP status +// RTP_STATUS_SET() : set a RTP status +// RTP_STATUS_UNSET() : unset a RTP status +// +// The PUT/SET/UNSET macros are available only in the kernel headers. + + +// RTP states + +pub const RTP_STATE_CREATE : c_int = 0x0001; // RrtpStructTP is under construction +pub const RTP_STATE_NORMAL : c_int = 0x0002; // RrtpStructTP is ready +pub const RTP_STATE_DELETE : c_int = 0x0004; // RrtpStructTP is being deleted + +pub const RTP_STATUS_STOP : c_int = 0x0100; // RTP hrtpStructas recieved stopped signal +pub const RTP_STATUS_ELECTED_DELETER : c_int = 0x0200; // RTP drtpStructelete has started + +pub const RTP_STATE_MASK : c_int = (RTP_STATE_CREATE | RTP_STATE_NORMAL | + RTP_STATE_DELETE); +pub const RTP_STATUS_MASK : c_int = (RTP_STATUS_STOP | RTP_STATUS_ELECTED_DELETER); + +pub fn RTP_STATE_GET (value : c_int) -> c_int { + value & RTP_STATE_MASK +} +pub fn RTP_STATUS_GET (value : c_int) -> c_int { + value & RTP_STATUS_MASK +} + +// Indicates that the RTP_ID returned is not valid. + +// RTP_ID_ERROR is supposed to be set to -1, but you can't set +// an unsigned value to a negative without casting, and you +// can't cast unless the size of the integer types are the same, +// but the size of RTP_ID may differ between kernel and user space. +// Bitwise or-ing min and max should get the same result. +pub const RTP_ID_ERROR : RTP_ID = RTP_ID::min_value() | RTP_ID::max_value(); + +// IS_RTP_ C macros + +pub fn IS_RTP_STATE_NORMAL (value : c_int) -> bool { + (RTP_STATE_GET(value) & RTP_STATE_NORMAL) == RTP_STATE_NORMAL +} +pub fn IS_RTP_STATE_CREATE (value : c_int) -> bool { + (RTP_STATE_GET(value) & RTP_STATE_CREATE) == RTP_STATE_CREATE +} +pub fn IS_RTP_STATE_DELETE (value : c_int) -> bool { + (RTP_STATE_GET(value) & RTP_STATE_DELETE) == RTP_STATE_DELETE +} +pub fn IS_RTP_STATUS_STOP (value : c_int) -> bool { + (RTP_STATUS_GET(value) & RTP_STATUS_STOP ) == RTP_STATUS_STOP +} +pub fn IS_RTP_STATUS_ELECTED_DELETER (value : c_int) -> bool { + (RTP_STATUS_GET(value) & RTP_STATUS_ELECTED_DELETER) == RTP_STATUS_ELECTED_DELETER +} + +// **** end of definitions for rtpLibCommon.h **** + + + + +// **** definitions for rtpLib.h **** + +pub fn rtpExit(exitCode : c_int) -> ! { + unsafe{ libc::exit (exitCode) } +} + +/* rtpLib.h in the kernel +pub const RTP_DEL_VIA_TASK_DELETE : c_int = 0x1; // rtpDelete() via taskDestroy() +pub const RTP_DEL_FORCE : c_int = 0x2; // Forceful rtpDelete() +pub const RTP_ID_ANY : RTP_ID = 0; // used for when a kernel task + // wants to wait for the next + // RTP to finish + + +// Function pointers + +pub type RTP_PRE_CREATE_HOOK = size_t; +pub type RTP_POST_CREATE_HOOK = size_t; +pub type RTP_INIT_COMPLETE_HOOK = size_t; +pub type RTP_DELETE_HOOK = size_t; +*/ + +// **** end of definitions for rtpLib.h **** + + + + + +// **** definitions for signal.h **** +pub fn rtpKill(rtpId : RTP_ID, signo : c_int) -> c_int { + unsafe{ libc::kill(rtpId as c_int, signo) } +} + +pub fn rtpSigqueue(rtpId : RTP_ID, signo : c_int, value : size_t) -> c_int { + unsafe{ libc::sigqueue(rtpId as c_int, signo, value) } +} + +pub fn _rtpSigqueue(rtpId : RTP_ID, signo : c_int, value : *mut size_t, code : c_int) -> c_int { + unsafe{ libc::_sigqueue(rtpId, signo, value, code) } +} + +pub fn taskRaise(signo : c_int) -> c_int { + unsafe{ libc::taskKill(libc::taskIdSelf(), signo) } +} +pub fn rtpRaise(signo : c_int) -> c_int { + unsafe{ libc::raise(signo) } +} + +// **** end of definitions for signal.h **** + + + +// **** definitions for taskLibCommon.h **** +pub const VX_PRIVATE_ENV : c_int = 0x0080; // 1 = private environment variables +pub const VX_NO_STACK_FILL : c_int = 0x0100; // 1 = avoid stack fill of 0xee +pub const VX_PRIVATE_UMASK : c_int = 0x0400; // 1 = private file creation mode mask +pub const VX_TASK_NOACTIVATE : c_int = 0x2000; // taskOpen() does not taskActivate() +pub const VX_NO_STACK_PROTECT : c_int = 0x4000; // no over/underflow stack protection, + // stack space remains executable + +// define for all valid user task options + +pub const VX_USR_TASK_OPTIONS_BASE: c_int = (VX_PRIVATE_ENV | + VX_NO_STACK_FILL | + VX_TASK_NOACTIVATE | + VX_NO_STACK_PROTECT | + VX_PRIVATE_UMASK); + +// **** end of definitions for taskLibCommon.h **** + + + +extern "C" { +// functions in rtpLibCommon.h + +// forward declarations + pub fn rtpSpawn ( + pubrtpFileName : *const c_char, + argv : *const *const c_char, + envp : *const *const c_char, + priority : c_int, + uStackSize : size_t, + options : c_int, + taskOptions : c_int, + ) -> RTP_ID; + + pub fn rtpInfoGet ( + rtpId : RTP_ID, + rtpStruct : *mut RTP_DESC, + ) -> c_int; + +/* functions in rtpLib.h for kernel + + + // function declarations + + pub fn rtpDelete ( + id : RTP_ID, + options : c_int, + status : c_int, + ) -> c_int; + + pub fn rtpDeleteForce ( + rtpId : RTP_ID + ) -> c_int; + + pub fn rtpShow ( + rtpNameOrId : *mut c_char, + level : c_int, + ) -> BOOL; + + // RTP signals are always present when RTPs are included. The public RTP + // signal APIs are declared here. + + + pub fn rtpKill ( + rtpId : RTP_ID, + signo : c_int, + ) -> c_int; + + pub fn rtpSigqueue ( + rtpId : RTP_ID, + signo : c_int, + value : size_t, // Actual type is const union sigval value, + // which is a union of int and void * + ) -> c_int; + + pub fn rtpTaskKill ( + tid : TASK_ID, + signo : c_int, + ) -> c_int; + + pub fn rtpTaskSigqueue ( + tid : TASK_ID, + signo : c_int, + value : const size_t, // Actual type is const union sigval, + // which is a union of int and void * + ) -> c_int; + + pub fn rtpWait ( + rtpWaitId : RTP_ID, + timeout : libc::alloc_jemalloc_Vx_ticks_t, + pRtpId : *mut RTP_ID, + pStatus : *mut c_int, + ) -> c_int; + + // Other public functions + + + pub fn rtpPreCreateHookAdd ( + hook : RTP_PRE_CREATE_HOOK, + addToHead : BOOL, + ) -> c_int; + + pub fn rtpPreCreateHookDelete ( + hook : RTP_POST_CREATE_HOOK, + ) -> c_int; + + pub fn rtpPostCreateHookAdd ( + hook : RTP_POST_CREATE_HOOK, + addToHead : BOOL, + ) -> c_int; + + pub fn rtpPostCreateHookDelete ( + hook : RTP_POST_CREATE_HOOK, + ) -> c_int; + + pub fn rtpInitCompleteHookAdd ( + hook : RTP_INIT_COMPLETE_HOOK, + addToHead : BOOL, + ) -> c_int; + + pub fn rtpInitCompleteHookDelete ( + hook : RTP_INIT_COMPLETE_HOOK, + ) -> c_int; + + pub fn rtpDeleteHookAdd ( + hook : RTP_DELETE_HOOK, + addToHead : BOOL, + ) -> c_int; + + pub fn rtpDeleteHookDelete ( + hook : RTP_DELETE_HOOK, + ) -> c_int; + + pub fn rtpMemShow ( + rtpNameOrId : *mut c_char, + level : c_int, + ) -> c_int; + + pub fn rtpHookShow ( + + ); +*/ +} diff --git a/src/libstd/sys/vxworks/rand.rs b/src/libstd/sys/vxworks/rand.rs new file mode 100644 index 0000000000..1ec0cbe4dc --- /dev/null +++ b/src/libstd/sys/vxworks/rand.rs @@ -0,0 +1,31 @@ +use crate::mem; +use crate::slice; + +pub fn hashmap_random_keys() -> (u64, u64) { + let mut v = (0, 0); + unsafe { + let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, + mem::size_of_val(&v)); + imp::fill_bytes(view); + } + return v +} + +mod imp { + use libc; + use crate::io; + + extern "C" { + fn randBytes (randBuf: *mut libc::c_uchar, + numOfBytes: libc::c_int) -> libc::c_int; + } + + pub fn fill_bytes(v: &mut [u8]) { + let ret = unsafe { + randBytes(v.as_mut_ptr() as *mut libc::c_uchar, v.len() as libc::c_int) + }; + if ret == -1 { + panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); + } + } +} diff --git a/src/libstd/sys/vxworks/rwlock.rs b/src/libstd/sys/vxworks/rwlock.rs new file mode 100644 index 0000000000..718f422ed1 --- /dev/null +++ b/src/libstd/sys/vxworks/rwlock.rs @@ -0,0 +1,113 @@ +use libc; +use crate::cell::UnsafeCell; +use crate::sync::atomic::{AtomicUsize, Ordering}; + +pub struct RWLock { + inner: UnsafeCell, + write_locked: UnsafeCell, + num_readers: AtomicUsize, +} + +unsafe impl Send for RWLock {} +unsafe impl Sync for RWLock {} + +impl RWLock { + pub const fn new() -> RWLock { + RWLock { + inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER), + write_locked: UnsafeCell::new(false), + num_readers: AtomicUsize::new(0), + } + } + + #[inline] + pub unsafe fn read(&self) { + let r = libc::pthread_rwlock_rdlock(self.inner.get()); + if r == libc::EAGAIN { + panic!("rwlock maximum reader count exceeded"); + } else if r == libc::EDEADLK || *self.write_locked.get() { + if r == 0 { + self.raw_unlock(); + } + panic!("rwlock read lock would result in deadlock"); + } else { + debug_assert_eq!(r, 0); + self.num_readers.fetch_add(1, Ordering::Relaxed); + } + } + + #[inline] + pub unsafe fn try_read(&self) -> bool { + let r = libc::pthread_rwlock_tryrdlock(self.inner.get()); + if r == 0 { + if *self.write_locked.get() { + self.raw_unlock(); + false + } else { + self.num_readers.fetch_add(1, Ordering::Relaxed); + true + } + } else { + false + } + } + + #[inline] + pub unsafe fn write(&self) { + let r = libc::pthread_rwlock_wrlock(self.inner.get()); + // See comments above for why we check for EDEADLK and write_locked. We + // also need to check that num_readers is 0. + if r == libc::EDEADLK || *self.write_locked.get() || + self.num_readers.load(Ordering::Relaxed) != 0 { + if r == 0 { + self.raw_unlock(); + } + panic!("rwlock write lock would result in deadlock"); + } else { + debug_assert_eq!(r, 0); + } + *self.write_locked.get() = true; + } + + #[inline] + pub unsafe fn try_write(&self) -> bool { + let r = libc::pthread_rwlock_trywrlock(self.inner.get()); + if r == 0 { + if *self.write_locked.get() || self.num_readers.load(Ordering::Relaxed) != 0 { + self.raw_unlock(); + false + } else { + *self.write_locked.get() = true; + true + } + } else { + false + } + } + + #[inline] + unsafe fn raw_unlock(&self) { + let r = libc::pthread_rwlock_unlock(self.inner.get()); + debug_assert_eq!(r, 0); + } + + #[inline] + pub unsafe fn read_unlock(&self) { + debug_assert!(!*self.write_locked.get()); + self.num_readers.fetch_sub(1, Ordering::Relaxed); + self.raw_unlock(); + } + + #[inline] + pub unsafe fn write_unlock(&self) { + debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0); + debug_assert!(*self.write_locked.get()); + *self.write_locked.get() = false; + self.raw_unlock(); + } + #[inline] + pub unsafe fn destroy(&self) { + let r = libc::pthread_rwlock_destroy(self.inner.get()); + debug_assert_eq!(r, 0); + } +} diff --git a/src/libstd/sys/vxworks/stack_overflow.rs b/src/libstd/sys/vxworks/stack_overflow.rs new file mode 100644 index 0000000000..08e7b310ca --- /dev/null +++ b/src/libstd/sys/vxworks/stack_overflow.rs @@ -0,0 +1,41 @@ +#![cfg_attr(test, allow(dead_code))] + +use self::imp::{make_handler, drop_handler}; + +pub use self::imp::cleanup; +pub use self::imp::init; + +pub struct Handler { + _data: *mut libc::c_void +} + +impl Handler { + pub unsafe fn new() -> Handler { + make_handler() + } +} + +impl Drop for Handler { + fn drop(&mut self) { + unsafe { + drop_handler(self); + } + } +} + +mod imp { + use crate::ptr; + + pub unsafe fn init() { + } + + pub unsafe fn cleanup() { + } + + pub unsafe fn make_handler() -> super::Handler { + super::Handler { _data: ptr::null_mut() } + } + + pub unsafe fn drop_handler(_handler: &mut super::Handler) { + } +} diff --git a/src/libstd/sys/redox/stdio.rs b/src/libstd/sys/vxworks/stdio.rs similarity index 73% rename from src/libstd/sys/redox/stdio.rs rename to src/libstd/sys/vxworks/stdio.rs index 33f5bdbb5d..35f163bbdb 100644 --- a/src/libstd/sys/redox/stdio.rs +++ b/src/libstd/sys/vxworks/stdio.rs @@ -1,5 +1,4 @@ use crate::io; -use crate::sys::{cvt, syscall}; use crate::sys::fd::FileDesc; pub struct Stdin(()); @@ -12,9 +11,9 @@ impl Stdin { impl io::Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result { - let fd = FileDesc::new(0); + let fd = FileDesc::new(libc::STDIN_FILENO); let ret = fd.read(buf); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } } @@ -25,14 +24,14 @@ impl Stdout { impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result { - let fd = FileDesc::new(1); + let fd = FileDesc::new(libc::STDOUT_FILENO); let ret = fd.write(buf); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } fn flush(&mut self) -> io::Result<()> { - cvt(syscall::fsync(1)).and(Ok(())) + Ok(()) } } @@ -42,19 +41,19 @@ impl Stderr { impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result { - let fd = FileDesc::new(2); + let fd = FileDesc::new(libc::STDERR_FILENO); let ret = fd.write(buf); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } fn flush(&mut self) -> io::Result<()> { - cvt(syscall::fsync(2)).and(Ok(())) + Ok(()) } } pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(crate::sys::syscall::EBADF as i32) + err.raw_os_error() == Some(libc::EBADF as i32) } pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE; diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs new file mode 100644 index 0000000000..58af8cbe48 --- /dev/null +++ b/src/libstd/sys/vxworks/thread.rs @@ -0,0 +1,143 @@ +use crate::cmp; +use crate::ffi::CStr; +use crate::io; +use crate::mem; +use crate::ptr; +use crate::sys::os; +use crate::time::Duration; + +use crate::sys_common::thread::*; + +pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; + +pub struct Thread { + id: libc::pthread_t, +} + +// Some platforms may have pthread_t as a pointer in which case we still want +// a thread to be Send/Sync +unsafe impl Send for Thread {} +unsafe impl Sync for Thread {} + +// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc, +// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS. +unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t, + stack_size: libc::size_t) -> libc::c_int { + libc::pthread_attr_setstacksize(attr, stack_size) +} + +impl Thread { + // unsafe: see thread::Builder::spawn_unchecked for safety requirements + pub unsafe fn new(stack: usize, p: Box) + -> io::Result { + let p = box p; + let mut native: libc::pthread_t = mem::zeroed(); + let mut attr: libc::pthread_attr_t = mem::zeroed(); + assert_eq!(libc::pthread_attr_init(&mut attr), 0); + + let stack_size = cmp::max(stack, min_stack_size(&attr)); + + match pthread_attr_setstacksize(&mut attr, + stack_size) { + 0 => {} + n => { + assert_eq!(n, libc::EINVAL); + // EINVAL means |stack_size| is either too small or not a + // multiple of the system page size. Because it's definitely + // >= PTHREAD_STACK_MIN, it must be an alignment issue. + // Round up to the nearest page and try again. + let page_size = os::page_size(); + let stack_size = (stack_size + page_size - 1) & + (-(page_size as isize - 1) as usize - 1); + assert_eq!(libc::pthread_attr_setstacksize(&mut attr, + stack_size), 0); + } + }; + + let ret = libc::pthread_create(&mut native, &attr, thread_start, + &*p as *const _ as *mut _); + assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + + return if ret != 0 { + Err(io::Error::from_raw_os_error(ret)) + } else { + mem::forget(p); // ownership passed to pthread_create + Ok(Thread { id: native }) + }; + + extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void { + unsafe { start_thread(main as *mut u8); } + ptr::null_mut() + } + } + + pub fn yield_now() { + let ret = unsafe { libc::sched_yield() }; + debug_assert_eq!(ret, 0); + } + + pub fn set_name(_name: &CStr) { + assert!(false, "FIXME: set_name"); + } + + pub fn sleep(dur: Duration) { + let mut secs = dur.as_secs(); + let mut nsecs = dur.subsec_nanos() as _; + + // If we're awoken with a signal then the return value will be -1 and + // nanosleep will fill in `ts` with the remaining time. + unsafe { + while secs > 0 || nsecs > 0 { + let mut ts = libc::timespec { + tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t, + tv_nsec: nsecs, + }; + secs -= ts.tv_sec as u64; + if libc::nanosleep(&ts, &mut ts) == -1 { + assert_eq!(os::errno(), libc::EINTR); + secs += ts.tv_sec as u64; + nsecs = ts.tv_nsec; + } else { + nsecs = 0; + } + } + } + } + + pub fn join(self) { + unsafe { + let ret = libc::pthread_join(self.id, ptr::null_mut()); + mem::forget(self); + assert!(ret == 0, + "failed to join thread: {}", io::Error::from_raw_os_error(ret)); + } + } + + pub fn id(&self) -> libc::pthread_t { self.id } + + pub fn into_id(self) -> libc::pthread_t { + let id = self.id; + mem::forget(self); + id + } +} + +impl Drop for Thread { + fn drop(&mut self) { + let ret = unsafe { libc::pthread_detach(self.id) }; + debug_assert_eq!(ret, 0); + } +} + +#[cfg_attr(test, allow(dead_code))] +pub mod guard { + use crate::ops::Range; + pub type Guard = Range; + pub unsafe fn current() -> Option { None } + pub unsafe fn init() -> Option { None } + pub unsafe fn deinit() {} +} + +fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { + libc::PTHREAD_STACK_MIN +} diff --git a/src/libstd/sys/vxworks/thread_local.rs b/src/libstd/sys/vxworks/thread_local.rs new file mode 100644 index 0000000000..ac615b76b3 --- /dev/null +++ b/src/libstd/sys/vxworks/thread_local.rs @@ -0,0 +1,34 @@ +#![allow(dead_code)] // not used on all platforms + +use crate::mem; + +pub type Key = libc::pthread_key_t; + +#[inline] +pub unsafe fn create(dtor: Option) -> Key { + let mut key = 0; + assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0); + key +} + +#[inline] +pub unsafe fn set(key: Key, value: *mut u8) { + let r = libc::pthread_setspecific(key, value as *mut _); + debug_assert_eq!(r, 0); +} + +#[inline] +pub unsafe fn get(key: Key) -> *mut u8 { + libc::pthread_getspecific(key) as *mut u8 +} + +#[inline] +pub unsafe fn destroy(key: Key) { + let r = libc::pthread_key_delete(key); + debug_assert_eq!(r, 0); +} + +#[inline] +pub fn requires_synchronized_create() -> bool { + false +} diff --git a/src/libstd/sys/vxworks/time.rs b/src/libstd/sys/vxworks/time.rs new file mode 100644 index 0000000000..cb3a4241ea --- /dev/null +++ b/src/libstd/sys/vxworks/time.rs @@ -0,0 +1,224 @@ +use crate::cmp::Ordering; +use libc; +use crate::time::Duration; +use ::core::hash::{Hash, Hasher}; + +pub use self::inner::{Instant, SystemTime, UNIX_EPOCH}; +use crate::convert::TryInto; + +const NSEC_PER_SEC: u64 = 1_000_000_000; + +#[derive(Copy, Clone)] +struct Timespec { + t: libc::timespec, +} + +impl Timespec { + const fn zero() -> Timespec { + Timespec { + t: libc::timespec { tv_sec: 0, tv_nsec: 0 }, + } + } + fn sub_timespec(&self, other: &Timespec) -> Result { + if self >= other { + Ok(if self.t.tv_nsec >= other.t.tv_nsec { + Duration::new((self.t.tv_sec - other.t.tv_sec) as u64, + (self.t.tv_nsec - other.t.tv_nsec) as u32) + } else { + Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64, + self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - + other.t.tv_nsec as u32) + }) + } else { + match other.sub_timespec(self) { + Ok(d) => Err(d), + Err(d) => Ok(d), + } + } + } + + fn checked_add_duration(&self, other: &Duration) -> Option { + let mut secs = other + .as_secs() + .try_into() // <- target type would be `libc::time_t` + .ok() + .and_then(|secs| self.t.tv_sec.checked_add(secs))?; + + // Nano calculations can't overflow because nanos are <1B which fit + // in a u32. + let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32; + if nsec >= NSEC_PER_SEC as u32 { + nsec -= NSEC_PER_SEC as u32; + secs = secs.checked_add(1)?; + } + Some(Timespec { + t: libc::timespec { + tv_sec: secs, + tv_nsec: nsec as _, + }, + }) + } + + fn checked_sub_duration(&self, other: &Duration) -> Option { + let mut secs = other + .as_secs() + .try_into() // <- target type would be `libc::time_t` + .ok() + .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; + + // Similar to above, nanos can't overflow. + let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; + if nsec < 0 { + nsec += NSEC_PER_SEC as i32; + secs = secs.checked_sub(1)?; + } + Some(Timespec { + t: libc::timespec { + tv_sec: secs, + tv_nsec: nsec as _, + }, + }) + } +} + +impl PartialEq for Timespec { + fn eq(&self, other: &Timespec) -> bool { + self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec + } +} + +impl Eq for Timespec {} + +impl PartialOrd for Timespec { + fn partial_cmp(&self, other: &Timespec) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Timespec { + fn cmp(&self, other: &Timespec) -> Ordering { + let me = (self.t.tv_sec, self.t.tv_nsec); + let other = (other.t.tv_sec, other.t.tv_nsec); + me.cmp(&other) + } +} + +impl Hash for Timespec { + fn hash(&self, state: &mut H) { + self.t.tv_sec.hash(state); + self.t.tv_nsec.hash(state); + } +} +mod inner { + use crate::fmt; + use libc; + use crate::sys::cvt; + use crate::time::Duration; + + use super::Timespec; + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct Instant { + t: Timespec, + } + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct SystemTime { + t: Timespec, + } + + pub const UNIX_EPOCH: SystemTime = SystemTime { + t: Timespec { + t: libc::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + }, + }; + + impl Instant { + pub fn now() -> Instant { + Instant { t: now(libc::CLOCK_MONOTONIC) } + } + + pub const fn zero() -> Instant { + Instant { + t: Timespec::zero(), + } + } + + pub fn actually_monotonic() -> bool { + true + } + + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + self.t.sub_timespec(&other.t).ok() + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant { t: self.t.checked_add_duration(other)? }) + } + + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant { t: self.t.checked_sub_duration(other)? }) + } + } + + impl fmt::Debug for Instant { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Instant") + .field("tv_sec", &self.t.t.tv_sec) + .field("tv_nsec", &self.t.t.tv_nsec) + .finish() + } + } + + impl SystemTime { + pub fn now() -> SystemTime { + SystemTime { t: now(libc::CLOCK_REALTIME) } + } + + pub fn sub_time(&self, other: &SystemTime) + -> Result { + self.t.sub_timespec(&other.t) + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(SystemTime { t: self.t.checked_add_duration(other)? }) + } + + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime { t: self.t.checked_sub_duration(other)? }) + } + } + + impl From for SystemTime { + fn from(t: libc::timespec) -> SystemTime { + SystemTime { t: Timespec { t: t } } + } + } + + impl fmt::Debug for SystemTime { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SystemTime") + .field("tv_sec", &self.t.t.tv_sec) + .field("tv_nsec", &self.t.t.tv_nsec) + .finish() + } + } + + pub type clock_t = libc::c_int; + + fn now(clock: clock_t) -> Timespec { + let mut t = Timespec { + t: libc::timespec { + tv_sec: 0, + tv_nsec: 0, + } + }; + cvt(unsafe { + libc::clock_gettime(clock, &mut t.t) + }).unwrap(); + t + } +} diff --git a/src/libstd/sys/vxworks/weak.rs b/src/libstd/sys/vxworks/weak.rs new file mode 100644 index 0000000000..284f211642 --- /dev/null +++ b/src/libstd/sys/vxworks/weak.rs @@ -0,0 +1,60 @@ +//! Support for "weak linkage" to symbols on Unix +//! +//! Some I/O operations we do in libstd require newer versions of OSes but we +//! need to maintain binary compatibility with older releases for now. In order +//! to use the new functionality when available we use this module for +//! detection. +//! +//! One option to use here is weak linkage, but that is unfortunately only +//! really workable on Linux. Hence, use dlsym to get the symbol value at +//! runtime. This is also done for compatibility with older versions of glibc, +//! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that +//! we've been dynamically linked to the library the symbol comes from, but that +//! is currently always the case for things like libpthread/libc. +//! +//! A long time ago this used weak linkage for the __pthread_get_minstack +//! symbol, but that caused Debian to detect an unnecessarily strict versioned +//! dependency on libc6 (#23628). + +use crate::ffi::CStr; +use crate::marker; +use crate::mem; +use crate::sync::atomic::{AtomicUsize, Ordering}; + +pub struct Weak { + name: &'static str, + addr: AtomicUsize, + _marker: marker::PhantomData, +} + +impl Weak { + pub const fn new(name: &'static str) -> Weak { + Weak { + name, + addr: AtomicUsize::new(1), + _marker: marker::PhantomData, + } + } + + pub fn get(&self) -> Option { + assert_eq!(mem::size_of::(), mem::size_of::()); + unsafe { + if self.addr.load(Ordering::SeqCst) == 1 { + self.addr.store(fetch(self.name), Ordering::SeqCst); + } + match self.addr.load(Ordering::SeqCst) { + 0 => None, + addr => Some(mem::transmute_copy::(&addr)), + } + } + } +} + +unsafe fn fetch(name: &str) -> usize { + let name = match CStr::from_bytes_with_nul(name.as_bytes()) { + Ok(cstr) => cstr, + Err(..) => return 0, + }; + assert!(false, "FIXME: fetch"); + libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize +} diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs index cc8f1e16fa..ffecca5d1b 100644 --- a/src/libstd/sys/wasi/io.rs +++ b/src/libstd/sys/wasi/io.rs @@ -21,6 +21,18 @@ impl<'a> IoSlice<'a> { } } + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.buf_len < n { + panic!("advancing IoSlice beyond its length"); + } + + unsafe { + self.vec.buf_len -= n; + self.vec.buf = self.vec.buf.add(n); + } + } + #[inline] pub fn as_slice(&self) -> &[u8] { unsafe { @@ -29,6 +41,7 @@ impl<'a> IoSlice<'a> { } } +#[repr(transparent)] pub struct IoSliceMut<'a> { vec: __wasi_iovec_t, _p: PhantomData<&'a mut [u8]>, @@ -46,6 +59,18 @@ impl<'a> IoSliceMut<'a> { } } + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.buf_len < n { + panic!("advancing IoSlice beyond its length"); + } + + unsafe { + self.vec.buf_len -= n; + self.vec.buf = self.vec.buf.add(n); + } + } + #[inline] pub fn as_slice(&self) -> &[u8] { unsafe { diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index e22434439f..f842869e08 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -47,6 +47,8 @@ pub mod stdio; pub mod thread; #[path = "../wasm/thread_local.rs"] pub mod thread_local; +#[path = "../wasm/fast_thread_local.rs"] +pub mod fast_thread_local; pub mod time; pub mod ext; diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/fast_thread_local.rs new file mode 100644 index 0000000000..ff2198175f --- /dev/null +++ b/src/libstd/sys/wasm/fast_thread_local.rs @@ -0,0 +1,9 @@ +#![unstable(feature = "thread_local_internals", issue = "0")] + +pub unsafe fn register_dtor(_t: *mut u8, _dtor: unsafe extern fn(*mut u8)) { + // FIXME: right now there is no concept of "thread exit", but this is likely + // going to show up at some point in the form of an exported symbol that the + // wasm runtime is oging to be expected to call. For now we basically just + // ignore the arguments, but if such a function starts to exist it will + // likely look like the OSX implementation in `unix/fast_thread_local.rs` +} diff --git a/src/libstd/sys/wasm/io.rs b/src/libstd/sys/wasm/io.rs index 4b423a5cbc..976e122463 100644 --- a/src/libstd/sys/wasm/io.rs +++ b/src/libstd/sys/wasm/io.rs @@ -1,3 +1,5 @@ +use crate::mem; + pub struct IoSlice<'a>(&'a [u8]); impl<'a> IoSlice<'a> { @@ -6,6 +8,11 @@ impl<'a> IoSlice<'a> { IoSlice(buf) } + #[inline] + pub fn advance(&mut self, n: usize) { + self.0 = &self.0[n..] + } + #[inline] pub fn as_slice(&self) -> &[u8] { self.0 @@ -20,6 +27,13 @@ impl<'a> IoSliceMut<'a> { IoSliceMut(buf) } + #[inline] + pub fn advance(&mut self, n: usize) { + let slice = mem::replace(&mut self.0, &mut []); + let (_, remaining) = slice.split_at_mut(n); + self.0 = remaining; + } + #[inline] pub fn as_slice(&self) -> &[u8] { self.0 diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index 7d157709eb..56cbafcfdb 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -37,6 +37,8 @@ pub mod stack_overflow; pub mod thread; pub mod time; pub mod stdio; +pub mod thread_local; +pub mod fast_thread_local; pub use crate::sys_common::os_str_bytes as os_str; @@ -48,13 +50,10 @@ cfg_if::cfg_if! { pub mod mutex; #[path = "rwlock_atomics.rs"] pub mod rwlock; - #[path = "thread_local_atomics.rs"] - pub mod thread_local; } else { pub mod condvar; pub mod mutex; pub mod rwlock; - pub mod thread_local; } } diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 61b4003cd3..d06965f327 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -59,48 +59,40 @@ pub mod guard { pub unsafe fn init() -> Option { None } } -cfg_if::cfg_if! { - if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] { - #[link(wasm_import_module = "__wbindgen_thread_xform__")] - extern { - fn __wbindgen_current_id() -> u32; - fn __wbindgen_tcb_get() -> u32; - fn __wbindgen_tcb_set(ptr: u32); +// This is only used by atomics primitives when the `atomics` feature is +// enabled. In that mode we currently just use our own thread-local to store our +// current thread's ID, and then we lazily initialize it to something allocated +// from a global counter. +#[cfg(target_feature = "atomics")] +pub fn my_id() -> u32 { + use crate::sync::atomic::{AtomicU32, Ordering::SeqCst}; + + static NEXT_ID: AtomicU32 = AtomicU32::new(0); + + #[thread_local] + static mut MY_ID: u32 = 0; + + unsafe { + // If our thread ID isn't set yet then we need to allocate one. Do so + // with with a simple "atomically add to a global counter" strategy. + // This strategy doesn't handled what happens when the counter + // overflows, however, so just abort everything once the counter + // overflows and eventually we could have some sort of recycling scheme + // (or maybe this is all totally irrelevant by that point!). In any case + // though we're using a CAS loop instead of a `fetch_add` to ensure that + // the global counter never overflows. + if MY_ID == 0 { + let mut cur = NEXT_ID.load(SeqCst); + MY_ID = loop { + let next = cur.checked_add(1).unwrap_or_else(|| { + crate::arch::wasm32::unreachable() + }); + match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) { + Ok(_) => break next, + Err(i) => cur = i, + } + }; } - pub fn my_id() -> u32 { - unsafe { __wbindgen_current_id() } - } - - // These are currently only ever used in `thread_local_atomics.rs`, if - // you'd like to use them be sure to update that and make sure everyone - // agrees what's what. - pub fn tcb_get() -> *mut u8 { - use crate::mem; - assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::()); - unsafe { __wbindgen_tcb_get() as *mut u8 } - } - - pub fn tcb_set(ptr: *mut u8) { - unsafe { __wbindgen_tcb_set(ptr as u32); } - } - - // FIXME: still need something for hooking exiting a thread to free - // data... - - } else if #[cfg(target_feature = "atomics")] { - pub fn my_id() -> u32 { - panic!("thread ids not implemented on wasm with atomics yet") - } - - pub fn tcb_get() -> *mut u8 { - panic!("thread local data not implemented on wasm with atomics yet") - } - - pub fn tcb_set(_ptr: *mut u8) { - panic!("thread local data not implemented on wasm with atomics yet") - } - } else { - // stubbed out because no functions actually access these intrinsics - // unless atomics are enabled + MY_ID } } diff --git a/src/libstd/sys/wasm/thread_local.rs b/src/libstd/sys/wasm/thread_local.rs index 29e9854bcf..8a0ca6f3d2 100644 --- a/src/libstd/sys/wasm/thread_local.rs +++ b/src/libstd/sys/wasm/thread_local.rs @@ -1,40 +1,26 @@ -use crate::boxed::Box; -use crate::ptr; - pub type Key = usize; -struct Allocated { - value: *mut u8, - dtor: Option, -} - #[inline] -pub unsafe fn create(dtor: Option) -> Key { - Box::into_raw(Box::new(Allocated { - value: ptr::null_mut(), - dtor, - })) as usize +pub unsafe fn create(_dtor: Option) -> Key { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn set(key: Key, value: *mut u8) { - (*(key as *mut Allocated)).value = value; +pub unsafe fn set(_key: Key, _value: *mut u8) { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn get(key: Key) -> *mut u8 { - (*(key as *mut Allocated)).value +pub unsafe fn get(_key: Key) -> *mut u8 { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn destroy(key: Key) { - let key = Box::from_raw(key as *mut Allocated); - if let Some(f) = key.dtor { - f(key.value); - } +pub unsafe fn destroy(_key: Key) { + panic!("should not be used on the wasm target"); } #[inline] pub fn requires_synchronized_create() -> bool { - false + panic!("should not be used on the wasm target"); } diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs deleted file mode 100644 index 3dc0bb2455..0000000000 --- a/src/libstd/sys/wasm/thread_local_atomics.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::sys::thread; -use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; - -const MAX_KEYS: usize = 128; -static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); - -struct ThreadControlBlock { - keys: [*mut u8; MAX_KEYS], -} - -impl ThreadControlBlock { - fn new() -> ThreadControlBlock { - ThreadControlBlock { - keys: [core::ptr::null_mut(); MAX_KEYS], - } - } - - fn get() -> *mut ThreadControlBlock { - let ptr = thread::tcb_get(); - if !ptr.is_null() { - return ptr as *mut ThreadControlBlock - } - let tcb = Box::into_raw(Box::new(ThreadControlBlock::new())); - thread::tcb_set(tcb as *mut u8); - tcb - } -} - -pub type Key = usize; - -pub unsafe fn create(dtor: Option) -> Key { - drop(dtor); // FIXME: need to figure out how to hook thread exit to run this - let key = NEXT_KEY.fetch_add(1, SeqCst); - if key >= MAX_KEYS { - NEXT_KEY.store(MAX_KEYS, SeqCst); - panic!("cannot allocate space for more TLS keys"); - } - // offset by 1 so we never hand out 0. This is currently required by - // `sys_common/thread_local.rs` where it can't cope with keys of value 0 - // because it messes up the atomic management. - return key + 1 -} - -pub unsafe fn set(key: Key, value: *mut u8) { - (*ThreadControlBlock::get()).keys[key - 1] = value; -} - -pub unsafe fn get(key: Key) -> *mut u8 { - (*ThreadControlBlock::get()).keys[key - 1] -} - -pub unsafe fn destroy(_key: Key) { - // FIXME: should implement this somehow, this isn't typically called but it - // can be called if two threads race to initialize a TLS slot and one ends - // up not being needed. -} - -#[inline] -pub fn requires_synchronized_create() -> bool { - false -} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 6ad338660c..f706709c9c 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -34,9 +34,7 @@ pub type ULONG = c_ulong; pub type LPBOOL = *mut BOOL; pub type LPBYTE = *mut BYTE; -pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION; pub type LPCSTR = *const CHAR; -pub type LPCVOID = *const c_void; pub type LPCWSTR = *const WCHAR; pub type LPDWORD = *mut DWORD; pub type LPHANDLE = *mut HANDLE; @@ -121,6 +119,7 @@ impl Clone for WIN32_FIND_DATAW { } pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01; +pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80; pub const WSADESCRIPTION_LEN: usize = 256; pub const WSASYS_STATUS_LEN: usize = 128; @@ -130,6 +129,7 @@ pub const INVALID_SOCKET: SOCKET = !0; pub const WSAEACCES: c_int = 10013; pub const WSAEINVAL: c_int = 10022; pub const WSAEWOULDBLOCK: c_int = 10035; +pub const WSAEPROTOTYPE: c_int = 10041; pub const WSAEADDRINUSE: c_int = 10048; pub const WSAEADDRNOTAVAIL: c_int = 10049; pub const WSAECONNABORTED: c_int = 10053; @@ -141,7 +141,6 @@ pub const WSAECONNREFUSED: c_int = 10061; pub const MAX_PROTOCOL_CHAIN: DWORD = 7; -pub const TOKEN_READ: DWORD = 0x20008; pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8; pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c; @@ -157,8 +156,6 @@ pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; -pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001; - pub const PROGRESS_CONTINUE: DWORD = 0; pub const ERROR_FILE_NOT_FOUND: DWORD = 2; @@ -259,10 +256,6 @@ pub const WAIT_OBJECT_0: DWORD = 0x00000000; pub const WAIT_TIMEOUT: DWORD = 258; pub const WAIT_FAILED: DWORD = 0xFFFFFFFF; -pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0; -pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd; -pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15; - pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001; pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002; pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000; @@ -342,20 +335,6 @@ pub struct WIN32_FILE_ATTRIBUTE_DATA { pub nFileSizeLow: DWORD, } -#[repr(C)] -pub struct BY_HANDLE_FILE_INFORMATION { - pub dwFileAttributes: DWORD, - pub ftCreationTime: FILETIME, - pub ftLastAccessTime: FILETIME, - pub ftLastWriteTime: FILETIME, - pub dwVolumeSerialNumber: DWORD, - pub nFileSizeHigh: DWORD, - pub nFileSizeLow: DWORD, - pub nNumberOfLinks: DWORD, - pub nFileIndexHigh: DWORD, - pub nFileIndexLow: DWORD, -} - #[repr(C)] #[allow(dead_code)] // we only use some variants pub enum FILE_INFO_BY_HANDLE_CLASS { @@ -461,25 +440,6 @@ pub struct REPARSE_MOUNTPOINT_DATA_BUFFER { pub ReparseTarget: WCHAR, } -#[repr(C)] -pub struct EXCEPTION_RECORD { - pub ExceptionCode: DWORD, - pub ExceptionFlags: DWORD, - pub ExceptionRecord: *mut EXCEPTION_RECORD, - pub ExceptionAddress: LPVOID, - pub NumberParameters: DWORD, - pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS] -} - -#[repr(C)] -pub struct EXCEPTION_POINTERS { - pub ExceptionRecord: *mut EXCEPTION_RECORD, - pub ContextRecord: *mut CONTEXT, -} - -pub type PVECTORED_EXCEPTION_HANDLER = extern "system" - fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG; - #[repr(C)] pub struct GUID { pub Data1: DWORD, @@ -562,8 +522,6 @@ pub enum ADDRESS_MODE { AddrModeFlat, } -pub enum CONTEXT {} - #[repr(C)] pub struct SOCKADDR_STORAGE_LH { pub ss_family: ADDRESS_FAMILY, @@ -625,16 +583,6 @@ pub enum EXCEPTION_DISPOSITION { ExceptionCollidedUnwind } -#[repr(C)] -#[derive(Copy, Clone)] -pub struct CONSOLE_READCONSOLE_CONTROL { - pub nLength: ULONG, - pub nInitialChars: ULONG, - pub dwCtrlWakeupMask: ULONG, - pub dwControlKeyState: ULONG, -} -pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL; - #[repr(C)] #[derive(Copy)] pub struct fd_set { @@ -655,6 +603,134 @@ pub struct timeval { pub tv_usec: c_long, } +// Functions forbidden when targeting UWP +cfg_if::cfg_if! { +if #[cfg(not(target_vendor = "uwp"))] { + pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0; + pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd; + pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15; + + #[repr(C)] + pub struct EXCEPTION_RECORD { + pub ExceptionCode: DWORD, + pub ExceptionFlags: DWORD, + pub ExceptionRecord: *mut EXCEPTION_RECORD, + pub ExceptionAddress: LPVOID, + pub NumberParameters: DWORD, + pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS] + } + + pub enum CONTEXT {} + + #[repr(C)] + pub struct EXCEPTION_POINTERS { + pub ExceptionRecord: *mut EXCEPTION_RECORD, + pub ContextRecord: *mut CONTEXT, + } + + pub type PVECTORED_EXCEPTION_HANDLER = extern "system" + fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct CONSOLE_READCONSOLE_CONTROL { + pub nLength: ULONG, + pub nInitialChars: ULONG, + pub dwCtrlWakeupMask: ULONG, + pub dwControlKeyState: ULONG, + } + + pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL; + + #[repr(C)] + pub struct BY_HANDLE_FILE_INFORMATION { + pub dwFileAttributes: DWORD, + pub ftCreationTime: FILETIME, + pub ftLastAccessTime: FILETIME, + pub ftLastWriteTime: FILETIME, + pub dwVolumeSerialNumber: DWORD, + pub nFileSizeHigh: DWORD, + pub nFileSizeLow: DWORD, + pub nNumberOfLinks: DWORD, + pub nFileIndexHigh: DWORD, + pub nFileIndexLow: DWORD, + } + + pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION; + pub type LPCVOID = *const c_void; + + pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001; + + pub const TOKEN_READ: DWORD = 0x20008; + + extern "system" { + #[link_name = "SystemFunction036"] + pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN; + + pub fn ReadConsoleW(hConsoleInput: HANDLE, + lpBuffer: LPVOID, + nNumberOfCharsToRead: DWORD, + lpNumberOfCharsRead: LPDWORD, + pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL; + + pub fn WriteConsoleW(hConsoleOutput: HANDLE, + lpBuffer: LPCVOID, + nNumberOfCharsToWrite: DWORD, + lpNumberOfCharsWritten: LPDWORD, + lpReserved: LPVOID) -> BOOL; + + pub fn GetConsoleMode(hConsoleHandle: HANDLE, + lpMode: LPDWORD) -> BOOL; + // Allowed but unused by UWP + pub fn OpenProcessToken(ProcessHandle: HANDLE, + DesiredAccess: DWORD, + TokenHandle: *mut HANDLE) -> BOOL; + pub fn GetUserProfileDirectoryW(hToken: HANDLE, + lpProfileDir: LPWSTR, + lpcchSize: *mut DWORD) -> BOOL; + pub fn GetFileInformationByHandle(hFile: HANDLE, + lpFileInformation: LPBY_HANDLE_FILE_INFORMATION) + -> BOOL; + pub fn SetHandleInformation(hObject: HANDLE, + dwMask: DWORD, + dwFlags: DWORD) -> BOOL; + pub fn AddVectoredExceptionHandler(FirstHandler: ULONG, + VectoredHandler: PVECTORED_EXCEPTION_HANDLER) + -> LPVOID; + pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR, + lpTargetFileName: LPCWSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES) + -> BOOL; + } +} +} + +// UWP specific functions & types +cfg_if::cfg_if! { +if #[cfg(target_vendor = "uwp")] { + pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002; + + #[repr(C)] + pub struct FILE_STANDARD_INFO { + pub AllocationSize: LARGE_INTEGER, + pub EndOfFile: LARGE_INTEGER, + pub NumberOfLink: DWORD, + pub DeletePending: BOOLEAN, + pub Directory: BOOLEAN, + } + + extern "system" { + pub fn GetFileInformationByHandleEx(hFile: HANDLE, + fileInfoClass: FILE_INFO_BY_HANDLE_CLASS, + lpFileInformation: LPVOID, + dwBufferSize: DWORD) -> BOOL; + pub fn BCryptGenRandom(hAlgorithm: LPVOID, pBuffer: *mut u8, + cbBuffer: ULONG, dwFlags: ULONG) -> LONG; + } +} +} + +// Shared between Desktop & UWP extern "system" { pub fn WSAStartup(wVersionRequested: WORD, lpWSAData: LPWSADATA) -> c_int; @@ -694,34 +770,13 @@ extern "system" { pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION); pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION); - pub fn ReadConsoleW(hConsoleInput: HANDLE, - lpBuffer: LPVOID, - nNumberOfCharsToRead: DWORD, - lpNumberOfCharsRead: LPDWORD, - pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL; - - pub fn WriteConsoleW(hConsoleOutput: HANDLE, - lpBuffer: LPCVOID, - nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: LPDWORD, - lpReserved: LPVOID) -> BOOL; - - pub fn GetConsoleMode(hConsoleHandle: HANDLE, - lpMode: LPDWORD) -> BOOL; pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL; - pub fn GetFileInformationByHandle(hFile: HANDLE, - lpFileInformation: LPBY_HANDLE_FILE_INFORMATION) - -> BOOL; - pub fn SetLastError(dwErrCode: DWORD); pub fn GetCommandLineW() -> *mut LPCWSTR; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; - pub fn OpenProcessToken(ProcessHandle: HANDLE, - DesiredAccess: DWORD, - TokenHandle: *mut HANDLE) -> BOOL; pub fn GetCurrentProcess() -> HANDLE; pub fn GetCurrentThread() -> HANDLE; pub fn GetStdHandle(which: DWORD) -> HANDLE; @@ -746,21 +801,12 @@ extern "system" { pub fn SwitchToThread() -> BOOL; pub fn Sleep(dwMilliseconds: DWORD); pub fn GetProcessId(handle: HANDLE) -> DWORD; - pub fn GetUserProfileDirectoryW(hToken: HANDLE, - lpProfileDir: LPWSTR, - lpcchSize: *mut DWORD) -> BOOL; - pub fn SetHandleInformation(hObject: HANDLE, - dwMask: DWORD, - dwFlags: DWORD) -> BOOL; pub fn CopyFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, lpData: LPVOID, pbCancel: LPBOOL, dwCopyFlags: DWORD) -> BOOL; - pub fn AddVectoredExceptionHandler(FirstHandler: ULONG, - VectoredHandler: PVECTORED_EXCEPTION_HANDLER) - -> LPVOID; pub fn FormatMessageW(flags: DWORD, lpSrc: LPVOID, msgId: DWORD, @@ -857,10 +903,6 @@ extern "system" { lpOverlapped: LPOVERLAPPED) -> BOOL; pub fn CloseHandle(hObject: HANDLE) -> BOOL; - pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR, - lpTargetFileName: LPCWSTR, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES) - -> BOOL; pub fn MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD) @@ -950,8 +992,6 @@ extern "system" { exceptfds: *mut fd_set, timeout: *const timeval) -> c_int; - #[link_name = "SystemFunction036"] - pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN; pub fn GetProcessHeap() -> HANDLE; pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; @@ -975,6 +1015,7 @@ compat_fn! { _dwFlags: DWORD) -> DWORD { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } + #[cfg(not(target_vendor = "uwp"))] pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } diff --git a/src/libstd/sys/windows/compat.rs b/src/libstd/sys/windows/compat.rs index 748c1616d1..544b2087f9 100644 --- a/src/libstd/sys/windows/compat.rs +++ b/src/libstd/sys/windows/compat.rs @@ -37,12 +37,14 @@ pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str, macro_rules! compat_fn { ($module:ident: $( + $(#[$meta:meta])* pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty { $($body:expr);* } )*) => ($( #[allow(unused_variables)] + $(#[$meta])* pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype { use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::mem; diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 268a14ff0a..23964dc5bd 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -437,6 +437,33 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn file_size(&self) -> u64; + + /// Returns the value of the `dwVolumeSerialNumber` field of this + /// metadata. + /// + /// This will return `None` if the `Metadata` instance was created from a + /// call to `DirEntry::metadata`. If this `Metadata` was created by using + /// `fs::metadata` or `File::metadata`, then this will return `Some`. + #[unstable(feature = "windows_by_handle", issue = "63010")] + fn volume_serial_number(&self) -> Option; + + /// Returns the value of the `nNumberOfLinks` field of this + /// metadata. + /// + /// This will return `None` if the `Metadata` instance was created from a + /// call to `DirEntry::metadata`. If this `Metadata` was created by using + /// `fs::metadata` or `File::metadata`, then this will return `Some`. + #[unstable(feature = "windows_by_handle", issue = "63010")] + fn number_of_links(&self) -> Option; + + /// Returns the value of the `nFileIndex{Low,High}` fields of this + /// metadata. + /// + /// This will return `None` if the `Metadata` instance was created from a + /// call to `DirEntry::metadata`. If this `Metadata` was created by using + /// `fs::metadata` or `File::metadata`, then this will return `Some`. + #[unstable(feature = "windows_by_handle", issue = "63010")] + fn file_index(&self) -> Option; } #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -446,6 +473,9 @@ impl MetadataExt for Metadata { fn last_access_time(&self) -> u64 { self.as_inner().accessed_u64() } fn last_write_time(&self) -> u64 { self.as_inner().modified_u64() } fn file_size(&self) -> u64 { self.as_inner().size() } + fn volume_serial_number(&self) -> Option { self.as_inner().volume_serial_number() } + fn number_of_links(&self) -> Option { self.as_inner().number_of_links() } + fn file_index(&self) -> Option { self.as_inner().file_index() } } /// Windows-specific extensions to [`FileType`]. diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index d5cb205c85..5bae6ba474 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -25,6 +25,9 @@ pub struct FileAttr { last_write_time: c::FILETIME, file_size: u64, reparse_tag: c::DWORD, + volume_serial_number: Option, + number_of_links: Option, + file_index: Option, } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -156,6 +159,9 @@ impl DirEntry { } else { 0 }, + volume_serial_number: None, + number_of_links: None, + file_index: None, }) } } @@ -287,19 +293,70 @@ impl File { Ok(()) } + #[cfg(not(target_vendor = "uwp"))] pub fn file_attr(&self) -> io::Result { unsafe { let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed(); - cvt(c::GetFileInformationByHandle(self.handle.raw(), - &mut info))?; - let mut attr = FileAttr { + cvt(c::GetFileInformationByHandle(self.handle.raw(), &mut info))?; + let mut reparse_tag = 0; + if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { + let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + if let Ok((_, buf)) = self.reparse_point(&mut b) { + reparse_tag = buf.ReparseTag; + } + } + Ok(FileAttr { attributes: info.dwFileAttributes, creation_time: info.ftCreationTime, last_access_time: info.ftLastAccessTime, last_write_time: info.ftLastWriteTime, - file_size: ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64), + file_size: (info.nFileSizeLow as u64) | ((info.nFileSizeHigh as u64) << 32), + reparse_tag, + volume_serial_number: Some(info.dwVolumeSerialNumber), + number_of_links: Some(info.nNumberOfLinks), + file_index: Some((info.nFileIndexLow as u64) | + ((info.nFileIndexHigh as u64) << 32)), + }) + } + } + + #[cfg(target_vendor = "uwp")] + pub fn file_attr(&self) -> io::Result { + unsafe { + let mut info: c::FILE_BASIC_INFO = mem::zeroed(); + let size = mem::size_of_val(&info); + cvt(c::GetFileInformationByHandleEx(self.handle.raw(), + c::FileBasicInfo, + &mut info as *mut _ as *mut libc::c_void, + size as c::DWORD))?; + let mut attr = FileAttr { + attributes: info.FileAttributes, + creation_time: c::FILETIME { + dwLowDateTime: info.CreationTime as c::DWORD, + dwHighDateTime: (info.CreationTime >> 32) as c::DWORD, + }, + last_access_time: c::FILETIME { + dwLowDateTime: info.LastAccessTime as c::DWORD, + dwHighDateTime: (info.LastAccessTime >> 32) as c::DWORD, + }, + last_write_time: c::FILETIME { + dwLowDateTime: info.LastWriteTime as c::DWORD, + dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD, + }, + file_size: 0, reparse_tag: 0, + volume_serial_number: None, + number_of_links: None, + file_index: None, }; + let mut info: c::FILE_STANDARD_INFO = mem::zeroed(); + let size = mem::size_of_val(&info); + cvt(c::GetFileInformationByHandleEx(self.handle.raw(), + c::FileStandardInfo, + &mut info as *mut _ as *mut libc::c_void, + size as c::DWORD))?; + attr.file_size = info.AllocationSize as u64; + attr.number_of_links = Some(info.NumberOfLinks); if attr.is_reparse_point() { let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; if let Ok((_, buf)) = self.reparse_point(&mut b) { @@ -463,7 +520,9 @@ impl FileAttr { FilePermissions { attrs: self.attributes } } - pub fn attrs(&self) -> u32 { self.attributes as u32 } + pub fn attrs(&self) -> u32 { + self.attributes + } pub fn file_type(&self) -> FileType { FileType::new(self.attributes, self.reparse_tag) @@ -493,8 +552,16 @@ impl FileAttr { to_u64(&self.creation_time) } - fn is_reparse_point(&self) -> bool { - self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 + pub fn volume_serial_number(&self) -> Option { + self.volume_serial_number + } + + pub fn number_of_links(&self) -> Option { + self.number_of_links + } + + pub fn file_index(&self) -> Option { + self.file_index } } @@ -670,6 +737,7 @@ pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> { Ok(()) } +#[cfg(not(target_vendor = "uwp"))] pub fn link(src: &Path, dst: &Path) -> io::Result<()> { let src = to_u16s(src)?; let dst = to_u16s(dst)?; @@ -679,6 +747,12 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> { Ok(()) } +#[cfg(target_vendor = "uwp")] +pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { + return Err(io::Error::new(io::ErrorKind::Other, + "hard link are not supported on UWP")); +} + pub fn stat(path: &Path) -> io::Result { let mut opts = OpenOptions::new(); // No read or write permissions are necessary diff --git a/src/libstd/sys/windows/io.rs b/src/libstd/sys/windows/io.rs index c045a63e91..e44dcbe164 100644 --- a/src/libstd/sys/windows/io.rs +++ b/src/libstd/sys/windows/io.rs @@ -21,6 +21,18 @@ impl<'a> IoSlice<'a> { } } + #[inline] + pub fn advance(&mut self, n: usize) { + if (self.vec.len as usize) < n { + panic!("advancing IoSlice beyond its length"); + } + + unsafe { + self.vec.len -= n as c::ULONG; + self.vec.buf = self.vec.buf.add(n); + } + } + #[inline] pub fn as_slice(&self) -> &[u8] { unsafe { @@ -29,6 +41,7 @@ impl<'a> IoSlice<'a> { } } +#[repr(transparent)] pub struct IoSliceMut<'a> { vec: c::WSABUF, _p: PhantomData<&'a mut [u8]>, @@ -47,6 +60,18 @@ impl<'a> IoSliceMut<'a> { } } + #[inline] + pub fn advance(&mut self, n: usize) { + if (self.vec.len as usize) < n { + panic!("advancing IoSliceMut beyond its length"); + } + + unsafe { + self.vec.len -= n as c::ULONG; + self.vec.buf = self.vec.buf.add(n); + } + } + #[inline] pub fn as_slice(&self) -> &[u8] { unsafe { diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 1cb5553912..d59ac5959a 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -33,11 +33,20 @@ pub mod pipe; pub mod process; pub mod rand; pub mod rwlock; -pub mod stack_overflow; pub mod thread; pub mod thread_local; pub mod time; -pub mod stdio; +cfg_if::cfg_if! { + if #[cfg(not(target_vendor = "uwp"))] { + pub mod stdio; + pub mod stack_overflow; + } else { + pub mod stdio_uwp; + pub mod stack_overflow_uwp; + pub use self::stdio_uwp as stdio; + pub use self::stack_overflow_uwp as stack_overflow; + } +} #[cfg(not(test))] pub fn init() { @@ -195,7 +204,7 @@ fn wide_char_to_multi_byte(code_page: u32, } } -pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { +pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] { match v.iter().position(|c| *c == 0) { // don't include the 0 Some(i) => &v[..i], diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index 7dd1af5441..32f4011fb3 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -97,12 +97,26 @@ impl Socket { }; let socket = unsafe { match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0, - c::WSA_FLAG_OVERLAPPED) { - c::INVALID_SOCKET => Err(last_error()), + c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT) { + c::INVALID_SOCKET => { + match c::WSAGetLastError() { + c::WSAEPROTOTYPE => { + match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0, + c::WSA_FLAG_OVERLAPPED) { + c::INVALID_SOCKET => Err(last_error()), + n => { + let s = Socket(n); + s.set_no_inherit()?; + Ok(s) + }, + } + }, + n => Err(io::Error::from_raw_os_error(n)), + } + }, n => Ok(Socket(n)), } }?; - socket.set_no_inherit()?; Ok(socket) } @@ -168,7 +182,6 @@ impl Socket { n => Ok(Socket(n)), } }?; - socket.set_no_inherit()?; Ok(socket) } @@ -178,16 +191,34 @@ impl Socket { cvt(c::WSADuplicateSocketW(self.0, c::GetCurrentProcessId(), &mut info))?; + match c::WSASocketW(info.iAddressFamily, info.iSocketType, info.iProtocol, &mut info, 0, - c::WSA_FLAG_OVERLAPPED) { - c::INVALID_SOCKET => Err(last_error()), + c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT) { + c::INVALID_SOCKET => { + match c::WSAGetLastError() { + c::WSAEPROTOTYPE => { + match c::WSASocketW(info.iAddressFamily, + info.iSocketType, + info.iProtocol, + &mut info, 0, + c::WSA_FLAG_OVERLAPPED) { + c::INVALID_SOCKET => Err(last_error()), + n => { + let s = Socket(n); + s.set_no_inherit()?; + Ok(s) + }, + } + }, + n => Err(io::Error::from_raw_os_error(n)), + } + }, n => Ok(Socket(n)), } }?; - socket.set_no_inherit()?; Ok(socket) } @@ -312,6 +343,7 @@ impl Socket { } } + #[cfg(not(target_vendor = "uwp"))] fn set_no_inherit(&self) -> io::Result<()> { sys::cvt(unsafe { c::SetHandleInformation(self.0 as c::HANDLE, @@ -319,6 +351,11 @@ impl Socket { }).map(|_| ()) } + #[cfg(target_vendor = "uwp")] + fn set_no_inherit(&self) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, "Unavailable on UWP")) + } + pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { let how = match how { Shutdown::Write => c::SD_SEND, diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 4e50b5521e..7c400dce68 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -13,7 +13,6 @@ use crate::path::{self, PathBuf}; use crate::ptr; use crate::slice; use crate::sys::{c, cvt}; -use crate::sys::handle::Handle; use super::to_u16s; @@ -284,10 +283,11 @@ pub fn temp_dir() -> PathBuf { }, super::os2path).unwrap() } -pub fn home_dir() -> Option { - crate::env::var_os("HOME").or_else(|| { - crate::env::var_os("USERPROFILE") - }).map(PathBuf::from).or_else(|| unsafe { +#[cfg(not(target_vendor = "uwp"))] +fn home_dir_crt() -> Option { + unsafe { + use crate::sys::handle::Handle; + let me = c::GetCurrentProcess(); let mut token = ptr::null_mut(); if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 { @@ -301,7 +301,18 @@ pub fn home_dir() -> Option { _ => sz - 1, // sz includes the null terminator } }, super::os2path).ok() - }) + } +} + +#[cfg(target_vendor = "uwp")] +fn home_dir_crt() -> Option { + None +} + +pub fn home_dir() -> Option { + crate::env::var_os("HOME").or_else(|| { + crate::env::var_os("USERPROFILE") + }).map(PathBuf::from).or_else(|| home_dir_crt()) } pub fn exit(code: i32) -> ! { diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index f3178a5e9e..7eae28cb14 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -19,7 +19,7 @@ pub fn is_verbatim_sep(b: u8) -> bool { b == b'\\' } -pub fn parse_prefix<'a>(path: &'a OsStr) -> Option> { +pub fn parse_prefix(path: &OsStr) -> Option> { use crate::path::Prefix::*; unsafe { // The unsafety here stems from converting between &OsStr and &[u8] diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 493ee8a9a2..041d5385eb 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -45,7 +45,7 @@ pub struct Pipes { /// mode. This means that technically speaking it should only ever be used /// with `OVERLAPPED` instances, but also works out ok if it's only ever used /// once at a time (which we do indeed guarantee). -pub fn anon_pipe(ours_readable: bool) -> io::Result { +pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result { // Note that we specifically do *not* use `CreatePipe` here because // unfortunately the anonymous pipes returned do not support overlapped // operations. Instead, we create a "hopefully unique" name and create a @@ -137,6 +137,13 @@ pub fn anon_pipe(ours_readable: bool) -> io::Result { opts.write(ours_readable); opts.read(!ours_readable); opts.share_mode(0); + let size = mem::size_of::(); + let mut sa = c::SECURITY_ATTRIBUTES { + nLength: size as c::DWORD, + lpSecurityDescriptor: ptr::null_mut(), + bInheritHandle: their_handle_inheritable as i32, + }; + opts.security_attributes(&mut sa); let theirs = File::open(Path::new(&name), &opts)?; let theirs = AnonPipe { inner: theirs.into_handle() }; @@ -342,7 +349,7 @@ impl<'a> Drop for AsyncPipe<'a> { // If anything here fails, there's not really much we can do, so we leak // the buffer/OVERLAPPED pointers to ensure we're at least memory safe. if self.pipe.cancel_io().is_err() || self.result().is_err() { - let buf = mem::replace(self.dst, Vec::new()); + let buf = mem::take(self.dst); let overlapped = Box::new(unsafe { mem::zeroed() }); let overlapped = mem::replace(&mut self.overlapped, overlapped); mem::forget((buf, overlapped)); diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index e39b7ae889..05e0ca6706 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -267,13 +267,8 @@ impl Stdio { Stdio::MakePipe => { let ours_readable = stdio_id != c::STD_INPUT_HANDLE; - let pipes = pipe::anon_pipe(ours_readable)?; + let pipes = pipe::anon_pipe(ours_readable, true)?; *pipe = Some(pipes.ours); - cvt(unsafe { - c::SetHandleInformation(pipes.theirs.handle().raw(), - c::HANDLE_FLAG_INHERIT, - c::HANDLE_FLAG_INHERIT) - })?; Ok(pipes.theirs.into_handle()) } diff --git a/src/libstd/sys/windows/rand.rs b/src/libstd/sys/windows/rand.rs index 0193f4defa..c9bcb5d741 100644 --- a/src/libstd/sys/windows/rand.rs +++ b/src/libstd/sys/windows/rand.rs @@ -2,6 +2,7 @@ use crate::io; use crate::mem; use crate::sys::c; +#[cfg(not(target_vendor = "uwp"))] pub fn hashmap_random_keys() -> (u64, u64) { let mut v = (0, 0); let ret = unsafe { @@ -14,3 +15,20 @@ pub fn hashmap_random_keys() -> (u64, u64) { } return v } + +#[cfg(target_vendor = "uwp")] +pub fn hashmap_random_keys() -> (u64, u64) { + use crate::ptr; + + let mut v = (0, 0); + let ret = unsafe { + c::BCryptGenRandom(ptr::null_mut(), &mut v as *mut _ as *mut u8, + mem::size_of_val(&v) as c::ULONG, + c::BCRYPT_USE_SYSTEM_PREFERRED_RNG) + }; + if ret != 0 { + panic!("couldn't generate random bytes: {}", + io::Error::last_os_error()); + } + return v +} diff --git a/src/libstd/sys/redox/stack_overflow.rs b/src/libstd/sys/windows/stack_overflow_uwp.rs similarity index 52% rename from src/libstd/sys/redox/stack_overflow.rs rename to src/libstd/sys/windows/stack_overflow_uwp.rs index cf01d323d4..e7236cf359 100644 --- a/src/libstd/sys/redox/stack_overflow.rs +++ b/src/libstd/sys/windows/stack_overflow_uwp.rs @@ -3,15 +3,11 @@ pub struct Handler; impl Handler { - pub unsafe fn new() -> Handler { + pub fn new() -> Handler { Handler } } -pub unsafe fn init() { +pub unsafe fn init() {} -} - -pub unsafe fn cleanup() { - -} +pub unsafe fn cleanup() {} diff --git a/src/libstd/sys/windows/stdio_uwp.rs b/src/libstd/sys/windows/stdio_uwp.rs new file mode 100644 index 0000000000..489d3df286 --- /dev/null +++ b/src/libstd/sys/windows/stdio_uwp.rs @@ -0,0 +1,85 @@ +#![unstable(issue = "0", feature = "windows_stdio")] + +use crate::io; +use crate::sys::c; +use crate::sys::handle::Handle; +use crate::mem::ManuallyDrop; + +pub struct Stdin { +} +pub struct Stdout; +pub struct Stderr; + +const MAX_BUFFER_SIZE: usize = 8192; +pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3; + +pub fn get_handle(handle_id: c::DWORD) -> io::Result { + let handle = unsafe { c::GetStdHandle(handle_id) }; + if handle == c::INVALID_HANDLE_VALUE { + Err(io::Error::last_os_error()) + } else if handle.is_null() { + Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32)) + } else { + Ok(handle) + } +} + +fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result { + let handle = get_handle(handle_id)?; + let handle = Handle::new(handle); + ManuallyDrop::new(handle).write(data) +} + +impl Stdin { + pub fn new() -> io::Result { + Ok(Stdin { }) + } +} + +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let handle = get_handle(c::STD_INPUT_HANDLE)?; + let handle = Handle::new(handle); + ManuallyDrop::new(handle).read(buf) + } +} + +impl Stdout { + pub fn new() -> io::Result { + Ok(Stdout) + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + write(c::STD_OUTPUT_HANDLE, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub fn new() -> io::Result { + Ok(Stderr) + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + write(c::STD_ERROR_HANDLE, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +pub fn is_ebadf(err: &io::Error) -> bool { + err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32) +} + +pub fn panic_output() -> Option { + Stderr::new().ok() +} diff --git a/src/libstd/sys_common/alloc.rs b/src/libstd/sys_common/alloc.rs index 978a70bee0..1cfc7ed17f 100644 --- a/src/libstd/sys_common/alloc.rs +++ b/src/libstd/sys_common/alloc.rs @@ -12,7 +12,8 @@ use crate::ptr; target_arch = "powerpc", target_arch = "powerpc64", target_arch = "asmjs", - target_arch = "wasm32")))] + target_arch = "wasm32", + target_arch = "hexagon")))] pub const MIN_ALIGN: usize = 8; #[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64", diff --git a/src/libstd/sys_common/io.rs b/src/libstd/sys_common/io.rs index 44b0963302..8789abe55c 100644 --- a/src/libstd/sys_common/io.rs +++ b/src/libstd/sys_common/io.rs @@ -16,7 +16,7 @@ pub mod test { p.join(path) } - pub fn path<'a>(&'a self) -> &'a Path { + pub fn path(&self) -> &Path { let TempDir(ref p) = *self; p } diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index 13a59f66c5..9190a3b0d5 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -68,7 +68,6 @@ pub mod fs; cfg_if::cfg_if! { if #[cfg(any(target_os = "cloudabi", target_os = "l4re", - target_os = "redox", all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))] { pub use crate::sys::net; diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs index a4961974d8..d734f412bf 100644 --- a/src/libstd/sys_common/os_str_bytes.rs +++ b/src/libstd/sys_common/os_str_bytes.rs @@ -18,6 +18,12 @@ pub(crate) struct Buf { pub inner: Vec } +// FIXME: +// `Buf::as_slice` current implementation relies +// on `Slice` being layout-compatible with `[u8]`. +// When attribute privacy is implemented, `Slice` should be annotated as `#[repr(transparent)]`. +// Anyway, `Slice` representation and layout are considered implementation detail, are +// not documented and must not be relied upon. pub(crate) struct Slice { pub inner: [u8] } diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 9b355aa202..f85b5d632f 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -2,6 +2,7 @@ #![unstable(feature = "thread_local_internals", issue = "0")] +use crate::error::Error; use crate::fmt; /// A thread local storage key which owns its contents. @@ -189,6 +190,7 @@ macro_rules! __thread_local_inner { /// An error returned by [`LocalKey::try_with`](struct.LocalKey.html#method.try_with). #[stable(feature = "thread_local_try_with", since = "1.26.0")] +#[derive(Clone, Copy, Eq, PartialEq)] pub struct AccessError { _private: (), } @@ -207,6 +209,9 @@ impl fmt::Display for AccessError { } } +#[stable(feature = "thread_local_try_with", since = "1.26.0")] +impl Error for AccessError {} + impl LocalKey { #[doc(hidden)] #[unstable(feature = "thread_local_internals", diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 35de4f4008..764041d2f4 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -1742,6 +1742,6 @@ mod tests { assert!(thread::current().id() != spawned_id); } - // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due + // NOTE: the corresponding test for stderr is in ui/thread-stderr, due // to the test harness apparently interfering with stderr configuration. } diff --git a/src/libstd/time.rs b/src/libstd/time.rs index dc97f8c04a..98371b9ba3 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -396,6 +396,7 @@ impl SystemTime { /// This function may fail because measurements taken earlier are not /// guaranteed to always be before later measurements (due to anomalies such /// as the system clock being adjusted either forwards or backwards). + /// [`Instant`] can be used to measure elapsed time without this risk of failure. /// /// If successful, [`Ok`]`(`[`Duration`]`)` is returned where the duration represents /// the amount of time elapsed from the specified measurement to this one. @@ -406,6 +407,7 @@ impl SystemTime { /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok /// [`Duration`]: ../../std/time/struct.Duration.html /// [`Err`]: ../../std/result/enum.Result.html#variant.Err + /// [`Instant`]: ../../std/time/struct.Instant.html /// /// # Examples /// @@ -414,7 +416,7 @@ impl SystemTime { /// /// let sys_time = SystemTime::now(); /// let difference = sys_time.duration_since(sys_time) - /// .expect("SystemTime::duration_since failed"); + /// .expect("Clock may have gone backwards"); /// println!("{:?}", difference); /// ``` #[stable(feature = "time2", since = "1.8.0")] @@ -423,7 +425,8 @@ impl SystemTime { self.0.sub_time(&earlier.0).map_err(SystemTimeError) } - /// Returns the amount of time elapsed since this system time was created. + /// Returns the difference between the clock time when this + /// system time was created, and the current clock time. /// /// This function may fail as the underlying system clock is susceptible to /// drift and updates (e.g., the system clock could go backwards), so this @@ -431,12 +434,15 @@ impl SystemTime { /// returned where the duration represents the amount of time elapsed from /// this time measurement to the current time. /// + /// To measure elapsed time reliably, use [`Instant`] instead. + /// /// Returns an [`Err`] if `self` is later than the current system time, and /// the error contains how far from the current system time `self` is. /// /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok /// [`Duration`]: ../../std/time/struct.Duration.html /// [`Err`]: ../../std/result/enum.Result.html#variant.Err + /// [`Instant`]: ../../std/time/struct.Instant.html /// /// # Examples /// diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index b48f3c9b8b..d4a9acc156 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -7,17 +7,18 @@ edition = "2018" [lib] name = "syntax" path = "lib.rs" -crate-type = ["dylib"] +doctest = false [dependencies] bitflags = "1.0" -serialize = { path = "../libserialize" } +rustc_serialize = { path = "../libserialize", package = "serialize" } log = "0.4" scoped-tls = "1.0" lazy_static = "1.0.0" syntax_pos = { path = "../libsyntax_pos" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_lexer = { path = "../librustc_lexer" } rustc_macros = { path = "../librustc_macros" } rustc_target = { path = "../librustc_target" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c627596bbd..052eb55b40 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -5,8 +5,8 @@ pub use UnsafeSource::*; pub use crate::symbol::{Ident, Symbol as Name}; pub use crate::util::parser::ExprPrecedence; -use crate::ext::hygiene::{Mark, SyntaxContext}; -use crate::parse::token; +use crate::ext::hygiene::{ExpnId, SyntaxContext}; +use crate::parse::token::{self, DelimToken}; use crate::print::pprust; use crate::ptr::P; use crate::source_map::{dummy_spanned, respan, Spanned}; @@ -22,11 +22,14 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; -use serialize::{self, Decoder, Encoder}; +use rustc_serialize::{self, Decoder, Encoder}; use std::fmt; pub use rustc_target::abi::FloatTy; +#[cfg(test)] +mod tests; + #[derive(Clone, RustcEncodable, RustcDecodable, Copy)] pub struct Label { pub ident: Ident, @@ -50,11 +53,17 @@ impl fmt::Debug for Lifetime { f, "lifetime({}: {})", self.id, - pprust::lifetime_to_string(self) + self ) } } +impl fmt::Display for Lifetime { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.ident.name.as_str()) + } +} + /// A "Path" is essentially Rust's notion of a name. /// /// It's represented as a sequence of identifiers, @@ -245,12 +254,12 @@ mod node_id_inner { pub use node_id_inner::NodeId; impl NodeId { - pub fn placeholder_from_mark(mark: Mark) -> Self { - NodeId::from_u32(mark.as_u32()) + pub fn placeholder_from_expn_id(expn_id: ExpnId) -> Self { + NodeId::from_u32(expn_id.as_u32()) } - pub fn placeholder_to_mark(self) -> Mark { - Mark::from_u32(self.as_u32()) + pub fn placeholder_to_expn_id(self) -> ExpnId { + ExpnId::from_u32(self.as_u32()) } } @@ -260,13 +269,13 @@ impl fmt::Display for NodeId { } } -impl serialize::UseSpecializedEncodable for NodeId { +impl rustc_serialize::UseSpecializedEncodable for NodeId { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(self.as_u32()) } } -impl serialize::UseSpecializedDecodable for NodeId { +impl rustc_serialize::UseSpecializedDecodable for NodeId { fn default_decode(d: &mut D) -> Result { d.read_u32().map(NodeId::from_u32) } @@ -513,21 +522,28 @@ impl fmt::Debug for Pat { } impl Pat { + /// Attempt reparsing the pattern as a type. + /// This is intended for use by diagnostics. pub(super) fn to_ty(&self) -> Option> { let node = match &self.node { + // In a type expression `_` is an inference variable. PatKind::Wild => TyKind::Infer, + // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) => { TyKind::Path(None, Path::from_ident(*ident)) } PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), PatKind::Mac(mac) => TyKind::Mac(mac.clone()), + // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type. PatKind::Ref(pat, mutbl) => pat .to_ty() .map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?, - PatKind::Slice(pats, None, _) if pats.len() == 1 => { - pats[0].to_ty().map(TyKind::Slice)? - } - PatKind::Tuple(pats, None) => { + // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array, + // when `P` can be reparsed as a type `T`. + PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?, + // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)` + // assuming `T0` to `Tn` are all syntactically valid as types. + PatKind::Tuple(pats) => { let mut tys = Vec::with_capacity(pats.len()); // FIXME(#48994) - could just be collected into an Option for pat in pats { @@ -553,19 +569,15 @@ impl Pat { return false; } - match self.node { - PatKind::Ident(_, _, Some(ref p)) => p.walk(it), - PatKind::Struct(_, ref fields, _) => fields.iter().all(|field| field.node.pat.walk(it)), - PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => { + match &self.node { + PatKind::Ident(_, _, Some(p)) => p.walk(it), + PatKind::Struct(_, fields, _) => fields.iter().all(|field| field.node.pat.walk(it)), + PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) => { s.iter().all(|p| p.walk(it)) } - PatKind::Box(ref s) | PatKind::Ref(ref s, _) | PatKind::Paren(ref s) => s.walk(it), - PatKind::Slice(ref before, ref slice, ref after) => { - before.iter().all(|p| p.walk(it)) - && slice.iter().all(|p| p.walk(it)) - && after.iter().all(|p| p.walk(it)) - } + PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it), PatKind::Wild + | PatKind::Rest | PatKind::Lit(_) | PatKind::Range(..) | PatKind::Ident(..) @@ -573,6 +585,14 @@ impl Pat { | PatKind::Mac(_) => true, } } + + /// Is this a `..` pattern? + pub fn is_rest(&self) -> bool { + match self.node { + PatKind::Rest => true, + _ => false, + } + } } /// A single field in a struct pattern @@ -624,9 +644,7 @@ pub enum PatKind { Struct(Path, Vec>, /* recovered */ bool), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// `0 <= position <= subpats.len()`. - TupleStruct(Path, Vec>, Option), + TupleStruct(Path, Vec>), /// A possibly qualified path pattern. /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants @@ -635,9 +653,7 @@ pub enum PatKind { Path(Option, Path), /// A tuple pattern (`(a, b)`). - /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// `0 <= position <= subpats.len()`. - Tuple(Vec>, Option), + Tuple(Vec>), /// A `box` pattern. Box(P), @@ -651,9 +667,22 @@ pub enum PatKind { /// A range pattern (e.g., `1...2`, `1..=2` or `1..2`). Range(P, P, Spanned), - /// `[a, b, ..i, y, z]` is represented as: - /// `PatKind::Slice(box [a, b], Some(i), box [y, z])` - Slice(Vec>, Option>, Vec>), + /// A slice pattern `[a, b, c]`. + Slice(Vec>), + + /// A rest pattern `..`. + /// + /// Syntactically it is valid anywhere. + /// + /// Semantically however, it only has meaning immediately inside: + /// - a slice pattern: `[a, .., b]`, + /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`, + /// - a tuple pattern: `(a, .., b)`, + /// - a tuple struct/variant pattern: `$path(a, .., b)`. + /// + /// In all of these cases, an additional restriction applies, + /// only one rest pattern may occur in the pattern sequences. + Rest, /// Parentheses in patterns used for grouping (i.e., `(PAT)`). Paren(P), @@ -1152,7 +1181,7 @@ pub enum ExprKind { /// preexisting defs. Async(CaptureBy, NodeId, P), /// An await expression (`my_future.await`). - Await(AwaitOrigin, P), + Await(P), /// A try block (`try { ... }`). TryBlock(P), @@ -1255,15 +1284,6 @@ pub enum Movability { Movable, } -/// Whether an `await` comes from `await!` or `.await` syntax. -/// FIXME: this should be removed when support for legacy `await!` is removed. -/// https://github.com/rust-lang/rust/issues/60610 -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] -pub enum AwaitOrigin { - FieldLike, - MacroLike, -} - pub type Mac = Spanned; /// Represents a macro invocation. The `Path` indicates which macro @@ -1277,6 +1297,7 @@ pub struct Mac_ { pub path: Path, pub delim: MacDelimiter, pub tts: TokenStream, + pub prior_type_ascription: Option<(Span, bool)>, } #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] @@ -1292,6 +1313,16 @@ impl Mac_ { } } +impl MacDelimiter { + crate fn to_token(self) -> DelimToken { + match self { + MacDelimiter::Parenthesis => DelimToken::Paren, + MacDelimiter::Bracket => DelimToken::Bracket, + MacDelimiter::Brace => DelimToken::Brace, + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct MacroDef { pub tokens: TokenStream, @@ -1449,6 +1480,7 @@ pub enum TraitItemKind { Macro(Mac), } +/// Represents anything within an `impl` block. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct ImplItem { pub id: NodeId, @@ -1463,12 +1495,13 @@ pub struct ImplItem { pub tokens: Option, } +/// Represents various kinds of content within an `impl`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum ImplItemKind { Const(P, P), Method(MethodSig, P), - Type(P), - Existential(GenericBounds), + TyAlias(P), + OpaqueTy(GenericBounds), Macro(Mac), } @@ -1671,7 +1704,7 @@ pub enum TyKind { /// /// The `NodeId` exists to prevent lowering from having to /// generate `NodeId`s on the fly, which would complicate - /// the generation of `existential type` items significantly. + /// the generation of opaque `type Foo = impl Trait` items significantly. ImplTrait(NodeId, GenericBounds), /// No-op; kept solely so that we can pretty-print faithfully. Paren(P), @@ -1760,6 +1793,7 @@ pub struct Arg { pub ty: P, pub pat: P, pub id: NodeId, + pub span: Span, } /// Alternative representation for `Arg`s describing `self` parameter of methods. @@ -1818,6 +1852,7 @@ impl Arg { node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None), span, }), + span, ty, id: DUMMY_NODE_ID, }; @@ -2066,9 +2101,7 @@ pub enum AttrStyle { Inner, } -#[derive( - Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialOrd, Ord, Copy, -)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy)] pub struct AttrId(pub usize); impl Idx for AttrId { @@ -2080,6 +2113,18 @@ impl Idx for AttrId { } } +impl rustc_serialize::Encodable for AttrId { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_unit() + } +} + +impl rustc_serialize::Decodable for AttrId { + fn decode(d: &mut D) -> Result { + d.read_nil().map(|_| crate::attr::mk_attr_id()) + } +} + /// Metadata associated with an item. /// Doc-comments are promoted to attributes that have `is_sugared_doc = true`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -2292,11 +2337,11 @@ pub enum ItemKind { /// A type alias (`type` or `pub type`). /// /// E.g., `type Foo = Bar;`. - Ty(P, Generics), - /// An existential type declaration (`existential type`). + TyAlias(P, Generics), + /// An opaque `impl Trait` type alias. /// - /// E.g., `existential type Foo: Bar + Boo;`. - Existential(GenericBounds, Generics), + /// E.g., `type Foo = impl Bar + Boo;`. + OpaqueTy(GenericBounds, Generics), /// An enum definition (`enum` or `pub enum`). /// /// E.g., `enum Foo { C, D }`. @@ -2349,8 +2394,8 @@ impl ItemKind { ItemKind::Mod(..) => "module", ItemKind::ForeignMod(..) => "foreign module", ItemKind::GlobalAsm(..) => "global asm", - ItemKind::Ty(..) => "type alias", - ItemKind::Existential(..) => "existential type", + ItemKind::TyAlias(..) => "type alias", + ItemKind::OpaqueTy(..) => "opaque type", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", ItemKind::Union(..) => "union", @@ -2394,16 +2439,3 @@ impl ForeignItemKind { } } } - -#[cfg(test)] -mod tests { - use super::*; - use serialize; - - // Are ASTs encodable? - #[test] - fn check_asts_encodable() { - fn assert_encodable() {} - assert_encodable::(); - } -} diff --git a/src/libsyntax/ast/tests.rs b/src/libsyntax/ast/tests.rs new file mode 100644 index 0000000000..7558e9cc3a --- /dev/null +++ b/src/libsyntax/ast/tests.rs @@ -0,0 +1,8 @@ +use super::*; + +// Are ASTs encodable? +#[test] +fn check_asts_encodable() { + fn assert_encodable() {} + assert_encodable::(); +} diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index bf6eab4ec9..b5037b75f7 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -1,10 +1,13 @@ //! Parsing and validation of builtin attributes use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; +use crate::early_buffered_lints::BufferedEarlyLintId; +use crate::ext::base::ExtCtxt; use crate::feature_gate::{Features, GatedCfg}; use crate::parse::ParseSess; use errors::{Applicability, Handler}; +use syntax_pos::hygiene::Transparency; use syntax_pos::{symbol::Symbol, symbol::sym, Span}; use super::{mark_used, MetaItemKind}; @@ -18,6 +21,27 @@ enum AttrError { UnsupportedLiteral(&'static str, /* is_bytestr */ bool), } +/// A template that the attribute input must match. +/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now. +#[derive(Clone, Copy)] +pub struct AttributeTemplate { + crate word: bool, + crate list: Option<&'static str>, + crate name_value_str: Option<&'static str>, +} + +impl AttributeTemplate { + /// Checks that the given meta-item is compatible with this template. + fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool { + match meta_item_kind { + ast::MetaItemKind::Word => self.word, + ast::MetaItemKind::List(..) => self.list.is_some(), + ast::MetaItemKind::NameValue(lit) if lit.node.is_str() => self.name_value_str.is_some(), + ast::MetaItemKind::NameValue(..) => false, + } + } +} + fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { let diag = &sess.span_diagnostic; match error { @@ -130,7 +154,7 @@ pub struct Stability { #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue - Unstable { reason: Option, issue: u32 }, + Unstable { reason: Option, issue: u32, is_soft: bool }, Stable { since: Symbol }, } @@ -170,7 +194,8 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool }) } -/// Finds the first stability attribute. `None` if none exists. +/// Collects stability info from all stability attributes in `attrs`. +/// Returns `None` if no stability attributes are found. pub fn find_stability(sess: &ParseSess, attrs: &[Attribute], item_sp: Span) -> Option { find_stability_generic(sess, attrs.iter(), item_sp) @@ -318,19 +343,27 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let mut feature = None; let mut reason = None; let mut issue = None; + let mut is_soft = false; for meta in metas { if let Some(mi) = meta.meta_item() { match mi.name_or_empty() { sym::feature => if !get(mi, &mut feature) { continue 'outer }, sym::reason => if !get(mi, &mut reason) { continue 'outer }, sym::issue => if !get(mi, &mut issue) { continue 'outer }, + sym::soft => { + if !mi.is_word() { + let msg = "`soft` should not have any arguments"; + sess.span_diagnostic.span_err(mi.span, msg); + } + is_soft = true; + } _ => { handle_errors( sess, meta.span(), AttrError::UnknownMetaItem( mi.path.to_string(), - &["feature", "reason", "issue"] + &["feature", "reason", "issue", "soft"] ), ); continue 'outer @@ -362,7 +395,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, "incorrect 'issue'"); continue } - } + }, + is_soft, }, feature, rustc_depr: None, @@ -854,3 +888,108 @@ fn int_type_of_word(s: Symbol) -> Option { _ => None } } + +pub enum TransparencyError { + UnknownTransparency(Symbol, Span), + MultipleTransparencyAttrs(Span, Span), +} + +pub fn find_transparency( + attrs: &[Attribute], is_legacy: bool +) -> (Transparency, Option) { + let mut transparency = None; + let mut error = None; + for attr in attrs { + if attr.check_name(sym::rustc_macro_transparency) { + if let Some((_, old_span)) = transparency { + error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span)); + break; + } else if let Some(value) = attr.value_str() { + transparency = Some((match &*value.as_str() { + "transparent" => Transparency::Transparent, + "semitransparent" => Transparency::SemiTransparent, + "opaque" => Transparency::Opaque, + _ => { + error = Some(TransparencyError::UnknownTransparency(value, attr.span)); + continue; + } + }, attr.span)); + } + } + } + let fallback = if is_legacy { Transparency::SemiTransparent } else { Transparency::Opaque }; + (transparency.map_or(fallback, |t| t.0), error) +} + +pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { + // All the built-in macro attributes are "words" at the moment. + let template = AttributeTemplate { word: true, list: None, name_value_str: None }; + let attr = ecx.attribute(meta_item.clone()); + check_builtin_attribute(ecx.parse_sess, &attr, name, template); +} + +crate fn check_builtin_attribute( + sess: &ParseSess, attr: &ast::Attribute, name: Symbol, template: AttributeTemplate +) { + // Some special attributes like `cfg` must be checked + // before the generic check, so we skip them here. + let should_skip = |name| name == sym::cfg; + // Some of previously accepted forms were used in practice, + // report them as warnings for now. + let should_warn = |name| name == sym::doc || name == sym::ignore || + name == sym::inline || name == sym::link || + name == sym::test || name == sym::bench; + + match attr.parse_meta(sess) { + Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) { + let error_msg = format!("malformed `{}` attribute input", name); + let mut msg = "attribute must be of the form ".to_owned(); + let mut suggestions = vec![]; + let mut first = true; + if template.word { + first = false; + let code = format!("#[{}]", name); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if let Some(descr) = template.list { + if !first { + msg.push_str(" or "); + } + first = false; + let code = format!("#[{}({})]", name, descr); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if let Some(descr) = template.name_value_str { + if !first { + msg.push_str(" or "); + } + let code = format!("#[{} = \"{}\"]", name, descr); + msg.push_str(&format!("`{}`", &code)); + suggestions.push(code); + } + if should_warn(name) { + sess.buffer_lint( + BufferedEarlyLintId::IllFormedAttributeInput, + meta.span, + ast::CRATE_NODE_ID, + &msg, + ); + } else { + sess.span_diagnostic.struct_span_err(meta.span, &error_msg) + .span_suggestions( + meta.span, + if suggestions.len() == 1 { + "must be of the form" + } else { + "the following are the possible correct uses" + }, + suggestions.into_iter(), + Applicability::HasPlaceholders, + ).emit(); + } + } + Err(mut err) => err.emit(), + } +} diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 436620ae72..a9d3227b3a 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -2,17 +2,14 @@ mod builtin; -pub use builtin::{ - cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation, - find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, OptimizeAttr, - IntType, ReprAttr, RustcDeprecation, Stability, StabilityLevel, UnwindAttr, -}; +pub use builtin::*; pub use IntType::*; pub use ReprAttr::*; pub use StabilityLevel::*; +pub use crate::ast::Attribute; use crate::ast; -use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; +use crate::ast::{AttrId, AttrStyle, Name, Ident, Path, PathSegment}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam}; use crate::mut_visit::visit_clobber; @@ -34,7 +31,7 @@ use std::iter; use std::ops::DerefMut; pub fn mark_used(attr: &Attribute) { - debug!("Marking {:?} as used.", attr); + debug!("marking {:?} as used", attr); GLOBALS.with(|globals| { globals.used_attrs.lock().insert(attr.id); }); @@ -47,7 +44,7 @@ pub fn is_used(attr: &Attribute) -> bool { } pub fn mark_known(attr: &Attribute) { - debug!("Marking {:?} as known.", attr); + debug!("marking {:?} as known", attr); GLOBALS.with(|globals| { globals.known_attrs.lock().insert(attr.id); }); @@ -60,7 +57,7 @@ pub fn is_known(attr: &Attribute) -> bool { } pub fn is_known_lint_tool(m_item: Ident) -> bool { - ["clippy"].contains(&m_item.as_str().as_ref()) + [sym::clippy, sym::rustc].contains(&m_item.name) } impl NestedMetaItem { @@ -332,13 +329,14 @@ impl Attribute { let meta = mk_name_value_item_str( Ident::with_empty_ctxt(sym::doc), dummy_spanned(Symbol::intern(&strip_doc_comment_decoration(&comment.as_str())))); - let mut attr = if self.style == ast::AttrStyle::Outer { - mk_attr_outer(self.span, self.id, meta) - } else { - mk_attr_inner(self.span, self.id, meta) - }; - attr.is_sugared_doc = true; - f(&attr) + f(&Attribute { + id: self.id, + style: self.style, + path: meta.path, + tokens: meta.node.tokens(meta.span), + is_sugared_doc: true, + span: self.span, + }) } else { f(self) } @@ -349,16 +347,17 @@ impl Attribute { pub fn mk_name_value_item_str(ident: Ident, value: Spanned) -> MetaItem { let lit_kind = LitKind::Str(value.node, ast::StrStyle::Cooked); - mk_name_value_item(ident.span.to(value.span), ident, lit_kind, value.span) + mk_name_value_item(ident, lit_kind, value.span) } -pub fn mk_name_value_item(span: Span, ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { +pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { let lit = Lit::from_lit_kind(lit_kind, lit_span); + let span = ident.span.to(lit_span); MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(lit) } } -pub fn mk_list_item(span: Span, ident: Ident, items: Vec) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) } +pub fn mk_list_item(ident: Ident, items: Vec) -> MetaItem { + MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::List(items) } } pub fn mk_word_item(ident: Ident) -> MetaItem { @@ -369,7 +368,7 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { NestedMetaItem::MetaItem(mk_word_item(ident)) } -pub fn mk_attr_id() -> AttrId { +crate fn mk_attr_id() -> AttrId { use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -380,46 +379,36 @@ pub fn mk_attr_id() -> AttrId { AttrId(id) } -/// Returns an inner attribute with the given value. -pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute { - mk_spanned_attr_inner(span, id, item) -} - /// Returns an inner attribute with the given value and span. -pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute { +pub fn mk_attr_inner(item: MetaItem) -> Attribute { Attribute { - id, + id: mk_attr_id(), style: ast::AttrStyle::Inner, path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, - span: sp, + span: item.span, } } -/// Returns an outer attribute with the given value. -pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute { - mk_spanned_attr_outer(span, id, item) -} - /// Returns an outer attribute with the given value and span. -pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute { +pub fn mk_attr_outer(item: MetaItem) -> Attribute { Attribute { - id, + id: mk_attr_id(), style: ast::AttrStyle::Outer, path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, - span: sp, + span: item.span, } } -pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { +pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute { let style = doc_comment_style(&text.as_str()); let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked); let lit = Lit::from_lit_kind(lit_kind, span); Attribute { - id, + id: mk_attr_id(), style, path: Path::from_ident(Ident::with_empty_ctxt(sym::doc).with_span_pos(span)), tokens: MetaItemKind::NameValue(lit).tokens(span), @@ -440,12 +429,12 @@ pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { }) } -pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> { +pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> { attrs.iter().find(|attr| attr.check_name(name)) } -pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol) - -> impl Iterator { +pub fn filter_by_name(attrs: &[Attribute], name: Symbol) + -> impl Iterator { attrs.iter().filter(move |attr| attr.check_name(name)) } diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs index 6f7493ad59..b754d08337 100644 --- a/src/libsyntax/diagnostics/macros.rs +++ b/src/libsyntax/diagnostics/macros.rs @@ -170,19 +170,19 @@ macro_rules! help { #[macro_export] macro_rules! register_diagnostics { ($($code:tt),*) => ( - $(register_diagnostic! { $code })* + $($crate::register_diagnostic! { $code })* ); ($($code:tt),*,) => ( - $(register_diagnostic! { $code })* + $($crate::register_diagnostic! { $code })* ) } #[macro_export] macro_rules! register_long_diagnostics { ($($code:tt: $description:tt),*) => ( - $(register_diagnostic! { $code, $description })* + $($crate::register_diagnostic! { $code, $description })* ); ($($code:tt: $description:tt),*,) => ( - $(register_diagnostic! { $code, $description })* + $($crate::register_diagnostic! { $code, $description })* ) } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index ee640a1603..80591ad304 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -4,7 +4,6 @@ use std::env; use crate::ast::{self, Ident, Name}; use crate::source_map; use crate::ext::base::{ExtCtxt, MacEager, MacResult}; -use crate::ext::build::AstBuilder; use crate::parse::token::{self, Token}; use crate::ptr::P; use crate::symbol::kw; @@ -123,7 +122,6 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>, MacEager::items(smallvec![]) } -#[allow(deprecated)] pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>, span: Span, token_tree: &[TokenTree]) @@ -149,7 +147,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>, ecx.span_bug(span, &format!( "error writing metadata for triple `{}` and crate `{}`, error: {}, \ cause: {:?}", - target_triple, crate_name, e.description(), e.cause() + target_triple, crate_name, e.description(), e.source() )); } }); diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs index b26a1165fe..36c1da2929 100644 --- a/src/libsyntax/early_buffered_lints.rs +++ b/src/libsyntax/early_buffered_lints.rs @@ -10,6 +10,7 @@ use syntax_pos::MultiSpan; /// passed to `rustc::lint::Lint::from_parser_lint_id` to get a `rustc::lint::Lint`. pub enum BufferedEarlyLintId { IllFormedAttributeInput, + MetaVariableMisuse, } /// Stores buffered lint info which can later be passed to `librustc`. diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs index e2d212eb72..1ba29011f7 100644 --- a/src/libsyntax/error_codes.rs +++ b/src/libsyntax/error_codes.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - // Error messages for EXXXX errors. // Each message should start and end with a new line, and be wrapped to 80 characters. // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. @@ -182,7 +180,7 @@ beta compilers will not comply. Example of erroneous code (on a stable compiler): ```ignore (depends on release channel) -#![feature(non_ascii_idents)] // error: #![feature] may not be used on the +#![feature(non_ascii_idents)] // error: `#![feature]` may not be used on the // stable release channel ``` diff --git a/src/libsyntax/ext/allocator.rs b/src/libsyntax/ext/allocator.rs new file mode 100644 index 0000000000..99aeb5414c --- /dev/null +++ b/src/libsyntax/ext/allocator.rs @@ -0,0 +1,75 @@ +use crate::{ast, attr, visit}; +use crate::symbol::{sym, Symbol}; +use syntax_pos::Span; + +#[derive(Clone, Copy)] +pub enum AllocatorKind { + Global, + DefaultLib, + DefaultExe, +} + +impl AllocatorKind { + pub fn fn_name(&self, base: &str) -> String { + match *self { + AllocatorKind::Global => format!("__rg_{}", base), + AllocatorKind::DefaultLib => format!("__rdl_{}", base), + AllocatorKind::DefaultExe => format!("__rde_{}", base), + } + } +} + +pub enum AllocatorTy { + Layout, + Ptr, + ResultPtr, + Unit, + Usize, +} + +pub struct AllocatorMethod { + pub name: &'static str, + pub inputs: &'static [AllocatorTy], + pub output: AllocatorTy, +} + +pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ + AllocatorMethod { + name: "alloc", + inputs: &[AllocatorTy::Layout], + output: AllocatorTy::ResultPtr, + }, + AllocatorMethod { + name: "dealloc", + inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout], + output: AllocatorTy::Unit, + }, + AllocatorMethod { + name: "realloc", + inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize], + output: AllocatorTy::ResultPtr, + }, + AllocatorMethod { + name: "alloc_zeroed", + inputs: &[AllocatorTy::Layout], + output: AllocatorTy::ResultPtr, + }, +]; + +pub fn global_allocator_spans(krate: &ast::Crate) -> Vec { + struct Finder { name: Symbol, spans: Vec } + impl<'ast> visit::Visitor<'ast> for Finder { + fn visit_item(&mut self, item: &'ast ast::Item) { + if item.ident.name == self.name && + attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) { + self.spans.push(item.span); + } + visit::walk_item(self, item) + } + } + + let name = Symbol::intern(&AllocatorKind::Global.fn_name("alloc")); + let mut f = Finder { name, spans: Vec::new() }; + visit::walk_crate(&mut f, krate); + f.spans +} diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 318a5a3a82..50ae052b4b 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,21 +1,21 @@ use crate::ast::{self, Attribute, Name, PatKind}; -use crate::attr::HasAttrs; +use crate::attr::{HasAttrs, Stability, Deprecation}; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; -use crate::ext::hygiene::{Mark, SyntaxContext, Transparency}; +use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency}; use crate::mut_visit::{self, MutVisitor}; use crate::parse::{self, parser, DirectoryOwnership}; use crate::parse::token; use crate::ptr::P; use crate::symbol::{kw, sym, Ident, Symbol}; use crate::{ThinVec, MACRO_ARGUMENTS}; -use crate::tokenstream::{self, TokenStream}; +use crate::tokenstream::{self, TokenStream, TokenTree}; use errors::{DiagnosticBuilder, DiagnosticId}; use smallvec::{smallvec, SmallVec}; -use syntax_pos::{Span, MultiSpan, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnInfo, ExpnFormat}; +use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP}; +use syntax_pos::hygiene::{ExpnInfo, ExpnKind}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; @@ -24,6 +24,7 @@ use std::path::PathBuf; use std::rc::Rc; use std::default::Default; +pub use syntax_pos::hygiene::MacroKind; #[derive(Debug,Clone)] pub enum Annotatable { @@ -218,7 +219,6 @@ pub trait TTMacroExpander { ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, - def_span: Option, ) -> Box; } @@ -235,7 +235,6 @@ impl TTMacroExpander for F ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, - _def_span: Option, ) -> Box { struct AvoidInterpolatedIdents; @@ -518,37 +517,6 @@ impl MacResult for DummyResult { } } -/// Represents different kinds of macro invocations that can be resolved. -#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum MacroKind { - /// A bang macro - foo!() - Bang, - /// An attribute macro - #[foo] - Attr, - /// A derive attribute macro - #[derive(Foo)] - Derive, - /// A view of a procedural macro from the same crate that defines it. - ProcMacroStub, -} - -impl MacroKind { - pub fn descr(self) -> &'static str { - match self { - MacroKind::Bang => "macro", - MacroKind::Attr => "attribute macro", - MacroKind::Derive => "derive macro", - MacroKind::ProcMacroStub => "crate-local procedural macro", - } - } - - pub fn article(self) -> &'static str { - match self { - MacroKind::Attr => "an", - _ => "a", - } - } -} - /// A syntax extension kind. pub enum SyntaxExtensionKind { /// A token-based function-like macro. @@ -606,8 +574,8 @@ pub enum SyntaxExtensionKind { pub struct SyntaxExtension { /// A syntax extension kind. pub kind: SyntaxExtensionKind, - /// Some info about the macro's definition point. - pub def_info: Option<(ast::NodeId, Span)>, + /// Span of the macro definition. + pub span: Span, /// Hygienic properties of spans produced by this macro by default. pub default_transparency: Transparency, /// Whitelist of unstable features that are treated as stable inside this macro. @@ -616,12 +584,19 @@ pub struct SyntaxExtension { pub allow_internal_unsafe: bool, /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. pub local_inner_macros: bool, - /// The macro's feature name and tracking issue number if it is unstable. - pub unstable_feature: Option<(Symbol, u32)>, + /// The macro's stability info. + pub stability: Option, + /// The macro's deprecation info. + pub deprecation: Option, /// Names of helper attributes registered by this macro. pub helper_attrs: Vec, /// Edition of the crate in which this macro is defined. pub edition: Edition, + /// Built-in macros have a couple of special properties like availability + /// in `#[no_implicit_prelude]` modules, so we have to keep this flag. + pub is_builtin: bool, + /// We have to identify macros providing a `Copy` impl early for compatibility reasons. + pub is_derive_copy: bool, } impl SyntaxExtensionKind { @@ -657,31 +632,46 @@ impl SyntaxExtension { /// Constructs a syntax extension with default properties. pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension { SyntaxExtension { - def_info: None, + span: DUMMY_SP, default_transparency: kind.default_transparency(), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, - unstable_feature: None, + stability: None, + deprecation: None, helper_attrs: Vec::new(), edition, + is_builtin: false, + is_derive_copy: false, kind, } } - fn expn_format(&self, symbol: Symbol) -> ExpnFormat { - match self.kind { - SyntaxExtensionKind::Bang(..) | - SyntaxExtensionKind::LegacyBang(..) => ExpnFormat::MacroBang(symbol), - _ => ExpnFormat::MacroAttribute(symbol), + pub fn dummy_bang(edition: Edition) -> SyntaxExtension { + fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree]) + -> Box { + DummyResult::any(span) } + SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition) } - pub fn expn_info(&self, call_site: Span, format: &str) -> ExpnInfo { + pub fn dummy_derive(edition: Edition) -> SyntaxExtension { + fn expander(_: &mut ExtCtxt<'_>, _: Span, _: &ast::MetaItem, _: Annotatable) + -> Vec { + Vec::new() + } + SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition) + } + + pub fn non_macro_attr(mark_used: bool, edition: Edition) -> SyntaxExtension { + SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition) + } + + pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo { ExpnInfo { call_site, - format: self.expn_format(Symbol::intern(format)), - def_site: self.def_info.map(|(_, span)| span), + kind: ExpnKind::Macro(self.macro_kind(), descr), + def_site: self.span, default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), allow_internal_unsafe: self.allow_internal_unsafe, @@ -693,37 +683,38 @@ impl SyntaxExtension { pub type NamedSyntaxExtension = (Name, SyntaxExtension); +/// Error type that denotes indeterminacy. +pub struct Indeterminate; + +bitflags::bitflags! { + /// Built-in derives that need some extra tracking beyond the usual macro functionality. + #[derive(Default)] + pub struct SpecialDerives: u8 { + const PARTIAL_EQ = 1 << 0; + const EQ = 1 << 1; + const COPY = 1 << 2; + } +} + pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; - fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; + fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId; - fn resolve_dollar_crates(&mut self, fragment: &AstFragment); - fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, - derives: &[Mark]); - fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc); + fn resolve_dollar_crates(&mut self); + fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment, + derives: &[ExpnId]); + fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension); fn resolve_imports(&mut self); - fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool) - -> Result>, Determinacy>; - fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, invoc_id: Mark, - derives_in_scope: Vec, force: bool) - -> Result, Determinacy>; + fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) + -> Result>, Indeterminate>; fn check_unused_macros(&self); -} - -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum Determinacy { - Determined, - Undetermined, -} -impl Determinacy { - pub fn determined(determined: bool) -> Determinacy { - if determined { Determinacy::Determined } else { Determinacy::Undetermined } - } + fn has_derives(&self, expn_id: ExpnId, derives: SpecialDerives) -> bool; + fn add_derives(&mut self, expn_id: ExpnId, derives: SpecialDerives); } #[derive(Clone)] @@ -734,11 +725,11 @@ pub struct ModuleData { #[derive(Clone)] pub struct ExpansionData { - pub mark: Mark, + pub id: ExpnId, pub depth: usize, pub module: Rc, pub directory_ownership: DirectoryOwnership, - pub crate_span: Option, + pub prior_type_ascription: Option<(Span, bool)>, } /// One of these is made during expansion and incrementally updated as we go; @@ -764,11 +755,11 @@ impl<'a> ExtCtxt<'a> { root_path: PathBuf::new(), resolver, current_expansion: ExpansionData { - mark: Mark::root(), + id: ExpnId::root(), depth: 0, module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned { relative: None }, - crate_span: None, + prior_type_ascription: None, }, expansions: FxHashMap::default(), } @@ -792,13 +783,13 @@ impl<'a> ExtCtxt<'a> { pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config } pub fn call_site(&self) -> Span { - match self.current_expansion.mark.expn_info() { + match self.current_expansion.id.expn_info() { Some(expn_info) => expn_info.call_site, None => DUMMY_SP, } } pub fn backtrace(&self) -> SyntaxContext { - SyntaxContext::empty().apply_mark(self.current_expansion.mark) + SyntaxContext::empty().apply_mark(self.current_expansion.id) } /// Returns span for the macro which originally caused the current expansion to happen. @@ -809,7 +800,7 @@ impl<'a> ExtCtxt<'a> { let mut last_macro = None; loop { if ctxt.outer_expn_info().map_or(None, |info| { - if info.format.name() == sym::include { + if info.kind.descr() == sym::include { // Stop going up the backtrace once include! is encountered return None; } @@ -906,7 +897,7 @@ impl<'a> ExtCtxt<'a> { ast::Ident::from_str(st) } pub fn std_path(&self, components: &[Symbol]) -> Vec { - let def_site = DUMMY_SP.apply_mark(self.current_expansion.mark); + let def_site = DUMMY_SP.apply_mark(self.current_expansion.id); iter::once(Ident::new(kw::DollarCrate, def_site)) .chain(components.iter().map(|&s| Ident::with_empty_ctxt(s))) .collect() @@ -918,6 +909,31 @@ impl<'a> ExtCtxt<'a> { pub fn check_unused_macros(&self) { self.resolver.check_unused_macros(); } + + /// Resolve a path mentioned inside Rust code. + /// + /// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths. + /// + /// Returns an absolute path to the file that `path` refers to. + pub fn resolve_path(&self, path: impl Into, span: Span) -> PathBuf { + let path = path.into(); + + // Relative paths are resolved relative to the file in which they are found + // after macro expansion (that is, they are unhygienic). + if !path.is_absolute() { + let callsite = span.source_callsite(); + let mut result = match self.source_map().span_to_unmapped_path(callsite) { + FileName::Real(path) => path, + FileName::DocTest(path, _) => path, + other => panic!("cannot resolve relative path in non-file source `{}`", other), + }; + result.pop(); + result.push(path); + result + } else { + path + } + } } /// Extracts a string literal from the macro expanded version of `expr`, @@ -928,9 +944,6 @@ pub fn expr_to_spanned_string<'a>( mut expr: P, err_msg: &str, ) -> Result, Option>> { - // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation. - expr.span = expr.span.apply_mark(cx.current_expansion.mark); - // we want to be able to handle e.g., `concat!("foo", "bar")` cx.expander().visit_expr(&mut expr); Err(match expr.node { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index baf1031de1..22962499a2 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -9,295 +9,20 @@ use crate::ThinVec; use rustc_target::spec::abi::Abi; use syntax_pos::{Pos, Span}; -pub trait AstBuilder { - // Paths - fn path(&self, span: Span, strs: Vec ) -> ast::Path; - fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path; - fn path_global(&self, span: Span, strs: Vec ) -> ast::Path; - fn path_all(&self, sp: Span, - global: bool, - idents: Vec, - args: Vec, - constraints: Vec) - -> ast::Path; - - fn qpath(&self, self_type: P, - trait_path: ast::Path, - ident: ast::Ident) - -> (ast::QSelf, ast::Path); - fn qpath_all(&self, self_type: P, - trait_path: ast::Path, - ident: ast::Ident, - args: Vec, - constraints: Vec) - -> (ast::QSelf, ast::Path); - - // types and consts - fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy; - - fn ty(&self, span: Span, ty: ast::TyKind) -> P; - fn ty_path(&self, path: ast::Path) -> P; - fn ty_ident(&self, span: Span, idents: ast::Ident) -> P; - fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst; - fn const_ident(&self, span: Span, idents: ast::Ident) -> ast::AnonConst; - - fn ty_rptr(&self, span: Span, - ty: P, - lifetime: Option, - mutbl: ast::Mutability) -> P; - fn ty_ptr(&self, span: Span, - ty: P, - mutbl: ast::Mutability) -> P; - - fn ty_infer(&self, sp: Span) -> P; - - fn typaram(&self, - span: Span, - id: ast::Ident, - attrs: Vec, - bounds: ast::GenericBounds, - default: Option>) -> ast::GenericParam; - - fn trait_ref(&self, path: ast::Path) -> ast::TraitRef; - fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef; - fn trait_bound(&self, path: ast::Path) -> ast::GenericBound; - fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime; - fn lifetime_def(&self, - span: Span, - ident: ast::Ident, - attrs: Vec, - bounds: ast::GenericBounds) - -> ast::GenericParam; - - // Statements - fn stmt_expr(&self, expr: P) -> ast::Stmt; - fn stmt_semi(&self, expr: P) -> ast::Stmt; - fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt; - fn stmt_let_typed(&self, - sp: Span, - mutbl: bool, - ident: ast::Ident, - typ: P, - ex: P) - -> ast::Stmt; - fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt; - fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt; - - // Blocks - fn block(&self, span: Span, stmts: Vec) -> P; - fn block_expr(&self, expr: P) -> P; - - // Expressions - fn expr(&self, span: Span, node: ast::ExprKind) -> P; - fn expr_path(&self, path: ast::Path) -> P; - fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P; - fn expr_ident(&self, span: Span, id: ast::Ident) -> P; - - fn expr_self(&self, span: Span) -> P; - fn expr_binary(&self, sp: Span, op: ast::BinOpKind, - lhs: P, rhs: P) -> P; - fn expr_deref(&self, sp: Span, e: P) -> P; - fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P; - - fn expr_addr_of(&self, sp: Span, e: P) -> P; - fn expr_mut_addr_of(&self, sp: Span, e: P) -> P; - fn expr_field_access(&self, span: Span, expr: P, ident: ast::Ident) -> P; - fn expr_tup_field_access(&self, sp: Span, expr: P, - idx: usize) -> P; - fn expr_call(&self, span: Span, expr: P, args: Vec>) -> P; - fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec>) -> P; - fn expr_call_global(&self, sp: Span, fn_path: Vec, - args: Vec> ) -> P; - fn expr_method_call(&self, span: Span, - expr: P, ident: ast::Ident, - args: Vec> ) -> P; - fn expr_block(&self, b: P) -> P; - fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P; - - fn field_imm(&self, span: Span, name: Ident, e: P) -> ast::Field; - fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec) -> P; - fn expr_struct_ident(&self, span: Span, id: ast::Ident, - fields: Vec) -> P; - - fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P; - - fn expr_usize(&self, span: Span, i: usize) -> P; - fn expr_isize(&self, sp: Span, i: isize) -> P; - fn expr_u8(&self, sp: Span, u: u8) -> P; - fn expr_u16(&self, sp: Span, u: u16) -> P; - fn expr_u32(&self, sp: Span, u: u32) -> P; - fn expr_bool(&self, sp: Span, value: bool) -> P; - - fn expr_vec(&self, sp: Span, exprs: Vec>) -> P; - fn expr_vec_ng(&self, sp: Span) -> P; - fn expr_vec_slice(&self, sp: Span, exprs: Vec>) -> P; - fn expr_str(&self, sp: Span, s: Symbol) -> P; - - fn expr_some(&self, sp: Span, expr: P) -> P; - fn expr_none(&self, sp: Span) -> P; - - fn expr_break(&self, sp: Span) -> P; - - fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P; - - fn expr_fail(&self, span: Span, msg: Symbol) -> P; - fn expr_unreachable(&self, span: Span) -> P; - - fn expr_ok(&self, span: Span, expr: P) -> P; - fn expr_err(&self, span: Span, expr: P) -> P; - fn expr_try(&self, span: Span, head: P) -> P; - - fn pat(&self, span: Span, pat: PatKind) -> P; - fn pat_wild(&self, span: Span) -> P; - fn pat_lit(&self, span: Span, expr: P) -> P; - fn pat_ident(&self, span: Span, ident: ast::Ident) -> P; - - fn pat_ident_binding_mode(&self, - span: Span, - ident: ast::Ident, - bm: ast::BindingMode) -> P; - fn pat_path(&self, span: Span, path: ast::Path) -> P; - fn pat_tuple_struct(&self, span: Span, path: ast::Path, - subpats: Vec>) -> P; - fn pat_struct(&self, span: Span, path: ast::Path, - field_pats: Vec>) -> P; - fn pat_tuple(&self, span: Span, pats: Vec>) -> P; - - fn pat_some(&self, span: Span, pat: P) -> P; - fn pat_none(&self, span: Span) -> P; - - fn pat_ok(&self, span: Span, pat: P) -> P; - fn pat_err(&self, span: Span, pat: P) -> P; - - fn arm(&self, span: Span, pats: Vec>, expr: P) -> ast::Arm; - fn arm_unreachable(&self, span: Span) -> ast::Arm; - - fn expr_match(&self, span: Span, arg: P, arms: Vec ) -> P; - fn expr_if(&self, span: Span, - cond: P, then: P, els: Option>) -> P; - fn expr_loop(&self, span: Span, block: P) -> P; - - fn lambda_fn_decl(&self, - span: Span, - fn_decl: P, - body: P, - fn_decl_span: Span) - -> P; +// Left so that Cargo tests don't break, this can be removed once those no longer use it +pub trait AstBuilder {} - fn lambda(&self, span: Span, ids: Vec, body: P) -> P; - fn lambda0(&self, span: Span, body: P) -> P; - fn lambda1(&self, span: Span, body: P, ident: ast::Ident) -> P; - - fn lambda_stmts(&self, span: Span, ids: Vec, - blk: Vec) -> P; - fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P; - fn lambda_stmts_1(&self, span: Span, stmts: Vec, - ident: ast::Ident) -> P; - - // Items - fn item(&self, span: Span, - name: Ident, attrs: Vec , node: ast::ItemKind) -> P; - - fn arg(&self, span: Span, name: Ident, ty: P) -> ast::Arg; - // FIXME: unused `self` - fn fn_decl(&self, inputs: Vec , output: ast::FunctionRetTy) -> P; - - fn item_fn_poly(&self, - span: Span, - name: Ident, - inputs: Vec , - output: P, - generics: Generics, - body: P) -> P; - fn item_fn(&self, - span: Span, - name: Ident, - inputs: Vec , - output: P, - body: P) -> P; - - fn variant(&self, span: Span, name: Ident, tys: Vec> ) -> ast::Variant; - fn item_enum_poly(&self, - span: Span, - name: Ident, - enum_definition: ast::EnumDef, - generics: Generics) -> P; - fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> P; - - fn item_struct_poly(&self, - span: Span, - name: Ident, - struct_def: ast::VariantData, - generics: Generics) -> P; - fn item_struct(&self, span: Span, name: Ident, struct_def: ast::VariantData) -> P; - - fn item_mod(&self, span: Span, inner_span: Span, - name: Ident, attrs: Vec, - items: Vec>) -> P; - - fn item_extern_crate(&self, span: Span, name: Ident) -> P; - - fn item_static(&self, - span: Span, - name: Ident, - ty: P, - mutbl: ast::Mutability, - expr: P) - -> P; - - fn item_const(&self, - span: Span, - name: Ident, - ty: P, - expr: P) - -> P; - - fn item_ty_poly(&self, - span: Span, - name: Ident, - ty: P, - generics: Generics) -> P; - fn item_ty(&self, span: Span, name: Ident, ty: P) -> P; - - fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute; - - fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem; - - fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem; - - fn meta_list(&self, - sp: Span, - name: ast::Name, - mis: Vec ) - -> ast::MetaItem; - fn meta_name_value(&self, - sp: Span, - name: ast::Name, - value: ast::LitKind) - -> ast::MetaItem; - - fn item_use(&self, sp: Span, - vis: ast::Visibility, vp: P) -> P; - fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P; - fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, - ident: Option, path: ast::Path) -> P; - fn item_use_list(&self, sp: Span, vis: ast::Visibility, - path: Vec, imports: &[ast::Ident]) -> P; - fn item_use_glob(&self, sp: Span, - vis: ast::Visibility, path: Vec) -> P; -} - -impl<'a> AstBuilder for ExtCtxt<'a> { - fn path(&self, span: Span, strs: Vec ) -> ast::Path { +impl<'a> ExtCtxt<'a> { + pub fn path(&self, span: Span, strs: Vec ) -> ast::Path { self.path_all(span, false, strs, vec![], vec![]) } - fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path { + pub fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path { self.path(span, vec![id]) } - fn path_global(&self, span: Span, strs: Vec ) -> ast::Path { + pub fn path_global(&self, span: Span, strs: Vec ) -> ast::Path { self.path_all(span, true, strs, vec![], vec![]) } - fn path_all(&self, + pub fn path_all(&self, span: Span, global: bool, mut idents: Vec , @@ -330,7 +55,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { /// Constructs a qualified path. /// /// Constructs a path like `::ident`. - fn qpath(&self, + pub fn qpath(&self, self_type: P, trait_path: ast::Path, ident: ast::Ident) @@ -341,7 +66,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { /// Constructs a qualified path. /// /// Constructs a path like `::ident<'a, T, A = Bar>`. - fn qpath_all(&self, + pub fn qpath_all(&self, self_type: P, trait_path: ast::Path, ident: ast::Ident, @@ -363,14 +88,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }, path) } - fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy { + pub fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy { ast::MutTy { ty, mutbl, } } - fn ty(&self, span: Span, ty: ast::TyKind) -> P { + pub fn ty(&self, span: Span, ty: ast::TyKind) -> P { P(ast::Ty { id: ast::DUMMY_NODE_ID, span, @@ -378,18 +103,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn ty_path(&self, path: ast::Path) -> P { + pub fn ty_path(&self, path: ast::Path) -> P { self.ty(path.span, ast::TyKind::Path(None, path)) } // Might need to take bounds as an argument in the future, if you ever want // to generate a bounded existential trait type. - fn ty_ident(&self, span: Span, ident: ast::Ident) + pub fn ty_ident(&self, span: Span, ident: ast::Ident) -> P { self.ty_path(self.path_ident(span, ident)) } - fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst { + pub fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst { ast::AnonConst { id: ast::DUMMY_NODE_ID, value: P(ast::Expr { @@ -401,11 +126,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst { + pub fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst { self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident))) } - fn ty_rptr(&self, + pub fn ty_rptr(&self, span: Span, ty: P, lifetime: Option, @@ -415,7 +140,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::TyKind::Rptr(lifetime, self.ty_mt(ty, mutbl))) } - fn ty_ptr(&self, + pub fn ty_ptr(&self, span: Span, ty: P, mutbl: ast::Mutability) @@ -424,11 +149,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::TyKind::Ptr(self.ty_mt(ty, mutbl))) } - fn ty_infer(&self, span: Span) -> P { + pub fn ty_infer(&self, span: Span) -> P { self.ty(span, ast::TyKind::Infer) } - fn typaram(&self, + pub fn typaram(&self, span: Span, ident: ast::Ident, attrs: Vec, @@ -445,14 +170,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { + pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID, } } - fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { + pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_generic_params: Vec::new(), trait_ref: self.trait_ref(path), @@ -460,16 +185,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { + pub fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None) } - fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime { + pub fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime { ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) } } - fn lifetime_def(&self, + pub fn lifetime_def(&self, span: Span, ident: ast::Ident, attrs: Vec, @@ -485,7 +210,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_expr(&self, expr: P) -> ast::Stmt { + pub fn stmt_expr(&self, expr: P) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, @@ -493,7 +218,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_semi(&self, expr: P) -> ast::Stmt { + pub fn stmt_semi(&self, expr: P) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, @@ -501,7 +226,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, + pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt { let pat = if mutbl { let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mutable); @@ -524,7 +249,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_let_typed(&self, + pub fn stmt_let_typed(&self, sp: Span, mutbl: bool, ident: ast::Ident, @@ -553,7 +278,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // Generates `let _: Type;`, which is usually used for type assertions. - fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt { + pub fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt { let local = P(ast::Local { pat: self.pat_wild(span), ty: Some(ty), @@ -569,7 +294,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { + pub fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, node: ast::StmtKind::Item(item), @@ -577,14 +302,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn block_expr(&self, expr: P) -> P { + pub fn block_expr(&self, expr: P) -> P { self.block(expr.span, vec![ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, node: ast::StmtKind::Expr(expr), }]) } - fn block(&self, span: Span, stmts: Vec) -> P { + pub fn block(&self, span: Span, stmts: Vec) -> P { P(ast::Block { stmts, id: ast::DUMMY_NODE_ID, @@ -593,7 +318,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn expr(&self, span: Span, node: ast::ExprKind) -> P { + pub fn expr(&self, span: Span, node: ast::ExprKind) -> P { P(ast::Expr { id: ast::DUMMY_NODE_ID, node, @@ -602,61 +327,65 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn expr_path(&self, path: ast::Path) -> P { + pub fn expr_path(&self, path: ast::Path) -> P { self.expr(path.span, ast::ExprKind::Path(None, path)) } /// Constructs a `QPath` expression. - fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P { + pub fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P { self.expr(span, ast::ExprKind::Path(Some(qself), path)) } - fn expr_ident(&self, span: Span, id: ast::Ident) -> P { + pub fn expr_ident(&self, span: Span, id: ast::Ident) -> P { self.expr_path(self.path_ident(span, id)) } - fn expr_self(&self, span: Span) -> P { + pub fn expr_self(&self, span: Span) -> P { self.expr_ident(span, Ident::with_empty_ctxt(kw::SelfLower)) } - fn expr_binary(&self, sp: Span, op: ast::BinOpKind, + pub fn expr_binary(&self, sp: Span, op: ast::BinOpKind, lhs: P, rhs: P) -> P { self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs)) } - fn expr_deref(&self, sp: Span, e: P) -> P { + pub fn expr_deref(&self, sp: Span, e: P) -> P { self.expr_unary(sp, UnOp::Deref, e) } - fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P { + pub fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P { self.expr(sp, ast::ExprKind::Unary(op, e)) } - fn expr_field_access(&self, sp: Span, expr: P, ident: ast::Ident) -> P { + pub fn expr_field_access( + &self, sp: Span, expr: P, ident: ast::Ident, + ) -> P { self.expr(sp, ast::ExprKind::Field(expr, ident.with_span_pos(sp))) } - fn expr_tup_field_access(&self, sp: Span, expr: P, idx: usize) -> P { + pub fn expr_tup_field_access(&self, sp: Span, expr: P, idx: usize) -> P { let ident = Ident::from_str(&idx.to_string()).with_span_pos(sp); self.expr(sp, ast::ExprKind::Field(expr, ident)) } - fn expr_addr_of(&self, sp: Span, e: P) -> P { + pub fn expr_addr_of(&self, sp: Span, e: P) -> P { self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Immutable, e)) } - fn expr_mut_addr_of(&self, sp: Span, e: P) -> P { + pub fn expr_mut_addr_of(&self, sp: Span, e: P) -> P { self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Mutable, e)) } - fn expr_call(&self, span: Span, expr: P, args: Vec>) -> P { + pub fn expr_call( + &self, span: Span, expr: P, args: Vec>, + ) -> P { self.expr(span, ast::ExprKind::Call(expr, args)) } - fn expr_call_ident(&self, span: Span, id: ast::Ident, + pub fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec>) -> P { self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) } - fn expr_call_global(&self, sp: Span, fn_path: Vec , + pub fn expr_call_global(&self, sp: Span, fn_path: Vec , args: Vec> ) -> P { let pathexpr = self.expr_path(self.path_global(sp, fn_path)); self.expr_call(sp, pathexpr, args) } - fn expr_method_call(&self, span: Span, + pub fn expr_method_call(&self, span: Span, expr: P, ident: ast::Ident, mut args: Vec> ) -> P { @@ -664,10 +393,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let segment = ast::PathSegment::from_ident(ident.with_span_pos(span)); self.expr(span, ast::ExprKind::MethodCall(segment, args)) } - fn expr_block(&self, b: P) -> P { + pub fn expr_block(&self, b: P) -> P { self.expr(b.span, ast::ExprKind::Block(b, None)) } - fn field_imm(&self, span: Span, ident: Ident, e: P) -> ast::Field { + pub fn field_imm(&self, span: Span, ident: Ident, e: P) -> ast::Field { ast::Field { ident: ident.with_span_pos(span), expr: e, @@ -676,23 +405,25 @@ impl<'a> AstBuilder for ExtCtxt<'a> { attrs: ThinVec::new(), } } - fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec) -> P { + pub fn expr_struct( + &self, span: Span, path: ast::Path, fields: Vec + ) -> P { self.expr(span, ast::ExprKind::Struct(path, fields, None)) } - fn expr_struct_ident(&self, span: Span, + pub fn expr_struct_ident(&self, span: Span, id: ast::Ident, fields: Vec) -> P { self.expr_struct(span, self.path_ident(span, id), fields) } - fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { + pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { let lit = ast::Lit::from_lit_kind(lit_kind, span); self.expr(span, ast::ExprKind::Lit(lit)) } - fn expr_usize(&self, span: Span, i: usize) -> P { + pub fn expr_usize(&self, span: Span, i: usize) -> P { self.expr_lit(span, ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize))) } - fn expr_isize(&self, sp: Span, i: isize) -> P { + pub fn expr_isize(&self, sp: Span, i: isize) -> P { if i < 0 { let i = (-i) as u128; let lit_ty = ast::LitIntType::Signed(ast::IntTy::Isize); @@ -703,59 +434,59 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::LitIntType::Signed(ast::IntTy::Isize))) } } - fn expr_u32(&self, sp: Span, u: u32) -> P { + pub fn expr_u32(&self, sp: Span, u: u32) -> P { self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32))) } - fn expr_u16(&self, sp: Span, u: u16) -> P { + pub fn expr_u16(&self, sp: Span, u: u16) -> P { self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U16))) } - fn expr_u8(&self, sp: Span, u: u8) -> P { + pub fn expr_u8(&self, sp: Span, u: u8) -> P { self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U8))) } - fn expr_bool(&self, sp: Span, value: bool) -> P { + pub fn expr_bool(&self, sp: Span, value: bool) -> P { self.expr_lit(sp, ast::LitKind::Bool(value)) } - fn expr_vec(&self, sp: Span, exprs: Vec>) -> P { + pub fn expr_vec(&self, sp: Span, exprs: Vec>) -> P { self.expr(sp, ast::ExprKind::Array(exprs)) } - fn expr_vec_ng(&self, sp: Span) -> P { + pub fn expr_vec_ng(&self, sp: Span) -> P { self.expr_call_global(sp, self.std_path(&[sym::vec, sym::Vec, sym::new]), Vec::new()) } - fn expr_vec_slice(&self, sp: Span, exprs: Vec>) -> P { + pub fn expr_vec_slice(&self, sp: Span, exprs: Vec>) -> P { self.expr_addr_of(sp, self.expr_vec(sp, exprs)) } - fn expr_str(&self, sp: Span, s: Symbol) -> P { + pub fn expr_str(&self, sp: Span, s: Symbol) -> P { self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked)) } - fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P { + pub fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P { self.expr(sp, ast::ExprKind::Cast(expr, ty)) } - fn expr_some(&self, sp: Span, expr: P) -> P { + pub fn expr_some(&self, sp: Span, expr: P) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); self.expr_call_global(sp, some, vec![expr]) } - fn expr_none(&self, sp: Span) -> P { + pub fn expr_none(&self, sp: Span) -> P { let none = self.std_path(&[sym::option, sym::Option, sym::None]); let none = self.path_global(sp, none); self.expr_path(none) } - fn expr_break(&self, sp: Span) -> P { + pub fn expr_break(&self, sp: Span) -> P { self.expr(sp, ast::ExprKind::Break(None, None)) } - fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P { + pub fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P { self.expr(sp, ast::ExprKind::Tup(exprs)) } - fn expr_fail(&self, span: Span, msg: Symbol) -> P { + pub fn expr_fail(&self, span: Span, msg: Symbol) -> P { let loc = self.source_map().lookup_char_pos(span.lo()); let expr_file = self.expr_str(span, Symbol::intern(&loc.file.name.to_string())); let expr_line = self.expr_u32(span, loc.line as u32); @@ -764,27 +495,27 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let expr_loc_ptr = self.expr_addr_of(span, expr_loc_tuple); self.expr_call_global( span, - self.std_path(&[sym::rt, sym::begin_panic]), + [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), vec![ self.expr_str(span, msg), expr_loc_ptr]) } - fn expr_unreachable(&self, span: Span) -> P { + pub fn expr_unreachable(&self, span: Span) -> P { self.expr_fail(span, Symbol::intern("internal error: entered unreachable code")) } - fn expr_ok(&self, sp: Span, expr: P) -> P { + pub fn expr_ok(&self, sp: Span, expr: P) -> P { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); self.expr_call_global(sp, ok, vec![expr]) } - fn expr_err(&self, sp: Span, expr: P) -> P { + pub fn expr_err(&self, sp: Span, expr: P) -> P { let err = self.std_path(&[sym::result, sym::Result, sym::Err]); self.expr_call_global(sp, err, vec![expr]) } - fn expr_try(&self, sp: Span, head: P) -> P { + pub fn expr_try(&self, sp: Span, head: P) -> P { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); let ok_path = self.path_global(sp, ok); let err = self.std_path(&[sym::result, sym::Result, sym::Err]); @@ -814,67 +545,67 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } - fn pat(&self, span: Span, pat: PatKind) -> P { + pub fn pat(&self, span: Span, pat: PatKind) -> P { P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span }) } - fn pat_wild(&self, span: Span) -> P { + pub fn pat_wild(&self, span: Span) -> P { self.pat(span, PatKind::Wild) } - fn pat_lit(&self, span: Span, expr: P) -> P { + pub fn pat_lit(&self, span: Span, expr: P) -> P { self.pat(span, PatKind::Lit(expr)) } - fn pat_ident(&self, span: Span, ident: ast::Ident) -> P { + pub fn pat_ident(&self, span: Span, ident: ast::Ident) -> P { let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Immutable); self.pat_ident_binding_mode(span, ident, binding_mode) } - fn pat_ident_binding_mode(&self, + pub fn pat_ident_binding_mode(&self, span: Span, ident: ast::Ident, bm: ast::BindingMode) -> P { let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); self.pat(span, pat) } - fn pat_path(&self, span: Span, path: ast::Path) -> P { + pub fn pat_path(&self, span: Span, path: ast::Path) -> P { self.pat(span, PatKind::Path(None, path)) } - fn pat_tuple_struct(&self, span: Span, path: ast::Path, + pub fn pat_tuple_struct(&self, span: Span, path: ast::Path, subpats: Vec>) -> P { - self.pat(span, PatKind::TupleStruct(path, subpats, None)) + self.pat(span, PatKind::TupleStruct(path, subpats)) } - fn pat_struct(&self, span: Span, path: ast::Path, + pub fn pat_struct(&self, span: Span, path: ast::Path, field_pats: Vec>) -> P { self.pat(span, PatKind::Struct(path, field_pats, false)) } - fn pat_tuple(&self, span: Span, pats: Vec>) -> P { - self.pat(span, PatKind::Tuple(pats, None)) + pub fn pat_tuple(&self, span: Span, pats: Vec>) -> P { + self.pat(span, PatKind::Tuple(pats)) } - fn pat_some(&self, span: Span, pat: P) -> P { + pub fn pat_some(&self, span: Span, pat: P) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, vec![pat]) } - fn pat_none(&self, span: Span) -> P { + pub fn pat_none(&self, span: Span) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::None]); let path = self.path_global(span, some); self.pat_path(span, path) } - fn pat_ok(&self, span: Span, pat: P) -> P { + pub fn pat_ok(&self, span: Span, pat: P) -> P { let some = self.std_path(&[sym::result, sym::Result, sym::Ok]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, vec![pat]) } - fn pat_err(&self, span: Span, pat: P) -> P { + pub fn pat_err(&self, span: Span, pat: P) -> P { let some = self.std_path(&[sym::result, sym::Result, sym::Err]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, vec![pat]) } - fn arm(&self, span: Span, pats: Vec>, expr: P) -> ast::Arm { + pub fn arm(&self, span: Span, pats: Vec>, expr: P) -> ast::Arm { ast::Arm { attrs: vec![], pats, @@ -884,25 +615,25 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn arm_unreachable(&self, span: Span) -> ast::Arm { + pub fn arm_unreachable(&self, span: Span) -> ast::Arm { self.arm(span, vec![self.pat_wild(span)], self.expr_unreachable(span)) } - fn expr_match(&self, span: Span, arg: P, arms: Vec) -> P { + pub fn expr_match(&self, span: Span, arg: P, arms: Vec) -> P { self.expr(span, ast::ExprKind::Match(arg, arms)) } - fn expr_if(&self, span: Span, cond: P, + pub fn expr_if(&self, span: Span, cond: P, then: P, els: Option>) -> P { let els = els.map(|x| self.expr_block(self.block_expr(x))); self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els)) } - fn expr_loop(&self, span: Span, block: P) -> P { + pub fn expr_loop(&self, span: Span, block: P) -> P { self.expr(span, ast::ExprKind::Loop(block, None)) } - fn lambda_fn_decl(&self, + pub fn lambda_fn_decl(&self, span: Span, fn_decl: P, body: P, @@ -916,7 +647,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn_decl_span)) } - fn lambda(&self, + pub fn lambda(&self, span: Span, ids: Vec, body: P) @@ -937,41 +668,42 @@ impl<'a> AstBuilder for ExtCtxt<'a> { span)) } - fn lambda0(&self, span: Span, body: P) -> P { + pub fn lambda0(&self, span: Span, body: P) -> P { self.lambda(span, Vec::new(), body) } - fn lambda1(&self, span: Span, body: P, ident: ast::Ident) -> P { + pub fn lambda1(&self, span: Span, body: P, ident: ast::Ident) -> P { self.lambda(span, vec![ident], body) } - fn lambda_stmts(&self, + pub fn lambda_stmts(&self, span: Span, ids: Vec, stmts: Vec) -> P { self.lambda(span, ids, self.expr_block(self.block(span, stmts))) } - fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P { + pub fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P { self.lambda0(span, self.expr_block(self.block(span, stmts))) } - fn lambda_stmts_1(&self, span: Span, stmts: Vec, + pub fn lambda_stmts_1(&self, span: Span, stmts: Vec, ident: ast::Ident) -> P { self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) } - fn arg(&self, span: Span, ident: ast::Ident, ty: P) -> ast::Arg { + pub fn arg(&self, span: Span, ident: ast::Ident, ty: P) -> ast::Arg { let arg_pat = self.pat_ident(span, ident); ast::Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat: arg_pat, + span, ty, } } // FIXME: unused `self` - fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { + pub fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { P(ast::FnDecl { inputs, output, @@ -979,7 +711,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item(&self, span: Span, name: Ident, + pub fn item(&self, span: Span, name: Ident, attrs: Vec, node: ast::ItemKind) -> P { // FIXME: Would be nice if our generated code didn't violate // Rust coding conventions @@ -994,7 +726,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item_fn_poly(&self, + pub fn item_fn_poly(&self, span: Span, name: Ident, inputs: Vec , @@ -1015,7 +747,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { body)) } - fn item_fn(&self, + pub fn item_fn(&self, span: Span, name: Ident, inputs: Vec , @@ -1031,7 +763,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { body) } - fn variant(&self, span: Span, ident: Ident, tys: Vec> ) -> ast::Variant { + pub fn variant(&self, span: Span, ident: Ident, tys: Vec> ) -> ast::Variant { let fields: Vec<_> = tys.into_iter().map(|ty| { ast::StructField { span: ty.span, @@ -1059,19 +791,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item_enum_poly(&self, span: Span, name: Ident, + pub fn item_enum_poly(&self, span: Span, name: Ident, enum_definition: ast::EnumDef, generics: Generics) -> P { self.item(span, name, Vec::new(), ast::ItemKind::Enum(enum_definition, generics)) } - fn item_enum(&self, span: Span, name: Ident, + pub fn item_enum(&self, span: Span, name: Ident, enum_definition: ast::EnumDef) -> P { self.item_enum_poly(span, name, enum_definition, Generics::default()) } - fn item_struct(&self, span: Span, name: Ident, + pub fn item_struct(&self, span: Span, name: Ident, struct_def: ast::VariantData) -> P { self.item_struct_poly( span, @@ -1081,12 +813,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ) } - fn item_struct_poly(&self, span: Span, name: Ident, + pub fn item_struct_poly(&self, span: Span, name: Ident, struct_def: ast::VariantData, generics: Generics) -> P { self.item(span, name, Vec::new(), ast::ItemKind::Struct(struct_def, generics)) } - fn item_mod(&self, span: Span, inner_span: Span, name: Ident, + pub fn item_mod(&self, span: Span, inner_span: Span, name: Ident, attrs: Vec, items: Vec>) -> P { self.item( @@ -1101,11 +833,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ) } - fn item_extern_crate(&self, span: Span, name: Ident) -> P { + pub fn item_extern_crate(&self, span: Span, name: Ident) -> P { self.item(span, name, Vec::new(), ast::ItemKind::ExternCrate(None)) } - fn item_static(&self, + pub fn item_static(&self, span: Span, name: Ident, ty: P, @@ -1115,7 +847,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, expr)) } - fn item_const(&self, + pub fn item_const(&self, span: Span, name: Ident, ty: P, @@ -1124,39 +856,38 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr)) } - fn item_ty_poly(&self, span: Span, name: Ident, ty: P, + pub fn item_ty_poly(&self, span: Span, name: Ident, ty: P, generics: Generics) -> P { - self.item(span, name, Vec::new(), ast::ItemKind::Ty(ty, generics)) + self.item(span, name, Vec::new(), ast::ItemKind::TyAlias(ty, generics)) } - fn item_ty(&self, span: Span, name: Ident, ty: P) -> P { + pub fn item_ty(&self, span: Span, name: Ident, ty: P) -> P { self.item_ty_poly(span, name, ty, Generics::default()) } - fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute { - attr::mk_spanned_attr_outer(sp, attr::mk_attr_id(), mi) + pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { + attr::mk_attr_outer(mi) } - fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { - attr::mk_word_item(Ident::with_empty_ctxt(w).with_span_pos(sp)) + pub fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { + attr::mk_word_item(Ident::new(w, sp)) } - fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem { - attr::mk_nested_word_item(Ident::with_empty_ctxt(w).with_span_pos(sp)) + pub fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem { + attr::mk_nested_word_item(Ident::new(w, sp)) } - fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec) + pub fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec) -> ast::MetaItem { - attr::mk_list_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), mis) + attr::mk_list_item(Ident::new(name, sp), mis) } - fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind) + pub fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind) -> ast::MetaItem { - attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span), - lit_kind, span) + attr::mk_name_value_item(Ident::new(name, span), lit_kind, span) } - fn item_use(&self, sp: Span, + pub fn item_use(&self, sp: Span, vis: ast::Visibility, vp: P) -> P { P(ast::Item { id: ast::DUMMY_NODE_ID, @@ -1169,11 +900,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P { + pub fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P { self.item_use_simple_(sp, vis, None, path) } - fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, + pub fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, rename: Option, path: ast::Path) -> P { self.item_use(sp, vis, P(ast::UseTree { span: sp, @@ -1182,7 +913,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { })) } - fn item_use_list(&self, sp: Span, vis: ast::Visibility, + pub fn item_use_list(&self, sp: Span, vis: ast::Visibility, path: Vec, imports: &[ast::Ident]) -> P { let imports = imports.iter().map(|id| { (ast::UseTree { @@ -1199,7 +930,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { })) } - fn item_use_glob(&self, sp: Span, + pub fn item_use_glob(&self, sp: Span, vis: ast::Visibility, path: Vec) -> P { self.item_use(sp, vis, P(ast::UseTree { span: sp, diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs deleted file mode 100644 index 3b4243ed24..0000000000 --- a/src/libsyntax/ext/derive.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::attr::HasAttrs; -use crate::ast; -use crate::source_map::{ExpnInfo, ExpnFormat}; -use crate::ext::base::ExtCtxt; -use crate::ext::build::AstBuilder; -use crate::parse::parser::PathStyle; -use crate::symbol::{Symbol, sym}; -use crate::errors::Applicability; - -use syntax_pos::Span; - -use rustc_data_structures::fx::FxHashSet; - -pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec { - let mut result = Vec::new(); - attrs.retain(|attr| { - if attr.path != sym::derive { - return true; - } - if !attr.is_meta_item_list() { - cx.struct_span_err(attr.span, "malformed `derive` attribute input") - .span_suggestion( - attr.span, - "missing traits to be derived", - "#[derive(Trait1, Trait2, ...)]".to_owned(), - Applicability::HasPlaceholders, - ).emit(); - return false; - } - - match attr.parse_list(cx.parse_sess, - |parser| parser.parse_path_allowing_meta(PathStyle::Mod)) { - Ok(traits) => { - result.extend(traits); - true - } - Err(mut e) => { - e.emit(); - false - } - } - }); - result -} - -pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::Path], item: &mut T) - where T: HasAttrs, -{ - let (mut names, mut pretty_name) = (FxHashSet::default(), "derive(".to_owned()); - for (i, path) in traits.iter().enumerate() { - if i > 0 { - pretty_name.push_str(", "); - } - pretty_name.push_str(&path.to_string()); - names.insert(unwrap_or!(path.segments.get(0), continue).ident.name); - } - pretty_name.push(')'); - - cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable( - ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)), span, cx.parse_sess.edition, - &[sym::rustc_attrs, sym::structural_match], - )); - - let span = span.with_ctxt(cx.backtrace()); - item.visit_attrs(|attrs| { - if names.contains(&Symbol::intern("Eq")) && names.contains(&Symbol::intern("PartialEq")) { - let meta = cx.meta_word(span, Symbol::intern("structural_match")); - attrs.push(cx.attribute(span, meta)); - } - if names.contains(&Symbol::intern("Copy")) { - let meta = cx.meta_word(span, sym::rustc_copy_clone_marker); - attrs.push(cx.attribute(span, meta)); - } - }); -} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5473f55aa3..cf1ae3e316 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -4,8 +4,9 @@ use crate::attr::{self, HasAttrs}; use crate::source_map::{dummy_spanned, respan}; use crate::config::StripUnconfigured; use crate::ext::base::*; -use crate::ext::derive::{add_derived_markers, collect_derives}; -use crate::ext::hygiene::{Mark, SyntaxContext}; +use crate::ext::proc_macro::collect_derives; +use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind}; +use crate::ext::tt::macro_rules::annotate_err_with_kind; use crate::ext::placeholders::{placeholder, PlaceholderExpander}; use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; use crate::mut_visit::*; @@ -13,8 +14,7 @@ use crate::parse::{DirectoryOwnership, PResult, ParseSess}; use crate::parse::token; use crate::parse::parser::Parser; use crate::ptr::P; -use crate::symbol::Symbol; -use crate::symbol::{kw, sym}; +use crate::symbol::{sym, Symbol}; use crate::tokenstream::{TokenStream, TokenTree}; use crate::visit::{self, Visitor}; use crate::util::map_in_place::MapInPlace; @@ -159,8 +159,8 @@ ast_fragments! { } impl AstFragmentKind { - fn dummy(self, span: Span) -> Option { - self.make_from(DummyResult::any(span)) + fn dummy(self, span: Span) -> AstFragment { + self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment") } fn expect_from_annotatables>(self, items: I) @@ -197,13 +197,13 @@ pub struct Invocation { pub enum InvocationKind { Bang { mac: ast::Mac, - ident: Option, span: Span, }, Attr { - attr: Option, - traits: Vec, + attr: ast::Attribute, item: Annotatable, + // Required for resolving derive helper attributes. + derives: Vec, // We temporarily report errors for attribute macros placed after derives after_derive: bool, }, @@ -211,15 +211,22 @@ pub enum InvocationKind { path: Path, item: Annotatable, }, + /// "Invocation" that contains all derives from an item, + /// broken into multiple `Derive` invocations when expanded. + /// FIXME: Find a way to remove it. + DeriveContainer { + derives: Vec, + item: Annotatable, + }, } impl Invocation { pub fn span(&self) -> Span { - match self.kind { - InvocationKind::Bang { span, .. } => span, - InvocationKind::Attr { attr: Some(ref attr), .. } => attr.span, - InvocationKind::Attr { attr: None, .. } => DUMMY_SP, - InvocationKind::Derive { ref path, .. } => path.span, + match &self.kind { + InvocationKind::Bang { span, .. } => *span, + InvocationKind::Attr { attr, .. } => attr.span, + InvocationKind::Derive { path, .. } => path.span, + InvocationKind::DeriveContainer { item, .. } => item.span(), } } } @@ -245,7 +252,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { module.directory.pop(); self.cx.root_path = module.directory.clone(); self.cx.current_expansion.module = Rc::new(module); - self.cx.current_expansion.crate_span = Some(krate.span); let orig_mod_span = krate.module.inner; @@ -298,7 +304,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // Unresolved macros produce dummy outputs as a recovery measure. invocations.reverse(); let mut expanded_fragments = Vec::new(); - let mut derives: FxHashMap> = FxHashMap::default(); + let mut derives: FxHashMap> = FxHashMap::default(); let mut undetermined_invocations = Vec::new(); let (mut progress, mut force) = (false, !self.monotonic); loop { @@ -307,98 +313,79 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } else { self.resolve_imports(); if undetermined_invocations.is_empty() { break } - invocations = mem::replace(&mut undetermined_invocations, Vec::new()); + invocations = mem::take(&mut undetermined_invocations); force = !mem::replace(&mut progress, false); continue }; let scope = - if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark }; + if self.monotonic { invoc.expansion_data.id } else { orig_expansion_data.id }; let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) { - Ok(ext) => Some(ext), - Err(Determinacy::Determined) => None, - Err(Determinacy::Undetermined) => { + Ok(ext) => ext, + Err(Indeterminate) => { undetermined_invocations.push(invoc); continue } }; progress = true; - let ExpansionData { depth, mark, .. } = invoc.expansion_data; + let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data; self.cx.current_expansion = invoc.expansion_data.clone(); - self.cx.current_expansion.mark = scope; // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { - if let Some(ext) = ext { - let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span()); - let fragment = self.expand_invoc(invoc, &*ext).unwrap_or_else(|| { - invoc_fragment_kind.dummy(invoc_span).unwrap() - }); - self.collect_invocations(fragment, &[]) - } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { - if !item.derive_allowed() { - let attr = attr::find_by_name(item.attrs(), sym::derive) - .expect("`derive` attribute should exist"); - let span = attr.span; - let mut err = self.cx.mut_span_err(span, - "`derive` may only be applied to \ - structs, enums and unions"); - if let ast::AttrStyle::Inner = attr.style { - let trait_list = traits.iter() - .map(|t| t.to_string()).collect::>(); - let suggestion = format!("#[derive({})]", trait_list.join(", ")); - err.span_suggestion( - span, "try an outer attribute", suggestion, - // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT - Applicability::MaybeIncorrect - ); - } - err.emit(); + let fragment = self.expand_invoc(invoc, &ext.kind); + self.collect_invocations(fragment, &[]) + } else if let InvocationKind::DeriveContainer { derives: traits, item } = invoc.kind { + if !item.derive_allowed() { + let attr = attr::find_by_name(item.attrs(), sym::derive) + .expect("`derive` attribute should exist"); + let span = attr.span; + let mut err = self.cx.mut_span_err(span, + "`derive` may only be applied to \ + structs, enums and unions"); + if let ast::AttrStyle::Inner = attr.style { + let trait_list = traits.iter() + .map(|t| t.to_string()).collect::>(); + let suggestion = format!("#[derive({})]", trait_list.join(", ")); + err.span_suggestion( + span, "try an outer attribute", suggestion, + // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT + Applicability::MaybeIncorrect + ); } + err.emit(); + } - let mut item = self.fully_configure(item); - item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive)); - let mut item_with_markers = item.clone(); - add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers); - let derives = derives.entry(invoc.expansion_data.mark).or_default(); - - derives.reserve(traits.len()); - invocations.reserve(traits.len()); - for path in &traits { - let mark = Mark::fresh(self.cx.current_expansion.mark); - derives.push(mark); - let item = match self.cx.resolver.resolve_macro_path( - path, MacroKind::Derive, Mark::root(), Vec::new(), false) { - Ok(ext) => match ext.kind { - SyntaxExtensionKind::LegacyDerive(..) => item_with_markers.clone(), - _ => item.clone(), - }, - _ => item.clone(), - }; - invocations.push(Invocation { - kind: InvocationKind::Derive { path: path.clone(), item }, - fragment_kind: invoc.fragment_kind, - expansion_data: ExpansionData { - mark, - ..invoc.expansion_data.clone() - }, - }); - } - let fragment = invoc.fragment_kind - .expect_from_annotatables(::std::iter::once(item_with_markers)); - self.collect_invocations(fragment, derives) - } else { - unreachable!() + let mut item = self.fully_configure(item); + item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive)); + let derives = derives.entry(invoc.expansion_data.id).or_default(); + + derives.reserve(traits.len()); + invocations.reserve(traits.len()); + for path in traits { + let expn_id = ExpnId::fresh(self.cx.current_expansion.id, None); + derives.push(expn_id); + invocations.push(Invocation { + kind: InvocationKind::Derive { path, item: item.clone() }, + fragment_kind: invoc.fragment_kind, + expansion_data: ExpansionData { + id: expn_id, + ..invoc.expansion_data.clone() + }, + }); } + let fragment = invoc.fragment_kind + .expect_from_annotatables(::std::iter::once(item)); + self.collect_invocations(fragment, derives) } else { - self.collect_invocations(invoc.fragment_kind.dummy(invoc.span()).unwrap(), &[]) + unreachable!() }; if expanded_fragments.len() < depth { expanded_fragments.push(Vec::new()); } - expanded_fragments[depth - 1].push((mark, expanded_fragment)); + expanded_fragments[depth - 1].push((expn_id, expanded_fragment)); if !self.cx.ecfg.single_step { invocations.extend(new_invocations.into_iter().rev()); } @@ -411,7 +398,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { while let Some(expanded_fragments) = expanded_fragments.pop() { for (mark, expanded_fragment) in expanded_fragments.into_iter().rev() { let derives = derives.remove(&mark).unwrap_or_else(Vec::new); - placeholder_expander.add(NodeId::placeholder_from_mark(mark), + placeholder_expander.add(NodeId::placeholder_from_expn_id(mark), expanded_fragment, derives); } } @@ -429,10 +416,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s. /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and /// prepares data for resolving paths of macro invocations. - fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[Mark]) + fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[ExpnId]) -> (AstFragment, Vec) { // Resolve `$crate`s in the fragment for pretty-printing. - self.cx.resolver.resolve_dollar_crates(&fragment); + self.cx.resolver.resolve_dollar_crates(); let invocations = { let mut collector = InvocationCollector { @@ -450,7 +437,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if self.monotonic { self.cx.resolver.visit_ast_fragment_with_placeholders( - self.cx.current_expansion.mark, &fragment, derives); + self.cx.current_expansion.id, &fragment, derives); } (fragment, invocations) @@ -488,28 +475,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option { - if invoc.fragment_kind == AstFragmentKind::ForeignItems && - !self.cx.ecfg.macros_in_extern_enabled() { - if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else { + fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtensionKind) -> AstFragment { + let (fragment_kind, span) = (invoc.fragment_kind, invoc.span()); + if fragment_kind == AstFragmentKind::ForeignItems && !self.cx.ecfg.macros_in_extern() { + if let SyntaxExtensionKind::NonMacroAttr { .. } = ext {} else { emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern, - invoc.span(), GateIssue::Language, + span, GateIssue::Language, "macro invocations in `extern {}` blocks are experimental"); } } - let result = match invoc.kind { - InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext)?, - InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext)?, - InvocationKind::Derive { .. } => self.expand_derive_invoc(invoc, ext)?, - }; - if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit { - let info = self.cx.current_expansion.mark.expn_info().unwrap(); + let info = self.cx.current_expansion.id.expn_info().unwrap(); let suggested_limit = self.cx.ecfg.recursion_limit * 2; let mut err = self.cx.struct_span_err(info.call_site, &format!("recursion limit reached while expanding the macro `{}`", - info.format.name())); + info.kind.descr())); err.help(&format!( "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", suggested_limit)); @@ -518,61 +499,88 @@ impl<'a, 'b> MacroExpander<'a, 'b> { FatalError.raise(); } - Some(result) - } - - fn expand_attr_invoc(&mut self, - invoc: Invocation, - ext: &SyntaxExtension) - -> Option { - let (attr, mut item) = match invoc.kind { - InvocationKind::Attr { attr, item, .. } => (attr?, item), - _ => unreachable!(), - }; - - match &ext.kind { - SyntaxExtensionKind::NonMacroAttr { mark_used } => { - attr::mark_known(&attr); - if *mark_used { - attr::mark_used(&attr); + match invoc.kind { + InvocationKind::Bang { mac, .. } => match ext { + SyntaxExtensionKind::Bang(expander) => { + self.gate_proc_macro_expansion_kind(span, fragment_kind); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + let result = + self.parse_ast_fragment(tok_result, fragment_kind, &mac.node.path, span); + self.gate_proc_macro_expansion(span, &result); + result } - item.visit_attrs(|attrs| attrs.push(attr)); - Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) - } - SyntaxExtensionKind::LegacyAttr(expander) => { - let meta = attr.parse_meta(self.cx.parse_sess) - .map_err(|mut e| { e.emit(); }).ok()?; - let item = expander.expand(self.cx, attr.span, &meta, item); - Some(invoc.fragment_kind.expect_from_annotatables(item)) - } - SyntaxExtensionKind::Attr(expander) => { - self.gate_proc_macro_attr_item(attr.span, &item); - let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { - Annotatable::Item(item) => token::NtItem(item), - Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()), - Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()), - Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()), - Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), - Annotatable::Expr(expr) => token::NtExpr(expr), - })), DUMMY_SP).into(); - let input = self.extract_proc_macro_attr_input(attr.tokens, attr.span); - let tok_result = expander.expand(self.cx, attr.span, input, item_tok); - let res = self.parse_ast_fragment(tok_result, invoc.fragment_kind, - &attr.path, attr.span); - self.gate_proc_macro_expansion(attr.span, &res); - res + SyntaxExtensionKind::LegacyBang(expander) => { + let prev = self.cx.current_expansion.prior_type_ascription; + self.cx.current_expansion.prior_type_ascription = + mac.node.prior_type_ascription; + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + let result = if let Some(result) = fragment_kind.make_from(tok_result) { + result + } else { + let msg = format!("non-{kind} macro in {kind} position: {path}", + kind = fragment_kind.name(), path = mac.node.path); + self.cx.span_err(span, &msg); + self.cx.trace_macros_diag(); + fragment_kind.dummy(span) + }; + self.cx.current_expansion.prior_type_ascription = prev; + result + } + _ => unreachable!() } - SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => { - self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path)); - self.cx.trace_macros_diag(); - invoc.fragment_kind.dummy(attr.span) + InvocationKind::Attr { attr, mut item, .. } => match ext { + SyntaxExtensionKind::Attr(expander) => { + self.gate_proc_macro_attr_item(span, &item); + let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { + Annotatable::Item(item) => token::NtItem(item), + Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()), + Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()), + Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()), + Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), + Annotatable::Expr(expr) => token::NtExpr(expr), + })), DUMMY_SP).into(); + let input = self.extract_proc_macro_attr_input(attr.tokens, span); + let tok_result = expander.expand(self.cx, span, input, item_tok); + let res = self.parse_ast_fragment(tok_result, fragment_kind, &attr.path, span); + self.gate_proc_macro_expansion(span, &res); + res + } + SyntaxExtensionKind::LegacyAttr(expander) => { + match attr.parse_meta(self.cx.parse_sess) { + Ok(meta) => { + let item = expander.expand(self.cx, span, &meta, item); + fragment_kind.expect_from_annotatables(item) + } + Err(mut err) => { + err.emit(); + fragment_kind.dummy(span) + } + } + } + SyntaxExtensionKind::NonMacroAttr { mark_used } => { + attr::mark_known(&attr); + if *mark_used { + attr::mark_used(&attr); + } + item.visit_attrs(|attrs| attrs.push(attr)); + fragment_kind.expect_from_annotatables(iter::once(item)) + } + _ => unreachable!() } - _ => { - let msg = &format!("macro `{}` may not be used in attributes", attr.path); - self.cx.span_err(attr.span, msg); - self.cx.trace_macros_diag(); - invoc.fragment_kind.dummy(attr.span) + InvocationKind::Derive { path, item } => match ext { + SyntaxExtensionKind::Derive(expander) | + SyntaxExtensionKind::LegacyDerive(expander) => { + if !item.derive_allowed() { + return fragment_kind.dummy(span); + } + let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path }; + let span = span.with_ctxt(self.cx.backtrace()); + let items = expander.expand(self.cx, span, &meta, item); + fragment_kind.expect_from_annotatables(items) + } + _ => unreachable!() } + InvocationKind::DeriveContainer { .. } => unreachable!() } } @@ -588,7 +596,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { None => return TokenStream::empty(), } self.cx.span_err(span, "custom attribute invocations must be \ - of the form #[foo] or #[foo(..)], the macro name must only be \ + of the form `#[foo]` or `#[foo(..)]`, the macro name must only be \ followed by a delimiter token"); TokenStream::empty() } @@ -619,14 +627,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ); } - fn gate_proc_macro_expansion(&self, span: Span, fragment: &Option) { + fn gate_proc_macro_expansion(&self, span: Span, fragment: &AstFragment) { if self.cx.ecfg.proc_macro_hygiene() { return } - let fragment = match fragment { - Some(fragment) => fragment, - None => return, - }; fragment.visit_with(&mut DisallowMacros { span, @@ -658,104 +662,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - /// Expand a macro invocation. Returns the resulting expanded AST fragment. - fn expand_bang_invoc(&mut self, - invoc: Invocation, - ext: &SyntaxExtension) - -> Option { - let kind = invoc.fragment_kind; - let (mac, ident, span) = match invoc.kind { - InvocationKind::Bang { mac, ident, span } => (mac, ident, span), - _ => unreachable!(), - }; - let path = &mac.node.path; - - let ident = ident.unwrap_or_else(|| Ident::invalid()); - let validate = |this: &mut Self| { - // feature-gate the macro invocation - if let Some((feature, issue)) = ext.unstable_feature { - let crate_span = this.cx.current_expansion.crate_span.unwrap(); - // don't stability-check macros in the same crate - // (the only time this is null is for syntax extensions registered as macros) - if ext.def_info.map_or(false, |(_, def_span)| !crate_span.contains(def_span)) - && !span.allows_unstable(feature) - && this.cx.ecfg.features.map_or(true, |feats| { - // macro features will count as lib features - !feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature) - }) { - let explain = format!("macro {}! is unstable", path); - emit_feature_err(this.cx.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &explain); - this.cx.trace_macros_diag(); - } - } - - if ident.name != kw::Invalid { - let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); - this.cx.span_err(path.span, &msg); - this.cx.trace_macros_diag(); - return Err(kind.dummy(span)); - } - Ok(()) - }; - - let opt_expanded = match &ext.kind { - SyntaxExtensionKind::LegacyBang(expander) => { - if let Err(dummy_span) = validate(self) { - dummy_span - } else { - kind.make_from(expander.expand( - self.cx, - span, - mac.node.stream(), - ext.def_info.map(|(_, s)| s), - )) - } - } - - SyntaxExtensionKind::Attr(..) | - SyntaxExtensionKind::LegacyAttr(..) | - SyntaxExtensionKind::NonMacroAttr { .. } => { - self.cx.span_err(path.span, - &format!("`{}` can only be used in attributes", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } - - SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => { - self.cx.span_err(path.span, &format!("`{}` is a derive macro", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } - - SyntaxExtensionKind::Bang(expander) => { - if ident.name != kw::Invalid { - let msg = - format!("macro {}! expects no ident argument, given '{}'", path, ident); - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) - } else { - self.gate_proc_macro_expansion_kind(span, kind); - let tok_result = expander.expand(self.cx, span, mac.node.stream()); - let result = self.parse_ast_fragment(tok_result, kind, path, span); - self.gate_proc_macro_expansion(span, &result); - result - } - } - }; - - if opt_expanded.is_some() { - opt_expanded - } else { - let msg = format!("non-{kind} macro in {kind} position: {name}", - name = path.segments[0].ident.name, kind = kind.name()); - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) - } - } - fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) { let kind = match kind { AstFragmentKind::Expr => "expressions", @@ -780,50 +686,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ); } - /// Expand a derive invocation. Returns the resulting expanded AST fragment. - fn expand_derive_invoc(&mut self, - invoc: Invocation, - ext: &SyntaxExtension) - -> Option { - let (path, item) = match invoc.kind { - InvocationKind::Derive { path, item } => (path, item), - _ => unreachable!(), - }; - if !item.derive_allowed() { - return None; - } - - match &ext.kind { - SyntaxExtensionKind::Derive(expander) | - SyntaxExtensionKind::LegacyDerive(expander) => { - let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span: path.span, path }; - let span = meta.span.with_ctxt(self.cx.backtrace()); - let items = expander.expand(self.cx, span, &meta, item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) - } - _ => { - let msg = &format!("macro `{}` may not be used for derive attributes", path); - self.cx.span_err(path.span, msg); - self.cx.trace_macros_diag(); - invoc.fragment_kind.dummy(path.span) - } - } - } - - fn parse_ast_fragment(&mut self, - toks: TokenStream, - kind: AstFragmentKind, - path: &Path, - span: Span) - -> Option { + fn parse_ast_fragment( + &mut self, + toks: TokenStream, + kind: AstFragmentKind, + path: &Path, + span: Span, + ) -> AstFragment { let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::>()); match parser.parse_ast_fragment(kind, false) { Ok(fragment) => { parser.ensure_complete_parse(path, kind.name(), span); - Some(fragment) + fragment } Err(mut err) => { err.set_span(span); + annotate_err_with_kind(&mut err, kind, span); err.emit(); self.cx.trace_macros_diag(); kind.dummy(span) @@ -860,7 +738,7 @@ impl<'a> Parser<'a> { AstFragmentKind::ForeignItems => { let mut items = SmallVec::new(); while self.token != token::Eof { - items.push(self.parse_foreign_item()?); + items.push(self.parse_foreign_item(DUMMY_SP)?); } AstFragment::ForeignItems(items) } @@ -930,31 +808,44 @@ struct InvocationCollector<'a, 'b> { impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { - let mark = Mark::fresh(self.cx.current_expansion.mark); + // Expansion info for all the collected invocations is set upon their resolution, + // with exception of the derive container case which is not resolved and can get + // its expansion info immediately. + let expn_info = match &kind { + InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default( + ExpnKind::Macro(MacroKind::Attr, sym::derive), + item.span(), self.cx.parse_sess.edition, + )), + _ => None, + }; + let expn_id = ExpnId::fresh(self.cx.current_expansion.id, expn_info); self.invocations.push(Invocation { kind, fragment_kind, expansion_data: ExpansionData { - mark, + id: expn_id, depth: self.cx.current_expansion.depth + 1, ..self.cx.current_expansion.clone() }, }); - placeholder(fragment_kind, NodeId::placeholder_from_mark(mark)) + placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id)) } fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment { - self.collect(kind, InvocationKind::Bang { mac, ident: None, span }) + self.collect(kind, InvocationKind::Bang { mac, span }) } fn collect_attr(&mut self, attr: Option, - traits: Vec, + derives: Vec, item: Annotatable, kind: AstFragmentKind, after_derive: bool) -> AstFragment { - self.collect(kind, InvocationKind::Attr { attr, traits, item, after_derive }) + self.collect(kind, match attr { + Some(attr) => InvocationKind::Attr { attr, item, derives, after_derive }, + None => InvocationKind::DeriveContainer { derives, item }, + }) } fn find_attr_invoc(&self, attrs: &mut Vec, after_derive: &mut bool) @@ -968,7 +859,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { }) .map(|i| attrs.remove(i)); if let Some(attr) = &attr { - if !self.cx.ecfg.enable_custom_inner_attributes() && + if !self.cx.ecfg.custom_inner_attributes() && attr.style == ast::AttrStyle::Inner && attr.path != sym::test { emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes, attr.span, GateIssue::Language, @@ -1179,13 +1070,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ast::ItemKind::Mac(..) => { self.check_attributes(&item.attrs); item.and_then(|item| match item.node { - ItemKind::Mac(mac) => { - self.collect(AstFragmentKind::Items, InvocationKind::Bang { - mac, - ident: Some(item.ident), - span: item.span, - }).make_items() - } + ItemKind::Mac(mac) => self.collect( + AstFragmentKind::Items, InvocationKind::Bang { mac, span: item.span } + ).make_items(), _ => unreachable!(), }) } @@ -1362,7 +1249,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { return noop_visit_attribute(at, self); } - let filename = self.cx.root_path.join(file.to_string()); + let filename = self.cx.resolve_path(&*file.as_str(), it.span()); match fs::read_to_string(&filename) { Ok(src) => { let src_interned = Symbol::intern(&src); @@ -1387,7 +1274,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ]; let include_ident = Ident::with_empty_ctxt(sym::include); - let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info); + let item = attr::mk_list_item(include_ident, include_info); items.push(ast::NestedMetaItem::MetaItem(item)); } Err(e) => { @@ -1411,10 +1298,6 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ); err.span_label(lit.span, "couldn't read file"); - if e.kind() == ErrorKind::NotFound { - err.help("external doc paths are relative to the crate root"); - } - err.emit(); } } @@ -1452,11 +1335,15 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } - let meta = attr::mk_list_item(DUMMY_SP, Ident::with_empty_ctxt(sym::doc), items); - match at.style { - ast::AttrStyle::Inner => *at = attr::mk_spanned_attr_inner(at.span, at.id, meta), - ast::AttrStyle::Outer => *at = attr::mk_spanned_attr_outer(at.span, at.id, meta), - } + let meta = attr::mk_list_item(Ident::with_empty_ctxt(sym::doc), items); + *at = attr::Attribute { + span: at.span, + id: at.id, + style: at.style, + path: meta.path, + tokens: meta.node.tokens(meta.span), + is_sugared_doc: false, + }; } else { noop_visit_attribute(at, self) } @@ -1485,19 +1372,6 @@ pub struct ExpansionConfig<'feat> { pub keep_macs: bool, } -macro_rules! feature_tests { - ($( fn $getter:ident = $field:ident, )*) => { - $( - pub fn $getter(&self) -> bool { - match self.features { - Some(&Features { $field: true, .. }) => true, - _ => false, - } - } - )* - } -} - impl<'feat> ExpansionConfig<'feat> { pub fn default(crate_name: String) -> ExpansionConfig<'static> { ExpansionConfig { @@ -1511,29 +1385,20 @@ impl<'feat> ExpansionConfig<'feat> { } } - feature_tests! { - fn enable_asm = asm, - fn enable_custom_test_frameworks = custom_test_frameworks, - fn enable_global_asm = global_asm, - fn enable_log_syntax = log_syntax, - fn enable_concat_idents = concat_idents, - fn enable_trace_macros = trace_macros, - fn enable_allow_internal_unstable = allow_internal_unstable, - fn enable_format_args_nl = format_args_nl, - fn macros_in_extern_enabled = macros_in_extern, - fn proc_macro_hygiene = proc_macro_hygiene, + fn macros_in_extern(&self) -> bool { + self.features.map_or(false, |features| features.macros_in_extern) } - - fn enable_custom_inner_attributes(&self) -> bool { - self.features.map_or(false, |features| { - features.custom_inner_attributes || features.custom_attribute || features.rustc_attrs - }) + fn proc_macro_hygiene(&self) -> bool { + self.features.map_or(false, |features| features.proc_macro_hygiene) + } + fn custom_inner_attributes(&self) -> bool { + self.features.map_or(false, |features| features.custom_inner_attributes) } } // A Marker adds the given mark to the syntax context. #[derive(Debug)] -pub struct Marker(pub Mark); +pub struct Marker(pub ExpnId); impl MutVisitor for Marker { fn visit_span(&mut self, span: &mut Span) { diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index b2b8bfb09b..b2b17b0fb2 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -2,7 +2,7 @@ use crate::ast::{self, NodeId}; use crate::source_map::{DUMMY_SP, dummy_spanned}; use crate::ext::base::ExtCtxt; use crate::ext::expand::{AstFragment, AstFragmentKind}; -use crate::ext::hygiene::Mark; +use crate::ext::hygiene::ExpnId; use crate::tokenstream::TokenStream; use crate::mut_visit::*; use crate::ptr::P; @@ -18,6 +18,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { path: ast::Path { span: DUMMY_SP, segments: Vec::new() }, tts: TokenStream::empty().into(), delim: ast::MacDelimiter::Brace, + prior_type_ascription: None, }) } @@ -84,11 +85,11 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> { } } - pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, derives: Vec) { + pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, derives: Vec) { fragment.mut_visit_with(self); if let AstFragment::Items(mut items) = fragment { for derive in derives { - match self.remove(NodeId::placeholder_from_mark(derive)) { + match self.remove(NodeId::placeholder_from_expn_id(derive)) { AstFragment::Items(derived_items) => items.extend(derived_items), _ => unreachable!(), } diff --git a/src/libsyntax/ext/proc_macro.rs b/src/libsyntax/ext/proc_macro.rs new file mode 100644 index 0000000000..c17b6f6b42 --- /dev/null +++ b/src/libsyntax/ext/proc_macro.rs @@ -0,0 +1,217 @@ +use crate::ast::{self, ItemKind, Attribute, Mac}; +use crate::attr::{mark_used, mark_known}; +use crate::errors::{Applicability, FatalError}; +use crate::ext::base::{self, *}; +use crate::ext::proc_macro_server; +use crate::parse::{self, token}; +use crate::parse::parser::PathStyle; +use crate::symbol::sym; +use crate::tokenstream::{self, TokenStream}; +use crate::visit::Visitor; + +use rustc_data_structures::sync::Lrc; +use syntax_pos::{Span, DUMMY_SP}; + +const EXEC_STRATEGY: proc_macro::bridge::server::SameThread = + proc_macro::bridge::server::SameThread; + +pub struct BangProcMacro { + pub client: proc_macro::bridge::client::Client< + fn(proc_macro::TokenStream) -> proc_macro::TokenStream, + >, +} + +impl base::ProcMacro for BangProcMacro { + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt<'_>, + span: Span, + input: TokenStream) + -> TokenStream { + let server = proc_macro_server::Rustc::new(ecx); + match self.client.run(&EXEC_STRATEGY, server, input) { + Ok(stream) => stream, + Err(e) => { + let msg = "proc macro panicked"; + let mut err = ecx.struct_span_fatal(span, msg); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); + } + + err.emit(); + FatalError.raise(); + } + } + } +} + +pub struct AttrProcMacro { + pub client: proc_macro::bridge::client::Client< + fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream, + >, +} + +impl base::AttrProcMacro for AttrProcMacro { + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt<'_>, + span: Span, + annotation: TokenStream, + annotated: TokenStream) + -> TokenStream { + let server = proc_macro_server::Rustc::new(ecx); + match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) { + Ok(stream) => stream, + Err(e) => { + let msg = "custom attribute panicked"; + let mut err = ecx.struct_span_fatal(span, msg); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); + } + + err.emit(); + FatalError.raise(); + } + } + } +} + +pub struct ProcMacroDerive { + pub client: proc_macro::bridge::client::Client< + fn(proc_macro::TokenStream) -> proc_macro::TokenStream, + >, + pub attrs: Vec, +} + +impl MultiItemModifier for ProcMacroDerive { + fn expand(&self, + ecx: &mut ExtCtxt<'_>, + span: Span, + _meta_item: &ast::MetaItem, + item: Annotatable) + -> Vec { + let item = match item { + Annotatable::Item(item) => item, + Annotatable::ImplItem(_) | + Annotatable::TraitItem(_) | + Annotatable::ForeignItem(_) | + Annotatable::Stmt(_) | + Annotatable::Expr(_) => { + ecx.span_err(span, "proc-macro derives may only be \ + applied to a struct, enum, or union"); + return Vec::new() + } + }; + match item.node { + ItemKind::Struct(..) | + ItemKind::Enum(..) | + ItemKind::Union(..) => {}, + _ => { + ecx.span_err(span, "proc-macro derives may only be \ + applied to a struct, enum, or union"); + return Vec::new() + } + } + + // Mark attributes as known, and used. + MarkAttrs(&self.attrs).visit_item(&item); + + let token = token::Interpolated(Lrc::new(token::NtItem(item))); + let input = tokenstream::TokenTree::token(token, DUMMY_SP).into(); + + let server = proc_macro_server::Rustc::new(ecx); + let stream = match self.client.run(&EXEC_STRATEGY, server, input) { + Ok(stream) => stream, + Err(e) => { + let msg = "proc-macro derive panicked"; + let mut err = ecx.struct_span_fatal(span, msg); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); + } + + err.emit(); + FatalError.raise(); + } + }; + + let error_count_before = ecx.parse_sess.span_diagnostic.err_count(); + let msg = "proc-macro derive produced unparseable tokens"; + + let mut parser = parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive")); + let mut items = vec![]; + + loop { + match parser.parse_item() { + Ok(None) => break, + Ok(Some(item)) => { + items.push(Annotatable::Item(item)) + } + Err(mut err) => { + // FIXME: handle this better + err.cancel(); + ecx.struct_span_fatal(span, msg).emit(); + FatalError.raise(); + } + } + } + + + // fail if there have been errors emitted + if ecx.parse_sess.span_diagnostic.err_count() > error_count_before { + ecx.struct_span_fatal(span, msg).emit(); + FatalError.raise(); + } + + items + } +} + +struct MarkAttrs<'a>(&'a [ast::Name]); + +impl<'a> Visitor<'a> for MarkAttrs<'a> { + fn visit_attribute(&mut self, attr: &Attribute) { + if let Some(ident) = attr.ident() { + if self.0.contains(&ident.name) { + mark_used(attr); + mark_known(attr); + } + } + } + + fn visit_mac(&mut self, _mac: &Mac) {} +} + +pub fn is_proc_macro_attr(attr: &Attribute) -> bool { + [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] + .iter().any(|kind| attr.check_name(*kind)) +} + +crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec { + let mut result = Vec::new(); + attrs.retain(|attr| { + if attr.path != sym::derive { + return true; + } + if !attr.is_meta_item_list() { + cx.struct_span_err(attr.span, "malformed `derive` attribute input") + .span_suggestion( + attr.span, + "missing traits to be derived", + "#[derive(Trait1, Trait2, ...)]".to_owned(), + Applicability::HasPlaceholders, + ).emit(); + return false; + } + + match attr.parse_list(cx.parse_sess, + |parser| parser.parse_path_allowing_meta(PathStyle::Mod)) { + Ok(traits) => { + result.extend(traits); + true + } + Err(mut e) => { + e.emit(); + false + } + } + }); + result +} diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs similarity index 97% rename from src/libsyntax_ext/proc_macro_server.rs rename to src/libsyntax/ext/proc_macro_server.rs index c9d99e5831..36621ce777 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -1,21 +1,19 @@ -use errors::{Diagnostic, DiagnosticBuilder}; - -use std::panic; - -use proc_macro::bridge::{server, TokenTree}; -use proc_macro::{Delimiter, Level, LineColumn, Spacing}; +use crate::ast; +use crate::ext::base::ExtCtxt; +use crate::parse::{self, token, ParseSess}; +use crate::parse::lexer::comments; +use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; +use errors::{Diagnostic, DiagnosticBuilder}; use rustc_data_structures::sync::Lrc; -use std::ascii; -use std::ops::Bound; -use syntax::ast; -use syntax::ext::base::ExtCtxt; -use syntax::parse::lexer::comments; -use syntax::parse::{self, token, ParseSess}; -use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; +use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; use syntax_pos::hygiene::{SyntaxContext, Transparency}; use syntax_pos::symbol::{kw, sym, Symbol}; -use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; + +use proc_macro::{Delimiter, Level, LineColumn, Spacing}; +use proc_macro::bridge::{server, TokenTree}; +use std::{ascii, panic}; +use std::ops::Bound; trait FromInternal { fn from_internal(x: T) -> Self; @@ -52,7 +50,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec)> { fn from_internal(((tree, is_joint), sess, stack): (TreeAndJoint, &ParseSess, &mut Vec)) -> Self { - use syntax::parse::token::*; + use crate::parse::token::*; let joint = is_joint == Joint; let Token { kind, span } = match tree { @@ -186,14 +184,14 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec)> } OpenDelim(..) | CloseDelim(..) => unreachable!(), - Whitespace | Comment | Shebang(..) | Eof => unreachable!(), + Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => unreachable!(), } } } impl ToInternal for TokenTree { fn to_internal(self) -> TokenStream { - use syntax::parse::token::*; + use crate::parse::token::*; let (ch, joint, span) = match self { TokenTree::Punct(Punct { ch, joint, span }) => (ch, joint, span), @@ -364,11 +362,11 @@ pub(crate) struct Rustc<'a> { impl<'a> Rustc<'a> { pub fn new(cx: &'a ExtCtxt<'_>) -> Self { // No way to determine def location for a proc macro right now, so use call location. - let location = cx.current_expansion.mark.expn_info().unwrap().call_site; + let location = cx.current_expansion.id.expn_info().unwrap().call_site; let to_span = |transparency| { location.with_ctxt( SyntaxContext::empty() - .apply_mark_with_transparency(cx.current_expansion.mark, transparency), + .apply_mark_with_transparency(cx.current_expansion.id, transparency), ) }; Rustc { @@ -548,10 +546,10 @@ impl server::Literal for Rustc<'_> { self.lit(token::Float, Symbol::intern(n), None) } fn f32(&mut self, n: &str) -> Self::Literal { - self.lit(token::Float, Symbol::intern(n), Some(Symbol::intern("f32"))) + self.lit(token::Float, Symbol::intern(n), Some(sym::f32)) } fn f64(&mut self, n: &str) -> Self::Literal { - self.lit(token::Float, Symbol::intern(n), Some(Symbol::intern("f64"))) + self.lit(token::Float, Symbol::intern(n), Some(sym::f64)) } fn string(&mut self, string: &str) -> Self::Literal { let mut escaped = String::new(); diff --git a/src/libsyntax/ext/tt/macro_check.rs b/src/libsyntax/ext/tt/macro_check.rs new file mode 100644 index 0000000000..5af9719990 --- /dev/null +++ b/src/libsyntax/ext/tt/macro_check.rs @@ -0,0 +1,626 @@ +//! Checks that meta-variables in macro definition are correctly declared and used. +//! +//! # What is checked +//! +//! ## Meta-variables must not be bound twice +//! +//! ``` +//! macro_rules! foo { ($x:tt $x:tt) => { $x }; } +//! ``` +//! +//! This check is sound (no false-negative) and complete (no false-positive). +//! +//! ## Meta-variables must not be free +//! +//! ``` +//! macro_rules! foo { () => { $x }; } +//! ``` +//! +//! This check is also done at macro instantiation but only if the branch is taken. +//! +//! ## Meta-variables must repeat at least as many times as their binder +//! +//! ``` +//! macro_rules! foo { ($($x:tt)*) => { $x }; } +//! ``` +//! +//! This check is also done at macro instantiation but only if the branch is taken. +//! +//! ## Meta-variables must repeat with the same Kleene operators as their binder +//! +//! ``` +//! macro_rules! foo { ($($x:tt)+) => { $($x)* }; } +//! ``` +//! +//! This check is not done at macro instantiation. +//! +//! # Disclaimer +//! +//! In the presence of nested macros (a macro defined in a macro), those checks may have false +//! positives and false negatives. We try to detect those cases by recognizing potential macro +//! definitions in RHSes, but nested macros may be hidden through the use of particular values of +//! meta-variables. +//! +//! ## Examples of false positive +//! +//! False positives can come from cases where we don't recognize a nested macro, because it depends +//! on particular values of meta-variables. In the following example, we think both instances of +//! `$x` are free, which is a correct statement if `$name` is anything but `macro_rules`. But when +//! `$name` is `macro_rules`, like in the instantiation below, then `$x:tt` is actually a binder of +//! the nested macro and `$x` is bound to it. +//! +//! ``` +//! macro_rules! foo { ($name:ident) => { $name! bar { ($x:tt) => { $x }; } }; } +//! foo!(macro_rules); +//! ``` +//! +//! False positives can also come from cases where we think there is a nested macro while there +//! isn't. In the following example, we think `$x` is free, which is incorrect because `bar` is not +//! a nested macro since it is not evaluated as code by `stringify!`. +//! +//! ``` +//! macro_rules! foo { () => { stringify!(macro_rules! bar { () => { $x }; }) }; } +//! ``` +//! +//! ## Examples of false negative +//! +//! False negatives can come from cases where we don't recognize a meta-variable, because it depends +//! on particular values of meta-variables. In the following examples, we don't see that if `$d` is +//! instantiated with `$` then `$d z` becomes `$z` in the nested macro definition and is thus a free +//! meta-variable. Note however, that if `foo` is instantiated, then we would check the definition +//! of `bar` and would see the issue. +//! +//! ``` +//! macro_rules! foo { ($d:tt) => { macro_rules! bar { ($y:tt) => { $d z }; } }; } +//! ``` +//! +//! # How it is checked +//! +//! There are 3 main functions: `check_binders`, `check_occurrences`, and `check_nested_macro`. They +//! all need some kind of environment. +//! +//! ## Environments +//! +//! Environments are used to pass information. +//! +//! ### From LHS to RHS +//! +//! When checking a LHS with `check_binders`, we produce (and use) an environment for binders, +//! namely `Binders`. This is a mapping from binder name to information about that binder: the span +//! of the binder for error messages and the stack of Kleene operators under which it was bound in +//! the LHS. +//! +//! This environment is used by both the LHS and RHS. The LHS uses it to detect duplicate binders. +//! The RHS uses it to detect the other errors. +//! +//! ### From outer macro to inner macro +//! +//! When checking the RHS of an outer macro and we detect a nested macro definition, we push the +//! current state, namely `MacroState`, to an environment of nested macro definitions. Each state +//! stores the LHS binders when entering the macro definition as well as the stack of Kleene +//! operators under which the inner macro is defined in the RHS. +//! +//! This environment is a stack representing the nesting of macro definitions. As such, the stack of +//! Kleene operators under which a meta-variable is repeating is the concatenation of the stacks +//! stored when entering a macro definition starting from the state in which the meta-variable is +//! bound. +use crate::ast::NodeId; +use crate::early_buffered_lints::BufferedEarlyLintId; +use crate::ext::tt::quoted::{KleeneToken, TokenTree}; +use crate::parse::token::TokenKind; +use crate::parse::token::{DelimToken, Token}; +use crate::parse::ParseSess; +use crate::symbol::{kw, sym}; + +use rustc_data_structures::fx::FxHashMap; +use smallvec::SmallVec; +use syntax_pos::{symbol::Ident, MultiSpan, Span}; + +/// Stack represented as linked list. +/// +/// Those are used for environments because they grow incrementally and are not mutable. +enum Stack<'a, T> { + /// Empty stack. + Empty, + /// A non-empty stack. + Push { + /// The top element. + top: T, + /// The previous elements. + prev: &'a Stack<'a, T>, + }, +} + +impl<'a, T> Stack<'a, T> { + /// Returns whether a stack is empty. + fn is_empty(&self) -> bool { + match *self { + Stack::Empty => true, + _ => false, + } + } + + /// Returns a new stack with an element of top. + fn push(&'a self, top: T) -> Stack<'a, T> { + Stack::Push { top, prev: self } + } +} + +impl<'a, T> Iterator for &'a Stack<'a, T> { + type Item = &'a T; + + // Iterates from top to bottom of the stack. + fn next(&mut self) -> Option<&'a T> { + match *self { + Stack::Empty => None, + Stack::Push { ref top, ref prev } => { + *self = prev; + Some(top) + } + } + } +} + +impl From<&Stack<'_, KleeneToken>> for SmallVec<[KleeneToken; 1]> { + fn from(ops: &Stack<'_, KleeneToken>) -> SmallVec<[KleeneToken; 1]> { + let mut ops: SmallVec<[KleeneToken; 1]> = ops.cloned().collect(); + // The stack is innermost on top. We want outermost first. + ops.reverse(); + ops + } +} + +/// Information attached to a meta-variable binder in LHS. +struct BinderInfo { + /// The span of the meta-variable in LHS. + span: Span, + /// The stack of Kleene operators (outermost first). + ops: SmallVec<[KleeneToken; 1]>, +} + +/// An environment of meta-variables to their binder information. +type Binders = FxHashMap; + +/// The state at which we entered a macro definition in the RHS of another macro definition. +struct MacroState<'a> { + /// The binders of the branch where we entered the macro definition. + binders: &'a Binders, + /// The stack of Kleene operators (outermost first) where we entered the macro definition. + ops: SmallVec<[KleeneToken; 1]>, +} + +/// Checks that meta-variables are used correctly in a macro definition. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `span` is used when no spans are available +/// - `lhses` and `rhses` should have the same length and represent the macro definition +pub fn check_meta_variables( + sess: &ParseSess, + node_id: NodeId, + span: Span, + lhses: &[TokenTree], + rhses: &[TokenTree], +) -> bool { + if lhses.len() != rhses.len() { + sess.span_diagnostic.span_bug(span, "length mismatch between LHSes and RHSes") + } + let mut valid = true; + for (lhs, rhs) in lhses.iter().zip(rhses.iter()) { + let mut binders = Binders::default(); + check_binders(sess, node_id, lhs, &Stack::Empty, &mut binders, &Stack::Empty, &mut valid); + check_occurrences(sess, node_id, rhs, &Stack::Empty, &binders, &Stack::Empty, &mut valid); + } + valid +} + +/// Checks `lhs` as part of the LHS of a macro definition, extends `binders` with new binders, and +/// sets `valid` to false in case of errors. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `lhs` is checked as part of a LHS +/// - `macros` is the stack of possible outer macros +/// - `binders` contains the binders of the LHS +/// - `ops` is the stack of Kleene operators from the LHS +/// - `valid` is set in case of errors +fn check_binders( + sess: &ParseSess, + node_id: NodeId, + lhs: &TokenTree, + macros: &Stack<'_, MacroState<'_>>, + binders: &mut Binders, + ops: &Stack<'_, KleeneToken>, + valid: &mut bool, +) { + match *lhs { + TokenTree::Token(..) => {} + // This can only happen when checking a nested macro because this LHS is then in the RHS of + // the outer macro. See ui/macros/macro-of-higher-order.rs where $y:$fragment in the + // LHS of the nested macro (and RHS of the outer macro) is parsed as MetaVar(y) Colon + // MetaVar(fragment) and not as MetaVarDecl(y, fragment). + TokenTree::MetaVar(span, name) => { + if macros.is_empty() { + sess.span_diagnostic.span_bug(span, "unexpected MetaVar in lhs"); + } + // There are 3 possibilities: + if let Some(prev_info) = binders.get(&name) { + // 1. The meta-variable is already bound in the current LHS: This is an error. + let mut span = MultiSpan::from_span(span); + span.push_span_label(prev_info.span, "previous declaration".into()); + buffer_lint(sess, span, node_id, "duplicate matcher binding"); + } else if get_binder_info(macros, binders, name).is_none() { + // 2. The meta-variable is free: This is a binder. + binders.insert(name, BinderInfo { span, ops: ops.into() }); + } else { + // 3. The meta-variable is bound: This is an occurrence. + check_occurrences(sess, node_id, lhs, macros, binders, ops, valid); + } + } + // Similarly, this can only happen when checking a toplevel macro. + TokenTree::MetaVarDecl(span, name, _kind) => { + if !macros.is_empty() { + sess.span_diagnostic.span_bug(span, "unexpected MetaVarDecl in nested lhs"); + } + if let Some(prev_info) = get_binder_info(macros, binders, name) { + // Duplicate binders at the top-level macro definition are errors. The lint is only + // for nested macro definitions. + sess.span_diagnostic + .struct_span_err(span, "duplicate matcher binding") + .span_note(prev_info.span, "previous declaration was here") + .emit(); + *valid = false; + } else { + binders.insert(name, BinderInfo { span, ops: ops.into() }); + } + } + TokenTree::Delimited(_, ref del) => { + for tt in &del.tts { + check_binders(sess, node_id, tt, macros, binders, ops, valid); + } + } + TokenTree::Sequence(_, ref seq) => { + let ops = ops.push(seq.kleene); + for tt in &seq.tts { + check_binders(sess, node_id, tt, macros, binders, &ops, valid); + } + } + } +} + +/// Returns the binder information of a meta-variable. +/// +/// Arguments: +/// - `macros` is the stack of possible outer macros +/// - `binders` contains the current binders +/// - `name` is the name of the meta-variable we are looking for +fn get_binder_info<'a>( + mut macros: &'a Stack<'a, MacroState<'a>>, + binders: &'a Binders, + name: Ident, +) -> Option<&'a BinderInfo> { + binders.get(&name).or_else(|| macros.find_map(|state| state.binders.get(&name))) +} + +/// Checks `rhs` as part of the RHS of a macro definition and sets `valid` to false in case of +/// errors. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `rhs` is checked as part of a RHS +/// - `macros` is the stack of possible outer macros +/// - `binders` contains the binders of the associated LHS +/// - `ops` is the stack of Kleene operators from the RHS +/// - `valid` is set in case of errors +fn check_occurrences( + sess: &ParseSess, + node_id: NodeId, + rhs: &TokenTree, + macros: &Stack<'_, MacroState<'_>>, + binders: &Binders, + ops: &Stack<'_, KleeneToken>, + valid: &mut bool, +) { + match *rhs { + TokenTree::Token(..) => {} + TokenTree::MetaVarDecl(span, _name, _kind) => { + sess.span_diagnostic.span_bug(span, "unexpected MetaVarDecl in rhs") + } + TokenTree::MetaVar(span, name) => { + check_ops_is_prefix(sess, node_id, macros, binders, ops, span, name); + } + TokenTree::Delimited(_, ref del) => { + check_nested_occurrences(sess, node_id, &del.tts, macros, binders, ops, valid); + } + TokenTree::Sequence(_, ref seq) => { + let ops = ops.push(seq.kleene); + check_nested_occurrences(sess, node_id, &seq.tts, macros, binders, &ops, valid); + } + } +} + +/// Represents the processed prefix of a nested macro. +#[derive(Clone, Copy, PartialEq, Eq)] +enum NestedMacroState { + /// Nothing that matches a nested macro definition was processed yet. + Empty, + /// The token `macro_rules` was processed. + MacroRules, + /// The tokens `macro_rules!` were processed. + MacroRulesNot, + /// The tokens `macro_rules!` followed by a name were processed. The name may be either directly + /// an identifier or a meta-variable (that hopefully would be instantiated by an identifier). + MacroRulesNotName, + /// The keyword `macro` was processed. + Macro, + /// The keyword `macro` followed by a name was processed. + MacroName, + /// The keyword `macro` followed by a name and a token delimited by parentheses was processed. + MacroNameParen, +} + +/// Checks `tts` as part of the RHS of a macro definition, tries to recognize nested macro +/// definitions, and sets `valid` to false in case of errors. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `tts` is checked as part of a RHS and may contain macro definitions +/// - `macros` is the stack of possible outer macros +/// - `binders` contains the binders of the associated LHS +/// - `ops` is the stack of Kleene operators from the RHS +/// - `valid` is set in case of errors +fn check_nested_occurrences( + sess: &ParseSess, + node_id: NodeId, + tts: &[TokenTree], + macros: &Stack<'_, MacroState<'_>>, + binders: &Binders, + ops: &Stack<'_, KleeneToken>, + valid: &mut bool, +) { + let mut state = NestedMacroState::Empty; + let nested_macros = macros.push(MacroState { binders, ops: ops.into() }); + let mut nested_binders = Binders::default(); + for tt in tts { + match (state, tt) { + ( + NestedMacroState::Empty, + &TokenTree::Token(Token { kind: TokenKind::Ident(name, false), .. }), + ) => { + if name == sym::macro_rules { + state = NestedMacroState::MacroRules; + } else if name == kw::Macro { + state = NestedMacroState::Macro; + } + } + ( + NestedMacroState::MacroRules, + &TokenTree::Token(Token { kind: TokenKind::Not, .. }), + ) => { + state = NestedMacroState::MacroRulesNot; + } + ( + NestedMacroState::MacroRulesNot, + &TokenTree::Token(Token { kind: TokenKind::Ident(..), .. }), + ) => { + state = NestedMacroState::MacroRulesNotName; + } + (NestedMacroState::MacroRulesNot, &TokenTree::MetaVar(..)) => { + state = NestedMacroState::MacroRulesNotName; + // We check that the meta-variable is correctly used. + check_occurrences(sess, node_id, tt, macros, binders, ops, valid); + } + (NestedMacroState::MacroRulesNotName, &TokenTree::Delimited(_, ref del)) + | (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) + if del.delim == DelimToken::Brace => + { + let legacy = state == NestedMacroState::MacroRulesNotName; + state = NestedMacroState::Empty; + let rest = + check_nested_macro(sess, node_id, legacy, &del.tts, &nested_macros, valid); + // If we did not check the whole macro definition, then check the rest as if outside + // the macro definition. + check_nested_occurrences( + sess, + node_id, + &del.tts[rest..], + macros, + binders, + ops, + valid, + ); + } + ( + NestedMacroState::Macro, + &TokenTree::Token(Token { kind: TokenKind::Ident(..), .. }), + ) => { + state = NestedMacroState::MacroName; + } + (NestedMacroState::Macro, &TokenTree::MetaVar(..)) => { + state = NestedMacroState::MacroName; + // We check that the meta-variable is correctly used. + check_occurrences(sess, node_id, tt, macros, binders, ops, valid); + } + (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) + if del.delim == DelimToken::Paren => + { + state = NestedMacroState::MacroNameParen; + nested_binders = Binders::default(); + check_binders( + sess, + node_id, + tt, + &nested_macros, + &mut nested_binders, + &Stack::Empty, + valid, + ); + } + (NestedMacroState::MacroNameParen, &TokenTree::Delimited(_, ref del)) + if del.delim == DelimToken::Brace => + { + state = NestedMacroState::Empty; + check_occurrences( + sess, + node_id, + tt, + &nested_macros, + &nested_binders, + &Stack::Empty, + valid, + ); + } + (_, ref tt) => { + state = NestedMacroState::Empty; + check_occurrences(sess, node_id, tt, macros, binders, ops, valid); + } + } + } +} + +/// Checks the body of nested macro, returns where the check stopped, and sets `valid` to false in +/// case of errors. +/// +/// The token trees are checked as long as they look like a list of (LHS) => {RHS} token trees. This +/// check is a best-effort to detect a macro definition. It returns the position in `tts` where we +/// stopped checking because we detected we were not in a macro definition anymore. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `legacy` specifies whether the macro is legacy +/// - `tts` is checked as a list of (LHS) => {RHS} +/// - `macros` is the stack of outer macros +/// - `valid` is set in case of errors +fn check_nested_macro( + sess: &ParseSess, + node_id: NodeId, + legacy: bool, + tts: &[TokenTree], + macros: &Stack<'_, MacroState<'_>>, + valid: &mut bool, +) -> usize { + let n = tts.len(); + let mut i = 0; + let separator = if legacy { TokenKind::Semi } else { TokenKind::Comma }; + loop { + // We expect 3 token trees: `(LHS) => {RHS}`. The separator is checked after. + if i + 2 >= n + || !tts[i].is_delimited() + || !tts[i + 1].is_token(&TokenKind::FatArrow) + || !tts[i + 2].is_delimited() + { + break; + } + let lhs = &tts[i]; + let rhs = &tts[i + 2]; + let mut binders = Binders::default(); + check_binders(sess, node_id, lhs, macros, &mut binders, &Stack::Empty, valid); + check_occurrences(sess, node_id, rhs, macros, &binders, &Stack::Empty, valid); + // Since the last semicolon is optional for legacy macros and decl_macro are not terminated, + // we increment our checked position by how many token trees we already checked (the 3 + // above) before checking for the separator. + i += 3; + if i == n || !tts[i].is_token(&separator) { + break; + } + // We increment our checked position for the semicolon. + i += 1; + } + i +} + +/// Checks that a meta-variable occurrence is valid. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `macros` is the stack of possible outer macros +/// - `binders` contains the binders of the associated LHS +/// - `ops` is the stack of Kleene operators from the RHS +/// - `span` is the span of the meta-variable to check +/// - `name` is the name of the meta-variable to check +fn check_ops_is_prefix( + sess: &ParseSess, + node_id: NodeId, + macros: &Stack<'_, MacroState<'_>>, + binders: &Binders, + ops: &Stack<'_, KleeneToken>, + span: Span, + name: Ident, +) { + let macros = macros.push(MacroState { binders, ops: ops.into() }); + // Accumulates the stacks the operators of each state until (and including when) the + // meta-variable is found. The innermost stack is first. + let mut acc: SmallVec<[&SmallVec<[KleeneToken; 1]>; 1]> = SmallVec::new(); + for state in ¯os { + acc.push(&state.ops); + if let Some(binder) = state.binders.get(&name) { + // This variable concatenates the stack of operators from the RHS of the LHS where the + // meta-variable was defined to where it is used (in possibly nested macros). The + // outermost operator is first. + let mut occurrence_ops: SmallVec<[KleeneToken; 2]> = SmallVec::new(); + // We need to iterate from the end to start with outermost stack. + for ops in acc.iter().rev() { + occurrence_ops.extend_from_slice(ops); + } + ops_is_prefix(sess, node_id, span, name, &binder.ops, &occurrence_ops); + return; + } + } + buffer_lint(sess, span.into(), node_id, &format!("unknown macro variable `{}`", name)); +} + +/// Returns whether `binder_ops` is a prefix of `occurrence_ops`. +/// +/// The stack of Kleene operators of a meta-variable occurrence just needs to have the stack of +/// Kleene operators of its binder as a prefix. +/// +/// Consider $i in the following example: +/// +/// ( $( $i:ident = $($j:ident),+ );* ) => { $($( $i += $j; )+)* } +/// +/// It occurs under the Kleene stack ["*", "+"] and is bound under ["*"] only. +/// +/// Arguments: +/// - `sess` is used to emit diagnostics and lints +/// - `node_id` is used to emit lints +/// - `span` is the span of the meta-variable being check +/// - `name` is the name of the meta-variable being check +/// - `binder_ops` is the stack of Kleene operators for the binder +/// - `occurrence_ops` is the stack of Kleene operators for the occurrence +fn ops_is_prefix( + sess: &ParseSess, + node_id: NodeId, + span: Span, + name: Ident, + binder_ops: &[KleeneToken], + occurrence_ops: &[KleeneToken], +) { + for (i, binder) in binder_ops.iter().enumerate() { + if i >= occurrence_ops.len() { + let mut span = MultiSpan::from_span(span); + span.push_span_label(binder.span, "expected repetition".into()); + let message = &format!("variable '{}' is still repeating at this depth", name); + buffer_lint(sess, span, node_id, message); + return; + } + let occurrence = &occurrence_ops[i]; + if occurrence.op != binder.op { + let mut span = MultiSpan::from_span(span); + span.push_span_label(binder.span, "expected repetition".into()); + span.push_span_label(occurrence.span, "conflicting repetition".into()); + let message = "meta-variable repeats with different Kleene operator"; + buffer_lint(sess, span, node_id, message); + return; + } + } +} + +fn buffer_lint(sess: &ParseSess, span: MultiSpan, node_id: NodeId, message: &str) { + sess.buffer_lint(BufferedEarlyLintId::MetaVariableMisuse, span, node_id, message); +} diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 92ce3779a3..dbf14daa30 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -92,7 +92,6 @@ use rustc_data_structures::sync::Lrc; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::mem; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; // To avoid costly uniqueness checks, we require that `MatchSeq` always has a nonempty body. @@ -280,7 +279,7 @@ pub enum ParseResult { /// A `ParseResult` where the `Success` variant contains a mapping of `Ident`s to `NamedMatch`es. /// This represents the mapping of metavars to the token trees they bind to. -pub type NamedParseResult = ParseResult>>; +pub type NamedParseResult = ParseResult>; /// Count how many metavars are named in the given matcher `ms`. pub fn count_names(ms: &[TokenTree]) -> usize { @@ -373,7 +372,7 @@ fn nameize>( sess: &ParseSess, m: &TokenTree, res: &mut I, - ret_val: &mut FxHashMap>, + ret_val: &mut FxHashMap, ) -> Result<(), (syntax_pos::Span, String)> { match *m { TokenTree::Sequence(_, ref seq) => for next_m in &seq.tts { @@ -390,8 +389,7 @@ fn nameize>( TokenTree::MetaVarDecl(sp, bind_name, _) => { match ret_val.entry(bind_name) { Vacant(spot) => { - // FIXME(simulacrum): Don't construct Rc here - spot.insert(Rc::new(res.next().unwrap())); + spot.insert(res.next().unwrap()); } Occupied(..) => { return Err((sp, format!("duplicated bind name: {}", bind_name))) @@ -557,8 +555,8 @@ fn inner_parse_loop<'root, 'tt>( // implicitly disallowing OneOrMore from having 0 matches here. Thus, that will // result in a "no rules expected token" error by virtue of this matcher not // working. - if seq.op == quoted::KleeneOp::ZeroOrMore - || seq.op == quoted::KleeneOp::ZeroOrOne + if seq.kleene.op == quoted::KleeneOp::ZeroOrMore + || seq.kleene.op == quoted::KleeneOp::ZeroOrOne { let mut new_item = item.clone(); new_item.match_cur += seq.num_captures; @@ -573,7 +571,7 @@ fn inner_parse_loop<'root, 'tt>( cur_items.push(MatcherPosHandle::Box(Box::new(MatcherPos { stack: smallvec![], sep: seq.separator.clone(), - seq_op: Some(seq.op), + seq_op: Some(seq.kleene.op), idx: 0, matches, match_lo: item.match_cur, @@ -901,7 +899,7 @@ fn may_begin_with(token: &Token, name: Name) -> bool { /// # Returns /// /// The parsed non-terminal. -fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> Nonterminal { +fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal { if name == sym::tt { return token::NtTT(p.parse_token_tree()); } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 1a448cb2a4..b057a9ad44 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -2,7 +2,7 @@ use crate::edition::Edition; use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::ext::expand::{AstFragment, AstFragmentKind}; -use crate::ext::hygiene::Transparency; +use crate::ext::tt::macro_check; use crate::ext::tt::macro_parser::{parse, parse_failure_msg}; use crate::ext::tt::macro_parser::{Error, Failure, Success}; use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq}; @@ -15,11 +15,11 @@ use crate::parse::token::{self, NtTT, Token}; use crate::parse::{Directory, ParseSess}; use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; -use crate::{ast, attr}; +use crate::{ast, attr, attr::TransparencyError}; -use errors::FatalError; +use errors::{DiagnosticBuilder, FatalError}; use log::debug; -use syntax_pos::{symbol::Ident, Span}; +use syntax_pos::Span; use rustc_data_structures::fx::FxHashMap; use std::borrow::Cow; @@ -43,6 +43,18 @@ pub struct ParserAnyMacro<'a> { arm_span: Span, } +pub fn annotate_err_with_kind(err: &mut DiagnosticBuilder<'_>, kind: AstFragmentKind, span: Span) { + match kind { + AstFragmentKind::Ty => { + err.span_label(span, "this macro call doesn't expand to a type"); + } + AstFragmentKind::Pat => { + err.span_label(span, "this macro call doesn't expand to a pattern"); + } + _ => {} + }; +} + impl<'a> ParserAnyMacro<'a> { pub fn make(mut self: Box>, kind: AstFragmentKind) -> AstFragment { let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self; @@ -70,6 +82,32 @@ impl<'a> ParserAnyMacro<'a> { } else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() { e.span_label(site_span, "in this macro invocation"); } + match kind { + AstFragmentKind::Pat if macro_ident.name == sym::vec => { + let mut suggestion = None; + if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) { + if let Some(bang) = code.find('!') { + suggestion = Some(code[bang + 1..].to_string()); + } + } + if let Some(suggestion) = suggestion { + e.span_suggestion( + site_span, + "use a slice pattern here instead", + suggestion, + Applicability::MachineApplicable, + ); + } else { + e.span_label( + site_span, + "use a slice pattern here instead", + ); + } + e.help("for more information, see https://doc.rust-lang.org/edition-guide/\ + rust-2018/slice-patterns.html"); + } + _ => annotate_err_with_kind(&mut e, kind, site_span), + }; e })); @@ -89,6 +127,7 @@ impl<'a> ParserAnyMacro<'a> { struct MacroRulesMacroExpander { name: ast::Ident, + span: Span, lhses: Vec, rhses: Vec, valid: bool, @@ -100,12 +139,11 @@ impl TTMacroExpander for MacroRulesMacroExpander { cx: &'cx mut ExtCtxt<'_>, sp: Span, input: TokenStream, - def_span: Option, ) -> Box { if !self.valid { return DummyResult::any(sp); } - generic_extension(cx, sp, def_span, self.name, input, &self.lhses, &self.rhses) + generic_extension(cx, sp, self.span, self.name, input, &self.lhses, &self.rhses) } } @@ -118,7 +156,7 @@ fn trace_macros_note(cx: &mut ExtCtxt<'_>, sp: Span, message: String) { fn generic_extension<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, - def_span: Option, + def_span: Span, name: ast::Ident, arg: TokenStream, lhses: &[quoted::TokenTree], @@ -173,6 +211,7 @@ fn generic_extension<'cx>( let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None); p.root_module_name = cx.current_expansion.module.mod_path.last().map(|id| id.as_str().to_string()); + p.last_type_ascription = cx.current_expansion.prior_type_ascription; p.process_potential_macro_variable(); // Let the context choose how to interpret the result. @@ -200,10 +239,8 @@ fn generic_extension<'cx>( let span = token.span.substitute_dummy(sp); let mut err = cx.struct_span_err(span, &parse_failure_msg(&token)); err.span_label(span, label); - if let Some(sp) = def_span { - if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() { - err.span_label(cx.source_map().def_span(sp), "when calling this macro"); - } + if !def_span.is_dummy() && cx.source_map().span_to_filename(def_span).is_real() { + err.span_label(cx.source_map().def_span(def_span), "when calling this macro"); } // Check whether there's a missing comma in this macro call, like `println!("{}" a);` @@ -276,7 +313,7 @@ pub fn compile( if body.legacy { token::Semi } else { token::Comma }, def.span, )), - op: quoted::KleeneOp::OneOrMore, + kleene: quoted::KleeneToken::new(quoted::KleeneOp::OneOrMore, def.span), num_captures: 2, }), ), @@ -284,9 +321,12 @@ pub fn compile( quoted::TokenTree::Sequence( DelimSpan::dummy(), Lrc::new(quoted::SequenceRepetition { - tts: vec![quoted::TokenTree::token(token::Semi, def.span)], + tts: vec![quoted::TokenTree::token( + if body.legacy { token::Semi } else { token::Comma }, + def.span, + )], separator: None, - op: quoted::KleeneOp::ZeroOrMore, + kleene: quoted::KleeneToken::new(quoted::KleeneOp::ZeroOrMore, def.span), num_captures: 0, }), ), @@ -310,7 +350,7 @@ pub fn compile( let mut valid = true; // Extract the arguments: - let lhses = match *argument_map[&lhs_nm] { + let lhses = match argument_map[&lhs_nm] { MatchedSeq(ref s, _) => s .iter() .map(|m| { @@ -337,7 +377,7 @@ pub fn compile( _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"), }; - let rhses = match *argument_map[&rhs_nm] { + let rhses = match argument_map[&rhs_nm] { MatchedSeq(ref s, _) => s .iter() .map(|m| { @@ -369,24 +409,28 @@ pub fn compile( // don't abort iteration early, so that errors for multiple lhses can be reported for lhs in &lhses { valid &= check_lhs_no_empty_seq(sess, slice::from_ref(lhs)); - valid &= check_lhs_duplicate_matcher_bindings( - sess, - slice::from_ref(lhs), - &mut FxHashMap::default(), - def.id, - ); } - let expander: Box<_> = - Box::new(MacroRulesMacroExpander { name: def.ident, lhses, rhses, valid }); + // We use CRATE_NODE_ID instead of `def.id` otherwise we may emit buffered lints for a node id + // that is not lint-checked and trigger the "failed to process buffered lint here" bug. + valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses); - let default_transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) { - Transparency::Transparent - } else if body.legacy { - Transparency::SemiTransparent - } else { - Transparency::Opaque - }; + let expander: Box<_> = + Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, lhses, rhses, valid }); + + let (default_transparency, transparency_error) = + attr::find_transparency(&def.attrs, body.legacy); + match transparency_error { + Some(TransparencyError::UnknownTransparency(value, span)) => + sess.span_diagnostic.span_err( + span, &format!("unknown macro transparency: `{}`", value) + ), + Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => + sess.span_diagnostic.span_err( + vec![old_span, new_span], "multiple macro transparency attributes" + ), + None => {} + } let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| { @@ -417,8 +461,6 @@ pub fn compile( }) }); - let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); - let mut local_inner_macros = false; if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { if let Some(l) = macro_export.meta_item_list() { @@ -426,25 +468,21 @@ pub fn compile( } } - let unstable_feature = - attr::find_stability(&sess, &def.attrs, def.span).and_then(|stability| { - if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { - Some((stability.feature, issue)) - } else { - None - } - }); + let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro); SyntaxExtension { kind: SyntaxExtensionKind::LegacyBang(expander), - def_info: Some((def.id, def.span)), + span: def.span, default_transparency, allow_internal_unstable, - allow_internal_unsafe, + allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe), local_inner_macros, - unstable_feature, + stability: attr::find_stability(&sess, &def.attrs, def.span), + deprecation: attr::find_deprecation(&sess, &def.attrs, def.span), helper_attrs: Vec::new(), edition, + is_builtin, + is_derive_copy: is_builtin && def.ident.name == sym::Copy, } } @@ -484,8 +522,8 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { && seq.tts.iter().all(|seq_tt| match *seq_tt { TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis, TokenTree::Sequence(_, ref sub_seq) => { - sub_seq.op == quoted::KleeneOp::ZeroOrMore - || sub_seq.op == quoted::KleeneOp::ZeroOrOne + sub_seq.kleene.op == quoted::KleeneOp::ZeroOrMore + || sub_seq.kleene.op == quoted::KleeneOp::ZeroOrOne } _ => false, }) @@ -504,45 +542,6 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { true } -/// Check that the LHS contains no duplicate matcher bindings. e.g. `$a:expr, $a:expr` would be -/// illegal, since it would be ambiguous which `$a` to use if we ever needed to. -fn check_lhs_duplicate_matcher_bindings( - sess: &ParseSess, - tts: &[quoted::TokenTree], - metavar_names: &mut FxHashMap, - node_id: ast::NodeId, -) -> bool { - use self::quoted::TokenTree; - for tt in tts { - match *tt { - TokenTree::MetaVarDecl(span, name, _kind) => { - if let Some(&prev_span) = metavar_names.get(&name) { - sess.span_diagnostic - .struct_span_err(span, "duplicate matcher binding") - .span_note(prev_span, "previous declaration was here") - .emit(); - return false; - } else { - metavar_names.insert(name, span); - } - } - TokenTree::Delimited(_, ref del) => { - if !check_lhs_duplicate_matcher_bindings(sess, &del.tts, metavar_names, node_id) { - return false; - } - } - TokenTree::Sequence(_, ref seq) => { - if !check_lhs_duplicate_matcher_bindings(sess, &seq.tts, metavar_names, node_id) { - return false; - } - } - _ => {} - } - } - - true -} - fn check_rhs(sess: &ParseSess, rhs: "ed::TokenTree) -> bool { match *rhs { quoted::TokenTree::Delimited(..) => return true, @@ -635,8 +634,8 @@ impl FirstSets { // Reverse scan: Sequence comes before `first`. if subfirst.maybe_empty - || seq_rep.op == quoted::KleeneOp::ZeroOrMore - || seq_rep.op == quoted::KleeneOp::ZeroOrOne + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne { // If sequence is potentially empty, then // union them (preserving first emptiness). @@ -672,38 +671,37 @@ impl FirstSets { return first; } TokenTree::Sequence(sp, ref seq_rep) => { - match self.first.get(&sp.entire()) { - Some(&Some(ref subfirst)) => { - // If the sequence contents can be empty, then the first - // token could be the separator token itself. - - if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { - first.add_one_maybe(TokenTree::Token(sep.clone())); - } - - assert!(first.maybe_empty); - first.add_all(subfirst); - if subfirst.maybe_empty - || seq_rep.op == quoted::KleeneOp::ZeroOrMore - || seq_rep.op == quoted::KleeneOp::ZeroOrOne - { - // continue scanning for more first - // tokens, but also make sure we - // restore empty-tracking state - first.maybe_empty = true; - continue; - } else { - return first; - } - } - + let subfirst_owned; + let subfirst = match self.first.get(&sp.entire()) { + Some(&Some(ref subfirst)) => subfirst, Some(&None) => { - panic!("assume all sequences have (unique) spans for now"); + subfirst_owned = self.first(&seq_rep.tts[..]); + &subfirst_owned } - None => { panic!("We missed a sequence during FirstSets construction"); } + }; + + // If the sequence contents can be empty, then the first + // token could be the separator token itself. + if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { + first.add_one_maybe(TokenTree::Token(sep.clone())); + } + + assert!(first.maybe_empty); + first.add_all(subfirst); + if subfirst.maybe_empty + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne + { + // Continue scanning for more first + // tokens, but also make sure we + // restore empty-tracking state. + first.maybe_empty = true; + continue; + } else { + return first; } } } @@ -795,7 +793,7 @@ impl TokenSet { } // Checks that `matcher` is internally consistent and that it -// can legally by followed by a token N, for all N in `follow`. +// can legally be followed by a token `N`, for all `N` in `follow`. // (If `follow` is empty, then it imposes no constraint on // the `matcher`.) // diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index ccf9db842a..cad94a0e4c 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -27,7 +27,7 @@ impl Delimited { let open_span = if span.is_dummy() { span } else { - span.with_lo(span.lo() + BytePos(self.delim.len() as u32)) + span.with_hi(span.lo() + BytePos(self.delim.len() as u32)) }; TokenTree::token(token::OpenDelim(self.delim), open_span) } @@ -50,11 +50,23 @@ pub struct SequenceRepetition { /// The optional separator pub separator: Option, /// Whether the sequence can be repeated zero (*), or one or more times (+) - pub op: KleeneOp, + pub kleene: KleeneToken, /// The number of `Match`s that appear in the sequence (and subsequences) pub num_captures: usize, } +#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] +pub struct KleeneToken { + pub span: Span, + pub op: KleeneOp, +} + +impl KleeneToken { + pub fn new(op: KleeneOp, span: Span) -> KleeneToken { + KleeneToken { span, op } + } +} + /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star) /// for token sequences. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -111,6 +123,22 @@ impl TokenTree { } } + /// Returns `true` if the given token tree is delimited. + pub fn is_delimited(&self) -> bool { + match *self { + TokenTree::Delimited(..) => true, + _ => false, + } + } + + /// Returns `true` if the given token tree is a token of the given kind. + pub fn is_token(&self, expected_kind: &TokenKind) -> bool { + match self { + TokenTree::Token(Token { kind: actual_kind, .. }) => actual_kind == expected_kind, + _ => false, + } + } + /// Gets the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences. pub fn get_tt(&self, index: usize) -> TokenTree { match (self, index) { @@ -273,7 +301,7 @@ fn parse_tree( macro_node_id, ); // Get the Kleene operator and optional separator - let (separator, op) = parse_sep_and_kleene_op(trees, span.entire(), sess); + let (separator, kleene) = parse_sep_and_kleene_op(trees, span.entire(), sess); // Count the number of captured "names" (i.e., named metavars) let name_captures = macro_parser::count_names(&sequence); TokenTree::Sequence( @@ -281,7 +309,7 @@ fn parse_tree( Lrc::new(SequenceRepetition { tts: sequence, separator, - op, + kleene, num_captures: name_captures, }), ) @@ -379,16 +407,16 @@ fn parse_sep_and_kleene_op( input: &mut Peekable>, span: Span, sess: &ParseSess, -) -> (Option, KleeneOp) { +) -> (Option, KleeneToken) { // We basically look at two token trees here, denoted as #1 and #2 below let span = match parse_kleene_op(input, span) { // #1 is a `?`, `+`, or `*` KleeneOp - Ok(Ok((op, _))) => return (None, op), + Ok(Ok((op, span))) => return (None, KleeneToken::new(op, span)), // #1 is a separator followed by #2, a KleeneOp Ok(Err(token)) => match parse_kleene_op(input, token.span) { // #2 is the `?` Kleene op, which does not take a separator (error) - Ok(Ok((KleeneOp::ZeroOrOne, _))) => { + Ok(Ok((KleeneOp::ZeroOrOne, span))) => { // Error! sess.span_diagnostic.span_err( token.span, @@ -396,11 +424,11 @@ fn parse_sep_and_kleene_op( ); // Return a dummy - return (None, KleeneOp::ZeroOrMore); + return (None, KleeneToken::new(KleeneOp::ZeroOrMore, span)); } // #2 is a KleeneOp :D - Ok(Ok((op, _))) => return (Some(token), op), + Ok(Ok((op, span))) => return (Some(token), KleeneToken::new(op, span)), // #2 is a random token or not a token at all :( Ok(Err(Token { span, .. })) | Err(span) => span, @@ -414,5 +442,5 @@ fn parse_sep_and_kleene_op( sess.span_diagnostic.span_err(span, "expected one of: `*`, `+`, or `?`"); // Return a dummy - (None, KleeneOp::ZeroOrMore) + (None, KleeneToken::new(KleeneOp::ZeroOrMore, span)) } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index ea7f8e356a..214e721fd1 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -12,7 +12,6 @@ use smallvec::{smallvec, SmallVec}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use std::mem; -use std::rc::Rc; /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). enum Frame { @@ -65,9 +64,9 @@ impl Iterator for Frame { /// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`. /// /// Along the way, we do some additional error checking. -pub fn transcribe( +pub(super) fn transcribe( cx: &ExtCtxt<'_>, - interp: &FxHashMap>, + interp: &FxHashMap, src: Vec, ) -> TokenStream { // Nothing for us to transcribe... @@ -183,7 +182,7 @@ pub fn transcribe( // Is the repetition empty? if len == 0 { - if seq.op == quoted::KleeneOp::OneOrMore { + if seq.kleene.op == quoted::KleeneOp::OneOrMore { // FIXME: this really ought to be caught at macro definition // time... It happens when the Kleene operator in the matcher and // the body for the same meta-variable do not match. @@ -212,14 +211,14 @@ pub fn transcribe( // Find the matched nonterminal from the macro invocation, and use it to replace // the meta-var. if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { - if let MatchedNonterminal(ref nt) = *cur_matched { + if let MatchedNonterminal(ref nt) = cur_matched { // FIXME #2887: why do we apply a mark when matching a token tree meta-var // (e.g. `$x:tt`), but not when we are matching any other type of token // tree? if let NtTT(ref tt) = **nt { result.push(tt.clone().into()); } else { - sp = sp.apply_mark(cx.current_expansion.mark); + sp = sp.apply_mark(cx.current_expansion.id); let token = TokenTree::token(token::Interpolated(nt.clone()), sp); result.push(token.into()); } @@ -234,8 +233,8 @@ pub fn transcribe( // If we aren't able to match the meta-var, we push it back into the result but // with modified syntax context. (I believe this supports nested macros). let ident = - Ident::new(ident.name, ident.span.apply_mark(cx.current_expansion.mark)); - sp = sp.apply_mark(cx.current_expansion.mark); + Ident::new(ident.name, ident.span.apply_mark(cx.current_expansion.id)); + sp = sp.apply_mark(cx.current_expansion.id); result.push(TokenTree::token(token::Dollar, sp).into()); result.push(TokenTree::Token(Token::from_ast_ident(ident)).into()); } @@ -247,15 +246,15 @@ pub fn transcribe( // jump back out of the Delimited, pop the result_stack and add the new results back to // the previous results (from outside the Delimited). quoted::TokenTree::Delimited(mut span, delimited) => { - span = span.apply_mark(cx.current_expansion.mark); + span = span.apply_mark(cx.current_expansion.id); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); - result_stack.push(mem::replace(&mut result, Vec::new())); + result_stack.push(mem::take(&mut result)); } // Nothing much to do here. Just push the token to the result, being careful to // preserve syntax context. quoted::TokenTree::Token(token) => { - let mut marker = Marker(cx.current_expansion.mark); + let mut marker = Marker(cx.current_expansion.id); let mut tt = TokenTree::Token(token); noop_visit_tt(&mut tt, &mut marker); result.push(tt.into()); @@ -273,18 +272,17 @@ pub fn transcribe( /// See the definition of `repeats` in the `transcribe` function. `repeats` is used to descend /// into the right place in nested matchers. If we attempt to descend too far, the macro writer has /// made a mistake, and we return `None`. -fn lookup_cur_matched( +fn lookup_cur_matched<'a>( ident: Ident, - interpolations: &FxHashMap>, + interpolations: &'a FxHashMap, repeats: &[(usize, usize)], -) -> Option> { +) -> Option<&'a NamedMatch> { interpolations.get(&ident).map(|matched| { - let mut matched = matched.clone(); + let mut matched = matched; for &(idx, _) in repeats { - let m = matched.clone(); - match *m { + match matched { MatchedNonterminal(_) => break, - MatchedSeq(ref ads, _) => matched = Rc::new(ads[idx].clone()), + MatchedSeq(ref ads, _) => matched = ads.get(idx).unwrap(), } } @@ -343,7 +341,7 @@ impl LockstepIterSize { /// multiple nested matcher sequences. fn lockstep_iter_size( tree: "ed::TokenTree, - interpolations: &FxHashMap>, + interpolations: &FxHashMap, repeats: &[(usize, usize)], ) -> LockstepIterSize { use quoted::TokenTree; @@ -360,7 +358,7 @@ fn lockstep_iter_size( } TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => { match lookup_cur_matched(name, interpolations, repeats) { - Some(matched) => match *matched { + Some(matched) => match matched { MatchedNonterminal(_) => LockstepIterSize::Unconstrained, MatchedSeq(ref ads, _) => LockstepIterSize::Constraint(ads.len(), name), }, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e6a09e7f87..08a113b53d 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -19,8 +19,7 @@ use crate::ast::{ self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, PatKind, RangeEnd, }; -use crate::attr; -use crate::early_buffered_lints::BufferedEarlyLintId; +use crate::attr::{self, check_builtin_attribute, AttributeTemplate}; use crate::source_map::Spanned; use crate::edition::{ALL_EDITIONS, Edition}; use crate::visit::{self, FnKind, Visitor}; @@ -31,6 +30,7 @@ use crate::tokenstream::TokenTree; use errors::{Applicability, DiagnosticBuilder, Handler}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use log::debug; @@ -125,6 +125,9 @@ declare_features! ( // no-tracking-issue-start + // Allows using compiler's own crates. + (active, rustc_private, "1.0.0", Some(27812), None), + // Allows using the `rust-intrinsic`'s "ABI". (active, intrinsics, "1.0.0", None, None), @@ -198,9 +201,6 @@ declare_features! ( // no-tracking-issue-end - // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). - (active, dropck_parametricity, "1.3.0", Some(28498), None), - // no-tracking-issue-start // Allows using `#[omit_gdb_pretty_printer_section]`. @@ -243,9 +243,6 @@ declare_features! ( // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. (active, allocator_internals, "1.20.0", None, None), - // Allows using the `format_args_nl` macro. - (active, format_args_nl, "1.29.0", None, None), - // no-tracking-issue-end // Added for testing E0705; perma-unstable. @@ -286,12 +283,6 @@ declare_features! ( // feature-group-start: actual feature gates // ------------------------------------------------------------------------- - // Allows using `asm!` macro with which inline assembly can be embedded. - (active, asm, "1.0.0", Some(29722), None), - - // Allows using the `concat_idents!` macro with which identifiers can be concatenated. - (active, concat_idents, "1.0.0", Some(29599), None), - // Allows using the `#[link_args]` attribute. (active, link_args, "1.0.0", Some(29596), None), @@ -307,12 +298,6 @@ declare_features! ( // Allows using `#[thread_local]` on `static` items. (active, thread_local, "1.0.0", Some(29594), None), - // Allows using the `log_syntax!` macro. - (active, log_syntax, "1.0.0", Some(29598), None), - - // Allows using the `trace_macros!` macro. - (active, trace_macros, "1.0.0", Some(29598), None), - // Allows the use of SIMD types in functions declared in `extern` blocks. (active, simd_ffi, "1.0.0", Some(27731), None), @@ -323,7 +308,7 @@ declare_features! ( (active, nll, "1.0.0", Some(43234), None), // Allows using slice patterns. - (active, slice_patterns, "1.0.0", Some(23121), None), + (active, slice_patterns, "1.0.0", Some(62254), None), // Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(57563), None), @@ -402,9 +387,6 @@ declare_features! ( // Allows `extern "x86-interrupt" fn()`. (active, abi_x86_interrupt, "1.17.0", Some(40180), None), - // Allows module-level inline assembly by way of `global_asm!()`. - (active, global_asm, "1.18.0", Some(35119), None), - // Allows overlapping impls of marker traits. (active, overlapping_marker_traits, "1.18.0", Some(29864), None), @@ -471,9 +453,6 @@ declare_features! ( // Allows `#[doc(alias = "...")]`. (active, doc_alias, "1.27.0", Some(50146), None), - // Allows defining `existential type`s. - (active, existential_type, "1.28.0", Some(34511), None), - // Allows inconsistent bounds in where clauses. (active, trivial_bounds, "1.28.0", Some(48214), None), @@ -486,10 +465,6 @@ declare_features! ( // Allows async and await syntax. (active, async_await, "1.28.0", Some(50547), None), - // Allows await! macro-like syntax. - // This will likely be removed prior to stabilization of async/await. - (active, await_macro, "1.28.0", Some(50547), None), - // Allows reinterpretation of the bits of a value of one type as another type during const eval. (active, const_transmute, "1.29.0", Some(53605), None), @@ -525,7 +500,7 @@ declare_features! ( (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None), // Allows `impl Trait` in bindings (`let`, `const`, `static`). - (active, impl_trait_in_bindings, "1.30.0", Some(34511), None), + (active, impl_trait_in_bindings, "1.30.0", Some(63065), None), // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. (active, lint_reasons, "1.31.0", Some(54503), None), @@ -561,10 +536,10 @@ declare_features! ( // Allows `if/while p && let q = r && ...` chains. (active, let_chains, "1.37.0", Some(53667), None), - // #[repr(transparent)] on enums. + // Allows #[repr(transparent)] on enums (RFC 2645). (active, transparent_enums, "1.37.0", Some(60405), None), - // #[repr(transparent)] on unions. + // Allows #[repr(transparent)] on unions (RFC 2645). (active, transparent_unions, "1.37.0", Some(60405), None), // Allows explicit discriminants on non-unit enum variants. @@ -573,15 +548,27 @@ declare_features! ( // Allows `impl Trait` with multiple unrelated lifetimes. (active, member_constraints, "1.37.0", Some(61977), None), + // Allows `async || body` closures. + (active, async_closure, "1.37.0", Some(62290), None), + + // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests + (active, cfg_doctest, "1.37.0", Some(62210), None), + + // Allows `[x; N]` where `x` is a constant (RFC 2203). + (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None), + + // Allows `impl Trait` to be used inside type aliases (RFC 2515). + (active, type_alias_impl_trait, "1.38.0", Some(63063), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- ); -// Some features are known to be incomplete and using them is likely to have -// unanticipated results, such as compiler crashes. We warn the user about these -// to alert them. -const INCOMPLETE_FEATURES: &[Symbol] = &[ +/// Some features are known to be incomplete and using them is likely to have +/// unanticipated results, such as compiler crashes. We warn the user about these +/// to alert them. +pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::impl_trait_in_bindings, sym::generic_associated_types, sym::const_generics, @@ -610,7 +597,7 @@ declare_features! ( (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, + (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, Some("merged into `#![feature(slice_patterns)]`")), (removed, macro_reexport, "1.0.0", Some(29638), None, Some("subsumed by `pub use`")), @@ -634,6 +621,13 @@ declare_features! ( (removed, extern_in_paths, "1.33.0", Some(55600), None, Some("subsumed by `::foo::bar` paths")), (removed, quote, "1.33.0", Some(29601), None, None), + // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). + (removed, dropck_parametricity, "1.38.0", Some(28498), None, None), + (removed, await_macro, "1.38.0", Some(50547), None, + Some("subsumed by `.await` syntax")), + // Allows defining `existential type`s. + (removed, existential_type, "1.38.0", Some(63063), None, + Some("removed in favor of `#![feature(type_alias_impl_trait)]`")), // ------------------------------------------------------------------------- // feature-group-end: removed features @@ -894,27 +888,6 @@ pub enum AttributeGate { Ungated, } -/// A template that the attribute input must match. -/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now. -#[derive(Clone, Copy)] -pub struct AttributeTemplate { - word: bool, - list: Option<&'static str>, - name_value_str: Option<&'static str>, -} - -impl AttributeTemplate { - /// Checks that the given meta-item is compatible with this template. - fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool { - match meta_item_kind { - ast::MetaItemKind::Word => self.word, - ast::MetaItemKind::List(..) => self.list.is_some(), - ast::MetaItemKind::NameValue(lit) if lit.node.is_str() => self.name_value_str.is_some(), - ast::MetaItemKind::NameValue(..) => false, - } - } -} - /// A convenience macro for constructing attribute templates. /// E.g., `template!(Word, List: "description")` means that the attribute /// supports forms `#[attr]` and `#[attr(description)]`. @@ -1105,7 +1078,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "the `#[rustc_const_unstable]` attribute \ is an internal feature", cfg_fn!(rustc_const_unstable))), - (sym::global_allocator, Normal, template!(Word), Ungated), (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, sym::allocator_internals, "the `#[default_lib_allocator]` \ @@ -1292,12 +1264,26 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ attribute is just used for rustc unit \ tests and will never be stable", cfg_fn!(rustc_attrs))), + (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "the `#[rustc_dump_env_program_clauses]` \ + attribute is just used for rustc unit \ + tests and will never be stable", + cfg_fn!(rustc_attrs))), + (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "the `#[rustc_object_lifetime_default]` \ + attribute is just used for rustc unit \ + tests and will never be stable", + cfg_fn!(rustc_attrs))), (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable, sym::rustc_attrs, "the `#[rustc_test_marker]` attribute \ is used internally to track tests", cfg_fn!(rustc_attrs))), - (sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr: + "transparent|semitransparent|opaque"), + Gated(Stability::Unstable, sym::rustc_attrs, "used internally for testing macro hygiene", cfg_fn!(rustc_attrs))), @@ -1343,12 +1329,27 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ /*opt*/ attributes(name1, name2, ...)"), Ungated), - (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, sym::rustc_attrs, "internal implementation detail", cfg_fn!(rustc_attrs))), - (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, + (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + + (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + + (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + + (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable, sym::rustc_attrs, "internal implementation detail", cfg_fn!(rustc_attrs))), @@ -1406,25 +1407,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ cfg_fn!(omit_gdb_pretty_printer_section) ) ), - (sym::unsafe_destructor_blind_to_params, - Normal, - template!(Word), - Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761", - Some("replace this attribute with `#[may_dangle]`")), - sym::dropck_parametricity, - "unsafe_destructor_blind_to_params has been replaced by \ - may_dangle and will be removed in the future", - cfg_fn!(dropck_parametricity))), (sym::may_dangle, Normal, template!(Word), Gated(Stability::Unstable, sym::dropck_eyepatch, - "may_dangle has unstable semantics and may be removed in the future", + "`may_dangle` has unstable semantics and may be removed in the future", cfg_fn!(dropck_eyepatch))), (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable, sym::unwind_attributes, - "#[unwind] is experimental", + "`#[unwind]` is experimental", cfg_fn!(unwind_attributes))), (sym::used, Whitelisted, template!(Word), Ungated), @@ -1510,13 +1502,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable, sym::alloc_error_handler, - "#[alloc_error_handler] is an unstable feature", + "`#[alloc_error_handler]` is an unstable feature", cfg_fn!(alloc_error_handler))), // RFC 2412 (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable, sym::optimize_attribute, - "#[optimize] attribute is an unstable feature", + "`#[optimize]` attribute is an unstable feature", cfg_fn!(optimize_attribute))), // Crate level attributes @@ -1530,7 +1522,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, sym::custom_test_frameworks, - EXPLAIN_CUSTOM_TEST_FRAMEWORKS, + "custom test frameworks are an unstable feature", cfg_fn!(custom_test_frameworks))), ]; @@ -1554,6 +1546,7 @@ const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[ (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), + (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)), ]; #[derive(Debug)] @@ -1632,13 +1625,21 @@ impl<'a> Context<'a> { if let Some(content) = attr.meta_item_list() { if content.iter().any(|c| c.check_name(sym::include)) { gate_feature!(self, external_doc, attr.span, - "#[doc(include = \"...\")] is experimental" + "`#[doc(include = \"...\")]` is experimental" ); } } } debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); return; + } else { + for segment in &attr.path.segments { + if segment.ident.as_str().starts_with("rustc") { + let msg = "attributes starting with `rustc` are \ + reserved for use by the `rustc` compiler"; + gate_feature!(self, rustc_attrs, segment.ident.span, msg); + } + } } for &(n, ty) in self.plugin_attributes { if attr.path == n { @@ -1649,19 +1650,13 @@ impl<'a> Context<'a> { return; } } - if !attr::is_known(attr) { - if attr.name_or_empty().as_str().starts_with("rustc_") { - let msg = "unless otherwise specified, attributes with the prefix `rustc_` \ - are reserved for internal compiler diagnostics"; - gate_feature!(self, rustc_attrs, attr.span, msg); - } else if !is_macro { - // Only run the custom attribute lint during regular feature gate - // checking. Macro gating runs before the plugin attributes are - // registered, so we skip this in that case. - let msg = format!("The attribute `{}` is currently unknown to the compiler and \ - may have meaning added to it in the future", attr.path); - gate_feature!(self, custom_attribute, attr.span, &msg); - } + if !is_macro && !attr::is_known(attr) { + // Only run the custom attribute lint during regular feature gate + // checking. Macro gating runs before the plugin attributes are + // registered, so we skip this in that case. + let msg = format!("the attribute `{}` is currently unknown to the compiler and \ + may have meaning added to it in the future", attr.path); + gate_feature!(self, custom_attribute, attr.span, &msg); } } } @@ -1759,7 +1754,7 @@ fn leveled_feature_err<'a, S: Into>( // #23973: do not suggest `#![feature(...)]` if we are in beta/stable if sess.unstable_features.is_nightly_build() { - err.help(&format!("add #![feature({})] to the crate attributes to enable", feature)); + err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature)); } // If we're on stable and only emitting a "soft" warning, add a note to @@ -1779,26 +1774,6 @@ const EXPLAIN_BOX_SYNTAX: &str = pub const EXPLAIN_STMT_ATTR_SYNTAX: &str = "attributes on expressions are experimental"; -pub const EXPLAIN_ASM: &str = - "inline assembly is not stable enough for use and is subject to change"; - -pub const EXPLAIN_GLOBAL_ASM: &str = - "`global_asm!` is not stable enough for use and is subject to change"; - -pub const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str = - "custom test frameworks are an unstable feature"; - -pub const EXPLAIN_LOG_SYNTAX: &str = - "`log_syntax!` is not stable enough for use and is subject to change"; - -pub const EXPLAIN_CONCAT_IDENTS: &str = - "`concat_idents` is not stable enough for use and is subject to change"; - -pub const EXPLAIN_FORMAT_ARGS_NL: &str = - "`format_args_nl` is only for internal language use and is subject to change"; - -pub const EXPLAIN_TRACE_MACROS: &str = - "`trace_macros` is not stable enough for use and is subject to change"; pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str = "allow_internal_unstable side-steps feature gating and stability checks"; pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str = @@ -1882,70 +1857,6 @@ impl<'a> PostExpansionVisitor<'a> { Abi::System => {} } } - - fn check_builtin_attribute(&mut self, attr: &ast::Attribute, name: Symbol, - template: AttributeTemplate) { - // Some special attributes like `cfg` must be checked - // before the generic check, so we skip them here. - let should_skip = |name| name == sym::cfg; - // Some of previously accepted forms were used in practice, - // report them as warnings for now. - let should_warn = |name| name == sym::doc || name == sym::ignore || - name == sym::inline || name == sym::link; - - match attr.parse_meta(self.context.parse_sess) { - Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) { - let error_msg = format!("malformed `{}` attribute input", name); - let mut msg = "attribute must be of the form ".to_owned(); - let mut suggestions = vec![]; - let mut first = true; - if template.word { - first = false; - let code = format!("#[{}]", name); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if let Some(descr) = template.list { - if !first { - msg.push_str(" or "); - } - first = false; - let code = format!("#[{}({})]", name, descr); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if let Some(descr) = template.name_value_str { - if !first { - msg.push_str(" or "); - } - let code = format!("#[{} = \"{}\"]", name, descr); - msg.push_str(&format!("`{}`", &code)); - suggestions.push(code); - } - if should_warn(name) { - self.context.parse_sess.buffer_lint( - BufferedEarlyLintId::IllFormedAttributeInput, - meta.span, - ast::CRATE_NODE_ID, - &msg, - ); - } else { - self.context.parse_sess.span_diagnostic.struct_span_err(meta.span, &error_msg) - .span_suggestions( - meta.span, - if suggestions.len() == 1 { - "must be of the form" - } else { - "the following are the possible correct uses" - }, - suggestions.into_iter(), - Applicability::HasPlaceholders, - ).emit(); - } - } - Err(mut err) => err.emit(), - } - } } impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { @@ -1961,23 +1872,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if let Some(content) = attr.meta_item_list() { if content.len() == 1 && content[0].check_name(sym::cfg) { gate_feature_post!(&self, doc_cfg, attr.span, - "#[doc(cfg(...))] is experimental" + "`#[doc(cfg(...))]` is experimental" ); } else if content.iter().any(|c| c.check_name(sym::masked)) { gate_feature_post!(&self, doc_masked, attr.span, - "#[doc(masked)] is experimental" + "`#[doc(masked)]` is experimental" ); } else if content.iter().any(|c| c.check_name(sym::spotlight)) { gate_feature_post!(&self, doc_spotlight, attr.span, - "#[doc(spotlight)] is experimental" + "`#[doc(spotlight)]` is experimental" ); } else if content.iter().any(|c| c.check_name(sym::alias)) { gate_feature_post!(&self, doc_alias, attr.span, - "#[doc(alias = \"...\")] is experimental" + "`#[doc(alias = \"...\")]` is experimental" ); } else if content.iter().any(|c| c.check_name(sym::keyword)) { gate_feature_post!(&self, doc_keyword, attr.span, - "#[doc(keyword = \"...\")] is experimental" + "`#[doc(keyword = \"...\")]` is experimental" ); } } @@ -1986,7 +1897,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match attr_info { // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. Some(&(name, _, template, _)) if name != sym::rustc_dummy => - self.check_builtin_attribute(attr, name, template), + check_builtin_attribute(self.context.parse_sess, attr, name, template), _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { if token == token::Eq { // All key-value attributes are restricted to meta-item syntax. @@ -2020,13 +1931,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } if attr::contains_name(&i.attrs[..], sym::start) { gate_feature_post!(&self, start, i.span, - "a #[start] function is an experimental \ + "a `#[start]` function is an experimental \ feature whose signature may change \ over time"); } if attr::contains_name(&i.attrs[..], sym::main) { gate_feature_post!(&self, main, i.span, - "declaration of a nonstandard #[main] \ + "declaration of a non-standard `#[main]` \ function may change over time, for now \ a top-level `fn main()` is required"); } @@ -2101,12 +2012,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, decl_macro, i.span, msg); } - ast::ItemKind::Existential(..) => { + ast::ItemKind::OpaqueTy(..) => { gate_feature_post!( &self, - existential_type, + type_alias_impl_trait, i.span, - "existential types are unstable" + "`impl Trait` in type aliases is unstable" ); } @@ -2191,25 +2102,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "labels on blocks are unstable"); } } - ast::ExprKind::Closure(_, ast::IsAsync::Async { .. }, ..) => { - gate_feature_post!(&self, async_await, e.span, "async closures are unstable"); - } ast::ExprKind::Async(..) => { gate_feature_post!(&self, async_await, e.span, "async blocks are unstable"); } - ast::ExprKind::Await(origin, _) => { - match origin { - ast::AwaitOrigin::FieldLike => - gate_feature_post!(&self, async_await, e.span, "async/await is unstable"), - ast::AwaitOrigin::MacroLike => - gate_feature_post!( - &self, - await_macro, - e.span, - "`await!()` macro syntax is unstable, and will soon be removed \ - in favor of `.await` syntax." - ), - } + ast::ExprKind::Await(_) => { + gate_feature_post!(&self, async_await, e.span, "async/await is unstable"); } _ => {} } @@ -2221,11 +2118,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_pat(&mut self, pattern: &'a ast::Pat) { - match pattern.node { - PatKind::Slice(_, Some(ref subslice), _) => { - gate_feature_post!(&self, slice_patterns, - subslice.span, - "syntax for subslices in slice patterns is not yet stabilized"); + match &pattern.node { + PatKind::Slice(pats) => { + for pat in &*pats { + let span = pat.span; + let inner_pat = match &pat.node { + PatKind::Ident(.., Some(pat)) => pat, + _ => pat, + }; + if inner_pat.is_rest() { + gate_feature_post!( + &self, + slice_patterns, + span, + "subslice patterns are unstable" + ); + } + } } PatKind::Box(..) => { gate_feature_post!(&self, box_patterns, @@ -2332,15 +2241,15 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ii.node { ast::ImplItemKind::Method(..) => {} - ast::ImplItemKind::Existential(..) => { + ast::ImplItemKind::OpaqueTy(..) => { gate_feature_post!( &self, - existential_type, + type_alias_impl_trait, ii.span, - "existential types are unstable" + "`impl Trait` in type aliases is unstable" ); } - ast::ImplItemKind::Type(_) => { + ast::ImplItemKind::TyAlias(_) => { if !ii.generics.params.is_empty() { gate_feature_post!(&self, generic_associated_types, ii.span, "generic associated types are unstable"); @@ -2414,15 +2323,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } let name = mi.name_or_empty(); - if INCOMPLETE_FEATURES.iter().any(|f| name == *f) { - span_handler.struct_span_warn( - mi.span(), - &format!( - "the feature `{}` is incomplete and may cause the compiler to crash", - name - ) - ).emit(); - } if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { if *edition <= crate_edition { @@ -2527,6 +2427,10 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], features } +fn for_each_in_lock(vec: &Lock>, f: impl Fn(&T)) { + vec.borrow().iter().for_each(f); +} + pub fn check_crate(krate: &ast::Crate, sess: &ParseSess, features: &Features, @@ -2539,27 +2443,26 @@ pub fn check_crate(krate: &ast::Crate, plugin_attributes, }; - sess - .param_attr_spans - .borrow() - .iter() - .for_each(|span| gate_feature!( - &ctx, - param_attrs, - *span, - "attributes on function parameters are unstable" - )); - - sess - .let_chains_spans - .borrow() - .iter() - .for_each(|span| gate_feature!( - &ctx, - let_chains, - *span, - "`let` expressions in this position are experimental" - )); + for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!( + &ctx, + param_attrs, + *span, + "attributes on function parameters are unstable" + )); + + for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!( + &ctx, + let_chains, + *span, + "`let` expressions in this position are experimental" + )); + + for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!( + &ctx, + async_closure, + *span, + "async closures are unstable" + )); let visitor = &mut PostExpansionVisitor { context: &ctx, @@ -2614,7 +2517,7 @@ fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, if attr.check_name(sym::feature) { let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"); span_err!(span_handler, attr.span, E0554, - "#![feature] may not be used on the {} release channel", + "`#![feature]` may not be used on the {} release channel", release_channel); } } diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 767ab74355..83c9c692bd 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -122,7 +122,6 @@ struct Diagnostic { } #[derive(RustcEncodable)] -#[allow(unused_attributes)] struct DiagnosticSpan { file_name: String, byte_start: u32, @@ -170,7 +169,7 @@ struct DiagnosticSpanMacroExpansion { macro_decl_name: String, /// span where macro was defined (if known) - def_site_span: Option, + def_site_span: DiagnosticSpan, } #[derive(RustcEncodable)] @@ -300,14 +299,13 @@ impl DiagnosticSpan { None, backtrace, je); - let def_site_span = bt.def_site_span.map(|sp| { - Self::from_span_full(sp, + let def_site_span = + Self::from_span_full(bt.def_site_span, false, None, None, vec![].into_iter(), - je) - }); + je); Box::new(DiagnosticSpanMacroExpansion { span: call_site, macro_decl_name: bt.macro_decl_name, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 337b842473..8ac48d8d74 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -7,26 +7,24 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] -#![deny(rust_2018_idioms)] -#![deny(internal)] -#![deny(unused_lifetimes)] - #![feature(bind_by_move_pattern_guards)] +#![feature(box_syntax)] #![feature(const_fn)] #![feature(const_transmute)] #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(mem_take)] #![feature(nll)] -#![feature(rustc_attrs)] +#![feature(proc_macro_diagnostic)] +#![feature(proc_macro_internals)] +#![feature(proc_macro_span)] #![feature(rustc_diagnostic_macros)] -#![feature(step_trait)] #![feature(try_trait)] #![feature(unicode_internals)] #![recursion_limit="256"] -#[allow(unused_extern_crates)] -extern crate serialize as rustc_serialize; // used by deriving +extern crate proc_macro; pub use errors; use rustc_data_structures::sync::Lock; @@ -35,12 +33,16 @@ pub use rustc_data_structures::thin_vec::ThinVec; use ast::AttrId; use syntax_pos::edition::Edition; +#[cfg(test)] +mod tests; + const MACRO_ARGUMENTS: Option<&'static str> = Some("macro arguments"); // A variant of 'try!' that panics on an Err. This is used as a crutch on the // way towards a non-panic!-prone parser. It should be used for fatal parsing // errors; eventually we plan to convert all code using panictry to just use // normal try. +#[macro_export] macro_rules! panictry { ($e:expr) => ({ use std::result::Result::{Ok, Err}; @@ -133,8 +135,6 @@ pub mod util { pub mod lev_distance; pub mod node_count; pub mod parser; - #[cfg(test)] - pub mod parser_testing; pub mod map_in_place; } @@ -151,29 +151,31 @@ pub mod mut_visit; pub mod parse; pub mod ptr; pub mod show_span; -pub mod std_inject; pub use syntax_pos::edition; pub use syntax_pos::symbol; -pub mod test; pub mod tokenstream; pub mod visit; pub mod print { pub mod pp; pub mod pprust; + mod helpers; } pub mod ext { + mod placeholders; + mod proc_macro_server; + pub use syntax_pos::hygiene; + pub mod allocator; pub mod base; pub mod build; - pub mod derive; pub mod expand; - pub mod placeholders; - pub mod source_util; + pub mod proc_macro; pub mod tt { pub mod transcribe; + pub mod macro_check; pub mod macro_parser; pub mod macro_rules; pub mod quoted; @@ -182,7 +184,4 @@ pub mod ext { pub mod early_buffered_lints; -#[cfg(test)] -mod test_snippet; - __build_diagnostic_array! { libsyntax, DIAGNOSTICS } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index e23bc025f6..be04c6a76b 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -22,6 +22,9 @@ use rustc_data_structures::sync::Lrc; use std::ops::DerefMut; use std::{panic, process, ptr}; +#[cfg(test)] +mod tests; + pub trait ExpectOne { fn expect_one(self, err: &'static str) -> A::Item; } @@ -530,7 +533,7 @@ pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { } pub fn noop_visit_mac(Spanned { node, span }: &mut Mac, vis: &mut T) { - let Mac_ { path, delim: _, tts } = node; + let Mac_ { path, delim: _, tts, .. } = node; vis.visit_path(path); vis.visit_tts(tts); vis.visit_span(span); @@ -558,10 +561,11 @@ pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { vis.visit_span(span); } -pub fn noop_visit_arg(Arg { attrs, id, pat, ty }: &mut Arg, vis: &mut T) { +pub fn noop_visit_arg(Arg { attrs, id, pat, span, ty }: &mut Arg, vis: &mut T) { vis.visit_id(id); visit_thin_attrs(attrs, vis); vis.visit_pat(pat); + vis.visit_span(span); vis.visit_ty(ty); } @@ -843,11 +847,11 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { ItemKind::Mod(m) => vis.visit_mod(m), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::GlobalAsm(_ga) => {} - ItemKind::Ty(ty, generics) => { + ItemKind::TyAlias(ty, generics) => { vis.visit_ty(ty); vis.visit_generics(generics); } - ItemKind::Existential(bounds, generics) => { + ItemKind::OpaqueTy(bounds, generics) => { visit_bounds(bounds, vis); vis.visit_generics(generics); } @@ -929,8 +933,8 @@ pub fn noop_flat_map_impl_item(mut item: ImplItem, visitor: &mut visit_method_sig(sig, visitor); visitor.visit_block(body); } - ImplItemKind::Type(ty) => visitor.visit_ty(ty), - ImplItemKind::Existential(bounds) => visit_bounds(bounds, visitor), + ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty), + ImplItemKind::OpaqueTy(bounds) => visit_bounds(bounds, visitor), ImplItemKind::Macro(mac) => visitor.visit_mac(mac), } visitor.visit_span(span); @@ -1020,15 +1024,15 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { let Pat { id, node, span } = pat.deref_mut(); vis.visit_id(id); match node { - PatKind::Wild => {} + PatKind::Wild | PatKind::Rest => {} PatKind::Ident(_binding_mode, ident, sub) => { vis.visit_ident(ident); visit_opt(sub, |sub| vis.visit_pat(sub)); } PatKind::Lit(e) => vis.visit_expr(e), - PatKind::TupleStruct(path, pats, _ddpos) => { + PatKind::TupleStruct(path, elems) => { vis.visit_path(path); - visit_vec(pats, |pat| vis.visit_pat(pat)); + visit_vec(elems, |elem| vis.visit_pat(elem)); } PatKind::Path(qself, path) => { vis.visit_qself(qself); @@ -1043,7 +1047,7 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { vis.visit_span(span); }; } - PatKind::Tuple(elts, _ddpos) => visit_vec(elts, |elt| vis.visit_pat(elt)), + PatKind::Tuple(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)), PatKind::Box(inner) => vis.visit_pat(inner), PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { @@ -1051,11 +1055,7 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { vis.visit_expr(e2); vis.visit_span(span); } - PatKind::Slice(before, slice, after) => { - visit_vec(before, |pat| vis.visit_pat(pat)); - visit_opt(slice, |slice| vis.visit_pat(slice)); - visit_vec(after, |pat| vis.visit_pat(pat)); - } + PatKind::Slice(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)), PatKind::Paren(inner) => vis.visit_pat(inner), PatKind::Mac(mac) => vis.visit_mac(mac), } @@ -1142,7 +1142,7 @@ pub fn noop_visit_expr(Expr { node, id, span, attrs }: &mut Expr, vis.visit_id(node_id); vis.visit_block(body); } - ExprKind::Await(_origin, expr) => vis.visit_expr(expr), + ExprKind::Await(expr) => vis.visit_expr(expr), ExprKind::Assign(el, er) => { vis.visit_expr(el); vis.visit_expr(er); @@ -1258,78 +1258,3 @@ pub fn noop_visit_vis(Spanned { node, span }: &mut Visibility, vi } vis.visit_span(span); } - -#[cfg(test)] -mod tests { - use std::io; - use crate::ast::{self, Ident}; - use crate::util::parser_testing::{string_to_crate, matches_codepattern}; - use crate::print::pprust; - use crate::mut_visit; - use crate::with_default_globals; - use super::*; - - // this version doesn't care about getting comments or docstrings in. - fn fake_print_crate(s: &mut pprust::State<'_>, - krate: &ast::Crate) -> io::Result<()> { - s.print_mod(&krate.module, &krate.attrs) - } - - // change every identifier to "zz" - struct ToZzIdentMutVisitor; - - impl MutVisitor for ToZzIdentMutVisitor { - fn visit_ident(&mut self, ident: &mut ast::Ident) { - *ident = Ident::from_str("zz"); - } - fn visit_mac(&mut self, mac: &mut ast::Mac) { - mut_visit::noop_visit_mac(mac, self) - } - } - - // maybe add to expand.rs... - macro_rules! assert_pred { - ($pred:expr, $predname:expr, $a:expr , $b:expr) => ( - { - let pred_val = $pred; - let a_val = $a; - let b_val = $b; - if !(pred_val(&a_val, &b_val)) { - panic!("expected args satisfying {}, got {} and {}", - $predname, a_val, b_val); - } - } - ) - } - - // make sure idents get transformed everywhere - #[test] fn ident_transformation () { - with_default_globals(|| { - let mut zz_visitor = ToZzIdentMutVisitor; - let mut krate = string_to_crate( - "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); - zz_visitor.visit_crate(&mut krate); - assert_pred!( - matches_codepattern, - "matches_codepattern", - pprust::to_string(|s| fake_print_crate(s, &krate)), - "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()); - }) - } - - // even inside macro defs.... - #[test] fn ident_transformation_in_defs () { - with_default_globals(|| { - let mut zz_visitor = ToZzIdentMutVisitor; - let mut krate = string_to_crate( - "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ - (g $(d $d $e)+))} ".to_string()); - zz_visitor.visit_crate(&mut krate); - assert_pred!( - matches_codepattern, - "matches_codepattern", - pprust::to_string(|s| fake_print_crate(s, &krate)), - "macro_rules! zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)));".to_string()); - }) - } -} diff --git a/src/libsyntax/mut_visit/tests.rs b/src/libsyntax/mut_visit/tests.rs new file mode 100644 index 0000000000..6868736976 --- /dev/null +++ b/src/libsyntax/mut_visit/tests.rs @@ -0,0 +1,71 @@ +use super::*; + +use crate::ast::{self, Ident}; +use crate::tests::{string_to_crate, matches_codepattern}; +use crate::print::pprust; +use crate::mut_visit; +use crate::with_default_globals; + +// this version doesn't care about getting comments or docstrings in. +fn fake_print_crate(s: &mut pprust::State<'_>, + krate: &ast::Crate) { + s.print_mod(&krate.module, &krate.attrs) +} + +// change every identifier to "zz" +struct ToZzIdentMutVisitor; + +impl MutVisitor for ToZzIdentMutVisitor { + fn visit_ident(&mut self, ident: &mut ast::Ident) { + *ident = Ident::from_str("zz"); + } + fn visit_mac(&mut self, mac: &mut ast::Mac) { + mut_visit::noop_visit_mac(mac, self) + } +} + +// maybe add to expand.rs... +macro_rules! assert_pred { + ($pred:expr, $predname:expr, $a:expr , $b:expr) => ( + { + let pred_val = $pred; + let a_val = $a; + let b_val = $b; + if !(pred_val(&a_val, &b_val)) { + panic!("expected args satisfying {}, got {} and {}", + $predname, a_val, b_val); + } + } + ) +} + +// make sure idents get transformed everywhere +#[test] fn ident_transformation () { + with_default_globals(|| { + let mut zz_visitor = ToZzIdentMutVisitor; + let mut krate = string_to_crate( + "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); + zz_visitor.visit_crate(&mut krate); + assert_pred!( + matches_codepattern, + "matches_codepattern", + pprust::to_string(|s| fake_print_crate(s, &krate)), + "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()); + }) +} + +// even inside macro defs.... +#[test] fn ident_transformation_in_defs () { + with_default_globals(|| { + let mut zz_visitor = ToZzIdentMutVisitor; + let mut krate = string_to_crate( + "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ + (g $(d $d $e)+))} ".to_string()); + zz_visitor.visit_crate(&mut krate); + assert_pred!( + matches_codepattern, + "matches_codepattern", + pprust::to_string(|s| fake_print_crate(s, &krate)), + "macro_rules! zz{(zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+))}".to_string()); + }) +} diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index b28d48b944..a42da11236 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -4,6 +4,7 @@ use crate::parse::{SeqSep, PResult}; use crate::parse::token::{self, Nonterminal, DelimToken}; use crate::parse::parser::{Parser, TokenType, PathStyle}; use crate::tokenstream::{TokenStream, TokenTree}; +use crate::source_map::Span; use log::debug; use smallvec::smallvec; @@ -11,7 +12,7 @@ use smallvec::smallvec; #[derive(Debug)] enum InnerAttributeParsePolicy<'a> { Permitted, - NotPermitted { reason: &'a str }, + NotPermitted { reason: &'a str, saw_doc_comment: bool, prev_attr_sp: Option }, } const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \ @@ -42,13 +43,17 @@ impl<'a> Parser<'a> { DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG }; let inner_parse_policy = - InnerAttributeParsePolicy::NotPermitted { reason: inner_error_reason }; + InnerAttributeParsePolicy::NotPermitted { + reason: inner_error_reason, + saw_doc_comment: just_parsed_doc_comment, + prev_attr_sp: attrs.last().and_then(|a| Some(a.span)) + }; let attr = self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?; attrs.push(attr); just_parsed_doc_comment = false; } token::DocComment(s) => { - let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.token.span); + let attr = attr::mk_sugared_doc_attr(s, self.token.span); if attr.style != ast::AttrStyle::Outer { let mut err = self.fatal("expected outer doc comment"); err.note("inner doc comments like this (starting with \ @@ -76,8 +81,11 @@ impl<'a> Parser<'a> { let inner_parse_policy = if permit_inner { InnerAttributeParsePolicy::Permitted } else { - InnerAttributeParsePolicy::NotPermitted - { reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG } + InnerAttributeParsePolicy::NotPermitted { + reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG, + saw_doc_comment: false, + prev_attr_sp: None + } }; self.parse_attribute_with_inner_parse_policy(inner_parse_policy) } @@ -98,19 +106,9 @@ impl<'a> Parser<'a> { if let InnerAttributeParsePolicy::Permitted = inner_parse_policy { self.expected_tokens.push(TokenType::Token(token::Not)); } + let style = if self.token == token::Not { self.bump(); - if let InnerAttributeParsePolicy::NotPermitted { reason } = inner_parse_policy - { - let span = self.token.span; - self.diagnostic() - .struct_span_err(span, reason) - .note("inner attributes, like `#![no_std]`, annotate the item \ - enclosing them, and are usually found at the beginning of \ - source files. Outer attributes, like `#[test]`, annotate the \ - item following them.") - .emit() - } ast::AttrStyle::Inner } else { ast::AttrStyle::Outer @@ -121,7 +119,38 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Bracket))?; let hi = self.prev_span; - (lo.to(hi), path, tokens, style) + let attr_sp = lo.to(hi); + + // Emit error if inner attribute is encountered and not permitted + if style == ast::AttrStyle::Inner { + if let InnerAttributeParsePolicy::NotPermitted { reason, + saw_doc_comment, prev_attr_sp } = inner_parse_policy { + let prev_attr_note = if saw_doc_comment { + "previous doc comment" + } else { + "previous outer attribute" + }; + + let mut diagnostic = self + .diagnostic() + .struct_span_err(attr_sp, reason); + + if let Some(prev_attr_sp) = prev_attr_sp { + diagnostic + .span_label(attr_sp, "not permitted following an outer attibute") + .span_label(prev_attr_sp, prev_attr_note); + } + + diagnostic + .note("inner attributes, like `#![no_std]`, annotate the item \ + enclosing them, and are usually found at the beginning of \ + source files. Outer attributes, like `#[test]`, annotate the \ + item following them.") + .emit() + } + } + + (attr_sp, path, tokens, style) } _ => { let token_str = self.this_token_to_string(); @@ -210,7 +239,7 @@ impl<'a> Parser<'a> { } token::DocComment(s) => { // we need to get the position of this token before we bump. - let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.token.span); + let attr = attr::mk_sugared_doc_attr(s, self.token.span); if attr.style == ast::AttrStyle::Inner { attrs.push(attr); self.bump(); @@ -226,7 +255,7 @@ impl<'a> Parser<'a> { fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> { let lit = self.parse_lit()?; - debug!("Checking if {:?} is unusuffixed.", lit); + debug!("checking if {:?} is unusuffixed", lit); if !lit.node.is_unsuffixed() { let msg = "suffixed literals are not allowed in attributes"; diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index 0ea0b2a694..730efb5ef0 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -2,6 +2,7 @@ use crate::ast::{ self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData, }; +use crate::feature_gate::{feature_err, UnstableFeatures}; use crate::parse::{SeqSep, PResult, Parser, ParseSess}; use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType}; use crate::parse::token::{self, TokenKind}; @@ -13,8 +14,9 @@ use crate::ThinVec; use crate::util::parser::AssocOp; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_data_structures::fx::FxHashSet; -use syntax_pos::{Span, DUMMY_SP, MultiSpan}; +use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError}; use log::{debug, trace}; +use std::mem; /// Creates a placeholder argument. crate fn dummy_arg(ident: Ident) -> Arg { @@ -28,7 +30,7 @@ crate fn dummy_arg(ident: Ident) -> Arg { span: ident.span, id: ast::DUMMY_NODE_ID }; - Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, ty: P(ty) } + Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, span: ident.span, ty: P(ty) } } pub enum Error { @@ -197,6 +199,10 @@ impl<'a> Parser<'a> { &self.sess.span_diagnostic } + crate fn span_to_snippet(&self, span: Span) -> Result { + self.sess.source_map().span_to_snippet(span) + } + crate fn expected_ident_found(&self) -> DiagnosticBuilder<'a> { let mut err = self.struct_span_err( self.token.span, @@ -325,8 +331,8 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Return) || self.token.is_keyword(kw::While) ); - let cm = self.sess.source_map(); - match (cm.lookup_line(self.token.span.lo()), cm.lookup_line(sp.lo())) { + let sm = self.sess.source_map(); + match (sm.lookup_line(self.token.span.lo()), sm.lookup_line(sp.lo())) { (Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => { // The spans are in different lines, expected `;` and found `let` or `return`. // High likelihood that it is only a missing `;`. @@ -364,9 +370,53 @@ impl<'a> Parser<'a> { err.span_label(self.token.span, "unexpected token"); } } + self.maybe_annotate_with_ascription(&mut err, false); Err(err) } + pub fn maybe_annotate_with_ascription( + &self, + err: &mut DiagnosticBuilder<'_>, + maybe_expected_semicolon: bool, + ) { + if let Some((sp, likely_path)) = self.last_type_ascription { + let sm = self.sess.source_map(); + let next_pos = sm.lookup_char_pos(self.token.span.lo()); + let op_pos = sm.lookup_char_pos(sp.hi()); + + if likely_path { + err.span_suggestion( + sp, + "maybe write a path separator here", + "::".to_string(), + match self.sess.unstable_features { + UnstableFeatures::Disallow => Applicability::MachineApplicable, + _ => Applicability::MaybeIncorrect, + }, + ); + } else if op_pos.line != next_pos.line && maybe_expected_semicolon { + err.span_suggestion( + sp, + "try using a semicolon", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } else if let UnstableFeatures::Disallow = self.sess.unstable_features { + err.span_label(sp, "tried to parse a type due to this"); + } else { + err.span_label(sp, "tried to parse a type due to this type ascription"); + } + if let UnstableFeatures::Disallow = self.sess.unstable_features { + // Give extra information about type ascription only if it's a nightly compiler. + } else { + err.note("`#![feature(type_ascription)]` lets you annotate an expression with a \ + type: `: `"); + err.note("for more information, see \ + https://github.com/rust-lang/rust/issues/23416"); + } + } + } + /// Eats and discards tokens until one of `kets` is encountered. Respects token trees, /// passes through any errors encountered. Used for error recovery. crate fn eat_to_tokens(&mut self, kets: &[&TokenKind]) { @@ -503,8 +553,10 @@ impl<'a> Parser<'a> { ExprKind::Binary(op, _, _) if op.node.is_comparison() => { // respan to include both operators let op_span = op.span.to(self.token.span); - let mut err = self.diagnostic().struct_span_err(op_span, - "chained comparison operators require parentheses"); + let mut err = self.struct_span_err( + op_span, + "chained comparison operators require parentheses", + ); if op.node == BinOpKind::Lt && *outer_op == AssocOp::Less || // Include `<` to provide this recommendation *outer_op == AssocOp::Greater // even in a case like the following: @@ -555,7 +607,7 @@ impl<'a> Parser<'a> { .collect::>(); if !discriminant_spans.is_empty() && has_fields { - let mut err = crate::feature_gate::feature_err( + let mut err = feature_err( sess, sym::arbitrary_enum_discriminant, discriminant_spans.clone(), @@ -611,14 +663,12 @@ impl<'a> Parser<'a> { match ty.node { TyKind::Rptr(ref lifetime, ref mut_ty) => { let sum_with_parens = pprust::to_string(|s| { - use crate::print::pprust::PrintState; - - s.s.word("&")?; - s.print_opt_lifetime(lifetime)?; - s.print_mutability(mut_ty.mutbl)?; - s.popen()?; - s.print_type(&mut_ty.ty)?; - s.print_type_bounds(" +", &bounds)?; + s.s.word("&"); + s.print_opt_lifetime(lifetime); + s.print_mutability(mut_ty.mutbl); + s.popen(); + s.print_type(&mut_ty.ty); + s.print_type_bounds(" +", &bounds); s.pclose() }); err.span_suggestion( @@ -673,8 +723,6 @@ impl<'a> Parser<'a> { path.span = ty_span.to(self.prev_span); let ty_str = self - .sess - .source_map() .span_to_snippet(ty_span) .unwrap_or_else(|_| pprust::ty_to_string(&ty)); self.diagnostic() @@ -770,8 +818,8 @@ impl<'a> Parser<'a> { return Ok(recovered); } } - let cm = self.sess.source_map(); - match (cm.lookup_line(prev_sp.lo()), cm.lookup_line(sp.lo())) { + let sm = self.sess.source_map(); + match (sm.lookup_line(prev_sp.lo()), sm.lookup_line(sp.lo())) { (Ok(ref a), Ok(ref b)) if a.line == b.line => { // When the spans are in the same line, it means that the only content // between them is whitespace, point only at the found token. @@ -785,13 +833,59 @@ impl<'a> Parser<'a> { Err(err) } - /// Consume alternative await syntaxes like `await `, `await? `, `await()` - /// and `await { }`. + crate fn parse_semi_or_incorrect_foreign_fn_body( + &mut self, + ident: &Ident, + extern_sp: Span, + ) -> PResult<'a, ()> { + if self.token != token::Semi { + // this might be an incorrect fn definition (#62109) + let parser_snapshot = self.clone(); + match self.parse_inner_attrs_and_block() { + Ok((_, body)) => { + self.struct_span_err(ident.span, "incorrect `fn` inside `extern` block") + .span_label(ident.span, "can't have a body") + .span_label(body.span, "this body is invalid here") + .span_label( + extern_sp, + "`extern` blocks define existing foreign functions and `fn`s \ + inside of them cannot have a body") + .help("you might have meant to write a function accessible through ffi, \ + which can be done by writing `extern fn` outside of the \ + `extern` block") + .note("for more information, visit \ + https://doc.rust-lang.org/std/keyword.extern.html") + .emit(); + } + Err(mut err) => { + err.cancel(); + mem::replace(self, parser_snapshot); + self.expect(&token::Semi)?; + } + } + } else { + self.bump(); + } + Ok(()) + } + + /// Consume alternative await syntaxes like `await!()`, `await `, + /// `await? `, `await()`, and `await { }`. crate fn parse_incorrect_await_syntax( &mut self, lo: Span, await_sp: Span, ) -> PResult<'a, (Span, ExprKind)> { + if self.token == token::Not { + // Handle `await!()`. + self.expect(&token::Not)?; + self.expect(&token::OpenDelim(token::Paren))?; + let expr = self.parse_expr()?; + self.expect(&token::CloseDelim(token::Paren))?; + let sp = self.error_on_incorrect_await(lo, self.prev_span, &expr, false); + return Ok((sp, ExprKind::Await(expr))) + } + let is_question = self.eat(&token::Question); // Handle `await? `. let expr = if self.token == token::OpenDelim(token::Brace) { // Handle `await { }`. @@ -809,10 +903,15 @@ impl<'a> Parser<'a> { err.span_label(await_sp, "while parsing this incorrect await expression"); err })?; - let expr_str = self.sess.source_map().span_to_snippet(expr.span) + let sp = self.error_on_incorrect_await(lo, expr.span, &expr, is_question); + Ok((sp, ExprKind::Await(expr))) + } + + fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span { + let expr_str = self.span_to_snippet(expr.span) .unwrap_or_else(|_| pprust::expr_to_string(&expr)); let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" }); - let sp = lo.to(expr.span); + let sp = lo.to(hi); let app = match expr.node { ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await ?` _ => Applicability::MachineApplicable, @@ -820,7 +919,7 @@ impl<'a> Parser<'a> { self.struct_span_err(sp, "incorrect use of `await`") .span_suggestion(sp, "`await` is a postfix operation", suggestion, app) .emit(); - Ok((sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr))) + sp } /// If encountering `future.await()`, consume and emit error. @@ -843,6 +942,48 @@ impl<'a> Parser<'a> { } } + /// Recover a situation like `for ( $pat in $expr )` + /// and suggest writing `for $pat in $expr` instead. + /// + /// This should be called before parsing the `$block`. + crate fn recover_parens_around_for_head( + &mut self, + pat: P, + expr: &Expr, + begin_paren: Option, + ) -> P { + match (&self.token.kind, begin_paren) { + (token::CloseDelim(token::Paren), Some(begin_par_sp)) => { + self.bump(); + + let pat_str = self + // Remove the `(` from the span of the pattern: + .span_to_snippet(pat.span.trim_start(begin_par_sp).unwrap()) + .unwrap_or_else(|_| pprust::pat_to_string(&pat)); + + self.struct_span_err(self.prev_span, "unexpected closing `)`") + .span_label(begin_par_sp, "opening `(`") + .span_suggestion( + begin_par_sp.to(self.prev_span), + "remove parenthesis in `for` loop", + format!("{} in {}", pat_str, pprust::expr_to_string(&expr)), + // With e.g. `for (x) in y)` this would replace `(x) in y)` + // with `x) in y)` which is syntactically invalid. + // However, this is prevented before we get here. + Applicability::MachineApplicable, + ) + .emit(); + + // Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint. + pat.and_then(|pat| match pat.node { + PatKind::Paren(pat) => pat, + _ => P(pat), + }) + } + _ => pat, + } + } + crate fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { self.token.is_ident() && if let ast::ExprKind::Path(..) = node { true } else { false } && @@ -852,47 +993,9 @@ impl<'a> Parser<'a> { self.look_ahead(2, |t| t.is_ident()) || self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz` self.look_ahead(2, |t| t.is_ident()) || - self.look_ahead(1, |t| t == &token::ModSep) && // `foo:bar::baz` - self.look_ahead(2, |t| t.is_ident()) - } - - crate fn bad_type_ascription( - &self, - err: &mut DiagnosticBuilder<'a>, - lhs_span: Span, - cur_op_span: Span, - next_sp: Span, - maybe_path: bool, - ) { - err.span_label(self.token.span, "expecting a type here because of type ascription"); - let cm = self.sess.source_map(); - let next_pos = cm.lookup_char_pos(next_sp.lo()); - let op_pos = cm.lookup_char_pos(cur_op_span.hi()); - if op_pos.line != next_pos.line { - err.span_suggestion( - cur_op_span, - "try using a semicolon", - ";".to_string(), - Applicability::MaybeIncorrect, - ); - } else { - if maybe_path { - err.span_suggestion( - cur_op_span, - "maybe you meant to write a path separator here", - "::".to_string(), - Applicability::MaybeIncorrect, - ); - } else { - err.note("#![feature(type_ascription)] lets you annotate an \ - expression with a type: `: `") - .span_note( - lhs_span, - "this expression expects an ascribed type after the colon", - ) - .help("this might be indicative of a syntax error elsewhere"); - } - } + self.look_ahead(1, |t| t == &token::ModSep) && + (self.look_ahead(2, |t| t.is_ident()) || // `foo:bar::baz` + self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::` } crate fn recover_seq_parse_error( @@ -1063,17 +1166,14 @@ impl<'a> Parser<'a> { crate fn check_for_for_in_in_typo(&mut self, in_span: Span) { if self.eat_keyword(kw::In) { // a common typo: `for _ in in bar {}` - let mut err = self.sess.span_diagnostic.struct_span_err( - self.prev_span, - "expected iterable, found keyword `in`", - ); - err.span_suggestion_short( - in_span.until(self.prev_span), - "remove the duplicated `in`", - String::new(), - Applicability::MachineApplicable, - ); - err.emit(); + self.struct_span_err(self.prev_span, "expected iterable, found keyword `in`") + .span_suggestion_short( + in_span.until(self.prev_span), + "remove the duplicated `in`", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); } } @@ -1086,12 +1186,12 @@ impl<'a> Parser<'a> { crate fn eat_incorrect_doc_comment_for_arg_type(&mut self) { if let token::DocComment(_) = self.token.kind { - let mut err = self.diagnostic().struct_span_err( + self.struct_span_err( self.token.span, "documentation comments cannot be applied to a function parameter's type", - ); - err.span_label(self.token.span, "doc comments are not allowed here"); - err.emit(); + ) + .span_label(self.token.span, "doc comments are not allowed here") + .emit(); self.bump(); } else if self.token == token::Pound && self.look_ahead(1, |t| { *t == token::OpenDelim(token::Bracket) @@ -1103,12 +1203,12 @@ impl<'a> Parser<'a> { } let sp = lo.to(self.token.span); self.bump(); - let mut err = self.diagnostic().struct_span_err( + self.struct_span_err( sp, "attributes cannot be applied to a function parameter's type", - ); - err.span_label(sp, "attributes are not allowed here"); - err.emit(); + ) + .span_label(sp, "attributes are not allowed here") + .emit(); } } @@ -1164,18 +1264,19 @@ impl<'a> Parser<'a> { self.expect(&token::Colon)?; let ty = self.parse_ty()?; - let mut err = self.diagnostic().struct_span_err_with_code( - pat.span, - "patterns aren't allowed in methods without bodies", - DiagnosticId::Error("E0642".into()), - ); - err.span_suggestion_short( - pat.span, - "give this argument a name or use an underscore to ignore it", - "_".to_owned(), - Applicability::MachineApplicable, - ); - err.emit(); + self.diagnostic() + .struct_span_err_with_code( + pat.span, + "patterns aren't allowed in methods without bodies", + DiagnosticId::Error("E0642".into()), + ) + .span_suggestion_short( + pat.span, + "give this argument a name or use an underscore to ignore it", + "_".to_owned(), + Applicability::MachineApplicable, + ) + .emit(); // Pretend the pattern is `_`, to avoid duplicate errors from AST validation. let pat = P(Pat { diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index 97d3fc002e..5121a9ef7b 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -2,15 +2,16 @@ pub use CommentStyle::*; use crate::ast; use crate::source_map::SourceMap; -use crate::parse::lexer::{is_block_doc_comment, is_pattern_whitespace}; -use crate::parse::lexer::{self, ParseSess, StringReader}; +use crate::parse::lexer::is_block_doc_comment; +use crate::parse::lexer::ParseSess; use syntax_pos::{BytePos, CharPos, Pos, FileName}; -use log::debug; -use std::io::Read; use std::usize; +#[cfg(test)] +mod tests; + #[derive(Clone, Copy, PartialEq, Debug)] pub enum CommentStyle { /// No code on either side of each line of the comment @@ -136,66 +137,6 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String { panic!("not a doc-comment: {}", comment); } -fn push_blank_line_comment(rdr: &StringReader<'_>, comments: &mut Vec) { - debug!(">>> blank-line comment"); - comments.push(Comment { - style: BlankLine, - lines: Vec::new(), - pos: rdr.pos, - }); -} - -fn consume_whitespace_counting_blank_lines( - rdr: &mut StringReader<'_>, - comments: &mut Vec -) { - while is_pattern_whitespace(rdr.ch) && !rdr.is_eof() { - if rdr.ch_is('\n') { - push_blank_line_comment(rdr, &mut *comments); - } - rdr.bump(); - } -} - -fn read_shebang_comment(rdr: &mut StringReader<'_>, - code_to_the_left: bool, - comments: &mut Vec) { - debug!(">>> shebang comment"); - let p = rdr.pos; - debug!("<<< shebang comment"); - comments.push(Comment { - style: if code_to_the_left { Trailing } else { Isolated }, - lines: vec![rdr.read_one_line_comment()], - pos: p, - }); -} - -fn read_line_comments(rdr: &mut StringReader<'_>, - code_to_the_left: bool, - comments: &mut Vec) { - debug!(">>> line comments"); - let p = rdr.pos; - let mut lines: Vec = Vec::new(); - while rdr.ch_is('/') && rdr.nextch_is('/') { - let line = rdr.read_one_line_comment(); - debug!("{}", line); - // Doc comments are not put in comments. - if is_doc_comment(&line[..]) { - break; - } - lines.push(line); - rdr.consume_non_eol_whitespace(); - } - debug!("<<< line comments"); - if !lines.is_empty() { - comments.push(Comment { - style: if code_to_the_left { Trailing } else { Isolated }, - lines, - pos: p, - }); - } -} - /// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. /// Otherwise returns `Some(k)` where `k` is first char offset after that leading /// whitespace. Note that `k` may be outside bounds of `s`. @@ -210,224 +151,104 @@ fn all_whitespace(s: &str, col: CharPos) -> Option { Some(idx) } -fn trim_whitespace_prefix_and_push_line(lines: &mut Vec, s: String, col: CharPos) { +fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str { let len = s.len(); - let s1 = match all_whitespace(&s[..], col) { - Some(col) => { - if col < len { - s[col..len].to_string() - } else { - String::new() - } - } + match all_whitespace(&s, col) { + Some(col) => if col < len { &s[col..] } else { "" }, None => s, - }; - debug!("pushing line: {}", s1); - lines.push(s1); -} - -fn read_block_comment(rdr: &mut StringReader<'_>, - code_to_the_left: bool, - comments: &mut Vec) { - debug!(">>> block comment"); - let p = rdr.pos; - let mut lines: Vec = Vec::new(); - - // Count the number of chars since the start of the line by rescanning. - let src_index = rdr.src_index(rdr.source_file.line_begin_pos(rdr.pos)); - let end_src_index = rdr.src_index(rdr.pos); - assert!(src_index <= end_src_index, - "src_index={}, end_src_index={}, line_begin_pos={}", - src_index, end_src_index, rdr.source_file.line_begin_pos(rdr.pos).to_u32()); - - let col = CharPos(rdr.src[src_index..end_src_index].chars().count()); - - rdr.bump(); - rdr.bump(); - - let mut curr_line = String::from("/*"); - - // doc-comments are not really comments, they are attributes - if (rdr.ch_is('*') && !rdr.nextch_is('*')) || rdr.ch_is('!') { - while !(rdr.ch_is('*') && rdr.nextch_is('/')) && !rdr.is_eof() { - curr_line.push(rdr.ch.unwrap()); - rdr.bump(); - } - if !rdr.is_eof() { - curr_line.push_str("*/"); - rdr.bump(); - rdr.bump(); - } - if is_block_doc_comment(&curr_line[..]) { - return; - } - assert!(!curr_line.contains('\n')); - lines.push(curr_line); - } else { - let mut level: isize = 1; - while level > 0 { - debug!("=== block comment level {}", level); - if rdr.is_eof() { - rdr.fatal("unterminated block comment").raise(); - } - if rdr.ch_is('\n') { - trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col); - curr_line = String::new(); - rdr.bump(); - } else { - curr_line.push(rdr.ch.unwrap()); - if rdr.ch_is('/') && rdr.nextch_is('*') { - rdr.bump(); - rdr.bump(); - curr_line.push('*'); - level += 1; - } else { - if rdr.ch_is('*') && rdr.nextch_is('/') { - rdr.bump(); - rdr.bump(); - curr_line.push('/'); - level -= 1; - } else { - rdr.bump(); - } - } - } - } - if !curr_line.is_empty() { - trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col); - } } - - let mut style = if code_to_the_left { - Trailing - } else { - Isolated - }; - rdr.consume_non_eol_whitespace(); - if !rdr.is_eof() && !rdr.ch_is('\n') && lines.len() == 1 { - style = Mixed; - } - debug!("<<< block comment"); - comments.push(Comment { - style, - lines, - pos: p, - }); } - -fn consume_comment(rdr: &mut StringReader<'_>, - comments: &mut Vec, - code_to_the_left: &mut bool, - anything_to_the_left: &mut bool) { - debug!(">>> consume comment"); - if rdr.ch_is('/') && rdr.nextch_is('/') { - read_line_comments(rdr, *code_to_the_left, comments); - *code_to_the_left = false; - *anything_to_the_left = false; - } else if rdr.ch_is('/') && rdr.nextch_is('*') { - read_block_comment(rdr, *code_to_the_left, comments); - *anything_to_the_left = true; - } else if rdr.ch_is('#') && rdr.nextch_is('!') { - read_shebang_comment(rdr, *code_to_the_left, comments); - *code_to_the_left = false; - *anything_to_the_left = false; - } else { - panic!(); - } - debug!("<<< consume comment"); +fn split_block_comment_into_lines( + text: &str, + col: CharPos, +) -> Vec { + let mut res: Vec = vec![]; + let mut lines = text.lines(); + // just push the first line + res.extend(lines.next().map(|it| it.to_string())); + // for other lines, strip common whitespace prefix + for line in lines { + res.push(trim_whitespace_prefix(line, col).to_string()) + } + res } // it appears this function is called only from pprust... that's // probably not a good thing. -pub fn gather_comments(sess: &ParseSess, path: FileName, srdr: &mut dyn Read) -> Vec -{ - let mut src = String::new(); - srdr.read_to_string(&mut src).unwrap(); +pub fn gather_comments(sess: &ParseSess, path: FileName, src: String) -> Vec { let cm = SourceMap::new(sess.source_map().path_mapping().clone()); let source_file = cm.new_source_file(path, src); - let mut rdr = lexer::StringReader::new_raw(sess, source_file, None); + let text = (*source_file.src.as_ref().unwrap()).clone(); + let text: &str = text.as_str(); + let start_bpos = source_file.start_pos; + let mut pos = 0; let mut comments: Vec = Vec::new(); - let mut code_to_the_left = false; // Only code - let mut anything_to_the_left = false; // Code or comments + let mut code_to_the_left = false; - while !rdr.is_eof() { - loop { - // Eat all the whitespace and count blank lines. - rdr.consume_non_eol_whitespace(); - if rdr.ch_is('\n') { - if anything_to_the_left { - rdr.bump(); // The line is not blank, do not count. + if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { + comments.push(Comment { + style: Isolated, + lines: vec![text[..shebang_len].to_string()], + pos: start_bpos, + }); + pos += shebang_len; + } + + for token in rustc_lexer::tokenize(&text[pos..]) { + let token_text = &text[pos..pos + token.len]; + match token.kind { + rustc_lexer::TokenKind::Whitespace => { + if let Some(mut idx) = token_text.find('\n') { + code_to_the_left = false; + while let Some(next_newline) = &token_text[idx + 1..].find('\n') { + idx = idx + 1 + next_newline; + comments.push(Comment { + style: BlankLine, + lines: vec![], + pos: start_bpos + BytePos((pos + idx) as u32), + }); + } + } + } + rustc_lexer::TokenKind::BlockComment { terminated: _ } => { + if !is_block_doc_comment(token_text) { + let code_to_the_right = match text[pos + token.len..].chars().next() { + Some('\r') | Some('\n') => false, + _ => true, + }; + let style = match (code_to_the_left, code_to_the_right) { + (true, true) | (false, true) => Mixed, + (false, false) => Isolated, + (true, false) => Trailing, + }; + + // Count the number of chars since the start of the line by rescanning. + let pos_in_file = start_bpos + BytePos(pos as u32); + let line_begin_in_file = source_file.line_begin_pos(pos_in_file); + let line_begin_pos = (line_begin_in_file - start_bpos).to_usize(); + let col = CharPos(text[line_begin_pos..pos].chars().count()); + + let lines = split_block_comment_into_lines(token_text, col); + comments.push(Comment { style, lines, pos: pos_in_file }) } - consume_whitespace_counting_blank_lines(&mut rdr, &mut comments); - code_to_the_left = false; - anything_to_the_left = false; } - // Eat one comment group - if rdr.peeking_at_comment() { - consume_comment(&mut rdr, &mut comments, - &mut code_to_the_left, &mut anything_to_the_left); - } else { - break + rustc_lexer::TokenKind::LineComment => { + if !is_doc_comment(token_text) { + comments.push(Comment { + style: if code_to_the_left { Trailing } else { Isolated }, + lines: vec![token_text.to_string()], + pos: start_bpos + BytePos(pos as u32), + }) + } + } + _ => { + code_to_the_left = true; } } - - rdr.next_token(); - code_to_the_left = true; - anything_to_the_left = true; + pos += token.len; } comments } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_block_doc_comment_1() { - let comment = "/**\n * Test \n ** Test\n * Test\n*/"; - let stripped = strip_doc_comment_decoration(comment); - assert_eq!(stripped, " Test \n* Test\n Test"); - } - - #[test] - fn test_block_doc_comment_2() { - let comment = "/**\n * Test\n * Test\n*/"; - let stripped = strip_doc_comment_decoration(comment); - assert_eq!(stripped, " Test\n Test"); - } - - #[test] - fn test_block_doc_comment_3() { - let comment = "/**\n let a: *i32;\n *a = 5;\n*/"; - let stripped = strip_doc_comment_decoration(comment); - assert_eq!(stripped, " let a: *i32;\n *a = 5;"); - } - - #[test] - fn test_block_doc_comment_4() { - let comment = "/*******************\n test\n *********************/"; - let stripped = strip_doc_comment_decoration(comment); - assert_eq!(stripped, " test"); - } - - #[test] - fn test_line_doc_comment() { - let stripped = strip_doc_comment_decoration("/// test"); - assert_eq!(stripped, " test"); - let stripped = strip_doc_comment_decoration("///! test"); - assert_eq!(stripped, " test"); - let stripped = strip_doc_comment_decoration("// test"); - assert_eq!(stripped, " test"); - let stripped = strip_doc_comment_decoration("// test"); - assert_eq!(stripped, " test"); - let stripped = strip_doc_comment_decoration("///test"); - assert_eq!(stripped, "test"); - let stripped = strip_doc_comment_decoration("///!test"); - assert_eq!(stripped, "test"); - let stripped = strip_doc_comment_decoration("//test"); - assert_eq!(stripped, "test"); - } -} diff --git a/src/libsyntax/parse/lexer/comments/tests.rs b/src/libsyntax/parse/lexer/comments/tests.rs new file mode 100644 index 0000000000..f9cd69fb50 --- /dev/null +++ b/src/libsyntax/parse/lexer/comments/tests.rs @@ -0,0 +1,47 @@ +use super::*; + +#[test] +fn test_block_doc_comment_1() { + let comment = "/**\n * Test \n ** Test\n * Test\n*/"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped, " Test \n* Test\n Test"); +} + +#[test] +fn test_block_doc_comment_2() { + let comment = "/**\n * Test\n * Test\n*/"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped, " Test\n Test"); +} + +#[test] +fn test_block_doc_comment_3() { + let comment = "/**\n let a: *i32;\n *a = 5;\n*/"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped, " let a: *i32;\n *a = 5;"); +} + +#[test] +fn test_block_doc_comment_4() { + let comment = "/*******************\n test\n *********************/"; + let stripped = strip_doc_comment_decoration(comment); + assert_eq!(stripped, " test"); +} + +#[test] +fn test_line_doc_comment() { + let stripped = strip_doc_comment_decoration("/// test"); + assert_eq!(stripped, " test"); + let stripped = strip_doc_comment_decoration("///! test"); + assert_eq!(stripped, " test"); + let stripped = strip_doc_comment_decoration("// test"); + assert_eq!(stripped, " test"); + let stripped = strip_doc_comment_decoration("// test"); + assert_eq!(stripped, " test"); + let stripped = strip_doc_comment_decoration("///test"); + assert_eq!(stripped, "test"); + let stripped = strip_doc_comment_decoration("///!test"); + assert_eq!(stripped, "test"); + let stripped = strip_doc_comment_decoration("//test"); + assert_eq!(stripped, "test"); +} diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4e4fe4256c..e86d4c7fde 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1,19 +1,23 @@ use crate::parse::ParseSess; use crate::parse::token::{self, Token, TokenKind}; use crate::symbol::{sym, Symbol}; -use crate::parse::unescape; use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char}; -use errors::{FatalError, Diagnostic, DiagnosticBuilder}; +use errors::{FatalError, DiagnosticBuilder}; use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION}; -use core::unicode::property::Pattern_White_Space; +use rustc_lexer::Base; +use rustc_lexer::unescape; use std::borrow::Cow; use std::char; use std::iter; +use std::convert::TryInto; use rustc_data_structures::sync::Lrc; use log::debug; +#[cfg(test)] +mod tests; + pub mod comments; mod tokentrees; mod unicode_chars; @@ -28,159 +32,22 @@ pub struct UnmatchedBrace { } pub struct StringReader<'a> { - crate sess: &'a ParseSess, - /// The absolute offset within the source_map of the next character to read - crate next_pos: BytePos, - /// The absolute offset within the source_map of the current character - crate pos: BytePos, - /// The current character (which has been read from self.pos) - crate ch: Option, - crate source_file: Lrc, + sess: &'a ParseSess, + /// Initial position, read-only. + start_pos: BytePos, + /// The absolute offset within the source_map of the current character. + pos: BytePos, /// Stop reading src at this index. - crate end_src_index: usize, - // cached: - peek_token: Token, - peek_span_src_raw: Span, - fatal_errs: Vec>, - // cache a direct reference to the source text, so that we don't have to - // retrieve it via `self.source_file.src.as_ref().unwrap()` all the time. + end_src_index: usize, + /// Source text to tokenize. src: Lrc, override_span: Option, } impl<'a> StringReader<'a> { - fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span { - self.mk_sp_and_raw(lo, hi).0 - } - - fn mk_sp_and_raw(&self, lo: BytePos, hi: BytePos) -> (Span, Span) { - let raw = Span::new(lo, hi, NO_EXPANSION); - let real = self.override_span.unwrap_or(raw); - - (real, raw) - } - - fn unwrap_or_abort(&mut self, res: Result) -> Token { - match res { - Ok(tok) => tok, - Err(_) => { - self.emit_fatal_errors(); - FatalError.raise(); - } - } - } - - fn next_token(&mut self) -> Token where Self: Sized { - let res = self.try_next_token(); - self.unwrap_or_abort(res) - } - - /// Returns the next token. EFFECT: advances the string_reader. - pub fn try_next_token(&mut self) -> Result { - assert!(self.fatal_errs.is_empty()); - let ret_val = self.peek_token.take(); - self.advance_token()?; - Ok(ret_val) - } - - /// Immutably extract string if found at current position with given delimiters - fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option { - let mut pos = self.pos; - let mut idx = self.src_index(pos); - let mut ch = char_at(&self.src, idx); - if ch != from_ch { - return None; - } - pos = pos + Pos::from_usize(ch.len_utf8()); - let start_pos = pos; - idx = self.src_index(pos); - while idx < self.end_src_index { - ch = char_at(&self.src, idx); - if ch == to_ch { - return Some(self.src[self.src_index(start_pos)..self.src_index(pos)].to_string()); - } - pos = pos + Pos::from_usize(ch.len_utf8()); - idx = self.src_index(pos); - } - return None; - } - - fn try_real_token(&mut self) -> Result { - let mut t = self.try_next_token()?; - loop { - match t.kind { - token::Whitespace | token::Comment | token::Shebang(_) => { - t = self.try_next_token()?; - } - _ => break, - } - } - - Ok(t) - } - - pub fn real_token(&mut self) -> Token { - let res = self.try_real_token(); - self.unwrap_or_abort(res) - } - - #[inline] - fn is_eof(&self) -> bool { - self.ch.is_none() - } - - fn fail_unterminated_raw_string(&self, pos: BytePos, hash_count: u16) -> ! { - let mut err = self.struct_span_fatal(pos, pos, "unterminated raw string"); - err.span_label(self.mk_sp(pos, pos), "unterminated raw string"); - - if hash_count > 0 { - err.note(&format!("this raw string should be terminated with `\"{}`", - "#".repeat(hash_count as usize))); - } - - err.emit(); - FatalError.raise(); - } - - fn fatal(&self, m: &str) -> FatalError { - self.fatal_span(self.peek_token.span, m) - } - - crate fn emit_fatal_errors(&mut self) { - for err in &mut self.fatal_errs { - err.emit(); - } - - self.fatal_errs.clear(); - } - - pub fn buffer_fatal_errors(&mut self) -> Vec { - let mut buffer = Vec::new(); - - for err in self.fatal_errs.drain(..) { - err.buffer(&mut buffer); - } - - buffer - } - - pub fn peek(&self) -> &Token { - &self.peek_token - } - - /// For comments.rs, which hackily pokes into next_pos and ch - fn new_raw(sess: &'a ParseSess, + pub fn new(sess: &'a ParseSess, source_file: Lrc, override_span: Option) -> Self { - let mut sr = StringReader::new_raw_internal(sess, source_file, override_span); - sr.bump(); - - sr - } - - fn new_raw_internal(sess: &'a ParseSess, source_file: Lrc, - override_span: Option) -> Self - { if source_file.src.is_none() { sess.span_diagnostic.bug(&format!("Cannot lex source_file without source: {}", source_file.name)); @@ -190,30 +57,14 @@ impl<'a> StringReader<'a> { StringReader { sess, - next_pos: source_file.start_pos, + start_pos: source_file.start_pos, pos: source_file.start_pos, - ch: Some('\n'), - source_file, end_src_index: src.len(), - peek_token: Token::dummy(), - peek_span_src_raw: syntax_pos::DUMMY_SP, src, - fatal_errs: Vec::new(), override_span, } } - pub fn new_or_buffered_errs(sess: &'a ParseSess, - source_file: Lrc, - override_span: Option) -> Result> { - let mut sr = StringReader::new_raw(sess, source_file, override_span); - if sr.advance_token().is_err() { - Err(sr.buffer_fatal_errors()) - } else { - Ok(sr) - } - } - pub fn retokenize(sess: &'a ParseSess, mut span: Span) -> Self { let begin = sess.source_map().lookup_byte_offset(span.lo()); let end = sess.source_map().lookup_byte_offset(span.hi()); @@ -223,25 +74,61 @@ impl<'a> StringReader<'a> { span = span.shrink_to_lo(); } - let mut sr = StringReader::new_raw_internal(sess, begin.sf, None); + let mut sr = StringReader::new(sess, begin.sf, None); // Seek the lexer to the right byte range. - sr.next_pos = span.lo(); sr.end_src_index = sr.src_index(span.hi()); - sr.bump(); + sr + } - if sr.advance_token().is_err() { - sr.emit_fatal_errors(); - FatalError.raise(); - } - sr + fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span { + self.override_span.unwrap_or_else(|| Span::new(lo, hi, NO_EXPANSION)) } - #[inline] - fn ch_is(&self, c: char) -> bool { - self.ch == Some(c) + /// Returns the next token, including trivia like whitespace or comments. + /// + /// `Err(())` means that some errors were encountered, which can be + /// retrieved using `buffer_fatal_errors`. + pub fn next_token(&mut self) -> Token { + let start_src_index = self.src_index(self.pos); + let text: &str = &self.src[start_src_index..self.end_src_index]; + + if text.is_empty() { + let span = self.mk_sp(self.pos, self.pos); + return Token::new(token::Eof, span); + } + + { + let is_beginning_of_file = self.pos == self.start_pos; + if is_beginning_of_file { + if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { + let start = self.pos; + self.pos = self.pos + BytePos::from_usize(shebang_len); + + let sym = self.symbol_from(start + BytePos::from_usize("#!".len())); + let kind = token::Shebang(sym); + + let span = self.mk_sp(start, self.pos); + return Token::new(kind, span); + } + } + } + + let token = rustc_lexer::first_token(text); + + let start = self.pos; + self.pos = self.pos + BytePos::from_usize(token.len); + + debug!("try_next_token: {:?}({:?})", token.kind, self.str_from(start)); + + // This could use `?`, but that makes code significantly (10-20%) slower. + // https://github.com/rust-lang/rust/issues/37939 + let kind = self.cook_lexer_token(token.kind, start); + + let span = self.mk_sp(start, self.pos); + Token::new(kind, span) } /// Report a fatal lexical error with a given span. @@ -265,16 +152,6 @@ impl<'a> StringReader<'a> { self.err_span(self.mk_sp(from_pos, to_pos), m) } - /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an - /// escaped character to the error message - fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> FatalError { - let mut m = m.to_string(); - m.push_str(": "); - push_escaped_char(&mut m, c); - - self.fatal_span_(from_pos, to_pos, &m[..]) - } - fn struct_span_fatal(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> DiagnosticBuilder<'a> { @@ -291,33 +168,327 @@ impl<'a> StringReader<'a> { self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..]) } - /// Advance peek_token to refer to the next token, and - /// possibly update the interner. - fn advance_token(&mut self) -> Result<(), ()> { - match self.scan_whitespace_or_comment() { - Some(comment) => { - self.peek_span_src_raw = comment.span; - self.peek_token = comment; + /// Turns simple `rustc_lexer::TokenKind` enum into a rich + /// `libsyntax::TokenKind`. This turns strings into interned + /// symbols and runs additional validation. + fn cook_lexer_token( + &self, + token: rustc_lexer::TokenKind, + start: BytePos, + ) -> TokenKind { + match token { + rustc_lexer::TokenKind::LineComment => { + let string = self.str_from(start); + // comments with only more "/"s are not doc comments + let tok = if is_doc_comment(string) { + let mut idx = 0; + loop { + idx = match string[idx..].find('\r') { + None => break, + Some(it) => idx + it + 1 + }; + if string[idx..].chars().next() != Some('\n') { + self.err_span_(start + BytePos(idx as u32 - 1), + start + BytePos(idx as u32), + "bare CR not allowed in doc-comment"); + } + } + token::DocComment(Symbol::intern(string)) + } else { + token::Comment + }; + + tok + } + rustc_lexer::TokenKind::BlockComment { terminated } => { + let string = self.str_from(start); + // block comments starting with "/**" or "/*!" are doc-comments + // but comments with only "*"s between two "/"s are not + let is_doc_comment = is_block_doc_comment(string); + + if !terminated { + let msg = if is_doc_comment { + "unterminated block doc-comment" + } else { + "unterminated block comment" + }; + let last_bpos = self.pos; + self.fatal_span_(start, last_bpos, msg).raise(); + } + + let tok = if is_doc_comment { + let has_cr = string.contains('\r'); + let string = if has_cr { + self.translate_crlf(start, + string, + "bare CR not allowed in block doc-comment") + } else { + string.into() + }; + token::DocComment(Symbol::intern(&string[..])) + } else { + token::Comment + }; + + tok } - None => { - let (kind, start_pos, end_pos) = if self.is_eof() { - (token::Eof, self.source_file.end_pos, self.source_file.end_pos) + rustc_lexer::TokenKind::Whitespace => token::Whitespace, + rustc_lexer::TokenKind::Ident | rustc_lexer::TokenKind::RawIdent => { + let is_raw_ident = token == rustc_lexer::TokenKind::RawIdent; + let mut ident_start = start; + if is_raw_ident { + ident_start = ident_start + BytePos(2); + } + // FIXME: perform NFKC normalization here. (Issue #2253) + let sym = self.symbol_from(ident_start); + if is_raw_ident { + let span = self.mk_sp(start, self.pos); + if !sym.can_be_raw() { + self.err_span(span, &format!("`{}` cannot be a raw identifier", sym)); + } + self.sess.raw_identifier_spans.borrow_mut().push(span); + } + token::Ident(sym, is_raw_ident) + } + rustc_lexer::TokenKind::Literal { kind, suffix_start } => { + let suffix_start = start + BytePos(suffix_start as u32); + let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind); + let suffix = if suffix_start < self.pos { + let string = self.str_from(suffix_start); + if string == "_" { + self.sess.span_diagnostic + .struct_span_warn(self.mk_sp(suffix_start, self.pos), + "underscore literal suffix is not allowed") + .warn("this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!") + .note("for more information, see issue #42326 \ + ") + .emit(); + None + } else { + Some(Symbol::intern(string)) + } } else { - let start_pos = self.pos; - (self.next_token_inner()?, start_pos, self.pos) + None }; - let (real, raw) = self.mk_sp_and_raw(start_pos, end_pos); - self.peek_token = Token::new(kind, real); - self.peek_span_src_raw = raw; + token::Literal(token::Lit { kind, symbol, suffix }) + } + rustc_lexer::TokenKind::Lifetime { starts_with_number } => { + // Include the leading `'` in the real identifier, for macro + // expansion purposes. See #12512 for the gory details of why + // this is necessary. + let lifetime_name = self.str_from(start); + if starts_with_number { + self.err_span_( + start, + self.pos, + "lifetimes cannot start with a number", + ); + } + let ident = Symbol::intern(lifetime_name); + token::Lifetime(ident) + } + rustc_lexer::TokenKind::Semi => token::Semi, + rustc_lexer::TokenKind::Comma => token::Comma, + rustc_lexer::TokenKind::DotDotDot => token::DotDotDot, + rustc_lexer::TokenKind::DotDotEq => token::DotDotEq, + rustc_lexer::TokenKind::DotDot => token::DotDot, + rustc_lexer::TokenKind::Dot => token::Dot, + rustc_lexer::TokenKind::OpenParen => token::OpenDelim(token::Paren), + rustc_lexer::TokenKind::CloseParen => token::CloseDelim(token::Paren), + rustc_lexer::TokenKind::OpenBrace => token::OpenDelim(token::Brace), + rustc_lexer::TokenKind::CloseBrace => token::CloseDelim(token::Brace), + rustc_lexer::TokenKind::OpenBracket => token::OpenDelim(token::Bracket), + rustc_lexer::TokenKind::CloseBracket => token::CloseDelim(token::Bracket), + rustc_lexer::TokenKind::At => token::At, + rustc_lexer::TokenKind::Pound => token::Pound, + rustc_lexer::TokenKind::Tilde => token::Tilde, + rustc_lexer::TokenKind::Question => token::Question, + rustc_lexer::TokenKind::ColonColon => token::ModSep, + rustc_lexer::TokenKind::Colon => token::Colon, + rustc_lexer::TokenKind::Dollar => token::Dollar, + rustc_lexer::TokenKind::EqEq => token::EqEq, + rustc_lexer::TokenKind::Eq => token::Eq, + rustc_lexer::TokenKind::FatArrow => token::FatArrow, + rustc_lexer::TokenKind::Ne => token::Ne, + rustc_lexer::TokenKind::Not => token::Not, + rustc_lexer::TokenKind::Le => token::Le, + rustc_lexer::TokenKind::LArrow => token::LArrow, + rustc_lexer::TokenKind::Lt => token::Lt, + rustc_lexer::TokenKind::ShlEq => token::BinOpEq(token::Shl), + rustc_lexer::TokenKind::Shl => token::BinOp(token::Shl), + rustc_lexer::TokenKind::Ge => token::Ge, + rustc_lexer::TokenKind::Gt => token::Gt, + rustc_lexer::TokenKind::ShrEq => token::BinOpEq(token::Shr), + rustc_lexer::TokenKind::Shr => token::BinOp(token::Shr), + rustc_lexer::TokenKind::RArrow => token::RArrow, + rustc_lexer::TokenKind::Minus => token::BinOp(token::Minus), + rustc_lexer::TokenKind::MinusEq => token::BinOpEq(token::Minus), + rustc_lexer::TokenKind::And => token::BinOp(token::And), + rustc_lexer::TokenKind::AndEq => token::BinOpEq(token::And), + rustc_lexer::TokenKind::AndAnd => token::AndAnd, + rustc_lexer::TokenKind::Or => token::BinOp(token::Or), + rustc_lexer::TokenKind::OrEq => token::BinOpEq(token::Or), + rustc_lexer::TokenKind::OrOr => token::OrOr, + rustc_lexer::TokenKind::Plus => token::BinOp(token::Plus), + rustc_lexer::TokenKind::PlusEq => token::BinOpEq(token::Plus), + rustc_lexer::TokenKind::Star => token::BinOp(token::Star), + rustc_lexer::TokenKind::StarEq => token::BinOpEq(token::Star), + rustc_lexer::TokenKind::Slash => token::BinOp(token::Slash), + rustc_lexer::TokenKind::SlashEq => token::BinOpEq(token::Slash), + rustc_lexer::TokenKind::Caret => token::BinOp(token::Caret), + rustc_lexer::TokenKind::CaretEq => token::BinOpEq(token::Caret), + rustc_lexer::TokenKind::Percent => token::BinOp(token::Percent), + rustc_lexer::TokenKind::PercentEq => token::BinOpEq(token::Percent), + + rustc_lexer::TokenKind::Unknown => { + let c = self.str_from(start).chars().next().unwrap(); + let mut err = self.struct_fatal_span_char(start, + self.pos, + "unknown start of token", + c); + // FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs, + // instead of keeping a table in `check_for_substitution`into the token. Ideally, + // this should be inside `rustc_lexer`. However, we should first remove compound + // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it, + // as there will be less overall work to do this way. + let token = unicode_chars::check_for_substitution(self, start, c, &mut err) + .unwrap_or_else(|| token::Unknown(self.symbol_from(start))); + err.emit(); + token } } + } - Ok(()) + fn cook_lexer_literal( + &self, + start: BytePos, + suffix_start: BytePos, + kind: rustc_lexer::LiteralKind + ) -> (token::LitKind, Symbol) { + match kind { + rustc_lexer::LiteralKind::Char { terminated } => { + if !terminated { + self.fatal_span_(start, suffix_start, + "unterminated character literal".into()) + .raise() + } + let content_start = start + BytePos(1); + let content_end = suffix_start - BytePos(1); + self.validate_char_escape(content_start, content_end); + let id = self.symbol_from_to(content_start, content_end); + (token::Char, id) + }, + rustc_lexer::LiteralKind::Byte { terminated } => { + if !terminated { + self.fatal_span_(start + BytePos(1), suffix_start, + "unterminated byte constant".into()) + .raise() + } + let content_start = start + BytePos(2); + let content_end = suffix_start - BytePos(1); + self.validate_byte_escape(content_start, content_end); + let id = self.symbol_from_to(content_start, content_end); + (token::Byte, id) + }, + rustc_lexer::LiteralKind::Str { terminated } => { + if !terminated { + self.fatal_span_(start, suffix_start, + "unterminated double quote string".into()) + .raise() + } + let content_start = start + BytePos(1); + let content_end = suffix_start - BytePos(1); + self.validate_str_escape(content_start, content_end); + let id = self.symbol_from_to(content_start, content_end); + (token::Str, id) + } + rustc_lexer::LiteralKind::ByteStr { terminated } => { + if !terminated { + self.fatal_span_(start + BytePos(1), suffix_start, + "unterminated double quote byte string".into()) + .raise() + } + let content_start = start + BytePos(2); + let content_end = suffix_start - BytePos(1); + self.validate_byte_str_escape(content_start, content_end); + let id = self.symbol_from_to(content_start, content_end); + (token::ByteStr, id) + } + rustc_lexer::LiteralKind::RawStr { n_hashes, started, terminated } => { + if !started { + self.report_non_started_raw_string(start); + } + if !terminated { + self.report_unterminated_raw_string(start, n_hashes) + } + let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes); + let n = u32::from(n_hashes); + let content_start = start + BytePos(2 + n); + let content_end = suffix_start - BytePos(1 + n); + self.validate_raw_str_escape(content_start, content_end); + let id = self.symbol_from_to(content_start, content_end); + (token::StrRaw(n_hashes), id) + } + rustc_lexer::LiteralKind::RawByteStr { n_hashes, started, terminated } => { + if !started { + self.report_non_started_raw_string(start); + } + if !terminated { + self.report_unterminated_raw_string(start, n_hashes) + } + let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes); + let n = u32::from(n_hashes); + let content_start = start + BytePos(3 + n); + let content_end = suffix_start - BytePos(1 + n); + self.validate_raw_byte_str_escape(content_start, content_end); + let id = self.symbol_from_to(content_start, content_end); + (token::ByteStrRaw(n_hashes), id) + } + rustc_lexer::LiteralKind::Int { base, empty_int } => { + if empty_int { + self.err_span_(start, suffix_start, "no valid digits found for number"); + (token::Integer, sym::integer(0)) + } else { + self.validate_int_literal(base, start, suffix_start); + (token::Integer, self.symbol_from_to(start, suffix_start)) + } + }, + rustc_lexer::LiteralKind::Float { base, empty_exponent } => { + if empty_exponent { + let mut err = self.struct_span_fatal( + start, self.pos, + "expected at least one digit in exponent" + ); + err.emit(); + } + + match base { + Base::Hexadecimal => { + self.err_span_(start, suffix_start, + "hexadecimal float literal is not supported") + } + Base::Octal => { + self.err_span_(start, suffix_start, + "octal float literal is not supported") + } + Base::Binary => { + self.err_span_(start, suffix_start, + "binary float literal is not supported") + } + _ => () + } + + let id = self.symbol_from_to(start, suffix_start); + (token::Float, id) + }, + } } #[inline] fn src_index(&self, pos: BytePos) -> usize { - (pos - self.source_file.start_pos).to_usize() + (pos - self.start_pos).to_usize() } /// Slice of the source text from `start` up to but excluding `self.pos`, @@ -391,909 +562,58 @@ impl<'a> StringReader<'a> { } } - /// Advance the StringReader by one character. - crate fn bump(&mut self) { - let next_src_index = self.src_index(self.next_pos); - if next_src_index < self.end_src_index { - let next_ch = char_at(&self.src, next_src_index); - let next_ch_len = next_ch.len_utf8(); - - self.ch = Some(next_ch); - self.pos = self.next_pos; - self.next_pos = self.next_pos + Pos::from_usize(next_ch_len); - } else { - self.ch = None; - self.pos = self.next_pos; - } - } - - fn nextch(&self) -> Option { - let next_src_index = self.src_index(self.next_pos); - if next_src_index < self.end_src_index { - Some(char_at(&self.src, next_src_index)) - } else { - None - } - } - - #[inline] - fn nextch_is(&self, c: char) -> bool { - self.nextch() == Some(c) - } - - fn nextnextch(&self) -> Option { - let next_src_index = self.src_index(self.next_pos); - if next_src_index < self.end_src_index { - let next_next_src_index = - next_src_index + char_at(&self.src, next_src_index).len_utf8(); - if next_next_src_index < self.end_src_index { - return Some(char_at(&self.src, next_next_src_index)); - } - } - None - } - - #[inline] - fn nextnextch_is(&self, c: char) -> bool { - self.nextnextch() == Some(c) - } - - /// Eats *, if possible. - fn scan_optional_raw_name(&mut self) -> Option { - if !ident_start(self.ch) { - return None; - } - - let start = self.pos; - self.bump(); - - while ident_continue(self.ch) { - self.bump(); - } - - match self.str_from(start) { - "_" => { - self.sess.span_diagnostic - .struct_span_warn(self.mk_sp(start, self.pos), - "underscore literal suffix is not allowed") - .warn("this was previously accepted by the compiler but is \ - being phased out; it will become a hard error in \ - a future release!") - .note("for more information, see issue #42326 \ - ") - .emit(); - None - } - name => Some(Symbol::intern(name)) - } - } - - /// PRECONDITION: self.ch is not whitespace - /// Eats any kind of comment. - fn scan_comment(&mut self) -> Option { - if let Some(c) = self.ch { - if c.is_whitespace() { - let msg = "called consume_any_line_comment, but there was whitespace"; - self.sess.span_diagnostic.span_err(self.mk_sp(self.pos, self.pos), msg); - } - } - - if self.ch_is('/') { - match self.nextch() { - Some('/') => { - self.bump(); - self.bump(); - - // line comments starting with "///" or "//!" are doc-comments - let doc_comment = (self.ch_is('/') && !self.nextch_is('/')) || self.ch_is('!'); - let start_bpos = self.pos - BytePos(2); - - while !self.is_eof() { - match self.ch.unwrap() { - '\n' => break, - '\r' => { - if self.nextch_is('\n') { - // CRLF - break; - } else if doc_comment { - self.err_span_(self.pos, - self.next_pos, - "bare CR not allowed in doc-comment"); - } - } - _ => (), - } - self.bump(); - } - - let kind = if doc_comment { - token::DocComment(self.symbol_from(start_bpos)) - } else { - token::Comment - }; - Some(Token::new(kind, self.mk_sp(start_bpos, self.pos))) - } - Some('*') => { - self.bump(); - self.bump(); - self.scan_block_comment() - } - _ => None, - } - } else if self.ch_is('#') { - if self.nextch_is('!') { - - // Parse an inner attribute. - if self.nextnextch_is('[') { - return None; - } - - let is_beginning_of_file = self.pos == self.source_file.start_pos; - if is_beginning_of_file { - debug!("Skipping a shebang"); - let start = self.pos; - while !self.ch_is('\n') && !self.is_eof() { - self.bump(); - } - return Some(Token::new( - token::Shebang(self.symbol_from(start)), - self.mk_sp(start, self.pos), - )); - } - } - None - } else { - None - } - } - - /// If there is whitespace, shebang, or a comment, scan it. Otherwise, - /// return `None`. - fn scan_whitespace_or_comment(&mut self) -> Option { - match self.ch.unwrap_or('\0') { - // # to handle shebang at start of file -- this is the entry point - // for skipping over all "junk" - '/' | '#' => { - let c = self.scan_comment(); - debug!("scanning a comment {:?}", c); - c - }, - c if is_pattern_whitespace(Some(c)) => { - let start_bpos = self.pos; - while is_pattern_whitespace(self.ch) { - self.bump(); - } - let c = Some(Token::new(token::Whitespace, self.mk_sp(start_bpos, self.pos))); - debug!("scanning whitespace: {:?}", c); - c - } - _ => None, - } - } - - /// Might return a sugared-doc-attr - fn scan_block_comment(&mut self) -> Option { - // block comments starting with "/**" or "/*!" are doc-comments - let is_doc_comment = self.ch_is('*') || self.ch_is('!'); - let start_bpos = self.pos - BytePos(2); - - let mut level: isize = 1; - let mut has_cr = false; - while level > 0 { - if self.is_eof() { - let msg = if is_doc_comment { - "unterminated block doc-comment" - } else { - "unterminated block comment" - }; - let last_bpos = self.pos; - self.fatal_span_(start_bpos, last_bpos, msg).raise(); - } - let n = self.ch.unwrap(); - match n { - '/' if self.nextch_is('*') => { - level += 1; - self.bump(); - } - '*' if self.nextch_is('/') => { - level -= 1; - self.bump(); - } - '\r' => { - has_cr = true; - } - _ => (), - } - self.bump(); - } - - let string = self.str_from(start_bpos); - // but comments with only "*"s between two "/"s are not - let kind = if is_block_doc_comment(string) { - let string = if has_cr { - self.translate_crlf(start_bpos, - string, - "bare CR not allowed in block doc-comment") - } else { - string.into() - }; - token::DocComment(Symbol::intern(&string[..])) - } else { - token::Comment - }; - - Some(Token::new(kind, self.mk_sp(start_bpos, self.pos))) - } - - /// Scan through any digits (base `scan_radix`) or underscores, - /// and return how many digits there were. - /// - /// `real_radix` represents the true radix of the number we're - /// interested in, and errors will be emitted for any digits - /// between `real_radix` and `scan_radix`. - fn scan_digits(&mut self, real_radix: u32, scan_radix: u32) -> usize { - assert!(real_radix <= scan_radix); - let mut len = 0; - - loop { - let c = self.ch; - if c == Some('_') { - debug!("skipping a _"); - self.bump(); - continue; - } - match c.and_then(|cc| cc.to_digit(scan_radix)) { - Some(_) => { - debug!("{:?} in scan_digits", c); - // check that the hypothetical digit is actually - // in range for the true radix - if c.unwrap().to_digit(real_radix).is_none() { - self.err_span_(self.pos, - self.next_pos, - &format!("invalid digit for a base {} literal", real_radix)); - } - len += 1; - self.bump(); - } - _ => return len, - } - } - } - - /// Lex a LIT_INTEGER or a LIT_FLOAT - fn scan_number(&mut self, c: char) -> (token::LitKind, Symbol) { - let mut base = 10; - let start_bpos = self.pos; - self.bump(); - - let num_digits = if c == '0' { - match self.ch.unwrap_or('\0') { - 'b' => { - self.bump(); - base = 2; - self.scan_digits(2, 10) - } - 'o' => { - self.bump(); - base = 8; - self.scan_digits(8, 10) - } - 'x' => { - self.bump(); - base = 16; - self.scan_digits(16, 16) - } - '0'..='9' | '_' | '.' | 'e' | 'E' => { - self.scan_digits(10, 10) + 1 - } - _ => { - // just a 0 - return (token::Integer, sym::integer(0)); - } - } - } else if c.is_digit(10) { - self.scan_digits(10, 10) + 1 - } else { - 0 - }; - - if num_digits == 0 { - self.err_span_(start_bpos, self.pos, "no valid digits found for number"); - - return (token::Integer, Symbol::intern("0")); - } - - // might be a float, but don't be greedy if this is actually an - // integer literal followed by field/method access or a range pattern - // (`0..2` and `12.foo()`) - if self.ch_is('.') && !self.nextch_is('.') && - !ident_start(self.nextch()) { - // might have stuff after the ., and if it does, it needs to start - // with a number - self.bump(); - if self.ch.unwrap_or('\0').is_digit(10) { - self.scan_digits(10, 10); - self.scan_float_exponent(); - } - let pos = self.pos; - self.check_float_base(start_bpos, pos, base); - - (token::Float, self.symbol_from(start_bpos)) - } else { - // it might be a float if it has an exponent - if self.ch_is('e') || self.ch_is('E') { - self.scan_float_exponent(); - let pos = self.pos; - self.check_float_base(start_bpos, pos, base); - return (token::Float, self.symbol_from(start_bpos)); - } - // but we certainly have an integer! - (token::Integer, self.symbol_from(start_bpos)) - } - } - - /// Scan over a float exponent. - fn scan_float_exponent(&mut self) { - if self.ch_is('e') || self.ch_is('E') { - self.bump(); - - if self.ch_is('-') || self.ch_is('+') { - self.bump(); - } - - if self.scan_digits(10, 10) == 0 { - let mut err = self.struct_span_fatal( - self.pos, self.next_pos, - "expected at least one digit in exponent" - ); - if let Some(ch) = self.ch { - // check for e.g., Unicode minus '−' (Issue #49746) - if unicode_chars::check_for_substitution(self, ch, &mut err) { - self.bump(); - self.scan_digits(10, 10); - } - } - err.emit(); - } - } - } - - /// Checks that a base is valid for a floating literal, emitting a nice - /// error if it isn't. - fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: usize) { - match base { - 16 => { - self.err_span_(start_bpos, - last_bpos, - "hexadecimal float literal is not supported") - } - 8 => { - self.err_span_(start_bpos, - last_bpos, - "octal float literal is not supported") - } - 2 => { - self.err_span_(start_bpos, - last_bpos, - "binary float literal is not supported") - } - _ => (), - } - } - - fn binop(&mut self, op: token::BinOpToken) -> TokenKind { - self.bump(); - if self.ch_is('=') { - self.bump(); - token::BinOpEq(op) - } else { - token::BinOp(op) - } - } - - /// Returns the next token from the string, advances the input past that - /// token, and updates the interner - fn next_token_inner(&mut self) -> Result { - let c = self.ch; - - if ident_start(c) { - let (is_ident_start, is_raw_ident) = - match (c.unwrap(), self.nextch(), self.nextnextch()) { - // r# followed by an identifier starter is a raw identifier. - // This is an exception to the r# case below. - ('r', Some('#'), x) if ident_start(x) => (true, true), - // r as in r" or r#" is part of a raw string literal. - // b as in b' is part of a byte literal. - // They are not identifiers, and are handled further down. - ('r', Some('"'), _) | - ('r', Some('#'), _) | - ('b', Some('"'), _) | - ('b', Some('\''), _) | - ('b', Some('r'), Some('"')) | - ('b', Some('r'), Some('#')) => (false, false), - _ => (true, false), - }; - - if is_ident_start { - let raw_start = self.pos; - if is_raw_ident { - // Consume the 'r#' characters. - self.bump(); - self.bump(); - } - - let start = self.pos; - self.bump(); - - while ident_continue(self.ch) { - self.bump(); - } - - // FIXME: perform NFKC normalization here. (Issue #2253) - let name = self.symbol_from(start); - if is_raw_ident { - let span = self.mk_sp(raw_start, self.pos); - if !name.can_be_raw() { - self.err_span(span, &format!("`{}` cannot be a raw identifier", name)); - } - self.sess.raw_identifier_spans.borrow_mut().push(span); - } - - return Ok(token::Ident(name, is_raw_ident)); - } - } - - if is_dec_digit(c) { - let (kind, symbol) = self.scan_number(c.unwrap()); - let suffix = self.scan_optional_raw_name(); - debug!("next_token_inner: scanned number {:?}, {:?}, {:?}", kind, symbol, suffix); - return Ok(TokenKind::lit(kind, symbol, suffix)); - } - - match c.expect("next_token_inner called at EOF") { - // One-byte tokens. - ';' => { - self.bump(); - Ok(token::Semi) - } - ',' => { - self.bump(); - Ok(token::Comma) - } - '.' => { - self.bump(); - if self.ch_is('.') { - self.bump(); - if self.ch_is('.') { - self.bump(); - Ok(token::DotDotDot) - } else if self.ch_is('=') { - self.bump(); - Ok(token::DotDotEq) - } else { - Ok(token::DotDot) - } - } else { - Ok(token::Dot) - } - } - '(' => { - self.bump(); - Ok(token::OpenDelim(token::Paren)) - } - ')' => { - self.bump(); - Ok(token::CloseDelim(token::Paren)) - } - '{' => { - self.bump(); - Ok(token::OpenDelim(token::Brace)) - } - '}' => { - self.bump(); - Ok(token::CloseDelim(token::Brace)) - } - '[' => { - self.bump(); - Ok(token::OpenDelim(token::Bracket)) - } - ']' => { - self.bump(); - Ok(token::CloseDelim(token::Bracket)) - } - '@' => { - self.bump(); - Ok(token::At) - } - '#' => { - self.bump(); - Ok(token::Pound) - } - '~' => { - self.bump(); - Ok(token::Tilde) - } - '?' => { - self.bump(); - Ok(token::Question) - } - ':' => { - self.bump(); - if self.ch_is(':') { - self.bump(); - Ok(token::ModSep) - } else { - Ok(token::Colon) - } - } - - '$' => { - self.bump(); - Ok(token::Dollar) - } - - // Multi-byte tokens. - '=' => { - self.bump(); - if self.ch_is('=') { - self.bump(); - Ok(token::EqEq) - } else if self.ch_is('>') { - self.bump(); - Ok(token::FatArrow) - } else { - Ok(token::Eq) - } - } - '!' => { - self.bump(); - if self.ch_is('=') { - self.bump(); - Ok(token::Ne) - } else { - Ok(token::Not) - } - } - '<' => { - self.bump(); - match self.ch.unwrap_or('\x00') { - '=' => { - self.bump(); - Ok(token::Le) - } - '<' => { - Ok(self.binop(token::Shl)) - } - '-' => { - self.bump(); - Ok(token::LArrow) - } - _ => { - Ok(token::Lt) - } - } - } - '>' => { - self.bump(); - match self.ch.unwrap_or('\x00') { - '=' => { - self.bump(); - Ok(token::Ge) - } - '>' => { - Ok(self.binop(token::Shr)) - } - _ => { - Ok(token::Gt) - } - } - } - '\'' => { - // Either a character constant 'a' OR a lifetime name 'abc - let start_with_quote = self.pos; - self.bump(); - let start = self.pos; - - // If the character is an ident start not followed by another single - // quote, then this is a lifetime name: - let starts_with_number = self.ch.unwrap_or('\x00').is_numeric(); - if (ident_start(self.ch) || starts_with_number) && !self.nextch_is('\'') { - self.bump(); - while ident_continue(self.ch) { - self.bump(); - } - // lifetimes shouldn't end with a single quote - // if we find one, then this is an invalid character literal - if self.ch_is('\'') { - let symbol = self.symbol_from(start); - self.bump(); - self.validate_char_escape(start_with_quote); - return Ok(TokenKind::lit(token::Char, symbol, None)); - } - - if starts_with_number { - // this is a recovered lifetime written `'1`, error but accept it - self.err_span_( - start_with_quote, - self.pos, - "lifetimes cannot start with a number", - ); - } - - // Include the leading `'` in the real identifier, for macro - // expansion purposes. See #12512 for the gory details of why - // this is necessary. - return Ok(token::Lifetime(self.symbol_from(start_with_quote))); - } - let msg = "unterminated character literal"; - let symbol = self.scan_single_quoted_string(start_with_quote, msg); - self.validate_char_escape(start_with_quote); - let suffix = self.scan_optional_raw_name(); - Ok(TokenKind::lit(token::Char, symbol, suffix)) - } - 'b' => { - self.bump(); - let (kind, symbol) = match self.ch { - Some('\'') => { - let start_with_quote = self.pos; - self.bump(); - let msg = "unterminated byte constant"; - let symbol = self.scan_single_quoted_string(start_with_quote, msg); - self.validate_byte_escape(start_with_quote); - (token::Byte, symbol) - }, - Some('"') => { - let start_with_quote = self.pos; - let msg = "unterminated double quote byte string"; - let symbol = self.scan_double_quoted_string(msg); - self.validate_byte_str_escape(start_with_quote); - (token::ByteStr, symbol) - }, - Some('r') => { - let (start, end, hash_count) = self.scan_raw_string(); - let symbol = self.symbol_from_to(start, end); - self.validate_raw_byte_str_escape(start, end); - - (token::ByteStrRaw(hash_count), symbol) - } - _ => unreachable!(), // Should have been a token::Ident above. - }; - let suffix = self.scan_optional_raw_name(); - - Ok(TokenKind::lit(kind, symbol, suffix)) - } - '"' => { - let start_with_quote = self.pos; - let msg = "unterminated double quote string"; - let symbol = self.scan_double_quoted_string(msg); - self.validate_str_escape(start_with_quote); - let suffix = self.scan_optional_raw_name(); - Ok(TokenKind::lit(token::Str, symbol, suffix)) - } - 'r' => { - let (start, end, hash_count) = self.scan_raw_string(); - let symbol = self.symbol_from_to(start, end); - self.validate_raw_str_escape(start, end); - let suffix = self.scan_optional_raw_name(); - - Ok(TokenKind::lit(token::StrRaw(hash_count), symbol, suffix)) - } - '-' => { - if self.nextch_is('>') { - self.bump(); - self.bump(); - Ok(token::RArrow) - } else { - Ok(self.binop(token::Minus)) - } - } - '&' => { - if self.nextch_is('&') { - self.bump(); - self.bump(); - Ok(token::AndAnd) - } else { - Ok(self.binop(token::And)) - } - } - '|' => { - match self.nextch() { - Some('|') => { - self.bump(); - self.bump(); - Ok(token::OrOr) - } - _ => { - Ok(self.binop(token::Or)) - } - } - } - '+' => { - Ok(self.binop(token::Plus)) - } - '*' => { - Ok(self.binop(token::Star)) - } - '/' => { - Ok(self.binop(token::Slash)) - } - '^' => { - Ok(self.binop(token::Caret)) - } - '%' => { - Ok(self.binop(token::Percent)) - } - c => { - let last_bpos = self.pos; - let bpos = self.next_pos; - let mut err = self.struct_fatal_span_char(last_bpos, - bpos, - "unknown start of token", - c); - unicode_chars::check_for_substitution(self, c, &mut err); - self.fatal_errs.push(err); - - Err(()) - } - } - } - - fn read_to_eol(&mut self) -> String { - let mut val = String::new(); - while !self.ch_is('\n') && !self.is_eof() { - val.push(self.ch.unwrap()); - self.bump(); - } - - if self.ch_is('\n') { - self.bump(); - } - - val - } - - fn read_one_line_comment(&mut self) -> String { - let val = self.read_to_eol(); - assert!((val.as_bytes()[0] == b'/' && val.as_bytes()[1] == b'/') || - (val.as_bytes()[0] == b'#' && val.as_bytes()[1] == b'!')); - val - } - - fn consume_non_eol_whitespace(&mut self) { - while is_pattern_whitespace(self.ch) && !self.ch_is('\n') && !self.is_eof() { - self.bump(); - } + fn report_non_started_raw_string(&self, start: BytePos) -> ! { + let bad_char = self.str_from(start).chars().last().unwrap(); + self + .struct_fatal_span_char( + start, + self.pos, + "found invalid character; only `#` is allowed \ + in raw string delimitation", + bad_char, + ) + .emit(); + FatalError.raise() } - fn peeking_at_comment(&self) -> bool { - (self.ch_is('/') && self.nextch_is('/')) || (self.ch_is('/') && self.nextch_is('*')) || - // consider shebangs comments, but not inner attributes - (self.ch_is('#') && self.nextch_is('!') && !self.nextnextch_is('[')) - } + fn report_unterminated_raw_string(&self, start: BytePos, n_hashes: usize) -> ! { + let mut err = self.struct_span_fatal( + start, start, + "unterminated raw string", + ); + err.span_label( + self.mk_sp(start, start), + "unterminated raw string", + ); - fn scan_single_quoted_string(&mut self, - start_with_quote: BytePos, - unterminated_msg: &str) -> Symbol { - // assumes that first `'` is consumed - let start = self.pos; - // lex `'''` as a single char, for recovery - if self.ch_is('\'') && self.nextch_is('\'') { - self.bump(); - } else { - let mut first = true; - loop { - if self.ch_is('\'') { - break; - } - if self.ch_is('\\') && (self.nextch_is('\'') || self.nextch_is('\\')) { - self.bump(); - self.bump(); - } else { - // Only attempt to infer single line string literals. If we encounter - // a slash, bail out in order to avoid nonsensical suggestion when - // involving comments. - if self.is_eof() - || (self.ch_is('/') && !first) - || (self.ch_is('\n') && !self.nextch_is('\'')) { - - self.fatal_span_(start_with_quote, self.pos, unterminated_msg.into()) - .raise() - } - self.bump(); - } - first = false; - } + if n_hashes > 0 { + err.note(&format!("this raw string should be terminated with `\"{}`", + "#".repeat(n_hashes as usize))); } - let id = self.symbol_from(start); - self.bump(); - id - } - - fn scan_double_quoted_string(&mut self, unterminated_msg: &str) -> Symbol { - debug_assert!(self.ch_is('\"')); - let start_with_quote = self.pos; - self.bump(); - let start = self.pos; - while !self.ch_is('"') { - if self.is_eof() { - let pos = self.pos; - self.fatal_span_(start_with_quote, pos, unterminated_msg).raise(); - } - if self.ch_is('\\') && (self.nextch_is('\\') || self.nextch_is('"')) { - self.bump(); - } - self.bump(); - } - let id = self.symbol_from(start); - self.bump(); - id + err.emit(); + FatalError.raise() } - /// Scans a raw (byte) string, returning byte position range for `""` - /// (including quotes) along with `#` character count in `(b)r##...""##...`; - fn scan_raw_string(&mut self) -> (BytePos, BytePos, u16) { - let start_bpos = self.pos; - self.bump(); - let mut hash_count: u16 = 0; - while self.ch_is('#') { - if hash_count == 65535 { - let bpos = self.next_pos; - self.fatal_span_(start_bpos, - bpos, + fn restrict_n_hashes(&self, start: BytePos, n_hashes: usize) -> u16 { + match n_hashes.try_into() { + Ok(n_hashes) => n_hashes, + Err(_) => { + self.fatal_span_(start, + self.pos, "too many `#` symbols: raw strings may be \ - delimited by up to 65535 `#` symbols").raise(); + delimited by up to 65535 `#` symbols").raise(); } - self.bump(); - hash_count += 1; } - - if self.is_eof() { - self.fail_unterminated_raw_string(start_bpos, hash_count); - } else if !self.ch_is('"') { - let last_bpos = self.pos; - let curr_char = self.ch.unwrap(); - self.fatal_span_char(start_bpos, - last_bpos, - "found invalid character; only `#` is allowed \ - in raw string delimitation", - curr_char).raise(); - } - self.bump(); - let content_start_bpos = self.pos; - let mut content_end_bpos; - 'outer: loop { - match self.ch { - None => { - self.fail_unterminated_raw_string(start_bpos, hash_count); - } - Some('"') => { - content_end_bpos = self.pos; - for _ in 0..hash_count { - self.bump(); - if !self.ch_is('#') { - continue 'outer; - } - } - break; - } - _ => (), - } - self.bump(); - } - - self.bump(); - - (content_start_bpos, content_end_bpos, hash_count) } - fn validate_char_escape(&self, start_with_quote: BytePos) { - let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + fn validate_char_escape(&self, content_start: BytePos, content_end: BytePos) { + let lit = self.str_from_to(content_start, content_end); if let Err((off, err)) = unescape::unescape_char(lit) { emit_unescape_error( &self.sess.span_diagnostic, lit, - self.mk_sp(start_with_quote, self.pos), + self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), unescape::Mode::Char, 0..off, err, @@ -1301,13 +621,13 @@ impl<'a> StringReader<'a> { } } - fn validate_byte_escape(&self, start_with_quote: BytePos) { - let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + fn validate_byte_escape(&self, content_start: BytePos, content_end: BytePos) { + let lit = self.str_from_to(content_start, content_end); if let Err((off, err)) = unescape::unescape_byte(lit) { emit_unescape_error( &self.sess.span_diagnostic, lit, - self.mk_sp(start_with_quote, self.pos), + self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), unescape::Mode::Byte, 0..off, err, @@ -1315,14 +635,14 @@ impl<'a> StringReader<'a> { } } - fn validate_str_escape(&self, start_with_quote: BytePos) { - let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + fn validate_str_escape(&self, content_start: BytePos, content_end: BytePos) { + let lit = self.str_from_to(content_start, content_end); unescape::unescape_str(lit, &mut |range, c| { if let Err(err) = c { emit_unescape_error( &self.sess.span_diagnostic, lit, - self.mk_sp(start_with_quote, self.pos), + self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), unescape::Mode::Str, range, err, @@ -1363,14 +683,14 @@ impl<'a> StringReader<'a> { }) } - fn validate_byte_str_escape(&self, start_with_quote: BytePos) { - let lit = self.str_from_to(start_with_quote + BytePos(1), self.pos - BytePos(1)); + fn validate_byte_str_escape(&self, content_start: BytePos, content_end: BytePos) { + let lit = self.str_from_to(content_start, content_end); unescape::unescape_byte_str(lit, &mut |range, c| { if let Err(err) = c { emit_unescape_error( &self.sess.span_diagnostic, lit, - self.mk_sp(start_with_quote, self.pos), + self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)), unescape::Mode::ByteStr, range, err, @@ -1378,23 +698,25 @@ impl<'a> StringReader<'a> { } }) } -} -// This tests the character for the unicode property 'PATTERN_WHITE_SPACE' which -// is guaranteed to be forward compatible. http://unicode.org/reports/tr31/#R3 -#[inline] -crate fn is_pattern_whitespace(c: Option) -> bool { - c.map_or(false, Pattern_White_Space) -} - -#[inline] -fn in_range(c: Option, lo: char, hi: char) -> bool { - c.map_or(false, |c| lo <= c && c <= hi) -} + fn validate_int_literal(&self, base: Base, content_start: BytePos, content_end: BytePos) { + let base = match base { + Base::Binary => 2, + Base::Octal => 8, + _ => return, + }; + let s = self.str_from_to(content_start + BytePos(2), content_end); + for (idx, c) in s.char_indices() { + let idx = idx as u32; + if c != '_' && c.to_digit(base).is_none() { + let lo = content_start + BytePos(2 + idx); + let hi = content_start + BytePos(2 + idx + c.len_utf8() as u32); + self.err_span_(lo, hi, + &format!("invalid digit for a base {} literal", base)); -#[inline] -fn is_dec_digit(c: Option) -> bool { - in_range(c, '0', '9') + } + } + } } fn is_doc_comment(s: &str) -> bool { @@ -1411,290 +733,3 @@ fn is_block_doc_comment(s: &str) -> bool { debug!("is {:?} a doc comment? {}", s, res); res } - -/// Determine whether `c` is a valid start for an ident. -fn ident_start(c: Option) -> bool { - let c = match c { - Some(c) => c, - None => return false, - }; - - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c > '\x7f' && c.is_xid_start()) -} - -fn ident_continue(c: Option) -> bool { - let c = match c { - Some(c) => c, - None => return false, - }; - - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || - (c > '\x7f' && c.is_xid_continue()) -} - -#[inline] -fn char_at(s: &str, byte: usize) -> char { - s[byte..].chars().next().unwrap() -} - -#[cfg(test)] -mod tests { - use super::*; - - use crate::ast::CrateConfig; - use crate::symbol::Symbol; - use crate::source_map::{SourceMap, FilePathMapping}; - use crate::feature_gate::UnstableFeatures; - use crate::parse::token; - use crate::diagnostics::plugin::ErrorMap; - use crate::with_default_globals; - use std::io; - use std::path::PathBuf; - use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition}; - use rustc_data_structures::fx::{FxHashSet, FxHashMap}; - use rustc_data_structures::sync::Lock; - - fn mk_sess(sm: Lrc) -> ParseSess { - let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), - Some(sm.clone()), - false, - false, - false); - ParseSess { - span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)), - unstable_features: UnstableFeatures::from_environment(), - config: CrateConfig::default(), - included_mod_stack: Lock::new(Vec::new()), - source_map: sm, - missing_fragment_specifiers: Lock::new(FxHashSet::default()), - raw_identifier_spans: Lock::new(Vec::new()), - registered_diagnostics: Lock::new(ErrorMap::new()), - buffered_lints: Lock::new(vec![]), - edition: Edition::from_session(), - ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), - param_attr_spans: Lock::new(Vec::new()), - let_chains_spans: Lock::new(Vec::new()), - } - } - - // open a string reader for the given string - fn setup<'a>(sm: &SourceMap, - sess: &'a ParseSess, - teststr: String) - -> StringReader<'a> { - let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr); - let mut sr = StringReader::new_raw(sess, sf, None); - if sr.advance_token().is_err() { - sr.emit_fatal_errors(); - FatalError.raise(); - } - sr - } - - #[test] - fn t1() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - let mut string_reader = setup(&sm, - &sh, - "/* my source file */ fn main() { println!(\"zebra\"); }\n" - .to_string()); - assert_eq!(string_reader.next_token(), token::Comment); - assert_eq!(string_reader.next_token(), token::Whitespace); - let tok1 = string_reader.next_token(); - let tok2 = Token::new( - mk_ident("fn"), - Span::new(BytePos(21), BytePos(23), NO_EXPANSION), - ); - assert_eq!(tok1.kind, tok2.kind); - assert_eq!(tok1.span, tok2.span); - assert_eq!(string_reader.next_token(), token::Whitespace); - // the 'main' id is already read: - assert_eq!(string_reader.pos.clone(), BytePos(28)); - // read another token: - let tok3 = string_reader.next_token(); - let tok4 = Token::new( - mk_ident("main"), - Span::new(BytePos(24), BytePos(28), NO_EXPANSION), - ); - assert_eq!(tok3.kind, tok4.kind); - assert_eq!(tok3.span, tok4.span); - // the lparen is already read: - assert_eq!(string_reader.pos.clone(), BytePos(29)) - }) - } - - // check that the given reader produces the desired stream - // of tokens (stop checking after exhausting the expected vec) - fn check_tokenization(mut string_reader: StringReader<'_>, expected: Vec) { - for expected_tok in &expected { - assert_eq!(&string_reader.next_token(), expected_tok); - } - } - - // make the identifier by looking up the string in the interner - fn mk_ident(id: &str) -> TokenKind { - token::Ident(Symbol::intern(id), false) - } - - fn mk_lit(kind: token::LitKind, symbol: &str, suffix: Option<&str>) -> TokenKind { - TokenKind::lit(kind, Symbol::intern(symbol), suffix.map(Symbol::intern)) - } - - #[test] - fn doublecolonparsing() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization(setup(&sm, &sh, "a b".to_string()), - vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); - }) - } - - #[test] - fn dcparsing_2() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization(setup(&sm, &sh, "a::b".to_string()), - vec![mk_ident("a"), token::ModSep, mk_ident("b")]); - }) - } - - #[test] - fn dcparsing_3() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization(setup(&sm, &sh, "a ::b".to_string()), - vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); - }) - } - - #[test] - fn dcparsing_4() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization(setup(&sm, &sh, "a:: b".to_string()), - vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); - }) - } - - #[test] - fn character_a() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token(), - mk_lit(token::Char, "a", None)); - }) - } - - #[test] - fn character_space() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token(), - mk_lit(token::Char, " ", None)); - }) - } - - #[test] - fn character_escaped() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "'\\n'".to_string()).next_token(), - mk_lit(token::Char, "\\n", None)); - }) - } - - #[test] - fn lifetime_name() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "'abc".to_string()).next_token(), - token::Lifetime(Symbol::intern("'abc"))); - }) - } - - #[test] - fn raw_string() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token(), - mk_lit(token::StrRaw(3), "\"#a\\b\x00c\"", None)); - }) - } - - #[test] - fn literal_suffixes() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - macro_rules! test { - ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ - assert_eq!(setup(&sm, &sh, format!("{}suffix", $input)).next_token(), - mk_lit(token::$tok_type, $tok_contents, Some("suffix"))); - // with a whitespace separator: - assert_eq!(setup(&sm, &sh, format!("{} suffix", $input)).next_token(), - mk_lit(token::$tok_type, $tok_contents, None)); - }} - } - - test!("'a'", Char, "a"); - test!("b'a'", Byte, "a"); - test!("\"a\"", Str, "a"); - test!("b\"a\"", ByteStr, "a"); - test!("1234", Integer, "1234"); - test!("0b101", Integer, "0b101"); - test!("0xABC", Integer, "0xABC"); - test!("1.0", Float, "1.0"); - test!("1.0e10", Float, "1.0e10"); - - assert_eq!(setup(&sm, &sh, "2us".to_string()).next_token(), - mk_lit(token::Integer, "2", Some("us"))); - assert_eq!(setup(&sm, &sh, "r###\"raw\"###suffix".to_string()).next_token(), - mk_lit(token::StrRaw(3), "raw", Some("suffix"))); - assert_eq!(setup(&sm, &sh, "br###\"raw\"###suffix".to_string()).next_token(), - mk_lit(token::ByteStrRaw(3), "raw", Some("suffix"))); - }) - } - - #[test] - fn line_doc_comments() { - assert!(is_doc_comment("///")); - assert!(is_doc_comment("/// blah")); - assert!(!is_doc_comment("////")); - } - - #[test] - fn nested_block_comments() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string()); - assert_eq!(lexer.next_token(), token::Comment); - assert_eq!(lexer.next_token(), mk_lit(token::Char, "a", None)); - }) - } - - #[test] - fn crlf_comments() { - with_default_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string()); - let comment = lexer.next_token(); - assert_eq!(comment.kind, token::Comment); - assert_eq!((comment.span.lo(), comment.span.hi()), (BytePos(0), BytePos(7))); - assert_eq!(lexer.next_token(), token::Whitespace); - assert_eq!(lexer.next_token(), token::DocComment(Symbol::intern("/// test"))); - }) - } -} diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs new file mode 100644 index 0000000000..fc47e4f0b1 --- /dev/null +++ b/src/libsyntax/parse/lexer/tests.rs @@ -0,0 +1,255 @@ +use super::*; + +use crate::ast::CrateConfig; +use crate::symbol::Symbol; +use crate::source_map::{SourceMap, FilePathMapping}; +use crate::feature_gate::UnstableFeatures; +use crate::parse::token; +use crate::diagnostics::plugin::ErrorMap; +use crate::with_default_globals; +use std::io; +use std::path::PathBuf; +use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition}; +use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use rustc_data_structures::sync::{Lock, Once}; + +fn mk_sess(sm: Lrc) -> ParseSess { + let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), + Some(sm.clone()), + false, + false, + false); + ParseSess { + span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)), + unstable_features: UnstableFeatures::from_environment(), + config: CrateConfig::default(), + included_mod_stack: Lock::new(Vec::new()), + source_map: sm, + missing_fragment_specifiers: Lock::new(FxHashSet::default()), + raw_identifier_spans: Lock::new(Vec::new()), + registered_diagnostics: Lock::new(ErrorMap::new()), + buffered_lints: Lock::new(vec![]), + edition: Edition::from_session(), + ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), + param_attr_spans: Lock::new(Vec::new()), + let_chains_spans: Lock::new(Vec::new()), + async_closure_spans: Lock::new(Vec::new()), + injected_crate_name: Once::new(), + } +} + +// open a string reader for the given string +fn setup<'a>(sm: &SourceMap, + sess: &'a ParseSess, + teststr: String) + -> StringReader<'a> { + let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr); + StringReader::new(sess, sf, None) +} + +#[test] +fn t1() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + let mut string_reader = setup(&sm, + &sh, + "/* my source file */ fn main() { println!(\"zebra\"); }\n" + .to_string()); + assert_eq!(string_reader.next_token(), token::Comment); + assert_eq!(string_reader.next_token(), token::Whitespace); + let tok1 = string_reader.next_token(); + let tok2 = Token::new( + mk_ident("fn"), + Span::new(BytePos(21), BytePos(23), NO_EXPANSION), + ); + assert_eq!(tok1.kind, tok2.kind); + assert_eq!(tok1.span, tok2.span); + assert_eq!(string_reader.next_token(), token::Whitespace); + // read another token: + let tok3 = string_reader.next_token(); + assert_eq!(string_reader.pos.clone(), BytePos(28)); + let tok4 = Token::new( + mk_ident("main"), + Span::new(BytePos(24), BytePos(28), NO_EXPANSION), + ); + assert_eq!(tok3.kind, tok4.kind); + assert_eq!(tok3.span, tok4.span); + + assert_eq!(string_reader.next_token(), token::OpenDelim(token::Paren)); + assert_eq!(string_reader.pos.clone(), BytePos(29)) + }) +} + +// check that the given reader produces the desired stream +// of tokens (stop checking after exhausting the expected vec) +fn check_tokenization(mut string_reader: StringReader<'_>, expected: Vec) { + for expected_tok in &expected { + assert_eq!(&string_reader.next_token(), expected_tok); + } +} + +// make the identifier by looking up the string in the interner +fn mk_ident(id: &str) -> TokenKind { + token::Ident(Symbol::intern(id), false) +} + +fn mk_lit(kind: token::LitKind, symbol: &str, suffix: Option<&str>) -> TokenKind { + TokenKind::lit(kind, Symbol::intern(symbol), suffix.map(Symbol::intern)) +} + +#[test] +fn doublecolonparsing() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + check_tokenization(setup(&sm, &sh, "a b".to_string()), + vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); + }) +} + +#[test] +fn dcparsing_2() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + check_tokenization(setup(&sm, &sh, "a::b".to_string()), + vec![mk_ident("a"), token::ModSep, mk_ident("b")]); + }) +} + +#[test] +fn dcparsing_3() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + check_tokenization(setup(&sm, &sh, "a ::b".to_string()), + vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); + }) +} + +#[test] +fn dcparsing_4() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + check_tokenization(setup(&sm, &sh, "a:: b".to_string()), + vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); + }) +} + +#[test] +fn character_a() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token(), + mk_lit(token::Char, "a", None)); + }) +} + +#[test] +fn character_space() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token(), + mk_lit(token::Char, " ", None)); + }) +} + +#[test] +fn character_escaped() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + assert_eq!(setup(&sm, &sh, "'\\n'".to_string()).next_token(), + mk_lit(token::Char, "\\n", None)); + }) +} + +#[test] +fn lifetime_name() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + assert_eq!(setup(&sm, &sh, "'abc".to_string()).next_token(), + token::Lifetime(Symbol::intern("'abc"))); + }) +} + +#[test] +fn raw_string() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + assert_eq!(setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token(), + mk_lit(token::StrRaw(3), "\"#a\\b\x00c\"", None)); + }) +} + +#[test] +fn literal_suffixes() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + macro_rules! test { + ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ + assert_eq!(setup(&sm, &sh, format!("{}suffix", $input)).next_token(), + mk_lit(token::$tok_type, $tok_contents, Some("suffix"))); + // with a whitespace separator: + assert_eq!(setup(&sm, &sh, format!("{} suffix", $input)).next_token(), + mk_lit(token::$tok_type, $tok_contents, None)); + }} + } + + test!("'a'", Char, "a"); + test!("b'a'", Byte, "a"); + test!("\"a\"", Str, "a"); + test!("b\"a\"", ByteStr, "a"); + test!("1234", Integer, "1234"); + test!("0b101", Integer, "0b101"); + test!("0xABC", Integer, "0xABC"); + test!("1.0", Float, "1.0"); + test!("1.0e10", Float, "1.0e10"); + + assert_eq!(setup(&sm, &sh, "2us".to_string()).next_token(), + mk_lit(token::Integer, "2", Some("us"))); + assert_eq!(setup(&sm, &sh, "r###\"raw\"###suffix".to_string()).next_token(), + mk_lit(token::StrRaw(3), "raw", Some("suffix"))); + assert_eq!(setup(&sm, &sh, "br###\"raw\"###suffix".to_string()).next_token(), + mk_lit(token::ByteStrRaw(3), "raw", Some("suffix"))); + }) +} + +#[test] +fn line_doc_comments() { + assert!(is_doc_comment("///")); + assert!(is_doc_comment("/// blah")); + assert!(!is_doc_comment("////")); +} + +#[test] +fn nested_block_comments() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string()); + assert_eq!(lexer.next_token(), token::Comment); + assert_eq!(lexer.next_token(), mk_lit(token::Char, "a", None)); + }) +} + +#[test] +fn crlf_comments() { + with_default_globals(|| { + let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let sh = mk_sess(sm.clone()); + let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string()); + let comment = lexer.next_token(); + assert_eq!(comment.kind, token::Comment); + assert_eq!((comment.span.lo(), comment.span.hi()), (BytePos(0), BytePos(7))); + assert_eq!(lexer.next_token(), token::Whitespace); + assert_eq!(lexer.next_token(), token::DocComment(Symbol::intern("/// test"))); + }) +} diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs index 99d9d40a45..37e67a2729 100644 --- a/src/libsyntax/parse/lexer/tokentrees.rs +++ b/src/libsyntax/parse/lexer/tokentrees.rs @@ -4,13 +4,14 @@ use crate::print::pprust::token_to_string; use crate::parse::lexer::{StringReader, UnmatchedBrace}; use crate::parse::token::{self, Token}; use crate::parse::PResult; -use crate::tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree, TreeAndJoint}; +use crate::tokenstream::{DelimSpan, IsJoint::{self, *}, TokenStream, TokenTree, TreeAndJoint}; impl<'a> StringReader<'a> { crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec) { let mut tt_reader = TokenTreesReader { string_reader: self, token: Token::dummy(), + joint_to_prev: Joint, open_braces: Vec::new(), unmatched_braces: Vec::new(), matching_delim_spans: Vec::new(), @@ -24,6 +25,7 @@ impl<'a> StringReader<'a> { struct TokenTreesReader<'a> { string_reader: StringReader<'a>, token: Token, + joint_to_prev: IsJoint, /// Stack of open delimiters and their spans. Used for error message. open_braces: Vec<(token::DelimToken, Span)>, unmatched_braces: Vec, @@ -203,21 +205,26 @@ impl<'a> TokenTreesReader<'a> { }, _ => { let tt = TokenTree::Token(self.token.take()); - // Note that testing for joint-ness here is done via the raw - // source span as the joint-ness is a property of the raw source - // rather than wanting to take `override_span` into account. - // Additionally, we actually check if the *next* pair of tokens - // is joint, but this is equivalent to checking the current pair. - let raw = self.string_reader.peek_span_src_raw; self.real_token(); - let is_joint = raw.hi() == self.string_reader.peek_span_src_raw.lo() - && self.token.is_op(); + let is_joint = self.joint_to_prev == Joint && self.token.is_op(); Ok((tt, if is_joint { Joint } else { NonJoint })) } } } fn real_token(&mut self) { - self.token = self.string_reader.real_token(); + self.joint_to_prev = Joint; + loop { + let token = self.string_reader.next_token(); + match token.kind { + token::Whitespace | token::Comment | token::Shebang(_) | token::Unknown(_) => { + self.joint_to_prev = NonJoint; + } + _ => { + self.token = token; + return; + }, + } + } } } diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 94ce6297fb..eaa736c6a3 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -1,10 +1,12 @@ // Characters and their corresponding confusables were collected from // http://www.unicode.org/Public/security/10.0.0/confusables.txt -use syntax_pos::{Span, Pos, NO_EXPANSION}; -use errors::{Applicability, DiagnosticBuilder}; use super::StringReader; +use errors::{Applicability, DiagnosticBuilder}; +use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION, symbol::kw}; +use crate::parse::token; +#[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('
', "Line Separator", ' '), ('
', "Paragraph Separator", ' '), @@ -49,7 +51,7 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('─', "Box Drawings Light Horizontal", '-'), ('━', "Box Drawings Heavy Horizontal", '-'), ('㇐', "CJK Stroke H", '-'), - ('ꟷ', "Latin Epigraphic Letter Dideways", '-'), + ('ꟷ', "Latin Epigraphic Letter Sideways I", '-'), ('ᅳ', "Hangul Jungseong Eu", '-'), ('ㅡ', "Hangul Letter Eu", '-'), ('一', "CJK Unified Ideograph-4E00", '-'), @@ -293,74 +295,99 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('〉', "Right-Pointing Angle Bracket", '>'), ('〉', "Right Angle Bracket", '>'), ('》', "Right Double Angle Bracket", '>'), - ('>', "Fullwidth Greater-Than Sign", '>'), ]; - - -const ASCII_ARRAY: &[(char, &str)] = &[ - (' ', "Space"), - ('_', "Underscore"), - ('-', "Minus/Hyphen"), - (',', "Comma"), - (';', "Semicolon"), - (':', "Colon"), - ('!', "Exclamation Mark"), - ('?', "Question Mark"), - ('.', "Period"), - ('\'', "Single Quote"), - ('"', "Quotation Mark"), - ('(', "Left Parenthesis"), - (')', "Right Parenthesis"), - ('[', "Left Square Bracket"), - (']', "Right Square Bracket"), - ('{', "Left Curly Brace"), - ('}', "Right Curly Brace"), - ('*', "Asterisk"), - ('/', "Slash"), - ('\\', "Backslash"), - ('&', "Ampersand"), - ('+', "Plus Sign"), - ('<', "Less-Than Sign"), - ('=', "Equals Sign"), - ('>', "Greater-Than Sign"), ]; - -crate fn check_for_substitution<'a>(reader: &StringReader<'a>, - ch: char, - err: &mut DiagnosticBuilder<'a>) -> bool { - UNICODE_ARRAY - .iter() - .find(|&&(c, _, _)| c == ch) - .map(|&(_, u_name, ascii_char)| { - let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); - match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { - Some(&(ascii_char, ascii_name)) => { - // special help suggestion for "directed" double quotes - if let Some(s) = reader.peek_delimited('“', '”') { - let msg = format!("Unicode characters '“' (Left Double Quotation Mark) and \ - '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", - ascii_char, ascii_name); - err.span_suggestion( - Span::new(reader.pos, reader.next_pos + Pos::from_usize(s.len()) + - Pos::from_usize('”'.len_utf8()), NO_EXPANSION), - &msg, - format!("\"{}\"", s), - Applicability::MaybeIncorrect); - } else { - let msg = - format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", - ch, u_name, ascii_char, ascii_name); - err.span_suggestion( - span, - &msg, - ascii_char.to_string(), - Applicability::MaybeIncorrect); - } - true - }, - None => { - let msg = format!("substitution character not found for '{}'", ch); - reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); - false - } + ('>', "Fullwidth Greater-Than Sign", '>'), +]; + +// FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs, instead of +// keeping the substitution token in this table. Ideally, this should be inside `rustc_lexer`. +// However, we should first remove compound tokens like `<<` from `rustc_lexer`, and then add +// fancier error recovery to it, as there will be less overall work to do this way. +const ASCII_ARRAY: &[(char, &str, Option)] = &[ + (' ', "Space", Some(token::Whitespace)), + ('_', "Underscore", Some(token::Ident(kw::Underscore, false))), + ('-', "Minus/Hyphen", Some(token::BinOp(token::Minus))), + (',', "Comma", Some(token::Comma)), + (';', "Semicolon", Some(token::Semi)), + (':', "Colon", Some(token::Colon)), + ('!', "Exclamation Mark", Some(token::Not)), + ('?', "Question Mark", Some(token::Question)), + ('.', "Period", Some(token::Dot)), + ('(', "Left Parenthesis", Some(token::OpenDelim(token::Paren))), + (')', "Right Parenthesis", Some(token::CloseDelim(token::Paren))), + ('[', "Left Square Bracket", Some(token::OpenDelim(token::Bracket))), + (']', "Right Square Bracket", Some(token::CloseDelim(token::Bracket))), + ('{', "Left Curly Brace", Some(token::OpenDelim(token::Brace))), + ('}', "Right Curly Brace", Some(token::CloseDelim(token::Brace))), + ('*', "Asterisk", Some(token::BinOp(token::Star))), + ('/', "Slash", Some(token::BinOp(token::Slash))), + ('\\', "Backslash", None), + ('&', "Ampersand", Some(token::BinOp(token::And))), + ('+', "Plus Sign", Some(token::BinOp(token::Plus))), + ('<', "Less-Than Sign", Some(token::Lt)), + ('=', "Equals Sign", Some(token::Eq)), + ('>', "Greater-Than Sign", Some(token::Gt)), + // FIXME: Literals are already lexed by this point, so we can't recover gracefully just by + // spitting the correct token out. + ('\'', "Single Quote", None), + ('"', "Quotation Mark", None), +]; + +crate fn check_for_substitution<'a>( + reader: &StringReader<'a>, + pos: BytePos, + ch: char, + err: &mut DiagnosticBuilder<'a>, +) -> Option { + let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) { + Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char), + None => return None, + }; + + let span = Span::new(pos, pos + Pos::from_usize(ch.len_utf8()), NO_EXPANSION); + + let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) { + Some((_ascii_char, ascii_name, token)) => (ascii_name, token), + None => { + let msg = format!("substitution character not found for '{}'", ch); + reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + return None; } - }).unwrap_or(false) + }; + + // special help suggestion for "directed" double quotes + if let Some(s) = peek_delimited(&reader.src[reader.src_index(pos)..], '“', '”') { + let msg = format!( + "Unicode characters '“' (Left Double Quotation Mark) and \ + '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", + ascii_char, ascii_name + ); + err.span_suggestion( + Span::new( + pos, + pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()), + NO_EXPANSION, + ), + &msg, + format!("\"{}\"", s), + Applicability::MaybeIncorrect, + ); + } else { + let msg = format!( + "Unicode character '{}' ({}) looks like '{}' ({}), but it is not", + ch, u_name, ascii_char, ascii_name + ); + err.span_suggestion(span, &msg, ascii_char.to_string(), Applicability::MaybeIncorrect); + } + token.clone() +} + +/// Extract string if found at current position with given delimiters +fn peek_delimited(text: &str, from_ch: char, to_ch: char) -> Option<&str> { + let mut chars = text.chars(); + let first_char = chars.next()?; + if first_char != from_ch { + return None; + } + let last_char_idx = chars.as_str().find(to_ch)?; + Some(&chars.as_str()[..last_char_idx]) } diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs index ef55bf6b92..6409acba57 100644 --- a/src/libsyntax/parse/literal.rs +++ b/src/libsyntax/parse/literal.rs @@ -4,9 +4,6 @@ use crate::ast::{self, Lit, LitKind}; use crate::parse::parser::Parser; use crate::parse::PResult; use crate::parse::token::{self, Token, TokenKind}; -use crate::parse::unescape::{unescape_char, unescape_byte}; -use crate::parse::unescape::{unescape_str, unescape_byte_str}; -use crate::parse::unescape::{unescape_raw_str, unescape_raw_byte_str}; use crate::print::pprust; use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::{TokenStream, TokenTree}; @@ -15,6 +12,9 @@ use errors::{Applicability, Handler}; use log::debug; use rustc_data_structures::sync::Lrc; use syntax_pos::Span; +use rustc_lexer::unescape::{unescape_char, unescape_byte}; +use rustc_lexer::unescape::{unescape_str, unescape_byte_str}; +use rustc_lexer::unescape::{unescape_raw_str, unescape_raw_byte_str}; use std::ascii; @@ -344,7 +344,7 @@ impl<'a> Parser<'a> { // Pack possible quotes and prefixes from the original literal into // the error literal's symbol so they can be pretty-printed faithfully. let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None); - let symbol = Symbol::intern(&pprust::literal_to_string(suffixless_lit)); + let symbol = Symbol::intern(&suffixless_lit.to_string()); let lit = token::Lit::new(token::Err, symbol, lit.suffix); Lit::from_lit_token(lit, span).map_err(|_| unreachable!()) } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index e19eab371f..80aa7a3526 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -10,9 +10,10 @@ use crate::parse::token::TokenKind; use crate::tokenstream::{TokenStream, TokenTree}; use crate::diagnostics::plugin::ErrorMap; use crate::print::pprust; +use crate::symbol::Symbol; use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; -use rustc_data_structures::sync::{Lrc, Lock}; +use rustc_data_structures::sync::{Lrc, Lock, Once}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; use syntax_pos::edition::Edition; @@ -21,7 +22,8 @@ use std::borrow::Cow; use std::path::{Path, PathBuf}; use std::str; -pub type PResult<'a, T> = Result>; +#[cfg(test)] +mod tests; #[macro_use] pub mod parser; @@ -32,9 +34,10 @@ pub mod token; crate mod classify; crate mod diagnostics; crate mod literal; -crate mod unescape; crate mod unescape_error_reporting; +pub type PResult<'a, T> = Result>; + /// Info about a parsing session. pub struct ParseSess { pub span_diagnostic: Handler, @@ -57,6 +60,9 @@ pub struct ParseSess { pub param_attr_spans: Lock>, // Places where `let` exprs were used and should be feature gated according to `let_chains`. pub let_chains_spans: Lock>, + // Places where `async || ..` exprs were used and should be feature gated. + pub async_closure_spans: Lock>, + pub injected_crate_name: Once, } impl ParseSess { @@ -84,6 +90,8 @@ impl ParseSess { ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), param_attr_spans: Lock::new(Vec::new()), let_chains_spans: Lock::new(Vec::new()), + async_closure_spans: Lock::new(Vec::new()), + injected_crate_name: Once::new(), } } @@ -305,7 +313,7 @@ pub fn maybe_file_to_stream( source_file: Lrc, override_span: Option, ) -> Result<(TokenStream, Vec), Vec> { - let srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?; + let srdr = lexer::StringReader::new(sess, source_file, override_span); let (token_trees, unmatched_braces) = srdr.into_token_trees(); match token_trees { @@ -363,7 +371,7 @@ pub fn stream_to_parser_with_base_dir<'a>( /// A sequence separator. pub struct SeqSep { - /// The seperator token. + /// The separator token. pub sep: Option, /// `true` if a trailing separator is allowed. pub trailing_sep_allowed: bool, @@ -384,294 +392,3 @@ impl SeqSep { } } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::ast::{self, Name, PatKind}; - use crate::attr::first_attr_value_str_by_name; - use crate::ptr::P; - use crate::parse::token::Token; - use crate::print::pprust::item_to_string; - use crate::symbol::{kw, sym}; - use crate::tokenstream::{DelimSpan, TokenTree}; - use crate::util::parser_testing::string_to_stream; - use crate::util::parser_testing::{string_to_expr, string_to_item}; - use crate::with_default_globals; - use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION}; - - /// Parses an item. - /// - /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err` - /// when a syntax error occurred. - fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess) - -> PResult<'_, Option>> { - new_parser_from_source_str(sess, name, source).parse_item() - } - - // produce a syntax_pos::span - fn sp(a: u32, b: u32) -> Span { - Span::new(BytePos(a), BytePos(b), NO_EXPANSION) - } - - #[should_panic] - #[test] fn bad_path_expr_1() { - with_default_globals(|| { - string_to_expr("::abc::def::return".to_string()); - }) - } - - // check the token-tree-ization of macros - #[test] - fn string_to_tts_macro () { - with_default_globals(|| { - let tts: Vec<_> = - string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect(); - let tts: &[TokenTree] = &tts[..]; - - match tts { - [ - TokenTree::Token(Token { kind: token::Ident(name_macro_rules, false), .. }), - TokenTree::Token(Token { kind: token::Not, .. }), - TokenTree::Token(Token { kind: token::Ident(name_zip, false), .. }), - TokenTree::Delimited(_, macro_delim, macro_tts) - ] - if name_macro_rules == &sym::macro_rules && name_zip.as_str() == "zip" => { - let tts = ¯o_tts.trees().collect::>(); - match &tts[..] { - [ - TokenTree::Delimited(_, first_delim, first_tts), - TokenTree::Token(Token { kind: token::FatArrow, .. }), - TokenTree::Delimited(_, second_delim, second_tts), - ] - if macro_delim == &token::Paren => { - let tts = &first_tts.trees().collect::>(); - match &tts[..] { - [ - TokenTree::Token(Token { kind: token::Dollar, .. }), - TokenTree::Token(Token { kind: token::Ident(name, false), .. }), - ] - if first_delim == &token::Paren && name.as_str() == "a" => {}, - _ => panic!("value 3: {:?} {:?}", first_delim, first_tts), - } - let tts = &second_tts.trees().collect::>(); - match &tts[..] { - [ - TokenTree::Token(Token { kind: token::Dollar, .. }), - TokenTree::Token(Token { kind: token::Ident(name, false), .. }), - ] - if second_delim == &token::Paren && name.as_str() == "a" => {}, - _ => panic!("value 4: {:?} {:?}", second_delim, second_tts), - } - }, - _ => panic!("value 2: {:?} {:?}", macro_delim, macro_tts), - } - }, - _ => panic!("value: {:?}",tts), - } - }) - } - - #[test] - fn string_to_tts_1() { - with_default_globals(|| { - let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); - - let expected = TokenStream::new(vec![ - TokenTree::token(token::Ident(kw::Fn, false), sp(0, 2)).into(), - TokenTree::token(token::Ident(Name::intern("a"), false), sp(3, 4)).into(), - TokenTree::Delimited( - DelimSpan::from_pair(sp(5, 6), sp(13, 14)), - token::DelimToken::Paren, - TokenStream::new(vec![ - TokenTree::token(token::Ident(Name::intern("b"), false), sp(6, 7)).into(), - TokenTree::token(token::Colon, sp(8, 9)).into(), - TokenTree::token(token::Ident(sym::i32, false), sp(10, 13)).into(), - ]).into(), - ).into(), - TokenTree::Delimited( - DelimSpan::from_pair(sp(15, 16), sp(20, 21)), - token::DelimToken::Brace, - TokenStream::new(vec![ - TokenTree::token(token::Ident(Name::intern("b"), false), sp(17, 18)).into(), - TokenTree::token(token::Semi, sp(18, 19)).into(), - ]).into(), - ).into() - ]); - - assert_eq!(tts, expected); - }) - } - - #[test] fn parse_use() { - with_default_globals(|| { - let use_s = "use foo::bar::baz;"; - let vitem = string_to_item(use_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], use_s); - - let use_s = "use foo::bar as baz;"; - let vitem = string_to_item(use_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], use_s); - }) - } - - #[test] fn parse_extern_crate() { - with_default_globals(|| { - let ex_s = "extern crate foo;"; - let vitem = string_to_item(ex_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], ex_s); - - let ex_s = "extern crate foo as bar;"; - let vitem = string_to_item(ex_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], ex_s); - }) - } - - fn get_spans_of_pat_idents(src: &str) -> Vec { - let item = string_to_item(src.to_string()).unwrap(); - - struct PatIdentVisitor { - spans: Vec - } - impl<'a> crate::visit::Visitor<'a> for PatIdentVisitor { - fn visit_pat(&mut self, p: &'a ast::Pat) { - match p.node { - PatKind::Ident(_ , ref spannedident, _) => { - self.spans.push(spannedident.span.clone()); - } - _ => { - crate::visit::walk_pat(self, p); - } - } - } - } - let mut v = PatIdentVisitor { spans: Vec::new() }; - crate::visit::walk_item(&mut v, &item); - return v.spans; - } - - #[test] fn span_of_self_arg_pat_idents_are_correct() { - with_default_globals(|| { - - let srcs = ["impl z { fn a (&self, &myarg: i32) {} }", - "impl z { fn a (&mut self, &myarg: i32) {} }", - "impl z { fn a (&'a self, &myarg: i32) {} }", - "impl z { fn a (self, &myarg: i32) {} }", - "impl z { fn a (self: Foo, &myarg: i32) {} }", - ]; - - for &src in &srcs { - let spans = get_spans_of_pat_idents(src); - let (lo, hi) = (spans[0].lo(), spans[0].hi()); - assert!("self" == &src[lo.to_usize()..hi.to_usize()], - "\"{}\" != \"self\". src=\"{}\"", - &src[lo.to_usize()..hi.to_usize()], src) - } - }) - } - - #[test] fn parse_exprs () { - with_default_globals(|| { - // just make sure that they parse.... - string_to_expr("3 + 4".to_string()); - string_to_expr("a::z.froob(b,&(987+3))".to_string()); - }) - } - - #[test] fn attrs_fix_bug () { - with_default_globals(|| { - string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) - -> Result, String> { - #[cfg(windows)] - fn wb() -> c_int { - (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int - } - - #[cfg(unix)] - fn wb() -> c_int { O_WRONLY as c_int } - - let mut fflags: c_int = wb(); -}".to_string()); - }) - } - - #[test] fn crlf_doc_comments() { - with_default_globals(|| { - let sess = ParseSess::new(FilePathMapping::empty()); - - let name_1 = FileName::Custom("crlf_source_1".to_string()); - let source = "/// doc comment\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name_1, source, &sess) - .unwrap().unwrap(); - let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap(); - assert_eq!(doc.as_str(), "/// doc comment"); - - let name_2 = FileName::Custom("crlf_source_2".to_string()); - let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name_2, source, &sess) - .unwrap().unwrap(); - let docs = item.attrs.iter().filter(|a| a.path == sym::doc) - .map(|a| a.value_str().unwrap().to_string()).collect::>(); - let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; - assert_eq!(&docs[..], b); - - let name_3 = FileName::Custom("clrf_source_3".to_string()); - let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap(); - let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap(); - assert_eq!(doc.as_str(), "/** doc comment\n * with CRLF */"); - }); - } - - #[test] - fn ttdelim_span() { - fn parse_expr_from_source_str( - name: FileName, source: String, sess: &ParseSess - ) -> PResult<'_, P> { - new_parser_from_source_str(sess, name, source).parse_expr() - } - - with_default_globals(|| { - let sess = ParseSess::new(FilePathMapping::empty()); - let expr = parse_expr_from_source_str(PathBuf::from("foo").into(), - "foo!( fn main() { body } )".to_string(), &sess).unwrap(); - - let tts: Vec<_> = match expr.node { - ast::ExprKind::Mac(ref mac) => mac.node.stream().trees().collect(), - _ => panic!("not a macro"), - }; - - let span = tts.iter().rev().next().unwrap().span(); - - match sess.source_map().span_to_snippet(span) { - Ok(s) => assert_eq!(&s[..], "{ body }"), - Err(_) => panic!("could not get snippet"), - } - }); - } - - // This tests that when parsing a string (rather than a file) we don't try - // and read in a file for a module declaration and just parse a stub. - // See `recurse_into_file_modules` in the parser. - #[test] - fn out_of_line_mod() { - with_default_globals(|| { - let sess = ParseSess::new(FilePathMapping::empty()); - let item = parse_item_from_source_str( - PathBuf::from("foo").into(), - "mod foo { struct S; mod this_does_not_exist; }".to_owned(), - &sess, - ).unwrap().unwrap(); - - if let ast::ItemKind::Mod(ref m) = item.node { - assert!(m.items.len() == 2); - } else { - panic!(); - } - }); - } -} diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b2e319a478..1c1428c571 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1,47 +1,25 @@ -// ignore-tidy-filelength - -use crate::ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy}; -use crate::ast::{GenericBound, TraitBoundModifier}; -use crate::ast::Unsafety; -use crate::ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind}; -use crate::ast::Block; -use crate::ast::{BlockCheckMode, CaptureBy, Movability}; -use crate::ast::{Constness, Crate}; -use crate::ast::Defaultness; -use crate::ast::EnumDef; -use crate::ast::{Expr, ExprKind, RangeLimits}; -use crate::ast::{Field, FnDecl, FnHeader}; -use crate::ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; -use crate::ast::{GenericParam, GenericParamKind}; -use crate::ast::GenericArg; -use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind}; -use crate::ast::{Label, Lifetime}; -use crate::ast::Local; -use crate::ast::MacStmtStyle; -use crate::ast::{Mac, Mac_, MacDelimiter}; -use crate::ast::{MutTy, Mutability}; -use crate::ast::{Pat, PatKind, PathSegment}; -use crate::ast::{PolyTraitRef, QSelf}; -use crate::ast::{Stmt, StmtKind}; -use crate::ast::{VariantData, StructField}; -use crate::ast::StrStyle; -use crate::ast::SelfKind; -use crate::ast::{TraitItem, TraitRef, TraitObjectSyntax}; -use crate::ast::{Ty, TyKind, AssocTyConstraint, AssocTyConstraintKind, GenericBounds}; -use crate::ast::{Visibility, VisibilityKind, WhereClause, CrateSugar}; -use crate::ast::{UseTree, UseTreeKind}; -use crate::ast::{BinOpKind, UnOp}; -use crate::ast::{RangeEnd, RangeSyntax}; -use crate::{ast, attr}; -use crate::ext::base::DummyResult; +mod expr; +mod pat; +mod item; +pub use item::AliasKind; +mod module; +pub use module::{ModulePath, ModulePathSuccess}; +mod ty; +mod path; +pub use path::PathStyle; +mod stmt; +mod generics; + +use crate::ast::{self, AttrStyle, Attribute, Arg, BindingMode, StrStyle, SelfKind}; +use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind}; +use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar}; use crate::ext::hygiene::SyntaxContext; -use crate::source_map::{self, SourceMap, Spanned, respan}; -use crate::parse::{SeqSep, classify, literal, token}; +use crate::source_map::{self, respan}; +use crate::parse::{SeqSep, literal, token}; use crate::parse::lexer::UnmatchedBrace; use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use crate::parse::token::{Token, TokenKind, DelimToken}; -use crate::parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership}; -use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par}; +use crate::parse::{ParseSess, Directory, DirectoryOwnership}; use crate::print::pprust; use crate::ptr::P; use crate::parse::PResult; @@ -50,25 +28,14 @@ use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use crate::symbol::{kw, sym, Symbol}; use crate::parse::diagnostics::{Error, dummy_arg}; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; +use errors::{Applicability, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; use log::debug; use std::borrow::Cow; -use std::cmp; -use std::mem; -use std::path::{self, Path, PathBuf}; -use std::slice; - -#[derive(Debug)] -/// Whether the type alias or associated type is a concrete type or an existential type -pub enum AliasKind { - /// Just a new name for the same type - Weak(P), - /// Only trait impls of the type will be usable, not the actual type itself - Existential(GenericBounds), -} +use std::{cmp, mem, slice}; +use std::path::PathBuf; bitflags::bitflags! { struct Restrictions: u8 { @@ -77,31 +44,6 @@ bitflags::bitflags! { } } -type ItemInfo = (Ident, ItemKind, Option>); - -/// Specifies how to parse a path. -#[derive(Copy, Clone, PartialEq)] -pub enum PathStyle { - /// In some contexts, notably in expressions, paths with generic arguments are ambiguous - /// with something else. For example, in expressions `segment < ....` can be interpreted - /// as a comparison and `segment ( ....` can be interpreted as a function call. - /// In all such contexts the non-path interpretation is preferred by default for practical - /// reasons, but the path interpretation can be forced by the disambiguator `::`, e.g. - /// `x` - comparisons, `x::` - unambiguously a path. - Expr, - /// In other contexts, notably in types, no ambiguity exists and paths can be written - /// without the disambiguator, e.g., `x` - unambiguously a path. - /// Paths with disambiguators are still accepted, `x::` - unambiguously a path too. - Type, - /// A path with generic arguments disallowed, e.g., `foo::bar::Baz`, used in imports, - /// visibilities or attributes. - /// Technically, this variant is unnecessary and e.g., `Expr` can be used instead - /// (paths in "mod" contexts have to be checked later for absence of generic arguments - /// anyway, due to macros), but it is used to avoid weird suggestions about expected - /// tokens when something goes wrong. - Mod, -} - #[derive(Clone, Copy, PartialEq, Debug)] crate enum SemiColonMode { Break, @@ -115,41 +57,8 @@ crate enum BlockMode { Ignore, } -/// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression -/// dropped into the token stream, which happens while parsing the result of -/// macro expansion). Placement of these is not as complex as I feared it would -/// be. The important thing is to make sure that lookahead doesn't balk at -/// `token::Interpolated` tokens. -macro_rules! maybe_whole_expr { - ($p:expr) => { - if let token::Interpolated(nt) = &$p.token.kind { - match &**nt { - token::NtExpr(e) | token::NtLiteral(e) => { - let e = e.clone(); - $p.bump(); - return Ok(e); - } - token::NtPath(path) => { - let path = path.clone(); - $p.bump(); - return Ok($p.mk_expr( - $p.token.span, ExprKind::Path(None, path), ThinVec::new() - )); - } - token::NtBlock(block) => { - let block = block.clone(); - $p.bump(); - return Ok($p.mk_expr( - $p.token.span, ExprKind::Block(block, None), ThinVec::new() - )); - } - _ => {}, - }; - } - } -} - /// As maybe_whole_expr, but for things other than expressions +#[macro_export] macro_rules! maybe_whole { ($p:expr, $constructor:ident, |$x:ident| $e:expr) => { if let token::Interpolated(nt) = &$p.token.kind { @@ -163,6 +72,7 @@ macro_rules! maybe_whole { } /// If the next tokens are ill-formed `$ty::` recover them as `<$ty>::`. +#[macro_export] macro_rules! maybe_recover_from_interpolated_ty_qpath { ($self: expr, $allow_qpath_recovery: expr) => { if $allow_qpath_recovery && $self.look_ahead(1, |t| t == &token::ModSep) { @@ -239,6 +149,7 @@ pub struct Parser<'a> { /// error. crate unclosed_delims: Vec, crate last_unexpected_token_span: Option, + crate last_type_ascription: Option<(Span, bool /* likely path typo */)>, /// If present, this `Parser` is not parsing Rust code but rather a macro call. crate subparser_name: Option<&'static str>, } @@ -413,52 +324,6 @@ impl TokenType { } } -/// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, -/// `IDENT<::AssocTy>`. -/// -/// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes -/// that `IDENT` is not the ident of a fn trait. -fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { - t == &token::ModSep || t == &token::Lt || - t == &token::BinOp(token::Shl) -} - -/// Information about the path to a module. -pub struct ModulePath { - name: String, - path_exists: bool, - pub result: Result, -} - -pub struct ModulePathSuccess { - pub path: PathBuf, - pub directory_ownership: DirectoryOwnership, - warn: bool, -} - -#[derive(Debug)] -enum LhsExpr { - NotYetParsed, - AttributesParsed(ThinVec), - AlreadyParsed(P), -} - -impl From>> for LhsExpr { - fn from(o: Option>) -> Self { - if let Some(attrs) = o { - LhsExpr::AttributesParsed(attrs) - } else { - LhsExpr::NotYetParsed - } - } -} - -impl From> for LhsExpr { - fn from(expr: P) -> Self { - LhsExpr::AlreadyParsed(expr) - } -} - #[derive(Copy, Clone, Debug)] crate enum TokenExpectType { Expect, @@ -502,6 +367,7 @@ impl<'a> Parser<'a> { max_angle_bracket_count: 0, unclosed_delims: Vec::new(), last_unexpected_token_span: None, + last_type_ascription: None, subparser_name, }; @@ -599,20 +465,6 @@ impl<'a> Parser<'a> { } } - /// Returns the span of expr, if it was not interpolated or the span of the interpolated token. - fn interpolated_or_expr_span( - &self, - expr: PResult<'a, P>, - ) -> PResult<'a, (Span, P)> { - expr.map(|e| { - if self.prev_token_kind == PrevTokenKind::Interpolated { - (self.prev_span, e) - } else { - (e.span, e) - } - }) - } - pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.parse_ident_common(true) } @@ -752,7 +604,6 @@ impl<'a> Parser<'a> { } } - /// Checks to see if the next token is either `+` or `+=`. /// Otherwise returns `false`. fn check_plus(&mut self) -> bool { @@ -888,14 +739,13 @@ impl<'a> Parser<'a> { /// Parses a sequence, including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_seq_to_end(&mut self, - ket: &TokenKind, - sep: SeqSep, - f: F) - -> PResult<'a, Vec> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, - { - let (val, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; + pub fn parse_seq_to_end( + &mut self, + ket: &TokenKind, + sep: SeqSep, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, Vec> { + let (val, _, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; if !recovered { self.bump(); } @@ -905,39 +755,39 @@ impl<'a> Parser<'a> { /// Parses a sequence, not including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_seq_to_before_end( + pub fn parse_seq_to_before_end( &mut self, ket: &TokenKind, sep: SeqSep, - f: F, - ) -> PResult<'a, (Vec, bool)> - where F: FnMut(&mut Parser<'a>) -> PResult<'a, T> - { + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool, bool)> { self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f) } - crate fn parse_seq_to_before_tokens( + fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool { + kets.iter().any(|k| { + match expect { + TokenExpectType::Expect => self.check(k), + TokenExpectType::NoExpect => self.token == **k, + } + }) + } + + crate fn parse_seq_to_before_tokens( &mut self, kets: &[&TokenKind], sep: SeqSep, expect: TokenExpectType, - mut f: F, - ) -> PResult<'a, (Vec, bool /* recovered */)> - where F: FnMut(&mut Parser<'a>) -> PResult<'a, T> - { + mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool /* trailing */, bool /* recovered */)> { let mut first = true; let mut recovered = false; + let mut trailing = false; let mut v = vec![]; - while !kets.iter().any(|k| { - match expect { - TokenExpectType::Expect => self.check(k), - TokenExpectType::NoExpect => self.token == **k, - } - }) { - match self.token.kind { - token::CloseDelim(..) | token::Eof => break, - _ => {} - }; + while !self.expect_any_with_type(kets, expect) { + if let token::CloseDelim(..) | token::Eof = self.token.kind { + break + } if let Some(ref t) = sep.sep { if first { first = false; @@ -971,12 +821,8 @@ impl<'a> Parser<'a> { } } } - if sep.trailing_sep_allowed && kets.iter().any(|k| { - match expect { - TokenExpectType::Expect => self.check(k), - TokenExpectType::NoExpect => self.token == **k, - } - }) { + if sep.trailing_sep_allowed && self.expect_any_with_type(kets, expect) { + trailing = true; break; } @@ -984,27 +830,45 @@ impl<'a> Parser<'a> { v.push(t); } - Ok((v, recovered)) + Ok((v, trailing, recovered)) } /// Parses a sequence, including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. - fn parse_unspanned_seq( + fn parse_unspanned_seq( &mut self, bra: &TokenKind, ket: &TokenKind, sep: SeqSep, - f: F, - ) -> PResult<'a, Vec> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, - { + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool)> { self.expect(bra)?; - let (result, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; + let (result, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; if !recovered { self.eat(ket); } - Ok(result) + Ok((result, trailing)) + } + + fn parse_delim_comma_seq( + &mut self, + delim: DelimToken, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool)> { + self.parse_unspanned_seq( + &token::OpenDelim(delim), + &token::CloseDelim(delim), + SeqSep::trailing_allowed(token::Comma), + f, + ) + } + + fn parse_paren_comma_seq( + &mut self, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool)> { + self.parse_delim_comma_seq(token::Paren, f) } /// Advance the parser by one token @@ -1069,50 +933,6 @@ impl<'a> Parser<'a> { self.look_ahead(dist, |t| kws.iter().any(|&kw| t.is_keyword(kw))) } - /// Is the current token one of the keywords that signals a bare function type? - fn token_is_bare_fn_keyword(&mut self) -> bool { - self.check_keyword(kw::Fn) || - self.check_keyword(kw::Unsafe) || - self.check_keyword(kw::Extern) - } - - /// Parses a `TyKind::BareFn` type. - fn parse_ty_bare_fn(&mut self, generic_params: Vec) -> PResult<'a, TyKind> { - /* - - [unsafe] [extern "ABI"] fn (S) -> T - ^~~~^ ^~~~^ ^~^ ^ - | | | | - | | | Return type - | | Argument types - | | - | ABI - Function Style - */ - - let unsafety = self.parse_unsafety(); - let abi = if self.eat_keyword(kw::Extern) { - self.parse_opt_abi()?.unwrap_or(Abi::C) - } else { - Abi::Rust - }; - - self.expect_keyword(kw::Fn)?; - let (inputs, c_variadic) = self.parse_fn_args(false, true)?; - let ret_ty = self.parse_ret_ty(false)?; - let decl = P(FnDecl { - inputs, - output: ret_ty, - c_variadic, - }); - Ok(TyKind::BareFn(P(BareFnTy { - abi, - unsafety, - generic_params, - decl, - }))) - } - /// Parses asyncness: `async` or nothing. fn parse_asyncness(&mut self) -> IsAsync { if self.eat_keyword(kw::Async) { @@ -1134,342 +954,6 @@ impl<'a> Parser<'a> { } } - /// Parses the items in a trait declaration. - pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> { - maybe_whole!(self, NtTraitItem, |x| x); - let attrs = self.parse_outer_attributes()?; - let mut unclosed_delims = vec![]; - let (mut item, tokens) = self.collect_tokens(|this| { - let item = this.parse_trait_item_(at_end, attrs); - unclosed_delims.append(&mut this.unclosed_delims); - item - })?; - self.unclosed_delims.append(&mut unclosed_delims); - // See `parse_item` for why this clause is here. - if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) { - item.tokens = Some(tokens); - } - Ok(item) - } - - fn parse_trait_item_(&mut self, - at_end: &mut bool, - mut attrs: Vec) -> PResult<'a, TraitItem> { - let lo = self.token.span; - self.eat_bad_pub(); - let (name, node, generics) = if self.eat_keyword(kw::Type) { - self.parse_trait_item_assoc_ty()? - } else if self.is_const_item() { - self.expect_keyword(kw::Const)?; - let ident = self.parse_ident()?; - self.expect(&token::Colon)?; - let ty = self.parse_ty()?; - let default = if self.eat(&token::Eq) { - let expr = self.parse_expr()?; - self.expect(&token::Semi)?; - Some(expr) - } else { - self.expect(&token::Semi)?; - None - }; - (ident, TraitItemKind::Const(ty, default), ast::Generics::default()) - } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? { - // trait item macro. - (Ident::invalid(), ast::TraitItemKind::Macro(mac), ast::Generics::default()) - } else { - let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?; - - let ident = self.parse_ident()?; - let mut generics = self.parse_generics()?; - - let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| { - // This is somewhat dubious; We don't want to allow - // argument names to be left off if there is a - // definition... - - // We don't allow argument names to be left off in edition 2018. - let is_name_required = p.token.span.rust_2018(); - p.parse_arg_general(true, false, |_| is_name_required) - })?; - generics.where_clause = self.parse_where_clause()?; - - let sig = ast::MethodSig { - header: FnHeader { - unsafety, - constness, - abi, - asyncness, - }, - decl, - }; - - let body = match self.token.kind { - token::Semi => { - self.bump(); - *at_end = true; - debug!("parse_trait_methods(): parsing required method"); - None - } - token::OpenDelim(token::Brace) => { - debug!("parse_trait_methods(): parsing provided method"); - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) - } - token::Interpolated(ref nt) => { - match **nt { - token::NtBlock(..) => { - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) - } - _ => { - return self.expected_semi_or_open_brace(); - } - } - } - _ => { - return self.expected_semi_or_open_brace(); - } - }; - (ident, ast::TraitItemKind::Method(sig, body), generics) - }; - - Ok(TraitItem { - id: ast::DUMMY_NODE_ID, - ident: name, - attrs, - generics, - node, - span: lo.to(self.prev_span), - tokens: None, - }) - } - - /// Parses an optional return type `[ -> TY ]` in a function declaration. - fn parse_ret_ty(&mut self, allow_plus: bool) -> PResult<'a, FunctionRetTy> { - if self.eat(&token::RArrow) { - Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true, false)?)) - } else { - Ok(FunctionRetTy::Default(self.token.span.shrink_to_lo())) - } - } - - /// Parses a type. - pub fn parse_ty(&mut self) -> PResult<'a, P> { - self.parse_ty_common(true, true, false) - } - - /// Parses a type in restricted contexts where `+` is not permitted. - /// - /// Example 1: `&'a TYPE` - /// `+` is prohibited to maintain operator priority (P(+) < P(&)). - /// Example 2: `value1 as TYPE + value2` - /// `+` is prohibited to avoid interactions with expression grammar. - fn parse_ty_no_plus(&mut self) -> PResult<'a, P> { - self.parse_ty_common(false, true, false) - } - - fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool, - allow_c_variadic: bool) -> PResult<'a, P> { - maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); - maybe_whole!(self, NtTy, |x| x); - - let lo = self.token.span; - let mut impl_dyn_multi = false; - let node = if self.eat(&token::OpenDelim(token::Paren)) { - // `(TYPE)` is a parenthesized type. - // `(TYPE,)` is a tuple with a single field of type TYPE. - let mut ts = vec![]; - let mut last_comma = false; - while self.token != token::CloseDelim(token::Paren) { - ts.push(self.parse_ty()?); - if self.eat(&token::Comma) { - last_comma = true; - } else { - last_comma = false; - break; - } - } - let trailing_plus = self.prev_token_kind == PrevTokenKind::Plus; - self.expect(&token::CloseDelim(token::Paren))?; - - if ts.len() == 1 && !last_comma { - let ty = ts.into_iter().nth(0).unwrap().into_inner(); - let maybe_bounds = allow_plus && self.token.is_like_plus(); - match ty.node { - // `(TY_BOUND_NOPAREN) + BOUND + ...`. - TyKind::Path(None, ref path) if maybe_bounds => { - self.parse_remaining_bounds(Vec::new(), path.clone(), lo, true)? - } - TyKind::TraitObject(ref bounds, TraitObjectSyntax::None) - if maybe_bounds && bounds.len() == 1 && !trailing_plus => { - let path = match bounds[0] { - GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(), - GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"), - }; - self.parse_remaining_bounds(Vec::new(), path, lo, true)? - } - // `(TYPE)` - _ => TyKind::Paren(P(ty)) - } - } else { - TyKind::Tup(ts) - } - } else if self.eat(&token::Not) { - // Never type `!` - TyKind::Never - } else if self.eat(&token::BinOp(token::Star)) { - // Raw pointer - TyKind::Ptr(self.parse_ptr()?) - } else if self.eat(&token::OpenDelim(token::Bracket)) { - // Array or slice - let t = self.parse_ty()?; - // Parse optional `; EXPR` in `[TYPE; EXPR]` - let t = match self.maybe_parse_fixed_length_of_vec()? { - None => TyKind::Slice(t), - Some(length) => TyKind::Array(t, AnonConst { - id: ast::DUMMY_NODE_ID, - value: length, - }), - }; - self.expect(&token::CloseDelim(token::Bracket))?; - t - } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) { - // Reference - self.expect_and()?; - self.parse_borrowed_pointee()? - } else if self.eat_keyword_noexpect(kw::Typeof) { - // `typeof(EXPR)` - // In order to not be ambiguous, the type must be surrounded by parens. - self.expect(&token::OpenDelim(token::Paren))?; - let e = AnonConst { - id: ast::DUMMY_NODE_ID, - value: self.parse_expr()?, - }; - self.expect(&token::CloseDelim(token::Paren))?; - TyKind::Typeof(e) - } else if self.eat_keyword(kw::Underscore) { - // A type to be inferred `_` - TyKind::Infer - } else if self.token_is_bare_fn_keyword() { - // Function pointer type - self.parse_ty_bare_fn(Vec::new())? - } else if self.check_keyword(kw::For) { - // Function pointer type or bound list (trait object type) starting with a poly-trait. - // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` - // `for<'lt> Trait1<'lt> + Trait2 + 'a` - let lo = self.token.span; - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; - if self.token_is_bare_fn_keyword() { - self.parse_ty_bare_fn(lifetime_defs)? - } else { - let path = self.parse_path(PathStyle::Type)?; - let parse_plus = allow_plus && self.check_plus(); - self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)? - } - } else if self.eat_keyword(kw::Impl) { - // Always parse bounds greedily for better error recovery. - let bounds = self.parse_generic_bounds(None)?; - impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus; - TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) - } else if self.check_keyword(kw::Dyn) && - (self.token.span.rust_2018() || - self.look_ahead(1, |t| t.can_begin_bound() && - !can_continue_type_after_non_fn_ident(t))) { - self.bump(); // `dyn` - // Always parse bounds greedily for better error recovery. - let bounds = self.parse_generic_bounds(None)?; - impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus; - TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) - } else if self.check(&token::Question) || - self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus()) { - // Bound list (trait object type) - TyKind::TraitObject(self.parse_generic_bounds_common(allow_plus, None)?, - TraitObjectSyntax::None) - } else if self.eat_lt() { - // Qualified path - let (qself, path) = self.parse_qpath(PathStyle::Type)?; - TyKind::Path(Some(qself), path) - } else if self.token.is_path_start() { - // Simple path - let path = self.parse_path(PathStyle::Type)?; - if self.eat(&token::Not) { - // Macro invocation in type position - let (delim, tts) = self.expect_delimited_token_tree()?; - let node = Mac_ { path, tts, delim }; - TyKind::Mac(respan(lo.to(self.prev_span), node)) - } else { - // Just a type path or bound list (trait object type) starting with a trait. - // `Type` - // `Trait1 + Trait2 + 'a` - if allow_plus && self.check_plus() { - self.parse_remaining_bounds(Vec::new(), path, lo, true)? - } else { - TyKind::Path(None, path) - } - } - } else if self.check(&token::DotDotDot) { - if allow_c_variadic { - self.eat(&token::DotDotDot); - TyKind::CVarArgs - } else { - return Err(self.fatal( - "only foreign functions are allowed to be C-variadic" - )); - } - } else { - let msg = format!("expected type, found {}", self.this_token_descr()); - return Err(self.fatal(&msg)); - }; - - let span = lo.to(self.prev_span); - let ty = P(Ty { node, span, id: ast::DUMMY_NODE_ID }); - - // Try to recover from use of `+` with incorrect priority. - self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty); - self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?; - self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery) - } - - fn parse_remaining_bounds(&mut self, generic_params: Vec, path: ast::Path, - lo: Span, parse_plus: bool) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span)); - let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; - if parse_plus { - self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded - bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?); - } - Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) - } - - fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { - let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None }; - let mutbl = self.parse_mutability(); - let ty = self.parse_ty_no_plus()?; - return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty, mutbl })); - } - - fn parse_ptr(&mut self) -> PResult<'a, MutTy> { - let mutbl = if self.eat_keyword(kw::Mut) { - Mutability::Mutable - } else if self.eat_keyword(kw::Const) { - Mutability::Immutable - } else { - let span = self.prev_span; - let msg = "expected mut or const in raw pointer type"; - self.struct_span_err(span, msg) - .span_label(span, msg) - .help("use `*mut T` or `*const T` as appropriate") - .emit(); - Mutability::Immutable - }; - let t = self.parse_ty_no_plus()?; - Ok(MutTy { ty: t, mutbl }) - } - fn is_named_argument(&self) -> bool { let offset = match self.token.kind { token::Interpolated(ref nt) => match **nt { @@ -1497,6 +981,7 @@ impl<'a> Parser<'a> { where F: Fn(&token::Token) -> bool { + let lo = self.token.span; let attrs = self.parse_arg_attributes()?; if let Some(mut arg) = self.parse_self_arg()? { arg.attrs = attrs.into(); @@ -1538,12 +1023,8 @@ impl<'a> Parser<'a> { match ty { Ok(ty) => { let ident = Ident::new(kw::Invalid, self.prev_span); - let pat = P(Pat { - id: ast::DUMMY_NODE_ID, - node: PatKind::Ident( - BindingMode::ByValue(Mutability::Immutable), ident, None), - span: ty.span, - }); + let bm = BindingMode::ByValue(Mutability::Immutable); + let pat = self.mk_pat_ident(ty.span, bm, ident); (pat, ty) } Err(mut err) => { @@ -1560,5468 +1041,468 @@ impl<'a> Parser<'a> { } }; - Ok(Arg { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, ty }) + let span = lo.to(self.token.span); + + Ok(Arg { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, span, ty }) } - /// Parses an argument in a lambda header (e.g., `|arg, arg|`). - fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> { - let attrs = self.parse_arg_attributes()?; - let pat = self.parse_pat(Some("argument name"))?; - let t = if self.eat(&token::Colon) { - self.parse_ty()? + /// Parses mutability (`mut` or nothing). + fn parse_mutability(&mut self) -> Mutability { + if self.eat_keyword(kw::Mut) { + Mutability::Mutable } else { - P(Ty { - id: ast::DUMMY_NODE_ID, - node: TyKind::Infer, - span: self.prev_span, - }) - }; - Ok(Arg { - attrs: attrs.into(), - ty: t, - pat, - id: ast::DUMMY_NODE_ID - }) + Mutability::Immutable + } } - fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option>> { - if self.eat(&token::Semi) { - Ok(Some(self.parse_expr()?)) + fn parse_field_name(&mut self) -> PResult<'a, Ident> { + if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) = + self.token.kind { + self.expect_no_suffix(self.token.span, "a tuple index", suffix); + self.bump(); + Ok(Ident::new(symbol, self.prev_span)) } else { - Ok(None) + self.parse_ident_common(false) } } - /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). - crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P> { - maybe_whole_expr!(self); + fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, TokenStream)> { + let delim = match self.token.kind { + token::OpenDelim(delim) => delim, + _ => { + let msg = "expected open delimiter"; + let mut err = self.fatal(msg); + err.span_label(self.token.span, msg); + return Err(err) + } + }; + let tts = match self.parse_token_tree() { + TokenTree::Delimited(_, _, tts) => tts, + _ => unreachable!(), + }; + let delim = match delim { + token::Paren => MacDelimiter::Parenthesis, + token::Bracket => MacDelimiter::Bracket, + token::Brace => MacDelimiter::Brace, + token::NoDelim => self.bug("unexpected no delimiter"), + }; + Ok((delim, tts.into())) + } - let minus_lo = self.token.span; - let minus_present = self.eat(&token::BinOp(token::Minus)); - let lo = self.token.span; - let literal = self.parse_lit()?; - let hi = self.prev_span; - let expr = self.mk_expr(lo.to(hi), ExprKind::Lit(literal), ThinVec::new()); - - if minus_present { - let minus_hi = self.prev_span; - let unary = self.mk_unary(UnOp::Neg, expr); - Ok(self.mk_expr(minus_lo.to(minus_hi), unary, ThinVec::new())) + fn parse_or_use_outer_attributes(&mut self, + already_parsed_attrs: Option>) + -> PResult<'a, ThinVec> { + if let Some(attrs) = already_parsed_attrs { + Ok(attrs) } else { - Ok(expr) + self.parse_outer_attributes().map(|a| a.into()) } } - fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> { - match self.token.kind { - token::Ident(name, _) if name.is_path_segment_keyword() => { - let span = self.token.span; + crate fn process_potential_macro_variable(&mut self) { + self.token = match self.token.kind { + token::Dollar if self.token.span.ctxt() != SyntaxContext::empty() && + self.look_ahead(1, |t| t.is_ident()) => { self.bump(); - Ok(Ident::new(name, span)) + let name = match self.token.kind { + token::Ident(name, _) => name, + _ => unreachable!() + }; + let span = self.prev_span.to(self.token.span); + self.diagnostic() + .struct_span_fatal(span, &format!("unknown macro variable `{}`", name)) + .span_label(span, "unknown macro variable") + .emit(); + self.bump(); + return } - _ => self.parse_ident(), - } + token::Interpolated(ref nt) => { + self.meta_var_span = Some(self.token.span); + // Interpolated identifier and lifetime tokens are replaced with usual identifier + // and lifetime tokens, so the former are never encountered during normal parsing. + match **nt { + token::NtIdent(ident, is_raw) => + Token::new(token::Ident(ident.name, is_raw), ident.span), + token::NtLifetime(ident) => + Token::new(token::Lifetime(ident.name), ident.span), + _ => return, + } + } + _ => return, + }; } - fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> { + /// Parses a single token tree from the input. + crate fn parse_token_tree(&mut self) -> TokenTree { match self.token.kind { - token::Ident(name, false) if name == kw::Underscore => { - let span = self.token.span; + token::OpenDelim(..) => { + let frame = mem::replace(&mut self.token_cursor.frame, + self.token_cursor.stack.pop().unwrap()); + self.token.span = frame.span.entire(); self.bump(); - Ok(Ident::new(name, span)) + TokenTree::Delimited( + frame.span, + frame.delim, + frame.tree_cursor.stream.into(), + ) + }, + token::CloseDelim(_) | token::Eof => unreachable!(), + _ => { + let token = self.token.take(); + self.bump(); + TokenTree::Token(token) } - _ => self.parse_ident(), } } - /// Parses a qualified path. - /// Assumes that the leading `<` has been parsed already. - /// - /// `qualified_path = ::path` - /// - /// # Examples - /// `::default` - /// `::a` - /// `::F::a` (without disambiguator) - /// `::F::a::` (with disambiguator) - fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, ast::Path)> { - let lo = self.prev_span; - let ty = self.parse_ty()?; - - // `path` will contain the prefix of the path up to the `>`, - // if any (e.g., `U` in the `::*` examples - // above). `path_span` has the span of that path, or an empty - // span in the case of something like `::Bar`. - let (mut path, path_span); - if self.eat_keyword(kw::As) { - let path_lo = self.token.span; - path = self.parse_path(PathStyle::Type)?; - path_span = path_lo.to(self.prev_span); - } else { - path_span = self.token.span.to(self.token.span); - path = ast::Path { segments: Vec::new(), span: path_span }; - } - - // See doc comment for `unmatched_angle_bracket_count`. - self.expect(&token::Gt)?; - if self.unmatched_angle_bracket_count > 0 { - self.unmatched_angle_bracket_count -= 1; - debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count); - } - - self.expect(&token::ModSep)?; - - let qself = QSelf { ty, path_span, position: path.segments.len() }; - self.parse_path_segments(&mut path.segments, style)?; - - Ok((qself, ast::Path { segments: path.segments, span: lo.to(self.prev_span) })) - } - - /// Parses simple paths. - /// - /// `path = [::] segment+` - /// `segment = ident | ident[::] | ident[::](args) [-> type]` - /// - /// # Examples - /// `a::b::C` (without disambiguator) - /// `a::b::C::` (with disambiguator) - /// `Fn(Args)` (without disambiguator) - /// `Fn::(Args)` (with disambiguator) - pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, ast::Path> { - maybe_whole!(self, NtPath, |path| { - if style == PathStyle::Mod && - path.segments.iter().any(|segment| segment.args.is_some()) { - self.diagnostic().span_err(path.span, "unexpected generic arguments in path"); - } - path - }); - - let lo = self.meta_var_span.unwrap_or(self.token.span); - let mut segments = Vec::new(); - let mod_sep_ctxt = self.token.span.ctxt(); - if self.eat(&token::ModSep) { - segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); - } - self.parse_path_segments(&mut segments, style)?; - - Ok(ast::Path { segments, span: lo.to(self.prev_span) }) - } - - /// Like `parse_path`, but also supports parsing `Word` meta items into paths for - /// backwards-compatibility. This is used when parsing derive macro paths in `#[derive]` - /// attributes. - pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, ast::Path> { - let meta_ident = match self.token.kind { - token::Interpolated(ref nt) => match **nt { - token::NtMeta(ref meta) => match meta.node { - ast::MetaItemKind::Word => Some(meta.path.clone()), - _ => None, - }, - _ => None, - }, - _ => None, - }; - if let Some(path) = meta_ident { - self.bump(); - return Ok(path); - } - self.parse_path(style) - } - - crate fn parse_path_segments(&mut self, - segments: &mut Vec, - style: PathStyle) - -> PResult<'a, ()> { - loop { - let segment = self.parse_path_segment(style)?; - if style == PathStyle::Expr { - // In order to check for trailing angle brackets, we must have finished - // recursing (`parse_path_segment` can indirectly call this function), - // that is, the next token must be the highlighted part of the below example: - // - // `Foo::>::Qux` - // ^ here - // - // As opposed to the below highlight (if we had only finished the first - // recursion): - // - // `Foo::>::Qux` - // ^ here - // - // `PathStyle::Expr` is only provided at the root invocation and never in - // `parse_path_segment` to recurse and therefore can be checked to maintain - // this invariant. - self.check_trailing_angle_brackets(&segment, token::ModSep); - } - segments.push(segment); - - if self.is_import_coupler() || !self.eat(&token::ModSep) { - return Ok(()); - } - } - } - - fn parse_path_segment(&mut self, style: PathStyle) -> PResult<'a, PathSegment> { - let ident = self.parse_path_segment_ident()?; - - let is_args_start = |token: &Token| match token.kind { - token::Lt | token::BinOp(token::Shl) | token::OpenDelim(token::Paren) - | token::LArrow => true, - _ => false, - }; - let check_args_start = |this: &mut Self| { - this.expected_tokens.extend_from_slice( - &[TokenType::Token(token::Lt), TokenType::Token(token::OpenDelim(token::Paren))] - ); - is_args_start(&this.token) - }; - - Ok(if style == PathStyle::Type && check_args_start(self) || - style != PathStyle::Mod && self.check(&token::ModSep) - && self.look_ahead(1, |t| is_args_start(t)) { - // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If - // it isn't, then we reset the unmatched angle bracket count as we're about to start - // parsing a new path. - if style == PathStyle::Expr { - self.unmatched_angle_bracket_count = 0; - self.max_angle_bracket_count = 0; - } - - // Generic arguments are found - `<`, `(`, `::<` or `::(`. - self.eat(&token::ModSep); - let lo = self.token.span; - let args = if self.eat_lt() { - // `<'a, T, A = U>` - let (args, constraints) = - self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?; - self.expect_gt()?; - let span = lo.to(self.prev_span); - AngleBracketedArgs { args, constraints, span }.into() - } else { - // `(T, U) -> R` - self.bump(); // `(` - let (inputs, recovered) = self.parse_seq_to_before_tokens( - &[&token::CloseDelim(token::Paren)], - SeqSep::trailing_allowed(token::Comma), - TokenExpectType::Expect, - |p| p.parse_ty())?; - if !recovered { - self.bump(); // `)` - } - let span = lo.to(self.prev_span); - let output = if self.eat(&token::RArrow) { - Some(self.parse_ty_common(false, false, false)?) - } else { - None - }; - ParenthesizedArgs { inputs, output, span }.into() - }; - - PathSegment { ident, args, id: ast::DUMMY_NODE_ID } - } else { - // Generic arguments are not found. - PathSegment::from_ident(ident) - }) - } - - crate fn check_lifetime(&mut self) -> bool { - self.expected_tokens.push(TokenType::Lifetime); - self.token.is_lifetime() - } - - /// Parses a single lifetime `'a` or panics. - crate fn expect_lifetime(&mut self) -> Lifetime { - if let Some(ident) = self.token.lifetime() { - let span = self.token.span; - self.bump(); - Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID } - } else { - self.span_bug(self.token.span, "not a lifetime") - } - } - - fn eat_label(&mut self) -> Option::B>::C; //~ ERROR cannot find type `A` in this scope let <::B>::C; //~ ERROR cannot find type `A` in this scope let 0 ..= <::B>::C; //~ ERROR cannot find type `A` in this scope - //~^ ERROR only char and numeric types are allowed in range patterns <::B>::C; //~ ERROR cannot find type `A` in this scope } diff --git a/src/test/ui/associated-path-shl.stderr b/src/test/ui/associated-path-shl.stderr index 23918ed2e3..71ee93f483 100644 --- a/src/test/ui/associated-path-shl.stderr +++ b/src/test/ui/associated-path-shl.stderr @@ -23,21 +23,11 @@ LL | let 0 ..= <::B>::C; | ^ not found in this scope error[E0412]: cannot find type `A` in this scope - --> $DIR/associated-path-shl.rs:9:7 + --> $DIR/associated-path-shl.rs:8:7 | LL | <::B>::C; | ^ not found in this scope -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/associated-path-shl.rs:7:15 - | -LL | let 0 ..= <::B>::C; - | ^^^^^^^^^^^ ranges require char or numeric types - | - = note: start type: {integer} - = note: end type: [type error] - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0029, E0412. -For more information about an error, try `rustc --explain E0029`. +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/associated-type-bounds/ambiguous-associated-type.rs b/src/test/ui/associated-type-bounds/ambiguous-associated-type.rs new file mode 100644 index 0000000000..9c47a003df --- /dev/null +++ b/src/test/ui/associated-type-bounds/ambiguous-associated-type.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(associated_type_bounds)] + +pub struct Flatten +where + I: Iterator, +{ + inner: ::IntoIter, +} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs index 8c9110d03e..9db5233e21 100644 --- a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs +++ b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs @@ -28,7 +28,7 @@ impl Case1 for S1 { type B = Range; } -// Ensure we don't have existential desugaring: +// Ensure we don't have opaque `impl Trait` desugaring: pub trait Foo { type Out: Baz; } pub trait Baz { type Assoc; } diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index bee56d6f68..1f2d755ed7 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -3,7 +3,7 @@ // error-pattern:could not find defining uses #![feature(associated_type_bounds)] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] #![feature(impl_trait_in_bindings)] #![feature(untagged_unions)] @@ -107,17 +107,17 @@ type TAW2 where T: Iterator = T; type TAW3 where T: Iterator = T; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] -existential type ETAI1>: Copy; +type ETAI1> = impl Copy; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] -existential type ETAI2>: Copy; +type ETAI2> = impl Copy; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] -existential type ETAI3>: Copy; +type ETAI3> = impl Copy; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] -existential type ETAI4: Iterator; +type ETAI4 = impl Iterator; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] -existential type ETAI5: Iterator; +type ETAI5 = impl Iterator; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] -existential type ETAI6: Iterator; +type ETAI6 = impl Iterator; //~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] trait TRI1> {} diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index 68367c9165..7f3a65ab69 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -3,6 +3,8 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the co | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:12:36 @@ -367,86 +369,86 @@ LL | type TAW3 where T: Iterator = T; error: could not find defining uses --> $DIR/duplicate.rs:110:1 | -LL | existential type ETAI1>: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI1> = impl Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:110:48 + --> $DIR/duplicate.rs:110:36 | -LL | existential type ETAI1>: Copy; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first +LL | type ETAI1> = impl Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first error: could not find defining uses --> $DIR/duplicate.rs:112:1 | -LL | existential type ETAI2>: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI2> = impl Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:112:48 + --> $DIR/duplicate.rs:112:36 | -LL | existential type ETAI2>: Copy; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first +LL | type ETAI2> = impl Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first error: could not find defining uses --> $DIR/duplicate.rs:114:1 | -LL | existential type ETAI3>: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI3> = impl Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:114:51 + --> $DIR/duplicate.rs:114:39 | -LL | existential type ETAI3>: Copy; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first +LL | type ETAI3> = impl Copy; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first error: could not find defining uses --> $DIR/duplicate.rs:116:1 | -LL | existential type ETAI4: Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI4 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:116:46 + --> $DIR/duplicate.rs:116:40 | -LL | existential type ETAI4: Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first +LL | type ETAI4 = impl Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first error: could not find defining uses --> $DIR/duplicate.rs:118:1 | -LL | existential type ETAI5: Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI5 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:118:46 + --> $DIR/duplicate.rs:118:40 | -LL | existential type ETAI5: Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first +LL | type ETAI5 = impl Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first error: could not find defining uses --> $DIR/duplicate.rs:120:1 | -LL | existential type ETAI6: Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI6 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:120:49 + --> $DIR/duplicate.rs:120:43 | -LL | existential type ETAI6: Iterator; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first +LL | type ETAI6 = impl Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:123:36 diff --git a/src/test/ui/associated-type-bounds/dyn-existential-type.rs b/src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs similarity index 98% rename from src/test/ui/associated-type-bounds/dyn-existential-type.rs rename to src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs index dc0afaa934..fd9e52a6ff 100644 --- a/src/test/ui/associated-type-bounds/dyn-existential-type.rs +++ b/src/test/ui/associated-type-bounds/dyn-impl-trait-type.rs @@ -1,7 +1,6 @@ // run-pass #![feature(associated_type_bounds)] -#![feature(existential_type)] use std::ops::Add; diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.stderr b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr index 5fe4818ef8..1b3975f099 100644 --- a/src/test/ui/associated-type-bounds/dyn-lcsit.stderr +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr @@ -3,4 +3,6 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the co | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs index 1b3e978594..f5a9bac6e3 100644 --- a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs +++ b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/issue-61752.rs b/src/test/ui/associated-type-bounds/issue-61752.rs new file mode 100644 index 0000000000..f38ec640e1 --- /dev/null +++ b/src/test/ui/associated-type-bounds/issue-61752.rs @@ -0,0 +1,24 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait Foo { + type Bar; +} + +impl Foo for () { + type Bar = (); +} + +fn a() where F::Bar: Copy {} + +fn b() where ::Bar: Copy {} + +// This used to complain about ambiguous associated types. +fn c>() where F::Bar: Copy {} + +fn main() { + a::<()>(); + b::<()>(); + c::<()>(); +} diff --git a/src/test/ui/associated-type-bounds/lcsit.stderr b/src/test/ui/associated-type-bounds/lcsit.stderr index 8fda11bedd..7c4349541e 100644 --- a/src/test/ui/associated-type-bounds/lcsit.stderr +++ b/src/test/ui/associated-type-bounds/lcsit.stderr @@ -3,4 +3,6 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the co | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/associated-type-bounds/existential-type.rs b/src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs similarity index 84% rename from src/test/ui/associated-type-bounds/existential-type.rs rename to src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs index 87046aec5c..9ee33e4149 100644 --- a/src/test/ui/associated-type-bounds/existential-type.rs +++ b/src/test/ui/associated-type-bounds/trait-alias-impl-trait.rs @@ -1,7 +1,7 @@ // run-pass #![feature(associated_type_bounds)] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::ops::Add; @@ -17,15 +17,15 @@ struct S1; struct S2; impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } -existential type Et1: Tr1; +type Et1 = impl Tr1; fn def_et1() -> Et1 { S1 } pub fn use_et1() { assert_copy(def_et1().mk()); } -existential type Et2: Tr1; +type Et2 = impl Tr1; fn def_et2() -> Et2 { S1 } pub fn use_et2() { assert_static(def_et2().mk()); } -existential type Et3: Tr1>>>; +type Et3 = impl Tr1>>>; fn def_et3() -> Et3 { struct A; impl Tr1 for A { @@ -44,7 +44,7 @@ pub fn use_et3() { assert_eq!(s, (0..10).map(|x| x + 1).sum()); } -existential type Et4: Tr1 Tr2<'a>>; +type Et4 = impl Tr1 Tr2<'a>>; fn def_et4() -> Et4 { #[derive(Copy, Clone)] struct A; diff --git a/src/test/ui/associated-type-bounds/trait-params.rs b/src/test/ui/associated-type-bounds/trait-params.rs index a9081d50cf..b0703a4ee2 100644 --- a/src/test/ui/associated-type-bounds/trait-params.rs +++ b/src/test/ui/associated-type-bounds/trait-params.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/type-alias.rs b/src/test/ui/associated-type-bounds/type-alias.rs index 1602fdd275..34bc0c9acb 100644 --- a/src/test/ui/associated-type-bounds/type-alias.rs +++ b/src/test/ui/associated-type-bounds/type-alias.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/type-alias.stderr b/src/test/ui/associated-type-bounds/type-alias.stderr index b93fc393ae..a3fa97f54e 100644 --- a/src/test/ui/associated-type-bounds/type-alias.stderr +++ b/src/test/ui/associated-type-bounds/type-alias.stderr @@ -4,7 +4,7 @@ warning: where clauses are not enforced in type aliases LL | type _TaWhere1 where T: Iterator = T; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(type_alias_bounds)] on by default + = note: `#[warn(type_alias_bounds)]` on by default = help: the clause will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases diff --git a/src/test/run-pass/associated-types/associated-types-basic.rs b/src/test/ui/associated-types/associated-types-basic.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-basic.rs rename to src/test/ui/associated-types/associated-types-basic.rs diff --git a/src/test/run-pass/associated-types/associated-types-binding-in-trait.rs b/src/test/ui/associated-types/associated-types-binding-in-trait.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-binding-in-trait.rs rename to src/test/ui/associated-types/associated-types-binding-in-trait.rs diff --git a/src/test/run-pass/associated-types/associated-types-binding-in-where-clause.rs b/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-binding-in-where-clause.rs rename to src/test/ui/associated-types/associated-types-binding-in-where-clause.rs diff --git a/src/test/run-pass/associated-types/associated-types-bound.rs b/src/test/ui/associated-types/associated-types-bound.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-bound.rs rename to src/test/ui/associated-types/associated-types-bound.rs diff --git a/src/test/run-pass/associated-types/associated-types-cc.rs b/src/test/ui/associated-types/associated-types-cc.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-cc.rs rename to src/test/ui/associated-types/associated-types-cc.rs diff --git a/src/test/run-pass/associated-types/associated-types-conditional-dispatch.rs b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-conditional-dispatch.rs rename to src/test/ui/associated-types/associated-types-conditional-dispatch.rs diff --git a/src/test/run-pass/associated-types/associated-types-constant-type.rs b/src/test/ui/associated-types/associated-types-constant-type.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-constant-type.rs rename to src/test/ui/associated-types/associated-types-constant-type.rs diff --git a/src/test/run-pass/associated-types/associated-types-doubleendediterator-object.rs b/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-doubleendediterator-object.rs rename to src/test/ui/associated-types/associated-types-doubleendediterator-object.rs diff --git a/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs rename to src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs diff --git a/src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env.rs b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-duplicate-binding-in-env.rs rename to src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs diff --git a/src/test/run-pass/associated-types/associated-types-enum-field-named.rs b/src/test/ui/associated-types/associated-types-enum-field-named.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-enum-field-named.rs rename to src/test/ui/associated-types/associated-types-enum-field-named.rs diff --git a/src/test/run-pass/associated-types/associated-types-enum-field-numbered.rs b/src/test/ui/associated-types/associated-types-enum-field-numbered.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-enum-field-numbered.rs rename to src/test/ui/associated-types/associated-types-enum-field-numbered.rs diff --git a/src/test/run-pass/associated-types/associated-types-eq-obj.rs b/src/test/ui/associated-types/associated-types-eq-obj.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-eq-obj.rs rename to src/test/ui/associated-types/associated-types-eq-obj.rs diff --git a/src/test/run-pass/associated-types/associated-types-from-supertrait.rs b/src/test/ui/associated-types/associated-types-from-supertrait.rs similarity index 87% rename from src/test/run-pass/associated-types/associated-types-from-supertrait.rs rename to src/test/ui/associated-types/associated-types-from-supertrait.rs index c040790188..8f40b94c09 100644 --- a/src/test/run-pass/associated-types/associated-types-from-supertrait.rs +++ b/src/test/ui/associated-types/associated-types-from-supertrait.rs @@ -1,3 +1,5 @@ +// run-pass + trait Foo: Iterator {} trait Bar: Foo {} diff --git a/src/test/run-pass/associated-types/associated-types-impl-redirect.rs b/src/test/ui/associated-types/associated-types-impl-redirect.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-impl-redirect.rs rename to src/test/ui/associated-types/associated-types-impl-redirect.rs diff --git a/src/test/run-pass/associated-types/associated-types-in-bound-type-arg.rs b/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-in-bound-type-arg.rs rename to src/test/ui/associated-types/associated-types-in-bound-type-arg.rs diff --git a/src/test/run-pass/associated-types/associated-types-in-default-method.rs b/src/test/ui/associated-types/associated-types-in-default-method.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-in-default-method.rs rename to src/test/ui/associated-types/associated-types-in-default-method.rs diff --git a/src/test/run-pass/associated-types/associated-types-in-fn.rs b/src/test/ui/associated-types/associated-types-in-fn.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-in-fn.rs rename to src/test/ui/associated-types/associated-types-in-fn.rs diff --git a/src/test/run-pass/associated-types/associated-types-in-impl-generics.rs b/src/test/ui/associated-types/associated-types-in-impl-generics.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-in-impl-generics.rs rename to src/test/ui/associated-types/associated-types-in-impl-generics.rs diff --git a/src/test/run-pass/associated-types/associated-types-in-inherent-method.rs b/src/test/ui/associated-types/associated-types-in-inherent-method.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-in-inherent-method.rs rename to src/test/ui/associated-types/associated-types-in-inherent-method.rs diff --git a/src/test/run-pass/associated-types/associated-types-issue-20220.rs b/src/test/ui/associated-types/associated-types-issue-20220.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-issue-20220.rs rename to src/test/ui/associated-types/associated-types-issue-20220.rs diff --git a/src/test/run-pass/associated-types/associated-types-issue-20371.rs b/src/test/ui/associated-types/associated-types-issue-20371.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-issue-20371.rs rename to src/test/ui/associated-types/associated-types-issue-20371.rs diff --git a/src/test/run-pass/associated-types/associated-types-issue-21212.rs b/src/test/ui/associated-types/associated-types-issue-21212.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-issue-21212.rs rename to src/test/ui/associated-types/associated-types-issue-21212.rs diff --git a/src/test/run-pass/associated-types/associated-types-iterator-binding.rs b/src/test/ui/associated-types/associated-types-iterator-binding.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-iterator-binding.rs rename to src/test/ui/associated-types/associated-types-iterator-binding.rs diff --git a/src/test/run-pass/associated-types/associated-types-method.rs b/src/test/ui/associated-types/associated-types-method.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-method.rs rename to src/test/ui/associated-types/associated-types-method.rs diff --git a/src/test/run-pass/associated-types/associated-types-nested-projections.rs b/src/test/ui/associated-types/associated-types-nested-projections.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-nested-projections.rs rename to src/test/ui/associated-types/associated-types-nested-projections.rs diff --git a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-binding.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-normalize-in-bounds-binding.rs rename to src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs diff --git a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-normalize-in-bounds-ufcs.rs rename to src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs diff --git a/src/test/run-pass/associated-types/associated-types-normalize-in-bounds.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-normalize-in-bounds.rs rename to src/test/ui/associated-types/associated-types-normalize-in-bounds.rs diff --git a/src/test/run-pass/associated-types/associated-types-normalize-unifield-struct.rs b/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-normalize-unifield-struct.rs rename to src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs diff --git a/src/test/run-pass/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs b/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs rename to src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs diff --git a/src/test/run-pass/associated-types/associated-types-projection-bound-in-supertraits.rs b/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-projection-bound-in-supertraits.rs rename to src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs diff --git a/src/test/run-pass/associated-types/associated-types-projection-from-known-type-in-impl.rs b/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-projection-from-known-type-in-impl.rs rename to src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs diff --git a/src/test/run-pass/associated-types/associated-types-projection-in-object-type.rs b/src/test/ui/associated-types/associated-types-projection-in-object-type.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-projection-in-object-type.rs rename to src/test/ui/associated-types/associated-types-projection-in-object-type.rs diff --git a/src/test/run-pass/associated-types/associated-types-projection-in-supertrait.rs b/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-projection-in-supertrait.rs rename to src/test/ui/associated-types/associated-types-projection-in-supertrait.rs diff --git a/src/test/run-pass/associated-types/associated-types-projection-in-where-clause.rs b/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-projection-in-where-clause.rs rename to src/test/ui/associated-types/associated-types-projection-in-where-clause.rs diff --git a/src/test/run-pass/associated-types/associated-types-projection-to-unrelated-trait.rs b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-projection-to-unrelated-trait.rs rename to src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs diff --git a/src/test/run-pass/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs rename to src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs diff --git a/src/test/run-pass/associated-types/associated-types-ref-from-struct.rs b/src/test/ui/associated-types/associated-types-ref-from-struct.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-ref-from-struct.rs rename to src/test/ui/associated-types/associated-types-ref-from-struct.rs diff --git a/src/test/run-pass/associated-types/associated-types-ref-in-struct-literal.rs b/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-ref-in-struct-literal.rs rename to src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs diff --git a/src/test/run-pass/associated-types/associated-types-region-erasure-issue-20582.rs b/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-region-erasure-issue-20582.rs rename to src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs diff --git a/src/test/run-pass/associated-types/associated-types-resolve-lifetime.rs b/src/test/ui/associated-types/associated-types-resolve-lifetime.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-resolve-lifetime.rs rename to src/test/ui/associated-types/associated-types-resolve-lifetime.rs diff --git a/src/test/run-pass/associated-types/associated-types-return.rs b/src/test/ui/associated-types/associated-types-return.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-return.rs rename to src/test/ui/associated-types/associated-types-return.rs diff --git a/src/test/run-pass/associated-types/associated-types-simple.rs b/src/test/ui/associated-types/associated-types-simple.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-simple.rs rename to src/test/ui/associated-types/associated-types-simple.rs diff --git a/src/test/run-pass/associated-types/associated-types-stream.rs b/src/test/ui/associated-types/associated-types-stream.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-stream.rs rename to src/test/ui/associated-types/associated-types-stream.rs diff --git a/src/test/run-pass/associated-types/associated-types-struct-field-named.rs b/src/test/ui/associated-types/associated-types-struct-field-named.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-struct-field-named.rs rename to src/test/ui/associated-types/associated-types-struct-field-named.rs diff --git a/src/test/run-pass/associated-types/associated-types-struct-field-numbered.rs b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-struct-field-numbered.rs rename to src/test/ui/associated-types/associated-types-struct-field-numbered.rs diff --git a/src/test/run-pass/associated-types/associated-types-sugar-path.rs b/src/test/ui/associated-types/associated-types-sugar-path.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-sugar-path.rs rename to src/test/ui/associated-types/associated-types-sugar-path.rs diff --git a/src/test/run-pass/associated-types/associated-types-where-clause-impl-ambiguity.rs b/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs similarity index 100% rename from src/test/run-pass/associated-types/associated-types-where-clause-impl-ambiguity.rs rename to src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs diff --git a/src/test/run-pass/associated-types/auxiliary/associated-types-cc-lib.rs b/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs similarity index 100% rename from src/test/run-pass/associated-types/auxiliary/associated-types-cc-lib.rs rename to src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs diff --git a/src/test/ui/associated-types/cache/chrono-scan.rs b/src/test/ui/associated-types/cache/chrono-scan.rs index 8ddd347ff3..964ddc9b62 100644 --- a/src/test/ui/associated-types/cache/chrono-scan.rs +++ b/src/test/ui/associated-types/cache/chrono-scan.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(deprecated)] + pub type ParseResult = Result; pub enum Item<'a> { diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs index 0eae1467fb..8a15eb8c57 100644 --- a/src/test/ui/async-await/async-await.rs +++ b/src/test/ui/async-await/async-await.rs @@ -70,12 +70,7 @@ fn async_nonmove_block(x: u8) -> impl Future { } } -fn async_closure(x: u8) -> impl Future { - (async move |x: u8| -> u8 { - wake_and_yield_once().await; - x - })(x) -} +// see async-closure.rs for async_closure + async_closure_in_unsafe_block async fn async_fn(x: u8) -> u8 { wake_and_yield_once().await; @@ -104,12 +99,10 @@ fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future:;` works async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 { - await!(wake_and_yield_once()); + wake_and_yield_once().await; *x } -*/ async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 { wake_and_yield_once().await; @@ -127,6 +120,18 @@ async unsafe fn unsafe_async_fn(x: u8) -> u8 { x } +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn async_block_in_unsafe_block(x: u8) -> impl Future { + unsafe { + async move { + unsafe_fn(unsafe_async_fn(x).await) + } + } +} + struct Foo; trait Bar { @@ -180,10 +185,10 @@ fn main() { test! { async_block, async_nonmove_block, - async_closure, async_fn, generic_async_fn, async_fn_with_internal_borrow, + async_block_in_unsafe_block, Foo::async_assoc_item, |x| { async move { diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs new file mode 100644 index 0000000000..6a766ede0e --- /dev/null +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs @@ -0,0 +1,67 @@ +// Test that `async { .. }` blocks: +// 1. do not allow `break` expressions. +// 2. get targeted by `return` and not the parent function. +// 3. get targeted by `?` and not the parent function. +// +// edition:2018 +// ignore-tidy-linelength + +#![feature(async_await)] + +fn main() {} + +use core::future::Future; + +fn return_targets_async_block_not_fn() -> u8 { + //~^ ERROR mismatched types + let block = async { + return 0u8; + }; + let _: &dyn Future = █ + //~^ ERROR type mismatch resolving `::Output == ()` +} + +async fn return_targets_async_block_not_async_fn() -> u8 { + //~^ ERROR type mismatch resolving + let block = async { + return 0u8; + }; + let _: &dyn Future = █ + //~^ ERROR type mismatch resolving `::Output == ()` +} + +fn no_break_in_async_block() { + async { + break 0u8; //~ ERROR `break` inside of a closure + // FIXME: This diagnostic is pretty bad. + }; +} + +fn no_break_in_async_block_even_with_outer_loop() { + loop { + async { + break 0u8; //~ ERROR `break` inside of a closure + }; + } +} + +struct MyErr; +fn err() -> Result { Err(MyErr) } + +fn rethrow_targets_async_block_not_fn() -> Result { + //~^ ERROR mismatched types + let block = async { + err()?; + Ok(()) + }; + let _: &dyn Future> = █ +} + +fn rethrow_targets_async_block_not_async_fn() -> Result { + //~^ ERROR mismatched types + let block = async { + err()?; + Ok(()) + }; + let _: &dyn Future> = █ +} diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr new file mode 100644 index 0000000000..f3f2d14584 --- /dev/null +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -0,0 +1,79 @@ +error[E0267]: `break` inside of a closure + --> $DIR/async-block-control-flow-static-semantics.rs:35:9 + | +LL | break 0u8; + | ^^^^^^^^^ cannot break inside of a closure + +error[E0267]: `break` inside of a closure + --> $DIR/async-block-control-flow-static-semantics.rs:43:13 + | +LL | break 0u8; + | ^^^^^^^^^ cannot break inside of a closure + +error[E0308]: mismatched types + --> $DIR/async-block-control-flow-static-semantics.rs:15:43 + | +LL | fn return_targets_async_block_not_fn() -> u8 { + | --------------------------------- ^^ expected u8, found () + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected type `u8` + found type `()` + +error[E0271]: type mismatch resolving `::Output == ()` + --> $DIR/async-block-control-flow-static-semantics.rs:20:39 + | +LL | let _: &dyn Future = █ + | ^^^^^^ expected u8, found () + | + = note: expected type `u8` + found type `()` + = note: required for the cast to the object type `dyn std::future::Future` + +error[E0271]: type mismatch resolving `::Output == ()` + --> $DIR/async-block-control-flow-static-semantics.rs:29:39 + | +LL | let _: &dyn Future = █ + | ^^^^^^ expected u8, found () + | + = note: expected type `u8` + found type `()` + = note: required for the cast to the object type `dyn std::future::Future` + +error[E0271]: type mismatch resolving `::Output == u8` + --> $DIR/async-block-control-flow-static-semantics.rs:24:55 + | +LL | async fn return_targets_async_block_not_async_fn() -> u8 { + | ^^ expected (), found u8 + | + = note: expected type `()` + found type `u8` + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/async-block-control-flow-static-semantics.rs:51:44 + | +LL | fn rethrow_targets_async_block_not_fn() -> Result { + | ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected type `std::result::Result` + found type `()` + +error[E0308]: mismatched types + --> $DIR/async-block-control-flow-static-semantics.rs:60:50 + | +LL | fn rethrow_targets_async_block_not_async_fn() -> Result { + | ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected type `std::result::Result` + found type `()` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0267, E0271, E0308. +For more information about an error, try `rustc --explain E0267`. diff --git a/src/test/ui/async-await/async-closure-matches-expr.rs b/src/test/ui/async-await/async-closure-matches-expr.rs new file mode 100644 index 0000000000..1c192a4d1d --- /dev/null +++ b/src/test/ui/async-await/async-closure-matches-expr.rs @@ -0,0 +1,12 @@ +// build-pass +// edition:2018 + +#![feature(async_await, async_closure)] + +macro_rules! match_expr { + ($x:expr) => {} +} + +fn main() { + match_expr!(async || {}); +} diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs new file mode 100644 index 0000000000..925b54b398 --- /dev/null +++ b/src/test/ui/async-await/async-closure.rs @@ -0,0 +1,97 @@ +// run-pass + +// edition:2018 +// aux-build:arc_wake.rs + +#![feature(async_await, async_closure)] + +extern crate arc_wake; + +use std::pin::Pin; +use std::future::Future; +use std::sync::{ + Arc, + atomic::{self, AtomicUsize}, +}; +use std::task::{Context, Poll}; +use arc_wake::ArcWake; + +struct Counter { + wakes: AtomicUsize, +} + +impl ArcWake for Counter { + fn wake(self: Arc) { + Self::wake_by_ref(&self) + } + fn wake_by_ref(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); + } +} + +struct WakeOnceThenComplete(bool); + +fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } + +impl Future for WakeOnceThenComplete { + type Output = (); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + if self.0 { + Poll::Ready(()) + } else { + cx.waker().wake_by_ref(); + self.0 = true; + Poll::Pending + } + } +} + +fn async_closure(x: u8) -> impl Future { + (async move |x: u8| -> u8 { + wake_and_yield_once().await; + x + })(x) +} + +fn async_closure_in_unsafe_block(x: u8) -> impl Future { + (unsafe { + async move |x: u8| unsafe_fn(unsafe_async_fn(x).await) + })(x) +} + +async unsafe fn unsafe_async_fn(x: u8) -> u8 { + wake_and_yield_once().await; + x +} + +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn test_future_yields_once_then_returns(f: F) +where + F: FnOnce(u8) -> Fut, + Fut: Future, +{ + let mut fut = Box::pin(f(9)); + let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); + let waker = ArcWake::into_waker(counter.clone()); + let mut cx = Context::from_waker(&waker); + assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); + assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); +} + +fn main() { + macro_rules! test { + ($($fn_name:expr,)*) => { $( + test_future_yields_once_then_returns($fn_name); + )* } + } + + test! { + async_closure, + async_closure_in_unsafe_block, + } +} diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs new file mode 100644 index 0000000000..d362348a3f --- /dev/null +++ b/src/test/ui/async-await/async-error-span.rs @@ -0,0 +1,17 @@ +// edition:2018 +#![feature(async_await)] + +// Regression test for issue #62382 + +use std::future::Future; + +fn get_future() -> impl Future { + panic!() +} + +async fn foo() { + let a; //~ ERROR type inside `async` object must be known in this context + get_future().await; +} + +fn main() {} diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr new file mode 100644 index 0000000000..bd8966b9c7 --- /dev/null +++ b/src/test/ui/async-await/async-error-span.stderr @@ -0,0 +1,15 @@ +error[E0698]: type inside `async` object must be known in this context + --> $DIR/async-error-span.rs:13:9 + | +LL | let a; + | ^ cannot infer type + | +note: the type is part of the `async` object because of this `await` + --> $DIR/async-error-span.rs:14:5 + | +LL | get_future().await; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0698`. diff --git a/src/test/ui/async-await/async-fn-path-elision.rs b/src/test/ui/async-await/async-fn-path-elision.rs index 8db7631ef4..447e40dddd 100644 --- a/src/test/ui/async-await/async-fn-path-elision.rs +++ b/src/test/ui/async-await/async-fn-path-elision.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] #![allow(dead_code)] struct HasLifetime<'a>(&'a bool); diff --git a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs index f07fc2fceb..5e1b8c6280 100644 --- a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs +++ b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/run-pass/async-await/async-fn-size-moved-locals.rs b/src/test/ui/async-await/async-fn-size-moved-locals.rs similarity index 82% rename from src/test/run-pass/async-await/async-fn-size-moved-locals.rs rename to src/test/ui/async-await/async-fn-size-moved-locals.rs index 139be7fe01..30b59d037d 100644 --- a/src/test/run-pass/async-await/async-fn-size-moved-locals.rs +++ b/src/test/ui/async-await/async-fn-size-moved-locals.rs @@ -7,6 +7,9 @@ // // See issue #59123 for a full explanation. +// ignore-wasm32-bare (sizes don't match) +// run-pass + // edition:2018 #![feature(async_await)] @@ -90,9 +93,27 @@ async fn joined_with_noop() { joiner.await } +async fn mixed_sizes() { + let a = BigFut::new(); + let b = BigFut::new(); + let c = BigFut::new(); + let d = BigFut::new(); + let e = BigFut::new(); + let joiner = Joiner { + a: Some(a), + b: Some(b), + c: Some(c), + }; + + d.await; + e.await; + joiner.await; +} + fn main() { assert_eq!(1028, std::mem::size_of_val(&single())); assert_eq!(1032, std::mem::size_of_val(&single_with_noop())); assert_eq!(3084, std::mem::size_of_val(&joined())); assert_eq!(3084, std::mem::size_of_val(&joined_with_noop())); + assert_eq!(7188, std::mem::size_of_val(&mixed_sizes())); } diff --git a/src/test/run-pass/async-await/async-fn-size.rs b/src/test/ui/async-await/async-fn-size.rs similarity index 81% rename from src/test/run-pass/async-await/async-fn-size.rs rename to src/test/ui/async-await/async-fn-size.rs index c4e328560d..c6b2ed13b0 100644 --- a/src/test/run-pass/async-await/async-fn-size.rs +++ b/src/test/ui/async-await/async-fn-size.rs @@ -1,9 +1,10 @@ +// run-pass +// aux-build:arc_wake.rs // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] -#[path = "../auxiliary/arc_wake.rs"] -mod arc_wake; +extern crate arc_wake; use std::pin::Pin; use std::future::Future; @@ -58,31 +59,31 @@ fn wait(fut: impl Future) -> u8 { fn base() -> WakeOnceThenComplete { WakeOnceThenComplete(false, 1) } async fn await1_level1() -> u8 { - await!(base()) + base().await } async fn await2_level1() -> u8 { - await!(base()) + await!(base()) + base().await + base().await } async fn await3_level1() -> u8 { - await!(base()) + await!(base()) + await!(base()) + base().await + base().await + base().await } async fn await3_level2() -> u8 { - await!(await3_level1()) + await!(await3_level1()) + await!(await3_level1()) + await3_level1().await + await3_level1().await + await3_level1().await } async fn await3_level3() -> u8 { - await!(await3_level2()) + await!(await3_level2()) + await!(await3_level2()) + await3_level2().await + await3_level2().await + await3_level2().await } async fn await3_level4() -> u8 { - await!(await3_level3()) + await!(await3_level3()) + await!(await3_level3()) + await3_level3().await + await3_level3().await + await3_level3().await } async fn await3_level5() -> u8 { - await!(await3_level4()) + await!(await3_level4()) + await!(await3_level4()) + await3_level4().await + await3_level4().await + await3_level4().await } fn main() { diff --git a/src/test/ui/async-await/async-matches-expr.rs b/src/test/ui/async-await/async-matches-expr.rs index f375d58d98..a6f0211e41 100644 --- a/src/test/ui/async-await/async-matches-expr.rs +++ b/src/test/ui/async-await/async-matches-expr.rs @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] macro_rules! match_expr { ($x:expr) => {} @@ -9,5 +9,4 @@ macro_rules! match_expr { fn main() { match_expr!(async {}); - match_expr!(async || {}); } diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs new file mode 100644 index 0000000000..cb9156dcc6 --- /dev/null +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs @@ -0,0 +1,21 @@ +// edition:2018 + +#![feature(async_await)] + +struct S; + +impl S { + async unsafe fn f() {} +} + +async unsafe fn f() {} + +async fn g() { + S::f(); //~ ERROR call to unsafe function is unsafe + f(); //~ ERROR call to unsafe function is unsafe +} + +fn main() { + S::f(); //~ ERROR call to unsafe function is unsafe + f(); //~ ERROR call to unsafe function is unsafe +} diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr new file mode 100644 index 0000000000..d22413beec --- /dev/null +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr @@ -0,0 +1,35 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5 + | +LL | S::f(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:15:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:19:5 + | +LL | S::f(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:20:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/async-await/async-with-closure.rs b/src/test/ui/async-await/async-with-closure.rs index e94a5f0853..f7dc874aff 100644 --- a/src/test/ui/async-await/async-with-closure.rs +++ b/src/test/ui/async-await/async-with-closure.rs @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] trait MyClosure { type Args; @@ -20,7 +20,7 @@ async fn get_future(_stream: MyStream) {} async fn f() { let messages: MyStream = unimplemented!(); - await!(get_future(messages)); + get_future(messages).await; } fn main() {} diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs similarity index 89% rename from src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs rename to src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs index c4f3f3edc4..422a5a6394 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs @@ -1,4 +1,4 @@ -#![feature(async_await, await_macro)] +#![feature(async_await)] #![allow(non_camel_case_types)] #![deny(keyword_idents)] @@ -29,6 +29,9 @@ macro_rules! await { } fn main() { + await!(); //~ ERROR `await` is a keyword in the 2018 edition + //~^ WARN this was previously accepted by the compiler + match await { await => {} } //~ ERROR `await` is a keyword in the 2018 edition //~^ ERROR `await` is a keyword in the 2018 edition //~^^ WARN this was previously accepted by the compiler diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr similarity index 78% rename from src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr rename to src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 067ecd6a51..8af0110169 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -1,11 +1,11 @@ error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:6:13 + --> $DIR/2015-edition-error-various-positions.rs:6:13 | LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | note: lint level defined here - --> $DIR/2015-edition-error-in-non-macro-position.rs:3:9 + --> $DIR/2015-edition-error-various-positions.rs:3:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(keyword_idents)] = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:8:20 + --> $DIR/2015-edition-error-various-positions.rs:8:20 | LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -22,7 +22,7 @@ LL | pub struct await; = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:12:16 + --> $DIR/2015-edition-error-various-positions.rs:12:16 | LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -31,7 +31,7 @@ LL | use outer_mod::await::await; = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:12:23 + --> $DIR/2015-edition-error-various-positions.rs:12:23 | LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -40,7 +40,7 @@ LL | use outer_mod::await::await; = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:17:14 + --> $DIR/2015-edition-error-various-positions.rs:17:14 | LL | struct Foo { await: () } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -49,7 +49,7 @@ LL | struct Foo { await: () } = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:21:15 + --> $DIR/2015-edition-error-various-positions.rs:21:15 | LL | impl Foo { fn await() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -58,7 +58,7 @@ LL | impl Foo { fn await() {} } = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:25:14 + --> $DIR/2015-edition-error-various-positions.rs:25:14 | LL | macro_rules! await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -67,7 +67,16 @@ LL | macro_rules! await { = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:32:11 + --> $DIR/2015-edition-error-various-positions.rs:32:5 + | +LL | await!(); + | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `await` is a keyword in the 2018 edition + --> $DIR/2015-edition-error-various-positions.rs:35:11 | LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -76,7 +85,7 @@ LL | match await { await => {} } = note: for more information, see issue #49716 error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-in-non-macro-position.rs:32:19 + --> $DIR/2015-edition-error-various-positions.rs:35:19 | LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -84,5 +93,5 @@ LL | match await { await => {} } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #49716 -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs index f59f1160e7..92f3210ac8 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs +++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs @@ -1,7 +1,7 @@ // edition:2018 #![allow(non_camel_case_types)] -#![feature(async_await, await_macro)] +#![feature(async_await)] mod outer_mod { pub mod await { //~ ERROR expected identifier, found reserved keyword `await` diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.rs b/src/test/ui/async-await/await-keyword/2018-edition-error.rs index d856869684..e620c27f9e 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error.rs +++ b/src/test/ui/async-await/await-keyword/2018-edition-error.rs @@ -9,4 +9,8 @@ mod outer_mod { use self::outer_mod::await::await; //~ ERROR expected identifier //~^ ERROR expected identifier, found reserved keyword `await` -fn main() {} +macro_rules! await { () => {}; } //~ ERROR expected identifier, found reserved keyword `await` + +fn main() { + await!(); //~ ERROR expected expression, found `)` +} diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr index 8afe5c1a36..9304928cfd 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr +++ b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr @@ -38,5 +38,21 @@ help: you can escape reserved keywords to use them as identifiers LL | use self::outer_mod::await::r#await; | ^^^^^^^ -error: aborting due to 4 previous errors +error: expected identifier, found reserved keyword `await` + --> $DIR/2018-edition-error.rs:12:14 + | +LL | macro_rules! await { () => {}; } + | ^^^^^ expected identifier, found reserved keyword +help: you can escape reserved keywords to use them as identifiers + | +LL | macro_rules! r#await { () => {}; } + | ^^^^^^^ + +error: expected expression, found `)` + --> $DIR/2018-edition-error.rs:15:12 + | +LL | await!(); + | ^ expected expression + +error: aborting due to 6 previous errors diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs index e1e5bdd3d1..25da337c58 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs @@ -104,6 +104,31 @@ fn foo25() -> Result<(), ()> { foo() } +async fn foo26() -> Result<(), ()> { + let _ = await!(bar()); //~ ERROR incorrect use of `await` + Ok(()) +} +async fn foo27() -> Result<(), ()> { + let _ = await!(bar())?; //~ ERROR incorrect use of `await` + Ok(()) +} +fn foo28() -> Result<(), ()> { + fn foo() -> Result<(), ()> { + let _ = await!(bar())?; //~ ERROR incorrect use of `await` + //~^ ERROR `await` is only allowed inside `async` functions + Ok(()) + } + foo() +} +fn foo29() -> Result<(), ()> { + let foo = || { + let _ = await!(bar())?; //~ ERROR incorrect use of `await` + //~^ ERROR `await` is only allowed inside `async` functions + Ok(()) + }; + foo() +} + fn main() { match await { await => () } //~^ ERROR expected expression, found `=>` diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr index 380da4448a..db86d3d5d0 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr @@ -88,8 +88,32 @@ error: incorrect use of `await` LL | let _ = bar().await()?; | ^^ help: `await` is not a method call, remove the parentheses +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:108:13 + | +LL | let _ = await!(bar()); + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:112:13 + | +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:117:17 + | +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + +error: incorrect use of `await` + --> $DIR/incorrect-syntax-suggestions.rs:125:17 + | +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` + error: expected expression, found `=>` - --> $DIR/incorrect-syntax-suggestions.rs:108:25 + --> $DIR/incorrect-syntax-suggestions.rs:133:25 | LL | match await { await => () } | ----- ^^ expected expression @@ -97,13 +121,13 @@ LL | match await { await => () } | while parsing this incorrect await expression error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:108:11 + --> $DIR/incorrect-syntax-suggestions.rs:133:11 | LL | match await { await => () } | ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await` error: expected one of `.`, `?`, `{`, or an operator, found `}` - --> $DIR/incorrect-syntax-suggestions.rs:111:1 + --> $DIR/incorrect-syntax-suggestions.rs:136:1 | LL | match await { await => () } | ----- - expected one of `.`, `?`, `{`, or an operator here @@ -193,6 +217,22 @@ LL | let foo = || { LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:117:17 + | +LL | fn foo() -> Result<(), ()> { + | --- this is not `async` +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/incorrect-syntax-suggestions.rs:125:17 + | +LL | let foo = || { + | -- this is not `async` +LL | let _ = await!(bar())?; + | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/incorrect-syntax-suggestions.rs:18:19 | @@ -202,6 +242,6 @@ LL | let _ = await bar()?; = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future` = note: required by `std::ops::Try::into_result` -error: aborting due to 29 previous errors +error: aborting due to 35 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/await-keyword/post_expansion_error.stderr b/src/test/ui/async-await/await-keyword/post_expansion_error.stderr index 4e525974c2..0996c38b3b 100644 --- a/src/test/ui/async-await/await-keyword/post_expansion_error.stderr +++ b/src/test/ui/async-await/await-keyword/post_expansion_error.stderr @@ -2,9 +2,7 @@ error: expected expression, found `)` --> $DIR/post_expansion_error.rs:8:12 | LL | await!() - | ----- ^ expected expression - | | - | while parsing this await macro call + | ^ expected expression error: aborting due to previous error diff --git a/src/test/ui/async-await/await-macro.rs b/src/test/ui/async-await/await-macro.rs deleted file mode 100644 index 7d8b7a257d..0000000000 --- a/src/test/ui/async-await/await-macro.rs +++ /dev/null @@ -1,201 +0,0 @@ -// run-pass - -// edition:2018 -// aux-build:arc_wake.rs - -#![feature(async_await, await_macro)] - -extern crate arc_wake; - -use std::pin::Pin; -use std::future::Future; -use std::sync::{ - Arc, - atomic::{self, AtomicUsize}, -}; -use std::task::{Context, Poll}; -use arc_wake::ArcWake; - -struct Counter { - wakes: AtomicUsize, -} - -impl ArcWake for Counter { - fn wake(self: Arc) { - Self::wake_by_ref(&self) - } - fn wake_by_ref(arc_self: &Arc) { - arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); - } -} - -struct WakeOnceThenComplete(bool); - -fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } - -impl Future for WakeOnceThenComplete { - type Output = (); - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { - if self.0 { - Poll::Ready(()) - } else { - cx.waker().wake_by_ref(); - self.0 = true; - Poll::Pending - } - } -} - -fn async_block(x: u8) -> impl Future { - async move { - await!(wake_and_yield_once()); - x - } -} - -fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future + 'a { - async move { - await!(wake_and_yield_once()); - *x - } -} - -fn async_nonmove_block(x: u8) -> impl Future { - async move { - let future = async { - await!(wake_and_yield_once()); - x - }; - await!(future) - } -} - -fn async_closure(x: u8) -> impl Future { - (async move |x: u8| -> u8 { - await!(wake_and_yield_once()); - x - })(x) -} - -async fn async_fn(x: u8) -> u8 { - await!(wake_and_yield_once()); - x -} - -async fn generic_async_fn(x: T) -> T { - await!(wake_and_yield_once()); - x -} - -async fn async_fn_with_borrow(x: &u8) -> u8 { - await!(wake_and_yield_once()); - *x -} - -async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 { - await!(wake_and_yield_once()); - *x -} - -fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future + 'a { - async move { - await!(wake_and_yield_once()); - *x - } -} - -/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works -async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 { - await!(wake_and_yield_once()); - *x -} -*/ - -async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 { - await!(wake_and_yield_once()); - *x -} - -fn async_fn_with_internal_borrow(y: u8) -> impl Future { - async move { - await!(async_fn_with_borrow_named_lifetime(&y)) - } -} - -async unsafe fn unsafe_async_fn(x: u8) -> u8 { - await!(wake_and_yield_once()); - x -} - -struct Foo; - -trait Bar { - fn foo() {} -} - -impl Foo { - async fn async_method(x: u8) -> u8 { - unsafe { - await!(unsafe_async_fn(x)) - } - } -} - -fn test_future_yields_once_then_returns(f: F) -where - F: FnOnce(u8) -> Fut, - Fut: Future, -{ - let mut fut = Box::pin(f(9)); - let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); - let waker = ArcWake::into_waker(counter.clone()); - let mut cx = Context::from_waker(&waker); - assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); - assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); - assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); -} - -fn main() { - macro_rules! test { - ($($fn_name:expr,)*) => { $( - test_future_yields_once_then_returns($fn_name); - )* } - } - - macro_rules! test_with_borrow { - ($($fn_name:expr,)*) => { $( - test_future_yields_once_then_returns(|x| { - async move { - await!($fn_name(&x)) - } - }); - )* } - } - - test! { - async_block, - async_nonmove_block, - async_closure, - async_fn, - generic_async_fn, - async_fn_with_internal_borrow, - Foo::async_method, - |x| { - async move { - unsafe { await!(unsafe_async_fn(x)) } - } - }, - } - test_with_borrow! { - async_block_with_borrow_named_lifetime, - async_fn_with_borrow, - async_fn_with_borrow_named_lifetime, - async_fn_with_impl_future_named_lifetime, - |x| { - async move { - await!(async_fn_multiple_args_named_lifetime(x, x)) - } - }, - } -} diff --git a/src/test/ui/async-await/await-unsize.rs b/src/test/ui/async-await/await-unsize.rs new file mode 100644 index 0000000000..d5e21257f4 --- /dev/null +++ b/src/test/ui/async-await/await-unsize.rs @@ -0,0 +1,16 @@ +// Regression test for #62312 + +// check-pass +// edition:2018 + +#![feature(async_await)] + +async fn make_boxed_object() -> Box { + Box::new(()) as _ +} + +async fn await_object() { + let _ = make_boxed_object().await; +} + +fn main() {} diff --git a/src/test/ui/async-await/bound-normalization.rs b/src/test/ui/async-await/bound-normalization.rs new file mode 100644 index 0000000000..8026350aaf --- /dev/null +++ b/src/test/ui/async-await/bound-normalization.rs @@ -0,0 +1,16 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +// See issue 60414 + +trait Trait { + type Assoc; +} + +async fn foo>() -> T::Assoc { + () +} + +fn main() {} diff --git a/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs b/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs new file mode 100644 index 0000000000..a5947e7f71 --- /dev/null +++ b/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs @@ -0,0 +1,18 @@ +// check-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn conditional_and_guaranteed_initialization(x: usize) -> usize { + let y; + if x > 5 { + y = echo(10).await; + } else { + y = get_something().await; + } + y +} + +async fn echo(x: usize) -> usize { x } +async fn get_something() -> usize { 10 } diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs index c2b59eecb9..dfd8b2e361 100644 --- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs +++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs @@ -3,7 +3,7 @@ // run-pass #![allow(unused_variables)] -#![feature(async_await, await_macro)] +#![feature(async_await)] // Test that the drop order for parameters in a fn and async fn matches up. Also test that // parameters (used or unused) are not dropped until the async fn completes execution. diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs index 708c570498..2a74485afb 100644 --- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs +++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs @@ -3,7 +3,7 @@ // run-pass #![allow(unused_variables)] -#![feature(async_await, await_macro)] +#![feature(async_await)] // Test that the drop order for parameters in a fn and async fn matches up. Also test that // parameters (used or unused) are not dropped until the async fn completes execution. diff --git a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs new file mode 100644 index 0000000000..db396d3957 --- /dev/null +++ b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs @@ -0,0 +1,176 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +#![allow(unused_variables)] +#![deny(dead_code)] +#![feature(async_await)] + +// Test that the drop order for locals in a fn and async fn matches up. +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::marker::PhantomData; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::Arc; +use std::task::{Context, Poll}; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +struct NeverReady; + +impl Future for NeverReady { + type Output = (); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + Poll::Pending + } +} + +async fn simple_variable_declaration_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + NeverReady.await; +} + +fn simple_variable_declaration_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); +} + +async fn varable_completely_contained_within_block_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + async { + let x = D("x", l.clone()); + } + .await; + let y = D("y", l.clone()); + NeverReady.await; +} + +fn varable_completely_contained_within_block_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + { + let x = D("x", l.clone()); + } + let y = D("y", l.clone()); +} + +async fn variables_moved_into_separate_blocks_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + async move { x }.await; + async move { y }.await; + NeverReady.await; +} + +fn variables_moved_into_separate_blocks_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + { + x + }; + { + y + }; +} + +async fn variables_moved_into_same_block_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + async move { + x; + y; + }; + NeverReady.await; +} + +fn variables_moved_into_same_block_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + { + x; + y; + }; + return; +} + +async fn move_after_current_await_doesnt_affect_order(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + NeverReady.await; + async move { + x; + y; + }; +} + +fn assert_drop_order_after_cancel>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let _ = fut.as_mut().poll(&mut cx); + drop(fut); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + assert_drop_order_after_cancel( + simple_variable_declaration_async, + simple_variable_declaration_sync, + ); + assert_drop_order_after_cancel( + varable_completely_contained_within_block_async, + varable_completely_contained_within_block_sync, + ); + assert_drop_order_after_cancel( + variables_moved_into_separate_blocks_async, + variables_moved_into_separate_blocks_sync, + ); + assert_drop_order_after_cancel( + variables_moved_into_same_block_async, + variables_moved_into_same_block_sync, + ); + assert_drop_order_after_cancel( + move_after_current_await_doesnt_affect_order, + simple_variable_declaration_sync, + ); +} diff --git a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs new file mode 100644 index 0000000000..410a623681 --- /dev/null +++ b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs @@ -0,0 +1,307 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +#![allow(unused_variables)] +#![feature(async_await)] + +// Test that the drop order for parameters in a fn and async fn matches up. Also test that +// parameters (used or unused) are not dropped until the async fn is cancelled. +// This file is mostly copy-pasted from drop-order-for-async-fn-parameters.rs + +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::marker::PhantomData; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::Arc; +use std::task::{Context, Poll}; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +struct NeverReady; + +impl Future for NeverReady { + type Output = (); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + Poll::Pending + } +} + +/// Check that unused bindings are dropped after the function is polled. +async fn foo_async(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn foo_sync(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns are dropped after the function is polled. +async fn bar_async(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn bar_sync(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns within more complex patterns are dropped after the function +/// is polled. +async fn baz_async((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn baz_sync((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore and unused bindings within and outwith more complex patterns are dropped +/// after the function is polled. +async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +struct Foo; + +impl Foo { + /// Check that unused bindings are dropped after the method is polled. + async fn foo_async(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foo_sync(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method is polled. + async fn bar_async(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn bar_sync(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// is polled. + async fn baz_async((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn baz_sync((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method is polled. + async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +struct Bar<'a>(PhantomData<&'a ()>); + +impl<'a> Bar<'a> { + /// Check that unused bindings are dropped after the method with self is polled. + async fn foo_async(&'a self, x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foo_sync(&'a self, x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method with self is polled. + async fn bar_async(&'a self, x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn bar_sync(&'a self, x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// with self is polled. + async fn baz_async(&'a self, (x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn baz_sync(&'a self, (x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method with self is polled. + async fn foobar_async(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foobar_sync(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +fn assert_drop_order_after_cancel>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let _ = fut.as_mut().poll(&mut cx); + + // Parameters are never dropped until the future completes. + assert_eq!(*actual_order.borrow(), vec![DropOrder::Function]); + + drop(fut); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + // Free functions (see doc comment on function for what it tests). + assert_drop_order_after_cancel( + |l| foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| foo_sync(D("x", l.clone()), D("_y", l.clone())), + ); + assert_drop_order_after_cancel( + |l| bar_async(D("x", l.clone()), D("_", l.clone())), + |l| bar_sync(D("x", l.clone()), D("_", l.clone())), + ); + assert_drop_order_after_cancel( + |l| baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| baz_sync((D("x", l.clone()), D("_", l.clone()))), + ); + assert_drop_order_after_cancel( + |l| { + foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods w/out self (see doc comment on function for what it tests). + assert_drop_order_after_cancel( + |l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())), + ); + assert_drop_order_after_cancel( + |l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())), + |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())), + ); + assert_drop_order_after_cancel( + |l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))), + ); + assert_drop_order_after_cancel( + |l| { + Foo::foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + Foo::foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods (see doc comment on function for what it tests). + let b = Bar(Default::default()); + assert_drop_order_after_cancel( + |l| b.foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())), + ); + assert_drop_order_after_cancel( + |l| b.bar_async(D("x", l.clone()), D("_", l.clone())), + |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())), + ); + assert_drop_order_after_cancel( + |l| b.baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))), + ); + assert_drop_order_after_cancel( + |l| { + b.foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + b.foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); +} diff --git a/src/test/ui/async-await/feature-async-closure.rs b/src/test/ui/async-await/feature-async-closure.rs new file mode 100644 index 0000000000..d07116b13a --- /dev/null +++ b/src/test/ui/async-await/feature-async-closure.rs @@ -0,0 +1,8 @@ +// edition:2018 +// gate-test-async_closure + +fn f() { + let _ = async || {}; //~ ERROR async closures are unstable +} + +fn main() {} diff --git a/src/test/ui/async-await/feature-async-closure.stderr b/src/test/ui/async-await/feature-async-closure.stderr new file mode 100644 index 0000000000..c3a8c92149 --- /dev/null +++ b/src/test/ui/async-await/feature-async-closure.stderr @@ -0,0 +1,12 @@ +error[E0658]: async closures are unstable + --> $DIR/feature-async-closure.rs:5:13 + | +LL | let _ = async || {}; + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62290 + = help: add `#![feature(async_closure)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/futures-api.rs b/src/test/ui/async-await/futures-api.rs similarity index 98% rename from src/test/run-pass/futures-api.rs rename to src/test/ui/async-await/futures-api.rs index ee77053fd5..a7da058de3 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/ui/async-await/futures-api.rs @@ -1,3 +1,5 @@ +// run-pass + // aux-build:arc_wake.rs extern crate arc_wake; diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs index 913f1435c6..8b60f2f82f 100644 --- a/src/test/ui/async-await/generics-and-bounds.rs +++ b/src/test/ui/async-await/generics-and-bounds.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/run-pass/async-await/issue-60709.rs b/src/test/ui/async-await/issue-60709.rs similarity index 90% rename from src/test/run-pass/async-await/issue-60709.rs rename to src/test/ui/async-await/issue-60709.rs index 778d3ee0c7..ad0b49fa4a 100644 --- a/src/test/run-pass/async-await/issue-60709.rs +++ b/src/test/ui/async-await/issue-60709.rs @@ -2,7 +2,9 @@ // handled incorrectly in generators. // compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018 -#![feature(async_await, await_macro)] +// run-pass + +#![feature(async_await)] #![allow(unused)] use std::future::Future; @@ -22,7 +24,7 @@ impl Future for Never { fn main() { let fut = async { let _rc = Rc::new(()); // Also crashes with Arc - await!(Never()); + Never().await; }; let _bla = fut; // Moving the future is required. } diff --git a/src/test/ui/async-await/issue-61793.rs b/src/test/ui/async-await/issue-61793.rs index bccdf0113f..a18fad8bb9 100644 --- a/src/test/ui/async-await/issue-61793.rs +++ b/src/test/ui/async-await/issue-61793.rs @@ -3,7 +3,7 @@ // while those two fields were at the same offset (which is impossible). // That is, memory ordering of `(X, ())`, but offsets of `((), X)`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await)] diff --git a/src/test/ui/async-await/issue-62658.rs b/src/test/ui/async-await/issue-62658.rs new file mode 100644 index 0000000000..90fbb47bff --- /dev/null +++ b/src/test/ui/async-await/issue-62658.rs @@ -0,0 +1,29 @@ +// This test created a generator whose size was not rounded to a multiple of its +// alignment. This caused an assertion error in codegen. + +// build-pass +// edition:2018 + +#![feature(async_await)] + +async fn noop() {} + +async fn foo() { + // This suspend should be the largest variant. + { + let x = [0u8; 17]; + noop().await; + println!("{:?}", x); + } + + // Add one variant that's aligned to 8 bytes. + { + let x = 0u64; + noop().await; + println!("{:?}", x); + } +} + +fn main() { + let _ = foo(); +} diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs index 2157cf7d4f..c57dc6b0ef 100644 --- a/src/test/ui/async-await/issues/issue-53249.rs +++ b/src/test/ui/async-await/issues/issue-53249.rs @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(arbitrary_self_types, async_await, await_macro)] +#![feature(arbitrary_self_types, async_await)] use std::task::{self, Poll}; use std::future::Future; @@ -37,11 +37,11 @@ impl Future for Lazy async fn __receive(want: WantFn) -> () where Fut: Future, WantFn: Fn(&Box) -> Fut, { - await!(lazy(|_| ())); + lazy(|_| ()).await; } pub fn basic_spawn_receive() { - async { await!(__receive(|_| async { () })) }; + async { __receive(|_| async { () }).await }; } fn main() {} diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs index ad18f41187..040989b33f 100644 --- a/src/test/ui/async-await/issues/issue-54974.rs +++ b/src/test/ui/async-await/issues/issue-54974.rs @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] use std::sync::Arc; diff --git a/src/test/ui/async-await/issues/issue-55324.rs b/src/test/ui/async-await/issues/issue-55324.rs index 4572e543f2..4f383a51a8 100644 --- a/src/test/ui/async-await/issues/issue-55324.rs +++ b/src/test/ui/async-await/issues/issue-55324.rs @@ -1,13 +1,13 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] use std::future::Future; #[allow(unused)] async fn foo>(x: &i32, future: F) -> i32 { - let y = await!(future); + let y = future.await; *x + y } diff --git a/src/test/ui/async-await/issues/issue-58885.rs b/src/test/ui/async-await/issues/issue-58885.rs index 99d87b2273..47744aeea6 100644 --- a/src/test/ui/async-await/issues/issue-58885.rs +++ b/src/test/ui/async-await/issues/issue-58885.rs @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] struct Xyz { a: u64, diff --git a/src/test/ui/async-await/issues/issue-59001.rs b/src/test/ui/async-await/issues/issue-59001.rs index c758244002..9334ddb0af 100644 --- a/src/test/ui/async-await/issues/issue-59001.rs +++ b/src/test/ui/async-await/issues/issue-59001.rs @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] use std::future::Future; diff --git a/src/test/ui/async-await/issues/issue-59972.rs b/src/test/ui/async-await/issues/issue-59972.rs index 31e7a65dc9..8f4254b10c 100644 --- a/src/test/ui/async-await/issues/issue-59972.rs +++ b/src/test/ui/async-await/issues/issue-59972.rs @@ -1,8 +1,12 @@ +// Incorrect handling of uninhabited types could cause us to mark generator +// types as entirely uninhabited, when they were in fact constructible. This +// caused us to hit "unreachable" code (illegal instruction on x86). + // run-pass // compile-flags: --edition=2018 -#![feature(async_await, await_macro)] +#![feature(async_await)] pub enum Uninhabited { } @@ -15,11 +19,22 @@ async fn noop() { } #[allow(unused)] async fn contains_never() { let error = uninhabited_async(); - await!(noop()); + noop().await; let error2 = error; } +#[allow(unused)] +async fn overlap_never() { + let error1 = uninhabited_async(); + noop().await; + let error2 = uninhabited_async(); + drop(error1); + noop().await; + drop(error2); +} + #[allow(unused_must_use)] fn main() { contains_never(); + overlap_never(); } diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs index f603c5bd3f..e4bdc96511 100644 --- a/src/test/ui/async-await/issues/issue-60518.rs +++ b/src/test/ui/async-await/issues/issue-60518.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await)] diff --git a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs index a4fe865012..99213e64d1 100644 --- a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs +++ b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs @@ -1,13 +1,14 @@ -// Test that existential types are allowed to contain late-bound regions. +// Test that opaque `impl Trait` types are allowed to contain late-bound regions. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await, existential_type)] +#![feature(async_await)] +#![feature(type_alias_impl_trait)] use std::future::Future; -pub existential type Func: Sized; +pub type Func = impl Sized; // Late bound region should be allowed to escape the function, since it's bound // in the type. @@ -17,7 +18,7 @@ fn null_function_ptr() -> Func { async fn async_nop(_: &u8) {} -pub existential type ServeFut: Future; +pub type ServeFut = impl Future; // Late bound regions occur in the generator witness type here. fn serve() -> ServeFut { diff --git a/src/test/ui/async-await/issues/issue-60674.rs b/src/test/ui/async-await/issues/issue-60674.rs index ecb8080338..99cdcbafc7 100644 --- a/src/test/ui/async-await/issues/issue-60674.rs +++ b/src/test/ui/async-await/issues/issue-60674.rs @@ -1,5 +1,5 @@ // aux-build:issue-60674.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await)] diff --git a/src/test/ui/async-await/issues/issue-61986.rs b/src/test/ui/async-await/issues/issue-61986.rs index da8b22bc10..77ecc47dfe 100644 --- a/src/test/ui/async-await/issues/issue-61986.rs +++ b/src/test/ui/async-await/issues/issue-61986.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // // Tests that we properly handle StorageDead/StorageLives for temporaries diff --git a/src/test/ui/async-await/issues/issue-62009.rs b/src/test/ui/async-await/issues/issue-62009-1.rs similarity index 80% rename from src/test/ui/async-await/issues/issue-62009.rs rename to src/test/ui/async-await/issues/issue-62009-1.rs index e2d58cac24..ac6605bcef 100644 --- a/src/test/ui/async-await/issues/issue-62009.rs +++ b/src/test/ui/async-await/issues/issue-62009-1.rs @@ -11,8 +11,6 @@ fn main() { //~^ ERROR `await` is only allowed inside `async` functions and blocks let task1 = print_dur().await; }.await; - (async || 2333)().await; - //~^ ERROR `await` is only allowed inside `async` functions and blocks (|_| 2333).await; //~^ ERROR `await` is only allowed inside `async` functions and blocks //~^^ ERROR diff --git a/src/test/ui/async-await/issues/issue-62009.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr similarity index 62% rename from src/test/ui/async-await/issues/issue-62009.stderr rename to src/test/ui/async-await/issues/issue-62009-1.stderr index 53d1f34fe4..2bbb6d079e 100644 --- a/src/test/ui/async-await/issues/issue-62009.stderr +++ b/src/test/ui/async-await/issues/issue-62009-1.stderr @@ -1,5 +1,5 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009.rs:8:5 + --> $DIR/issue-62009-1.rs:8:5 | LL | fn main() { | ---- this is not `async` @@ -7,7 +7,7 @@ LL | async { let (); }.await; | ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009.rs:10:5 + --> $DIR/issue-62009-1.rs:10:5 | LL | fn main() { | ---- this is not `async` @@ -19,16 +19,7 @@ LL | | }.await; | |___________^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009.rs:14:5 - | -LL | fn main() { - | ---- this is not `async` -... -LL | (async || 2333)().await; - | ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks - -error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009.rs:16:5 + --> $DIR/issue-62009-1.rs:14:5 | LL | fn main() { | ---- this is not `async` @@ -36,14 +27,14 @@ LL | fn main() { LL | (|_| 2333).await; | ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks -error[E0277]: the trait bound `[closure@$DIR/issue-62009.rs:16:5: 16:15]: std::future::Future` is not satisfied - --> $DIR/issue-62009.rs:16:5 +error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied + --> $DIR/issue-62009-1.rs:14:5 | LL | (|_| 2333).await; - | ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009.rs:16:5: 16:15]` + | ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]` | = note: required by `std::future::poll_with_tls_context` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issues/issue-62009-2.rs b/src/test/ui/async-await/issues/issue-62009-2.rs new file mode 100644 index 0000000000..52b62eaa9e --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62009-2.rs @@ -0,0 +1,10 @@ +// edition:2018 + +#![feature(async_await, async_closure)] + +async fn print_dur() {} + +fn main() { + (async || 2333)().await; + //~^ ERROR `await` is only allowed inside `async` functions and blocks +} diff --git a/src/test/ui/async-await/issues/issue-62009-2.stderr b/src/test/ui/async-await/issues/issue-62009-2.stderr new file mode 100644 index 0000000000..79b6803263 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-62009-2.stderr @@ -0,0 +1,10 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/issue-62009-2.rs:8:5 + | +LL | fn main() { + | ---- this is not `async` +LL | (async || 2333)().await; + | ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/move-part-await-return-rest-struct.rs b/src/test/ui/async-await/move-part-await-return-rest-struct.rs new file mode 100644 index 0000000000..9bd7a515cb --- /dev/null +++ b/src/test/ui/async-await/move-part-await-return-rest-struct.rs @@ -0,0 +1,20 @@ +// build-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +struct Small { + x: Vec, + y: Vec, +} + +// You are allowed to move out part of a struct to an async fn, you still +// have access to remaining parts after awaiting +async fn move_part_await_return_rest_struct() -> Vec { + let s = Small { x: vec![31], y: vec![19, 1441] }; + needs_vec(s.x).await; + s.y +} + +async fn needs_vec(_vec: Vec) {} diff --git a/src/test/ui/async-await/move-part-await-return-rest-tuple.rs b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs new file mode 100644 index 0000000000..69eee855e7 --- /dev/null +++ b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs @@ -0,0 +1,14 @@ +// build-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn move_part_await_return_rest_tuple() -> Vec { + let x = (vec![3], vec![4, 4]); + drop(x.1); + echo(x.0[0]).await; + x.0 +} + +async fn echo(x: usize) -> usize { x } diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs index 620b008096..589e260d08 100644 --- a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs +++ b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs @@ -3,7 +3,7 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(arbitrary_self_types, async_await, await_macro)] +#![feature(async_await)] #![allow(dead_code)] use std::ops::Add; diff --git a/src/test/ui/async-await/multiple-lifetimes/named.rs b/src/test/ui/async-await/multiple-lifetimes/named.rs index 7d13d48bc8..cd479e256b 100644 --- a/src/test/ui/async-await/multiple-lifetimes/named.rs +++ b/src/test/ui/async-await/multiple-lifetimes/named.rs @@ -3,7 +3,7 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(arbitrary_self_types, async_await, await_macro)] +#![feature(async_await)] async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-args-non-move-async-closure.rs index 345f19b062..62d4b3fb6f 100644 --- a/src/test/ui/async-await/no-args-non-move-async-closure.rs +++ b/src/test/ui/async-await/no-args-non-move-async-closure.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(async_await, await_macro)] +#![feature(async_await, async_closure)] fn main() { let _ = async |x: u8| {}; diff --git a/src/test/ui/async-await/no-move-across-await-struct.rs b/src/test/ui/async-await/no-move-across-await-struct.rs new file mode 100644 index 0000000000..58e0947089 --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-struct.rs @@ -0,0 +1,19 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn no_move_across_await_struct() -> Vec { + let s = Small { x: vec![31], y: vec![19, 1441] }; + needs_vec(s.x).await; + s.x + //~^ ERROR use of moved value: `s.x` +} + +struct Small { + x: Vec, + y: Vec, +} + +async fn needs_vec(_vec: Vec) {} diff --git a/src/test/ui/async-await/no-move-across-await-struct.stderr b/src/test/ui/async-await/no-move-across-await-struct.stderr new file mode 100644 index 0000000000..121c7791bd --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-struct.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `s.x` + --> $DIR/no-move-across-await-struct.rs:10:5 + | +LL | needs_vec(s.x).await; + | --- value moved here +LL | s.x + | ^^^ value used here after move + | + = note: move occurs because `s.x` has type `std::vec::Vec`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/async-await/no-move-across-await-tuple.rs b/src/test/ui/async-await/no-move-across-await-tuple.rs new file mode 100644 index 0000000000..5d3ed3da1e --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-tuple.rs @@ -0,0 +1,15 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn no_move_across_await_tuple() -> Vec { + let x = (vec![3], vec![4, 4]); + drop(x.1); + nothing().await; + x.1 + //~^ ERROR use of moved value: `x.1` +} + +async fn nothing() {} diff --git a/src/test/ui/async-await/no-move-across-await-tuple.stderr b/src/test/ui/async-await/no-move-across-await-tuple.stderr new file mode 100644 index 0000000000..5da037ea5c --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-tuple.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `x.1` + --> $DIR/no-move-across-await-tuple.rs:11:5 + | +LL | drop(x.1); + | --- value moved here +LL | nothing().await; +LL | x.1 + | ^^^ value used here after move + | + = note: move occurs because `x.1` has type `std::vec::Vec`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs new file mode 100644 index 0000000000..a916afb6b0 --- /dev/null +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs @@ -0,0 +1,16 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn no_non_guaranteed_initialization(x: usize) -> usize { + let y; + if x > 5 { + y = echo(10).await; + } + y + //~^ use of possibly uninitialized variable: `y` +} + +async fn echo(x: usize) -> usize { x + 1 } diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr new file mode 100644 index 0000000000..fb94522cac --- /dev/null +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr @@ -0,0 +1,9 @@ +error[E0381]: use of possibly uninitialized variable: `y` + --> $DIR/no-non-guaranteed-initialization.rs:12:5 + | +LL | y + | ^ use of possibly uninitialized `y` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs new file mode 100644 index 0000000000..40f9f5202e --- /dev/null +++ b/src/test/ui/async-await/partial-initialization-across-await.rs @@ -0,0 +1,44 @@ +// Test that we don't allow awaiting from an async fn while a local is partially +// initialized. + +// edition:2018 + +#![feature(async_await)] + +struct S { x: i32, y: i32 } +struct T(i32, i32); + +async fn noop() {} + +async fn test_tuple() { + let mut t: (i32, i32); + t.0 = 42; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + noop().await; + t.1 = 88; + let _ = t; +} + +async fn test_tuple_struct() { + let mut t: T; + t.0 = 42; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + noop().await; + t.1 = 88; + let _ = t; +} + +async fn test_struct() { + let mut t: S; + t.x = 42; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + noop().await; + t.y = 88; + let _ = t; +} + +fn main() { + let _ = test_tuple(); + let _ = test_tuple_struct(); + let _ = test_struct(); +} diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr new file mode 100644 index 0000000000..fe79eb08be --- /dev/null +++ b/src/test/ui/async-await/partial-initialization-across-await.stderr @@ -0,0 +1,21 @@ +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/partial-initialization-across-await.rs:15:5 + | +LL | t.0 = 42; + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/partial-initialization-across-await.rs:24:5 + | +LL | t.0 = 42; + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/partial-initialization-across-await.rs:33:5 + | +LL | t.x = 42; + | ^^^^^^^^ use of possibly uninitialized `t` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.rs b/src/test/ui/async-await/recursive-async-impl-trait-type.rs index a4e0801193..54f3339870 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.rs +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.rs @@ -2,10 +2,10 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden when using `async` and `await`. -#![feature(await_macro, async_await, generators)] +#![feature(async_await)] async fn recursive_async_function() -> () { //~ ERROR - await!(recursive_async_function()); + recursive_async_function().await; } fn main() {} diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr index abc9ff54bd..64f6eccd54 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr @@ -1,11 +1,11 @@ -error[E0720]: opaque type expands to a recursive type +error[E0733]: recursion in an `async fn` requires boxing --> $DIR/recursive-async-impl-trait-type.rs:7:40 | LL | async fn recursive_async_function() -> () { - | ^^ expands to self-referential type + | ^^ an `async fn` cannot invoke itself directly | - = note: expanded type is `std::future::GenFuture<[static generator@$DIR/recursive-async-impl-trait-type.rs:7:43: 9:2 {impl std::future::Future, ()}]>` + = note: a recursive `async fn` must be rewritten to return a boxed future. error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0733`. diff --git a/src/test/ui/async-await/suggest-missing-await-closure.fixed b/src/test/ui/async-await/suggest-missing-await-closure.fixed new file mode 100644 index 0000000000..60c9a8581a --- /dev/null +++ b/src/test/ui/async-await/suggest-missing-await-closure.fixed @@ -0,0 +1,23 @@ +// edition:2018 +// run-rustfix + +#![feature(async_await, async_closure)] + +fn take_u32(_x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +#[allow(unused)] +async fn suggest_await_in_async_closure() { + async || { + let x = make_u32(); + take_u32(x.await) + //~^ ERROR mismatched types [E0308] + //~| HELP consider using `.await` here + //~| SUGGESTION x.await + }; +} + +fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await-closure.rs b/src/test/ui/async-await/suggest-missing-await-closure.rs new file mode 100644 index 0000000000..cb992a27bc --- /dev/null +++ b/src/test/ui/async-await/suggest-missing-await-closure.rs @@ -0,0 +1,23 @@ +// edition:2018 +// run-rustfix + +#![feature(async_await, async_closure)] + +fn take_u32(_x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +#[allow(unused)] +async fn suggest_await_in_async_closure() { + async || { + let x = make_u32(); + take_u32(x) + //~^ ERROR mismatched types [E0308] + //~| HELP consider using `.await` here + //~| SUGGESTION x.await + }; +} + +fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr new file mode 100644 index 0000000000..487ca6c0fc --- /dev/null +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/suggest-missing-await-closure.rs:16:18 + | +LL | take_u32(x) + | ^ + | | + | expected u32, found opaque type + | help: consider using `.await` here: `x.await` + | + = note: expected type `u32` + found type `impl std::future::Future` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/async-await/suggest-missing-await.fixed b/src/test/ui/async-await/suggest-missing-await.fixed index 282be368c6..aa032682be 100644 --- a/src/test/ui/async-await/suggest-missing-await.fixed +++ b/src/test/ui/async-await/suggest-missing-await.fixed @@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() { //~| SUGGESTION x.await } -#[allow(unused)] -async fn suggest_await_in_async_closure() { - async || { - let x = make_u32(); - take_u32(x.await) - //~^ ERROR mismatched types [E0308] - //~| HELP consider using `.await` here - //~| SUGGESTION x.await - }; -} - fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs index 36103f050c..2ca814fbb2 100644 --- a/src/test/ui/async-await/suggest-missing-await.rs +++ b/src/test/ui/async-await/suggest-missing-await.rs @@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() { //~| SUGGESTION x.await } -#[allow(unused)] -async fn suggest_await_in_async_closure() { - async || { - let x = make_u32(); - take_u32(x) - //~^ ERROR mismatched types [E0308] - //~| HELP consider using `.await` here - //~| SUGGESTION x.await - }; -} - fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 59c20dcfbc..9bae715027 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -10,18 +10,6 @@ LL | take_u32(x) = note: expected type `u32` found type `impl std::future::Future` -error[E0308]: mismatched types - --> $DIR/suggest-missing-await.rs:25:18 - | -LL | take_u32(x) - | ^ - | | - | expected u32, found opaque type - | help: consider using `.await` here: `x.await` - | - = note: expected type `u32` - found type `impl std::future::Future` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/run-pass/atomic-access-bool.rs b/src/test/ui/atomic-access-bool.rs similarity index 98% rename from src/test/run-pass/atomic-access-bool.rs rename to src/test/ui/atomic-access-bool.rs index 8522493232..e9d48bb3b4 100644 --- a/src/test/run-pass/atomic-access-bool.rs +++ b/src/test/ui/atomic-access-bool.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] #![feature(atomic_access)] use std::sync::atomic::AtomicBool; diff --git a/src/test/run-pass/atomic-alignment.rs b/src/test/ui/atomic-alignment.rs similarity index 99% rename from src/test/run-pass/atomic-alignment.rs rename to src/test/ui/atomic-alignment.rs index ec1dbf42e4..5bda90d2ea 100644 --- a/src/test/run-pass/atomic-alignment.rs +++ b/src/test/ui/atomic-alignment.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(cfg_target_has_atomic)] #![feature(integer_atomics)] diff --git a/src/test/run-pass/atomic-compare_exchange.rs b/src/test/ui/atomic-compare_exchange.rs similarity index 99% rename from src/test/run-pass/atomic-compare_exchange.rs rename to src/test/ui/atomic-compare_exchange.rs index 77da820e07..9b327eef3c 100644 --- a/src/test/run-pass/atomic-compare_exchange.rs +++ b/src/test/ui/atomic-compare_exchange.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] #![feature(extended_compare_and_swap)] diff --git a/src/test/run-pass/atomic-print.rs b/src/test/ui/atomic-print.rs similarity index 98% rename from src/test/run-pass/atomic-print.rs rename to src/test/ui/atomic-print.rs index ee76ef9b25..ef3453da68 100644 --- a/src/test/run-pass/atomic-print.rs +++ b/src/test/ui/atomic-print.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(deprecated)] // ignore-cloudabi no process support diff --git a/src/test/run-pass/attr-main-2.rs b/src/test/ui/attr-main-2.rs similarity index 84% rename from src/test/run-pass/attr-main-2.rs rename to src/test/ui/attr-main-2.rs index e0bf6ecc8f..3a51f83ba3 100644 --- a/src/test/run-pass/attr-main-2.rs +++ b/src/test/ui/attr-main-2.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(main)] pub fn main() { diff --git a/src/test/run-pass/attr-main.rs b/src/test/ui/attr-main.rs similarity index 85% rename from src/test/run-pass/attr-main.rs rename to src/test/ui/attr-main.rs index 645baf32e0..9c4caaa4a4 100644 --- a/src/test/run-pass/attr-main.rs +++ b/src/test/ui/attr-main.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(main)] diff --git a/src/test/run-pass/attr-shebang.rs b/src/test/ui/attr-shebang.rs similarity index 86% rename from src/test/run-pass/attr-shebang.rs rename to src/test/ui/attr-shebang.rs index 73f1041082..cce31c9bb7 100644 --- a/src/test/run-pass/attr-shebang.rs +++ b/src/test/ui/attr-shebang.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] #![feature(rust1)] pub fn main() { } diff --git a/src/test/run-pass/attr-start.rs b/src/test/ui/attr-start.rs similarity index 91% rename from src/test/run-pass/attr-start.rs rename to src/test/ui/attr-start.rs index 29f86c9b59..6777631484 100644 --- a/src/test/run-pass/attr-start.rs +++ b/src/test/ui/attr-start.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(start)] diff --git a/src/test/run-pass/attr.rs b/src/test/ui/attr.rs similarity index 85% rename from src/test/run-pass/attr.rs rename to src/test/ui/attr.rs index 645baf32e0..9c4caaa4a4 100644 --- a/src/test/run-pass/attr.rs +++ b/src/test/ui/attr.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(main)] diff --git a/src/test/ui/attributes/attr-before-view-item.rs b/src/test/ui/attributes/attr-before-view-item.rs index fc040bd1a5..e1588aadab 100644 --- a/src/test/ui/attributes/attr-before-view-item.rs +++ b/src/test/ui/attributes/attr-before-view-item.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/attr-before-view-item2.rs b/src/test/ui/attributes/attr-before-view-item2.rs index c7fad3802e..c1f667372f 100644 --- a/src/test/ui/attributes/attr-before-view-item2.rs +++ b/src/test/ui/attributes/attr-before-view-item2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/attr-mix-new.rs b/src/test/ui/attributes/attr-mix-new.rs index d9cb551096..8119df0c40 100644 --- a/src/test/ui/attributes/attr-mix-new.rs +++ b/src/test/ui/attributes/attr-mix-new.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs index ca5fdd9da8..df9c8d8946 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs @@ -6,10 +6,8 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); -impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { +impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { //~^ ERROR trailing attribute after generic parameter } -fn main() { - -} +fn main() {} diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr index 55e7a98778..5b4f5222a2 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr @@ -1,8 +1,8 @@ error: trailing attribute after generic parameter - --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25 + --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:29 | -LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { - | ^^^^^^^ attributes must go before parameters +LL | impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs index c795612acf..d1d0440352 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs @@ -6,7 +6,7 @@ struct RefAny<'a, T>(&'a T); -impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} +impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {} //~^ ERROR trailing attribute after generic parameter fn main() {} diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr index acd0ae3678..fce3ff7de7 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr @@ -1,8 +1,8 @@ error: trailing attribute after generic parameter - --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35 + --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:43 | -LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} - | ^^^^^^^ attributes must go before parameters +LL | impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {} + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attributes/class-attributes-1.rs b/src/test/ui/attributes/class-attributes-1.rs index 7808367f2c..027b701e59 100644 --- a/src/test/ui/attributes/class-attributes-1.rs +++ b/src/test/ui/attributes/class-attributes-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pp-exact - Make sure we actually print the attributes #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/class-attributes-2.rs b/src/test/ui/attributes/class-attributes-2.rs index 348c70f35c..6aba6b8942 100644 --- a/src/test/ui/attributes/class-attributes-2.rs +++ b/src/test/ui/attributes/class-attributes-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/item-attributes.rs b/src/test/ui/attributes/item-attributes.rs index 72c9a35dc0..c760a28ecf 100644 --- a/src/test/ui/attributes/item-attributes.rs +++ b/src/test/ui/attributes/item-attributes.rs @@ -2,7 +2,7 @@ // for completeness since .rs files linked from .rc files support this // notation to specify their module's attributes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/method-attributes.rs b/src/test/ui/attributes/method-attributes.rs index 2d608acc71..67439718bd 100644 --- a/src/test/ui/attributes/method-attributes.rs +++ b/src/test/ui/attributes/method-attributes.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pp-exact - Make sure we print all the attributes // pretty-expanded FIXME #23616 diff --git a/src/test/ui/attributes/obsolete-attr.rs b/src/test/ui/attributes/obsolete-attr.rs index 89e2ad2669..8759344e6f 100644 --- a/src/test/ui/attributes/obsolete-attr.rs +++ b/src/test/ui/attributes/obsolete-attr.rs @@ -1,7 +1,9 @@ // Obsolete attributes fall back to feature gated custom attributes. -#[ab_isize="stdcall"] extern {} //~ ERROR attribute `ab_isize` is currently unknown +#[ab_isize="stdcall"] extern {} +//~^ ERROR cannot find attribute macro `ab_isize` in this scope -#[fixed_stack_segment] fn f() {} //~ ERROR attribute `fixed_stack_segment` is currently unknown +#[fixed_stack_segment] fn f() {} +//~^ ERROR cannot find attribute macro `fixed_stack_segment` in this scope fn main() {} diff --git a/src/test/ui/attributes/obsolete-attr.stderr b/src/test/ui/attributes/obsolete-attr.stderr index 2ed7f87935..9c6909f65f 100644 --- a/src/test/ui/attributes/obsolete-attr.stderr +++ b/src/test/ui/attributes/obsolete-attr.stderr @@ -1,21 +1,14 @@ -error[E0658]: The attribute `fixed_stack_segment` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/obsolete-attr.rs:5:3 +error: cannot find attribute macro `fixed_stack_segment` in this scope + --> $DIR/obsolete-attr.rs:6:3 | LL | #[fixed_stack_segment] fn f() {} | ^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `ab_isize` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `ab_isize` in this scope --> $DIR/obsolete-attr.rs:3:3 | LL | #[ab_isize="stdcall"] extern {} | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/attributes/unknown-attr.rs b/src/test/ui/attributes/unknown-attr.rs index e2a4f3226d..140a1fc3f9 100644 --- a/src/test/ui/attributes/unknown-attr.rs +++ b/src/test/ui/attributes/unknown-attr.rs @@ -2,8 +2,11 @@ #![feature(custom_inner_attributes)] -#![mutable_doc] //~ ERROR attribute `mutable_doc` is currently unknown +#![mutable_doc] +//~^ ERROR cannot find attribute macro `mutable_doc` in this scope -#[dance] mod a {} //~ ERROR attribute `dance` is currently unknown +#[dance] mod a {} +//~^ ERROR cannot find attribute macro `dance` in this scope -#[dance] fn main() {} //~ ERROR attribute `dance` is currently unknown +#[dance] fn main() {} +//~^ ERROR cannot find attribute macro `dance` in this scope diff --git a/src/test/ui/attributes/unknown-attr.stderr b/src/test/ui/attributes/unknown-attr.stderr index d0ac58108f..4d463874d6 100644 --- a/src/test/ui/attributes/unknown-attr.stderr +++ b/src/test/ui/attributes/unknown-attr.stderr @@ -1,30 +1,20 @@ -error[E0658]: The attribute `mutable_doc` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `mutable_doc` in this scope --> $DIR/unknown-attr.rs:5:4 | LL | #![mutable_doc] | ^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `dance` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/unknown-attr.rs:7:3 +error: cannot find attribute macro `dance` in this scope + --> $DIR/unknown-attr.rs:8:3 | LL | #[dance] mod a {} | ^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `dance` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/unknown-attr.rs:9:3 +error: cannot find attribute macro `dance` in this scope + --> $DIR/unknown-attr.rs:11:3 | LL | #[dance] fn main() {} | ^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/attributes/variant-attributes.rs b/src/test/ui/attributes/variant-attributes.rs index a910340f4a..ffcdeb52a0 100644 --- a/src/test/ui/attributes/variant-attributes.rs +++ b/src/test/ui/attributes/variant-attributes.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pp-exact - Make sure we actually print the attributes // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/augmented-assignments-feature-gate-cross.rs b/src/test/ui/augmented-assignments-feature-gate-cross.rs similarity index 92% rename from src/test/run-pass/augmented-assignments-feature-gate-cross.rs rename to src/test/ui/augmented-assignments-feature-gate-cross.rs index 566d452280..84988feb6f 100644 --- a/src/test/run-pass/augmented-assignments-feature-gate-cross.rs +++ b/src/test/ui/augmented-assignments-feature-gate-cross.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:augmented_assignments.rs extern crate augmented_assignments; diff --git a/src/test/run-pass/augmented-assignments-feature-gate.rs b/src/test/ui/augmented-assignments-feature-gate.rs similarity index 92% rename from src/test/run-pass/augmented-assignments-feature-gate.rs rename to src/test/ui/augmented-assignments-feature-gate.rs index 7809ac8ea9..8e686796fe 100644 --- a/src/test/run-pass/augmented-assignments-feature-gate.rs +++ b/src/test/ui/augmented-assignments-feature-gate.rs @@ -1,3 +1,5 @@ +// run-pass + use std::ops::AddAssign; struct Int(i32); diff --git a/src/test/run-pass/augmented-assignments.rs b/src/test/ui/augmented-assignments-rpass.rs similarity index 99% rename from src/test/run-pass/augmented-assignments.rs rename to src/test/ui/augmented-assignments-rpass.rs index c26d0ffce4..fb383cc57a 100644 --- a/src/test/run-pass/augmented-assignments.rs +++ b/src/test/ui/augmented-assignments-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] #![deny(unused_assignments)] diff --git a/src/test/run-pass/auto-instantiate.rs b/src/test/ui/auto-instantiate.rs similarity index 95% rename from src/test/run-pass/auto-instantiate.rs rename to src/test/ui/auto-instantiate.rs index ac21409e92..a58b178287 100644 --- a/src/test/run-pass/auto-instantiate.rs +++ b/src/test/ui/auto-instantiate.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #[derive(Debug)] struct Pair { a: T, b: U } diff --git a/src/test/run-pass/auto-is-contextual.rs b/src/test/ui/auto-is-contextual.rs similarity index 93% rename from src/test/run-pass/auto-is-contextual.rs rename to src/test/ui/auto-is-contextual.rs index 3405cc712d..a2ddd5374c 100644 --- a/src/test/run-pass/auto-is-contextual.rs +++ b/src/test/ui/auto-is-contextual.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(path_statements)] #![allow(dead_code)] macro_rules! auto { diff --git a/src/test/run-pass/autobind.rs b/src/test/ui/autobind.rs similarity index 96% rename from src/test/run-pass/autobind.rs rename to src/test/ui/autobind.rs index bb38b7afdf..70606a2a20 100644 --- a/src/test/run-pass/autobind.rs +++ b/src/test/ui/autobind.rs @@ -1,3 +1,5 @@ +// run-pass + fn f(x: Vec) -> T { return x.into_iter().next().unwrap(); } fn g(act: F) -> isize where F: FnOnce(Vec) -> isize { return act(vec![1, 2, 3]); } diff --git a/src/test/run-pass/autoref-autoderef/auto-ref-bounded-ty-param.rs b/src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/auto-ref-bounded-ty-param.rs rename to src/test/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs diff --git a/src/test/run-pass/autoref-autoderef/auto-ref-sliceable.rs b/src/test/ui/autoref-autoderef/auto-ref-sliceable.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/auto-ref-sliceable.rs rename to src/test/ui/autoref-autoderef/auto-ref-sliceable.rs diff --git a/src/test/run-pass/autoref-autoderef/auto-ref.rs b/src/test/ui/autoref-autoderef/auto-ref.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/auto-ref.rs rename to src/test/ui/autoref-autoderef/auto-ref.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-and-borrow-method-receiver.rs rename to src/test/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-method-on-trait.rs b/src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-method-on-trait.rs rename to src/test/ui/autoref-autoderef/autoderef-method-on-trait.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-method-priority.rs b/src/test/ui/autoref-autoderef/autoderef-method-priority.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-method-priority.rs rename to src/test/ui/autoref-autoderef/autoderef-method-priority.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs b/src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs rename to src/test/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-method-twice.rs b/src/test/ui/autoref-autoderef/autoderef-method-twice.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-method-twice.rs rename to src/test/ui/autoref-autoderef/autoderef-method-twice.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-method.rs b/src/test/ui/autoref-autoderef/autoderef-method.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-method.rs rename to src/test/ui/autoref-autoderef/autoderef-method.rs diff --git a/src/test/run-pass/autoref-autoderef/autoderef-privacy.rs b/src/test/ui/autoref-autoderef/autoderef-privacy.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoderef-privacy.rs rename to src/test/ui/autoref-autoderef/autoderef-privacy.rs diff --git a/src/test/run-pass/autoref-autoderef/autoref-intermediate-types-issue-3585.rs b/src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs similarity index 100% rename from src/test/run-pass/autoref-autoderef/autoref-intermediate-types-issue-3585.rs rename to src/test/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs diff --git a/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs similarity index 100% rename from src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs rename to src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs diff --git a/src/test/run-pass/auxiliary/augmented_assignments.rs b/src/test/ui/auxiliary/augmented_assignments.rs similarity index 100% rename from src/test/run-pass/auxiliary/augmented_assignments.rs rename to src/test/ui/auxiliary/augmented_assignments.rs diff --git a/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs b/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs similarity index 100% rename from src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs rename to src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs diff --git a/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs similarity index 100% rename from src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs rename to src/test/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs diff --git a/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs b/src/test/ui/auxiliary/check_static_recursion_foreign_helper.rs similarity index 100% rename from src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs rename to src/test/ui/auxiliary/check_static_recursion_foreign_helper.rs diff --git a/src/test/run-pass/auxiliary/cond_plugin.rs b/src/test/ui/auxiliary/cond_plugin.rs similarity index 100% rename from src/test/run-pass/auxiliary/cond_plugin.rs rename to src/test/ui/auxiliary/cond_plugin.rs diff --git a/src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs similarity index 100% rename from src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs rename to src/test/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs diff --git a/src/test/run-pass/auxiliary/debuginfo-lto-aux.rs b/src/test/ui/auxiliary/debuginfo-lto-aux.rs similarity index 100% rename from src/test/run-pass/auxiliary/debuginfo-lto-aux.rs rename to src/test/ui/auxiliary/debuginfo-lto-aux.rs diff --git a/src/test/run-pass/auxiliary/edition-kw-macro-2015.rs b/src/test/ui/auxiliary/edition-kw-macro-2015.rs similarity index 100% rename from src/test/run-pass/auxiliary/edition-kw-macro-2015.rs rename to src/test/ui/auxiliary/edition-kw-macro-2015.rs diff --git a/src/test/run-pass/auxiliary/edition-kw-macro-2018.rs b/src/test/ui/auxiliary/edition-kw-macro-2018.rs similarity index 100% rename from src/test/run-pass/auxiliary/edition-kw-macro-2018.rs rename to src/test/ui/auxiliary/edition-kw-macro-2018.rs diff --git a/src/test/run-pass/auxiliary/foreign_lib.rs b/src/test/ui/auxiliary/foreign_lib.rs similarity index 100% rename from src/test/run-pass/auxiliary/foreign_lib.rs rename to src/test/ui/auxiliary/foreign_lib.rs diff --git a/src/test/run-pass/auxiliary/hello_macro.rs b/src/test/ui/auxiliary/hello_macro.rs similarity index 100% rename from src/test/run-pass/auxiliary/hello_macro.rs rename to src/test/ui/auxiliary/hello_macro.rs diff --git a/src/test/run-pass/auxiliary/impl_privacy_xc_1.rs b/src/test/ui/auxiliary/impl_privacy_xc_1.rs similarity index 100% rename from src/test/run-pass/auxiliary/impl_privacy_xc_1.rs rename to src/test/ui/auxiliary/impl_privacy_xc_1.rs diff --git a/src/test/run-pass/auxiliary/impl_privacy_xc_2.rs b/src/test/ui/auxiliary/impl_privacy_xc_2.rs similarity index 100% rename from src/test/run-pass/auxiliary/impl_privacy_xc_2.rs rename to src/test/ui/auxiliary/impl_privacy_xc_2.rs diff --git a/src/test/run-pass/auxiliary/inline_dtor.rs b/src/test/ui/auxiliary/inline_dtor.rs similarity index 100% rename from src/test/run-pass/auxiliary/inline_dtor.rs rename to src/test/ui/auxiliary/inline_dtor.rs diff --git a/src/test/run-pass/auxiliary/inner_static.rs b/src/test/ui/auxiliary/inner_static.rs similarity index 100% rename from src/test/run-pass/auxiliary/inner_static.rs rename to src/test/ui/auxiliary/inner_static.rs diff --git a/src/test/run-pass/auxiliary/kinds_in_metadata.rs b/src/test/ui/auxiliary/kinds_in_metadata.rs similarity index 100% rename from src/test/run-pass/auxiliary/kinds_in_metadata.rs rename to src/test/ui/auxiliary/kinds_in_metadata.rs diff --git a/src/test/run-pass/auxiliary/link-cfg-works-transitive-dylib.rs b/src/test/ui/auxiliary/link-cfg-works-transitive-dylib.rs similarity index 100% rename from src/test/run-pass/auxiliary/link-cfg-works-transitive-dylib.rs rename to src/test/ui/auxiliary/link-cfg-works-transitive-dylib.rs diff --git a/src/test/run-pass/auxiliary/link-cfg-works-transitive-rlib.rs b/src/test/ui/auxiliary/link-cfg-works-transitive-rlib.rs similarity index 100% rename from src/test/run-pass/auxiliary/link-cfg-works-transitive-rlib.rs rename to src/test/ui/auxiliary/link-cfg-works-transitive-rlib.rs diff --git a/src/test/run-pass/auxiliary/linkage1.rs b/src/test/ui/auxiliary/linkage1.rs similarity index 100% rename from src/test/run-pass/auxiliary/linkage1.rs rename to src/test/ui/auxiliary/linkage1.rs diff --git a/src/test/run-pass/auxiliary/llvm_pr32379.rs b/src/test/ui/auxiliary/llvm_pr32379.rs similarity index 100% rename from src/test/run-pass/auxiliary/llvm_pr32379.rs rename to src/test/ui/auxiliary/llvm_pr32379.rs diff --git a/src/test/run-pass/auxiliary/msvc-data-only-lib.rs b/src/test/ui/auxiliary/msvc-data-only-lib.rs similarity index 100% rename from src/test/run-pass/auxiliary/msvc-data-only-lib.rs rename to src/test/ui/auxiliary/msvc-data-only-lib.rs diff --git a/src/test/run-pass/auxiliary/nested_item.rs b/src/test/ui/auxiliary/nested_item.rs similarity index 100% rename from src/test/run-pass/auxiliary/nested_item.rs rename to src/test/ui/auxiliary/nested_item.rs diff --git a/src/test/run-pass/auxiliary/proc_macro_def.rs b/src/test/ui/auxiliary/proc_macro_def.rs similarity index 100% rename from src/test/run-pass/auxiliary/proc_macro_def.rs rename to src/test/ui/auxiliary/proc_macro_def.rs diff --git a/src/test/run-pass/auxiliary/reachable-unnameable-items.rs b/src/test/ui/auxiliary/reachable-unnameable-items.rs similarity index 100% rename from src/test/run-pass/auxiliary/reachable-unnameable-items.rs rename to src/test/ui/auxiliary/reachable-unnameable-items.rs diff --git a/src/test/run-pass/auxiliary/reexport-should-still-link.rs b/src/test/ui/auxiliary/reexport-should-still-link.rs similarity index 100% rename from src/test/run-pass/auxiliary/reexport-should-still-link.rs rename to src/test/ui/auxiliary/reexport-should-still-link.rs diff --git a/src/test/run-pass/auxiliary/rmeta-rlib.rs b/src/test/ui/auxiliary/rmeta-rlib-rpass.rs similarity index 100% rename from src/test/run-pass/auxiliary/rmeta-rlib.rs rename to src/test/ui/auxiliary/rmeta-rlib-rpass.rs diff --git a/src/test/run-pass/auxiliary/rmeta-rmeta.rs b/src/test/ui/auxiliary/rmeta-rmeta.rs similarity index 100% rename from src/test/run-pass/auxiliary/rmeta-rmeta.rs rename to src/test/ui/auxiliary/rmeta-rmeta.rs diff --git a/src/test/run-pass/auxiliary/svh-a-base.rs b/src/test/ui/auxiliary/svh-a-base.rs similarity index 100% rename from src/test/run-pass/auxiliary/svh-a-base.rs rename to src/test/ui/auxiliary/svh-a-base.rs diff --git a/src/test/run-pass/auxiliary/svh-b.rs b/src/test/ui/auxiliary/svh-b.rs similarity index 100% rename from src/test/run-pass/auxiliary/svh-b.rs rename to src/test/ui/auxiliary/svh-b.rs diff --git a/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs b/src/test/ui/auxiliary/trait_superkinds_in_metadata.rs similarity index 100% rename from src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs rename to src/test/ui/auxiliary/trait_superkinds_in_metadata.rs diff --git a/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs b/src/test/ui/auxiliary/typeid-intrinsic-aux1.rs similarity index 100% rename from src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs rename to src/test/ui/auxiliary/typeid-intrinsic-aux1.rs diff --git a/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs b/src/test/ui/auxiliary/typeid-intrinsic-aux2.rs similarity index 100% rename from src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs rename to src/test/ui/auxiliary/typeid-intrinsic-aux2.rs diff --git a/src/test/run-pass/auxiliary/using-target-feature-unstable.rs b/src/test/ui/auxiliary/using-target-feature-unstable.rs similarity index 100% rename from src/test/run-pass/auxiliary/using-target-feature-unstable.rs rename to src/test/ui/auxiliary/using-target-feature-unstable.rs diff --git a/src/test/run-pass/backtrace-debuginfo-aux.rs b/src/test/ui/backtrace-debuginfo-aux.rs similarity index 97% rename from src/test/run-pass/backtrace-debuginfo-aux.rs rename to src/test/ui/backtrace-debuginfo-aux.rs index 781d6eba5e..1411bcf89e 100644 --- a/src/test/run-pass/backtrace-debuginfo-aux.rs +++ b/src/test/ui/backtrace-debuginfo-aux.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-test: not a test, used by backtrace-debuginfo.rs to test file!() #[inline(never)] diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/ui/backtrace-debuginfo.rs similarity index 85% rename from src/test/run-pass/backtrace-debuginfo.rs rename to src/test/ui/backtrace-debuginfo.rs index 69ce1f7032..0f31842b3b 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/ui/backtrace-debuginfo.rs @@ -1,3 +1,4 @@ +// run-pass // We disable tail merging here because it can't preserve debuginfo and thus // potentially breaks the backtraces. Also, subtle changes can decide whether // tail merging succeeds, so the test might work today but fail tomorrow due to a @@ -10,8 +11,8 @@ // ignore-pretty issue #37195 // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported -// normalize-stderr-test ".*\n" -> "" // ignore-sgx no processes +// normalize-stderr-test ".*\n" -> "" // Note that above `-opt-bisect-limit=0` is used to basically disable // optimizations. It creates tons of output on stderr, hence we normalize @@ -29,8 +30,23 @@ macro_rules! dump_and_die { ($($pos:expr),*) => ({ // FIXME(#18285): we cannot include the current position because // the macro span takes over the last frame's file/line. + // + // You might also be wondering why a major platform, + // i686-pc-windows-msvc, is located in here. Some of the saga can be + // found on #62897, but the tl;dr; is that it appears that if the + // standard library doesn't have debug information or frame pointers, + // which it doesn't by default on the test builders, then the stack + // walking routines in dbghelp will randomly terminate the stack trace + // in libstd without going further. Presumably the addition of frame + // pointers and/or debuginfo fixes this since tests always work with + // nightly compilers (which have debuginfo). In general though this test + // is replicated in rust-lang/backtrace-rs and has extensive coverage + // there, even on i686-pc-windows-msvc. We do the best we can in + // rust-lang/rust to test it as well, but sometimes we just gotta keep + // landing PRs. if cfg!(any(target_os = "android", all(target_os = "linux", target_arch = "arm"), + all(target_env = "msvc", target_arch = "x86"), target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")) { diff --git a/src/test/run-pass/backtrace.rs b/src/test/ui/backtrace.rs similarity index 98% rename from src/test/run-pass/backtrace.rs rename to src/test/ui/backtrace.rs index c73ba293ee..234a7f801c 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/ui/backtrace.rs @@ -1,8 +1,10 @@ +// run-pass // ignore-android FIXME #17520 // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported // ignore-openbsd no support for libbacktrace without filename // ignore-sgx no processes +// ignore-msvc see #62897 and `backtrace-debuginfo.rs` test // compile-flags:-g use std::env; diff --git a/src/test/ui/bad/bad-extern-link-attrs.stderr b/src/test/ui/bad/bad-extern-link-attrs.stderr index 18b0dc9ea3..525c605a9c 100644 --- a/src/test/ui/bad/bad-extern-link-attrs.stderr +++ b/src/test/ui/bad/bad-extern-link-attrs.stderr @@ -1,10 +1,10 @@ -error[E0459]: #[link(...)] specified without `name = "foo"` +error[E0459]: `#[link(...)]` specified without `name = "foo"` --> $DIR/bad-extern-link-attrs.rs:1:1 | LL | #[link()] | ^^^^^^^^^ missing `name` argument -error[E0454]: #[link(name = "")] given with empty name +error[E0454]: `#[link(name = "")]` given with empty name --> $DIR/bad-extern-link-attrs.rs:2:1 | LL | #[link(name = "")] diff --git a/src/test/ui/bad/bad-lint-cap2.stderr b/src/test/ui/bad/bad-lint-cap2.stderr index f6e67e6d78..75e257893f 100644 --- a/src/test/ui/bad/bad-lint-cap2.stderr +++ b/src/test/ui/bad/bad-lint-cap2.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(unused_imports)] implied by #[deny(warnings)] + = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]` error: aborting due to previous error diff --git a/src/test/ui/bad/bad-lint-cap3.stderr b/src/test/ui/bad/bad-lint-cap3.stderr index b898d792f6..96b40c98c0 100644 --- a/src/test/ui/bad/bad-lint-cap3.stderr +++ b/src/test/ui/bad/bad-lint-cap3.stderr @@ -9,5 +9,5 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[warn(unused_imports)] implied by #[warn(warnings)] + = note: `#[warn(unused_imports)]` implied by `#[warn(warnings)]` diff --git a/src/test/run-pass/bare-fn-implements-fn-mut.rs b/src/test/ui/bare-fn-implements-fn-mut.rs similarity index 96% rename from src/test/run-pass/bare-fn-implements-fn-mut.rs rename to src/test/ui/bare-fn-implements-fn-mut.rs index c06fc702ca..dfead48893 100644 --- a/src/test/run-pass/bare-fn-implements-fn-mut.rs +++ b/src/test/ui/bare-fn-implements-fn-mut.rs @@ -1,3 +1,5 @@ +// run-pass + use std::ops::FnMut; fn call_f(mut f: F) { diff --git a/src/test/run-pass/bare-static-string.rs b/src/test/ui/bare-static-string.rs similarity index 85% rename from src/test/run-pass/bare-static-string.rs rename to src/test/ui/bare-static-string.rs index 8d4782226d..d336dc7c6a 100644 --- a/src/test/run-pass/bare-static-string.rs +++ b/src/test/ui/bare-static-string.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let x: &'static str = "foo"; println!("{}", x); diff --git a/src/test/ui/bastion-of-the-turbofish.rs b/src/test/ui/bastion-of-the-turbofish.rs index 0716fcf7f2..cc43210d8e 100644 --- a/src/test/ui/bastion-of-the-turbofish.rs +++ b/src/test/ui/bastion-of-the-turbofish.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Bastion of the Turbofish // ------------------------ diff --git a/src/test/run-pass/bench/issue-32062.rs b/src/test/ui/bench/issue-32062.rs similarity index 100% rename from src/test/run-pass/bench/issue-32062.rs rename to src/test/ui/bench/issue-32062.rs diff --git a/src/test/run-pass/big-literals.rs b/src/test/ui/big-literals.rs similarity index 97% rename from src/test/run-pass/big-literals.rs rename to src/test/ui/big-literals.rs index 9b1fa2123f..131de5439b 100644 --- a/src/test/run-pass/big-literals.rs +++ b/src/test/ui/big-literals.rs @@ -1,3 +1,4 @@ +// run-pass // Catch mistakes in the overflowing literals lint. #![deny(overflowing_literals)] diff --git a/src/test/run-pass/binary-minus-without-space.rs b/src/test/ui/binary-minus-without-space.rs similarity index 91% rename from src/test/run-pass/binary-minus-without-space.rs rename to src/test/ui/binary-minus-without-space.rs index 60d00e7cf5..2fbd5300dd 100644 --- a/src/test/run-pass/binary-minus-without-space.rs +++ b/src/test/ui/binary-minus-without-space.rs @@ -1,3 +1,4 @@ +// run-pass // Check that issue #954 stays fixed diff --git a/src/test/run-pass/bind-by-move.rs b/src/test/ui/bind-by-move.rs similarity index 93% rename from src/test/run-pass/bind-by-move.rs rename to src/test/ui/bind-by-move.rs index 82db89468d..f0a9ebdd08 100644 --- a/src/test/run-pass/bind-by-move.rs +++ b/src/test/ui/bind-by-move.rs @@ -1,3 +1,5 @@ +// run-pass + use std::sync::Arc; fn dispose(_x: Arc) { } diff --git a/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr b/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr index 5f8b7007f3..c5f0256c2c 100644 --- a/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr +++ b/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr @@ -4,7 +4,7 @@ error[E0008]: cannot bind by-move into a pattern guard LL | Some(z) if z.recv().unwrap() => { panic!() }, | ^ moves value into pattern guard | - = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/binding/bind-field-short-with-modifiers.rs b/src/test/ui/binding/bind-field-short-with-modifiers.rs similarity index 100% rename from src/test/run-pass/binding/bind-field-short-with-modifiers.rs rename to src/test/ui/binding/bind-field-short-with-modifiers.rs diff --git a/src/test/run-pass/binding/borrowed-ptr-pattern-2.rs b/src/test/ui/binding/borrowed-ptr-pattern-2.rs similarity index 100% rename from src/test/run-pass/binding/borrowed-ptr-pattern-2.rs rename to src/test/ui/binding/borrowed-ptr-pattern-2.rs diff --git a/src/test/run-pass/binding/borrowed-ptr-pattern-3.rs b/src/test/ui/binding/borrowed-ptr-pattern-3.rs similarity index 100% rename from src/test/run-pass/binding/borrowed-ptr-pattern-3.rs rename to src/test/ui/binding/borrowed-ptr-pattern-3.rs diff --git a/src/test/run-pass/binding/borrowed-ptr-pattern-infallible.rs b/src/test/ui/binding/borrowed-ptr-pattern-infallible.rs similarity index 100% rename from src/test/run-pass/binding/borrowed-ptr-pattern-infallible.rs rename to src/test/ui/binding/borrowed-ptr-pattern-infallible.rs diff --git a/src/test/run-pass/binding/borrowed-ptr-pattern-option.rs b/src/test/ui/binding/borrowed-ptr-pattern-option.rs similarity index 100% rename from src/test/run-pass/binding/borrowed-ptr-pattern-option.rs rename to src/test/ui/binding/borrowed-ptr-pattern-option.rs diff --git a/src/test/run-pass/binding/borrowed-ptr-pattern.rs b/src/test/ui/binding/borrowed-ptr-pattern.rs similarity index 100% rename from src/test/run-pass/binding/borrowed-ptr-pattern.rs rename to src/test/ui/binding/borrowed-ptr-pattern.rs diff --git a/src/test/run-pass/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs similarity index 100% rename from src/test/run-pass/binding/empty-types-in-patterns.rs rename to src/test/ui/binding/empty-types-in-patterns.rs diff --git a/src/test/run-pass/binding/exhaustive-bool-match-sanity.rs b/src/test/ui/binding/exhaustive-bool-match-sanity.rs similarity index 100% rename from src/test/run-pass/binding/exhaustive-bool-match-sanity.rs rename to src/test/ui/binding/exhaustive-bool-match-sanity.rs diff --git a/src/test/run-pass/binding/expr-match-generic-unique1.rs b/src/test/ui/binding/expr-match-generic-unique1.rs similarity index 100% rename from src/test/run-pass/binding/expr-match-generic-unique1.rs rename to src/test/ui/binding/expr-match-generic-unique1.rs diff --git a/src/test/run-pass/binding/expr-match-generic-unique2.rs b/src/test/ui/binding/expr-match-generic-unique2.rs similarity index 100% rename from src/test/run-pass/binding/expr-match-generic-unique2.rs rename to src/test/ui/binding/expr-match-generic-unique2.rs diff --git a/src/test/run-pass/binding/expr-match-generic.rs b/src/test/ui/binding/expr-match-generic.rs similarity index 100% rename from src/test/run-pass/binding/expr-match-generic.rs rename to src/test/ui/binding/expr-match-generic.rs diff --git a/src/test/run-pass/binding/expr-match-panic-all.rs b/src/test/ui/binding/expr-match-panic-all.rs similarity index 100% rename from src/test/run-pass/binding/expr-match-panic-all.rs rename to src/test/ui/binding/expr-match-panic-all.rs diff --git a/src/test/run-pass/binding/expr-match-panic.rs b/src/test/ui/binding/expr-match-panic.rs similarity index 100% rename from src/test/run-pass/binding/expr-match-panic.rs rename to src/test/ui/binding/expr-match-panic.rs diff --git a/src/test/run-pass/binding/expr-match-unique.rs b/src/test/ui/binding/expr-match-unique.rs similarity index 100% rename from src/test/run-pass/binding/expr-match-unique.rs rename to src/test/ui/binding/expr-match-unique.rs diff --git a/src/test/run-pass/binding/expr-match.rs b/src/test/ui/binding/expr-match.rs similarity index 100% rename from src/test/run-pass/binding/expr-match.rs rename to src/test/ui/binding/expr-match.rs diff --git a/src/test/run-pass/binding/fat-arrow-match.rs b/src/test/ui/binding/fat-arrow-match.rs similarity index 100% rename from src/test/run-pass/binding/fat-arrow-match.rs rename to src/test/ui/binding/fat-arrow-match.rs diff --git a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs similarity index 99% rename from src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs rename to src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs index 4d5a6fbba2..ea4a9e5afa 100644 --- a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs +++ b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs @@ -1,3 +1,4 @@ +// run-pass // Check that partially moved from function parameters are dropped after the // named bindings that move from them. diff --git a/src/test/run-pass/binding/fn-pattern-expected-type-2.rs b/src/test/ui/binding/fn-pattern-expected-type-2.rs similarity index 100% rename from src/test/run-pass/binding/fn-pattern-expected-type-2.rs rename to src/test/ui/binding/fn-pattern-expected-type-2.rs diff --git a/src/test/run-pass/binding/fn-pattern-expected-type.rs b/src/test/ui/binding/fn-pattern-expected-type.rs similarity index 100% rename from src/test/run-pass/binding/fn-pattern-expected-type.rs rename to src/test/ui/binding/fn-pattern-expected-type.rs diff --git a/src/test/run-pass/binding/func-arg-incomplete-pattern.rs b/src/test/ui/binding/func-arg-incomplete-pattern.rs similarity index 100% rename from src/test/run-pass/binding/func-arg-incomplete-pattern.rs rename to src/test/ui/binding/func-arg-incomplete-pattern.rs diff --git a/src/test/run-pass/binding/func-arg-ref-pattern.rs b/src/test/ui/binding/func-arg-ref-pattern.rs similarity index 100% rename from src/test/run-pass/binding/func-arg-ref-pattern.rs rename to src/test/ui/binding/func-arg-ref-pattern.rs diff --git a/src/test/run-pass/binding/func-arg-wild-pattern.rs b/src/test/ui/binding/func-arg-wild-pattern.rs similarity index 100% rename from src/test/run-pass/binding/func-arg-wild-pattern.rs rename to src/test/ui/binding/func-arg-wild-pattern.rs diff --git a/src/test/run-pass/binding/if-let.rs b/src/test/ui/binding/if-let.rs similarity index 100% rename from src/test/run-pass/binding/if-let.rs rename to src/test/ui/binding/if-let.rs diff --git a/src/test/run-pass/binding/inconsistent-lifetime-mismatch.rs b/src/test/ui/binding/inconsistent-lifetime-mismatch.rs similarity index 100% rename from src/test/run-pass/binding/inconsistent-lifetime-mismatch.rs rename to src/test/ui/binding/inconsistent-lifetime-mismatch.rs diff --git a/src/test/run-pass/binding/inferred-suffix-in-pattern-range.rs b/src/test/ui/binding/inferred-suffix-in-pattern-range.rs similarity index 100% rename from src/test/run-pass/binding/inferred-suffix-in-pattern-range.rs rename to src/test/ui/binding/inferred-suffix-in-pattern-range.rs diff --git a/src/test/run-pass/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs similarity index 86% rename from src/test/run-pass/binding/irrefutable-slice-patterns.rs rename to src/test/ui/binding/irrefutable-slice-patterns.rs index 733e6b7b57..ac733ef6e9 100644 --- a/src/test/run-pass/binding/irrefutable-slice-patterns.rs +++ b/src/test/ui/binding/irrefutable-slice-patterns.rs @@ -4,7 +4,7 @@ #![feature(slice_patterns)] fn foo(s: &[i32]) -> &[i32] { - let &[ref xs..] = s; + let &[ref xs @ ..] = s; xs } diff --git a/src/test/run-pass/binding/let-assignability.rs b/src/test/ui/binding/let-assignability.rs similarity index 100% rename from src/test/run-pass/binding/let-assignability.rs rename to src/test/ui/binding/let-assignability.rs diff --git a/src/test/run-pass/binding/let-destruct-ref.rs b/src/test/ui/binding/let-destruct-ref.rs similarity index 100% rename from src/test/run-pass/binding/let-destruct-ref.rs rename to src/test/ui/binding/let-destruct-ref.rs diff --git a/src/test/run-pass/binding/let-var-hygiene.rs b/src/test/ui/binding/let-var-hygiene.rs similarity index 100% rename from src/test/run-pass/binding/let-var-hygiene.rs rename to src/test/ui/binding/let-var-hygiene.rs diff --git a/src/test/run-pass/binding/match-arm-statics.rs b/src/test/ui/binding/match-arm-statics.rs similarity index 100% rename from src/test/run-pass/binding/match-arm-statics.rs rename to src/test/ui/binding/match-arm-statics.rs diff --git a/src/test/run-pass/binding/match-beginning-vert.rs b/src/test/ui/binding/match-beginning-vert.rs similarity index 100% rename from src/test/run-pass/binding/match-beginning-vert.rs rename to src/test/ui/binding/match-beginning-vert.rs diff --git a/src/test/run-pass/binding/match-borrowed_str.rs b/src/test/ui/binding/match-borrowed_str.rs similarity index 100% rename from src/test/run-pass/binding/match-borrowed_str.rs rename to src/test/ui/binding/match-borrowed_str.rs diff --git a/src/test/run-pass/binding/match-bot-2.rs b/src/test/ui/binding/match-bot-2.rs similarity index 100% rename from src/test/run-pass/binding/match-bot-2.rs rename to src/test/ui/binding/match-bot-2.rs diff --git a/src/test/run-pass/binding/match-bot.rs b/src/test/ui/binding/match-bot.rs similarity index 100% rename from src/test/run-pass/binding/match-bot.rs rename to src/test/ui/binding/match-bot.rs diff --git a/src/test/run-pass/binding/match-byte-array-patterns.rs b/src/test/ui/binding/match-byte-array-patterns.rs similarity index 100% rename from src/test/run-pass/binding/match-byte-array-patterns.rs rename to src/test/ui/binding/match-byte-array-patterns.rs diff --git a/src/test/run-pass/binding/match-enum-struct-0.rs b/src/test/ui/binding/match-enum-struct-0.rs similarity index 100% rename from src/test/run-pass/binding/match-enum-struct-0.rs rename to src/test/ui/binding/match-enum-struct-0.rs diff --git a/src/test/run-pass/binding/match-enum-struct-1.rs b/src/test/ui/binding/match-enum-struct-1.rs similarity index 100% rename from src/test/run-pass/binding/match-enum-struct-1.rs rename to src/test/ui/binding/match-enum-struct-1.rs diff --git a/src/test/run-pass/binding/match-implicit-copy-unique.rs b/src/test/ui/binding/match-implicit-copy-unique.rs similarity index 100% rename from src/test/run-pass/binding/match-implicit-copy-unique.rs rename to src/test/ui/binding/match-implicit-copy-unique.rs diff --git a/src/test/run-pass/binding/match-in-macro.rs b/src/test/ui/binding/match-in-macro.rs similarity index 100% rename from src/test/run-pass/binding/match-in-macro.rs rename to src/test/ui/binding/match-in-macro.rs diff --git a/src/test/run-pass/binding/match-join.rs b/src/test/ui/binding/match-join.rs similarity index 100% rename from src/test/run-pass/binding/match-join.rs rename to src/test/ui/binding/match-join.rs diff --git a/src/test/run-pass/binding/match-larger-const.rs b/src/test/ui/binding/match-larger-const.rs similarity index 100% rename from src/test/run-pass/binding/match-larger-const.rs rename to src/test/ui/binding/match-larger-const.rs diff --git a/src/test/run-pass/binding/match-naked-record-expr.rs b/src/test/ui/binding/match-naked-record-expr.rs similarity index 100% rename from src/test/run-pass/binding/match-naked-record-expr.rs rename to src/test/ui/binding/match-naked-record-expr.rs diff --git a/src/test/run-pass/binding/match-naked-record.rs b/src/test/ui/binding/match-naked-record.rs similarity index 100% rename from src/test/run-pass/binding/match-naked-record.rs rename to src/test/ui/binding/match-naked-record.rs diff --git a/src/test/run-pass/binding/match-path.rs b/src/test/ui/binding/match-path.rs similarity index 100% rename from src/test/run-pass/binding/match-path.rs rename to src/test/ui/binding/match-path.rs diff --git a/src/test/run-pass/binding/match-pattern-bindings.rs b/src/test/ui/binding/match-pattern-bindings.rs similarity index 100% rename from src/test/run-pass/binding/match-pattern-bindings.rs rename to src/test/ui/binding/match-pattern-bindings.rs diff --git a/src/test/run-pass/binding/match-pattern-lit.rs b/src/test/ui/binding/match-pattern-lit.rs similarity index 100% rename from src/test/run-pass/binding/match-pattern-lit.rs rename to src/test/ui/binding/match-pattern-lit.rs diff --git a/src/test/run-pass/binding/match-pattern-no-type-params.rs b/src/test/ui/binding/match-pattern-no-type-params.rs similarity index 100% rename from src/test/run-pass/binding/match-pattern-no-type-params.rs rename to src/test/ui/binding/match-pattern-no-type-params.rs diff --git a/src/test/run-pass/binding/match-pattern-simple.rs b/src/test/ui/binding/match-pattern-simple.rs similarity index 100% rename from src/test/run-pass/binding/match-pattern-simple.rs rename to src/test/ui/binding/match-pattern-simple.rs diff --git a/src/test/run-pass/binding/match-phi.rs b/src/test/ui/binding/match-phi.rs similarity index 100% rename from src/test/run-pass/binding/match-phi.rs rename to src/test/ui/binding/match-phi.rs diff --git a/src/test/run-pass/binding/match-pipe-binding.rs b/src/test/ui/binding/match-pipe-binding.rs similarity index 100% rename from src/test/run-pass/binding/match-pipe-binding.rs rename to src/test/ui/binding/match-pipe-binding.rs diff --git a/src/test/run-pass/binding/match-range-infer.rs b/src/test/ui/binding/match-range-infer.rs similarity index 100% rename from src/test/run-pass/binding/match-range-infer.rs rename to src/test/ui/binding/match-range-infer.rs diff --git a/src/test/run-pass/binding/match-range-static.rs b/src/test/ui/binding/match-range-static.rs similarity index 100% rename from src/test/run-pass/binding/match-range-static.rs rename to src/test/ui/binding/match-range-static.rs diff --git a/src/test/run-pass/binding/match-range.rs b/src/test/ui/binding/match-range.rs similarity index 100% rename from src/test/run-pass/binding/match-range.rs rename to src/test/ui/binding/match-range.rs diff --git a/src/test/run-pass/binding/match-reassign.rs b/src/test/ui/binding/match-reassign.rs similarity index 100% rename from src/test/run-pass/binding/match-reassign.rs rename to src/test/ui/binding/match-reassign.rs diff --git a/src/test/run-pass/binding/match-ref-binding-in-guard-3256.rs b/src/test/ui/binding/match-ref-binding-in-guard-3256.rs similarity index 100% rename from src/test/run-pass/binding/match-ref-binding-in-guard-3256.rs rename to src/test/ui/binding/match-ref-binding-in-guard-3256.rs diff --git a/src/test/run-pass/binding/match-ref-binding-mut-option.rs b/src/test/ui/binding/match-ref-binding-mut-option.rs similarity index 100% rename from src/test/run-pass/binding/match-ref-binding-mut-option.rs rename to src/test/ui/binding/match-ref-binding-mut-option.rs diff --git a/src/test/run-pass/binding/match-ref-binding-mut.rs b/src/test/ui/binding/match-ref-binding-mut.rs similarity index 100% rename from src/test/run-pass/binding/match-ref-binding-mut.rs rename to src/test/ui/binding/match-ref-binding-mut.rs diff --git a/src/test/run-pass/binding/match-ref-binding.rs b/src/test/ui/binding/match-ref-binding.rs similarity index 100% rename from src/test/run-pass/binding/match-ref-binding.rs rename to src/test/ui/binding/match-ref-binding.rs diff --git a/src/test/run-pass/binding/match-ref-unsized.rs b/src/test/ui/binding/match-ref-unsized.rs similarity index 100% rename from src/test/run-pass/binding/match-ref-unsized.rs rename to src/test/ui/binding/match-ref-unsized.rs diff --git a/src/test/run-pass/binding/match-str.rs b/src/test/ui/binding/match-str.rs similarity index 100% rename from src/test/run-pass/binding/match-str.rs rename to src/test/ui/binding/match-str.rs diff --git a/src/test/run-pass/binding/match-struct-0.rs b/src/test/ui/binding/match-struct-0.rs similarity index 100% rename from src/test/run-pass/binding/match-struct-0.rs rename to src/test/ui/binding/match-struct-0.rs diff --git a/src/test/run-pass/binding/match-tag.rs b/src/test/ui/binding/match-tag.rs similarity index 100% rename from src/test/run-pass/binding/match-tag.rs rename to src/test/ui/binding/match-tag.rs diff --git a/src/test/run-pass/binding/match-unique-bind.rs b/src/test/ui/binding/match-unique-bind.rs similarity index 100% rename from src/test/run-pass/binding/match-unique-bind.rs rename to src/test/ui/binding/match-unique-bind.rs diff --git a/src/test/run-pass/binding/match-unsized.rs b/src/test/ui/binding/match-unsized.rs similarity index 100% rename from src/test/run-pass/binding/match-unsized.rs rename to src/test/ui/binding/match-unsized.rs diff --git a/src/test/run-pass/binding/match-value-binding-in-guard-3291.rs b/src/test/ui/binding/match-value-binding-in-guard-3291.rs similarity index 100% rename from src/test/run-pass/binding/match-value-binding-in-guard-3291.rs rename to src/test/ui/binding/match-value-binding-in-guard-3291.rs diff --git a/src/test/run-pass/binding/match-var-hygiene.rs b/src/test/ui/binding/match-var-hygiene.rs similarity index 100% rename from src/test/run-pass/binding/match-var-hygiene.rs rename to src/test/ui/binding/match-var-hygiene.rs diff --git a/src/test/run-pass/binding/match-vec-alternatives.rs b/src/test/ui/binding/match-vec-alternatives.rs similarity index 100% rename from src/test/run-pass/binding/match-vec-alternatives.rs rename to src/test/ui/binding/match-vec-alternatives.rs diff --git a/src/test/run-pass/binding/match-vec-rvalue.rs b/src/test/ui/binding/match-vec-rvalue.rs similarity index 100% rename from src/test/run-pass/binding/match-vec-rvalue.rs rename to src/test/ui/binding/match-vec-rvalue.rs diff --git a/src/test/run-pass/binding/match-with-ret-arm.rs b/src/test/ui/binding/match-with-ret-arm.rs similarity index 100% rename from src/test/run-pass/binding/match-with-ret-arm.rs rename to src/test/ui/binding/match-with-ret-arm.rs diff --git a/src/test/run-pass/binding/multi-let.rs b/src/test/ui/binding/multi-let.rs similarity index 100% rename from src/test/run-pass/binding/multi-let.rs rename to src/test/ui/binding/multi-let.rs diff --git a/src/test/run-pass/binding/mut-in-ident-patterns.rs b/src/test/ui/binding/mut-in-ident-patterns.rs similarity index 100% rename from src/test/run-pass/binding/mut-in-ident-patterns.rs rename to src/test/ui/binding/mut-in-ident-patterns.rs diff --git a/src/test/run-pass/binding/nested-exhaustive-match.rs b/src/test/ui/binding/nested-exhaustive-match.rs similarity index 100% rename from src/test/run-pass/binding/nested-exhaustive-match.rs rename to src/test/ui/binding/nested-exhaustive-match.rs diff --git a/src/test/run-pass/binding/nested-matchs.rs b/src/test/ui/binding/nested-matchs.rs similarity index 100% rename from src/test/run-pass/binding/nested-matchs.rs rename to src/test/ui/binding/nested-matchs.rs diff --git a/src/test/run-pass/binding/nested-pattern.rs b/src/test/ui/binding/nested-pattern.rs similarity index 100% rename from src/test/run-pass/binding/nested-pattern.rs rename to src/test/ui/binding/nested-pattern.rs diff --git a/src/test/run-pass/binding/nil-pattern.rs b/src/test/ui/binding/nil-pattern.rs similarity index 100% rename from src/test/run-pass/binding/nil-pattern.rs rename to src/test/ui/binding/nil-pattern.rs diff --git a/src/test/run-pass/binding/nullary-or-pattern.rs b/src/test/ui/binding/nullary-or-pattern.rs similarity index 100% rename from src/test/run-pass/binding/nullary-or-pattern.rs rename to src/test/ui/binding/nullary-or-pattern.rs diff --git a/src/test/run-pass/binding/optional_comma_in_match_arm.rs b/src/test/ui/binding/optional_comma_in_match_arm.rs similarity index 100% rename from src/test/run-pass/binding/optional_comma_in_match_arm.rs rename to src/test/ui/binding/optional_comma_in_match_arm.rs diff --git a/src/test/run-pass/binding/or-pattern.rs b/src/test/ui/binding/or-pattern.rs similarity index 100% rename from src/test/run-pass/binding/or-pattern.rs rename to src/test/ui/binding/or-pattern.rs diff --git a/src/test/run-pass/binding/order-drop-with-match.rs b/src/test/ui/binding/order-drop-with-match.rs similarity index 100% rename from src/test/run-pass/binding/order-drop-with-match.rs rename to src/test/ui/binding/order-drop-with-match.rs diff --git a/src/test/run-pass/binding/pat-ranges.rs b/src/test/ui/binding/pat-ranges.rs similarity index 100% rename from src/test/run-pass/binding/pat-ranges.rs rename to src/test/ui/binding/pat-ranges.rs diff --git a/src/test/run-pass/binding/pat-tuple-1.rs b/src/test/ui/binding/pat-tuple-1.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-1.rs rename to src/test/ui/binding/pat-tuple-1.rs diff --git a/src/test/run-pass/binding/pat-tuple-2.rs b/src/test/ui/binding/pat-tuple-2.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-2.rs rename to src/test/ui/binding/pat-tuple-2.rs diff --git a/src/test/run-pass/binding/pat-tuple-3.rs b/src/test/ui/binding/pat-tuple-3.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-3.rs rename to src/test/ui/binding/pat-tuple-3.rs diff --git a/src/test/run-pass/binding/pat-tuple-4.rs b/src/test/ui/binding/pat-tuple-4.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-4.rs rename to src/test/ui/binding/pat-tuple-4.rs diff --git a/src/test/run-pass/binding/pat-tuple-5.rs b/src/test/ui/binding/pat-tuple-5.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-5.rs rename to src/test/ui/binding/pat-tuple-5.rs diff --git a/src/test/run-pass/binding/pat-tuple-6.rs b/src/test/ui/binding/pat-tuple-6.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-6.rs rename to src/test/ui/binding/pat-tuple-6.rs diff --git a/src/test/run-pass/binding/pat-tuple-7.rs b/src/test/ui/binding/pat-tuple-7.rs similarity index 100% rename from src/test/run-pass/binding/pat-tuple-7.rs rename to src/test/ui/binding/pat-tuple-7.rs diff --git a/src/test/run-pass/binding/pattern-bound-var-in-for-each.rs b/src/test/ui/binding/pattern-bound-var-in-for-each.rs similarity index 100% rename from src/test/run-pass/binding/pattern-bound-var-in-for-each.rs rename to src/test/ui/binding/pattern-bound-var-in-for-each.rs diff --git a/src/test/run-pass/binding/pattern-in-closure.rs b/src/test/ui/binding/pattern-in-closure.rs similarity index 100% rename from src/test/run-pass/binding/pattern-in-closure.rs rename to src/test/ui/binding/pattern-in-closure.rs diff --git a/src/test/run-pass/binding/range-inclusive-pattern-precedence.rs b/src/test/ui/binding/range-inclusive-pattern-precedence.rs similarity index 100% rename from src/test/run-pass/binding/range-inclusive-pattern-precedence.rs rename to src/test/ui/binding/range-inclusive-pattern-precedence.rs diff --git a/src/test/run-pass/binding/simple-generic-match.rs b/src/test/ui/binding/simple-generic-match.rs similarity index 100% rename from src/test/run-pass/binding/simple-generic-match.rs rename to src/test/ui/binding/simple-generic-match.rs diff --git a/src/test/run-pass/binding/use-uninit-match.rs b/src/test/ui/binding/use-uninit-match.rs similarity index 100% rename from src/test/run-pass/binding/use-uninit-match.rs rename to src/test/ui/binding/use-uninit-match.rs diff --git a/src/test/run-pass/binding/use-uninit-match2.rs b/src/test/ui/binding/use-uninit-match2.rs similarity index 100% rename from src/test/run-pass/binding/use-uninit-match2.rs rename to src/test/ui/binding/use-uninit-match2.rs diff --git a/src/test/run-pass/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs similarity index 73% rename from src/test/run-pass/binding/zero_sized_subslice_match.rs rename to src/test/ui/binding/zero_sized_subslice_match.rs index 51e1c024bf..5326fa612a 100644 --- a/src/test/run-pass/binding/zero_sized_subslice_match.rs +++ b/src/test/ui/binding/zero_sized_subslice_match.rs @@ -7,6 +7,6 @@ fn main() { // The subslice used to go out of bounds for zero-sized array items, check that this doesn't // happen anymore match x { - [_, ref y..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) + [_, ref y @ ..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) } } diff --git a/src/test/run-pass/binops-issue-22743.rs b/src/test/ui/binops-issue-22743.rs similarity index 96% rename from src/test/run-pass/binops-issue-22743.rs rename to src/test/ui/binops-issue-22743.rs index 4e95597b67..393ba0a56c 100644 --- a/src/test/run-pass/binops-issue-22743.rs +++ b/src/test/ui/binops-issue-22743.rs @@ -1,3 +1,5 @@ +// run-pass + use std::ops::Mul; #[derive(Copy, Clone)] diff --git a/src/test/run-pass/binops.rs b/src/test/ui/binops.rs similarity index 99% rename from src/test/run-pass/binops.rs rename to src/test/ui/binops.rs index b24f8b723f..a7abf6087b 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/ui/binops.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] // Binop corner cases diff --git a/src/test/run-pass/bitwise.rs b/src/test/ui/bitwise.rs similarity index 98% rename from src/test/run-pass/bitwise.rs rename to src/test/ui/bitwise.rs index 309ccae148..f79ff3c6ef 100644 --- a/src/test/run-pass/bitwise.rs +++ b/src/test/ui/bitwise.rs @@ -1,3 +1,5 @@ +// run-pass + #[cfg(any(target_pointer_width = "32"))] fn target() { assert_eq!(-1000isize as usize >> 3_usize, 536870787_usize); diff --git a/src/test/run-pass/blind-item-local-shadow.rs b/src/test/ui/blind-item-local-shadow.rs similarity index 93% rename from src/test/run-pass/blind-item-local-shadow.rs rename to src/test/ui/blind-item-local-shadow.rs index d88374a351..942aeb6fdf 100644 --- a/src/test/run-pass/blind-item-local-shadow.rs +++ b/src/test/ui/blind-item-local-shadow.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_imports)] mod bar { diff --git a/src/test/run-pass/blind-item-mixed-crate-use-item.rs b/src/test/ui/blind-item-mixed-crate-use-item.rs similarity index 97% rename from src/test/run-pass/blind-item-mixed-crate-use-item.rs rename to src/test/ui/blind-item-mixed-crate-use-item.rs index 00d171f6e4..36d8ab151e 100644 --- a/src/test/run-pass/blind-item-mixed-crate-use-item.rs +++ b/src/test/ui/blind-item-mixed-crate-use-item.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:blind-item-mixed-crate-use-item-foo.rs // aux-build:blind-item-mixed-crate-use-item-foo2.rs diff --git a/src/test/run-pass/blind-item-mixed-use-item.rs b/src/test/ui/blind-item-mixed-use-item.rs similarity index 95% rename from src/test/run-pass/blind-item-mixed-use-item.rs rename to src/test/ui/blind-item-mixed-use-item.rs index e6008206ba..4a39054967 100644 --- a/src/test/run-pass/blind-item-mixed-use-item.rs +++ b/src/test/ui/blind-item-mixed-use-item.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 mod m { diff --git a/src/test/run-pass/block-arg-call-as.rs b/src/test/ui/block-arg-call-as.rs similarity index 92% rename from src/test/run-pass/block-arg-call-as.rs rename to src/test/ui/block-arg-call-as.rs index 7157cfecf3..87cf3a487b 100644 --- a/src/test/run-pass/block-arg-call-as.rs +++ b/src/test/ui/block-arg-call-as.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_snake_case)] fn asBlock(f: F) -> usize where F: FnOnce() -> usize { diff --git a/src/test/run-pass/block-arg.rs b/src/test/ui/block-arg.rs similarity index 95% rename from src/test/run-pass/block-arg.rs rename to src/test/ui/block-arg.rs index 8d5840ae9e..bd1385e5c3 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/ui/block-arg.rs @@ -1,3 +1,4 @@ +// run-pass // Check usage and precedence of block arguments in expressions: pub fn main() { let v = vec![-1.0f64, 0.0, 1.0, 2.0, 3.0]; diff --git a/src/test/run-pass/block-explicit-types.rs b/src/test/ui/block-explicit-types.rs similarity index 93% rename from src/test/run-pass/block-explicit-types.rs rename to src/test/ui/block-explicit-types.rs index 449a496758..860fcc8df2 100644 --- a/src/test/run-pass/block-explicit-types.rs +++ b/src/test/ui/block-explicit-types.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { fn as_buf(s: String, f: F) -> T where F: FnOnce(String) -> T { f(s) } as_buf("foo".to_string(), |foo: String| -> () { println!("{}", foo) }); diff --git a/src/test/run-pass/block-expr-precedence.rs b/src/test/ui/block-expr-precedence.rs similarity index 99% rename from src/test/run-pass/block-expr-precedence.rs rename to src/test/ui/block-expr-precedence.rs index 2be0ac4c44..d31eecda9b 100644 --- a/src/test/run-pass/block-expr-precedence.rs +++ b/src/test/ui/block-expr-precedence.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(unused_parens)] // This test has some extra semis in it that the pretty-printer won't diff --git a/src/test/run-pass/block-fn-coerce.rs b/src/test/ui/block-fn-coerce.rs similarity index 93% rename from src/test/run-pass/block-fn-coerce.rs rename to src/test/ui/block-fn-coerce.rs index 0fbc1f5178..fc5f51d46b 100644 --- a/src/test/run-pass/block-fn-coerce.rs +++ b/src/test/ui/block-fn-coerce.rs @@ -1,3 +1,5 @@ +// run-pass + fn force(f: F) -> isize where F: FnOnce() -> isize { return f(); } pub fn main() { diff --git a/src/test/run-pass/block-iter-1.rs b/src/test/ui/block-iter-1.rs similarity index 95% rename from src/test/run-pass/block-iter-1.rs rename to src/test/ui/block-iter-1.rs index 8b3fc95f5a..caf0266cff 100644 --- a/src/test/run-pass/block-iter-1.rs +++ b/src/test/ui/block-iter-1.rs @@ -1,3 +1,5 @@ +// run-pass + fn iter_vec(v: Vec , mut f: F) where F: FnMut(&T) { for x in &v { f(x); } } pub fn main() { diff --git a/src/test/run-pass/block-iter-2.rs b/src/test/ui/block-iter-2.rs similarity index 96% rename from src/test/run-pass/block-iter-2.rs rename to src/test/ui/block-iter-2.rs index 0176f6d26d..e90c1ee815 100644 --- a/src/test/run-pass/block-iter-2.rs +++ b/src/test/ui/block-iter-2.rs @@ -1,3 +1,5 @@ +// run-pass + fn iter_vec(v: Vec, mut f: F) where F: FnMut(&T) { for x in &v { f(x); } } pub fn main() { diff --git a/src/test/ui/block-result/block-must-not-have-result-while.rs b/src/test/ui/block-result/block-must-not-have-result-while.rs index 9659763139..108b9bc9e9 100644 --- a/src/test/ui/block-result/block-must-not-have-result-while.rs +++ b/src/test/ui/block-result/block-must-not-have-result-while.rs @@ -1,5 +1,5 @@ fn main() { - while true { + while true { //~ WARN denote infinite loops with true //~ ERROR mismatched types //~| expected type `()` //~| found type `bool` diff --git a/src/test/ui/block-result/block-must-not-have-result-while.stderr b/src/test/ui/block-result/block-must-not-have-result-while.stderr index 302d2972f7..44f62875ef 100644 --- a/src/test/ui/block-result/block-must-not-have-result-while.stderr +++ b/src/test/ui/block-result/block-must-not-have-result-while.stderr @@ -1,3 +1,11 @@ +warning: denote infinite loops with `loop { ... }` + --> $DIR/block-must-not-have-result-while.rs:2:5 + | +LL | while true { + | ^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + error[E0308]: mismatched types --> $DIR/block-must-not-have-result-while.rs:3:9 | diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr index 618d020ce0..f4984ca446 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> String { | - ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | 0u8; LL | "bla".to_string(); | - help: consider removing this semicolon @@ -18,7 +18,7 @@ error[E0308]: mismatched types LL | fn g() -> String { | - ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | "this won't work".to_string(); LL | "removeme".to_string(); | - help: consider removing this semicolon diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index d73489a602..cfb42c6012 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn blah() -> i32 { | ---- ^^^ expected i32, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression ... LL | ; | - help: consider removing this semicolon diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index 18adb15c96..f7cafab3d7 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn foo() -> String { | --- ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression ... LL | ; | - help: consider removing this semicolon @@ -18,7 +18,7 @@ error[E0308]: mismatched types LL | fn bar() -> String { | --- ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | "foobar".to_string() LL | ; | - help: consider removing this semicolon diff --git a/src/test/run-pass/bool-not.rs b/src/test/ui/bool-not.rs similarity index 91% rename from src/test/run-pass/bool-not.rs rename to src/test/ui/bool-not.rs index 34865a3676..84713d6818 100644 --- a/src/test/run-pass/bool-not.rs +++ b/src/test/ui/bool-not.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { if !false { assert!((true)); } else { assert!((false)); } if !true { assert!((false)); } else { assert!((true)); } diff --git a/src/test/run-pass/bool.rs b/src/test/ui/bool.rs similarity index 99% rename from src/test/run-pass/bool.rs rename to src/test/ui/bool.rs index e6322746f2..92f36c8fd2 100644 --- a/src/test/run-pass/bool.rs +++ b/src/test/ui/bool.rs @@ -1,3 +1,4 @@ +// run-pass // Basic boolean tests diff --git a/src/test/run-pass/borrow-by-val-method-receiver.rs b/src/test/ui/borrow-by-val-method-receiver.rs similarity index 92% rename from src/test/run-pass/borrow-by-val-method-receiver.rs rename to src/test/ui/borrow-by-val-method-receiver.rs index 5907f8238a..465bef1614 100644 --- a/src/test/run-pass/borrow-by-val-method-receiver.rs +++ b/src/test/ui/borrow-by-val-method-receiver.rs @@ -1,3 +1,5 @@ +// run-pass + trait Foo { fn foo(self); } diff --git a/src/test/ui/borrowck/assign-never-type.rs b/src/test/ui/borrowck/assign-never-type.rs new file mode 100644 index 0000000000..4f30ea1467 --- /dev/null +++ b/src/test/ui/borrowck/assign-never-type.rs @@ -0,0 +1,14 @@ +// Regression test for issue 62165 + +// check-pass + +#![feature(never_type)] + +pub fn main() { + loop { + match None { + None => return, + Some(val) => val, + }; + }; +} diff --git a/src/test/run-pass/borrowck/borrowck-assign-to-subfield.rs b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-assign-to-subfield.rs rename to src/test/ui/borrowck/borrowck-assign-to-subfield.rs diff --git a/src/test/run-pass/borrowck/borrowck-assignment-to-static-mut.rs b/src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-assignment-to-static-mut.rs rename to src/test/ui/borrowck/borrowck-assignment-to-static-mut.rs diff --git a/src/test/run-pass/borrowck/borrowck-binding-mutbl.rs b/src/test/ui/borrowck/borrowck-binding-mutbl.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-binding-mutbl.rs rename to src/test/ui/borrowck/borrowck-binding-mutbl.rs diff --git a/src/test/run-pass/borrowck/borrowck-borrow-from-expr-block.rs b/src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-borrow-from-expr-block.rs rename to src/test/ui/borrowck/borrowck-borrow-from-expr-block.rs diff --git a/src/test/run-pass/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs rename to src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs index 01dc0af855..83eab7fdea 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs @@ -2,18 +2,7 @@ // Deref and not DerefMut is implemented. use std::ops::Deref; - -struct Rc { - value: *const T -} - -impl Deref for Rc { - type Target = T; - - fn deref(&self) -> &T { - unsafe { &*self.value } - } -} +use std::rc::Rc; struct Point { x: isize, diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr index dc52685363..d262c57884 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr @@ -1,86 +1,114 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:47:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:36:19 | LL | let __isize = &mut x.y; | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:51:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:40:19 | LL | let __isize = &mut x.y; | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:59:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:48:5 | LL | &mut x.y | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:63:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:52:5 | LL | &mut x.y | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:67:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:56:5 | LL | x.y = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:71:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:60:5 | LL | x.y = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:75:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:64:5 | LL | x.y = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:83:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:72:5 | LL | x.set(0, 0); | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:87:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:76:5 | LL | x.set(0, 0); | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:95:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:84:5 | LL | x.y_mut() | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:99:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:88:5 | LL | x.y_mut() | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:103:6 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:92:6 | LL | *x.y_mut() = 3; | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:107:6 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:96:6 | LL | *x.y_mut() = 3; | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:111:6 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:100:6 | LL | *x.y_mut() = 3; | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` error: aborting due to 14 previous errors diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs index 39fa70c4e5..2b98a7b948 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs @@ -2,18 +2,7 @@ // Deref and not DerefMut is implemented. use std::ops::Deref; - -struct Rc { - value: *const T -} - -impl Deref for Rc { - type Target = T; - - fn deref<'a>(&'a self) -> &'a T { - unsafe { &*self.value } - } -} +use std::rc::Rc; fn deref_imm(x: Rc) { let __isize = &*x; diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr index 1755b22f59..8cacc29414 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr @@ -1,44 +1,58 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:23:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:12:19 | LL | let __isize = &mut *x; | ^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:27:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:16:19 | LL | let __isize = &mut *x; | ^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:35:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:24:5 | LL | &mut **x | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:39:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:28:5 | LL | &mut **x | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-deref.rs:43:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-deref.rs:32:5 | LL | *x = 3; | ^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-deref.rs:47:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-deref.rs:36:5 | LL | **x = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-deref.rs:51:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-deref.rs:40:5 | LL | **x = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` error: aborting due to 7 previous errors diff --git a/src/test/run-pass/borrowck/borrowck-closures-two-imm.rs b/src/test/ui/borrowck/borrowck-closures-two-imm.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-closures-two-imm.rs rename to src/test/ui/borrowck/borrowck-closures-two-imm.rs diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr index f1e1ae1883..20f05353d4 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr @@ -192,8 +192,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here LL | match v { -LL | &[x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -204,8 +204,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -216,8 +216,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -228,8 +228,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs index c8dbf4e691..c27d9519dc 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs @@ -140,22 +140,22 @@ fn main() { let mut v = &[1, 2, 3, 4, 5]; let x = &mut v; match v { - &[x..] => println!("{:?}", x), + &[x @ ..] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } match v { - &[_, x..] => println!("{:?}", x), + &[_, x @ ..] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } match v { - &[x.., _] => println!("{:?}", x), + &[x @ .., _] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } match v { - &[_, x.., _] => println!("{:?}", x), + &[_, x @ .., _] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr index 14b9b50f0c..38d847a90f 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr @@ -192,8 +192,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here LL | match v { -LL | &[x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -204,8 +204,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -216,8 +216,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -228,8 +228,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr new file mode 100644 index 0000000000..89af876455 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.polonius.stderr @@ -0,0 +1,16 @@ +error[E0597]: `books` does not live long enough + --> $DIR/borrowck-escaping-closure-error-2.rs:11:17 + | +LL | Box::new(|| books.push(4)) + | ------------^^^^^--------- + | | | | + | | | borrowed value does not live long enough + | | value captured here + | borrow later used here +LL | +LL | } + | - `books` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/run-pass/borrowck/borrowck-field-sensitivity.rs b/src/test/ui/borrowck/borrowck-field-sensitivity-rpass.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-field-sensitivity.rs rename to src/test/ui/borrowck/borrowck-field-sensitivity-rpass.rs diff --git a/src/test/run-pass/borrowck/borrowck-fixed-length-vecs.rs b/src/test/ui/borrowck/borrowck-fixed-length-vecs.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-fixed-length-vecs.rs rename to src/test/ui/borrowck/borrowck-fixed-length-vecs.rs diff --git a/src/test/run-pass/borrowck/borrowck-freeze-frozen-mut.rs b/src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-freeze-frozen-mut.rs rename to src/test/ui/borrowck/borrowck-freeze-frozen-mut.rs diff --git a/src/test/run-pass/borrowck/borrowck-lend-args.rs b/src/test/ui/borrowck/borrowck-lend-args.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-lend-args.rs rename to src/test/ui/borrowck/borrowck-lend-args.rs diff --git a/src/test/run-pass/borrowck/borrowck-macro-interaction-issue-6304.rs b/src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-macro-interaction-issue-6304.rs rename to src/test/ui/borrowck/borrowck-macro-interaction-issue-6304.rs diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr index 663164cfc2..a33a1d00a5 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr @@ -1,14 +1,14 @@ -warning[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/borrowck-migrate-to-nll.rs:25:18 +warning[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-migrate-to-nll.rs:28:21 | -LL | (|| { let bar = foo; bar.take() })(); - | ^^ --- - | | | - | | move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait - | | move occurs due to use in closure - | move out of `foo` occurs here +LL | let x = &mut block; + | ---------- mutable borrow occurs here +LL | let p: &'a u8 = &*block.current; + | ^^^^^^^^^^^^^^^ immutable borrow occurs here +LL | // (use `x` and `p` so enabling NLL doesn't assign overly short lifetimes) +LL | drop(x); + | - mutable borrow later used here | - = note: variables bound in patterns cannot be moved from until after the end of the pattern guard = warning: this error has been downgraded to a warning for backwards compatibility with previous releases = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future = note: for more information, try `rustc --explain E0729` diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs index 5b7018df91..6dda317e57 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs @@ -1,4 +1,4 @@ -// This is a test of the borrowck migrate mode. It leverages #27282, a +// This is a test of the borrowck migrate mode. It leverages #38899, a // bug that is fixed by NLL: this code is (unsoundly) accepted by // AST-borrowck, but is correctly rejected by the NLL borrowck. // @@ -10,6 +10,7 @@ // just ignore it instead: // ignore-compare-mode-nll +// ignore-compare-mode-polonius // revisions: zflag edition //[zflag]compile-flags: -Z borrowck=migrate @@ -17,15 +18,17 @@ //[zflag] run-pass //[edition] run-pass -fn main() { - match Some(&4) { - None => {}, - ref mut foo - if { - (|| { let bar = foo; bar.take() })(); - false - } => {}, - Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), - _ => println!("Here is some supposedly unreachable code."), - } +pub struct Block<'a> { + current: &'a u8, + unrelated: &'a u8, } + +fn bump<'a>(mut block: &mut Block<'a>) { + let x = &mut block; + let p: &'a u8 = &*block.current; + // (use `x` and `p` so enabling NLL doesn't assign overly short lifetimes) + drop(x); + drop(p); +} + +fn main() {} diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr index 663164cfc2..a33a1d00a5 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr @@ -1,14 +1,14 @@ -warning[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/borrowck-migrate-to-nll.rs:25:18 +warning[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-migrate-to-nll.rs:28:21 | -LL | (|| { let bar = foo; bar.take() })(); - | ^^ --- - | | | - | | move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait - | | move occurs due to use in closure - | move out of `foo` occurs here +LL | let x = &mut block; + | ---------- mutable borrow occurs here +LL | let p: &'a u8 = &*block.current; + | ^^^^^^^^^^^^^^^ immutable borrow occurs here +LL | // (use `x` and `p` so enabling NLL doesn't assign overly short lifetimes) +LL | drop(x); + | - mutable borrow later used here | - = note: variables bound in patterns cannot be moved from until after the end of the pattern guard = warning: this error has been downgraded to a warning for backwards compatibility with previous releases = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future = note: for more information, try `rustc --explain E0729` diff --git a/src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs b/src/test/ui/borrowck/borrowck-move-by-capture-ok.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-move-by-capture-ok.rs rename to src/test/ui/borrowck/borrowck-move-by-capture-ok.rs diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.rs b/src/test/ui/borrowck/borrowck-move-out-from-array.rs index 856b03edd2..ee6abf407a 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.rs @@ -10,7 +10,7 @@ fn move_out_from_begin_and_end() { fn move_out_by_const_index_and_subslice() { let a = [box 1, box 2]; let [_x, _] = a; - let [_y..] = a; //~ ERROR [E0382] + let [_y @ ..] = a; //~ ERROR [E0382] } fn main() {} diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr index 16722a456d..b34c03e6de 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr @@ -13,8 +13,8 @@ error[E0382]: use of moved value: `a[..]` | LL | let [_x, _] = a; | -- value moved here -LL | let [_y..] = a; - | ^^ value used here after move +LL | let [_y @ ..] = a; + | ^^^^^^^ value used here after move | = note: move occurs because `a[..]` has type `std::boxed::Box`, which does not implement the `Copy` trait diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs index cc524c1ac3..fa9a3c217d 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs @@ -15,7 +15,7 @@ pub fn main() { ]; let x: &[Foo] = &x; match *x { - [_, ref tail..] => { + [_, ref tail @ ..] => { match tail { //~^ ERROR cannot move out of type `[Foo]` &[Foo { string: a }, diff --git a/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs rename to src/test/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs diff --git a/src/test/run-pass/borrowck/borrowck-mut-uniq.rs b/src/test/ui/borrowck/borrowck-mut-uniq.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-mut-uniq.rs rename to src/test/ui/borrowck/borrowck-mut-uniq.rs diff --git a/src/test/run-pass/borrowck/borrowck-mut-vec-as-imm-slice.rs b/src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-mut-vec-as-imm-slice.rs rename to src/test/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr deleted file mode 100644 index 7e4a6322d5..0000000000 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.nll.stderr +++ /dev/null @@ -1,41 +0,0 @@ -error[E0302]: cannot assign in a pattern guard - --> $DIR/borrowck-mutate-in-guard.rs:10:25 - | -LL | Enum::A(_) if { x = Enum::B(false); false } => 1, - | ^^^^^^^^^^^^^^^^^^ assignment in pattern guard - -error[E0301]: cannot mutably borrow in a pattern guard - --> $DIR/borrowck-mutate-in-guard.rs:15:38 - | -LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, - | ^ borrowed mutably in pattern guard - | - = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable - -error[E0302]: cannot assign in a pattern guard - --> $DIR/borrowck-mutate-in-guard.rs:15:41 - | -LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, - | ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard - -error[E0510]: cannot assign `x` in match guard - --> $DIR/borrowck-mutate-in-guard.rs:10:25 - | -LL | match x { - | - value is immutable in match guard -LL | Enum::A(_) if { x = Enum::B(false); false } => 1, - | ^^^^^^^^^^^^^^^^^^ cannot assign - -error[E0510]: cannot mutably borrow `x` in match guard - --> $DIR/borrowck-mutate-in-guard.rs:15:33 - | -LL | match x { - | - value is immutable in match guard -... -LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, - | ^^^^^^ cannot mutably borrow - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0301, E0302, E0510. -For more information about an error, try `rustc --explain E0301`. diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs index 9ea5e5cd14..5b6aa7a979 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs @@ -9,15 +9,11 @@ fn foo() -> isize { match x { Enum::A(_) if { x = Enum::B(false); false } => 1, //~^ ERROR cannot assign in a pattern guard - //~| WARN cannot assign `x` in match guard - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will + //~| ERROR cannot assign `x` in match guard Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, //~^ ERROR cannot mutably borrow in a pattern guard //~| ERROR cannot assign in a pattern guard - //~| WARN cannot mutably borrow `x` in match guard - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will + //~| ERROR cannot mutably borrow `x` in match guard Enum::A(p) => *p, Enum::B(_) => 2, } diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr index ac6bed6137..674f137dbb 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr @@ -5,45 +5,37 @@ LL | Enum::A(_) if { x = Enum::B(false); false } => 1, | ^^^^^^^^^^^^^^^^^^ assignment in pattern guard error[E0301]: cannot mutably borrow in a pattern guard - --> $DIR/borrowck-mutate-in-guard.rs:15:38 + --> $DIR/borrowck-mutate-in-guard.rs:13:38 | LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, | ^ borrowed mutably in pattern guard | - = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable error[E0302]: cannot assign in a pattern guard - --> $DIR/borrowck-mutate-in-guard.rs:15:41 + --> $DIR/borrowck-mutate-in-guard.rs:13:41 | LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, | ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard -warning[E0510]: cannot assign `x` in match guard +error[E0510]: cannot assign `x` in match guard --> $DIR/borrowck-mutate-in-guard.rs:10:25 | LL | match x { | - value is immutable in match guard LL | Enum::A(_) if { x = Enum::B(false); false } => 1, | ^^^^^^^^^^^^^^^^^^ cannot assign - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -warning[E0510]: cannot mutably borrow `x` in match guard - --> $DIR/borrowck-mutate-in-guard.rs:15:33 +error[E0510]: cannot mutably borrow `x` in match guard + --> $DIR/borrowck-mutate-in-guard.rs:13:33 | LL | match x { | - value is immutable in match guard ... LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, | ^^^^^^ cannot mutably borrow - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0301, E0302, E0510. For more information about an error, try `rustc --explain E0301`. diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs index cb20873432..8adafaa8e9 100644 --- a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs +++ b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs @@ -54,6 +54,6 @@ fn main() { x: 1, }; s[2] = 20; - //~^ ERROR cannot assign to data in a `&` reference + //~^ ERROR cannot assign to data in an index of `Bar` drop(rs); } diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr index fcbfe72a34..84fe17d854 100644 --- a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr +++ b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr @@ -21,11 +21,13 @@ LL | f[&s] = 10; LL | drop(rs); | -- mutable borrow later used here -error[E0594]: cannot assign to data in a `&` reference +error[E0594]: cannot assign to data in an index of `Bar` --> $DIR/borrowck-overloaded-index-ref-index.rs:56:5 | LL | s[2] = 20; | ^^^^^^^^^ cannot assign + | + = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Bar` error: aborting due to 3 previous errors diff --git a/src/test/run-pass/borrowck/borrowck-pat-enum.rs b/src/test/ui/borrowck/borrowck-pat-enum.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-pat-enum.rs rename to src/test/ui/borrowck/borrowck-pat-enum.rs diff --git a/src/test/run-pass/borrowck/borrowck-pat-reassign-no-binding.rs b/src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-pat-reassign-no-binding.rs rename to src/test/ui/borrowck/borrowck-pat-reassign-no-binding.rs diff --git a/src/test/run-pass/borrowck/borrowck-rvalues-mutable.rs b/src/test/ui/borrowck/borrowck-rvalues-mutable.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-rvalues-mutable.rs rename to src/test/ui/borrowck/borrowck-rvalues-mutable.rs diff --git a/src/test/run-pass/borrowck/borrowck-scope-of-deref-issue-4666.rs b/src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-scope-of-deref-issue-4666.rs rename to src/test/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs diff --git a/src/test/run-pass/borrowck/borrowck-slice-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs similarity index 89% rename from src/test/run-pass/borrowck/borrowck-slice-pattern-element-loan.rs rename to src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs index 7675147c8e..048813b2b9 100644 --- a/src/test/run-pass/borrowck/borrowck-slice-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -5,7 +5,7 @@ fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { match *v { - [ref mut head, ref mut tail..] => { + [ref mut head, ref mut tail @ ..] => { Some((head, tail)) } [] => None diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs index 5de8dd3305..a6b54f9537 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs @@ -70,7 +70,7 @@ fn const_index_mixed(s: &mut [i32]) { fn const_index_and_subslice_ok(s: &mut [i32]) { if let [ref first, ref second, ..] = *s { - if let [_, _, ref mut tail..] = *s { + if let [_, _, ref mut tail @ ..] = *s { nop(&[first, second]); nop_subslice(tail); } @@ -79,7 +79,7 @@ fn const_index_and_subslice_ok(s: &mut [i32]) { fn const_index_and_subslice_err(s: &mut [i32]) { if let [ref first, ref second, ..] = *s { - if let [_, ref mut tail..] = *s { //~ERROR + if let [_, ref mut tail @ ..] = *s { //~ERROR nop(&[first, second]); nop_subslice(tail); } @@ -88,7 +88,7 @@ fn const_index_and_subslice_err(s: &mut [i32]) { fn const_index_and_subslice_from_end_ok(s: &mut [i32]) { if let [.., ref second, ref first] = *s { - if let [ref mut tail.., _, _] = *s { + if let [ref mut tail @ .., _, _] = *s { nop(&[first, second]); nop_subslice(tail); } @@ -97,7 +97,7 @@ fn const_index_and_subslice_from_end_ok(s: &mut [i32]) { fn const_index_and_subslice_from_end_err(s: &mut [i32]) { if let [.., ref second, ref first] = *s { - if let [ref mut tail.., _] = *s { //~ERROR + if let [ref mut tail @ .., _] = *s { //~ERROR nop(&[first, second]); nop_subslice(tail); } @@ -105,8 +105,8 @@ fn const_index_and_subslice_from_end_err(s: &mut [i32]) { } fn subslices(s: &mut [i32]) { - if let [_, _, _, ref s1..] = *s { - if let [ref mut s2.., _, _, _] = *s { //~ERROR + if let [_, _, _, ref s1 @ ..] = *s { + if let [ref mut s2 @ .., _, _, _] = *s { //~ERROR nop_subslice(s1); nop_subslice(s2); } diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr index f716ee68b0..2c019f4461 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr @@ -89,8 +89,8 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im | LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here -LL | if let [_, ref mut tail..] = *s { - | ^^^^^^^^^^^^ mutable borrow occurs here +LL | if let [_, ref mut tail @ ..] = *s { + | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here @@ -99,18 +99,18 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im | LL | if let [.., ref second, ref first] = *s { | ---------- immutable borrow occurs here -LL | if let [ref mut tail.., _] = *s { - | ^^^^^^^^^^^^ mutable borrow occurs here +LL | if let [ref mut tail @ .., _] = *s { + | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable --> $DIR/borrowck-slice-pattern-element-loan.rs:109:17 | -LL | if let [_, _, _, ref s1..] = *s { - | ------ immutable borrow occurs here -LL | if let [ref mut s2.., _, _, _] = *s { - | ^^^^^^^^^^ mutable borrow occurs here +LL | if let [_, _, _, ref s1 @ ..] = *s { + | ----------- immutable borrow occurs here +LL | if let [ref mut s2 @ .., _, _, _] = *s { + | ^^^^^^^^^^^^^^^ mutable borrow occurs here LL | nop_subslice(s1); | -- immutable borrow later used here diff --git a/src/test/run-pass/borrowck/borrowck-static-item-in-fn.rs b/src/test/ui/borrowck/borrowck-static-item-in-fn.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-static-item-in-fn.rs rename to src/test/ui/borrowck/borrowck-static-item-in-fn.rs diff --git a/src/test/run-pass/borrowck/borrowck-trait-lifetime.rs b/src/test/ui/borrowck/borrowck-trait-lifetime.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-trait-lifetime.rs rename to src/test/ui/borrowck/borrowck-trait-lifetime.rs diff --git a/src/test/run-pass/borrowck/borrowck-uniq-via-ref.rs b/src/test/ui/borrowck/borrowck-uniq-via-ref.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-uniq-via-ref.rs rename to src/test/ui/borrowck/borrowck-uniq-via-ref.rs diff --git a/src/test/run-pass/borrowck/borrowck-univariant-enum.rs b/src/test/ui/borrowck/borrowck-univariant-enum.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-univariant-enum.rs rename to src/test/ui/borrowck/borrowck-univariant-enum.rs diff --git a/src/test/run-pass/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-unsafe-static-mutable-borrows.rs rename to src/test/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs diff --git a/src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs b/src/test/ui/borrowck/borrowck-unused-mut-locals.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-unused-mut-locals.rs rename to src/test/ui/borrowck/borrowck-unused-mut-locals.rs diff --git a/src/test/run-pass/borrowck/borrowck-use-mut-borrow.rs b/src/test/ui/borrowck/borrowck-use-mut-borrow-rpass.rs similarity index 100% rename from src/test/run-pass/borrowck/borrowck-use-mut-borrow.rs rename to src/test/ui/borrowck/borrowck-use-mut-borrow-rpass.rs diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs index 100384d78c..53a9bcef74 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs @@ -4,7 +4,7 @@ fn a<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let tail = match vec { - &[_, ref tail..] => tail, + &[_, ref tail @ ..] => tail, _ => panic!("a") }; tail //~ ERROR cannot return value referencing local variable `vec` @@ -14,7 +14,7 @@ fn b<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let init = match vec { - &[ref init.., _] => init, + &[ref init @ .., _] => init, _ => panic!("b") }; init //~ ERROR cannot return value referencing local variable `vec` @@ -24,7 +24,7 @@ fn c<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let slice = match vec { - &[_, ref slice.., _] => slice, + &[_, ref slice @ .., _] => slice, _ => panic!("c") }; slice //~ ERROR cannot return value referencing local variable `vec` diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs index 4d99a92b18..dd9023f6d9 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs @@ -4,7 +4,7 @@ fn a() { let mut v = vec![1, 2, 3]; let vb: &mut [isize] = &mut v; match vb { - &mut [_a, ref tail..] => { + &mut [_a, ref tail @ ..] => { v.push(tail[0] + tail[1]); //~ ERROR cannot borrow } _ => {} diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs index efc5253071..420223009a 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs @@ -5,7 +5,7 @@ fn main() { let mut a = [1, 2, 3, 4]; let t = match a { - [1, 2, ref tail..] => tail, + [1, 2, ref tail @ ..] => tail, _ => unreachable!() }; println!("t[0]: {}", t[0]); diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr index b2f553ba49..9f8e6fe3b6 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr @@ -1,8 +1,8 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed --> $DIR/borrowck-vec-pattern-move-tail.rs:12:5 | -LL | [1, 2, ref tail..] => tail, - | -------- borrow of `a[_]` occurs here +LL | [1, 2, ref tail @ ..] => tail, + | ------------- borrow of `a[_]` occurs here ... LL | a[2] = 0; | ^^^^^^^^ assignment to borrowed `a[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs index 6448149391..a215305f68 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -19,7 +19,7 @@ fn b() { let mut vec = vec![box 1, box 2, box 3]; let vec: &mut [Box] = &mut vec; match vec { - &mut [ref _b..] => { + &mut [ref _b @ ..] => { //~^ borrow of `vec[_]` occurs here vec[0] = box 4; //~ ERROR cannot assign //~^ NOTE assignment to borrowed `vec[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index 072501f23f..f54a3a4072 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -13,8 +13,8 @@ LL | _a.use_ref(); error[E0506]: cannot assign to `vec[_]` because it is borrowed --> $DIR/borrowck-vec-pattern-nesting.rs:24:13 | -LL | &mut [ref _b..] => { - | ------ borrow of `vec[_]` occurs here +LL | &mut [ref _b @ ..] => { + | ----------- borrow of `vec[_]` occurs here LL | LL | vec[0] = box 4; | ^^^^^^ assignment to borrowed `vec[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs index e602e75886..c35be2f6be 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs @@ -4,7 +4,7 @@ fn a<'a>() -> &'a isize { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let tail = match vec { - &[_a, ref tail..] => &tail[0], + &[_a, ref tail @ ..] => &tail[0], _ => panic!("foo") }; tail //~ ERROR cannot return value referencing local variable `vec` diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs new file mode 100644 index 0000000000..a987c00b09 --- /dev/null +++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs @@ -0,0 +1,22 @@ +// Test that we don't allow partial initialization. +// This may be relaxed in the future (see #54987). + +fn main() { + let mut t: (u64, u64); + t.0 = 1; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + t.1 = 1; + + let mut t: (u64, u64); + t.1 = 1; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + t.0 = 1; + + let mut t: (u64, u64); + t.0 = 1; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + + let mut t: (u64,); + t.0 = 1; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] +} diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr new file mode 100644 index 0000000000..a32b17b165 --- /dev/null +++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr @@ -0,0 +1,27 @@ +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/disallow-possibly-uninitialized.rs:6:5 + | +LL | t.0 = 1; + | ^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/disallow-possibly-uninitialized.rs:11:5 + | +LL | t.1 = 1; + | ^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/disallow-possibly-uninitialized.rs:16:5 + | +LL | t.0 = 1; + | ^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/disallow-possibly-uninitialized.rs:20:5 + | +LL | t.0 = 1; + | ^^^^^^^ use of possibly uninitialized `t` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/index-mut-help-with-impl.stderr b/src/test/ui/borrowck/index-mut-help-with-impl.stderr index 4b29beb02b..89391f4099 100644 --- a/src/test/ui/borrowck/index-mut-help-with-impl.stderr +++ b/src/test/ui/borrowck/index-mut-help-with-impl.stderr @@ -3,8 +3,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable | LL | Index::index(&v, 1..2).make_ascii_uppercase(); | ^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable - | - = help: trait `IndexMut` is required to modify indexed content error: aborting due to previous error diff --git a/src/test/ui/borrowck/index-mut-help.stderr b/src/test/ui/borrowck/index-mut-help.stderr index fbc427a6e6..47f2171f88 100644 --- a/src/test/ui/borrowck/index-mut-help.stderr +++ b/src/test/ui/borrowck/index-mut-help.stderr @@ -1,4 +1,4 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable +error[E0596]: cannot borrow data in an index of `std::collections::HashMap<&str, std::string::String>` as mutable --> $DIR/index-mut-help.rs:11:5 | LL | map["peter"].clear(); @@ -6,13 +6,15 @@ LL | map["peter"].clear(); | = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, std::string::String>` -error[E0594]: cannot assign to data in a `&` reference +error[E0594]: cannot assign to data in an index of `std::collections::HashMap<&str, std::string::String>` --> $DIR/index-mut-help.rs:12:5 | LL | map["peter"] = "0".to_string(); | ^^^^^^^^^^^^ cannot assign + | + = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, std::string::String>` -error[E0596]: cannot borrow data in a `&` reference as mutable +error[E0596]: cannot borrow data in an index of `std::collections::HashMap<&str, std::string::String>` as mutable --> $DIR/index-mut-help.rs:13:13 | LL | let _ = &mut map["peter"]; diff --git a/src/test/ui/borrowck/issue-27282-mutation-in-guard.rs b/src/test/ui/borrowck/issue-27282-mutation-in-guard.rs new file mode 100644 index 0000000000..395c7d214d --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-mutation-in-guard.rs @@ -0,0 +1,13 @@ +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { + (|| { let bar = foo; bar.take() })(); + //~^ ERROR cannot move out of `foo` in pattern guard + false + } => {}, + Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), + _ => println!("Here is some supposedly unreachable code."), + } +} diff --git a/src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr b/src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr new file mode 100644 index 0000000000..ea7df7d5a7 --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr @@ -0,0 +1,15 @@ +error[E0507]: cannot move out of `foo` in pattern guard + --> $DIR/issue-27282-mutation-in-guard.rs:6:18 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^ --- + | | | + | | move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait + | | move occurs due to use in closure + | move out of `foo` occurs here + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.rs b/src/test/ui/borrowck/issue-31287-drop-in-guard.rs new file mode 100644 index 0000000000..07125b98a1 --- /dev/null +++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.rs @@ -0,0 +1,8 @@ +fn main() { + let a = Some("...".to_owned()); + let b = match a { + Some(_) if { drop(a); false } => None, + x => x, //~ ERROR use of moved value: `a` + }; + println!("{:?}", b); +} diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr new file mode 100644 index 0000000000..85c83ec4d7 --- /dev/null +++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `a` + --> $DIR/issue-31287-drop-in-guard.rs:5:9 + | +LL | let a = Some("...".to_owned()); + | - move occurs because `a` has type `std::option::Option`, which does not implement the `Copy` trait +LL | let b = match a { +LL | Some(_) if { drop(a); false } => None, + | - value moved here +LL | x => x, + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/issue-45983.migrate.stderr b/src/test/ui/borrowck/issue-45983.migrate.stderr index 3a6b2f69a1..c1564cf07e 100644 --- a/src/test/ui/borrowck/issue-45983.migrate.stderr +++ b/src/test/ui/borrowck/issue-45983.migrate.stderr @@ -1,5 +1,5 @@ error: borrowed data cannot be stored outside of its closure - --> $DIR/issue-45983.rs:19:27 + --> $DIR/issue-45983.rs:20:27 | LL | let x = None; | - borrowed data cannot be stored into here... diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr index 94360b65ff..dff0b4ceba 100644 --- a/src/test/ui/borrowck/issue-45983.nll.stderr +++ b/src/test/ui/borrowck/issue-45983.nll.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of closure - --> $DIR/issue-45983.rs:19:18 + --> $DIR/issue-45983.rs:20:18 | LL | let x = None; | - `x` is declared here, outside of the closure body @@ -9,7 +9,7 @@ LL | give_any(|y| x = Some(y)); | `y` is a reference that is only valid in the closure body error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/issue-45983.rs:19:18 + --> $DIR/issue-45983.rs:20:18 | LL | let x = None; | - help: consider changing this to be mutable: `mut x` diff --git a/src/test/ui/borrowck/issue-45983.rs b/src/test/ui/borrowck/issue-45983.rs index a2656f5939..3cd2820774 100644 --- a/src/test/ui/borrowck/issue-45983.rs +++ b/src/test/ui/borrowck/issue-45983.rs @@ -7,6 +7,7 @@ // revisions, don't worry about the --compare-mode=nll on this test. // ignore-compare-mode-nll +// ignore-compare-mode-polonius //[nll]compile-flags: -Z borrowck=mir diff --git a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs index 6d91fd3508..1d98067ce7 100644 --- a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs +++ b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274 // (for ensuring that NLL respects user-provided lifetime annotations) diff --git a/src/test/run-pass/borrowck/issue-62007-assign-box.rs b/src/test/ui/borrowck/issue-62007-assign-box.rs similarity index 100% rename from src/test/run-pass/borrowck/issue-62007-assign-box.rs rename to src/test/ui/borrowck/issue-62007-assign-box.rs diff --git a/src/test/run-pass/borrowck/issue-62007-assign-field.rs b/src/test/ui/borrowck/issue-62007-assign-field.rs similarity index 100% rename from src/test/run-pass/borrowck/issue-62007-assign-field.rs rename to src/test/ui/borrowck/issue-62007-assign-field.rs diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs new file mode 100644 index 0000000000..220b2ecf04 --- /dev/null +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs @@ -0,0 +1,12 @@ +fn main() { + let e: i32; + match e { + //~^ ERROR use of possibly uninitialized variable + ref u if true => {} + ref v if true => { + let tx = 0; + &tx; + } + _ => (), + } +} diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr new file mode 100644 index 0000000000..9701343d2b --- /dev/null +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr @@ -0,0 +1,9 @@ +error[E0381]: use of possibly uninitialized variable: `e` + --> $DIR/issue-62107-match-arm-scopes.rs:3:11 + | +LL | match e { + | ^ use of possibly uninitialized `e` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.rs b/src/test/ui/borrowck/mut-borrow-in-loop.rs index 09f3e4f9b7..22667906e1 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.rs +++ b/src/test/ui/borrowck/mut-borrow-in-loop.rs @@ -12,7 +12,7 @@ impl<'a, T : 'a> FuncWrapper<'a, T> { } fn in_while(self, arg : &'a mut T) { - while true { + while true { //~ WARN denote infinite loops with (self.func)(arg) //~ ERROR cannot borrow } } diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.stderr b/src/test/ui/borrowck/mut-borrow-in-loop.stderr index eda2f518f9..daee1a0d5c 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.stderr +++ b/src/test/ui/borrowck/mut-borrow-in-loop.stderr @@ -1,3 +1,11 @@ +warning: denote infinite loops with `loop { ... }` + --> $DIR/mut-borrow-in-loop.rs:15:9 + | +LL | while true { + | ^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + error[E0499]: cannot borrow `*arg` as mutable more than once at a time --> $DIR/mut-borrow-in-loop.rs:10:25 | diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr new file mode 100644 index 0000000000..a5b2e87627 --- /dev/null +++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.polonius.stderr @@ -0,0 +1,59 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:5:21 + | +LL | let ref mut x = 1234543; + | ^^^^^^^ creates a temporary which is freed while still in use +LL | x + | - borrow later used here +LL | } + | - temporary value is freed at the end of this statement + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:10:25 + | +LL | let (ref mut x, ) = (1234543, ); + | ^^^^^^^^^^^ creates a temporary which is freed while still in use +LL | x + | - borrow later used here +LL | } + | - temporary value is freed at the end of this statement + | + = note: consider using a `let` binding to create a longer lived value + +error[E0515]: cannot return value referencing temporary value + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:5 + | +LL | match 1234543 { + | ^ ------- temporary value created here + | _____| + | | +LL | | ref mut x => x +LL | | } + | |_____^ returns a value referencing data owned by the current function + +error[E0515]: cannot return value referencing temporary value + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:21:5 + | +LL | match (123443,) { + | ^ --------- temporary value created here + | _____| + | | +LL | | (ref mut x,) => x, +LL | | } + | |_____^ returns a value referencing data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/promote-ref-mut-in-let-issue-46557.rs:27:5 + | +LL | &mut 1234543 + | ^^^^^------- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0515, E0716. +For more information about an error, try `rustc --explain E0515`. diff --git a/src/test/run-pass/borrowck/two-phase-baseline.rs b/src/test/ui/borrowck/two-phase-baseline.rs similarity index 100% rename from src/test/run-pass/borrowck/two-phase-baseline.rs rename to src/test/ui/borrowck/two-phase-baseline.rs diff --git a/src/test/run-pass/borrowck/two-phase-bin-ops.rs b/src/test/ui/borrowck/two-phase-bin-ops.rs similarity index 100% rename from src/test/run-pass/borrowck/two-phase-bin-ops.rs rename to src/test/ui/borrowck/two-phase-bin-ops.rs diff --git a/src/test/run-pass/borrowck/two-phase-control-flow-split-before-activation.rs b/src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs similarity index 100% rename from src/test/run-pass/borrowck/two-phase-control-flow-split-before-activation.rs rename to src/test/ui/borrowck/two-phase-control-flow-split-before-activation.rs diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr index 8eb468892f..88e9ced03d 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2015.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -11,7 +11,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -21,7 +21,7 @@ LL | v.extend(&v); | mutable borrow occurs here warning: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -31,7 +31,7 @@ LL | v.push(shared.len()); | | | mutable borrow occurs here | - = note: #[warn(mutable_borrow_reservation_conflict)] on by default + = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future = note: for more information, see issue #59159 diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr index 8eb468892f..88e9ced03d 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.migrate2018.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -11,7 +11,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -21,7 +21,7 @@ LL | v.extend(&v); | mutable borrow occurs here warning: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -31,7 +31,7 @@ LL | v.push(shared.len()); | | | mutable borrow occurs here | - = note: #[warn(mutable_borrow_reservation_conflict)] on by default + = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future = note: for more information, see issue #59159 diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr index 730741c7a9..52017394e8 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2015.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -10,7 +10,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -20,7 +20,7 @@ LL | v.extend(&v); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr index 730741c7a9..52017394e8 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.nll2018.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:18:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:19:5 | LL | let shared = &v; | -- immutable borrow occurs here @@ -10,7 +10,7 @@ LL | v.extend(shared); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:28:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:29:5 | LL | v.extend(&v); | ^^------^--^ @@ -20,7 +20,7 @@ LL | v.extend(&v); | mutable borrow occurs here error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference-2.rs:39:5 + --> $DIR/two-phase-reservation-sharing-interference-2.rs:40:5 | LL | let shared = &v; | -- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs index de1af3aaa0..14f687c237 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference-2.rs @@ -3,6 +3,7 @@ // everyone else. //ignore-compare-mode-nll +//ignore-compare-mode-polonius //revisions: migrate2015 migrate2018 nll2015 nll2018 diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr b/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr new file mode 100644 index 0000000000..7b246426a2 --- /dev/null +++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr @@ -0,0 +1,148 @@ +error[E0503]: cannot use `self.cx` because it was mutably borrowed + --> $DIR/two-phase-surprise-no-conflict.rs:21:23 + | +LL | let _mut_borrow = &mut *self; + | ---------- borrow of `*self` occurs here +LL | let _access = self.cx; + | ^^^^^^^ use of borrowed `*self` +LL | +LL | _mut_borrow; + | ----------- borrow later used here + +error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:57:17 + | +LL | self.hash_expr(&self.cx_mut.body(eid).value); + | ^^^^^---------^^-----------^^^^^^^^^^^^^^^^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:119:51 + | +LL | reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut))); + | --- --------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:122:54 + | +LL | reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); + | --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:125:53 + | +LL | reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); + | --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:128:44 + | +LL | reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut)); + | --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:138:5 + | +LL | reg.register_bound(Box::new(CapturePass::new(®.sess_mut))); + | ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:141:5 + | +LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut))); + | ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable + --> $DIR/two-phase-surprise-no-conflict.rs:144:5 + | +LL | reg.register_ref(&CapturePass::new(®.sess_mut)); + | ^^^^------------^^^^^^^^^^^^^^^^^^^-------------^^ + | | | | + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `*reg` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:154:5 + | +LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^ + | | | | + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:154:54 + | +LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `*reg` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:158:5 + | +LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^ + | | | | + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:158:53 + | +LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); + | --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `*reg` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:162:5 + | +LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); + | ^^^^------------^^^^^^^^^^^^^^^^^^^^^^^-----------------^^ + | | | | + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time + --> $DIR/two-phase-surprise-no-conflict.rs:162:44 + | +LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); + | --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | | first borrow later used by call + | first mutable borrow occurs here + +error: aborting due to 15 previous errors + +Some errors have detailed explanations: E0499, E0502, E0503. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/run-pass/box-new.rs b/src/test/ui/box-new.rs similarity index 85% rename from src/test/run-pass/box-new.rs rename to src/test/ui/box-new.rs index 2d177bcf92..be1a40cf77 100644 --- a/src/test/run-pass/box-new.rs +++ b/src/test/ui/box-new.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 fn main() { diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/ui/bug-7183-generics.rs similarity index 98% rename from src/test/run-pass/bug-7183-generics.rs rename to src/test/ui/bug-7183-generics.rs index 72cfe1973a..f53a173612 100644 --- a/src/test/run-pass/bug-7183-generics.rs +++ b/src/test/ui/bug-7183-generics.rs @@ -1,3 +1,5 @@ +// run-pass + trait Speak : Sized { fn say(&self, s:&str) -> String; fn hi(&self) -> String { hello(self) } diff --git a/src/test/run-pass/bug-7295.rs b/src/test/ui/bug-7295.rs similarity index 93% rename from src/test/run-pass/bug-7295.rs rename to src/test/ui/bug-7295.rs index b6dea6c82d..156ff2ee82 100644 --- a/src/test/run-pass/bug-7295.rs +++ b/src/test/ui/bug-7295.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 pub trait Foo { diff --git a/src/test/run-pass/builtin-clone-unwind.rs b/src/test/ui/builtin-clone-unwind.rs similarity index 98% rename from src/test/run-pass/builtin-clone-unwind.rs rename to src/test/ui/builtin-clone-unwind.rs index fa27808291..339bcfa106 100644 --- a/src/test/run-pass/builtin-clone-unwind.rs +++ b/src/test/ui/builtin-clone-unwind.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] #![allow(unused_imports)] // ignore-wasm32-bare compiled with panic=abort by default diff --git a/src/test/run-pass/builtin-clone.rs b/src/test/ui/builtin-clone.rs similarity index 98% rename from src/test/run-pass/builtin-clone.rs rename to src/test/ui/builtin-clone.rs index 2a9b98a6e3..0874d5bc39 100644 --- a/src/test/run-pass/builtin-clone.rs +++ b/src/test/ui/builtin-clone.rs @@ -1,3 +1,4 @@ +// run-pass // Test that `Clone` is correctly implemented for builtin types. // Also test that cloning an array or a tuple is done right, i.e. // each component is cloned. diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/ui/builtin-superkinds-capabilities-transitive.rs similarity index 98% rename from src/test/run-pass/builtin-superkinds-capabilities-transitive.rs rename to src/test/ui/builtin-superkinds-capabilities-transitive.rs index 8ff70036ed..1f997d3712 100644 --- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs +++ b/src/test/ui/builtin-superkinds-capabilities-transitive.rs @@ -1,3 +1,4 @@ +// run-pass // Tests "transitivity" of super-builtin-kinds on traits. Here, if // we have a Foo, we know we have a Bar, and if we have a Bar, we // know we have a Send. So if we have a Foo we should know we have diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/ui/builtin-superkinds-capabilities-xc.rs similarity index 98% rename from src/test/run-pass/builtin-superkinds-capabilities-xc.rs rename to src/test/ui/builtin-superkinds-capabilities-xc.rs index 7af41cbf50..8416bb3a37 100644 --- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs +++ b/src/test/ui/builtin-superkinds-capabilities-xc.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:trait_superkinds_in_metadata.rs // Tests "capabilities" granted by traits with super-builtin-kinds, diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/ui/builtin-superkinds-capabilities.rs similarity index 97% rename from src/test/run-pass/builtin-superkinds-capabilities.rs rename to src/test/ui/builtin-superkinds-capabilities.rs index 2a2917b69b..e936f921a8 100644 --- a/src/test/run-pass/builtin-superkinds-capabilities.rs +++ b/src/test/ui/builtin-superkinds-capabilities.rs @@ -1,3 +1,4 @@ +// run-pass // Tests "capabilities" granted by traits that inherit from super- // builtin-kinds, e.g., if a trait requires Send to implement, then // at usage site of that trait, we know we have the Send capability. diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/ui/builtin-superkinds-in-metadata.rs similarity index 97% rename from src/test/run-pass/builtin-superkinds-in-metadata.rs rename to src/test/ui/builtin-superkinds-in-metadata.rs index f585d9cc4f..117014b44e 100644 --- a/src/test/run-pass/builtin-superkinds-in-metadata.rs +++ b/src/test/ui/builtin-superkinds-in-metadata.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] // aux-build:trait_superkinds_in_metadata.rs diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/ui/builtin-superkinds-phantom-typaram.rs similarity index 96% rename from src/test/run-pass/builtin-superkinds-phantom-typaram.rs rename to src/test/ui/builtin-superkinds-phantom-typaram.rs index 3899ecf6f3..9b80664b04 100644 --- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs +++ b/src/test/ui/builtin-superkinds-phantom-typaram.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Tests that even when a type parameter doesn't implement a required // super-builtin-kind of a trait, if the type parameter is never used, diff --git a/src/test/run-pass/builtin-superkinds-simple.rs b/src/test/ui/builtin-superkinds-simple.rs similarity index 93% rename from src/test/run-pass/builtin-superkinds-simple.rs rename to src/test/ui/builtin-superkinds-simple.rs index 670b8ed0e9..8d24771578 100644 --- a/src/test/run-pass/builtin-superkinds-simple.rs +++ b/src/test/ui/builtin-superkinds-simple.rs @@ -1,3 +1,4 @@ +// run-pass // Simple test case of implementing a trait with super-builtin-kinds. // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/builtin-superkinds-typaram.rs b/src/test/ui/builtin-superkinds-typaram.rs similarity index 94% rename from src/test/run-pass/builtin-superkinds-typaram.rs rename to src/test/ui/builtin-superkinds-typaram.rs index c3a456318b..f999dfff78 100644 --- a/src/test/run-pass/builtin-superkinds-typaram.rs +++ b/src/test/ui/builtin-superkinds-typaram.rs @@ -1,3 +1,4 @@ +// run-pass // Tests correct implementation of traits with super-builtin-kinds // using a bounded type parameter. diff --git a/src/test/run-pass/byte-literals.rs b/src/test/ui/byte-literals.rs similarity index 99% rename from src/test/run-pass/byte-literals.rs rename to src/test/ui/byte-literals.rs index 259ac08fd9..2649c2eac3 100644 --- a/src/test/run-pass/byte-literals.rs +++ b/src/test/ui/byte-literals.rs @@ -1,3 +1,4 @@ +// run-pass // diff --git a/src/test/run-pass/c-stack-as-value.rs b/src/test/ui/c-stack-as-value.rs similarity index 96% rename from src/test/run-pass/c-stack-as-value.rs rename to src/test/ui/c-stack-as-value.rs index 3b997295c1..7595b76fb3 100644 --- a/src/test/run-pass/c-stack-as-value.rs +++ b/src/test/ui/c-stack-as-value.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 // ignore-wasm32-bare no libc to test ffi with diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/ui/c-stack-returning-int64.rs similarity index 98% rename from src/test/run-pass/c-stack-returning-int64.rs rename to src/test/ui/c-stack-returning-int64.rs index ec162b40bf..388d280b83 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/ui/c-stack-returning-int64.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare no libc to test with // ignore-sgx no libc diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr index 3c5131835b..4947d6e529 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr @@ -23,6 +23,16 @@ LL | let _ = ap.with_copy(|ap| { ap }); | | return type of closure is core::ffi::VaList<'2, '_> | has type `core::ffi::VaList<'1, '_>` +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:20:5 + | +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` +LL | *ap0 = ap1; + | ^^^^ assignment requires that `'1` must outlive `'2` + error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:20:5 | @@ -34,7 +44,7 @@ LL | *ap0 = ap1; | ^^^^ assignment requires that `'1` must outlive `'2` error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:24:5 + --> $DIR/variadic-ffi-4.rs:25:5 | LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { | --- ------- has type `core::ffi::VaListImpl<'2>` @@ -44,7 +54,7 @@ LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:24:5 + --> $DIR/variadic-ffi-4.rs:25:5 | LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { | --- ------- has type `core::ffi::VaListImpl<'1>` @@ -54,7 +64,7 @@ LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` error[E0384]: cannot assign to immutable argument `ap0` - --> $DIR/variadic-ffi-4.rs:24:5 + --> $DIR/variadic-ffi-4.rs:25:5 | LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { | --- help: make this binding mutable: `mut ap0` @@ -62,7 +72,7 @@ LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ cannot assign to immutable argument error[E0597]: `ap1` does not live long enough - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { | - let's call the lifetime of this reference `'1` @@ -76,16 +86,26 @@ LL | } | - `ap1` dropped here while still borrowed error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:32:5 + --> $DIR/variadic-ffi-4.rs:33:12 + | +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'2>` + | | + | has type `&mut core::ffi::VaListImpl<'1>` +LL | *ap0 = ap1.clone(); + | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:33:12 | LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { | ------- ------- has type `core::ffi::VaListImpl<'1>` | | | has type `&mut core::ffi::VaListImpl<'2>` LL | *ap0 = ap1.clone(); - | ^^^^ assignment requires that `'1` must outlive `'2` + | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -error: aborting due to 9 previous errors +error: aborting due to 11 previous errors Some errors have detailed explanations: E0384, E0597, E0621. For more information about an error, try `rustc --explain E0384`. diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs index 07c32ecbfc..4a50d352a5 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.rs +++ b/src/test/ui/c-variadic/variadic-ffi-4.rs @@ -18,6 +18,7 @@ pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { *ap0 = ap1; //~ ERROR: mismatched types + //~^ ERROR: mismatched types } pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { @@ -29,5 +30,6 @@ pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ... } pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - *ap0 = ap1.clone(); //~ ERROR: cannot infer an appropriate lifetime + *ap0 = ap1.clone(); //~ ERROR: mismatched types + //~^ ERROR: mismatched types } diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index 72d4d8b634..7aa510e611 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -52,6 +52,7 @@ note: the anonymous lifetime #3 defined on the function body at 19:1... | LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1; +LL | | LL | | } | |_^ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1 @@ -59,17 +60,43 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the f | LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1; +LL | | +LL | | } + | |_^ + +error[E0308]: mismatched types + --> $DIR/variadic-ffi-4.rs:20:12 + | +LL | *ap0 = ap1; + | ^^^ lifetime mismatch + | + = note: expected type `core::ffi::VaListImpl<'_>` + found type `core::ffi::VaListImpl<'_>` +note: the anonymous lifetime #2 defined on the function body at 19:1... + --> $DIR/variadic-ffi-4.rs:19:1 + | +LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | | *ap0 = ap1; +LL | | +LL | | } + | |_^ +note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 19:1 + --> $DIR/variadic-ffi-4.rs:19:1 + | +LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | | *ap0 = ap1; +LL | | LL | | } | |_^ error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ | -note: the type is valid for the anonymous lifetime #1 defined on the function body at 23:1 - --> $DIR/variadic-ffi-4.rs:23:1 +note: the type is valid for the anonymous lifetime #1 defined on the function body at 24:1 + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -79,8 +106,8 @@ LL | | LL | | LL | | } | |_^ -note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 23:1 - --> $DIR/variadic-ffi-4.rs:23:1 +note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 24:1 + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -92,15 +119,15 @@ LL | | } | |_^ error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ lifetime mismatch | = note: expected type `&mut core::ffi::VaListImpl<'_>` found type `&mut core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 23:1... - --> $DIR/variadic-ffi-4.rs:23:1 +note: the anonymous lifetime #3 defined on the function body at 24:1... + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -110,8 +137,8 @@ LL | | LL | | LL | | } | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 23:1 - --> $DIR/variadic-ffi-4.rs:23:1 +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 24:1 + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -123,15 +150,15 @@ LL | | } | |_^ error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ lifetime mismatch | = note: expected type `&mut core::ffi::VaListImpl<'_>` found type `&mut core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 23:1... - --> $DIR/variadic-ffi-4.rs:23:1 +note: the anonymous lifetime #2 defined on the function body at 24:1... + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -141,8 +168,8 @@ LL | | LL | | LL | | } | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 23:1 - --> $DIR/variadic-ffi-4.rs:23:1 +note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 24:1 + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -154,13 +181,13 @@ LL | | } | |_^ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ | -note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 23:1... - --> $DIR/variadic-ffi-4.rs:23:1 +note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 24:1... + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -171,12 +198,12 @@ LL | | LL | | } | |_^ note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ -note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 23:1... - --> $DIR/variadic-ffi-4.rs:23:1 +note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 24:1... + --> $DIR/variadic-ffi-4.rs:24:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; @@ -187,39 +214,62 @@ LL | | LL | | } | |_^ note: ...so that reference does not outlive borrowed content - --> $DIR/variadic-ffi-4.rs:24:11 + --> $DIR/variadic-ffi-4.rs:25:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:32:16 +error[E0308]: mismatched types + --> $DIR/variadic-ffi-4.rs:33:12 | LL | *ap0 = ap1.clone(); - | ^^^^^ + | ^^^^^^^^^^^ lifetime mismatch | -note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 31:1... - --> $DIR/variadic-ffi-4.rs:31:1 + = note: expected type `core::ffi::VaListImpl<'_>` + found type `core::ffi::VaListImpl<'_>` +note: the anonymous lifetime #3 defined on the function body at 32:1... + --> $DIR/variadic-ffi-4.rs:32:1 | LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1.clone(); +LL | | LL | | } | |_^ - = note: ...so that the types are compatible: - expected &core::ffi::VaListImpl<'_> - found &core::ffi::VaListImpl<'_> -note: but, the lifetime must be valid for the anonymous lifetime #2 defined on the function body at 31:1... - --> $DIR/variadic-ffi-4.rs:31:1 +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 32:1 + --> $DIR/variadic-ffi-4.rs:32:1 | LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1.clone(); +LL | | +LL | | } + | |_^ + +error[E0308]: mismatched types + --> $DIR/variadic-ffi-4.rs:33:12 + | +LL | *ap0 = ap1.clone(); + | ^^^^^^^^^^^ lifetime mismatch + | + = note: expected type `core::ffi::VaListImpl<'_>` + found type `core::ffi::VaListImpl<'_>` +note: the anonymous lifetime #2 defined on the function body at 32:1... + --> $DIR/variadic-ffi-4.rs:32:1 + | +LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | | *ap0 = ap1.clone(); +LL | | +LL | | } + | |_^ +note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 32:1 + --> $DIR/variadic-ffi-4.rs:32:1 + | +LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | | *ap0 = ap1.clone(); +LL | | LL | | } | |_^ - = note: ...so that the expression is assignable: - expected core::ffi::VaListImpl<'_> - found core::ffi::VaListImpl<'_> -error: aborting due to 9 previous errors +error: aborting due to 11 previous errors Some errors have detailed explanations: E0308, E0621. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/run-pass/cabi-int-widening.rs b/src/test/ui/cabi-int-widening.rs similarity index 95% rename from src/test/run-pass/cabi-int-widening.rs rename to src/test/ui/cabi-int-widening.rs index f6524c6a3d..240eaebf3d 100644 --- a/src/test/run-pass/cabi-int-widening.rs +++ b/src/test/ui/cabi-int-widening.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare no libc to test ffi with #[link(name = "rust_test_helpers", kind = "static")] diff --git a/src/test/run-pass/can-copy-pod.rs b/src/test/ui/can-copy-pod.rs similarity index 96% rename from src/test/run-pass/can-copy-pod.rs rename to src/test/ui/can-copy-pod.rs index bc10d236b3..e6c57ca3f7 100644 --- a/src/test/run-pass/can-copy-pod.rs +++ b/src/test/ui/can-copy-pod.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 /* Any copyright is dedicated to the Public Domain. diff --git a/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs b/src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs similarity index 92% rename from src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs rename to src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs index f27803677c..781d5c14ab 100644 --- a/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs +++ b/src/test/ui/cancel-clean-via-immediate-rvalue-ref.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(box_syntax)] diff --git a/src/test/run-pass/cast-does-fallback.rs b/src/test/ui/cast-does-fallback.rs similarity index 95% rename from src/test/run-pass/cast-does-fallback.rs rename to src/test/ui/cast-does-fallback.rs index 6adf90fc0e..770f7a31c7 100644 --- a/src/test/run-pass/cast-does-fallback.rs +++ b/src/test/ui/cast-does-fallback.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { // Test that these type check correctly. (&42u8 >> 4) as usize; diff --git a/src/test/run-pass/cast-region-to-uint.rs b/src/test/ui/cast-region-to-uint.rs similarity index 88% rename from src/test/run-pass/cast-region-to-uint.rs rename to src/test/ui/cast-region-to-uint.rs index ef2f6f1c49..33ec2d2761 100644 --- a/src/test/run-pass/cast-region-to-uint.rs +++ b/src/test/ui/cast-region-to-uint.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let x: isize = 3; println!("&x={:x}", (&x as *const isize as usize)); diff --git a/src/test/run-pass/cast-rfc0401-vtable-kinds.rs b/src/test/ui/cast-rfc0401-vtable-kinds.rs similarity index 99% rename from src/test/run-pass/cast-rfc0401-vtable-kinds.rs rename to src/test/ui/cast-rfc0401-vtable-kinds.rs index a27dd9eef5..249481467e 100644 --- a/src/test/run-pass/cast-rfc0401-vtable-kinds.rs +++ b/src/test/ui/cast-rfc0401-vtable-kinds.rs @@ -1,3 +1,4 @@ +// run-pass // Check that you can cast between different pointers to trait objects // whose vtable have the same kind (both lengths, or both trait pointers). diff --git a/src/test/run-pass/cast-rfc0401.rs b/src/test/ui/cast-rfc0401.rs similarity index 99% rename from src/test/run-pass/cast-rfc0401.rs rename to src/test/ui/cast-rfc0401.rs index 017b63c737..996fa013fe 100644 --- a/src/test/run-pass/cast-rfc0401.rs +++ b/src/test/ui/cast-rfc0401.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] use std::vec; diff --git a/src/test/run-pass/cast-to-infer-ty.rs b/src/test/ui/cast-to-infer-ty.rs similarity index 93% rename from src/test/run-pass/cast-to-infer-ty.rs rename to src/test/ui/cast-to-infer-ty.rs index e29860cbfb..053ebb621a 100644 --- a/src/test/run-pass/cast-to-infer-ty.rs +++ b/src/test/ui/cast-to-infer-ty.rs @@ -1,3 +1,4 @@ +// run-pass // Check that we allow a cast to `_` so long as the target type can be // inferred elsewhere. diff --git a/src/test/run-pass/cast.rs b/src/test/ui/cast.rs similarity index 97% rename from src/test/run-pass/cast.rs rename to src/test/ui/cast.rs index c7977f461d..218275c4d9 100644 --- a/src/test/run-pass/cast.rs +++ b/src/test/ui/cast.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_assignments)] #![allow(unused_variables)] diff --git a/src/test/ui/cast/cast-ptr-to-int-const.stderr b/src/test/ui/cast/cast-ptr-to-int-const.stderr index c40accfd7c..140661738d 100644 --- a/src/test/ui/cast/cast-ptr-to-int-const.stderr +++ b/src/test/ui/cast/cast-ptr-to-int-const.stderr @@ -5,7 +5,7 @@ LL | main as u32 | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51910 - = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error[E0658]: casting pointers to integers in constants is unstable --> $DIR/cast-ptr-to-int-const.rs:9:9 @@ -14,7 +14,7 @@ LL | &Y as *const u32 as u32 | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51910 - = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/run-pass/catch-unwind-bang.rs b/src/test/ui/catch-unwind-bang.rs similarity index 93% rename from src/test/run-pass/catch-unwind-bang.rs rename to src/test/ui/catch-unwind-bang.rs index 6c6f5a4fcf..f181991713 100644 --- a/src/test/run-pass/catch-unwind-bang.rs +++ b/src/test/ui/catch-unwind-bang.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare compiled with panic=abort by default fn worker() -> ! { diff --git a/src/test/run-pass/cell-does-not-clone.rs b/src/test/ui/cell-does-not-clone.rs similarity index 97% rename from src/test/run-pass/cell-does-not-clone.rs rename to src/test/ui/cell-does-not-clone.rs index 7ba6419d8a..587447b54b 100644 --- a/src/test/run-pass/cell-does-not-clone.rs +++ b/src/test/ui/cell-does-not-clone.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] use std::cell::Cell; diff --git a/src/test/run-pass/cfg/auxiliary/cfg_inner_static.rs b/src/test/ui/cfg/auxiliary/cfg_inner_static.rs similarity index 100% rename from src/test/run-pass/cfg/auxiliary/cfg_inner_static.rs rename to src/test/ui/cfg/auxiliary/cfg_inner_static.rs diff --git a/src/test/run-pass/cfg/auxiliary/crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs similarity index 100% rename from src/test/run-pass/cfg/auxiliary/crate-attributes-using-cfg_attr.rs rename to src/test/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs diff --git a/src/test/run-pass/cfg/cfg-attr-cfg.rs b/src/test/ui/cfg/cfg-attr-cfg.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-attr-cfg.rs rename to src/test/ui/cfg/cfg-attr-cfg.rs diff --git a/src/test/run-pass/cfg/cfg-attr-crate.rs b/src/test/ui/cfg/cfg-attr-crate.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-attr-crate.rs rename to src/test/ui/cfg/cfg-attr-crate.rs diff --git a/src/test/run-pass/cfg/cfg-family.rs b/src/test/ui/cfg/cfg-family.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-family.rs rename to src/test/ui/cfg/cfg-family.rs diff --git a/src/test/run-pass/cfg/cfg-in-crate-1.rs b/src/test/ui/cfg/cfg-in-crate-1.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-in-crate-1.rs rename to src/test/ui/cfg/cfg-in-crate-1.rs diff --git a/src/test/run-pass/cfg/cfg-macros-foo.rs b/src/test/ui/cfg/cfg-macros-foo.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-macros-foo.rs rename to src/test/ui/cfg/cfg-macros-foo.rs diff --git a/src/test/run-pass/cfg/cfg-macros-notfoo.rs b/src/test/ui/cfg/cfg-macros-notfoo.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-macros-notfoo.rs rename to src/test/ui/cfg/cfg-macros-notfoo.rs diff --git a/src/test/run-pass/cfg/cfg-match-arm.rs b/src/test/ui/cfg/cfg-match-arm.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-match-arm.rs rename to src/test/ui/cfg/cfg-match-arm.rs diff --git a/src/test/run-pass/cfg/cfg-target-family.rs b/src/test/ui/cfg/cfg-target-family.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-target-family.rs rename to src/test/ui/cfg/cfg-target-family.rs diff --git a/src/test/run-pass/cfg/cfg-target-vendor.rs b/src/test/ui/cfg/cfg-target-vendor.rs similarity index 100% rename from src/test/run-pass/cfg/cfg-target-vendor.rs rename to src/test/ui/cfg/cfg-target-vendor.rs diff --git a/src/test/run-pass/cfg/cfg_attr.rs b/src/test/ui/cfg/cfg_attr.rs similarity index 100% rename from src/test/run-pass/cfg/cfg_attr.rs rename to src/test/ui/cfg/cfg_attr.rs diff --git a/src/test/run-pass/cfg/cfg_inner_static.rs b/src/test/ui/cfg/cfg_inner_static.rs similarity index 100% rename from src/test/run-pass/cfg/cfg_inner_static.rs rename to src/test/ui/cfg/cfg_inner_static.rs diff --git a/src/test/run-pass/cfg/cfg_stmt_expr.rs b/src/test/ui/cfg/cfg_stmt_expr.rs similarity index 100% rename from src/test/run-pass/cfg/cfg_stmt_expr.rs rename to src/test/ui/cfg/cfg_stmt_expr.rs diff --git a/src/test/run-pass/cfg/cfgs-on-items.rs b/src/test/ui/cfg/cfgs-on-items.rs similarity index 100% rename from src/test/run-pass/cfg/cfgs-on-items.rs rename to src/test/ui/cfg/cfgs-on-items.rs diff --git a/src/test/run-pass/cfg/conditional-compile-arch.rs b/src/test/ui/cfg/conditional-compile-arch.rs similarity index 100% rename from src/test/run-pass/cfg/conditional-compile-arch.rs rename to src/test/ui/cfg/conditional-compile-arch.rs diff --git a/src/test/run-pass/cfg/conditional-compile.rs b/src/test/ui/cfg/conditional-compile.rs similarity index 100% rename from src/test/run-pass/cfg/conditional-compile.rs rename to src/test/ui/cfg/conditional-compile.rs diff --git a/src/test/run-pass/cfg/crate-attributes-using-cfg_attr.rs b/src/test/ui/cfg/crate-attributes-using-cfg_attr.rs similarity index 100% rename from src/test/run-pass/cfg/crate-attributes-using-cfg_attr.rs rename to src/test/ui/cfg/crate-attributes-using-cfg_attr.rs diff --git a/src/test/run-pass/chalkify/builtin-copy-clone.rs b/src/test/ui/chalkify/builtin-copy-clone.rs similarity index 98% rename from src/test/run-pass/chalkify/builtin-copy-clone.rs rename to src/test/ui/chalkify/builtin-copy-clone.rs index 4f69714bc7..d403514b55 100644 --- a/src/test/run-pass/chalkify/builtin-copy-clone.rs +++ b/src/test/ui/chalkify/builtin-copy-clone.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z chalk // Test that `Clone` is correctly implemented for builtin types. diff --git a/src/test/run-pass/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs similarity index 98% rename from src/test/run-pass/chalkify/inherent_impl.rs rename to src/test/ui/chalkify/inherent_impl.rs index fbe30f1154..44e120c1ee 100644 --- a/src/test/run-pass/chalkify/inherent_impl.rs +++ b/src/test/ui/chalkify/inherent_impl.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z chalk trait Foo { } diff --git a/src/test/run-pass/chalkify/projection.rs b/src/test/ui/chalkify/projection.rs similarity index 96% rename from src/test/run-pass/chalkify/projection.rs rename to src/test/ui/chalkify/projection.rs index a598f68d3f..d6a8dd7a4a 100644 --- a/src/test/run-pass/chalkify/projection.rs +++ b/src/test/ui/chalkify/projection.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z chalk trait Foo { } diff --git a/src/test/run-pass/chalkify/super_trait.rs b/src/test/ui/chalkify/super_trait.rs similarity index 95% rename from src/test/run-pass/chalkify/super_trait.rs rename to src/test/ui/chalkify/super_trait.rs index 441d61ef24..eeff9fd9b8 100644 --- a/src/test/run-pass/chalkify/super_trait.rs +++ b/src/test/ui/chalkify/super_trait.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z chalk trait Foo { } diff --git a/src/test/run-pass/chalkify/trait_implied_bound.rs b/src/test/ui/chalkify/trait_implied_bound.rs similarity index 95% rename from src/test/run-pass/chalkify/trait_implied_bound.rs rename to src/test/ui/chalkify/trait_implied_bound.rs index f82453792f..8a2e1cf599 100644 --- a/src/test/run-pass/chalkify/trait_implied_bound.rs +++ b/src/test/ui/chalkify/trait_implied_bound.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z chalk trait Foo { } diff --git a/src/test/run-pass/chalkify/type_implied_bound.rs b/src/test/ui/chalkify/type_implied_bound.rs similarity index 97% rename from src/test/run-pass/chalkify/type_implied_bound.rs rename to src/test/ui/chalkify/type_implied_bound.rs index 94d976d324..8673f5319b 100644 --- a/src/test/run-pass/chalkify/type_implied_bound.rs +++ b/src/test/ui/chalkify/type_implied_bound.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z chalk trait Eq { } diff --git a/src/test/run-pass/char.rs b/src/test/ui/char.rs similarity index 94% rename from src/test/run-pass/char.rs rename to src/test/ui/char.rs index 1616d666c1..cfb7a37af0 100644 --- a/src/test/run-pass/char.rs +++ b/src/test/ui/char.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let c: char = 'x'; let d: char = 'x'; diff --git a/src/test/run-pass/char_unicode.rs b/src/test/ui/char_unicode.rs similarity index 95% rename from src/test/run-pass/char_unicode.rs rename to src/test/ui/char_unicode.rs index 90ec26e80b..93e5300e36 100644 --- a/src/test/run-pass/char_unicode.rs +++ b/src/test/ui/char_unicode.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(unicode_version)] /// Tests access to the internal Unicode Version type and value. diff --git a/src/test/run-pass/check-static-recursion-foreign.rs b/src/test/ui/check-static-recursion-foreign.rs similarity index 97% rename from src/test/run-pass/check-static-recursion-foreign.rs rename to src/test/ui/check-static-recursion-foreign.rs index 361f8a1d34..8ca0af8e47 100644 --- a/src/test/run-pass/check-static-recursion-foreign.rs +++ b/src/test/ui/check-static-recursion-foreign.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Static recursion check shouldn't fail when given a foreign item (#18279) diff --git a/src/test/run-pass/check_const-feature-gated.rs b/src/test/ui/check_const-feature-gated.rs similarity index 84% rename from src/test/run-pass/check_const-feature-gated.rs rename to src/test/ui/check_const-feature-gated.rs index 1c816d5d7c..f4faab1abc 100644 --- a/src/test/run-pass/check_const-feature-gated.rs +++ b/src/test/ui/check_const-feature-gated.rs @@ -1,3 +1,5 @@ +// run-pass + const ARR: [usize; 1] = [2]; fn main() { diff --git a/src/test/ui/check_match/issue-43253.rs b/src/test/ui/check_match/issue-43253.rs index 5d084248a7..a4d6e9b777 100644 --- a/src/test/ui/check_match/issue-43253.rs +++ b/src/test/ui/check_match/issue-43253.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(exclusive_range_pattern)] #![warn(unreachable_patterns)] diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/ui/child-outlives-parent.rs similarity index 95% rename from src/test/run-pass/child-outlives-parent.rs rename to src/test/ui/child-outlives-parent.rs index 80e3c81af5..e3a39a44bb 100644 --- a/src/test/run-pass/child-outlives-parent.rs +++ b/src/test/ui/child-outlives-parent.rs @@ -1,3 +1,4 @@ +// run-pass // Reported as issue #126, child leaks the string. // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/cleanup-arm-conditional.rs b/src/test/ui/cleanup-arm-conditional.rs similarity index 98% rename from src/test/run-pass/cleanup-arm-conditional.rs rename to src/test/ui/cleanup-arm-conditional.rs index b8b1099052..915842f3e8 100644 --- a/src/test/run-pass/cleanup-arm-conditional.rs +++ b/src/test/ui/cleanup-arm-conditional.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] #![allow(unused_imports)] // Test that cleanup scope for temporaries created in a match diff --git a/src/test/run-pass/cleanup-rvalue-during-if-and-while.rs b/src/test/ui/cleanup-rvalue-during-if-and-while.rs similarity index 98% rename from src/test/run-pass/cleanup-rvalue-during-if-and-while.rs rename to src/test/ui/cleanup-rvalue-during-if-and-while.rs index 370c95c666..6fecb4e76d 100644 --- a/src/test/run-pass/cleanup-rvalue-during-if-and-while.rs +++ b/src/test/ui/cleanup-rvalue-during-if-and-while.rs @@ -1,3 +1,4 @@ +// run-pass // This test verifies that temporaries created for `while`'s and `if` // conditions are dropped after the condition is evaluated. diff --git a/src/test/run-pass/cleanup-rvalue-for-scope.rs b/src/test/ui/cleanup-rvalue-for-scope.rs similarity index 98% rename from src/test/run-pass/cleanup-rvalue-for-scope.rs rename to src/test/ui/cleanup-rvalue-for-scope.rs index 488c6e580d..b6582c01fb 100644 --- a/src/test/run-pass/cleanup-rvalue-for-scope.rs +++ b/src/test/ui/cleanup-rvalue-for-scope.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_snake_case)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/run-pass/cleanup-rvalue-scopes.rs b/src/test/ui/cleanup-rvalue-scopes.rs similarity index 99% rename from src/test/run-pass/cleanup-rvalue-scopes.rs rename to src/test/ui/cleanup-rvalue-scopes.rs index 331c93f442..f51f13abf7 100644 --- a/src/test/run-pass/cleanup-rvalue-scopes.rs +++ b/src/test/ui/cleanup-rvalue-scopes.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_snake_case)] #![allow(unused_variables)] // Test that destructors for rvalue temporaries run either at end of diff --git a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs b/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs similarity index 98% rename from src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs rename to src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs index 7b4d66e757..62f8b81385 100644 --- a/src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs +++ b/src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/run-pass/cleanup-shortcircuit.rs b/src/test/ui/cleanup-shortcircuit.rs similarity index 98% rename from src/test/run-pass/cleanup-shortcircuit.rs rename to src/test/ui/cleanup-shortcircuit.rs index 6e67a276d4..19d774079a 100644 --- a/src/test/run-pass/cleanup-shortcircuit.rs +++ b/src/test/ui/cleanup-shortcircuit.rs @@ -1,3 +1,4 @@ +// run-pass // Test that cleanups for the RHS of shortcircuiting operators work. // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/clone-with-exterior.rs b/src/test/ui/clone-with-exterior.rs similarity index 96% rename from src/test/run-pass/clone-with-exterior.rs rename to src/test/ui/clone-with-exterior.rs index 1d3b54aa5e..1ef2971926 100644 --- a/src/test/run-pass/clone-with-exterior.rs +++ b/src/test/ui/clone-with-exterior.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] // ignore-emscripten no threads support diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/ui/close-over-big-then-small-data.rs similarity index 98% rename from src/test/run-pass/close-over-big-then-small-data.rs rename to src/test/ui/close-over-big-then-small-data.rs index 0eead0194e..40e5f500df 100644 --- a/src/test/run-pass/close-over-big-then-small-data.rs +++ b/src/test/ui/close-over-big-then-small-data.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // If we use GEPi rather than GEP_tup_like when // storing closure data (as we used to do), the u64 would diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs index 1bfaecd16c..5f02e642de 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] diff --git a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs index 3e42284b72..0ee738c2c2 100644 --- a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs +++ b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn with_closure(_: F) where F: FnOnce(A, &u32) diff --git a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs index cf417d7c2a..15711da4b0 100644 --- a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs +++ b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn with_closure(_: F) where F: FnOnce(A, &u32) diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs index 477eb40c57..f7b4f2b245 100644 --- a/src/test/ui/closure-expected-type/issue-24421.rs +++ b/src/test/ui/closure-expected-type/issue-24421.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn test(f: F) {} diff --git a/src/test/ui/closure_promotion.rs b/src/test/ui/closure_promotion.rs index db9c0a6ef3..db36985afe 100644 --- a/src/test/ui/closure_promotion.rs +++ b/src/test/ui/closure_promotion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(const_err)] diff --git a/src/test/run-pass/cmp-default.rs b/src/test/ui/cmp-default.rs similarity index 99% rename from src/test/run-pass/cmp-default.rs rename to src/test/ui/cmp-default.rs index 3be0eb4c5d..bb5c39f5cd 100644 --- a/src/test/run-pass/cmp-default.rs +++ b/src/test/ui/cmp-default.rs @@ -1,3 +1,5 @@ +// run-pass + use std::cmp::Ordering; // Test default methods in PartialOrd and PartialEq diff --git a/src/test/run-pass/codegen-object-shim.rs b/src/test/ui/codegen-object-shim.rs similarity index 90% rename from src/test/run-pass/codegen-object-shim.rs rename to src/test/ui/codegen-object-shim.rs index 26f53a9c18..9a85a50ebd 100644 --- a/src/test/run-pass/codegen-object-shim.rs +++ b/src/test/ui/codegen-object-shim.rs @@ -1,3 +1,5 @@ +// run-pass + fn main() { assert_eq!((ToString::to_string as fn(&(dyn ToString+'static)) -> String)(&"foo"), String::from("foo")); diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr index c424eb08a7..5b01314d8a 100644 --- a/src/test/ui/codemap_tests/bad-format-args.stderr +++ b/src/test/ui/codemap_tests/bad-format-args.stderr @@ -10,13 +10,13 @@ error: expected token: `,` --> $DIR/bad-format-args.rs:3:16 | LL | format!("" 1); - | ^ + | ^ expected `,` error: expected token: `,` --> $DIR/bad-format-args.rs:4:19 | LL | format!("", 1 1); - | ^ + | ^ expected `,` error: aborting due to 3 previous errors diff --git a/src/test/ui/codemap_tests/unicode_3.rs b/src/test/ui/codemap_tests/unicode_3.rs index ff6d54468b..b9bcc1b88a 100644 --- a/src/test/ui/codemap_tests/unicode_3.rs +++ b/src/test/ui/codemap_tests/unicode_3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; } diff --git a/src/test/ui/codemap_tests/unicode_3.stderr b/src/test/ui/codemap_tests/unicode_3.stderr index 56f4f73131..cc1a80bc07 100644 --- a/src/test/ui/codemap_tests/unicode_3.stderr +++ b/src/test/ui/codemap_tests/unicode_3.stderr @@ -4,5 +4,5 @@ warning: denote infinite loops with `loop { ... }` LL | let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; } | ^^^^^^^^^^ help: use `loop` | - = note: #[warn(while_true)] on by default + = note: `#[warn(while_true)]` on by default diff --git a/src/test/run-pass/coerce/coerce-expect-unsized.rs b/src/test/ui/coerce/coerce-expect-unsized.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-expect-unsized.rs rename to src/test/ui/coerce/coerce-expect-unsized.rs diff --git a/src/test/run-pass/coerce/coerce-overloaded-autoderef.rs b/src/test/ui/coerce/coerce-overloaded-autoderef.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-overloaded-autoderef.rs rename to src/test/ui/coerce/coerce-overloaded-autoderef.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs b/src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-imm-ptr-arg.rs rename to src/test/ui/coerce/coerce-reborrow-imm-ptr-arg.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-imm-ptr-rcvr.rs rename to src/test/ui/coerce/coerce-reborrow-imm-ptr-rcvr.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-imm-vec-arg.rs b/src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-imm-vec-arg.rs rename to src/test/ui/coerce/coerce-reborrow-imm-vec-arg.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-imm-vec-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-imm-vec-rcvr.rs rename to src/test/ui/coerce/coerce-reborrow-imm-vec-rcvr.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs b/src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-mut-ptr-arg.rs rename to src/test/ui/coerce/coerce-reborrow-mut-ptr-arg.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-mut-ptr-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-mut-ptr-rcvr.rs rename to src/test/ui/coerce/coerce-reborrow-mut-ptr-rcvr.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-mut-vec-arg.rs b/src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-mut-vec-arg.rs rename to src/test/ui/coerce/coerce-reborrow-mut-vec-arg.rs diff --git a/src/test/run-pass/coerce/coerce-reborrow-mut-vec-rcvr.rs b/src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-reborrow-mut-vec-rcvr.rs rename to src/test/ui/coerce/coerce-reborrow-mut-vec-rcvr.rs diff --git a/src/test/run-pass/coerce/coerce-unify-return.rs b/src/test/ui/coerce/coerce-unify-return.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-unify-return.rs rename to src/test/ui/coerce/coerce-unify-return.rs diff --git a/src/test/run-pass/coerce/coerce-unify.rs b/src/test/ui/coerce/coerce-unify.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-unify.rs rename to src/test/ui/coerce/coerce-unify.rs diff --git a/src/test/run-pass/coerce/coerce-unsize-subtype.rs b/src/test/ui/coerce/coerce-unsize-subtype.rs similarity index 100% rename from src/test/run-pass/coerce/coerce-unsize-subtype.rs rename to src/test/ui/coerce/coerce-unsize-subtype.rs diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.rs b/src/test/ui/coercion/coerce-issue-49593-box-never.rs index 81723bb15b..f005245e6d 100644 --- a/src/test/ui/coercion/coerce-issue-49593-box-never.rs +++ b/src/test/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(never_type)] #![allow(unreachable_code)] diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr index 057de5b625..955793e858 100644 --- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn plus_one(x: i32) -> i32 { | -------- ^^^ expected i32, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | x + 1; | - help: consider removing this semicolon | @@ -17,7 +17,7 @@ error[E0308]: mismatched types LL | fn foo() -> Result { | --- ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | Ok(1); | - help: consider removing this semicolon | diff --git a/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs similarity index 77% rename from src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs rename to src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs index 41b9d64d5f..9a191bad8b 100644 --- a/src/test/run-pass/coherence/auxiliary/re_rebalance_coherence_lib.rs +++ b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs @@ -20,3 +20,12 @@ pub struct BatchInsert<'a, T: 'a, Tab> { impl<'a, T:'a, Tab, DB> QueryFragment for BatchInsert<'a, T, Tab> where DB: SupportsDefaultKeyword + Backend, {} + +pub trait LibToOwned { + type Owned; +} + +pub struct LibCow::Owned> { + pub t: T, + pub o: Owned, +} diff --git a/src/test/run-pass/coherence/coherence-bigint-int.rs b/src/test/ui/coherence/coherence-bigint-int.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-bigint-int.rs rename to src/test/ui/coherence/coherence-bigint-int.rs diff --git a/src/test/run-pass/coherence/coherence-bigint-vecint.rs b/src/test/ui/coherence/coherence-bigint-vecint.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-bigint-vecint.rs rename to src/test/ui/coherence/coherence-bigint-vecint.rs diff --git a/src/test/run-pass/coherence/coherence-blanket.rs b/src/test/ui/coherence/coherence-blanket.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-blanket.rs rename to src/test/ui/coherence/coherence-blanket.rs diff --git a/src/test/run-pass/coherence/coherence-covered-type-parameter.rs b/src/test/ui/coherence/coherence-covered-type-parameter.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-covered-type-parameter.rs rename to src/test/ui/coherence/coherence-covered-type-parameter.rs diff --git a/src/test/run-pass/coherence/coherence-impl-in-fn.rs b/src/test/ui/coherence/coherence-impl-in-fn.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-impl-in-fn.rs rename to src/test/ui/coherence/coherence-impl-in-fn.rs diff --git a/src/test/run-pass/coherence/coherence-iterator-vec-any-elem.rs b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-iterator-vec-any-elem.rs rename to src/test/ui/coherence/coherence-iterator-vec-any-elem.rs diff --git a/src/test/run-pass/coherence/coherence-iterator-vec.rs b/src/test/ui/coherence/coherence-iterator-vec.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-iterator-vec.rs rename to src/test/ui/coherence/coherence-iterator-vec.rs diff --git a/src/test/run-pass/coherence/coherence-multidispatch-tuple.rs b/src/test/ui/coherence/coherence-multidispatch-tuple.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-multidispatch-tuple.rs rename to src/test/ui/coherence/coherence-multidispatch-tuple.rs diff --git a/src/test/run-pass/coherence/coherence-negative-impls-safe.rs b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-negative-impls-safe.rs rename to src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs diff --git a/src/test/run-pass/coherence/coherence-rfc447-constrained.rs b/src/test/ui/coherence/coherence-rfc447-constrained.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-rfc447-constrained.rs rename to src/test/ui/coherence/coherence-rfc447-constrained.rs diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index e740675780..a0ff580671 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -5,7 +5,7 @@ // universe transition (#56105) may eventually become an error. // revisions: old re -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![cfg_attr(re, feature(re_rebalance_coherence))] diff --git a/src/test/run-pass/coherence/coherence-where-clause.rs b/src/test/ui/coherence/coherence-where-clause.rs similarity index 100% rename from src/test/run-pass/coherence/coherence-where-clause.rs rename to src/test/ui/coherence/coherence-where-clause.rs diff --git a/src/test/run-pass/coherence/coherence_copy_like.rs b/src/test/ui/coherence/coherence_copy_like.rs similarity index 100% rename from src/test/run-pass/coherence/coherence_copy_like.rs rename to src/test/ui/coherence/coherence_copy_like.rs diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs index a030314262..22517f9da2 100644 --- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs +++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs @@ -2,7 +2,7 @@ // `MyType: !MyTrait` along with other "fundamental" wrappers. // aux-build:coherence_copy_like_lib.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // skip-codgen // revisions: old re diff --git a/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs new file mode 100644 index 0000000000..3df6114f62 --- /dev/null +++ b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:re_rebalance_coherence_lib-rpass.rs + +#![allow(dead_code)] +#![feature(re_rebalance_coherence)] +// check that a generic type with a default value from an associated type can be used without +// specifying the value, and without invoking coherence errors. + +extern crate re_rebalance_coherence_lib_rpass as lib; +use lib::*; + +struct MyString {} + +impl LibToOwned for MyString { + type Owned = String; +} + +impl PartialEq for LibCow { + fn eq(&self, _other: &MyString) -> bool { + // Test that the default type is used. + let _s: &String = &self.o; + + false + } +} + +fn main() {} diff --git a/src/test/run-pass/coherence/re-rebalance-coherence.rs b/src/test/ui/coherence/re-rebalance-coherence-rpass.rs similarity index 100% rename from src/test/run-pass/coherence/re-rebalance-coherence.rs rename to src/test/ui/coherence/re-rebalance-coherence-rpass.rs diff --git a/src/test/run-pass/collections-const-new.rs b/src/test/ui/collections-const-new.rs similarity index 95% rename from src/test/run-pass/collections-const-new.rs rename to src/test/ui/collections-const-new.rs index 37ee1a41c0..e01b0dfa14 100644 --- a/src/test/run-pass/collections-const-new.rs +++ b/src/test/ui/collections-const-new.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Test several functions can be used for constants // 1. Vec::new() diff --git a/src/test/run-pass/command-exec.rs b/src/test/ui/command-exec.rs similarity index 99% rename from src/test/run-pass/command-exec.rs rename to src/test/ui/command-exec.rs index aa5a3a3770..568be67abe 100644 --- a/src/test/run-pass/command-exec.rs +++ b/src/test/ui/command-exec.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] // ignore-windows - this is a unix-specific test // ignore-pretty issue #37199 diff --git a/src/test/run-pass/command-pre-exec.rs b/src/test/ui/command-pre-exec.rs similarity index 99% rename from src/test/run-pass/command-pre-exec.rs rename to src/test/ui/command-pre-exec.rs index 5c3cc31de5..c0fc554183 100644 --- a/src/test/run-pass/command-pre-exec.rs +++ b/src/test/ui/command-pre-exec.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] // ignore-windows - this is a unix-specific test // ignore-cloudabi no processes diff --git a/src/test/ui/command-uid-gid.rs b/src/test/ui/command-uid-gid.rs new file mode 100644 index 0000000000..f867106c35 --- /dev/null +++ b/src/test/ui/command-uid-gid.rs @@ -0,0 +1,32 @@ +// run-pass +// ignore-android +// ignore-cloudabi +// ignore-emscripten +// ignore-sgx + +#![feature(rustc_private)] + +fn main() { + #[cfg(unix)] + run() +} + +#[cfg(unix)] +fn run() { + extern crate libc; + use std::process::Command; + use std::os::unix::prelude::*; + + let mut p = Command::new("/bin/sh") + .arg("-c").arg("true") + .uid(unsafe { libc::getuid() }) + .gid(unsafe { libc::getgid() }) + .spawn().unwrap(); + assert!(p.wait().unwrap().success()); + + // if we're already root, this isn't a valid test. Most of the bots run + // as non-root though (android is an exception). + if unsafe { libc::getuid() != 0 } { + assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err()); + } +} diff --git a/src/test/run-pass/complex.rs b/src/test/ui/complex.rs similarity index 98% rename from src/test/run-pass/complex.rs rename to src/test/ui/complex.rs index 4c2bb6859d..9b11ca67e4 100644 --- a/src/test/run-pass/complex.rs +++ b/src/test/ui/complex.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unconditional_recursion)] #![allow(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/run-pass/concat.rs b/src/test/ui/concat-rpass.rs similarity index 97% rename from src/test/run-pass/concat.rs rename to src/test/ui/concat-rpass.rs index e89763745b..0c30a39d6a 100644 --- a/src/test/run-pass/concat.rs +++ b/src/test/ui/concat-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { assert_eq!(format!(concat!("foo", "bar", "{}"), "baz"), "foobarbaz".to_string()); assert_eq!(format!(concat!()), "".to_string()); diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr index ec77789449..5a70a5efc7 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr @@ -5,7 +5,7 @@ LL | #![cfg_attr(broken, no_core)] | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29639 - = help: add #![feature(no_core)] to the crate attributes to enable + = help: add `#![feature(no_core)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr index cd3563e66c..046defd556 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(unused)] | ^^^^^^ - = note: #[deny(unused_attributes)] implied by #[deny(unused)] + = note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]` error: unused attribute --> $DIR/cfg-attr-empty-is-unused.rs:10:1 diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs index f1ab2f0f94..0c7e7cad03 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs @@ -1,7 +1,7 @@ // Test that cfg_attr doesn't emit any attributes when the // configuration variable is false. This mirrors `cfg-attr-multi-true.rs` -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr index ad5177dc9c..5e9adf1780 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr @@ -5,7 +5,7 @@ LL | #![cfg_attr(broken, no_core, no_std)] | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29639 - = help: add #![feature(no_core)] to the crate attributes to enable + = help: add `#![feature(no_core)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr index 675997758e..06b6715665 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr @@ -5,7 +5,7 @@ LL | #![cfg_attr(broken, no_std, no_core)] | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29639 - = help: add #![feature(no_core)] to the crate attributes to enable + = help: add `#![feature(no_core)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs index 86524e8bd2..645e4e71df 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -2,7 +2,7 @@ // This is done by emitting two attributes that cause new warnings, and then // triggering those warnings. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr index 64e9570773..f55671f6bb 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr @@ -4,7 +4,7 @@ warning: use of deprecated item 'MustUseDeprecated' LL | impl MustUseDeprecated { | ^^^^^^^^^^^^^^^^^ | - = note: #[warn(deprecated)] on by default + = note: `#[warn(deprecated)]` on by default warning: use of deprecated item 'MustUseDeprecated' --> $DIR/cfg-attr-multi-true.rs:19:5 diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs index 1ed2ddcda4..22dbac7667 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs @@ -1,6 +1,7 @@ macro_rules! foo { () => { - #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown + #[cfg_attr(all(), unknown)] + //~^ ERROR cannot find attribute macro `unknown` in this scope fn foo() {} } } diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index ca3e3d9eff..c7c52a2923 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,4 +1,4 @@ -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `unknown` in this scope --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 | LL | #[cfg_attr(all(), unknown)] @@ -6,10 +6,6 @@ LL | #[cfg_attr(all(), unknown)] ... LL | foo!(); | ------- in this macro invocation - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.stderr b/src/test/ui/conditional-compilation/cfg-generic-params.stderr index 40ca44d9db..1f9731fcfb 100644 --- a/src/test/ui/conditional-compilation/cfg-generic-params.stderr +++ b/src/test/ui/conditional-compilation/cfg-generic-params.stderr @@ -16,50 +16,50 @@ error: only lifetime parameters can be used in this context LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy; | ^ -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/cfg-generic-params.rs:19:29 | LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/cfg-generic-params.rs:21:29 | LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/cfg-generic-params.rs:24:34 | LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/cfg-generic-params.rs:28:40 | LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/cfg-generic-params.rs:32:43 | LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 8 previous errors diff --git a/src/test/ui/const-generics/apit-with-const-param.stderr b/src/test/ui/const-generics/apit-with-const-param.stderr index b3038ee648..c4ad38a571 100644 --- a/src/test/ui/const-generics/apit-with-const-param.stderr +++ b/src/test/ui/const-generics/apit-with-const-param.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs new file mode 100644 index 0000000000..db941a440e --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs @@ -0,0 +1,40 @@ +// check-pass + +pub fn yes_vec_partial_eq_array() -> impl PartialEq<[B; 32]> +where + A: PartialEq, +{ + Vec::::new() +} + +pub fn yes_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]> +where + A: PartialEq, +{ + Vec::::new() +} + +use std::collections::VecDeque; + +pub fn yes_vecdeque_partial_eq_array() -> impl PartialEq<[B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +fn main() {} diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs new file mode 100644 index 0000000000..19107e6bf1 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs @@ -0,0 +1,43 @@ +pub fn no_vec_partial_eq_array() -> impl PartialEq<[B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + Vec::::new() +} + +pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + Vec::::new() +} + +use std::collections::VecDeque; + +pub fn no_vecdeque_partial_eq_array() -> impl PartialEq<[B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + VecDeque::::new() +} + +fn main() {} diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr new file mode 100644 index 0000000000..5c37468130 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr @@ -0,0 +1,48 @@ +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/alloc-traits-no-impls-length-33.rs:1:43 + | +LL | pub fn no_vec_partial_eq_array() -> impl PartialEq<[B; 33]> + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::vec::Vec` + = note: the return type of a function must have a statically known size + +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/alloc-traits-no-impls-length-33.rs:9:51 + | +LL | pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::vec::Vec` + = note: the return type of a function must have a statically known size + +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/alloc-traits-no-impls-length-33.rs:19:48 + | +LL | pub fn no_vecdeque_partial_eq_array() -> impl PartialEq<[B; 33]> + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::collections::VecDeque` + = note: the return type of a function must have a statically known size + +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/alloc-traits-no-impls-length-33.rs:27:56 + | +LL | pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::collections::VecDeque` + = note: the return type of a function must have a statically known size + +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/alloc-traits-no-impls-length-33.rs:35:60 + | +LL | pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a mut [B; 33]>` for `std::collections::VecDeque` + = note: the return type of a function must have a statically known size + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs new file mode 100644 index 0000000000..3a23b9b583 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength + +use std::{convert::TryFrom, rc::Rc, sync::Arc}; + +pub fn no_box() { + let boxed_slice = Box::new([0; 33]) as Box<[i32]>; + let boxed_array = >::try_from(boxed_slice); + //~^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From>` is not satisfied + //~^^ ERROR the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom>` is not satisfied +} + +pub fn no_rc() { + let boxed_slice = Rc::new([0; 33]) as Rc<[i32]>; + let boxed_array = >::try_from(boxed_slice); + //~^ ERROR the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From>` is not satisfied + //~^^ ERROR the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom>` is not satisfied +} + +pub fn no_arc() { + let boxed_slice = Arc::new([0; 33]) as Arc<[i32]>; + let boxed_array = >::try_from(boxed_slice); + //~^ ERROR the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From>` is not satisfied + //~^^ ERROR the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom>` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr new file mode 100644 index 0000000000..193fb4c437 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/alloc-types-no-impls-length-33.stderr @@ -0,0 +1,75 @@ +error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::From>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:7:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::boxed::Box<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::From> + as std::convert::From<&str>> + as std::convert::From>> + as std::convert::From> + and 16 others + = note: required because of the requirements on the impl of `std::convert::Into>` for `std::boxed::Box<[i32]>` + = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::boxed::Box<[i32; 33]>` + +error[E0277]: the trait bound `std::boxed::Box<[i32; 33]>: std::convert::TryFrom>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:7:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::boxed::Box<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::TryFrom>> + +error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::From>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:14:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::rc::Rc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::From> + as std::convert::From>> + as std::convert::From<&[T]>> + as std::convert::From>> + and 8 others + = note: required because of the requirements on the impl of `std::convert::Into>` for `std::rc::Rc<[i32]>` + = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::rc::Rc<[i32; 33]>` + +error[E0277]: the trait bound `std::rc::Rc<[i32; 33]>: std::convert::TryFrom>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:14:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::rc::Rc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::TryFrom>> + +error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::From>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:21:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From>` is not implemented for `std::sync::Arc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::From> + as std::convert::From>> + as std::convert::From<&[T]>> + as std::convert::From>> + and 8 others + = note: required because of the requirements on the impl of `std::convert::Into>` for `std::sync::Arc<[i32]>` + = note: required because of the requirements on the impl of `std::convert::TryFrom>` for `std::sync::Arc<[i32; 33]>` + +error[E0277]: the trait bound `std::sync::Arc<[i32; 33]>: std::convert::TryFrom>` is not satisfied + --> $DIR/alloc-types-no-impls-length-33.rs:21:23 + | +LL | let boxed_array = >::try_from(boxed_slice); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::TryFrom>` is not implemented for `std::sync::Arc<[i32; 33]>` + | + = help: the following implementations were found: + as std::convert::TryFrom>> + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/array-impls/core-traits-impls-length-32.rs b/src/test/ui/const-generics/array-impls/core-traits-impls-length-32.rs new file mode 100644 index 0000000000..9998bb84ca --- /dev/null +++ b/src/test/ui/const-generics/array-impls/core-traits-impls-length-32.rs @@ -0,0 +1,66 @@ +// check-pass + +pub fn yes_as_ref() -> impl AsRef<[u8]> { + [0; 32] +} + +pub fn yes_as_mut() -> impl AsMut<[u8]> { + [0; 32] +} + +pub fn yes_borrow() -> impl std::borrow::Borrow<[u8]> { + [0; 32] +} + +pub fn yes_borrow_mut() -> impl std::borrow::BorrowMut<[u8]> { + [0; 32] +} + +pub fn yes_try_from_slice() -> impl std::convert::TryFrom<&'static [u8]> { + [0; 32] +} + +pub fn yes_ref_try_from_slice() -> impl std::convert::TryFrom<&'static [u8]> { + let a: &'static _ = &[0; 32]; + a +} + +pub fn yes_hash() -> impl std::hash::Hash { + [0; 32] +} + +pub fn yes_debug() -> impl std::fmt::Debug { + [0; 32] +} + +pub fn yes_ref_into_iterator() -> impl IntoIterator { + let a: &'static _ = &[0; 32]; + a +} + +pub fn yes_partial_eq() -> impl PartialEq<[u8; 32]> { + [0; 32] +} + +pub fn yes_partial_eq_slice() -> impl PartialEq<[u8]> { + [0; 32] +} + +pub fn yes_slice_partial_eq() -> impl PartialEq<[u8; 32]> { + let a: &'static _ = &[0; 32]; + &a[..] +} + +pub fn yes_eq() -> impl Eq { + [0; 32] +} + +pub fn yes_partial_ord() -> impl PartialOrd<[u8; 32]> { + [0; 32] +} + +pub fn yes_ord() -> impl Ord { + [0; 32] +} + +fn main() {} diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs new file mode 100644 index 0000000000..8397d204f3 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs @@ -0,0 +1,29 @@ +pub fn no_debug() { + println!("{:?}", [0_usize; 33]); + //~^ ERROR arrays only have std trait implementations for lengths 0..=32 +} + +pub fn no_hash() { + use std::collections::HashSet; + let mut set = HashSet::new(); + set.insert([0_usize; 33]); + //~^ ERROR arrays only have std trait implementations for lengths 0..=32 +} + +pub fn no_partial_eq() -> bool { + [0_usize; 33] == [1_usize; 33] + //~^ ERROR binary operation `==` cannot be applied to type `[usize; 33]` +} + +pub fn no_partial_ord() -> bool { + [0_usize; 33] < [1_usize; 33] + //~^ ERROR binary operation `<` cannot be applied to type `[usize; 33]` +} + +pub fn no_into_iterator() { + for _ in &[0_usize; 33] { + //~^ ERROR the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr new file mode 100644 index 0000000000..09652d99e8 --- /dev/null +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr @@ -0,0 +1,54 @@ +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/core-traits-no-impls-length-33.rs:2:22 + | +LL | println!("{:?}", [0_usize; 33]); + | ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]` + | + = note: required because of the requirements on the impl of `std::fmt::Debug` for `[usize; 33]` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/core-traits-no-impls-length-33.rs:9:9 + | +LL | set.insert([0_usize; 33]); + | ^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]` + +error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]` + --> $DIR/core-traits-no-impls-length-33.rs:14:19 + | +LL | [0_usize; 33] == [1_usize; 33] + | ------------- ^^ ------------- [usize; 33] + | | + | [usize; 33] + | + = note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]` + +error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]` + --> $DIR/core-traits-no-impls-length-33.rs:19:19 + | +LL | [0_usize; 33] < [1_usize; 33] + | ------------- ^ ------------- [usize; 33] + | | + | [usize; 33] + | + = note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]` + +error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied + --> $DIR/core-traits-no-impls-length-33.rs:24:14 + | +LL | for _ in &[0_usize; 33] { + | ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]` + | + = help: the following implementations were found: + <&'a [T; _] as std::iter::IntoIterator> + <&'a [T] as std::iter::IntoIterator> + <&'a mut [T; _] as std::iter::IntoIterator> + <&'a mut [T] as std::iter::IntoIterator> + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0369. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr b/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr index bd18264c16..5a5eaba0b1 100644 --- a/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr +++ b/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/broken-mir-1.stderr b/src/test/ui/const-generics/broken-mir-1.stderr index 55dc7fcb7c..51de98ad52 100644 --- a/src/test/ui/const-generics/broken-mir-1.stderr +++ b/src/test/ui/const-generics/broken-mir-1.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/broken-mir-2.rs b/src/test/ui/const-generics/broken-mir-2.rs index fb9a63ea73..d9a4411b4f 100644 --- a/src/test/ui/const-generics/broken-mir-2.rs +++ b/src/test/ui/const-generics/broken-mir-2.rs @@ -4,6 +4,7 @@ use std::fmt::Debug; #[derive(Debug)] -struct S([T; N]); //~ ERROR `[T; _]` doesn't implement `std::fmt::Debug` +struct S([T; N]); +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 fn main() {} diff --git a/src/test/ui/const-generics/broken-mir-2.stderr b/src/test/ui/const-generics/broken-mir-2.stderr index fb9b88bde0..b72bc6a46a 100644 --- a/src/test/ui/const-generics/broken-mir-2.stderr +++ b/src/test/ui/const-generics/broken-mir-2.stderr @@ -3,14 +3,16 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default -error[E0277]: `[T; _]` doesn't implement `std::fmt::Debug` +error[E0277]: arrays only have std trait implementations for lengths 0..=32 --> $DIR/broken-mir-2.rs:7:36 | LL | struct S([T; N]); - | ^^^^^^ `[T; _]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[T; _]` | - = help: the trait `std::fmt::Debug` is not implemented for `[T; _]` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `[T; _]` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; _]` = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/src/test/ui/const-generics/cannot-infer-const-args.stderr b/src/test/ui/const-generics/cannot-infer-const-args.stderr index 544cd05cdb..32adc63156 100644 --- a/src/test/ui/const-generics/cannot-infer-const-args.stderr +++ b/src/test/ui/const-generics/cannot-infer-const-args.stderr @@ -3,6 +3,8 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0282]: type annotations needed --> $DIR/cannot-infer-const-args.rs:9:5 diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs index f592e486be..cb40734c1d 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr index 52907bbb67..00a98e3ba9 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr b/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr index 955b319d70..0392488fce 100644 --- a/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr +++ b/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/concrete-const-impl-method.stderr b/src/test/ui/const-generics/concrete-const-impl-method.stderr index 3ce488c627..5e730b5643 100644 --- a/src/test/ui/const-generics/concrete-const-impl-method.stderr +++ b/src/test/ui/const-generics/concrete-const-impl-method.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/condition-in-trait-const-arg.stderr b/src/test/ui/const-generics/condition-in-trait-const-arg.stderr index 7c85651e70..c9e22ab390 100644 --- a/src/test/ui/const-generics/condition-in-trait-const-arg.stderr +++ b/src/test/ui/const-generics/condition-in-trait-const-arg.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/const-arg-in-fn.stderr b/src/test/ui/const-generics/const-arg-in-fn.stderr index e32b714b25..61ba9cdaf5 100644 --- a/src/test/ui/const-generics/const-arg-in-fn.stderr +++ b/src/test/ui/const-generics/const-arg-in-fn.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/const-expression-parameter.stderr b/src/test/ui/const-generics/const-expression-parameter.stderr index c255127c28..7311e27c28 100644 --- a/src/test/ui/const-generics/const-expression-parameter.stderr +++ b/src/test/ui/const-generics/const-expression-parameter.stderr @@ -9,6 +9,8 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-fn-with-const-param.stderr b/src/test/ui/const-generics/const-fn-with-const-param.stderr index c0cd7bace4..3437ed33d0 100644 --- a/src/test/ui/const-generics/const-fn-with-const-param.stderr +++ b/src/test/ui/const-generics/const-fn-with-const-param.stderr @@ -1,9 +1,3 @@ -warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/const-fn-with-const-param.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - error: const parameters are not permitted in `const fn` --> $DIR/const-fn-with-const-param.rs:4:1 | @@ -13,5 +7,13 @@ LL | | X LL | | } | |_^ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-fn-with-const-param.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-generic-array-wrapper.stderr b/src/test/ui/const-generics/const-generic-array-wrapper.stderr index f92e11d47e..5c7b6a70d3 100644 --- a/src/test/ui/const-generics/const-generic-array-wrapper.stderr +++ b/src/test/ui/const-generics/const-generic-array-wrapper.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs index 2c81681b85..5bdbfd8ff1 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.rs +++ b/src/test/ui/const-generics/const-param-before-other-params.rs @@ -1,5 +1,4 @@ #![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash fn bar(_: &'a ()) { //~^ ERROR lifetime parameters must be declared prior to const parameters diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr index 33f981d1eb..87622f7e50 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.stderr +++ b/src/test/ui/const-generics/const-param-before-other-params.stderr @@ -1,17 +1,11 @@ -warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/const-param-before-other-params.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - error: lifetime parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:4:21 + --> $DIR/const-param-before-other-params.rs:3:21 | LL | fn bar(_: &'a ()) { | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` error: type parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:8:21 + --> $DIR/const-param-before-other-params.rs:7:21 | LL | fn foo(_: &T) { | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.stderr b/src/test/ui/const-generics/const-param-from-outer-fn.stderr index f0b7562f62..90ca85cd62 100644 --- a/src/test/ui/const-generics/const-param-from-outer-fn.stderr +++ b/src/test/ui/const-generics/const-param-from-outer-fn.stderr @@ -1,9 +1,3 @@ -warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/const-param-from-outer-fn.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - error[E0401]: can't use generic parameters from outer function --> $DIR/const-param-from-outer-fn.rs:6:9 | @@ -14,6 +8,14 @@ LL | fn bar() -> u32 { LL | X | ^ use of generic parameter from outer function +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-param-from-outer-fn.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error: aborting due to previous error For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/const-generics/const-param-in-trait-ungated.stderr b/src/test/ui/const-generics/const-param-in-trait-ungated.stderr index 53bc973841..cfb1f8b581 100644 --- a/src/test/ui/const-generics/const-param-in-trait-ungated.stderr +++ b/src/test/ui/const-generics/const-param-in-trait-ungated.stderr @@ -5,7 +5,7 @@ LL | trait Trait {} | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44580 - = help: add #![feature(const_generics)] to the crate attributes to enable + = help: add `#![feature(const_generics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-param-in-trait.stderr b/src/test/ui/const-generics/const-param-in-trait.stderr index a48eefddaa..c45523d2fa 100644 --- a/src/test/ui/const-generics/const-param-in-trait.stderr +++ b/src/test/ui/const-generics/const-param-in-trait.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index e3adbcfe60..c659074a09 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -11,7 +11,7 @@ LL | struct B(PhantomData<[T; N]>); | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44580 - = help: add #![feature(const_generics)] to the crate attributes to enable + = help: add `#![feature(const_generics)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index c7dcbe1354..142efe45ac 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -1,14 +1,16 @@ +error[E0671]: const parameters cannot depend on type parameters + --> $DIR/const-param-type-depends-on-type-param.rs:9:34 + | +LL | pub struct Dependent([(); X]); + | ^ const parameter depends on type parameter + warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/const-param-type-depends-on-type-param.rs:1:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ - -error[E0671]: const parameters cannot depend on type parameters - --> $DIR/const-param-type-depends-on-type-param.rs:9:34 | -LL | pub struct Dependent([(); X]); - | ^ const parameter depends on type parameter + = note: `#[warn(incomplete_features)]` on by default error[E0392]: parameter `T` is never used --> $DIR/const-param-type-depends-on-type-param.rs:9:22 diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr index 190798d202..fddb06981b 100644 --- a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr +++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr @@ -3,6 +3,8 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error: const parameter `x` should have an upper case name --> $DIR/const-parameter-uppercase-lint.rs:6:15 diff --git a/src/test/ui/const-generics/const-types.stderr b/src/test/ui/const-generics/const-types.stderr index fbf5d53754..ca3d7810ca 100644 --- a/src/test/ui/const-generics/const-types.stderr +++ b/src/test/ui/const-generics/const-types.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/derive-debug-array-wrapper.rs b/src/test/ui/const-generics/derive-debug-array-wrapper.rs index a29cb90ebb..eee634c156 100644 --- a/src/test/ui/const-generics/derive-debug-array-wrapper.rs +++ b/src/test/ui/const-generics/derive-debug-array-wrapper.rs @@ -3,7 +3,7 @@ #[derive(Debug)] struct X { - a: [u32; N], //~ ERROR `[u32; _]` doesn't implement `std::fmt::Debug` + a: [u32; N], //~ ERROR arrays only have std trait implementations for lengths 0..=32 } fn main() {} diff --git a/src/test/ui/const-generics/derive-debug-array-wrapper.stderr b/src/test/ui/const-generics/derive-debug-array-wrapper.stderr index 5bab1d1b54..08a9037a20 100644 --- a/src/test/ui/const-generics/derive-debug-array-wrapper.stderr +++ b/src/test/ui/const-generics/derive-debug-array-wrapper.stderr @@ -3,14 +3,16 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default -error[E0277]: `[u32; _]` doesn't implement `std::fmt::Debug` +error[E0277]: arrays only have std trait implementations for lengths 0..=32 --> $DIR/derive-debug-array-wrapper.rs:6:5 | LL | a: [u32; N], - | ^^^^^^^^^^^ `[u32; _]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[u32; _]` | - = help: the trait `std::fmt::Debug` is not implemented for `[u32; _]` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `[u32; _]` = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[u32; _]` = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/src/test/ui/const-generics/fn-taking-const-generic-array.stderr b/src/test/ui/const-generics/fn-taking-const-generic-array.stderr index 3670412832..d7f8f1364e 100644 --- a/src/test/ui/const-generics/fn-taking-const-generic-array.stderr +++ b/src/test/ui/const-generics/fn-taking-const-generic-array.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/impl-const-generic-struct.stderr b/src/test/ui/const-generics/impl-const-generic-struct.stderr index d443e060a9..1eae9c4038 100644 --- a/src/test/ui/const-generics/impl-const-generic-struct.stderr +++ b/src/test/ui/const-generics/impl-const-generic-struct.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/incorrect-number-of-const-args.stderr b/src/test/ui/const-generics/incorrect-number-of-const-args.stderr index 11727733eb..6aa1c23176 100644 --- a/src/test/ui/const-generics/incorrect-number-of-const-args.stderr +++ b/src/test/ui/const-generics/incorrect-number-of-const-args.stderr @@ -3,6 +3,8 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0107]: wrong number of const arguments: expected 2, found 1 --> $DIR/incorrect-number-of-const-args.rs:9:5 diff --git a/src/test/ui/const-generics/issue-60263.stderr b/src/test/ui/const-generics/issue-60263.stderr index ab1b9e4a7c..fe7b6fdb19 100644 --- a/src/test/ui/const-generics/issue-60263.stderr +++ b/src/test/ui/const-generics/issue-60263.stderr @@ -5,7 +5,7 @@ LL | struct B; | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44580 - = help: add #![feature(const_generics)] to the crate attributes to enable + = help: add `#![feature(const_generics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/const-generics/issue-60818-struct-constructors.rs b/src/test/ui/const-generics/issue-60818-struct-constructors.rs index 0b4aeae7a4..b810efe738 100644 --- a/src/test/ui/const-generics/issue-60818-struct-constructors.rs +++ b/src/test/ui/const-generics/issue-60818-struct-constructors.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash diff --git a/src/test/ui/const-generics/issue-60818-struct-constructors.stderr b/src/test/ui/const-generics/issue-60818-struct-constructors.stderr index 4b8f50b9b0..3e0cd81688 100644 --- a/src/test/ui/const-generics/issue-60818-struct-constructors.stderr +++ b/src/test/ui/const-generics/issue-60818-struct-constructors.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/issue-61336-1.stderr b/src/test/ui/const-generics/issue-61336-1.stderr index 1a5bb9f763..949fa896d8 100644 --- a/src/test/ui/const-generics/issue-61336-1.stderr +++ b/src/test/ui/const-generics/issue-61336-1.stderr @@ -3,6 +3,8 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error: array lengths can't depend on generic parameters --> $DIR/issue-61336-1.rs:5:9 diff --git a/src/test/ui/const-generics/issue-61336-2.rs b/src/test/ui/const-generics/issue-61336-2.rs index 604c14ee12..7bb36f41b8 100644 --- a/src/test/ui/const-generics/issue-61336-2.rs +++ b/src/test/ui/const-generics/issue-61336-2.rs @@ -3,11 +3,12 @@ fn f(x: T) -> [T; N] { [x; {N}] + //~^ ERROR array lengths can't depend on generic parameters } fn g(x: T) -> [T; N] { [x; {N}] - //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277] + //~^ ERROR array lengths can't depend on generic parameters } fn main() { diff --git a/src/test/ui/const-generics/issue-61336-2.stderr b/src/test/ui/const-generics/issue-61336-2.stderr index a7135b62f8..63f86c81b1 100644 --- a/src/test/ui/const-generics/issue-61336-2.stderr +++ b/src/test/ui/const-generics/issue-61336-2.stderr @@ -3,16 +3,20 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/issue-61336-2.rs:9:5 +error: array lengths can't depend on generic parameters + --> $DIR/issue-61336-2.rs:5:9 | LL | [x; {N}] - | ^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | ^^^ + +error: array lengths can't depend on generic parameters + --> $DIR/issue-61336-2.rs:10:9 | - = help: consider adding a `where T: std::marker::Copy` bound - = note: the `Copy` trait is required because the repeated element will be copied +LL | [x; {N}] + | ^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issue-61336.rs b/src/test/ui/const-generics/issue-61336.rs index 95930371d5..edc012cbb3 100644 --- a/src/test/ui/const-generics/issue-61336.rs +++ b/src/test/ui/const-generics/issue-61336.rs @@ -3,11 +3,12 @@ fn f(x: T) -> [T; N] { [x; N] + //~^ ERROR array lengths can't depend on generic parameters } fn g(x: T) -> [T; N] { [x; N] - //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277] + //~^ ERROR array lengths can't depend on generic parameters } fn main() { diff --git a/src/test/ui/const-generics/issue-61336.stderr b/src/test/ui/const-generics/issue-61336.stderr index 9939a59983..f96e8e02d4 100644 --- a/src/test/ui/const-generics/issue-61336.stderr +++ b/src/test/ui/const-generics/issue-61336.stderr @@ -3,16 +3,20 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/issue-61336.rs:9:5 +error: array lengths can't depend on generic parameters + --> $DIR/issue-61336.rs:5:9 | LL | [x; N] - | ^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | ^ + +error: array lengths can't depend on generic parameters + --> $DIR/issue-61336.rs:10:9 | - = help: consider adding a `where T: std::marker::Copy` bound - = note: the `Copy` trait is required because the repeated element will be copied +LL | [x; N] + | ^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issue-61422.rs b/src/test/ui/const-generics/issue-61422.rs index 3ccf38e561..68e5a52e0a 100644 --- a/src/test/ui/const-generics/issue-61422.rs +++ b/src/test/ui/const-generics/issue-61422.rs @@ -7,6 +7,7 @@ use std::mem; fn foo() { let arr: [u8; SIZE] = unsafe { + #[allow(deprecated)] let mut array: [u8; SIZE] = mem::uninitialized(); array }; diff --git a/src/test/ui/const-generics/issue-61422.stderr b/src/test/ui/const-generics/issue-61422.stderr index 4cb76ec4fe..166bd3c2d3 100644 --- a/src/test/ui/const-generics/issue-61422.stderr +++ b/src/test/ui/const-generics/issue-61422.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/mut-ref-const-param-array.stderr b/src/test/ui/const-generics/mut-ref-const-param-array.stderr index 261d3578a1..bd7ae49193 100644 --- a/src/test/ui/const-generics/mut-ref-const-param-array.stderr +++ b/src/test/ui/const-generics/mut-ref-const-param-array.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.stderr b/src/test/ui/const-generics/struct-with-invalid-const-param.stderr index 64354752fd..dfa2557e9f 100644 --- a/src/test/ui/const-generics/struct-with-invalid-const-param.stderr +++ b/src/test/ui/const-generics/struct-with-invalid-const-param.stderr @@ -1,14 +1,16 @@ +error[E0573]: expected type, found const parameter `C` + --> $DIR/struct-with-invalid-const-param.rs:4:23 + | +LL | struct S(C); + | ^ help: a struct with a similar name exists: `S` + warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/struct-with-invalid-const-param.rs:1:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ - -error[E0573]: expected type, found const parameter `C` - --> $DIR/struct-with-invalid-const-param.rs:4:23 | -LL | struct S(C); - | ^ help: a struct with a similar name exists: `S` + = note: `#[warn(incomplete_features)]` on by default error: aborting due to previous error diff --git a/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.stderr b/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.stderr index 661bbd113b..156eddafff 100644 --- a/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.stderr +++ b/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr index eb2e446396..3c05a35444 100644 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr index eaa20bb789..f27fc53103 100644 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/const-generics/unused-const-param.stderr b/src/test/ui/const-generics/unused-const-param.stderr index 0e7acfb673..27f023eeef 100644 --- a/src/test/ui/const-generics/unused-const-param.stderr +++ b/src/test/ui/const-generics/unused-const-param.stderr @@ -3,4 +3,6 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr index 727ce9e57a..18a09fdda7 100644 --- a/src/test/ui/consts/array-literal-index-oob.stderr +++ b/src/test/ui/consts/array-literal-index-oob.stderr @@ -4,7 +4,7 @@ error: index out of bounds: the len is 3 but the index is 4 LL | &{[1, 2, 3][4]}; | ^^^^^^^^^^^^ | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: this expression will panic at runtime --> $DIR/array-literal-index-oob.rs:2:5 diff --git a/src/test/run-pass/consts/assoc-const.rs b/src/test/ui/consts/assoc-const.rs similarity index 100% rename from src/test/run-pass/consts/assoc-const.rs rename to src/test/ui/consts/assoc-const.rs diff --git a/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs similarity index 100% rename from src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs rename to src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs diff --git a/src/test/run-pass/consts/auxiliary/cci_borrow_lib.rs b/src/test/ui/consts/auxiliary/cci_borrow_lib.rs similarity index 100% rename from src/test/run-pass/consts/auxiliary/cci_borrow_lib.rs rename to src/test/ui/consts/auxiliary/cci_borrow_lib.rs diff --git a/src/test/run-pass/consts/auxiliary/cci_const.rs b/src/test/ui/consts/auxiliary/cci_const.rs similarity index 100% rename from src/test/run-pass/consts/auxiliary/cci_const.rs rename to src/test/ui/consts/auxiliary/cci_const.rs diff --git a/src/test/run-pass/consts/auxiliary/cci_const_block.rs b/src/test/ui/consts/auxiliary/cci_const_block.rs similarity index 100% rename from src/test/run-pass/consts/auxiliary/cci_const_block.rs rename to src/test/ui/consts/auxiliary/cci_const_block.rs diff --git a/src/test/run-pass/consts/bswap-const.rs b/src/test/ui/consts/bswap-const.rs similarity index 100% rename from src/test/run-pass/consts/bswap-const.rs rename to src/test/ui/consts/bswap-const.rs diff --git a/src/test/run-pass/consts/chained-constants-stackoverflow.rs b/src/test/ui/consts/chained-constants-stackoverflow.rs similarity index 100% rename from src/test/run-pass/consts/chained-constants-stackoverflow.rs rename to src/test/ui/consts/chained-constants-stackoverflow.rs diff --git a/src/test/run-pass/consts/const-adt-align-mismatch.rs b/src/test/ui/consts/const-adt-align-mismatch.rs similarity index 100% rename from src/test/run-pass/consts/const-adt-align-mismatch.rs rename to src/test/ui/consts/const-adt-align-mismatch.rs diff --git a/src/test/run-pass/consts/const-autoderef.rs b/src/test/ui/consts/const-autoderef.rs similarity index 100% rename from src/test/run-pass/consts/const-autoderef.rs rename to src/test/ui/consts/const-autoderef.rs diff --git a/src/test/run-pass/consts/const-big-enum.rs b/src/test/ui/consts/const-big-enum.rs similarity index 100% rename from src/test/run-pass/consts/const-big-enum.rs rename to src/test/ui/consts/const-big-enum.rs diff --git a/src/test/run-pass/consts/const-binops.rs b/src/test/ui/consts/const-binops.rs similarity index 100% rename from src/test/run-pass/consts/const-binops.rs rename to src/test/ui/consts/const-binops.rs diff --git a/src/test/run-pass/consts/const-bitshift-rhs-inference.rs b/src/test/ui/consts/const-bitshift-rhs-inference.rs similarity index 100% rename from src/test/run-pass/consts/const-bitshift-rhs-inference.rs rename to src/test/ui/consts/const-bitshift-rhs-inference.rs diff --git a/src/test/run-pass/consts/const-block-cross-crate-fn.rs b/src/test/ui/consts/const-block-cross-crate-fn.rs similarity index 100% rename from src/test/run-pass/consts/const-block-cross-crate-fn.rs rename to src/test/ui/consts/const-block-cross-crate-fn.rs diff --git a/src/test/run-pass/consts/const-block-item-macro-codegen.rs b/src/test/ui/consts/const-block-item-macro-codegen.rs similarity index 100% rename from src/test/run-pass/consts/const-block-item-macro-codegen.rs rename to src/test/ui/consts/const-block-item-macro-codegen.rs diff --git a/src/test/run-pass/consts/const-block-item.rs b/src/test/ui/consts/const-block-item.rs similarity index 100% rename from src/test/run-pass/consts/const-block-item.rs rename to src/test/ui/consts/const-block-item.rs diff --git a/src/test/run-pass/consts/const-block-non-item-statement-3.rs b/src/test/ui/consts/const-block-non-item-statement-3.rs similarity index 100% rename from src/test/run-pass/consts/const-block-non-item-statement-3.rs rename to src/test/ui/consts/const-block-non-item-statement-3.rs diff --git a/src/test/run-pass/consts/const-block-non-item-statement.rs b/src/test/ui/consts/const-block-non-item-statement-rpass.rs similarity index 100% rename from src/test/run-pass/consts/const-block-non-item-statement.rs rename to src/test/ui/consts/const-block-non-item-statement-rpass.rs diff --git a/src/test/ui/consts/const-block-non-item-statement.rs b/src/test/ui/consts/const-block-non-item-statement.rs index 5ecf9a0498..9aec855269 100644 --- a/src/test/ui/consts/const-block-non-item-statement.rs +++ b/src/test/ui/consts/const-block-non-item-statement.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Foo { Bar = { let x = 1; 3 } diff --git a/src/test/run-pass/consts/const-block.rs b/src/test/ui/consts/const-block.rs similarity index 100% rename from src/test/run-pass/consts/const-block.rs rename to src/test/ui/consts/const-block.rs diff --git a/src/test/run-pass/consts/const-bound.rs b/src/test/ui/consts/const-bound.rs similarity index 100% rename from src/test/run-pass/consts/const-bound.rs rename to src/test/ui/consts/const-bound.rs diff --git a/src/test/run-pass/consts/const-byte-str-cast.rs b/src/test/ui/consts/const-byte-str-cast.rs similarity index 100% rename from src/test/run-pass/consts/const-byte-str-cast.rs rename to src/test/ui/consts/const-byte-str-cast.rs diff --git a/src/test/run-pass/consts/const-cast-ptr-int.rs b/src/test/ui/consts/const-cast-ptr-int.rs similarity index 100% rename from src/test/run-pass/consts/const-cast-ptr-int.rs rename to src/test/ui/consts/const-cast-ptr-int.rs diff --git a/src/test/run-pass/consts/const-cast.rs b/src/test/ui/consts/const-cast.rs similarity index 100% rename from src/test/run-pass/consts/const-cast.rs rename to src/test/ui/consts/const-cast.rs diff --git a/src/test/run-pass/consts/const-const.rs b/src/test/ui/consts/const-const.rs similarity index 100% rename from src/test/run-pass/consts/const-const.rs rename to src/test/ui/consts/const-const.rs diff --git a/src/test/run-pass/consts/const-contents.rs b/src/test/ui/consts/const-contents.rs similarity index 100% rename from src/test/run-pass/consts/const-contents.rs rename to src/test/ui/consts/const-contents.rs diff --git a/src/test/run-pass/consts/const-cross-crate-const.rs b/src/test/ui/consts/const-cross-crate-const.rs similarity index 100% rename from src/test/run-pass/consts/const-cross-crate-const.rs rename to src/test/ui/consts/const-cross-crate-const.rs diff --git a/src/test/run-pass/consts/const-cross-crate-extern.rs b/src/test/ui/consts/const-cross-crate-extern.rs similarity index 100% rename from src/test/run-pass/consts/const-cross-crate-extern.rs rename to src/test/ui/consts/const-cross-crate-extern.rs diff --git a/src/test/ui/consts/const-deref-ptr.stderr b/src/test/ui/consts/const-deref-ptr.stderr index 23ac3b85ee..6bfb9ee73e 100644 --- a/src/test/ui/consts/const-deref-ptr.stderr +++ b/src/test/ui/consts/const-deref-ptr.stderr @@ -5,7 +5,7 @@ LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51911 - = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/consts/const-deref.rs b/src/test/ui/consts/const-deref.rs similarity index 100% rename from src/test/run-pass/consts/const-deref.rs rename to src/test/ui/consts/const-deref.rs diff --git a/src/test/run-pass/consts/const-endianess.rs b/src/test/ui/consts/const-endianess.rs similarity index 100% rename from src/test/run-pass/consts/const-endianess.rs rename to src/test/ui/consts/const-endianess.rs diff --git a/src/test/run-pass/consts/const-enum-byref-self.rs b/src/test/ui/consts/const-enum-byref-self.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-byref-self.rs rename to src/test/ui/consts/const-enum-byref-self.rs diff --git a/src/test/run-pass/consts/const-enum-byref.rs b/src/test/ui/consts/const-enum-byref.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-byref.rs rename to src/test/ui/consts/const-enum-byref.rs diff --git a/src/test/run-pass/consts/const-enum-cast.rs b/src/test/ui/consts/const-enum-cast.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-cast.rs rename to src/test/ui/consts/const-enum-cast.rs diff --git a/src/test/run-pass/consts/const-enum-ptr.rs b/src/test/ui/consts/const-enum-ptr.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-ptr.rs rename to src/test/ui/consts/const-enum-ptr.rs diff --git a/src/test/run-pass/consts/const-enum-struct.rs b/src/test/ui/consts/const-enum-struct.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-struct.rs rename to src/test/ui/consts/const-enum-struct.rs diff --git a/src/test/run-pass/consts/const-enum-struct2.rs b/src/test/ui/consts/const-enum-struct2.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-struct2.rs rename to src/test/ui/consts/const-enum-struct2.rs diff --git a/src/test/run-pass/consts/const-enum-structlike.rs b/src/test/ui/consts/const-enum-structlike.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-structlike.rs rename to src/test/ui/consts/const-enum-structlike.rs diff --git a/src/test/run-pass/consts/const-enum-tuple.rs b/src/test/ui/consts/const-enum-tuple.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-tuple.rs rename to src/test/ui/consts/const-enum-tuple.rs diff --git a/src/test/run-pass/consts/const-enum-tuple2.rs b/src/test/ui/consts/const-enum-tuple2.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-tuple2.rs rename to src/test/ui/consts/const-enum-tuple2.rs diff --git a/src/test/run-pass/consts/const-enum-tuplestruct.rs b/src/test/ui/consts/const-enum-tuplestruct.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-tuplestruct.rs rename to src/test/ui/consts/const-enum-tuplestruct.rs diff --git a/src/test/run-pass/consts/const-enum-tuplestruct2.rs b/src/test/ui/consts/const-enum-tuplestruct2.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-tuplestruct2.rs rename to src/test/ui/consts/const-enum-tuplestruct2.rs diff --git a/src/test/run-pass/consts/const-enum-vec-index.rs b/src/test/ui/consts/const-enum-vec-index.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-vec-index.rs rename to src/test/ui/consts/const-enum-vec-index.rs diff --git a/src/test/run-pass/consts/const-enum-vec-ptr.rs b/src/test/ui/consts/const-enum-vec-ptr.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-vec-ptr.rs rename to src/test/ui/consts/const-enum-vec-ptr.rs diff --git a/src/test/run-pass/consts/const-enum-vector.rs b/src/test/ui/consts/const-enum-vector.rs similarity index 100% rename from src/test/run-pass/consts/const-enum-vector.rs rename to src/test/ui/consts/const-enum-vector.rs diff --git a/src/test/run-pass/consts/const-err.rs b/src/test/ui/consts/const-err-rpass.rs similarity index 100% rename from src/test/run-pass/consts/const-err.rs rename to src/test/ui/consts/const-err-rpass.rs diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr index 284b06984a..73aca91153 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -14,7 +14,7 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_ | | | a raw memory access tried to access part of a pointer value as raw bytes | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:30:45 diff --git a/src/test/ui/consts/const-eval/const_let.rs b/src/test/ui/consts/const-eval/const_let.rs index 63321b9120..18692dbced 100644 --- a/src/test/ui/consts/const-eval/const_let.rs +++ b/src/test/ui/consts/const-eval/const_let.rs @@ -9,10 +9,21 @@ impl Drop for FakeNeedsDrop { // ok const X: FakeNeedsDrop = { let x = FakeNeedsDrop; x }; +// ok (used to incorrectly error, see #62273) +const X2: FakeNeedsDrop = { let x; x = FakeNeedsDrop; x }; + // error const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; -//~^ ERROR constant contains unimplemented expression type +//~^ ERROR destructors cannot be evaluated at compile-time + +// error +const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x }; +//~^ ERROR destructors cannot be evaluated at compile-time // error const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; -//~^ ERROR constant contains unimplemented expression type +//~^ ERROR destructors cannot be evaluated at compile-time + +// error +const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); }; +//~^ ERROR destructors cannot be evaluated at compile-time diff --git a/src/test/ui/consts/const-eval/const_let.stderr b/src/test/ui/consts/const-eval/const_let.stderr index 00de97e6fb..0a6a222ae2 100644 --- a/src/test/ui/consts/const-eval/const_let.stderr +++ b/src/test/ui/consts/const-eval/const_let.stderr @@ -1,15 +1,26 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:13:55 +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/const_let.rs:16:32 | LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; - | ^ + | ^^^^^ constants cannot evaluate destructors -error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:17:35 +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/const_let.rs:20:33 + | +LL | const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x }; + | ^^^^^ constants cannot evaluate destructors + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/const_let.rs:24:21 | LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; - | ^ + | ^^^^^ constants cannot evaluate destructors + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/const_let.rs:28:22 + | +LL | const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); }; + | ^^^^^ constants cannot evaluate destructors -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index 12c7e3d34a..8a51d8aa88 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -6,7 +6,7 @@ LL | pub const Z: () = panic!("cheese"); | | | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:4:19 | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: any use of this value will cause an error diff --git a/src/test/ui/consts/const-eval/const_panic_libcore.stderr b/src/test/ui/consts/const-eval/const_panic_libcore.stderr index 9dddac49c9..e76446f101 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore.stderr @@ -6,7 +6,7 @@ LL | const Z: () = panic!("cheese"); | | | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore.rs:5:15 | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: any use of this value will cause an error diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr index df04a03681..22d173ad0c 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr @@ -6,7 +6,7 @@ LL | const Z: () = panic!("cheese"); | | | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:9:15 | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: any use of this value will cause an error diff --git a/src/test/ui/consts/const-eval/const_prop_errors.rs b/src/test/ui/consts/const-eval/const_prop_errors.rs index 51b50b2e75..48cfea82bd 100644 --- a/src/test/ui/consts/const-eval/const_prop_errors.rs +++ b/src/test/ui/consts/const-eval/const_prop_errors.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Foo { fn foo(self) -> u32; diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs index 44266682a5..9be1374f85 100644 --- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs +++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs @@ -4,8 +4,8 @@ fn main() {} // unconst and bad, will thus error in miri const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this -// unconst and fine -const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; +// unconst and bad, will thus error in miri +const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR any use of this // unconst and fine const Y: usize = unsafe { 42usize as *const i32 as usize + 1 }; // unconst and bad, will thus error in miri diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr index 0d4c0b9887..2cba833a74 100644 --- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr +++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr @@ -6,15 +6,23 @@ LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; | | | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default + +error: any use of this value will cause an error + --> $DIR/const_raw_ptr_ops.rs:8:27 + | +LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:12:28 | LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; - | ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^------- | | - | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants + | "pointer-to-integer cast" needs an rfc before being allowed inside constants error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:16:26 @@ -32,5 +40,5 @@ LL | const Z3: i32 = unsafe { *(44 as *const i32) }; | | | a memory access tried to interpret some bytes as a pointer -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/test/ui/consts/const-eval/const_signed_pat.rs b/src/test/ui/consts/const-eval/const_signed_pat.rs index cb4fb46bd0..d209e60448 100644 --- a/src/test/ui/consts/const-eval/const_signed_pat.rs +++ b/src/test/ui/consts/const-eval/const_signed_pat.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { const MIN: i8 = -5; diff --git a/src/test/ui/consts/const-eval/double_check.rs b/src/test/ui/consts/const-eval/double_check.rs index 9ac511767c..2cf6a5494d 100644 --- a/src/test/ui/consts/const-eval/double_check.rs +++ b/src/test/ui/consts/const-eval/double_check.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Foo { A = 5, diff --git a/src/test/ui/consts/const-eval/double_promotion.rs b/src/test/ui/consts/const-eval/double_promotion.rs index 0e75ea8e66..a9a3f071bf 100644 --- a/src/test/ui/consts/const-eval/double_promotion.rs +++ b/src/test/ui/consts/const-eval/double_promotion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_fn, rustc_attrs)] diff --git a/src/test/ui/consts/const-eval/duration_conversion.rs b/src/test/ui/consts/const-eval/duration_conversion.rs index 854f97d475..029d4e5e37 100644 --- a/src/test/ui/consts/const-eval/duration_conversion.rs +++ b/src/test/ui/consts/const-eval/duration_conversion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::time::Duration; diff --git a/src/test/ui/consts/const-eval/extern_fat_pointer.rs b/src/test/ui/consts/const-eval/extern_fat_pointer.rs index f8e6fd09c7..e2b3bc83c3 100644 --- a/src/test/ui/consts/const-eval/extern_fat_pointer.rs +++ b/src/test/ui/consts/const-eval/extern_fat_pointer.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_types)] diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr b/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr index 069a8bfd4e..5bf43cb8b6 100644 --- a/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr +++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr @@ -5,7 +5,7 @@ LL | Foo { u }.i | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51909 - = help: add #![feature(const_fn_union)] to the crate attributes to enable + = help: add `#![feature(const_fn_union)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr index 5d3e88e4e5..ac0ff7025d 100644 --- a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr +++ b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr @@ -5,7 +5,7 @@ LL | const Z: () = panic!("cheese"); | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 - = help: add #![feature(const_panic)] to the crate attributes to enable + = help: add `#![feature(const_panic)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0658]: panicking in constants is unstable @@ -15,7 +15,7 @@ LL | const X: () = unimplemented!(); | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 - = help: add #![feature(const_panic)] to the crate attributes to enable + = help: add `#![feature(const_panic)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0658]: panicking in constants is unstable @@ -25,7 +25,7 @@ LL | const Y: () = unreachable!(); | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 - = help: add #![feature(const_panic)] to the crate attributes to enable + = help: add `#![feature(const_panic)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs b/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs index 2ad1a633d1..ce0e11f29f 100644 --- a/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs +++ b/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Nullable { const NULL: Self; diff --git a/src/test/ui/consts/const-eval/ice-packed.rs b/src/test/ui/consts/const-eval/ice-packed.rs index b9fe4eadd4..250bf954e9 100644 --- a/src/test/ui/consts/const-eval/ice-packed.rs +++ b/src/test/ui/consts/const-eval/ice-packed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(Copy, Clone, PartialEq, Eq)] #[repr(packed)] pub struct Num(u64); diff --git a/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr b/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr index ac045f29b1..f330f9caaa 100644 --- a/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr +++ b/src/test/ui/consts/const-eval/index_out_of_bounds_propagated.stderr @@ -4,7 +4,7 @@ error: index out of bounds: the len is 1 but the index is 1 LL | array[1]; | ^^^^^^^^ | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index a2a45af7cb..8fa5b0a961 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -4,7 +4,9 @@ fn main() { let _ = [(); { //~^ WARNING Constant evaluating a complex constant, this might take some time let mut n = 113383; // #20 in https://oeis.org/A006884 - while n != 0 { //~ ERROR constant contains unimplemented expression type + while n != 0 { + //~^ ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 3a7da9ff2c..68e7fdb125 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,7 +1,15 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/infinite_loop.rs:7:15 + | +LL | while n != 0 { + | ^^^^^^ + error[E0019]: constant contains unimplemented expression type --> $DIR/infinite_loop.rs:7:9 | LL | / while n != 0 { +LL | | +LL | | LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; LL | | LL | | } @@ -21,12 +29,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:8:20 + --> $DIR/infinite_loop.rs:10:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0019, E0080. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/issue-47971.rs b/src/test/ui/consts/const-eval/issue-47971.rs index 9d7b05cd23..9de150bd05 100644 --- a/src/test/ui/consts/const-eval/issue-47971.rs +++ b/src/test/ui/consts/const-eval/issue-47971.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(pub &'static u32, pub u32); diff --git a/src/test/ui/consts/const-eval/issue-49296.stderr b/src/test/ui/consts/const-eval/issue-49296.stderr index 5a59a8b2df..7a4bba8daa 100644 --- a/src/test/ui/consts/const-eval/issue-49296.stderr +++ b/src/test/ui/consts/const-eval/issue-49296.stderr @@ -6,7 +6,7 @@ LL | const X: u64 = *wat(42); | | | dangling pointer was dereferenced | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/issue-50706.rs b/src/test/ui/consts/const-eval/issue-50706.rs index cb45b86cd7..bf69bc28da 100644 --- a/src/test/ui/consts/const-eval/issue-50706.rs +++ b/src/test/ui/consts/const-eval/issue-50706.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Stats; diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index da560046c5..d68f72d36e 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -6,7 +6,7 @@ LL | const BAR: usize = [5, 6, 7][T::BOO]; | | | index out of bounds: the len is 3 but the index is 42 | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant expression failed --> $DIR/issue-50814-2.rs:16:5 diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index bc9443b26f..707dfee7cd 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -6,7 +6,7 @@ LL | const MAX: u8 = A::MAX + B::MAX; | | | attempt to add with overflow | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant expression failed --> $DIR/issue-50814.rs:17:5 diff --git a/src/test/ui/consts/const-eval/issue-51300.rs b/src/test/ui/consts/const-eval/issue-51300.rs index 72a6072e4b..4753bf0f7b 100644 --- a/src/test/ui/consts/const-eval/issue-51300.rs +++ b/src/test/ui/consts/const-eval/issue-51300.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // https://github.com/rust-lang/rust/issues/51300 #[derive(PartialEq, Eq, Clone, Copy)] diff --git a/src/test/ui/consts/const-eval/issue-52442.rs b/src/test/ui/consts/const-eval/issue-52442.rs index fadcde528d..ea24578c7d 100644 --- a/src/test/ui/consts/const-eval/issue-52442.rs +++ b/src/test/ui/consts/const-eval/issue-52442.rs @@ -1,4 +1,5 @@ fn main() { - [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type - //~^ ERROR it is undefined behavior to use this value + [(); { &loop { break } as *const _ as usize } ]; + //~^ ERROR casting pointers to integers in constants is unstable + //~| ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/issue-52442.stderr b/src/test/ui/consts/const-eval/issue-52442.stderr index e9afec5766..5bd4979bdb 100644 --- a/src/test/ui/consts/const-eval/issue-52442.stderr +++ b/src/test/ui/consts/const-eval/issue-52442.stderr @@ -1,18 +1,19 @@ -error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52442.rs:2:14 +error[E0658]: casting pointers to integers in constants is unstable + --> $DIR/issue-52442.rs:2:13 | LL | [(); { &loop { break } as *const _ as usize } ]; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/51910 + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable -error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-52442.rs:2:11 +error[E0080]: evaluation of constant value failed + --> $DIR/issue-52442.rs:2:13 | LL | [(); { &loop { break } as *const _ as usize } ]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 2 previous errors -Some errors have detailed explanations: E0019, E0080. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0080, E0658. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index aafdd5fe61..b42249e57f 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -3,7 +3,9 @@ fn main() { //~^ WARNING Constant evaluating a complex constant, this might take some time let mut x = &0; let mut n = 0; - while n < 5 { //~ ERROR constant contains unimplemented expression type + while n < 5 { + //~^ ERROR constant contains unimplemented expression type + //~| ERROR constant contains unimplemented expression type n = (n + 1) % 5; //~ ERROR evaluation of constant value failed x = &0; // Materialize a new AllocId } diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 7a52a38d76..1e83cbcff2 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -1,7 +1,15 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/issue-52475.rs:6:15 + | +LL | while n < 5 { + | ^^^^^ + error[E0019]: constant contains unimplemented expression type --> $DIR/issue-52475.rs:6:9 | LL | / while n < 5 { +LL | | +LL | | LL | | n = (n + 1) % 5; LL | | x = &0; // Materialize a new AllocId LL | | } @@ -21,12 +29,12 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:7:17 + --> $DIR/issue-52475.rs:9:17 | LL | n = (n + 1) % 5; | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0019, E0080. For more information about an error, try `rustc --explain E0019`. diff --git a/src/test/ui/consts/const-eval/issue-53157.rs b/src/test/ui/consts/const-eval/issue-53157.rs index b995860997..ac0940b33e 100644 --- a/src/test/ui/consts/const-eval/issue-53157.rs +++ b/src/test/ui/consts/const-eval/issue-53157.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! m { () => {{ diff --git a/src/test/ui/consts/const-eval/issue-53401.rs b/src/test/ui/consts/const-eval/issue-53401.rs index e8ac5a9088..d300e0b512 100644 --- a/src/test/ui/consts/const-eval/issue-53401.rs +++ b/src/test/ui/consts/const-eval/issue-53401.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub const STATIC_TRAIT: &dyn Test = &(); diff --git a/src/test/ui/consts/const-eval/issue-55541.rs b/src/test/ui/consts/const-eval/issue-55541.rs index 611fb89341..d04570c67f 100644 --- a/src/test/ui/consts/const-eval/issue-55541.rs +++ b/src/test/ui/consts/const-eval/issue-55541.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that we can handle newtypes wrapping extern types diff --git a/src/test/ui/consts/const-eval/issue-62272.rs b/src/test/ui/consts/const-eval/issue-62272.rs new file mode 100644 index 0000000000..ad8589c737 --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-62272.rs @@ -0,0 +1,9 @@ +// run-pass + +// Tests that `loop`s unconditionally-broken-from are allowed in constants. + +const FOO: () = loop { break; }; + +fn main() { + [FOO; { let x; loop { x = 5; break; } x }]; +} diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 50757afaf5..5b89b0262a 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -5,11 +5,9 @@ fn main() { let _: [u8; 0] = [4; { match &1 as *const i32 as usize { //~^ ERROR casting pointers to integers in constants - //~| NOTE for more information, see //~| ERROR constant contains unimplemented expression type - 0 => 42, //~ ERROR constant contains unimplemented expression type - //~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed //~| ERROR evaluation of constant value failed + 0 => 42, //~ ERROR constant contains unimplemented expression type n => n, } }]; diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index 167d5ad8d6..3d34ac4266 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -5,7 +5,7 @@ LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51910 - = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error[E0019]: constant contains unimplemented expression type --> $DIR/match-test-ptr-null.rs:6:15 @@ -20,10 +20,10 @@ LL | 0 => 42, | ^ error[E0080]: evaluation of constant value failed - --> $DIR/match-test-ptr-null.rs:10:13 + --> $DIR/match-test-ptr-null.rs:6:15 | -LL | 0 => 42, - | ^ "pointer arithmetic or comparison" needs an rfc before being allowed inside constants +LL | match &1 as *const i32 as usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs b/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs index 0d14cf0f6d..cea367528c 100644 --- a/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs +++ b/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // if `X` were used instead of `x`, `X - 10` would result in a lint. // This file should never produce a lint, no matter how the const diff --git a/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs b/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs index 34f61ed5a3..ca75d65a39 100644 --- a/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs +++ b/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub fn main() { let y: &'static mut [u8; 0] = &mut []; diff --git a/src/test/ui/consts/const-eval/pub_const_err.rs b/src/test/ui/consts/const-eval/pub_const_err.rs index d882dad295..4ff140fee7 100644 --- a/src/test/ui/consts/const-eval/pub_const_err.rs +++ b/src/test/ui/consts/const-eval/pub_const_err.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(const_err)] #![crate_type = "lib"] diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.rs b/src/test/ui/consts/const-eval/pub_const_err_bin.rs index dee09b70d9..7f1586336e 100644 --- a/src/test/ui/consts/const-eval/pub_const_err_bin.rs +++ b/src/test/ui/consts/const-eval/pub_const_err_bin.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(const_err)] pub const Z: u32 = 0 - 1; diff --git a/src/test/ui/consts/const-eval/simple_with_undef.rs b/src/test/ui/consts/const-eval/simple_with_undef.rs index 61398f3a37..8a9f3fe974 100644 --- a/src/test/ui/consts/const-eval/simple_with_undef.rs +++ b/src/test/ui/consts/const-eval/simple_with_undef.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) const PARSE_BOOL: Option<&'static str> = None; static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42); diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index fe8675d326..d4b2220695 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -1,5 +1,10 @@ #![allow(const_err)] // make sure we cannot allow away the errors tested here + +#[repr(transparent)] +#[derive(Copy, Clone)] +struct Wrap(T); + #[repr(usize)] #[derive(Copy, Clone)] enum Enum { @@ -7,11 +12,20 @@ enum Enum { } union TransmuteEnum { in1: &'static u8, + in2: usize, out1: Enum, + out2: Wrap, } -// A pointer is guaranteed non-null -const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; +const GOOD_ENUM: Enum = unsafe { TransmuteEnum { in2: 0 }.out1 }; + +const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 }; +//~^ ERROR is undefined behavior + +const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; +//~^ ERROR is undefined behavior + +const BAD_ENUM_WRAPPED: Wrap = unsafe { TransmuteEnum { in1: &1 }.out2 }; //~^ ERROR is undefined behavior // (Potentially) invalid enum discriminant @@ -20,9 +34,7 @@ const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; enum Enum2 { A = 2, } -#[repr(transparent)] -#[derive(Copy, Clone)] -struct Wrap(T); + union TransmuteEnum2 { in1: usize, in2: &'static u8, @@ -33,17 +45,17 @@ union TransmuteEnum2 { } const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 }; //~^ ERROR is undefined behavior -const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 }; +const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 }; //~^ ERROR is undefined behavior -const BAD_ENUM4: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; +const BAD_ENUM2_WRAPPED: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; //~^ ERROR is undefined behavior // Undef enum discriminant. -const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; +const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; //~^ ERROR is undefined behavior // Pointer value in an enum with a niche that is not just 0. -const BAD_ENUM_PTR: Option = unsafe { TransmuteEnum2 { in2: &0 }.out3 }; +const BAD_ENUM2_OPTION_PTR: Option = unsafe { TransmuteEnum2 { in2: &0 }.out3 }; //~^ ERROR is undefined behavior // Invalid enum field content (mostly to test printing of paths for enum tuple @@ -53,7 +65,7 @@ union TransmuteChar { b: char, } // Need to create something which does not clash with enum layout optimizations. -const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b })); +const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b })); //~^ ERROR is undefined behavior fn main() { diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index 2bf4cf9bfd..8ecb1aabdd 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -1,13 +1,29 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:14:1 + --> $DIR/ub-enum.rs:22:1 | -LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant +LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:34:1 + --> $DIR/ub-enum.rs:25:1 + | +LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:28:1 + | +LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { TransmuteEnum { in1: &1 }.out2 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:46:1 | LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant @@ -15,45 +31,45 @@ LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:36:1 + --> $DIR/ub-enum.rs:48:1 | -LL | const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant +LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:38:1 + --> $DIR/ub-enum.rs:50:1 | -LL | const BAD_ENUM4: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be in the range 2..=2 +LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 2 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:42:1 + --> $DIR/ub-enum.rs:54:1 | -LL | const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant +LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:46:1 + --> $DIR/ub-enum.rs:58:1 | -LL | const BAD_ENUM_PTR: Option = unsafe { TransmuteEnum2 { in2: &0 }.out3 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant +LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { TransmuteEnum2 { in2: &0 }.out3 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:56:1 + --> $DIR/ub-enum.rs:68:1 | -LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b })); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at ..0.1, but expected something less or equal to 1114111 +LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b })); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at ..0.1, but expected something less or equal to 1114111 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs index 3e0b0948ef..bcbb4358ae 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.rs +++ b/src/test/ui/consts/const-eval/ub-nonnull.rs @@ -5,9 +5,19 @@ use std::mem; use std::ptr::NonNull; use std::num::{NonZeroU8, NonZeroUsize}; +const NON_NULL: NonNull = unsafe { mem::transmute(1usize) }; +const NON_NULL_PTR: NonNull = unsafe { mem::transmute(&1) }; + const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; //~^ ERROR it is undefined behavior to use this value +const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { +//~^ ERROR it is undefined behavior to use this value + let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle + let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic + mem::transmute(out_of_bounds_ptr) +} }; + const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; //~^ ERROR it is undefined behavior to use this value const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index 6230712ad6..2f9423fed3 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:8:1 + --> $DIR/ub-nonnull.rs:11:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 @@ -7,7 +7,20 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:11:1 + --> $DIR/ub-nonnull.rs:14:1 + | +LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { +LL | | +LL | | let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle +LL | | let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic +LL | | mem::transmute(out_of_bounds_ptr) +LL | | } }; + | |____^ type validation failed: encountered a potentially NULL pointer, but expected something that cannot possibly fail to be greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:21:1 | LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 @@ -15,7 +28,7 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:13:1 + --> $DIR/ub-nonnull.rs:23:1 | LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 @@ -23,7 +36,7 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:20:1 + --> $DIR/ub-nonnull.rs:30:1 | LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1 @@ -31,7 +44,7 @@ LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:28:1 + --> $DIR/ub-nonnull.rs:38:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 @@ -39,13 +52,13 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:34:1 + --> $DIR/ub-nonnull.rs:44:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref.stderr b/src/test/ui/consts/const-eval/ub-ref.stderr index 33535c235e..f1702955ed 100644 --- a/src/test/ui/consts/const-eval/ub-ref.stderr +++ b/src/test/ui/consts/const-eval/ub-ref.stderr @@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref.rs:20:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered integer pointer in non-ZST reference + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (created from integer) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr b/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr index 19db90c1cb..aac32ecc5b 100644 --- a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr +++ b/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/union-ub-fat-ptr.rs:78:1 | LL | const B: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling (not entirely in bounds) reference + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior @@ -26,7 +26,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/union-ub-fat-ptr.rs:90:1 | LL | const B2: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling (not entirely in bounds) reference + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/unused-broken-const.stderr b/src/test/ui/consts/const-eval/unused-broken-const.stderr index e45ce65d8b..a13cb87788 100644 --- a/src/test/ui/consts/const-eval/unused-broken-const.stderr +++ b/src/test/ui/consts/const-eval/unused-broken-const.stderr @@ -6,7 +6,7 @@ LL | const FOO: i32 = [][0]; | | | index out of bounds: the len is 0 but the index is 0 | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/valid-const.rs b/src/test/ui/consts/const-eval/valid-const.rs index a195e12def..30bd472192 100644 --- a/src/test/ui/consts/const-eval/valid-const.rs +++ b/src/test/ui/consts/const-eval/valid-const.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Some constants that *are* valid #![feature(const_transmute)] diff --git a/src/test/ui/consts/const-eval/zst_operand_eval.rs b/src/test/ui/consts/const-eval/zst_operand_eval.rs index d837da1066..7edb6bd03d 100644 --- a/src/test/ui/consts/const-eval/zst_operand_eval.rs +++ b/src/test/ui/consts/const-eval/zst_operand_eval.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) static ASSERT: () = [()][!(std::mem::size_of::() == 4) as usize]; diff --git a/src/test/ui/consts/const-expr-addr-operator.rs b/src/test/ui/consts/const-expr-addr-operator.rs index dc9f292c2b..37bf24c2fb 100644 --- a/src/test/ui/consts/const-expr-addr-operator.rs +++ b/src/test/ui/consts/const-expr-addr-operator.rs @@ -1,5 +1,5 @@ // Encountered while testing #44614. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub fn main() { // Constant of generic type (int) diff --git a/src/test/run-pass/consts/const-expr-in-fixed-length-vec.rs b/src/test/ui/consts/const-expr-in-fixed-length-vec.rs similarity index 100% rename from src/test/run-pass/consts/const-expr-in-fixed-length-vec.rs rename to src/test/ui/consts/const-expr-in-fixed-length-vec.rs diff --git a/src/test/run-pass/consts/const-expr-in-vec-repeat.rs b/src/test/ui/consts/const-expr-in-vec-repeat.rs similarity index 100% rename from src/test/run-pass/consts/const-expr-in-vec-repeat.rs rename to src/test/ui/consts/const-expr-in-vec-repeat.rs diff --git a/src/test/run-pass/consts/const-extern-function.rs b/src/test/ui/consts/const-extern-function.rs similarity index 100% rename from src/test/run-pass/consts/const-extern-function.rs rename to src/test/ui/consts/const-extern-function.rs diff --git a/src/test/run-pass/consts/const-fields-and-indexing.rs b/src/test/ui/consts/const-fields-and-indexing.rs similarity index 100% rename from src/test/run-pass/consts/const-fields-and-indexing.rs rename to src/test/ui/consts/const-fields-and-indexing.rs diff --git a/src/test/run-pass/consts/const-fn-const-eval.rs b/src/test/ui/consts/const-fn-const-eval.rs similarity index 100% rename from src/test/run-pass/consts/const-fn-const-eval.rs rename to src/test/ui/consts/const-fn-const-eval.rs diff --git a/src/test/ui/consts/const-fn-destructuring-arg.rs b/src/test/ui/consts/const-fn-destructuring-arg.rs index dcf89f90e3..d2c89cb54a 100644 --- a/src/test/ui/consts/const-fn-destructuring-arg.rs +++ b/src/test/ui/consts/const-fn-destructuring-arg.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) const fn i((a, b): (u32, u32)) -> u32 { a + b diff --git a/src/test/run-pass/consts/const-fn-feature-flags.rs b/src/test/ui/consts/const-fn-feature-flags.rs similarity index 100% rename from src/test/run-pass/consts/const-fn-feature-flags.rs rename to src/test/ui/consts/const-fn-feature-flags.rs diff --git a/src/test/run-pass/consts/const-fn-method.rs b/src/test/ui/consts/const-fn-method.rs similarity index 100% rename from src/test/run-pass/consts/const-fn-method.rs rename to src/test/ui/consts/const-fn-method.rs diff --git a/src/test/run-pass/consts/const-fn-nested.rs b/src/test/ui/consts/const-fn-nested.rs similarity index 100% rename from src/test/run-pass/consts/const-fn-nested.rs rename to src/test/ui/consts/const-fn-nested.rs diff --git a/src/test/run-pass/consts/const-fn-stability-calls.rs b/src/test/ui/consts/const-fn-stability-calls.rs similarity index 100% rename from src/test/run-pass/consts/const-fn-stability-calls.rs rename to src/test/ui/consts/const-fn-stability-calls.rs diff --git a/src/test/ui/consts/const-fn-type-name-any.rs b/src/test/ui/consts/const-fn-type-name-any.rs new file mode 100644 index 0000000000..4ccfb42098 --- /dev/null +++ b/src/test/ui/consts/const-fn-type-name-any.rs @@ -0,0 +1,29 @@ +// run-pass + +#![feature(const_fn)] +#![feature(const_type_name)] +#![allow(dead_code)] + +const fn type_name_wrapper(_: &T) -> &'static str { + std::any::type_name::() +} + +struct Struct { + a: TA, + b: TB, + c: TC, +} + +type StructInstantiation = Struct; + +const CONST_STRUCT: StructInstantiation = StructInstantiation { a: 12, b: 13.7, c: false }; + +const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT); + +fn main() { + let non_const_struct = StructInstantiation { a: 87, b: 65.99, c: true }; + + let non_const_struct_name = type_name_wrapper(&non_const_struct); + + assert_eq!(CONST_STRUCT_NAME, non_const_struct_name); +} diff --git a/src/test/run-pass/consts/const-fn-type-name.rs b/src/test/ui/consts/const-fn-type-name.rs similarity index 93% rename from src/test/run-pass/consts/const-fn-type-name.rs rename to src/test/ui/consts/const-fn-type-name.rs index 2ee6415aa6..2bb1aeecf3 100644 --- a/src/test/run-pass/consts/const-fn-type-name.rs +++ b/src/test/ui/consts/const-fn-type-name.rs @@ -5,7 +5,7 @@ #![allow(dead_code)] const fn type_name_wrapper(_: &T) -> &'static str { - unsafe { core::intrinsics::type_name::() } + core::intrinsics::type_name::() } struct Struct { diff --git a/src/test/run-pass/consts/const-fn-val.rs b/src/test/ui/consts/const-fn-val.rs similarity index 100% rename from src/test/run-pass/consts/const-fn-val.rs rename to src/test/ui/consts/const-fn-val.rs diff --git a/src/test/run-pass/consts/const-fn.rs b/src/test/ui/consts/const-fn.rs similarity index 100% rename from src/test/run-pass/consts/const-fn.rs rename to src/test/ui/consts/const-fn.rs diff --git a/src/test/run-pass/consts/const-index-feature-gate.rs b/src/test/ui/consts/const-index-feature-gate.rs similarity index 100% rename from src/test/run-pass/consts/const-index-feature-gate.rs rename to src/test/ui/consts/const-index-feature-gate.rs diff --git a/src/test/run-pass/consts/const-int-conversion.rs b/src/test/ui/consts/const-int-conversion-rpass.rs similarity index 98% rename from src/test/run-pass/consts/const-int-conversion.rs rename to src/test/ui/consts/const-int-conversion-rpass.rs index 1d3123d216..d52dbbae1e 100644 --- a/src/test/run-pass/consts/const-int-conversion.rs +++ b/src/test/ui/consts/const-int-conversion-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(const_int_conversion)] const REVERSE: u32 = 0x12345678_u32.reverse_bits(); diff --git a/src/test/run-pass/consts/const-int-overflowing.rs b/src/test/ui/consts/const-int-overflowing-rpass.rs similarity index 98% rename from src/test/run-pass/consts/const-int-overflowing.rs rename to src/test/ui/consts/const-int-overflowing-rpass.rs index 9597393df7..b619c7908a 100644 --- a/src/test/run-pass/consts/const-int-overflowing.rs +++ b/src/test/ui/consts/const-int-overflowing-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + const ADD_A: (u32, bool) = 5u32.overflowing_add(2); const ADD_B: (u32, bool) = u32::max_value().overflowing_add(1); diff --git a/src/test/run-pass/consts/const-int-rotate.rs b/src/test/ui/consts/const-int-rotate-rpass.rs similarity index 99% rename from src/test/run-pass/consts/const-int-rotate.rs rename to src/test/ui/consts/const-int-rotate-rpass.rs index 16946eadd6..14f34f76ce 100644 --- a/src/test/run-pass/consts/const-int-rotate.rs +++ b/src/test/ui/consts/const-int-rotate-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + const LEFT: u32 = 0x10000b3u32.rotate_left(8); const RIGHT: u32 = 0xb301u32.rotate_right(8); diff --git a/src/test/run-pass/consts/const-int-saturating-arith.rs b/src/test/ui/consts/const-int-saturating-arith.rs similarity index 99% rename from src/test/run-pass/consts/const-int-saturating-arith.rs rename to src/test/ui/consts/const-int-saturating-arith.rs index dae4c7216b..394d6c17f5 100644 --- a/src/test/run-pass/consts/const-int-saturating-arith.rs +++ b/src/test/ui/consts/const-int-saturating-arith.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten no i128 support #![feature(const_saturating_int_methods)] diff --git a/src/test/run-pass/consts/const-int-sign.rs b/src/test/ui/consts/const-int-sign-rpass.rs similarity index 97% rename from src/test/run-pass/consts/const-int-sign.rs rename to src/test/ui/consts/const-int-sign-rpass.rs index fcd3ef4ea0..05726cb228 100644 --- a/src/test/run-pass/consts/const-int-sign.rs +++ b/src/test/ui/consts/const-int-sign-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(const_int_sign)] const NEGATIVE_A: bool = (-10i32).is_negative(); diff --git a/src/test/ui/consts/const-int-unchecked.stderr b/src/test/ui/consts/const-int-unchecked.stderr index 0fa8200871..d569c6a201 100644 --- a/src/test/ui/consts/const-int-unchecked.stderr +++ b/src/test/ui/consts/const-int-unchecked.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) }; | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 8 in unchecked_shl + | Overflowing shift by 8 in `unchecked_shl` | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:16:31 @@ -14,7 +14,7 @@ error: any use of this value will cause an error LL | const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 16 in unchecked_shl + | Overflowing shift by 16 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:18:31 @@ -22,7 +22,7 @@ error: any use of this value will cause an error LL | const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 32 in unchecked_shl + | Overflowing shift by 32 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:20:31 @@ -30,7 +30,7 @@ error: any use of this value will cause an error LL | const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 64 in unchecked_shl + | Overflowing shift by 64 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:22:33 @@ -38,7 +38,7 @@ error: any use of this value will cause an error LL | const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) }; | --------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 128 in unchecked_shl + | Overflowing shift by 128 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:27:29 @@ -46,7 +46,7 @@ error: any use of this value will cause an error LL | const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) }; | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 8 in unchecked_shl + | Overflowing shift by 8 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:29:31 @@ -54,7 +54,7 @@ error: any use of this value will cause an error LL | const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_16, 16) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 16 in unchecked_shl + | Overflowing shift by 16 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:31:31 @@ -62,7 +62,7 @@ error: any use of this value will cause an error LL | const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 32 in unchecked_shl + | Overflowing shift by 32 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:33:31 @@ -70,7 +70,7 @@ error: any use of this value will cause an error LL | const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 64 in unchecked_shl + | Overflowing shift by 64 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:35:33 @@ -78,7 +78,7 @@ error: any use of this value will cause an error LL | const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) }; | --------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 128 in unchecked_shl + | Overflowing shift by 128 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:40:33 @@ -86,7 +86,7 @@ error: any use of this value will cause an error LL | const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) }; | --------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 255 in unchecked_shl + | Overflowing shift by 255 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:42:35 @@ -94,7 +94,7 @@ error: any use of this value will cause an error LL | const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 65535 in unchecked_shl + | Overflowing shift by 65535 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:44:35 @@ -102,7 +102,7 @@ error: any use of this value will cause an error LL | const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 4294967295 in unchecked_shl + | Overflowing shift by 4294967295 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:46:35 @@ -110,7 +110,7 @@ error: any use of this value will cause an error LL | const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 18446744073709551615 in unchecked_shl + | Overflowing shift by 18446744073709551615 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:48:37 @@ -118,7 +118,7 @@ error: any use of this value will cause an error LL | const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 340282366920938463463374607431768211455 in unchecked_shl + | Overflowing shift by 340282366920938463463374607431768211455 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:54:40 @@ -126,7 +126,7 @@ error: any use of this value will cause an error LL | const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) }; | ---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 250 in unchecked_shl + | Overflowing shift by 250 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:56:42 @@ -134,7 +134,7 @@ error: any use of this value will cause an error LL | const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) }; | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 65523 in unchecked_shl + | Overflowing shift by 65523 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:58:42 @@ -142,7 +142,7 @@ error: any use of this value will cause an error LL | const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) }; | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 4294967271 in unchecked_shl + | Overflowing shift by 4294967271 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:60:42 @@ -150,7 +150,7 @@ error: any use of this value will cause an error LL | const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) }; | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 18446744073709551586 in unchecked_shl + | Overflowing shift by 18446744073709551586 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:62:44 @@ -158,7 +158,7 @@ error: any use of this value will cause an error LL | const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) }; | -------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 340282366920938463463374607431768211363 in unchecked_shl + | Overflowing shift by 340282366920938463463374607431768211363 in `unchecked_shl` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:69:29 @@ -166,7 +166,7 @@ error: any use of this value will cause an error LL | const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) }; | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 8 in unchecked_shr + | Overflowing shift by 8 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:71:31 @@ -174,7 +174,7 @@ error: any use of this value will cause an error LL | const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 16 in unchecked_shr + | Overflowing shift by 16 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:73:31 @@ -182,7 +182,7 @@ error: any use of this value will cause an error LL | const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 32 in unchecked_shr + | Overflowing shift by 32 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:75:31 @@ -190,7 +190,7 @@ error: any use of this value will cause an error LL | const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 64 in unchecked_shr + | Overflowing shift by 64 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:77:33 @@ -198,7 +198,7 @@ error: any use of this value will cause an error LL | const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) }; | --------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 128 in unchecked_shr + | Overflowing shift by 128 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:82:29 @@ -206,7 +206,7 @@ error: any use of this value will cause an error LL | const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) }; | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 8 in unchecked_shr + | Overflowing shift by 8 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:84:31 @@ -214,7 +214,7 @@ error: any use of this value will cause an error LL | const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_16, 16) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 16 in unchecked_shr + | Overflowing shift by 16 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:86:31 @@ -222,7 +222,7 @@ error: any use of this value will cause an error LL | const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 32 in unchecked_shr + | Overflowing shift by 32 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:88:31 @@ -230,7 +230,7 @@ error: any use of this value will cause an error LL | const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) }; | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 64 in unchecked_shr + | Overflowing shift by 64 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:90:33 @@ -238,7 +238,7 @@ error: any use of this value will cause an error LL | const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) }; | --------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 128 in unchecked_shr + | Overflowing shift by 128 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:95:33 @@ -246,7 +246,7 @@ error: any use of this value will cause an error LL | const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) }; | --------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 255 in unchecked_shr + | Overflowing shift by 255 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:97:35 @@ -254,7 +254,7 @@ error: any use of this value will cause an error LL | const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 65535 in unchecked_shr + | Overflowing shift by 65535 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:99:35 @@ -262,7 +262,7 @@ error: any use of this value will cause an error LL | const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 4294967295 in unchecked_shr + | Overflowing shift by 4294967295 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:101:35 @@ -270,7 +270,7 @@ error: any use of this value will cause an error LL | const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 18446744073709551615 in unchecked_shr + | Overflowing shift by 18446744073709551615 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:103:37 @@ -278,7 +278,7 @@ error: any use of this value will cause an error LL | const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 340282366920938463463374607431768211455 in unchecked_shr + | Overflowing shift by 340282366920938463463374607431768211455 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:109:40 @@ -286,7 +286,7 @@ error: any use of this value will cause an error LL | const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) }; | ---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 250 in unchecked_shr + | Overflowing shift by 250 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:111:42 @@ -294,7 +294,7 @@ error: any use of this value will cause an error LL | const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) }; | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 65523 in unchecked_shr + | Overflowing shift by 65523 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:113:42 @@ -302,7 +302,7 @@ error: any use of this value will cause an error LL | const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) }; | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 4294967271 in unchecked_shr + | Overflowing shift by 4294967271 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:115:42 @@ -310,7 +310,7 @@ error: any use of this value will cause an error LL | const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) }; | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 18446744073709551586 in unchecked_shr + | Overflowing shift by 18446744073709551586 in `unchecked_shr` error: any use of this value will cause an error --> $DIR/const-int-unchecked.rs:117:44 @@ -318,7 +318,7 @@ error: any use of this value will cause an error LL | const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) }; | -------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | Overflowing shift by 340282366920938463463374607431768211363 in unchecked_shr + | Overflowing shift by 340282366920938463463374607431768211363 in `unchecked_shr` error: aborting due to 40 previous errors diff --git a/src/test/run-pass/consts/const-int-wrapping.rs b/src/test/ui/consts/const-int-wrapping-rpass.rs similarity index 98% rename from src/test/run-pass/consts/const-int-wrapping.rs rename to src/test/ui/consts/const-int-wrapping-rpass.rs index db86c25194..73147d7912 100644 --- a/src/test/run-pass/consts/const-int-wrapping.rs +++ b/src/test/ui/consts/const-int-wrapping-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + const ADD_A: u32 = 200u32.wrapping_add(55); const ADD_B: u32 = 200u32.wrapping_add(u32::max_value()); diff --git a/src/test/run-pass/consts/const-labeled-break.rs b/src/test/ui/consts/const-labeled-break.rs similarity index 84% rename from src/test/run-pass/consts/const-labeled-break.rs rename to src/test/ui/consts/const-labeled-break.rs index 9417159e6f..36e308ade9 100644 --- a/src/test/run-pass/consts/const-labeled-break.rs +++ b/src/test/ui/consts/const-labeled-break.rs @@ -1,3 +1,5 @@ +// run-pass + // Using labeled break in a while loop has caused an illegal instruction being // generated, and an ICE later. // @@ -5,6 +7,4 @@ const CRASH: () = 'a: while break 'a {}; -fn main() { - println!("{:?}", CRASH); -} +fn main() {} diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr index ef4fa126dc..150d3eb525 100644 --- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr @@ -6,7 +6,7 @@ LL | const LEN: usize = ONE - TWO; | | | attempt to subtract with overflow | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant value failed --> $DIR/const-len-underflow-separate-spans.rs:11:17 diff --git a/src/test/ui/consts/const-match-check.eval1.stderr b/src/test/ui/consts/const-match-check.eval1.stderr index 4c6499cf99..3bcb50c6dc 100644 --- a/src/test/ui/consts/const-match-check.eval1.stderr +++ b/src/test/ui/consts/const-match-check.eval1.stderr @@ -1,8 +1,8 @@ -error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered +error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered --> $DIR/const-match-check.rs:25:15 | LL | A = { let 0 = 0; 0 }, - | ^ pattern `-2147483648i32..=-1i32` not covered + | ^ pattern `std::i32::MIN..=-1i32` not covered error: aborting due to previous error diff --git a/src/test/ui/consts/const-match-check.eval2.stderr b/src/test/ui/consts/const-match-check.eval2.stderr index 854f8f3a7b..e292e1cc16 100644 --- a/src/test/ui/consts/const-match-check.eval2.stderr +++ b/src/test/ui/consts/const-match-check.eval2.stderr @@ -1,8 +1,8 @@ -error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered +error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered --> $DIR/const-match-check.rs:31:24 | LL | let x: [i32; { let 0 = 0; 0 }] = []; - | ^ pattern `-2147483648i32..=-1i32` not covered + | ^ pattern `std::i32::MIN..=-1i32` not covered error: aborting due to previous error diff --git a/src/test/ui/consts/const-match-check.matchck.stderr b/src/test/ui/consts/const-match-check.matchck.stderr index c9028b1c2a..8a9fbde853 100644 --- a/src/test/ui/consts/const-match-check.matchck.stderr +++ b/src/test/ui/consts/const-match-check.matchck.stderr @@ -1,26 +1,26 @@ -error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered +error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered --> $DIR/const-match-check.rs:4:22 | LL | const X: i32 = { let 0 = 0; 0 }; - | ^ pattern `-2147483648i32..=-1i32` not covered + | ^ pattern `std::i32::MIN..=-1i32` not covered -error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered +error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered --> $DIR/const-match-check.rs:8:23 | LL | static Y: i32 = { let 0 = 0; 0 }; - | ^ pattern `-2147483648i32..=-1i32` not covered + | ^ pattern `std::i32::MIN..=-1i32` not covered -error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered +error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered --> $DIR/const-match-check.rs:13:26 | LL | const X: i32 = { let 0 = 0; 0 }; - | ^ pattern `-2147483648i32..=-1i32` not covered + | ^ pattern `std::i32::MIN..=-1i32` not covered -error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered +error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered --> $DIR/const-match-check.rs:19:26 | LL | const X: i32 = { let 0 = 0; 0 }; - | ^ pattern `-2147483648i32..=-1i32` not covered + | ^ pattern `std::i32::MIN..=-1i32` not covered error: aborting due to 4 previous errors diff --git a/src/test/run-pass/consts/const-meth-pattern.rs b/src/test/ui/consts/const-meth-pattern.rs similarity index 100% rename from src/test/run-pass/consts/const-meth-pattern.rs rename to src/test/ui/consts/const-meth-pattern.rs diff --git a/src/test/run-pass/consts/const-needs_drop.rs b/src/test/ui/consts/const-needs_drop.rs similarity index 98% rename from src/test/run-pass/consts/const-needs_drop.rs rename to src/test/ui/consts/const-needs_drop.rs index 871300defa..58e8011644 100644 --- a/src/test/run-pass/consts/const-needs_drop.rs +++ b/src/test/ui/consts/const-needs_drop.rs @@ -1,3 +1,5 @@ +// run-pass + use std::mem; struct Trivial(u8, f32); diff --git a/src/test/run-pass/consts/const-negation.rs b/src/test/ui/consts/const-negation.rs similarity index 100% rename from src/test/run-pass/consts/const-negation.rs rename to src/test/ui/consts/const-negation.rs diff --git a/src/test/run-pass/consts/const-negative.rs b/src/test/ui/consts/const-negative.rs similarity index 100% rename from src/test/run-pass/consts/const-negative.rs rename to src/test/ui/consts/const-negative.rs diff --git a/src/test/ui/consts/const-nonzero.rs b/src/test/ui/consts/const-nonzero.rs index c06ab227f6..6db3d1b333 100644 --- a/src/test/ui/consts/const-nonzero.rs +++ b/src/test/ui/consts/const-nonzero.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::num::NonZeroU8; diff --git a/src/test/run-pass/consts/const-nullary-enum.rs b/src/test/ui/consts/const-nullary-enum.rs similarity index 100% rename from src/test/run-pass/consts/const-nullary-enum.rs rename to src/test/ui/consts/const-nullary-enum.rs diff --git a/src/test/run-pass/consts/const-nullary-univariant-enum.rs b/src/test/ui/consts/const-nullary-univariant-enum.rs similarity index 100% rename from src/test/run-pass/consts/const-nullary-univariant-enum.rs rename to src/test/ui/consts/const-nullary-univariant-enum.rs diff --git a/src/test/ui/consts/const-pattern-not-const-evaluable.rs b/src/test/ui/consts/const-pattern-not-const-evaluable.rs index 8dd78ca0ba..dae5343fe3 100644 --- a/src/test/ui/consts/const-pattern-not-const-evaluable.rs +++ b/src/test/ui/consts/const-pattern-not-const-evaluable.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(PartialEq, Eq)] enum Cake { diff --git a/src/test/run-pass/consts/const-pattern-variant.rs b/src/test/ui/consts/const-pattern-variant.rs similarity index 100% rename from src/test/run-pass/consts/const-pattern-variant.rs rename to src/test/ui/consts/const-pattern-variant.rs diff --git a/src/test/ui/consts/const-prop-ice.stderr b/src/test/ui/consts/const-prop-ice.stderr index 8ec54b4438..4b3880198b 100644 --- a/src/test/ui/consts/const-prop-ice.stderr +++ b/src/test/ui/consts/const-prop-ice.stderr @@ -4,7 +4,7 @@ error: index out of bounds: the len is 3 but the index is 3 LL | [0; 3][3u64 as usize]; | ^^^^^^^^^^^^^^^^^^^^^ | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/ui/consts/const-prop-ice2.stderr b/src/test/ui/consts/const-prop-ice2.stderr index 68a7164da3..dc17876eae 100644 --- a/src/test/ui/consts/const-prop-ice2.stderr +++ b/src/test/ui/consts/const-prop-ice2.stderr @@ -4,7 +4,7 @@ error: index out of bounds: the len is 1 but the index is 1 LL | println!("{}", xs[Enum::One as usize]); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/run-pass/consts/const-ptr-nonnull.rs b/src/test/ui/consts/const-ptr-nonnull-rpass.rs similarity index 100% rename from src/test/run-pass/consts/const-ptr-nonnull.rs rename to src/test/ui/consts/const-ptr-nonnull-rpass.rs diff --git a/src/test/run-pass/consts/const-ptr-unique.rs b/src/test/ui/consts/const-ptr-unique-rpass.rs similarity index 100% rename from src/test/run-pass/consts/const-ptr-unique.rs rename to src/test/ui/consts/const-ptr-unique-rpass.rs diff --git a/src/test/run-pass/consts/const-rec-and-tup.rs b/src/test/ui/consts/const-rec-and-tup.rs similarity index 100% rename from src/test/run-pass/consts/const-rec-and-tup.rs rename to src/test/ui/consts/const-rec-and-tup.rs diff --git a/src/test/run-pass/consts/const-region-ptrs-noncopy.rs b/src/test/ui/consts/const-region-ptrs-noncopy.rs similarity index 100% rename from src/test/run-pass/consts/const-region-ptrs-noncopy.rs rename to src/test/ui/consts/const-region-ptrs-noncopy.rs diff --git a/src/test/run-pass/consts/const-region-ptrs.rs b/src/test/ui/consts/const-region-ptrs.rs similarity index 100% rename from src/test/run-pass/consts/const-region-ptrs.rs rename to src/test/ui/consts/const-region-ptrs.rs diff --git a/src/test/run-pass/consts/const-repeated-values.rs b/src/test/ui/consts/const-repeated-values.rs similarity index 100% rename from src/test/run-pass/consts/const-repeated-values.rs rename to src/test/ui/consts/const-repeated-values.rs diff --git a/src/test/run-pass/consts/const-size_of-align_of.rs b/src/test/ui/consts/const-size_of-align_of.rs similarity index 100% rename from src/test/run-pass/consts/const-size_of-align_of.rs rename to src/test/ui/consts/const-size_of-align_of.rs diff --git a/src/test/ui/consts/const-slice-oob.stderr b/src/test/ui/consts/const-slice-oob.stderr index c90cdbcb26..7e191a6336 100644 --- a/src/test/ui/consts/const-slice-oob.stderr +++ b/src/test/ui/consts/const-slice-oob.stderr @@ -6,7 +6,7 @@ LL | const BAR: u32 = FOO[5]; | | | index out of bounds: the len is 3 but the index is 5 | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/run-pass/consts/const-str-ptr.rs b/src/test/ui/consts/const-str-ptr.rs similarity index 100% rename from src/test/run-pass/consts/const-str-ptr.rs rename to src/test/ui/consts/const-str-ptr.rs diff --git a/src/test/run-pass/consts/const-struct-offsets.rs b/src/test/ui/consts/const-struct-offsets.rs similarity index 100% rename from src/test/run-pass/consts/const-struct-offsets.rs rename to src/test/ui/consts/const-struct-offsets.rs diff --git a/src/test/run-pass/consts/const-struct.rs b/src/test/ui/consts/const-struct.rs similarity index 100% rename from src/test/run-pass/consts/const-struct.rs rename to src/test/ui/consts/const-struct.rs diff --git a/src/test/run-pass/consts/const-trait-to-trait.rs b/src/test/ui/consts/const-trait-to-trait.rs similarity index 100% rename from src/test/run-pass/consts/const-trait-to-trait.rs rename to src/test/ui/consts/const-trait-to-trait.rs diff --git a/src/test/run-pass/consts/const-tuple-struct.rs b/src/test/ui/consts/const-tuple-struct.rs similarity index 100% rename from src/test/run-pass/consts/const-tuple-struct.rs rename to src/test/ui/consts/const-tuple-struct.rs diff --git a/src/test/run-pass/consts/const-typeid-of.rs b/src/test/ui/consts/const-typeid-of-rpass.rs similarity index 100% rename from src/test/run-pass/consts/const-typeid-of.rs rename to src/test/ui/consts/const-typeid-of-rpass.rs diff --git a/src/test/run-pass/consts/const-unit-struct.rs b/src/test/ui/consts/const-unit-struct.rs similarity index 100% rename from src/test/run-pass/consts/const-unit-struct.rs rename to src/test/ui/consts/const-unit-struct.rs diff --git a/src/test/run-pass/consts/const-unsafe-fn.rs b/src/test/ui/consts/const-unsafe-fn.rs similarity index 100% rename from src/test/run-pass/consts/const-unsafe-fn.rs rename to src/test/ui/consts/const-unsafe-fn.rs diff --git a/src/test/ui/consts/const-validation-fail-55455.rs b/src/test/ui/consts/const-validation-fail-55455.rs index def4062339..583074888c 100644 --- a/src/test/ui/consts/const-validation-fail-55455.rs +++ b/src/test/ui/consts/const-validation-fail-55455.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/issues/55454 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct This(T); diff --git a/src/test/run-pass/consts/const-vec-of-fns.rs b/src/test/ui/consts/const-vec-of-fns.rs similarity index 100% rename from src/test/run-pass/consts/const-vec-of-fns.rs rename to src/test/ui/consts/const-vec-of-fns.rs diff --git a/src/test/run-pass/consts/const-vec-syntax.rs b/src/test/ui/consts/const-vec-syntax.rs similarity index 100% rename from src/test/run-pass/consts/const-vec-syntax.rs rename to src/test/ui/consts/const-vec-syntax.rs diff --git a/src/test/run-pass/consts/const-vecs-and-slices.rs b/src/test/ui/consts/const-vecs-and-slices.rs similarity index 100% rename from src/test/run-pass/consts/const-vecs-and-slices.rs rename to src/test/ui/consts/const-vecs-and-slices.rs diff --git a/src/test/run-pass/consts/const.rs b/src/test/ui/consts/const.rs similarity index 100% rename from src/test/run-pass/consts/const.rs rename to src/test/ui/consts/const.rs diff --git a/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs b/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs index c7617c9c7a..d22c789609 100644 --- a/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs +++ b/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:const_fn_lib.rs extern crate const_fn_lib; diff --git a/src/test/ui/consts/const_let_assign.rs b/src/test/ui/consts/const_let_assign.rs index 0b09b8469f..343fcb4859 100644 --- a/src/test/ui/consts/const_let_assign.rs +++ b/src/test/ui/consts/const_let_assign.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(i32); diff --git a/src/test/ui/consts/const_let_assign2.rs b/src/test/ui/consts/const_let_assign2.rs index 1c44237e49..4787c1750d 100644 --- a/src/test/ui/consts/const_let_assign2.rs +++ b/src/test/ui/consts/const_let_assign2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct AA { pub data: [u8; 10], diff --git a/src/test/ui/consts/const_let_eq_float.rs b/src/test/ui/consts/const_let_eq_float.rs index c48f54e567..0c927a0484 100644 --- a/src/test/ui/consts/const_let_eq_float.rs +++ b/src/test/ui/consts/const_let_eq_float.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_fn)] diff --git a/src/test/ui/consts/const_let_irrefutable.rs b/src/test/ui/consts/const_let_irrefutable.rs index 424a16f7ed..e889abf4ab 100644 --- a/src/test/ui/consts/const_let_irrefutable.rs +++ b/src/test/ui/consts/const_let_irrefutable.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/consts/const_let_refutable.nll.stderr b/src/test/ui/consts/const_let_refutable.nll.stderr deleted file mode 100644 index 3cc6de5bc4..0000000000 --- a/src/test/ui/consts/const_let_refutable.nll.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0005]: refutable pattern in function argument: `&[]` not covered - --> $DIR/const_let_refutable.rs:3:16 - | -LL | const fn slice([a, b]: &[i32]) -> i32 { - | ^^^^^^ pattern `&[]` not covered - -error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn` - --> $DIR/const_let_refutable.rs:4:5 - | -LL | a + b - | ^^^^^ - | - = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable - -error[E0381]: use of possibly uninitialized variable: `a` - --> $DIR/const_let_refutable.rs:4:5 - | -LL | a + b - | ^ use of possibly uninitialized `a` - -error[E0381]: use of possibly uninitialized variable: `b` - --> $DIR/const_let_refutable.rs:4:9 - | -LL | a + b - | ^ use of possibly uninitialized `b` - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0005, E0381, E0723. -For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs index 322048c7fb..7b3a591223 100644 --- a/src/test/ui/consts/const_let_refutable.rs +++ b/src/test/ui/consts/const_let_refutable.rs @@ -2,10 +2,6 @@ fn main() {} const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument a + b //~ ERROR can only call other `const fn` within a `const fn` - //~^ WARN use of possibly uninitialized variable: `a` - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will - //~| WARN use of possibly uninitialized variable: `b` - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will + //~^ ERROR use of possibly uninitialized variable: `a` + //~| ERROR use of possibly uninitialized variable: `b` } diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr index cdd696ee7f..a61c9b0c9f 100644 --- a/src/test/ui/consts/const_let_refutable.stderr +++ b/src/test/ui/consts/const_let_refutable.stderr @@ -11,29 +11,21 @@ LL | a + b | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable -warning[E0381]: use of possibly uninitialized variable: `a` +error[E0381]: use of possibly uninitialized variable: `a` --> $DIR/const_let_refutable.rs:4:5 | LL | a + b | ^ use of possibly uninitialized `a` - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -warning[E0381]: use of possibly uninitialized variable: `b` +error[E0381]: use of possibly uninitialized variable: `b` --> $DIR/const_let_refutable.rs:4:9 | LL | a + b | ^ use of possibly uninitialized `b` - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0005, E0381, E0723. For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/run-pass/consts/consts-in-patterns.rs b/src/test/ui/consts/consts-in-patterns.rs similarity index 100% rename from src/test/run-pass/consts/consts-in-patterns.rs rename to src/test/ui/consts/consts-in-patterns.rs diff --git a/src/test/ui/consts/dangling-alloc-id-ice.stderr b/src/test/ui/consts/dangling-alloc-id-ice.stderr index 87f84480bf..bac9f555d2 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.stderr +++ b/src/test/ui/consts/dangling-alloc-id-ice.stderr @@ -7,7 +7,7 @@ LL | | unsafe { Foo { y: &y }.long_live_the_unit } LL | | }; | |__^ type validation failed: encountered dangling pointer in final constant | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/ui/consts/dangling_raw_ptr.stderr b/src/test/ui/consts/dangling_raw_ptr.stderr index 0168c08f01..4748be37df 100644 --- a/src/test/ui/consts/dangling_raw_ptr.stderr +++ b/src/test/ui/consts/dangling_raw_ptr.stderr @@ -7,7 +7,7 @@ LL | | &x LL | | }; | |__^ type validation failed: encountered dangling pointer in final constant | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/run-pass/consts/deref_in_pattern.rs b/src/test/ui/consts/deref_in_pattern.rs similarity index 100% rename from src/test/run-pass/consts/deref_in_pattern.rs rename to src/test/ui/consts/deref_in_pattern.rs diff --git a/src/test/ui/consts/drop_none.rs b/src/test/ui/consts/drop_none.rs index 86a197ffb9..9d98d3be87 100644 --- a/src/test/ui/consts/drop_none.rs +++ b/src/test/ui/consts/drop_none.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A; impl Drop for A { diff --git a/src/test/run-pass/consts/ice-48279.rs b/src/test/ui/consts/ice-48279.rs similarity index 100% rename from src/test/run-pass/consts/ice-48279.rs rename to src/test/ui/consts/ice-48279.rs diff --git a/src/test/ui/consts/int_ptr_for_zst_slices.rs b/src/test/ui/consts/int_ptr_for_zst_slices.rs index afa2c6a5b9..34dafd00d2 100644 --- a/src/test/ui/consts/int_ptr_for_zst_slices.rs +++ b/src/test/ui/consts/int_ptr_for_zst_slices.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_raw_ptr_deref)] diff --git a/src/test/ui/consts/invalid_promotion.rs b/src/test/ui/consts/invalid_promotion.rs index f98406e50e..a31eaf40e0 100644 --- a/src/test/ui/consts/invalid_promotion.rs +++ b/src/test/ui/consts/invalid_promotion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // note this was only reproducible with lib crates // compile-flags: --crate-type=lib diff --git a/src/test/run-pass/consts/issue-37550.rs b/src/test/ui/consts/issue-37550.rs similarity index 100% rename from src/test/run-pass/consts/issue-37550.rs rename to src/test/ui/consts/issue-37550.rs diff --git a/src/test/ui/consts/issue-51559.rs b/src/test/ui/consts/issue-51559.rs new file mode 100644 index 0000000000..69f0d8df0a --- /dev/null +++ b/src/test/ui/consts/issue-51559.rs @@ -0,0 +1,7 @@ +#![feature(const_raw_ptr_to_usize_cast)] + +const BAR: *mut () = ((|| 3) as fn() -> i32) as *mut (); +pub const FOO: usize = unsafe { BAR as usize }; +//~^ ERROR any use of this value will cause an error + +fn main() {} diff --git a/src/test/ui/consts/issue-51559.stderr b/src/test/ui/consts/issue-51559.stderr new file mode 100644 index 0000000000..4d50ec818b --- /dev/null +++ b/src/test/ui/consts/issue-51559.stderr @@ -0,0 +1,12 @@ +error: any use of this value will cause an error + --> $DIR/issue-51559.rs:4:33 + | +LL | pub const FOO: usize = unsafe { BAR as usize }; + | --------------------------------^^^^^^^^^^^^--- + | | + | "pointer-to-integer cast" needs an rfc before being allowed inside constants + | + = note: `#[deny(const_err)]` on by default + +error: aborting due to previous error + diff --git a/src/test/ui/consts/issue-62045.rs b/src/test/ui/consts/issue-62045.rs index 9f41ed9a24..efeb9fc551 100644 --- a/src/test/ui/consts/issue-62045.rs +++ b/src/test/ui/consts/issue-62045.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { assert_eq!(&mut [0; 1][..], &mut []); diff --git a/src/test/run-pass/consts/issue-broken-mir.rs b/src/test/ui/consts/issue-broken-mir.rs similarity index 100% rename from src/test/run-pass/consts/issue-broken-mir.rs rename to src/test/ui/consts/issue-broken-mir.rs diff --git a/src/test/run-pass/consts/locals-in-const-fn.rs b/src/test/ui/consts/locals-in-const-fn.rs similarity index 100% rename from src/test/run-pass/consts/locals-in-const-fn.rs rename to src/test/ui/consts/locals-in-const-fn.rs diff --git a/src/test/run-pass/consts/match-const-fn-structs.rs b/src/test/ui/consts/match-const-fn-structs.rs similarity index 100% rename from src/test/run-pass/consts/match-const-fn-structs.rs rename to src/test/ui/consts/match-const-fn-structs.rs diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr index e6e1ced659..6228b012dd 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr @@ -5,7 +5,7 @@ LL | const fn error(_: fn()) {} | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs index 0395795ef7..0f9d372929 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs @@ -5,7 +5,7 @@ const fn error(_: fn()) {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_allow_const_fn_ptr] -//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +//~^ ERROR internal implementation detail const fn compiles(_: fn()) {} fn main() {} diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr index c934307e91..70a10d9a0c 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr @@ -1,11 +1,11 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:3 +error[E0658]: internal implementation detail + --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:1 | LL | #[rustc_allow_const_fn_ptr] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index ac8d082fc1..ecfd30e7b4 100644 --- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -5,7 +5,7 @@ LL | vec![1, 2, 3] | ^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr index b1a50be998..9919c17a04 100644 --- a/src/test/ui/consts/min_const_fn/cast_errors.stderr +++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr @@ -5,7 +5,7 @@ LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable --> $DIR/cast_errors.rs:5:23 @@ -14,7 +14,7 @@ LL | const fn closure() -> fn() { || {} } | ^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable --> $DIR/cast_errors.rs:8:5 @@ -23,7 +23,7 @@ LL | (|| {}) as fn(); | ^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable --> $DIR/cast_errors.rs:11:28 @@ -32,7 +32,7 @@ LL | const fn reify(f: fn()) -> unsafe fn() { f } | ^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable --> $DIR/cast_errors.rs:13:21 @@ -41,7 +41,7 @@ LL | const fn reify2() { main as unsafe fn(); } | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr index 7f6132ce9c..82ed1d4522 100644 --- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr +++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr @@ -5,7 +5,7 @@ LL | const fn cmp(x: fn(), y: fn()) -> bool { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/consts/min_const_fn/loop_ice.stderr b/src/test/ui/consts/min_const_fn/loop_ice.stderr index cb85956266..edf983fc56 100644 --- a/src/test/ui/consts/min_const_fn/loop_ice.stderr +++ b/src/test/ui/consts/min_const_fn/loop_ice.stderr @@ -5,7 +5,7 @@ LL | loop {} | ^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr index abbdb4ab63..4b43a0d0a1 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -11,7 +11,7 @@ LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:44:28 @@ -26,7 +26,7 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:51:27 @@ -41,7 +41,7 @@ LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable --> $DIR/min_const_fn.rs:58:39 @@ -50,7 +50,7 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn.rs:76:16 @@ -59,7 +59,7 @@ LL | const fn foo11(t: T) -> T { t } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn.rs:78:18 @@ -68,7 +68,7 @@ LL | const fn foo11_2(t: T) -> T { t } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn.rs:80:33 @@ -77,7 +77,7 @@ LL | const fn foo19(f: f32) -> f32 { f * 2.0 } | ^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn.rs:82:35 @@ -86,7 +86,7 @@ LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f } | ^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int and `bool` operations are stable in const fn --> $DIR/min_const_fn.rs:84:35 @@ -95,7 +95,7 @@ LL | const fn foo19_3(f: f32) -> f32 { -f } | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn.rs:86:43 @@ -104,7 +104,7 @@ LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g } | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: cannot access `static` items in const fn --> $DIR/min_const_fn.rs:90:27 @@ -113,7 +113,7 @@ LL | const fn foo25() -> u32 { BAR } | ^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: cannot access `static` items in const fn --> $DIR/min_const_fn.rs:91:36 @@ -122,7 +122,7 @@ LL | const fn foo26() -> &'static u32 { &BAR } | ^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:92:42 @@ -131,7 +131,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:94:63 @@ -140,7 +140,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:96:42 @@ -149,7 +149,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:98:63 @@ -158,7 +158,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:100:38 @@ -167,127 +167,127 @@ LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable -error[E0723]: loops and conditional expressions are not stable in const fn +error[E0723]: loops are not allowed in const fn --> $DIR/min_const_fn.rs:102:29 | LL | const fn foo30_5(b: bool) { while b { } } | ^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:104:44 + --> $DIR/min_const_fn.rs:105:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:106:44 + --> $DIR/min_const_fn.rs:107:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable - --> $DIR/min_const_fn.rs:108:14 + --> $DIR/min_const_fn.rs:109:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:113:6 + --> $DIR/min_const_fn.rs:114:6 | LL | impl Foo { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:118:6 + --> $DIR/min_const_fn.rs:119:6 | LL | impl Foo { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:123:6 + --> $DIR/min_const_fn.rs:124:6 | LL | impl Foo { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:129:24 + --> $DIR/min_const_fn.rs:130:24 | LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:131:34 + --> $DIR/min_const_fn.rs:132:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:133:22 + --> $DIR/min_const_fn.rs:134:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:134:23 + --> $DIR/min_const_fn.rs:135:23 | LL | const fn no_rpit() -> impl std::fmt::Debug {} | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:135:23 + --> $DIR/min_const_fn.rs:136:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:136:32 + --> $DIR/min_const_fn.rs:137:32 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0515]: cannot return reference to temporary value - --> $DIR/min_const_fn.rs:136:63 + --> $DIR/min_const_fn.rs:137:63 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^-- @@ -296,31 +296,31 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | returns a reference to data owned by the current function error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:144:41 + --> $DIR/min_const_fn.rs:145:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:147:21 + --> $DIR/min_const_fn.rs:148:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:149:27 + --> $DIR/min_const_fn.rs:150:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 37 previous errors diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 9523fcbfc6..8b423da788 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -99,7 +99,8 @@ const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } //~^ ERROR casting pointers to ints is unstable const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } //~^ ERROR loops and conditional expressions are not stable in const fn -const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn +const fn foo30_5(b: bool) { while b { } } +//~^ ERROR loops are not allowed in const fn const fn foo30_6() -> bool { let x = true; x } const fn foo36(a: bool, b: bool) -> bool { a && b } //~^ ERROR loops and conditional expressions are not stable in const fn diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 28a5ffb201..211902b687 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -11,7 +11,7 @@ LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:44:28 @@ -26,7 +26,7 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:51:27 @@ -41,7 +41,7 @@ LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable --> $DIR/min_const_fn.rs:58:39 @@ -50,7 +50,7 @@ LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn.rs:76:16 @@ -59,7 +59,7 @@ LL | const fn foo11(t: T) -> T { t } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn.rs:78:18 @@ -68,7 +68,7 @@ LL | const fn foo11_2(t: T) -> T { t } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn.rs:80:33 @@ -77,7 +77,7 @@ LL | const fn foo19(f: f32) -> f32 { f * 2.0 } | ^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn.rs:82:35 @@ -86,7 +86,7 @@ LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f } | ^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int and `bool` operations are stable in const fn --> $DIR/min_const_fn.rs:84:35 @@ -95,7 +95,7 @@ LL | const fn foo19_3(f: f32) -> f32 { -f } | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn.rs:86:43 @@ -104,7 +104,7 @@ LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g } | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: cannot access `static` items in const fn --> $DIR/min_const_fn.rs:90:27 @@ -113,7 +113,7 @@ LL | const fn foo25() -> u32 { BAR } | ^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: cannot access `static` items in const fn --> $DIR/min_const_fn.rs:91:36 @@ -122,7 +122,7 @@ LL | const fn foo26() -> &'static u32 { &BAR } | ^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:92:42 @@ -131,7 +131,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:94:63 @@ -140,7 +140,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:96:42 @@ -149,7 +149,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: casting pointers to ints is unstable in const fn --> $DIR/min_const_fn.rs:98:63 @@ -158,7 +158,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } | ^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:100:38 @@ -167,127 +167,127 @@ LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable -error[E0723]: loops and conditional expressions are not stable in const fn +error[E0723]: loops are not allowed in const fn --> $DIR/min_const_fn.rs:102:29 | LL | const fn foo30_5(b: bool) { while b { } } | ^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:104:44 + --> $DIR/min_const_fn.rs:105:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: loops and conditional expressions are not stable in const fn - --> $DIR/min_const_fn.rs:106:44 + --> $DIR/min_const_fn.rs:107:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable - --> $DIR/min_const_fn.rs:108:14 + --> $DIR/min_const_fn.rs:109:14 | LL | const fn inc(x: &mut i32) { *x += 1 } | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:113:6 + --> $DIR/min_const_fn.rs:114:6 | LL | impl Foo { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:118:6 + --> $DIR/min_const_fn.rs:119:6 | LL | impl Foo { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:123:6 + --> $DIR/min_const_fn.rs:124:6 | LL | impl Foo { | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:129:24 + --> $DIR/min_const_fn.rs:130:24 | LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:131:34 + --> $DIR/min_const_fn.rs:132:34 | LL | const fn no_apit2(_x: AlanTuring) {} | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:133:22 + --> $DIR/min_const_fn.rs:134:22 | LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/min_const_fn.rs:134:23 + --> $DIR/min_const_fn.rs:135:23 | LL | const fn no_rpit() -> impl std::fmt::Debug {} | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:135:23 + --> $DIR/min_const_fn.rs:136:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:136:32 + --> $DIR/min_const_fn.rs:137:32 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable warning[E0515]: cannot return reference to temporary value - --> $DIR/min_const_fn.rs:136:63 + --> $DIR/min_const_fn.rs:137:63 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } | ^-- @@ -300,31 +300,31 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } = note: for more information, try `rustc --explain E0729` error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable - --> $DIR/min_const_fn.rs:144:41 + --> $DIR/min_const_fn.rs:145:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:147:21 + --> $DIR/min_const_fn.rs:148:21 | LL | const fn no_fn_ptrs(_x: fn()) {} | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable - --> $DIR/min_const_fn.rs:149:27 + --> $DIR/min_const_fn.rs:150:27 | LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 36 previous errors diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr index 9ffb549057..0ea950d678 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr @@ -5,7 +5,7 @@ LL | x.0.field; | ^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn_dyn.rs:12:66 @@ -14,7 +14,7 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0716]: temporary value dropped while borrowed --> $DIR/min_const_fn_dyn.rs:12:67 diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr index 9ded93c167..02ddb03952 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr @@ -5,7 +5,7 @@ LL | x.0.field; | ^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable --> $DIR/min_const_fn_dyn.rs:12:66 @@ -14,7 +14,7 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } | ^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable warning[E0716]: temporary value dropped while borrowed --> $DIR/min_const_fn_dyn.rs:12:67 diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr index 5316d07afa..085ad1aad3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr @@ -5,7 +5,7 @@ LL | x.0.field; | ^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: function pointers in const fn are unstable --> $DIR/min_const_fn_fn_ptr.rs:14:59 @@ -14,7 +14,7 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) } | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs b/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs index 23bd733254..cb8f74186b 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::UnsafeCell; use std::sync::atomic::AtomicU32; diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr index c52d7c8511..0af5bdca81 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -5,7 +5,7 @@ LL | const fn bar() -> u32 { foo() } | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2` is not stable as `const fn` --> $DIR/min_const_fn_libstd_stability.rs:22:26 @@ -14,7 +14,7 @@ LL | const fn bar2() -> u32 { foo2() } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_fn_libstd_stability.rs:26:26 @@ -23,7 +23,7 @@ LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } | ^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2_gated` is not stable as `const fn` --> $DIR/min_const_fn_libstd_stability.rs:34:32 @@ -32,7 +32,7 @@ LL | const fn bar2_gated() -> u32 { foo2_gated() } | ^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr index d1de5daa74..d3f2ece1f9 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr @@ -5,7 +5,7 @@ LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51911 - = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constant functions is unstable --> $DIR/min_const_fn_unsafe.rs:53:70 @@ -14,7 +14,7 @@ LL | const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51911 - = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constant functions is unstable --> $DIR/min_const_fn_unsafe.rs:56:83 @@ -23,7 +23,7 @@ LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static u | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51911 - = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error[E0658]: unions in const fn are unstable --> $DIR/min_const_fn_unsafe.rs:63:5 @@ -32,7 +32,7 @@ LL | Foo { x: () }.y | ^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51909 - = help: add #![feature(const_fn_union)] to the crate attributes to enable + = help: add `#![feature(const_fn_union)]` to the crate attributes to enable error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block --> $DIR/min_const_fn_unsafe.rs:50:77 diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr index af39b99e90..bc6f8c5960 100644 --- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr @@ -5,7 +5,7 @@ LL | const unsafe fn bar() -> u32 { unsafe { foo() } } | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2` is not stable as `const fn` --> $DIR/min_const_unsafe_fn_libstd_stability.rs:22:42 @@ -14,7 +14,7 @@ LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: only int, `bool` and `char` operations are stable in const fn --> $DIR/min_const_unsafe_fn_libstd_stability.rs:26:33 @@ -23,7 +23,7 @@ LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } | ^^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2_gated` is not stable as `const fn` --> $DIR/min_const_unsafe_fn_libstd_stability.rs:34:48 @@ -32,7 +32,7 @@ LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } | ^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr index e4534d9ab9..a14fd740c6 100644 --- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr @@ -5,7 +5,7 @@ LL | const unsafe fn bar() -> u32 { foo() } | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2` is not stable as `const fn` --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:22:33 @@ -14,7 +14,7 @@ LL | const unsafe fn bar2() -> u32 { foo2() } | ^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: can only call other `const fn` within a `const fn`, but `const foo2_gated` is not stable as `const fn` --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:30:39 @@ -23,7 +23,7 @@ LL | const unsafe fn bar2_gated() -> u32 { foo2_gated() } | ^^^^^^^^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr index ed55849124..7c121be0d5 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr @@ -5,7 +5,7 @@ LL | let b = &mut a; | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable --> $DIR/mutable_borrow.rs:12:13 @@ -14,7 +14,7 @@ LL | let b = &mut a; | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/run-pass/consts/mozjs-error.rs b/src/test/ui/consts/mozjs-error.rs similarity index 100% rename from src/test/run-pass/consts/mozjs-error.rs rename to src/test/ui/consts/mozjs-error.rs diff --git a/src/test/run-pass/consts/non-scalar-cast.rs b/src/test/ui/consts/non-scalar-cast.rs similarity index 100% rename from src/test/run-pass/consts/non-scalar-cast.rs rename to src/test/ui/consts/non-scalar-cast.rs diff --git a/src/test/ui/consts/projection_qualif.stderr b/src/test/ui/consts/projection_qualif.stderr index c270296ac8..0c09f7ec52 100644 --- a/src/test/ui/consts/projection_qualif.stderr +++ b/src/test/ui/consts/projection_qualif.stderr @@ -17,7 +17,7 @@ LL | unsafe { *b = 5; } | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51911 - = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/promote_const_let.polonius.stderr b/src/test/ui/consts/promote_const_let.polonius.stderr new file mode 100644 index 0000000000..cf41bd7bdb --- /dev/null +++ b/src/test/ui/consts/promote_const_let.polonius.stderr @@ -0,0 +1,29 @@ +error[E0597]: `y` does not live long enough + --> $DIR/promote_const_let.rs:4:9 + | +LL | let x: &'static u32 = { + | - borrow later stored here +LL | let y = 42; +LL | &y + | ^^ borrowed value does not live long enough +LL | }; + | - `y` dropped here while still borrowed + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote_const_let.rs:6:28 + | +LL | let x: &'static u32 = &{ + | ____________------------____^ + | | | + | | type annotation requires that borrow lasts for `'static` +LL | | let y = 42; +LL | | y +LL | | }; + | |_____^ creates a temporary which is freed while still in use +LL | } + | - temporary value is freed at the end of this statement + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0597, E0716. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/promote_evaluation_unused_result.rs b/src/test/ui/consts/promote_evaluation_unused_result.rs index dc21b9fe8c..4eda785bb8 100644 --- a/src/test/ui/consts/promote_evaluation_unused_result.rs +++ b/src/test/ui/consts/promote_evaluation_unused_result.rs @@ -1,4 +1,4 @@ -//compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { diff --git a/src/test/ui/consts/promote_fn_calls.rs b/src/test/ui/consts/promote_fn_calls.rs index 6b6eea3636..8995aaacd8 100644 --- a/src/test/ui/consts/promote_fn_calls.rs +++ b/src/test/ui/consts/promote_fn_calls.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:promotable_const_fn_lib.rs extern crate promotable_const_fn_lib; diff --git a/src/test/ui/consts/promote_fn_calls_std.rs b/src/test/ui/consts/promote_fn_calls_std.rs index d982f35020..bdb472f3a9 100644 --- a/src/test/ui/consts/promote_fn_calls_std.rs +++ b/src/test/ui/consts/promote_fn_calls_std.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let x: &'static u8 = &u8::max_value(); diff --git a/src/test/ui/consts/promoted-validation-55454.rs b/src/test/ui/consts/promoted-validation-55454.rs index 5e193b1b7d..23cae4fb57 100644 --- a/src/test/ui/consts/promoted-validation-55454.rs +++ b/src/test/ui/consts/promoted-validation-55454.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/issues/55454 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(PartialEq)] struct This(T); diff --git a/src/test/ui/consts/promoted_regression.rs b/src/test/ui/consts/promoted_regression.rs index 68b9a20ecf..d57036ae58 100644 --- a/src/test/ui/consts/promoted_regression.rs +++ b/src/test/ui/consts/promoted_regression.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _ = &[("", ""); 3]; diff --git a/src/test/run-pass/consts/promotion.rs b/src/test/ui/consts/promotion.rs similarity index 100% rename from src/test/run-pass/consts/promotion.rs rename to src/test/ui/consts/promotion.rs diff --git a/src/test/run-pass/consts/references.rs b/src/test/ui/consts/references.rs similarity index 100% rename from src/test/run-pass/consts/references.rs rename to src/test/ui/consts/references.rs diff --git a/src/test/run-pass/consts/repeat_match.rs b/src/test/ui/consts/repeat_match.rs similarity index 100% rename from src/test/run-pass/consts/repeat_match.rs rename to src/test/ui/consts/repeat_match.rs diff --git a/src/test/run-pass/consts/return-in-const-fn.rs b/src/test/ui/consts/return-in-const-fn.rs similarity index 100% rename from src/test/run-pass/consts/return-in-const-fn.rs rename to src/test/ui/consts/return-in-const-fn.rs diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.rs new file mode 100644 index 0000000000..68a9227dea --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength +// ignore-compare-mode-nll +#![feature(const_in_array_repeat_expressions, nll)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +const fn type_no_copy() -> Option { + None +} + +const fn type_copy() -> u32 { + 3 +} + +fn no_copy() { + const ARR: [Option; 2] = [type_no_copy(); 2]; + //~^ ERROR the trait bound `std::option::Option: std::marker::Copy` is not satisfied [E0277] +} + +fn copy() { + const ARR: [u32; 2] = [type_copy(); 2]; +} + +fn main() {} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.stderr b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.stderr new file mode 100644 index 0000000000..82272af958 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-fns.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `std::option::Option: std::marker::Copy` is not satisfied + --> $DIR/const-fns.rs:18:35 + | +LL | const ARR: [Option; 2] = [type_no_copy(); 2]; + | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::option::Option` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs new file mode 100644 index 0000000000..3b7d7e5b51 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength +// ignore-compare-mode-nll +// compile-flags: -Z borrowck=migrate +#![feature(const_in_array_repeat_expressions)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_multiple_elements() { + let x = None; + let arr: [Option; 2] = [x; 2]; + //~^ ERROR the trait bound `std::option::Option: std::marker::Copy` is not satisfied [E0277] + } + + fn no_impl_copy_value_multiple_elements() { + let x = Some(Bar); + let arr: [Option; 2] = [x; 2]; + //~^ ERROR the trait bound `std::option::Option: std::marker::Copy` is not satisfied [E0277] + } +} + +fn main() {} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.stderr b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.stderr new file mode 100644 index 0000000000..aad6763f15 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `std::option::Option: std::marker::Copy` is not satisfied + --> $DIR/migrate-fail.rs:15:37 + | +LL | let arr: [Option; 2] = [x; 2]; + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::option::Option` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error[E0277]: the trait bound `std::option::Option: std::marker::Copy` is not satisfied + --> $DIR/migrate-fail.rs:21:37 + | +LL | let arr: [Option; 2] = [x; 2]; + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::option::Option` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs new file mode 100644 index 0000000000..bfa8ebcfdd --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs @@ -0,0 +1,128 @@ +// check-pass +// compile-flags: -Z borrowck=migrate +// ignore-compare-mode-nll +#![feature(const_in_array_repeat_expressions)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +mod constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn no_impl_copy_value_no_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_value_single_element() { + const FOO: Option = Some(Bar); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_value_multiple_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_empty_value_one_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_value_no_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_value_one_element() { + const FOO: Option = Some(4); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_value_multiple_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 2] = [FOO; 2]; + } +} + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + let x = None; + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + let x = None; + let arr: [Option; 1] = [x; 1]; + } + + fn no_impl_copy_value_no_elements() { + let x = Some(Bar); + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_value_single_element() { + let x = Some(Bar); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_no_elements() { + let x: Option = None; + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_empty_value_one_element() { + let x: Option = None; + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + let x: Option = None; + let arr: [Option; 2] = [x; 2]; + } + + fn impl_copy_value_no_elements() { + let x: Option = Some(4); + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_value_one_element() { + let x: Option = Some(4); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_value_multiple_elements() { + let x: Option = Some(4); + let arr: [Option; 2] = [x; 2]; + } +} + +fn main() {} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs new file mode 100644 index 0000000000..dc1193a2fe --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs @@ -0,0 +1,25 @@ +// ignore-tidy-linelength +// ignore-compare-mode-nll +#![feature(const_in_array_repeat_expressions, nll)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_multiple_elements() { + let x = None; + let arr: [Option; 2] = [x; 2]; + //~^ ERROR the trait bound `std::option::Option: std::marker::Copy` is not satisfied [E0277] + } + + fn no_impl_copy_value_multiple_elements() { + let x = Some(Bar); + let arr: [Option; 2] = [x; 2]; + //~^ ERROR the trait bound `std::option::Option: std::marker::Copy` is not satisfied [E0277] + } +} + +fn main() {} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.stderr b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.stderr new file mode 100644 index 0000000000..fd32484ff9 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `std::option::Option: std::marker::Copy` is not satisfied + --> $DIR/nll-fail.rs:14:37 + | +LL | let arr: [Option; 2] = [x; 2]; + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::option::Option` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error[E0277]: the trait bound `std::option::Option: std::marker::Copy` is not satisfied + --> $DIR/nll-fail.rs:20:37 + | +LL | let arr: [Option; 2] = [x; 2]; + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::option::Option` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs new file mode 100644 index 0000000000..a304f877ab --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs @@ -0,0 +1,127 @@ +// check-pass +// ignore-compare-mode-nll +#![allow(warnings)] +#![feature(const_in_array_repeat_expressions, nll)] + +// Some type that is not copyable. +struct Bar; + +mod constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn no_impl_copy_value_no_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_value_single_element() { + const FOO: Option = Some(Bar); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_value_multiple_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_empty_value_one_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_value_no_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_value_one_element() { + const FOO: Option = Some(4); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_value_multiple_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 2] = [FOO; 2]; + } +} + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + let x = None; + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + let x = None; + let arr: [Option; 1] = [x; 1]; + } + + fn no_impl_copy_value_no_elements() { + let x = Some(Bar); + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_value_single_element() { + let x = Some(Bar); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_no_elements() { + let x: Option = None; + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_empty_value_one_element() { + let x: Option = None; + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + let x: Option = None; + let arr: [Option; 2] = [x; 2]; + } + + fn impl_copy_value_no_elements() { + let x: Option = Some(4); + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_value_one_element() { + let x: Option = Some(4); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_value_multiple_elements() { + let x: Option = Some(4); + let arr: [Option; 2] = [x; 2]; + } +} + +fn main() {} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs new file mode 100644 index 0000000000..27bf5dabf5 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(const_in_array_repeat_expressions)] + +#[derive(Debug, Eq, PartialEq)] +struct Bar; + +fn main() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + + assert_eq!(ARR, [None::, None::]); +} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs new file mode 100644 index 0000000000..35484d265b --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs @@ -0,0 +1,10 @@ +// ignore-tidy-linelength +#![feature(const_in_array_repeat_expressions)] + +#[derive(Copy, Clone)] +struct Foo(T); + +fn main() { + [Foo(String::new()); 4]; + //~^ ERROR the trait bound `Foo: std::marker::Copy` is not satisfied [E0277] +} diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.stderr b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.stderr new file mode 100644 index 0000000000..186909e469 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `Foo: std::marker::Copy` is not satisfied + --> $DIR/trait-error.rs:8:5 + | +LL | [Foo(String::new()); 4]; + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `Foo` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/self_normalization.rs b/src/test/ui/consts/self_normalization.rs new file mode 100644 index 0000000000..b2a34f5877 --- /dev/null +++ b/src/test/ui/consts/self_normalization.rs @@ -0,0 +1,16 @@ +// check-pass + +fn testfn(_arr: &mut [(); 0]) {} + +trait TestTrait { + fn method(); +} + +impl TestTrait for [(); 0] { + fn method() { + let mut arr: Self = [(); 0]; + testfn(&mut arr); + } +} + +fn main() {} diff --git a/src/test/ui/consts/self_normalization2.rs b/src/test/ui/consts/self_normalization2.rs new file mode 100644 index 0000000000..4fca38cba3 --- /dev/null +++ b/src/test/ui/consts/self_normalization2.rs @@ -0,0 +1,21 @@ +// check-pass + +trait Gen { + fn gen(x: Self) -> T; +} + +struct A; + +impl Gen<[(); 0]> for A { + fn gen(x: Self) -> [(); 0] { + [] + } +} + +fn array() -> impl Gen<[(); 0]> { + A +} + +fn main() { + let [] = Gen::gen(array()); +} diff --git a/src/test/run-pass/consts/signed_enum_discr.rs b/src/test/ui/consts/signed_enum_discr.rs similarity index 100% rename from src/test/run-pass/consts/signed_enum_discr.rs rename to src/test/ui/consts/signed_enum_discr.rs diff --git a/src/test/ui/consts/single_variant_match_ice.stderr b/src/test/ui/consts/single_variant_match_ice.stderr index 851733726a..3f37a6c645 100644 --- a/src/test/ui/consts/single_variant_match_ice.stderr +++ b/src/test/ui/consts/single_variant_match_ice.stderr @@ -17,7 +17,7 @@ LL | match *self { | ^^^^^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/static-cycle-error.rs b/src/test/ui/consts/static-cycle-error.rs index 8e69d3eda6..9ce050aae2 100644 --- a/src/test/ui/consts/static-cycle-error.rs +++ b/src/test/ui/consts/static-cycle-error.rs @@ -1,4 +1,4 @@ -// compile-pass +// check-pass struct Foo { foo: Option<&'static Foo> diff --git a/src/test/ui/consts/static_mut_containing_mut_ref.rs b/src/test/ui/consts/static_mut_containing_mut_ref.rs index 27e1a11116..df09c76c55 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42]; diff --git a/src/test/ui/consts/std/slice.rs b/src/test/ui/consts/std/slice.rs index ad38105b6a..f19defc64d 100644 --- a/src/test/ui/consts/std/slice.rs +++ b/src/test/ui/consts/std/slice.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Wrap(T); unsafe impl Send for Wrap {} diff --git a/src/test/run-pass/consts/transmute-const.rs b/src/test/ui/consts/transmute-const.rs similarity index 100% rename from src/test/run-pass/consts/transmute-const.rs rename to src/test/ui/consts/transmute-const.rs diff --git a/src/test/run-pass/consts/tuple-struct-constructors.rs b/src/test/ui/consts/tuple-struct-constructors.rs similarity index 100% rename from src/test/run-pass/consts/tuple-struct-constructors.rs rename to src/test/ui/consts/tuple-struct-constructors.rs diff --git a/src/test/ui/consts/underscore_const_names.rs b/src/test/ui/consts/underscore_const_names.rs index 8d57e5074f..d0e625bf19 100644 --- a/src/test/ui/consts/underscore_const_names.rs +++ b/src/test/ui/consts/underscore_const_names.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused)] diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.rs b/src/test/ui/consts/uninhabited-const-issue-61744.rs index 21fbbf8cfb..4509ebc633 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.rs +++ b/src/test/ui/consts/uninhabited-const-issue-61744.rs @@ -1,11 +1,11 @@ // compile-fail pub const unsafe fn fake_type() -> T { - hint_unreachable() + hint_unreachable() //~ ERROR any use of this value will cause an error } pub const unsafe fn hint_unreachable() -> ! { - fake_type() //~ ERROR any use of this value will cause an error + fake_type() } trait Const { diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index 5c28554371..f390676fda 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -1,17 +1,66 @@ error: any use of this value will cause an error - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:4:5 | -LL | fake_type() - | ^^^^^^^^^^^ +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ | | - | tried to call a function with return type T passing return place of type ! + | reached the configured maximum number of stack frames | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:8:5 | inside call to `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:12:36 ... LL | const CONSTANT: i32 = unsafe { fake_type() }; | --------------------------------------------- | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error[E0080]: erroneous constant used --> $DIR/uninhabited-const-issue-61744.rs:18:10 diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs index 16b05310b9..508ff7e0ae 100644 --- a/src/test/ui/consts/union_constant.rs +++ b/src/test/ui/consts/union_constant.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) union Uninit { _never_use: *const u8, diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/ui/core-run-destroy.rs similarity index 97% rename from src/test/run-pass/core-run-destroy.rs rename to src/test/ui/core-run-destroy.rs index 625e517938..b3614bfd5b 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/ui/core-run-destroy.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(stable_features)] #![allow(deprecated)] @@ -6,6 +8,7 @@ // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes +// ignore-vxworks no 'cat' and 'sleep' // N.B., these tests kill child processes. Valgrind sees these children as leaking // memory, which makes for some *confusing* logs. That's why these are here diff --git a/src/test/run-pass/crate-leading-sep.rs b/src/test/ui/crate-leading-sep.rs similarity index 88% rename from src/test/run-pass/crate-leading-sep.rs rename to src/test/ui/crate-leading-sep.rs index 26d4df433a..ca5905fab4 100644 --- a/src/test/run-pass/crate-leading-sep.rs +++ b/src/test/ui/crate-leading-sep.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 fn main() { diff --git a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs b/src/test/ui/crate-method-reexport-grrrrrrr.rs similarity index 97% rename from src/test/run-pass/crate-method-reexport-grrrrrrr.rs rename to src/test/ui/crate-method-reexport-grrrrrrr.rs index 0d243e14b9..eefcf7738a 100644 --- a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs +++ b/src/test/ui/crate-method-reexport-grrrrrrr.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(box_syntax)] diff --git a/src/test/run-pass/crate-name-attr-used.rs b/src/test/ui/crate-name-attr-used.rs similarity index 93% rename from src/test/run-pass/crate-name-attr-used.rs rename to src/test/ui/crate-name-attr-used.rs index 666f80e566..ad53a53143 100644 --- a/src/test/run-pass/crate-name-attr-used.rs +++ b/src/test/ui/crate-name-attr-used.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags:--crate-name crate_name_attr_used -F unused-attributes // pretty-expanded FIXME #23616 diff --git a/src/test/ui/crate-name-mismatch.rs b/src/test/ui/crate-name-mismatch.rs index 49a257f7b8..23ad39a6f9 100644 --- a/src/test/ui/crate-name-mismatch.rs +++ b/src/test/ui/crate-name-mismatch.rs @@ -1,6 +1,6 @@ // compile-flags: --crate-name foo #![crate_name = "bar"] -//~^ ERROR: --crate-name and #[crate_name] are required to match, but `foo` != `bar` +//~^ ERROR: `--crate-name` and `#[crate_name]` are required to match, but `foo` != `bar` fn main() {} diff --git a/src/test/ui/crate-name-mismatch.stderr b/src/test/ui/crate-name-mismatch.stderr index 4784db86de..96618570d8 100644 --- a/src/test/ui/crate-name-mismatch.stderr +++ b/src/test/ui/crate-name-mismatch.stderr @@ -1,4 +1,4 @@ -error: --crate-name and #[crate_name] are required to match, but `foo` != `bar` +error: `--crate-name` and `#[crate_name]` are required to match, but `foo` != `bar` --> $DIR/crate-name-mismatch.rs:3:1 | LL | #![crate_name = "bar"] diff --git a/src/test/run-pass/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs similarity index 100% rename from src/test/run-pass/cross-crate/anon-extern-mod-cross-crate-2.rs rename to src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs rename to src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/anon_trait_static_method_lib.rs b/src/test/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/anon_trait_static_method_lib.rs rename to src/test/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_borrow_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_borrow_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_borrow_lib.rs rename to src/test/ui/cross-crate/auxiliary/cci_borrow_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_capture_clause.rs b/src/test/ui/cross-crate/auxiliary/cci_capture_clause.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_capture_clause.rs rename to src/test/ui/cross-crate/auxiliary/cci_capture_clause.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_const.rs b/src/test/ui/cross-crate/auxiliary/cci_const.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_const.rs rename to src/test/ui/cross-crate/auxiliary/cci_const.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_impl_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_impl_lib.rs rename to src/test/ui/cross-crate/auxiliary/cci_impl_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_iter_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_iter_lib.rs rename to src/test/ui/cross-crate/auxiliary/cci_iter_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_nested_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_nested_lib.rs rename to src/test/ui/cross-crate/auxiliary/cci_nested_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/cci_no_inline_lib.rs b/src/test/ui/cross-crate/auxiliary/cci_no_inline_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/cci_no_inline_lib.rs rename to src/test/ui/cross-crate/auxiliary/cci_no_inline_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/moves_based_on_type_lib.rs b/src/test/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/moves_based_on_type_lib.rs rename to src/test/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/newtype_struct_xc.rs b/src/test/ui/cross-crate/auxiliary/newtype_struct_xc.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/newtype_struct_xc.rs rename to src/test/ui/cross-crate/auxiliary/newtype_struct_xc.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/pub_static_array.rs b/src/test/ui/cross-crate/auxiliary/pub_static_array.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/pub_static_array.rs rename to src/test/ui/cross-crate/auxiliary/pub_static_array.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/reexported_static_methods.rs b/src/test/ui/cross-crate/auxiliary/reexported_static_methods.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/reexported_static_methods.rs rename to src/test/ui/cross-crate/auxiliary/reexported_static_methods.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs b/src/test/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs rename to src/test/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_address_insignificant.rs b/src/test/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/xcrate_address_insignificant.rs rename to src/test/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_associated_type_defaults.rs b/src/test/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/xcrate_associated_type_defaults.rs rename to src/test/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs b/src/test/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs rename to src/test/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_static_addresses.rs b/src/test/ui/cross-crate/auxiliary/xcrate_static_addresses.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/xcrate_static_addresses.rs rename to src/test/ui/cross-crate/auxiliary/xcrate_static_addresses.rs diff --git a/src/test/run-pass/cross-crate/auxiliary/xcrate_unit_struct.rs b/src/test/ui/cross-crate/auxiliary/xcrate_unit_struct.rs similarity index 100% rename from src/test/run-pass/cross-crate/auxiliary/xcrate_unit_struct.rs rename to src/test/ui/cross-crate/auxiliary/xcrate_unit_struct.rs diff --git a/src/test/run-pass/cross-crate/cci_borrow.rs b/src/test/ui/cross-crate/cci_borrow.rs similarity index 100% rename from src/test/run-pass/cross-crate/cci_borrow.rs rename to src/test/ui/cross-crate/cci_borrow.rs diff --git a/src/test/run-pass/cross-crate/cci_capture_clause.rs b/src/test/ui/cross-crate/cci_capture_clause.rs similarity index 100% rename from src/test/run-pass/cross-crate/cci_capture_clause.rs rename to src/test/ui/cross-crate/cci_capture_clause.rs diff --git a/src/test/run-pass/cross-crate/cci_impl_exe.rs b/src/test/ui/cross-crate/cci_impl_exe.rs similarity index 100% rename from src/test/run-pass/cross-crate/cci_impl_exe.rs rename to src/test/ui/cross-crate/cci_impl_exe.rs diff --git a/src/test/run-pass/cross-crate/cci_iter_exe.rs b/src/test/ui/cross-crate/cci_iter_exe.rs similarity index 100% rename from src/test/run-pass/cross-crate/cci_iter_exe.rs rename to src/test/ui/cross-crate/cci_iter_exe.rs diff --git a/src/test/run-pass/cross-crate/cci_nested_exe.rs b/src/test/ui/cross-crate/cci_nested_exe.rs similarity index 100% rename from src/test/run-pass/cross-crate/cci_nested_exe.rs rename to src/test/ui/cross-crate/cci_nested_exe.rs diff --git a/src/test/run-pass/cross-crate/cci_no_inline_exe.rs b/src/test/ui/cross-crate/cci_no_inline_exe.rs similarity index 100% rename from src/test/run-pass/cross-crate/cci_no_inline_exe.rs rename to src/test/ui/cross-crate/cci_no_inline_exe.rs diff --git a/src/test/run-pass/cross-crate/cross-crate-const-pat.rs b/src/test/ui/cross-crate/cross-crate-const-pat.rs similarity index 100% rename from src/test/run-pass/cross-crate/cross-crate-const-pat.rs rename to src/test/ui/cross-crate/cross-crate-const-pat.rs diff --git a/src/test/run-pass/cross-crate/cross-crate-newtype-struct-pat.rs b/src/test/ui/cross-crate/cross-crate-newtype-struct-pat.rs similarity index 100% rename from src/test/run-pass/cross-crate/cross-crate-newtype-struct-pat.rs rename to src/test/ui/cross-crate/cross-crate-newtype-struct-pat.rs diff --git a/src/test/run-pass/cross-crate/moves-based-on-type-cross-crate.rs b/src/test/ui/cross-crate/moves-based-on-type-cross-crate.rs similarity index 100% rename from src/test/run-pass/cross-crate/moves-based-on-type-cross-crate.rs rename to src/test/ui/cross-crate/moves-based-on-type-cross-crate.rs diff --git a/src/test/run-pass/cross-crate/reexported-static-methods-cross-crate.rs b/src/test/ui/cross-crate/reexported-static-methods-cross-crate.rs similarity index 100% rename from src/test/run-pass/cross-crate/reexported-static-methods-cross-crate.rs rename to src/test/ui/cross-crate/reexported-static-methods-cross-crate.rs diff --git a/src/test/run-pass/cross-crate/static-array-across-crate.rs b/src/test/ui/cross-crate/static-array-across-crate.rs similarity index 100% rename from src/test/run-pass/cross-crate/static-array-across-crate.rs rename to src/test/ui/cross-crate/static-array-across-crate.rs diff --git a/src/test/run-pass/cross-crate/xcrate-address-insignificant.rs b/src/test/ui/cross-crate/xcrate-address-insignificant.rs similarity index 100% rename from src/test/run-pass/cross-crate/xcrate-address-insignificant.rs rename to src/test/ui/cross-crate/xcrate-address-insignificant.rs diff --git a/src/test/run-pass/cross-crate/xcrate-associated-type-defaults.rs b/src/test/ui/cross-crate/xcrate-associated-type-defaults.rs similarity index 100% rename from src/test/run-pass/cross-crate/xcrate-associated-type-defaults.rs rename to src/test/ui/cross-crate/xcrate-associated-type-defaults.rs diff --git a/src/test/run-pass/cross-crate/xcrate-static-addresses.rs b/src/test/ui/cross-crate/xcrate-static-addresses.rs similarity index 100% rename from src/test/run-pass/cross-crate/xcrate-static-addresses.rs rename to src/test/ui/cross-crate/xcrate-static-addresses.rs diff --git a/src/test/run-pass/cross-crate/xcrate-trait-lifetime-param.rs b/src/test/ui/cross-crate/xcrate-trait-lifetime-param.rs similarity index 100% rename from src/test/run-pass/cross-crate/xcrate-trait-lifetime-param.rs rename to src/test/ui/cross-crate/xcrate-trait-lifetime-param.rs diff --git a/src/test/run-pass/cross-crate/xcrate-unit-struct.rs b/src/test/ui/cross-crate/xcrate-unit-struct.rs similarity index 100% rename from src/test/run-pass/cross-crate/xcrate-unit-struct.rs rename to src/test/ui/cross-crate/xcrate-unit-struct.rs diff --git a/src/test/run-pass/cross-crate/xcrate_generic_fn_nested_return.rs b/src/test/ui/cross-crate/xcrate_generic_fn_nested_return.rs similarity index 100% rename from src/test/run-pass/cross-crate/xcrate_generic_fn_nested_return.rs rename to src/test/ui/cross-crate/xcrate_generic_fn_nested_return.rs diff --git a/src/test/ui/cross/cross-fn-cache-hole.stderr b/src/test/ui/cross/cross-fn-cache-hole.stderr index 3bedd0dac2..0d325bb7ec 100644 --- a/src/test/ui/cross/cross-fn-cache-hole.stderr +++ b/src/test/ui/cross/cross-fn-cache-hole.stderr @@ -11,7 +11,7 @@ LL | | } | |_^ the trait `Bar` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/crt-static-off-works.rs b/src/test/ui/crt-static-off-works.rs similarity index 94% rename from src/test/run-pass/crt-static-off-works.rs rename to src/test/ui/crt-static-off-works.rs index 64d96709af..911467ee54 100644 --- a/src/test/run-pass/crt-static-off-works.rs +++ b/src/test/ui/crt-static-off-works.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] // compile-flags:-C target-feature=-crt-static -Z unstable-options // ignore-musl - requires changing the linker which is hard diff --git a/src/test/run-pass/crt-static-on-works.rs b/src/test/ui/crt-static-on-works.rs similarity index 93% rename from src/test/run-pass/crt-static-on-works.rs rename to src/test/ui/crt-static-on-works.rs index 272fcfe3b5..21407b1b91 100644 --- a/src/test/run-pass/crt-static-on-works.rs +++ b/src/test/ui/crt-static-on-works.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] // compile-flags:-C target-feature=+crt-static -Z unstable-options diff --git a/src/test/ui/custom_attribute.rs b/src/test/ui/custom_attribute.rs index 9cb43ab07a..13c873c3b7 100644 --- a/src/test/ui/custom_attribute.rs +++ b/src/test/ui/custom_attribute.rs @@ -1,9 +1,9 @@ #![feature(stmt_expr_attributes)] -#[foo] //~ ERROR The attribute `foo` +#[foo] //~ ERROR cannot find attribute macro `foo` in this scope fn main() { - #[foo] //~ ERROR The attribute `foo` + #[foo] //~ ERROR cannot find attribute macro `foo` in this scope let x = (); - #[foo] //~ ERROR The attribute `foo` + #[foo] //~ ERROR cannot find attribute macro `foo` in this scope x } diff --git a/src/test/ui/custom_attribute.stderr b/src/test/ui/custom_attribute.stderr index adb05e3fb2..b4f9f3f49b 100644 --- a/src/test/ui/custom_attribute.stderr +++ b/src/test/ui/custom_attribute.stderr @@ -1,30 +1,20 @@ -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `foo` in this scope --> $DIR/custom_attribute.rs:3:3 | LL | #[foo] | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `foo` in this scope --> $DIR/custom_attribute.rs:5:7 | LL | #[foo] | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `foo` in this scope --> $DIR/custom_attribute.rs:7:7 | LL | #[foo] | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/cycle-generic-bound.rs b/src/test/ui/cycle-generic-bound.rs similarity index 94% rename from src/test/run-pass/cycle-generic-bound.rs rename to src/test/ui/cycle-generic-bound.rs index 56bfa98451..9241f3789d 100644 --- a/src/test/run-pass/cycle-generic-bound.rs +++ b/src/test/ui/cycle-generic-bound.rs @@ -1,3 +1,4 @@ +// run-pass // Regression test for #15477. This test just needs to compile. // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/dead-code-alias-in-pat.rs b/src/test/ui/dead-code-alias-in-pat.rs similarity index 92% rename from src/test/run-pass/dead-code-alias-in-pat.rs rename to src/test/ui/dead-code-alias-in-pat.rs index 5b6ca26f1c..69d455f3b6 100644 --- a/src/test/run-pass/dead-code-alias-in-pat.rs +++ b/src/test/ui/dead-code-alias-in-pat.rs @@ -1,3 +1,5 @@ +// run-pass + #![deny(dead_code)] fn main() { diff --git a/src/test/run-pass/dead-code-leading-underscore.rs b/src/test/ui/dead-code-leading-underscore.rs similarity index 96% rename from src/test/run-pass/dead-code-leading-underscore.rs rename to src/test/ui/dead-code-leading-underscore.rs index eff40111ac..1b6e03ab88 100644 --- a/src/test/run-pass/dead-code-leading-underscore.rs +++ b/src/test/ui/dead-code-leading-underscore.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![deny(dead_code)] diff --git a/src/test/ui/dead-code-tuple-struct-field.rs b/src/test/ui/dead-code-tuple-struct-field.rs index 496ce4fb37..92a6795098 100644 --- a/src/test/ui/dead-code-tuple-struct-field.rs +++ b/src/test/ui/dead-code-tuple-struct-field.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(dead_code)] diff --git a/src/test/run-pass/debuginfo-lto.rs b/src/test/ui/debuginfo-lto.rs similarity index 98% rename from src/test/run-pass/debuginfo-lto.rs rename to src/test/ui/debuginfo-lto.rs index 680616fee7..e4beee9e73 100644 --- a/src/test/run-pass/debuginfo-lto.rs +++ b/src/test/ui/debuginfo-lto.rs @@ -1,3 +1,4 @@ +// run-pass // This test case makes sure that we don't run into LLVM's dreaded // "possible ODR violation" assertion when compiling with LTO + Debuginfo. // It covers cases that have traditionally been prone to cause this error. diff --git a/src/test/run-pass/deep.rs b/src/test/ui/deep.rs similarity index 94% rename from src/test/run-pass/deep.rs rename to src/test/ui/deep.rs index 5c3ecd8c22..2bb109c0e3 100644 --- a/src/test/run-pass/deep.rs +++ b/src/test/ui/deep.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten apparently blows the stack fn f(x: isize) -> isize { diff --git a/src/test/run-pass/default-alloc-error-hook.rs b/src/test/ui/default-alloc-error-hook.rs similarity index 97% rename from src/test/run-pass/default-alloc-error-hook.rs rename to src/test/ui/default-alloc-error-hook.rs index 7d1624320e..40f61c2b7d 100644 --- a/src/test/run-pass/default-alloc-error-hook.rs +++ b/src/test/ui/default-alloc-error-hook.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes diff --git a/src/test/run-pass/default-associated-types.rs b/src/test/ui/default-associated-types.rs similarity index 96% rename from src/test/run-pass/default-associated-types.rs rename to src/test/ui/default-associated-types.rs index d7ed943b84..aae70bffa3 100644 --- a/src/test/run-pass/default-associated-types.rs +++ b/src/test/ui/default-associated-types.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(associated_type_defaults)] trait Foo { diff --git a/src/test/run-pass/default-method-parsing.rs b/src/test/ui/default-method-parsing.rs similarity index 88% rename from src/test/run-pass/default-method-parsing.rs rename to src/test/ui/default-method-parsing.rs index 7f66605d7c..9ffb8d94a5 100644 --- a/src/test/run-pass/default-method-parsing.rs +++ b/src/test/ui/default-method-parsing.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/run-pass/default-method-simple.rs b/src/test/ui/default-method-simple.rs similarity index 95% rename from src/test/run-pass/default-method-simple.rs rename to src/test/ui/default-method-simple.rs index d046fce9b6..6f7ae6a3e0 100644 --- a/src/test/run-pass/default-method-simple.rs +++ b/src/test/ui/default-method-simple.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] trait Foo { diff --git a/src/test/run-pass/defaults-well-formedness.rs b/src/test/ui/defaults-well-formedness.rs similarity index 98% rename from src/test/run-pass/defaults-well-formedness.rs rename to src/test/ui/defaults-well-formedness.rs index cbcdb38fbe..3275890616 100644 --- a/src/test/run-pass/defaults-well-formedness.rs +++ b/src/test/ui/defaults-well-formedness.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] trait Trait {} struct Foo(U, V) where U: Trait; diff --git a/src/test/ui/definition-reachable/auxiliary/field-method-macro.rs b/src/test/ui/definition-reachable/auxiliary/field-method-macro.rs new file mode 100644 index 0000000000..30ba70bdfe --- /dev/null +++ b/src/test/ui/definition-reachable/auxiliary/field-method-macro.rs @@ -0,0 +1,23 @@ +#![feature(decl_macro)] + +mod n { + pub struct B(pub(crate) p::C); + impl B { + pub fn new() -> Self { + B(p::C) + } + } + mod p { + pub struct C; + + impl C { + pub fn foo(&self) -> i32 { + 33 + } + } + } +} + +pub macro m() { + n::B::new().0.foo() +} diff --git a/src/test/ui/definition-reachable/auxiliary/nested-fn-macro.rs b/src/test/ui/definition-reachable/auxiliary/nested-fn-macro.rs new file mode 100644 index 0000000000..a39e8c986c --- /dev/null +++ b/src/test/ui/definition-reachable/auxiliary/nested-fn-macro.rs @@ -0,0 +1,11 @@ +#![feature(decl_macro)] + +mod n { + pub(crate) mod p { + pub fn f() -> i32 { 12 } + } +} + +pub macro m() { + n::p::f() +} diff --git a/src/test/ui/definition-reachable/auxiliary/private-use-macro.rs b/src/test/ui/definition-reachable/auxiliary/private-use-macro.rs new file mode 100644 index 0000000000..4f283d9c19 --- /dev/null +++ b/src/test/ui/definition-reachable/auxiliary/private-use-macro.rs @@ -0,0 +1,11 @@ +#![feature(decl_macro)] + +mod n { + pub static S: i32 = 57; +} + +use n::S; + +pub macro m() { + S +} diff --git a/src/test/ui/definition-reachable/field-method.rs b/src/test/ui/definition-reachable/field-method.rs new file mode 100644 index 0000000000..60e895a2f9 --- /dev/null +++ b/src/test/ui/definition-reachable/field-method.rs @@ -0,0 +1,11 @@ +// Check that functions accessible through a field visible to a macro are +// considered reachable + +// aux-build:nested-fn-macro.rs +// run-pass + +extern crate nested_fn_macro; + +fn main() { + assert_eq!(nested_fn_macro::m!(), 12); +} diff --git a/src/test/ui/definition-reachable/nested-fn.rs b/src/test/ui/definition-reachable/nested-fn.rs new file mode 100644 index 0000000000..b596ba8936 --- /dev/null +++ b/src/test/ui/definition-reachable/nested-fn.rs @@ -0,0 +1,11 @@ +// Check that functions visible to macros through paths with >2 segements are +// considered reachable + +// aux-build:field-method-macro.rs +// run-pass + +extern crate field_method_macro; + +fn main() { + assert_eq!(field_method_macro::m!(), 33); +} diff --git a/src/test/ui/definition-reachable/private-non-types.rs b/src/test/ui/definition-reachable/private-non-types.rs new file mode 100644 index 0000000000..a601dabcb0 --- /dev/null +++ b/src/test/ui/definition-reachable/private-non-types.rs @@ -0,0 +1,21 @@ +// Check that we don't require stability annotations for private modules, +// imports and fields that are accessible to opaque macros. + +// check-pass + +#![feature(decl_macro, staged_api)] +#![stable(feature = "test", since = "1.0.0")] + +extern crate std as local_std; +use local_std::marker::Copy as LocalCopy; +mod private_mod { + #[stable(feature = "test", since = "1.0.0")] + pub struct A { + pub(crate) f: i32, + } +} + +#[stable(feature = "test", since = "1.0.0")] +pub macro m() {} + +fn main() {} diff --git a/src/test/ui/definition-reachable/private-types.rs b/src/test/ui/definition-reachable/private-types.rs new file mode 100644 index 0000000000..02c1224f4e --- /dev/null +++ b/src/test/ui/definition-reachable/private-types.rs @@ -0,0 +1,19 @@ +// Check that type privacy is taken into account when considering reachability + +// check-pass + +#![feature(decl_macro, staged_api)] +#![stable(feature = "test", since = "1.0.0")] + +// Type privacy should prevent use of these in other crates, so we shouldn't +// need a stability annotation. +fn private_function() {} +struct PrivateStruct { f: () } +enum PrivateEnum { V } +union PrivateUnion { g: () } +trait PrivateTrait {} + +#[stable(feature = "test", since = "1.0.0")] +pub macro m() {} + +fn main() {} diff --git a/src/test/ui/definition-reachable/private-use.rs b/src/test/ui/definition-reachable/private-use.rs new file mode 100644 index 0000000000..02cff0475e --- /dev/null +++ b/src/test/ui/definition-reachable/private-use.rs @@ -0,0 +1,10 @@ +// Check that private use statements can be used by + +// run-pass +// aux-build:private-use-macro.rs + +extern crate private_use_macro; + +fn main() { + assert_eq!(private_use_macro::m!(), 57); +} diff --git a/src/test/run-pass/deprecation-in-force-unstable.rs b/src/test/ui/deprecation-in-force-unstable.rs similarity index 91% rename from src/test/run-pass/deprecation-in-force-unstable.rs rename to src/test/ui/deprecation-in-force-unstable.rs index b3509734ff..4df9b802d4 100644 --- a/src/test/run-pass/deprecation-in-force-unstable.rs +++ b/src/test/ui/deprecation-in-force-unstable.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags:-Zforce-unstable-if-unmarked #[deprecated] // should work even with -Zforce-unstable-if-unmarked diff --git a/src/test/ui/deprecation/atomic_initializers.fixed b/src/test/ui/deprecation/atomic_initializers.fixed index dee1d979cf..363bda75f1 100644 --- a/src/test/ui/deprecation/atomic_initializers.fixed +++ b/src/test/ui/deprecation/atomic_initializers.fixed @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[allow(deprecated, unused_imports)] use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; diff --git a/src/test/ui/deprecation/atomic_initializers.rs b/src/test/ui/deprecation/atomic_initializers.rs index b9e25e817b..00c5f7b0b1 100644 --- a/src/test/ui/deprecation/atomic_initializers.rs +++ b/src/test/ui/deprecation/atomic_initializers.rs @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[allow(deprecated, unused_imports)] use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr index b009ff9486..16db00b6e8 100644 --- a/src/test/ui/deprecation/atomic_initializers.stderr +++ b/src/test/ui/deprecation/atomic_initializers.stderr @@ -4,5 +4,5 @@ warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated item: `AtomicIsize::new(0)` | - = note: #[warn(deprecated)] on by default + = note: `#[warn(deprecated)]` on by default diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr index a2cd196b21..1b69270d62 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr @@ -4,5 +4,5 @@ warning: macro_escape is a deprecated synonym for macro_use LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, #[macro_use] mod ... + = help: consider an outer attribute, `#[macro_use]` mod ... diff --git a/src/test/ui/deprecation/deprecation-in-future.stderr b/src/test/ui/deprecation/deprecation-in-future.stderr index 2284cfa8d6..4268680e9d 100644 --- a/src/test/ui/deprecation/deprecation-in-future.stderr +++ b/src/test/ui/deprecation/deprecation-in-future.stderr @@ -4,5 +4,5 @@ warning: use of deprecated item 'deprecated_future': text LL | deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated | ^^^^^^^^^^^^^^^^^ | - = note: #[warn(deprecated)] on by default + = note: `#[warn(deprecated)]` on by default diff --git a/src/test/ui/deprecation/derive_on_deprecated.rs b/src/test/ui/deprecation/derive_on_deprecated.rs index 4980a7f5aa..ed4055ecdd 100644 --- a/src/test/ui/deprecation/derive_on_deprecated.rs +++ b/src/test/ui/deprecation/derive_on_deprecated.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(deprecated)] diff --git a/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs index 235146bad9..3fd4346646 100644 --- a/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs +++ b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![forbid(deprecated)] diff --git a/src/test/run-pass/deref-lval.rs b/src/test/ui/deref-lval.rs similarity index 91% rename from src/test/run-pass/deref-lval.rs rename to src/test/ui/deref-lval.rs index d02adcb0cd..f57872f80e 100644 --- a/src/test/run-pass/deref-lval.rs +++ b/src/test/ui/deref-lval.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] use std::cell::Cell; diff --git a/src/test/run-pass/deref-mut-on-ref.rs b/src/test/ui/deref-mut-on-ref.rs similarity index 95% rename from src/test/run-pass/deref-mut-on-ref.rs rename to src/test/ui/deref-mut-on-ref.rs index 119d943026..a6df5495a2 100644 --- a/src/test/run-pass/deref-mut-on-ref.rs +++ b/src/test/ui/deref-mut-on-ref.rs @@ -1,3 +1,4 @@ +// run-pass // Test that `&mut T` implements `DerefMut` diff --git a/src/test/run-pass/deref-on-ref.rs b/src/test/ui/deref-on-ref.rs similarity index 96% rename from src/test/run-pass/deref-on-ref.rs rename to src/test/ui/deref-on-ref.rs index 651ccd5be8..973e61c9d5 100644 --- a/src/test/run-pass/deref-on-ref.rs +++ b/src/test/ui/deref-on-ref.rs @@ -1,3 +1,4 @@ +// run-pass // Test that `&T` and `&mut T` implement `Deref` diff --git a/src/test/run-pass/deref-rc.rs b/src/test/ui/deref-rc.rs similarity index 88% rename from src/test/run-pass/deref-rc.rs rename to src/test/ui/deref-rc.rs index ae17608fc5..9b4c63b192 100644 --- a/src/test/run-pass/deref-rc.rs +++ b/src/test/ui/deref-rc.rs @@ -1,3 +1,5 @@ +// run-pass + use std::rc::Rc; fn main() { diff --git a/src/test/run-pass/deref.rs b/src/test/ui/deref.rs similarity index 91% rename from src/test/run-pass/deref.rs rename to src/test/ui/deref.rs index 08b047f54d..cad4ede06a 100644 --- a/src/test/run-pass/deref.rs +++ b/src/test/ui/deref.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(box_syntax)] diff --git a/src/test/ui/derive-uninhabited-enum-38885.rs b/src/test/ui/derive-uninhabited-enum-38885.rs index b314eacc92..2c4d64e4e6 100644 --- a/src/test/ui/derive-uninhabited-enum-38885.rs +++ b/src/test/ui/derive-uninhabited-enum-38885.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Wunused // ensure there are no special warnings about uninhabited types diff --git a/src/test/ui/derived-errors/issue-31997.rs b/src/test/ui/derived-errors/issue-31997.rs index cfdee26c55..ff619313af 100644 --- a/src/test/ui/derived-errors/issue-31997.rs +++ b/src/test/ui/derived-errors/issue-31997.rs @@ -1,5 +1,6 @@ // Test that the resolve failure does not lead to downstream type errors. // See issue #31997. +#![allow(deprecated)] trait TheTrait { } diff --git a/src/test/ui/derived-errors/issue-31997.stderr b/src/test/ui/derived-errors/issue-31997.stderr index e9fe0d3971..b53c0cda8d 100644 --- a/src/test/ui/derived-errors/issue-31997.stderr +++ b/src/test/ui/derived-errors/issue-31997.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find function `bar` in this scope - --> $DIR/issue-31997.rs:13:21 + --> $DIR/issue-31997.rs:14:21 | LL | try!(closure(|| bar(core::ptr::null_mut()))); | ^^^ not found in this scope diff --git a/src/test/ui/derives/auxiliary/derive-marker-tricky.rs b/src/test/ui/derives/auxiliary/derive-marker-tricky.rs new file mode 100644 index 0000000000..70345351bd --- /dev/null +++ b/src/test/ui/derives/auxiliary/derive-marker-tricky.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(NoMarker)] +pub fn f(input: TokenStream) -> TokenStream { + if input.to_string().contains("rustc_copy_clone_marker") { + panic!("found `#[rustc_copy_clone_marker]`"); + } + TokenStream::new() +} diff --git a/src/test/ui/derives/derive-marker-tricky.rs b/src/test/ui/derives/derive-marker-tricky.rs new file mode 100644 index 0000000000..730ea4714c --- /dev/null +++ b/src/test/ui/derives/derive-marker-tricky.rs @@ -0,0 +1,16 @@ +// Test that `#[rustc_copy_clone_marker]` is not injected when a user-defined derive shadows +// a built-in derive in non-trivial scope (e.g. in a nested module). + +// check-pass +// aux-build:derive-marker-tricky.rs + +extern crate derive_marker_tricky; + +mod m { + use derive_marker_tricky::NoMarker as Copy; + + #[derive(Copy)] + struct S; +} + +fn main() {} diff --git a/src/test/ui/derives/deriving-meta-empty-trait-list.stderr b/src/test/ui/derives/deriving-meta-empty-trait-list.stderr index 95c94ded3e..b5d3670b5f 100644 --- a/src/test/ui/derives/deriving-meta-empty-trait-list.stderr +++ b/src/test/ui/derives/deriving-meta-empty-trait-list.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(unused)] | ^^^^^^ - = note: #[deny(unused_attributes)] implied by #[deny(unused)] + = note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]` error: aborting due to previous error diff --git a/src/test/ui/derives/deriving-meta-unknown-trait.stderr b/src/test/ui/derives/deriving-meta-unknown-trait.stderr index cf0173dfad..1b8e689c75 100644 --- a/src/test/ui/derives/deriving-meta-unknown-trait.stderr +++ b/src/test/ui/derives/deriving-meta-unknown-trait.stderr @@ -2,7 +2,7 @@ error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: try: `Eq` + | ^^^ help: a derive macro with a similar name exists: `Eq` error: aborting due to previous error diff --git a/src/test/ui/derives/deriving-with-repr-packed.rs b/src/test/ui/derives/deriving-with-repr-packed.rs index 66b0f85c85..d354cef66b 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.rs +++ b/src/test/ui/derives/deriving-with-repr-packed.rs @@ -6,15 +6,15 @@ // not be aligned. #[derive(Copy, Clone, PartialEq, Eq)] -//~^ ERROR #[derive] can't be used +//~^ ERROR `#[derive]` can't be used //~| hard error -//~^^^ ERROR #[derive] can't be used +//~^^^ ERROR `#[derive]` can't be used //~| hard error #[repr(packed)] pub struct Foo(T, T, T); #[derive(PartialEq, Eq)] -//~^ ERROR #[derive] can't be used +//~^ ERROR `#[derive]` can't be used //~| hard error #[repr(packed)] pub struct Bar(u32, u32, u32); @@ -23,7 +23,7 @@ pub struct Bar(u32, u32, u32); struct Y(usize); #[derive(PartialEq)] -//~^ ERROR #[derive] can't be used +//~^ ERROR `#[derive]` can't be used //~| hard error #[repr(packed)] struct X(Y); diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index 9d96908a05..8093c58a67 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -1,4 +1,4 @@ -error: #[derive] can't be used on a #[repr(packed)] struct with type or const parameters (error E0133) +error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) --> $DIR/deriving-with-repr-packed.rs:8:16 | LL | #[derive(Copy, Clone, PartialEq, Eq)] @@ -12,7 +12,7 @@ LL | #![deny(safe_packed_borrows)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 -error: #[derive] can't be used on a #[repr(packed)] struct with type or const parameters (error E0133) +error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) --> $DIR/deriving-with-repr-packed.rs:8:23 | LL | #[derive(Copy, Clone, PartialEq, Eq)] @@ -21,7 +21,7 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 -error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133) +error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) --> $DIR/deriving-with-repr-packed.rs:16:10 | LL | #[derive(PartialEq, Eq)] @@ -30,7 +30,7 @@ LL | #[derive(PartialEq, Eq)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 -error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133) +error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) --> $DIR/deriving-with-repr-packed.rs:25:10 | LL | #[derive(PartialEq)] diff --git a/src/test/run-pass/deriving/auxiliary/derive-no-std.rs b/src/test/ui/deriving/auxiliary/derive-no-std.rs similarity index 100% rename from src/test/run-pass/deriving/auxiliary/derive-no-std.rs rename to src/test/ui/deriving/auxiliary/derive-no-std.rs diff --git a/src/test/run-pass/deriving/derive-no-std.rs b/src/test/ui/deriving/derive-no-std.rs similarity index 100% rename from src/test/run-pass/deriving/derive-no-std.rs rename to src/test/ui/deriving/derive-no-std.rs diff --git a/src/test/run-pass/deriving/derive-partialord-correctness.rs b/src/test/ui/deriving/derive-partialord-correctness.rs similarity index 100% rename from src/test/run-pass/deriving/derive-partialord-correctness.rs rename to src/test/ui/deriving/derive-partialord-correctness.rs diff --git a/src/test/run-pass/deriving/deriving-associated-types.rs b/src/test/ui/deriving/deriving-associated-types.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-associated-types.rs rename to src/test/ui/deriving/deriving-associated-types.rs diff --git a/src/test/run-pass/deriving/deriving-bounds.rs b/src/test/ui/deriving/deriving-bounds.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-bounds.rs rename to src/test/ui/deriving/deriving-bounds.rs diff --git a/src/test/run-pass/deriving/deriving-clone-array.rs b/src/test/ui/deriving/deriving-clone-array.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-array.rs rename to src/test/ui/deriving/deriving-clone-array.rs diff --git a/src/test/run-pass/deriving/deriving-clone-enum.rs b/src/test/ui/deriving/deriving-clone-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-enum.rs rename to src/test/ui/deriving/deriving-clone-enum.rs diff --git a/src/test/run-pass/deriving/deriving-clone-generic-enum.rs b/src/test/ui/deriving/deriving-clone-generic-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-generic-enum.rs rename to src/test/ui/deriving/deriving-clone-generic-enum.rs diff --git a/src/test/run-pass/deriving/deriving-clone-generic-struct.rs b/src/test/ui/deriving/deriving-clone-generic-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-generic-struct.rs rename to src/test/ui/deriving/deriving-clone-generic-struct.rs diff --git a/src/test/run-pass/deriving/deriving-clone-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-generic-tuple-struct.rs rename to src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs diff --git a/src/test/run-pass/deriving/deriving-clone-struct.rs b/src/test/ui/deriving/deriving-clone-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-struct.rs rename to src/test/ui/deriving/deriving-clone-struct.rs diff --git a/src/test/run-pass/deriving/deriving-clone-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-tuple-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-clone-tuple-struct.rs rename to src/test/ui/deriving/deriving-clone-tuple-struct.rs diff --git a/src/test/run-pass/deriving/deriving-cmp-generic-enum.rs b/src/test/ui/deriving/deriving-cmp-generic-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-cmp-generic-enum.rs rename to src/test/ui/deriving/deriving-cmp-generic-enum.rs diff --git a/src/test/run-pass/deriving/deriving-cmp-generic-struct-enum.rs b/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-cmp-generic-struct-enum.rs rename to src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs diff --git a/src/test/run-pass/deriving/deriving-cmp-generic-struct.rs b/src/test/ui/deriving/deriving-cmp-generic-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-cmp-generic-struct.rs rename to src/test/ui/deriving/deriving-cmp-generic-struct.rs diff --git a/src/test/run-pass/deriving/deriving-cmp-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-cmp-generic-tuple-struct.rs rename to src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs diff --git a/src/test/run-pass/deriving/deriving-cmp-shortcircuit.rs b/src/test/ui/deriving/deriving-cmp-shortcircuit.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-cmp-shortcircuit.rs rename to src/test/ui/deriving/deriving-cmp-shortcircuit.rs diff --git a/src/test/run-pass/deriving/deriving-copyclone.rs b/src/test/ui/deriving/deriving-copyclone.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-copyclone.rs rename to src/test/ui/deriving/deriving-copyclone.rs diff --git a/src/test/run-pass/deriving/deriving-default-box.rs b/src/test/ui/deriving/deriving-default-box.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-default-box.rs rename to src/test/ui/deriving/deriving-default-box.rs diff --git a/src/test/run-pass/deriving/deriving-enum-single-variant.rs b/src/test/ui/deriving/deriving-enum-single-variant.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-enum-single-variant.rs rename to src/test/ui/deriving/deriving-enum-single-variant.rs diff --git a/src/test/run-pass/deriving/deriving-eq-ord-boxed-slice.rs b/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-eq-ord-boxed-slice.rs rename to src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs diff --git a/src/test/run-pass/deriving/deriving-hash.rs b/src/test/ui/deriving/deriving-hash.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-hash.rs rename to src/test/ui/deriving/deriving-hash.rs diff --git a/src/test/run-pass/deriving/deriving-in-fn.rs b/src/test/ui/deriving/deriving-in-fn.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-in-fn.rs rename to src/test/ui/deriving/deriving-in-fn.rs diff --git a/src/test/run-pass/deriving/deriving-in-macro.rs b/src/test/ui/deriving/deriving-in-macro.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-in-macro.rs rename to src/test/ui/deriving/deriving-in-macro.rs diff --git a/src/test/run-pass/deriving/deriving-meta-multiple.rs b/src/test/ui/deriving/deriving-meta-multiple.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-meta-multiple.rs rename to src/test/ui/deriving/deriving-meta-multiple.rs diff --git a/src/test/run-pass/deriving/deriving-meta.rs b/src/test/ui/deriving/deriving-meta.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-meta.rs rename to src/test/ui/deriving/deriving-meta.rs diff --git a/src/test/run-pass/deriving/deriving-self-lifetime-totalord-totaleq.rs b/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-self-lifetime-totalord-totaleq.rs rename to src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs diff --git a/src/test/run-pass/deriving/deriving-show-2.rs b/src/test/ui/deriving/deriving-show-2.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-show-2.rs rename to src/test/ui/deriving/deriving-show-2.rs diff --git a/src/test/run-pass/deriving/deriving-show.rs b/src/test/ui/deriving/deriving-show.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-show.rs rename to src/test/ui/deriving/deriving-show.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-c-enum.rs b/src/test/ui/deriving/deriving-via-extension-c-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-c-enum.rs rename to src/test/ui/deriving/deriving-via-extension-c-enum.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-enum.rs b/src/test/ui/deriving/deriving-via-extension-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-enum.rs rename to src/test/ui/deriving/deriving-via-extension-enum.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-hash-enum.rs b/src/test/ui/deriving/deriving-via-extension-hash-enum.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-hash-enum.rs rename to src/test/ui/deriving/deriving-via-extension-hash-enum.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-hash-struct.rs b/src/test/ui/deriving/deriving-via-extension-hash-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-hash-struct.rs rename to src/test/ui/deriving/deriving-via-extension-hash-struct.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-struct-empty.rs b/src/test/ui/deriving/deriving-via-extension-struct-empty.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-struct-empty.rs rename to src/test/ui/deriving/deriving-via-extension-struct-empty.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-struct-like-enum-variant.rs b/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-struct-like-enum-variant.rs rename to src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-struct-tuple.rs b/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-struct-tuple.rs rename to src/test/ui/deriving/deriving-via-extension-struct-tuple.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-struct.rs b/src/test/ui/deriving/deriving-via-extension-struct.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-struct.rs rename to src/test/ui/deriving/deriving-via-extension-struct.rs diff --git a/src/test/run-pass/deriving/deriving-via-extension-type-params.rs b/src/test/ui/deriving/deriving-via-extension-type-params.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-via-extension-type-params.rs rename to src/test/ui/deriving/deriving-via-extension-type-params.rs diff --git a/src/test/run-pass/deriving/deriving-with-repr-packed.rs b/src/test/ui/deriving/deriving-with-repr-packed.rs similarity index 100% rename from src/test/run-pass/deriving/deriving-with-repr-packed.rs rename to src/test/ui/deriving/deriving-with-repr-packed.rs diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr index 147225f1be..947ea6c24a 100644 --- a/src/test/ui/did_you_mean/issue-31424.stderr +++ b/src/test/ui/did_you_mean/issue-31424.stderr @@ -16,7 +16,7 @@ LL | LL | (&mut self).bar(); | ----------------- recursive call site | - = note: #[warn(unconditional_recursion)] on by default + = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs index b4795e76c9..66d562d2eb 100644 --- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs @@ -1,4 +1,6 @@ const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² //~^ ERROR expected at least one digit in exponent +//~| ERROR unknown start of token: \u{2212} +//~| ERROR cannot subtract `{integer}` from `{float}` fn main() {} diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr index 253deb2be6..9ee86adec5 100644 --- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -1,4 +1,10 @@ error: expected at least one digit in exponent + --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:47 + | +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² + | ^^^^^^ + +error: unknown start of token: \u{2212} --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 | LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² @@ -8,5 +14,14 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² | ^ -error: aborting due to previous error +error[E0277]: cannot subtract `{integer}` from `{float}` + --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 + | +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² + | ^ no implementation for `{float} - {integer}` + | + = help: the trait `std::ops::Sub<{integer}>` is not implemented for `{float}` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/run-pass/dispatch_from_dyn_zst.rs b/src/test/ui/dispatch_from_dyn_zst.rs similarity index 99% rename from src/test/run-pass/dispatch_from_dyn_zst.rs rename to src/test/ui/dispatch_from_dyn_zst.rs index a2181336e0..764f58ce9e 100644 --- a/src/test/run-pass/dispatch_from_dyn_zst.rs +++ b/src/test/ui/dispatch_from_dyn_zst.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(unsize, dispatch_from_dyn, never_type)] #![allow(dead_code)] diff --git a/src/test/run-pass/diverging-fallback-control-flow.rs b/src/test/ui/diverging-fallback-control-flow.rs similarity index 99% rename from src/test/run-pass/diverging-fallback-control-flow.rs rename to src/test/ui/diverging-fallback-control-flow.rs index c88ab42d5a..0f0f787b40 100644 --- a/src/test/run-pass/diverging-fallback-control-flow.rs +++ b/src/test/ui/diverging-fallback-control-flow.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unused_variables)] diff --git a/src/test/run-pass/diverging-fallback-method-chain.rs b/src/test/ui/diverging-fallback-method-chain.rs similarity index 97% rename from src/test/run-pass/diverging-fallback-method-chain.rs rename to src/test/ui/diverging-fallback-method-chain.rs index df1a64e3ae..ba9f05c64e 100644 --- a/src/test/run-pass/diverging-fallback-method-chain.rs +++ b/src/test/ui/diverging-fallback-method-chain.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] // Test a regression found when building compiler. The `produce()` // error type `T` winds up getting unified with result of `x.parse()`; diff --git a/src/test/run-pass/diverging-fallback-option.rs b/src/test/ui/diverging-fallback-option.rs similarity index 96% rename from src/test/run-pass/diverging-fallback-option.rs rename to src/test/ui/diverging-fallback-option.rs index af51717815..46bdfc96db 100644 --- a/src/test/run-pass/diverging-fallback-option.rs +++ b/src/test/ui/diverging-fallback-option.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(warnings)] // Here the type of `c` is `Option`, where `?T` is unconstrained. diff --git a/src/test/run-pass/double-ref.rs b/src/test/ui/double-ref.rs similarity index 98% rename from src/test/run-pass/double-ref.rs rename to src/test/ui/double-ref.rs index 16c98da945..e68b868337 100644 --- a/src/test/run-pass/double-ref.rs +++ b/src/test/ui/double-ref.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/drop/auxiliary/dropck_eyepatch_extern_crate.rs b/src/test/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs similarity index 100% rename from src/test/run-pass/drop/auxiliary/dropck_eyepatch_extern_crate.rs rename to src/test/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs diff --git a/src/test/run-pass/drop/drop-on-empty-block-exit.rs b/src/test/ui/drop/drop-on-empty-block-exit.rs similarity index 100% rename from src/test/run-pass/drop/drop-on-empty-block-exit.rs rename to src/test/ui/drop/drop-on-empty-block-exit.rs diff --git a/src/test/run-pass/drop/drop-on-ret.rs b/src/test/ui/drop/drop-on-ret.rs similarity index 100% rename from src/test/run-pass/drop/drop-on-ret.rs rename to src/test/ui/drop/drop-on-ret.rs diff --git a/src/test/run-pass/drop/drop-struct-as-object.rs b/src/test/ui/drop/drop-struct-as-object.rs similarity index 100% rename from src/test/run-pass/drop/drop-struct-as-object.rs rename to src/test/ui/drop/drop-struct-as-object.rs diff --git a/src/test/run-pass/drop/drop-trait-enum.rs b/src/test/ui/drop/drop-trait-enum.rs similarity index 100% rename from src/test/run-pass/drop/drop-trait-enum.rs rename to src/test/ui/drop/drop-trait-enum.rs diff --git a/src/test/run-pass/drop/drop-trait-generic.rs b/src/test/ui/drop/drop-trait-generic.rs similarity index 100% rename from src/test/run-pass/drop/drop-trait-generic.rs rename to src/test/ui/drop/drop-trait-generic.rs diff --git a/src/test/run-pass/drop/drop-trait.rs b/src/test/ui/drop/drop-trait.rs similarity index 100% rename from src/test/run-pass/drop/drop-trait.rs rename to src/test/ui/drop/drop-trait.rs diff --git a/src/test/run-pass/drop/drop-uninhabited-enum.rs b/src/test/ui/drop/drop-uninhabited-enum.rs similarity index 100% rename from src/test/run-pass/drop/drop-uninhabited-enum.rs rename to src/test/ui/drop/drop-uninhabited-enum.rs diff --git a/src/test/run-pass/drop/drop-with-type-ascription-1.rs b/src/test/ui/drop/drop-with-type-ascription-1.rs similarity index 100% rename from src/test/run-pass/drop/drop-with-type-ascription-1.rs rename to src/test/ui/drop/drop-with-type-ascription-1.rs diff --git a/src/test/run-pass/drop/drop-with-type-ascription-2.rs b/src/test/ui/drop/drop-with-type-ascription-2.rs similarity index 100% rename from src/test/run-pass/drop/drop-with-type-ascription-2.rs rename to src/test/ui/drop/drop-with-type-ascription-2.rs diff --git a/src/test/run-pass/drop/dropck-eyepatch-extern-crate.rs b/src/test/ui/drop/dropck-eyepatch-extern-crate.rs similarity index 100% rename from src/test/run-pass/drop/dropck-eyepatch-extern-crate.rs rename to src/test/ui/drop/dropck-eyepatch-extern-crate.rs diff --git a/src/test/run-pass/drop/dropck-eyepatch-reorder.rs b/src/test/ui/drop/dropck-eyepatch-reorder.rs similarity index 100% rename from src/test/run-pass/drop/dropck-eyepatch-reorder.rs rename to src/test/ui/drop/dropck-eyepatch-reorder.rs diff --git a/src/test/run-pass/drop/dropck-eyepatch.rs b/src/test/ui/drop/dropck-eyepatch.rs similarity index 100% rename from src/test/run-pass/drop/dropck-eyepatch.rs rename to src/test/ui/drop/dropck-eyepatch.rs diff --git a/src/test/run-pass/drop/dropck_legal_cycles.rs b/src/test/ui/drop/dropck_legal_cycles.rs similarity index 100% rename from src/test/run-pass/drop/dropck_legal_cycles.rs rename to src/test/ui/drop/dropck_legal_cycles.rs diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs new file mode 100644 index 0000000000..f3f5c38227 --- /dev/null +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -0,0 +1,328 @@ +// Test that values are not leaked in async functions, even in the cases where: +// * Dropping one of the values panics while running the future. +// * The future is dropped at one of its suspend points. +// * Dropping one of the values panics while dropping the future. + +// run-pass +// edition:2018 +// ignore-wasm32-bare compiled with panic=abort by default + +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![feature(slice_patterns)] +#![feature(async_await)] + +use std::{ + cell::{Cell, RefCell}, + future::Future, + marker::Unpin, + panic, + pin::Pin, + ptr, + rc::Rc, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + usize, +}; + +struct InjectedFailure; + +struct Defer { + ready: bool, + value: Option, +} + +impl Future for Defer { + type Output = T; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + if self.ready { + Poll::Ready(self.value.take().unwrap()) + } else { + self.ready = true; + Poll::Pending + } + } +} + +/// Allocator tracks the creation and destruction of `Ptr`s. +/// The `failing_op`-th operation will panic. +struct Allocator { + data: RefCell>, + failing_op: usize, + cur_ops: Cell, +} + +impl panic::UnwindSafe for Allocator {} +impl panic::RefUnwindSafe for Allocator {} + +impl Drop for Allocator { + fn drop(&mut self) { + let data = self.data.borrow(); + if data.iter().any(|d| *d) { + panic!("missing free: {:?}", data); + } + } +} + +impl Allocator { + fn new(failing_op: usize) -> Self { + Allocator { failing_op, cur_ops: Cell::new(0), data: RefCell::new(vec![]) } + } + fn alloc(&self) -> impl Future> + '_ { + self.fallible_operation(); + + let mut data = self.data.borrow_mut(); + + let addr = data.len(); + data.push(true); + Defer { ready: false, value: Some(Ptr(addr, self)) } + } + fn fallible_operation(&self) { + self.cur_ops.set(self.cur_ops.get() + 1); + + if self.cur_ops.get() == self.failing_op { + panic!(InjectedFailure); + } + } +} + +// Type that tracks whether it was dropped and can panic when it's created or +// destroyed. +struct Ptr<'a>(usize, &'a Allocator); +impl<'a> Drop for Ptr<'a> { + fn drop(&mut self) { + match self.1.data.borrow_mut()[self.0] { + false => panic!("double free at index {:?}", self.0), + ref mut d => *d = false, + } + + self.1.fallible_operation(); + } +} + +async fn dynamic_init(a: Rc, c: bool) { + let _x; + if c { + _x = Some(a.alloc().await); + } +} + +async fn dynamic_drop(a: Rc, c: bool) { + let x = a.alloc().await; + if c { + Some(x) + } else { + None + }; +} + +struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>); +async fn struct_dynamic_drop(a: Rc, c0: bool, c1: bool, c: bool) { + for i in 0..2 { + let x; + let y; + if (c0 && i == 0) || (c1 && i == 1) { + x = (a.alloc().await, a.alloc().await, a.alloc().await); + y = TwoPtrs(a.alloc().await, a.alloc().await); + if c { + drop(x.1); + a.alloc().await; + drop(y.0); + a.alloc().await; + } + } + } +} + +async fn field_assignment(a: Rc, c0: bool) { + let mut x = (TwoPtrs(a.alloc().await, a.alloc().await), a.alloc().await); + + x.1 = a.alloc().await; + x.1 = a.alloc().await; + + let f = (x.0).0; + a.alloc().await; + if c0 { + (x.0).0 = f; + } + a.alloc().await; +} + +async fn assignment(a: Rc, c0: bool, c1: bool) { + let mut _v = a.alloc().await; + let mut _w = a.alloc().await; + if c0 { + drop(_v); + } + _v = _w; + if c1 { + _w = a.alloc().await; + } +} + +async fn array_simple(a: Rc) { + let _x = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; +} + +async fn vec_simple(a: Rc) { + let _x = vec![a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; +} + +async fn mixed_drop_and_nondrop(a: Rc) { + // check that destructor panics handle drop + // and non-drop blocks in the same scope correctly. + // + // Surprisingly enough, this used to not work. + let (x, y, z); + x = a.alloc().await; + y = 5; + z = a.alloc().await; +} + +#[allow(unreachable_code)] +async fn vec_unreachable(a: Rc) { + let _x = vec![a.alloc().await, a.alloc().await, a.alloc().await, return]; +} + +async fn slice_pattern_one_of(a: Rc, i: usize) { + let array = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; + let _x = match i { + 0 => { + let [a, ..] = array; + a + } + 1 => { + let [_, a, ..] = array; + a + } + 2 => { + let [_, _, a, _] = array; + a + } + 3 => { + let [_, _, _, a] = array; + a + } + _ => panic!("unmatched"), + }; + a.alloc().await; +} + +async fn subslice_pattern_from_end_with_drop(a: Rc, arg: bool, arg2: bool) { + let arr = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; + if arg2 { + drop(arr); + return; + } + + if arg { + let [.., _x, _] = arr; + } else { + let [_, _y @ ..] = arr; + } + a.alloc().await; +} + +async fn subslice_pattern_reassign(a: Rc) { + let mut ar = [a.alloc().await, a.alloc().await, a.alloc().await]; + let [_, _, _x] = ar; + ar = [a.alloc().await, a.alloc().await, a.alloc().await]; + let [_, _y @ ..] = ar; + a.alloc().await; +} + +fn run_test(cx: &mut Context<'_>, ref f: F) +where + F: Fn(Rc) -> G, + G: Future, +{ + for polls in 0.. { + // Run without any panics to find which operations happen after the + // penultimate `poll`. + let first_alloc = Rc::new(Allocator::new(usize::MAX)); + let mut fut = Box::pin(f(first_alloc.clone())); + let mut ops_before_last_poll = 0; + let mut completed = false; + for _ in 0..polls { + ops_before_last_poll = first_alloc.cur_ops.get(); + if let Poll::Ready(()) = fut.as_mut().poll(cx) { + completed = true; + } + } + drop(fut); + + // Start at `ops_before_last_poll` so that we will always be able to + // `poll` the expected number of times. + for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() { + let alloc = Rc::new(Allocator::new(failing_op + 1)); + let f = &f; + let cx = &mut *cx; + let result = panic::catch_unwind(panic::AssertUnwindSafe(move || { + let mut fut = Box::pin(f(alloc)); + for _ in 0..polls { + let _ = fut.as_mut().poll(cx); + } + drop(fut); + })); + match result { + Ok(..) => panic!("test executed more ops on first call"), + Err(e) => { + if e.downcast_ref::().is_none() { + panic::resume_unwind(e); + } + } + } + } + + if completed { + break; + } + } +} + +fn clone_waker(data: *const ()) -> RawWaker { + RawWaker::new(data, &RawWakerVTable::new(clone_waker, drop, drop, drop)) +} + +fn main() { + let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) }; + let context = &mut Context::from_waker(&waker); + + run_test(context, |a| dynamic_init(a, false)); + run_test(context, |a| dynamic_init(a, true)); + run_test(context, |a| dynamic_drop(a, false)); + run_test(context, |a| dynamic_drop(a, true)); + + run_test(context, |a| assignment(a, false, false)); + run_test(context, |a| assignment(a, false, true)); + run_test(context, |a| assignment(a, true, false)); + run_test(context, |a| assignment(a, true, true)); + + run_test(context, |a| array_simple(a)); + run_test(context, |a| vec_simple(a)); + run_test(context, |a| vec_unreachable(a)); + + run_test(context, |a| struct_dynamic_drop(a, false, false, false)); + run_test(context, |a| struct_dynamic_drop(a, false, false, true)); + run_test(context, |a| struct_dynamic_drop(a, false, true, false)); + run_test(context, |a| struct_dynamic_drop(a, false, true, true)); + run_test(context, |a| struct_dynamic_drop(a, true, false, false)); + run_test(context, |a| struct_dynamic_drop(a, true, false, true)); + run_test(context, |a| struct_dynamic_drop(a, true, true, false)); + run_test(context, |a| struct_dynamic_drop(a, true, true, true)); + + run_test(context, |a| field_assignment(a, false)); + run_test(context, |a| field_assignment(a, true)); + + run_test(context, |a| mixed_drop_and_nondrop(a)); + + run_test(context, |a| slice_pattern_one_of(a, 0)); + run_test(context, |a| slice_pattern_one_of(a, 1)); + run_test(context, |a| slice_pattern_one_of(a, 2)); + run_test(context, |a| slice_pattern_one_of(a, 3)); + + run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, true)); + run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, false)); + run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true)); + run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false)); + run_test(context, |a| subslice_pattern_reassign(a)); +} diff --git a/src/test/run-pass/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs similarity index 99% rename from src/test/run-pass/drop/dynamic-drop.rs rename to src/test/ui/drop/dynamic-drop.rs index eb1a3f3a9f..8516bc3d96 100644 --- a/src/test/run-pass/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -237,7 +237,7 @@ fn subslice_pattern_from_end(a: &Allocator, arg: bool) { if arg { let[.., _x, _] = a; } else { - let[_, _y..] = a; + let[_, _y @ ..] = a; } } @@ -251,7 +251,7 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) { if arg { let[.., _x, _] = a; } else { - let[_, _y..] = a; + let[_, _y @ ..] = a; } } @@ -266,7 +266,7 @@ fn subslice_pattern_reassign(a: &Allocator) { let mut ar = [a.alloc(), a.alloc(), a.alloc()]; let[_, _, _x] = ar; ar = [a.alloc(), a.alloc(), a.alloc()]; - let[_, _y..] = ar; + let[_, _y @ ..] = ar; } fn panic_after_return(a: &Allocator) -> Ptr<'_> { diff --git a/src/test/run-pass/drop/no-drop-flag-size.rs b/src/test/ui/drop/no-drop-flag-size.rs similarity index 100% rename from src/test/run-pass/drop/no-drop-flag-size.rs rename to src/test/ui/drop/no-drop-flag-size.rs diff --git a/src/test/run-pass/drop/nondrop-cycle.rs b/src/test/ui/drop/nondrop-cycle.rs similarity index 100% rename from src/test/run-pass/drop/nondrop-cycle.rs rename to src/test/ui/drop/nondrop-cycle.rs diff --git a/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr new file mode 100644 index 0000000000..dbcb0fcebb --- /dev/null +++ b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr @@ -0,0 +1,74 @@ +error[E0597]: `o2` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:111:13 + | +LL | o1.set0(&o2); + | ^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `o2` dropped here while still borrowed + | borrow might be used here, when `o2` is dropped and runs the destructor for type `std::boxed::Box>` + +error[E0597]: `o3` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:112:13 + | +LL | o1.set1(&o3); + | ^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `o3` dropped here while still borrowed + | borrow might be used here, when `o3` is dropped and runs the destructor for type `std::boxed::Box>` + +error[E0597]: `o2` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:113:13 + | +LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + | -------- cast requires that `o2` is borrowed for `'static` +... +LL | o2.set0(&o2); + | ^^^ borrowed value does not live long enough +... +LL | } + | - `o2` dropped here while still borrowed + +error[E0597]: `o3` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:114:13 + | +LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + | -------- cast requires that `o3` is borrowed for `'static` +... +LL | o2.set1(&o3); + | ^^^ borrowed value does not live long enough +... +LL | } + | - `o3` dropped here while still borrowed + +error[E0597]: `o1` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:115:13 + | +LL | o3.set0(&o1); + | ^^^ borrowed value does not live long enough +LL | o3.set1(&o2); +LL | } + | - + | | + | `o1` dropped here while still borrowed + | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box>` + +error[E0597]: `o2` does not live long enough + --> $DIR/dropck_trait_cycle_checked.rs:116:13 + | +LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + | -------- cast requires that `o2` is borrowed for `'static` +... +LL | o3.set1(&o2); + | ^^^ borrowed value does not live long enough +LL | } + | - `o2` dropped here while still borrowed + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/run-pass/dupe-first-attr.rc b/src/test/ui/dupe-first-attr.rc similarity index 100% rename from src/test/run-pass/dupe-first-attr.rc rename to src/test/ui/dupe-first-attr.rc diff --git a/src/test/ui/duplicate/dupe-symbols-7.stderr b/src/test/ui/duplicate/dupe-symbols-7.stderr index 7d033ec3d8..d2cb4e0970 100644 --- a/src/test/ui/duplicate/dupe-symbols-7.stderr +++ b/src/test/ui/duplicate/dupe-symbols-7.stderr @@ -4,7 +4,7 @@ error: entry symbol `main` defined multiple times LL | fn main(){} | ^^^^^^^^^^^ | - = help: did you use #[no_mangle] on `fn main`? Use #[start] instead + = help: did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead error: aborting due to previous error diff --git a/src/test/run-pass/duplicated-external-mods.rs b/src/test/ui/duplicated-external-mods.rs similarity index 94% rename from src/test/run-pass/duplicated-external-mods.rs rename to src/test/ui/duplicated-external-mods.rs index f2c1e1f654..05a279a301 100644 --- a/src/test/run-pass/duplicated-external-mods.rs +++ b/src/test/ui/duplicated-external-mods.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:anon-extern-mod-cross-crate-1.rs // aux-build:anon-extern-mod-cross-crate-1.rs // pretty-expanded FIXME #23616 diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs index f535791d7f..cf14aef790 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Under the 2015 edition with the keyword_idents lint, `dyn` is // not entirely acceptable as an identifier. diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs index 27e4905586..0d85b87dee 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Under the 2015 edition with the keyword_idents lint, `dyn` is // not entirely acceptable as an identifier. diff --git a/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs index 8cef5c2b34..2a8b6b2483 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs @@ -1,7 +1,7 @@ // Under the 2015 edition without the keyword_idents lint, `dyn` is // entirely acceptable as an identifier. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(non_camel_case_types)] diff --git a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs index ff3830d617..2718e89a3f 100644 --- a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs +++ b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#56327: Some occurrences of `dyn` within a macro are // not instances of identifiers, and thus should *not* be caught by the diff --git a/src/test/run-pass/dynamically-sized-types/dst-coerce-custom.rs b/src/test/ui/dynamically-sized-types/dst-coerce-custom.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-coerce-custom.rs rename to src/test/ui/dynamically-sized-types/dst-coerce-custom.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-coerce-rc.rs b/src/test/ui/dynamically-sized-types/dst-coerce-rc.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-coerce-rc.rs rename to src/test/ui/dynamically-sized-types/dst-coerce-rc.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-coercions.rs b/src/test/ui/dynamically-sized-types/dst-coercions.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-coercions.rs rename to src/test/ui/dynamically-sized-types/dst-coercions.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-deref-mut.rs b/src/test/ui/dynamically-sized-types/dst-deref-mut.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-deref-mut.rs rename to src/test/ui/dynamically-sized-types/dst-deref-mut.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-deref.rs b/src/test/ui/dynamically-sized-types/dst-deref.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-deref.rs rename to src/test/ui/dynamically-sized-types/dst-deref.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-field-align.rs b/src/test/ui/dynamically-sized-types/dst-field-align.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-field-align.rs rename to src/test/ui/dynamically-sized-types/dst-field-align.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-index.rs b/src/test/ui/dynamically-sized-types/dst-index.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-index.rs rename to src/test/ui/dynamically-sized-types/dst-index.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-irrefutable-bind.rs b/src/test/ui/dynamically-sized-types/dst-irrefutable-bind.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-irrefutable-bind.rs rename to src/test/ui/dynamically-sized-types/dst-irrefutable-bind.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-raw.rs b/src/test/ui/dynamically-sized-types/dst-raw.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-raw.rs rename to src/test/ui/dynamically-sized-types/dst-raw.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-struct-sole.rs b/src/test/ui/dynamically-sized-types/dst-struct-sole.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-struct-sole.rs rename to src/test/ui/dynamically-sized-types/dst-struct-sole.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-struct.rs b/src/test/ui/dynamically-sized-types/dst-struct.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-struct.rs rename to src/test/ui/dynamically-sized-types/dst-struct.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-trait-tuple.rs b/src/test/ui/dynamically-sized-types/dst-trait-tuple.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-trait-tuple.rs rename to src/test/ui/dynamically-sized-types/dst-trait-tuple.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-trait.rs b/src/test/ui/dynamically-sized-types/dst-trait.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-trait.rs rename to src/test/ui/dynamically-sized-types/dst-trait.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-tuple-sole.rs b/src/test/ui/dynamically-sized-types/dst-tuple-sole.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-tuple-sole.rs rename to src/test/ui/dynamically-sized-types/dst-tuple-sole.rs diff --git a/src/test/run-pass/dynamically-sized-types/dst-tuple.rs b/src/test/ui/dynamically-sized-types/dst-tuple.rs similarity index 100% rename from src/test/run-pass/dynamically-sized-types/dst-tuple.rs rename to src/test/ui/dynamically-sized-types/dst-tuple.rs diff --git a/src/test/run-pass/early-ret-binop-add.rs b/src/test/ui/early-ret-binop-add.rs similarity index 93% rename from src/test/run-pass/early-ret-binop-add.rs rename to src/test/ui/early-ret-binop-add.rs index 158468c572..2b5df52a51 100644 --- a/src/test/run-pass/early-ret-binop-add.rs +++ b/src/test/ui/early-ret-binop-add.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unreachable_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/early-vtbl-resolution.rs b/src/test/ui/early-vtbl-resolution.rs similarity index 96% rename from src/test/run-pass/early-vtbl-resolution.rs rename to src/test/ui/early-vtbl-resolution.rs index 812771c29b..f4b69c1409 100644 --- a/src/test/run-pass/early-vtbl-resolution.rs +++ b/src/test/ui/early-vtbl-resolution.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/edition-keywords-2015-2015.rs b/src/test/ui/edition-keywords-2015-2015.rs similarity index 98% rename from src/test/run-pass/edition-keywords-2015-2015.rs rename to src/test/ui/edition-keywords-2015-2015.rs index 7d25b71422..943d203b80 100644 --- a/src/test/run-pass/edition-keywords-2015-2015.rs +++ b/src/test/ui/edition-keywords-2015-2015.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_mut)] #![allow(unused_assignments)] #![allow(unused_variables)] diff --git a/src/test/run-pass/edition-keywords-2015-2018.rs b/src/test/ui/edition-keywords-2015-2018.rs similarity index 98% rename from src/test/run-pass/edition-keywords-2015-2018.rs rename to src/test/ui/edition-keywords-2015-2018.rs index 92d474629c..8c3397c951 100644 --- a/src/test/run-pass/edition-keywords-2015-2018.rs +++ b/src/test/ui/edition-keywords-2015-2018.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_mut)] #![allow(unused_assignments)] #![allow(unused_variables)] diff --git a/src/test/run-pass/edition-keywords-2018-2015.rs b/src/test/ui/edition-keywords-2018-2015.rs similarity index 98% rename from src/test/run-pass/edition-keywords-2018-2015.rs rename to src/test/ui/edition-keywords-2018-2015.rs index e4ed5ffff9..2cb2dfb18a 100644 --- a/src/test/run-pass/edition-keywords-2018-2015.rs +++ b/src/test/ui/edition-keywords-2018-2015.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_assignments)] // edition:2018 // aux-build:edition-kw-macro-2015.rs diff --git a/src/test/run-pass/edition-keywords-2018-2018.rs b/src/test/ui/edition-keywords-2018-2018.rs similarity index 98% rename from src/test/run-pass/edition-keywords-2018-2018.rs rename to src/test/ui/edition-keywords-2018-2018.rs index e3624ac96e..5043440aa1 100644 --- a/src/test/run-pass/edition-keywords-2018-2018.rs +++ b/src/test/ui/edition-keywords-2018-2018.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_assignments)] // edition:2018 // aux-build:edition-kw-macro-2018.rs diff --git a/src/test/ui/editions/edition-extern-crate-allowed.rs b/src/test/ui/editions/edition-extern-crate-allowed.rs index 6361fff6ff..93fe69e0af 100644 --- a/src/test/ui/editions/edition-extern-crate-allowed.rs +++ b/src/test/ui/editions/edition-extern-crate-allowed.rs @@ -1,6 +1,6 @@ // aux-build:edition-extern-crate-allowed.rs // edition:2015 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_idioms)] diff --git a/src/test/ui/editions/edition-extern-crate-allowed.stderr b/src/test/ui/editions/edition-extern-crate-allowed.stderr index b675c13f75..45b46794be 100644 --- a/src/test/ui/editions/edition-extern-crate-allowed.stderr +++ b/src/test/ui/editions/edition-extern-crate-allowed.stderr @@ -9,5 +9,5 @@ note: lint level defined here | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ - = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] + = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]` diff --git a/src/test/ui/editions/edition-feature-ok.rs b/src/test/ui/editions/edition-feature-ok.rs index c2468df493..1264213269 100644 --- a/src/test/ui/editions/edition-feature-ok.rs +++ b/src/test/ui/editions/edition-feature-ok.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] diff --git a/src/test/ui/editions/edition-feature-redundant.rs b/src/test/ui/editions/edition-feature-redundant.rs index 87a2a22105..4309a777d3 100644 --- a/src/test/ui/editions/edition-feature-redundant.rs +++ b/src/test/ui/editions/edition-feature-redundant.rs @@ -1,5 +1,5 @@ // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] //~^ WARN the feature `rust_2018_preview` is included in the Rust 2018 edition diff --git a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs index 940b0c3c63..310bff21d1 100644 --- a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs +++ b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags:--extern edition_imports_2015 // aux-build:edition-imports-2015.rs diff --git a/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs b/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs index c3757ab193..9c3beb1ce5 100644 --- a/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs +++ b/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs @@ -1,6 +1,6 @@ // edition:2015 // aux-build:edition-kw-macro-2015.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(keyword_idents)] diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr index 9724f78db6..321545740c 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr @@ -7,8 +7,8 @@ LL | produces_async! {} = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers | -LL | ( ) => ( pub fn r#async ( ) { } ) - | ^^^^^^^ +LL | () => (pub fn r#async () { }) + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs b/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs index 6a30c49821..619e6424db 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs +++ b/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs @@ -1,6 +1,6 @@ // edition:2018 // aux-build:edition-kw-macro-2015.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(keyword_idents)] diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index 0d8850c239..3c4a153353 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -31,10 +31,10 @@ LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> <::edition_kw_macro_2015::passes_ident macros>:1:25 + --> <::edition_kw_macro_2015::passes_ident macros>:1:22 | -LL | ( $ i : ident ) => ( $ i ) - | ^ expected one of `move`, `|`, or `||` here +LL | ($ i : ident) => ($ i) + | ^ expected one of `move`, `|`, or `||` here | ::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8 | diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr index ab601c8d8a..8942e3ce43 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr @@ -7,8 +7,8 @@ LL | produces_async! {} = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) help: you can escape reserved keywords to use them as identifiers | -LL | ( ) => ( pub fn r#async ( ) { } ) - | ^^^^^^^ +LL | () => (pub fn r#async () { }) + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 0604b600d2..46aa9ca34e 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -31,10 +31,10 @@ LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> <::edition_kw_macro_2018::passes_ident macros>:1:25 + --> <::edition_kw_macro_2018::passes_ident macros>:1:22 | -LL | ( $ i : ident ) => ( $ i ) - | ^ expected one of `move`, `|`, or `||` here +LL | ($ i : ident) => ($ i) + | ^ expected one of `move`, `|`, or `||` here | ::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8 | diff --git a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr index 508d5df2a7..6a8861ba67 100644 --- a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr +++ b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #[deny(warnings)] | ^^^^^^^^ - = note: #[deny(tyvar_behind_raw_pointer)] implied by #[deny(warnings)] + = note: `#[deny(tyvar_behind_raw_pointer)]` implied by `#[deny(warnings)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #46906 diff --git a/src/test/run-pass/else-if.rs b/src/test/ui/else-if.rs similarity index 97% rename from src/test/run-pass/else-if.rs rename to src/test/ui/else-if.rs index 83a6658895..77d8d1abfa 100644 --- a/src/test/run-pass/else-if.rs +++ b/src/test/ui/else-if.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { if 1 == 2 { assert!((false)); diff --git a/src/test/ui/emit-artifact-notifications.polonius.stderr b/src/test/ui/emit-artifact-notifications.polonius.stderr new file mode 100644 index 0000000000..47b48b399c --- /dev/null +++ b/src/test/ui/emit-artifact-notifications.polonius.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/emit-artifact-notifications.polonius/libemit_artifact_notifications.rmeta","emit":"metadata"} diff --git a/src/test/ui/emit-artifact-notifications.rs b/src/test/ui/emit-artifact-notifications.rs index 2f17f95b7a..6aab237b94 100644 --- a/src/test/ui/emit-artifact-notifications.rs +++ b/src/test/ui/emit-artifact-notifications.rs @@ -1,5 +1,5 @@ -// compile-flags:--emit=metadata --error-format=json -Z emit-artifact-notifications -// compile-pass +// compile-flags:--emit=metadata --error-format=json --json artifacts +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. diff --git a/src/test/run-pass/empty-allocation-non-null.rs b/src/test/ui/empty-allocation-non-null.rs similarity index 95% rename from src/test/run-pass/empty-allocation-non-null.rs rename to src/test/ui/empty-allocation-non-null.rs index 31117936c7..925bddd5ed 100644 --- a/src/test/run-pass/empty-allocation-non-null.rs +++ b/src/test/ui/empty-allocation-non-null.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { assert!(Some(Box::new(())).is_some()); diff --git a/src/test/run-pass/empty-allocation-rvalue-non-null.rs b/src/test/ui/empty-allocation-rvalue-non-null.rs similarity index 89% rename from src/test/run-pass/empty-allocation-rvalue-non-null.rs rename to src/test/ui/empty-allocation-rvalue-non-null.rs index ac597bcb20..2f5a5c4bbc 100644 --- a/src/test/run-pass/empty-allocation-rvalue-non-null.rs +++ b/src/test/ui/empty-allocation-rvalue-non-null.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/empty-type-parameter-list.rs b/src/test/ui/empty-type-parameter-list.rs similarity index 97% rename from src/test/run-pass/empty-type-parameter-list.rs rename to src/test/ui/empty-type-parameter-list.rs index 43275090f2..e168cd03b2 100644 --- a/src/test/run-pass/empty-type-parameter-list.rs +++ b/src/test/ui/empty-type-parameter-list.rs @@ -1,3 +1,4 @@ +// run-pass // Test that empty type parameter list (<>) is synonymous with // no type parameters at all diff --git a/src/test/ui/empty/empty-linkname.stderr b/src/test/ui/empty/empty-linkname.stderr index df41cb8941..b9d1841f16 100644 --- a/src/test/ui/empty/empty-linkname.stderr +++ b/src/test/ui/empty/empty-linkname.stderr @@ -1,4 +1,4 @@ -error[E0454]: #[link(name = "")] given with empty name +error[E0454]: `#[link(name = "")]` given with empty name --> $DIR/empty-linkname.rs:1:1 | LL | #[link(name = "")] diff --git a/src/test/ui/empty/empty-never-array.nll.stderr b/src/test/ui/empty/empty-never-array.nll.stderr deleted file mode 100644 index 01ee1c3a4d..0000000000 --- a/src/test/ui/empty/empty-never-array.nll.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0005]: refutable pattern in local binding: `T(_, _)` not covered - --> $DIR/empty-never-array.rs:10:9 - | -LL | / enum Helper { -LL | | T(T, [!; 0]), -LL | | #[allow(dead_code)] -LL | | U(U), -LL | | } - | |_- `Helper` defined here -... -LL | let Helper::U(u) = Helper::T(t, []); - | ^^^^^^^^^^^^ pattern `T(_, _)` not covered - -error[E0381]: use of possibly uninitialized variable: `u` - --> $DIR/empty-never-array.rs:12:5 - | -LL | u - | ^ use of possibly uninitialized `u` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0005, E0381. -For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs index ce781da7d4..ffd2545b29 100644 --- a/src/test/ui/empty/empty-never-array.rs +++ b/src/test/ui/empty/empty-never-array.rs @@ -10,9 +10,7 @@ fn transmute(t: T) -> U { let Helper::U(u) = Helper::T(t, []); //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered u - //~^ WARN use of possibly uninitialized variable: `u` - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will + //~^ ERROR use of possibly uninitialized variable: `u` } fn main() { diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr index 9911dd4683..01ee1c3a4d 100644 --- a/src/test/ui/empty/empty-never-array.stderr +++ b/src/test/ui/empty/empty-never-array.stderr @@ -11,17 +11,13 @@ LL | | } LL | let Helper::U(u) = Helper::T(t, []); | ^^^^^^^^^^^^ pattern `T(_, _)` not covered -warning[E0381]: use of possibly uninitialized variable: `u` +error[E0381]: use of possibly uninitialized variable: `u` --> $DIR/empty-never-array.rs:12:5 | LL | u | ^ use of possibly uninitialized `u` - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -error: aborting due to previous error +error: aborting due to 2 previous errors Some errors have detailed explanations: E0005, E0381. For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/run-pass/empty_global_asm.rs b/src/test/ui/empty_global_asm.rs similarity index 95% rename from src/test/run-pass/empty_global_asm.rs rename to src/test/ui/empty_global_asm.rs index 5789985a03..efbe2b2eb6 100644 --- a/src/test/run-pass/empty_global_asm.rs +++ b/src/test/ui/empty_global_asm.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(global_asm)] #[cfg(target_arch = "x86")] diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/enable-unstable-lib-feature.rs index 383c6868ce..aa6a973d7b 100644 --- a/src/test/ui/enable-unstable-lib-feature.rs +++ b/src/test/ui/enable-unstable-lib-feature.rs @@ -6,7 +6,6 @@ #![deny(non_snake_case)] // To trigger a hard error // Shouldn't generate a warning about unstable features -#[allow(unused_extern_crates)] extern crate stability_cfg2; pub fn BOGUS() { } //~ ERROR diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/enable-unstable-lib-feature.stderr index 5b6ebc4c0d..d5b8c0efaa 100644 --- a/src/test/ui/enable-unstable-lib-feature.stderr +++ b/src/test/ui/enable-unstable-lib-feature.stderr @@ -1,5 +1,5 @@ error: function `BOGUS` should have a snake case name - --> $DIR/enable-unstable-lib-feature.rs:12:8 + --> $DIR/enable-unstable-lib-feature.rs:11:8 | LL | pub fn BOGUS() { } | ^^^^^ help: convert the identifier to snake case: `bogus` diff --git a/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr b/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr index f50ed2c184..afd7bda49f 100644 --- a/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr +++ b/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr @@ -5,7 +5,7 @@ LL | Tuple() = 2, | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60553 - = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable error[E0658]: discriminants on non-unit variants are experimental --> $DIR/feature-gate-arbitrary_enum_discriminant.rs:8:14 @@ -14,7 +14,7 @@ LL | Struct{} = 3, | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60553 - = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants --> $DIR/feature-gate-arbitrary_enum_discriminant.rs:4:10 @@ -29,7 +29,7 @@ LL | Struct{} = 3, | ------------ struct variant defined here | = note: for more information, see https://github.com/rust-lang/rust/issues/60553 - = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/run-pass/env-args-reverse-iterator.rs b/src/test/ui/env-args-reverse-iterator.rs similarity index 98% rename from src/test/run-pass/env-args-reverse-iterator.rs rename to src/test/ui/env-args-reverse-iterator.rs index d677aa8500..0ffd74f87a 100644 --- a/src/test/run-pass/env-args-reverse-iterator.rs +++ b/src/test/ui/env-args-reverse-iterator.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes diff --git a/src/test/run-pass/env-funky-keys.rs b/src/test/ui/env-funky-keys.rs similarity index 98% rename from src/test/run-pass/env-funky-keys.rs rename to src/test/ui/env-funky-keys.rs index 3b236e2b3a..4faceb5326 100644 --- a/src/test/run-pass/env-funky-keys.rs +++ b/src/test/ui/env-funky-keys.rs @@ -1,3 +1,4 @@ +// run-pass // Ignore this test on Android, because it segfaults there. // ignore-android diff --git a/src/test/run-pass/env-home-dir.rs b/src/test/ui/env-home-dir.rs similarity index 99% rename from src/test/run-pass/env-home-dir.rs rename to src/test/ui/env-home-dir.rs index 62f45d0a2e..a75be48fd5 100644 --- a/src/test/run-pass/env-home-dir.rs +++ b/src/test/ui/env-home-dir.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] #![allow(deprecated)] // ignore-cloudabi no environment variables present diff --git a/src/test/run-pass/env-null-vars.rs b/src/test/ui/env-null-vars.rs similarity index 96% rename from src/test/run-pass/env-null-vars.rs rename to src/test/ui/env-null-vars.rs index bdd1d4778c..10582a8a51 100644 --- a/src/test/run-pass/env-null-vars.rs +++ b/src/test/ui/env-null-vars.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] // ignore-windows diff --git a/src/test/run-pass/env-vars.rs b/src/test/ui/env-vars.rs similarity index 96% rename from src/test/run-pass/env-vars.rs rename to src/test/ui/env-vars.rs index 6159638745..2ea906788e 100644 --- a/src/test/run-pass/env-vars.rs +++ b/src/test/ui/env-vars.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no env vars // ignore-wasm32-bare no env vars diff --git a/src/test/run-pass/epoch-gate-feature.rs b/src/test/ui/epoch-gate-feature.rs similarity index 95% rename from src/test/run-pass/epoch-gate-feature.rs rename to src/test/ui/epoch-gate-feature.rs index 6f0b31518c..5f7feb5347 100644 --- a/src/test/run-pass/epoch-gate-feature.rs +++ b/src/test/ui/epoch-gate-feature.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_variables)] // Checks if the correct registers are being used to pass arguments diff --git a/src/test/run-pass/eq-multidispatch.rs b/src/test/ui/eq-multidispatch.rs similarity index 98% rename from src/test/run-pass/eq-multidispatch.rs rename to src/test/ui/eq-multidispatch.rs index 1212f5d17d..69d83f496b 100644 --- a/src/test/run-pass/eq-multidispatch.rs +++ b/src/test/ui/eq-multidispatch.rs @@ -1,3 +1,5 @@ +// run-pass + #[derive(PartialEq, Debug)] struct Bar; #[derive(Debug)] diff --git a/src/test/ui/error-codes/E0008.stderr b/src/test/ui/error-codes/E0008.stderr index 2505c03a14..6b45439c4b 100644 --- a/src/test/ui/error-codes/E0008.stderr +++ b/src/test/ui/error-codes/E0008.stderr @@ -4,7 +4,7 @@ error[E0008]: cannot bind by-move into a pattern guard LL | Some(s) if s.len() == 0 => {}, | ^ moves value into pattern guard | - = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr index 816a48f102..a58d16bfaf 100644 --- a/src/test/ui/error-codes/E0034.stderr +++ b/src/test/ui/error-codes/E0034.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `Trait1` for the type `Tes | LL | fn foo() {} | ^^^^^^^^ + = help: to disambiguate the method call, write `Trait1::foo(...)` instead note: candidate #2 is defined in an impl of the trait `Trait2` for the type `Test` --> $DIR/E0034.rs:16:5 | LL | fn foo() {} | ^^^^^^^^ + = help: to disambiguate the method call, write `Trait2::foo(...)` instead error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0121.stderr b/src/test/ui/error-codes/E0121.stderr index b7f4ce4d23..beb8941320 100644 --- a/src/test/ui/error-codes/E0121.stderr +++ b/src/test/ui/error-codes/E0121.stderr @@ -2,13 +2,19 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/E0121.rs:1:13 | LL | fn foo() -> _ { 5 } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/E0121.rs:3:13 | LL | static BAR: _ = "test"; - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `&'static str` error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0137.stderr b/src/test/ui/error-codes/E0137.stderr index a5f05d33a0..f4d5e10369 100644 --- a/src/test/ui/error-codes/E0137.stderr +++ b/src/test/ui/error-codes/E0137.stderr @@ -1,11 +1,11 @@ -error[E0137]: multiple functions with a #[main] attribute +error[E0137]: multiple functions with a `#[main]` attribute --> $DIR/E0137.rs:7:1 | LL | fn foo() {} - | ----------- first #[main] function + | ----------- first `#[main]` function ... LL | fn f() {} - | ^^^^^^^^^ additional #[main] function + | ^^^^^^^^^ additional `#[main]` function error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0254.rs b/src/test/ui/error-codes/E0254.rs index d166aff565..e291268be8 100644 --- a/src/test/ui/error-codes/E0254.rs +++ b/src/test/ui/error-codes/E0254.rs @@ -1,4 +1,4 @@ -#![allow(unused_extern_crates, non_camel_case_types)] +#![allow(non_camel_case_types)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0259.rs b/src/test/ui/error-codes/E0259.rs index c83561be9c..e7e94d5863 100644 --- a/src/test/ui/error-codes/E0259.rs +++ b/src/test/ui/error-codes/E0259.rs @@ -1,5 +1,4 @@ #![feature(rustc_private)] -#![allow(unused_extern_crates)] extern crate alloc; diff --git a/src/test/ui/error-codes/E0259.stderr b/src/test/ui/error-codes/E0259.stderr index fd6a4087ae..4a48a4d554 100644 --- a/src/test/ui/error-codes/E0259.stderr +++ b/src/test/ui/error-codes/E0259.stderr @@ -1,5 +1,5 @@ error[E0259]: the name `alloc` is defined multiple times - --> $DIR/E0259.rs:6:1 + --> $DIR/E0259.rs:5:1 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/error-codes/E0260.rs b/src/test/ui/error-codes/E0260.rs index 73b8934159..f7eb220b08 100644 --- a/src/test/ui/error-codes/E0260.rs +++ b/src/test/ui/error-codes/E0260.rs @@ -1,5 +1,3 @@ -#![allow(unused_extern_crates)] - extern crate alloc; mod alloc { diff --git a/src/test/ui/error-codes/E0260.stderr b/src/test/ui/error-codes/E0260.stderr index 7d0b302291..737b20b91e 100644 --- a/src/test/ui/error-codes/E0260.stderr +++ b/src/test/ui/error-codes/E0260.stderr @@ -1,5 +1,5 @@ error[E0260]: the name `alloc` is defined multiple times - --> $DIR/E0260.rs:5:1 + --> $DIR/E0260.rs:3:1 | LL | extern crate alloc; | ------------------- previous import of the extern crate `alloc` here diff --git a/src/test/ui/error-codes/E0301.stderr b/src/test/ui/error-codes/E0301.stderr index 44e823631b..4f12fd3850 100644 --- a/src/test/ui/error-codes/E0301.stderr +++ b/src/test/ui/error-codes/E0301.stderr @@ -4,7 +4,7 @@ error[E0301]: cannot mutably borrow in a pattern guard LL | option if option.take().is_none() => {}, | ^^^^^^ borrowed mutably in pattern guard | - = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable error[E0596]: cannot borrow `option` as mutable, as it is immutable for the pattern guard --> $DIR/E0301.rs:4:19 diff --git a/src/test/ui/error-codes/E0395.stderr b/src/test/ui/error-codes/E0395.stderr index 30a4d4815f..a4580f1cb2 100644 --- a/src/test/ui/error-codes/E0395.stderr +++ b/src/test/ui/error-codes/E0395.stderr @@ -5,7 +5,7 @@ LL | static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53020 - = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable + = help: add `#![feature(const_compare_raw_pointers)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0396-fixed.stderr b/src/test/ui/error-codes/E0396-fixed.stderr index 4b7f1fa82c..7222f87da2 100644 --- a/src/test/ui/error-codes/E0396-fixed.stderr +++ b/src/test/ui/error-codes/E0396-fixed.stderr @@ -6,7 +6,7 @@ LL | const VALUE: u8 = unsafe { *REG_ADDR }; | | | a memory access tried to interpret some bytes as a pointer | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0396.stderr b/src/test/ui/error-codes/E0396.stderr index 6d2d121e91..f0aa739a69 100644 --- a/src/test/ui/error-codes/E0396.stderr +++ b/src/test/ui/error-codes/E0396.stderr @@ -5,7 +5,7 @@ LL | const VALUE: u8 = unsafe { *REG_ADDR }; | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51911 - = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0432.stderr b/src/test/ui/error-codes/E0432.stderr index 137a1af6f9..afb031c225 100644 --- a/src/test/ui/error-codes/E0432.stderr +++ b/src/test/ui/error-codes/E0432.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `something` --> $DIR/E0432.rs:1:5 | LL | use something::Foo; - | ^^^^^^^^^ maybe a missing `extern crate something;`? + | ^^^^^^^^^ maybe a missing crate `something`? error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0454.stderr b/src/test/ui/error-codes/E0454.stderr index 352c3baa83..499162694e 100644 --- a/src/test/ui/error-codes/E0454.stderr +++ b/src/test/ui/error-codes/E0454.stderr @@ -1,4 +1,4 @@ -error[E0454]: #[link(name = "")] given with empty name +error[E0454]: `#[link(name = "")]` given with empty name --> $DIR/E0454.rs:1:1 | LL | #[link(name = "")] extern {} diff --git a/src/test/ui/error-codes/E0458.stderr b/src/test/ui/error-codes/E0458.stderr index d60fd96c77..51f7764aaf 100644 --- a/src/test/ui/error-codes/E0458.stderr +++ b/src/test/ui/error-codes/E0458.stderr @@ -6,7 +6,7 @@ LL | #[link(kind = "wonderful_unicorn")] extern {} | | | unknown kind -error[E0459]: #[link(...)] specified without `name = "foo"` +error[E0459]: `#[link(...)]` specified without `name = "foo"` --> $DIR/E0458.rs:1:1 | LL | #[link(kind = "wonderful_unicorn")] extern {} diff --git a/src/test/ui/error-codes/E0459.stderr b/src/test/ui/error-codes/E0459.stderr index da7069fbb4..c618fea9af 100644 --- a/src/test/ui/error-codes/E0459.stderr +++ b/src/test/ui/error-codes/E0459.stderr @@ -1,4 +1,4 @@ -error[E0459]: #[link(...)] specified without `name = "foo"` +error[E0459]: `#[link(...)]` specified without `name = "foo"` --> $DIR/E0459.rs:1:1 | LL | #[link(kind = "dylib")] extern {} diff --git a/src/test/ui/error-codes/E0528.rs b/src/test/ui/error-codes/E0528.rs index f2681fa043..17d03b14fc 100644 --- a/src/test/ui/error-codes/E0528.rs +++ b/src/test/ui/error-codes/E0528.rs @@ -3,7 +3,7 @@ fn main() { let r = &[1, 2]; match r { - &[a, b, c, rest..] => { + &[a, b, c, rest @ ..] => { //~^ ERROR E0528 } } diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr index a7205af505..0f56609114 100644 --- a/src/test/ui/error-codes/E0528.stderr +++ b/src/test/ui/error-codes/E0528.stderr @@ -1,8 +1,8 @@ error[E0528]: pattern requires at least 3 elements but array has 2 --> $DIR/E0528.rs:6:10 | -LL | &[a, b, c, rest..] => { - | ^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements +LL | &[a, b, c, rest @ ..] => { + | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr index ff3f74addd..071dbccd80 100644 --- a/src/test/ui/error-codes/E0658.stderr +++ b/src/test/ui/error-codes/E0658.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35118 - = help: add #![feature(repr128)] to the crate attributes to enable + = help: add `#![feature(repr128)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0661.rs b/src/test/ui/error-codes/E0661.rs index 8d355a8a02..2440e3a446 100644 --- a/src/test/ui/error-codes/E0661.rs +++ b/src/test/ui/error-codes/E0661.rs @@ -1,3 +1,5 @@ +// ignore-emscripten + #![feature(asm)] fn main() { diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr index 30a23fd58c..58f7e7fa0f 100644 --- a/src/test/ui/error-codes/E0661.stderr +++ b/src/test/ui/error-codes/E0661.stderr @@ -1,5 +1,5 @@ error[E0661]: output operand constraint lacks '=' or '+' - --> $DIR/E0661.rs:5:18 + --> $DIR/E0661.rs:7:18 | LL | asm!("nop" : "r"(a)); | ^^^ diff --git a/src/test/ui/error-codes/E0662.rs b/src/test/ui/error-codes/E0662.rs index 7fe528c474..343ed27f83 100644 --- a/src/test/ui/error-codes/E0662.rs +++ b/src/test/ui/error-codes/E0662.rs @@ -1,3 +1,5 @@ +// ignore-emscripten + #![feature(asm)] fn main() { diff --git a/src/test/ui/error-codes/E0662.stderr b/src/test/ui/error-codes/E0662.stderr index 0d3701aa95..3b2f7632f3 100644 --- a/src/test/ui/error-codes/E0662.stderr +++ b/src/test/ui/error-codes/E0662.stderr @@ -1,5 +1,5 @@ error[E0662]: input operand constraint contains '=' - --> $DIR/E0662.rs:6:12 + --> $DIR/E0662.rs:8:12 | LL | : "=test"("a") | ^^^^^^^ diff --git a/src/test/ui/error-codes/E0663.rs b/src/test/ui/error-codes/E0663.rs index e5b8156cfb..cfbb4b3775 100644 --- a/src/test/ui/error-codes/E0663.rs +++ b/src/test/ui/error-codes/E0663.rs @@ -1,3 +1,5 @@ +// ignore-emscripten + #![feature(asm)] fn main() { diff --git a/src/test/ui/error-codes/E0663.stderr b/src/test/ui/error-codes/E0663.stderr index 46a079af15..4ac0a85f26 100644 --- a/src/test/ui/error-codes/E0663.stderr +++ b/src/test/ui/error-codes/E0663.stderr @@ -1,5 +1,5 @@ error[E0663]: input operand constraint contains '+' - --> $DIR/E0663.rs:6:12 + --> $DIR/E0663.rs:8:12 | LL | : "+test"("a") | ^^^^^^^ diff --git a/src/test/ui/error-codes/E0664.rs b/src/test/ui/error-codes/E0664.rs index 29ec7ced4f..fe70c9f96e 100644 --- a/src/test/ui/error-codes/E0664.rs +++ b/src/test/ui/error-codes/E0664.rs @@ -1,3 +1,5 @@ +// ignore-emscripten + #![feature(asm)] fn main() { diff --git a/src/test/ui/error-codes/E0664.stderr b/src/test/ui/error-codes/E0664.stderr index 3a99fce6ee..435e465920 100644 --- a/src/test/ui/error-codes/E0664.stderr +++ b/src/test/ui/error-codes/E0664.stderr @@ -1,5 +1,5 @@ error[E0664]: clobber should not be surrounded by braces - --> $DIR/E0664.rs:7:12 + --> $DIR/E0664.rs:9:12 | LL | : "{eax}" | ^^^^^^^ diff --git a/src/test/ui/error-codes/E0705.rs b/src/test/ui/error-codes/E0705.rs index cc2b8f64d9..4e32ef3556 100644 --- a/src/test/ui/error-codes/E0705.rs +++ b/src/test/ui/error-codes/E0705.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This is a stub feature that doesn't control anything, so to make tidy happy, // gate-test-test_2018_feature diff --git a/src/test/ui/error-codes/E0730.stderr b/src/test/ui/error-codes/E0730.stderr index f9281262bb..9309ee9906 100644 --- a/src/test/ui/error-codes/E0730.stderr +++ b/src/test/ui/error-codes/E0730.stderr @@ -3,6 +3,8 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0730]: cannot pattern-match on an array without a fixed length --> $DIR/E0730.rs:6:9 diff --git a/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs b/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs index 4e85bcc4ba..141f363694 100644 --- a/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs +++ b/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs @@ -9,7 +9,7 @@ pub trait LolInto: Sized { } pub trait LolFrom { - fn from(T) -> Self; + fn from(_: T) -> Self; } impl<'a, T: ?Sized, U> LolInto for &'a T where T: LolTo { diff --git a/src/test/run-pass/estr-uniq.rs b/src/test/ui/estr-uniq.rs similarity index 96% rename from src/test/run-pass/estr-uniq.rs rename to src/test/ui/estr-uniq.rs index 6b2607a997..1d0a427395 100644 --- a/src/test/run-pass/estr-uniq.rs +++ b/src/test/ui/estr-uniq.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_assignments)] #![allow(unknown_lints)] diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs index d95c4b0999..d97b693f52 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs @@ -2,7 +2,9 @@ fn main() { match [5..4, 99..105, 43..44] { - [_, 99.., _] => {}, //~ ERROR unexpected token: `,` + [_, 99.., _] => {}, + //~^ ERROR `X..` range patterns are not supported + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 359725a41c..4ecd8515ee 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -1,8 +1,20 @@ -error: unexpected token: `,` - --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:17 +error: `X..` range patterns are not supported + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 | LL | [_, 99.., _] => {}, - | ^ + | ^^^^ help: try using the maximum value for the type: `99..MAX` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 + | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` +LL | [_, 99.., _] => {}, + | ^^^^ expected struct `std::ops::Range`, found integer + | + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs index 95677e34dd..09f459c986 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs @@ -2,7 +2,10 @@ fn main() { match [5..4, 99..105, 43..44] { - [_, 99..] => {}, //~ ERROR unexpected token: `]` + [_, 99..] => {}, + //~^ ERROR `X..` range patterns are not supported + //~| ERROR pattern requires 2 elements but array has 3 + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index 8f849d7b3f..922d269231 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -1,8 +1,27 @@ -error: unexpected token: `]` - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:17 +error: `X..` range patterns are not supported + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 | LL | [_, 99..] => {}, - | ^ + | ^^^^ help: try using the maximum value for the type: `99..MAX` -error: aborting due to previous error +error[E0527]: pattern requires 2 elements but array has 3 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:9 + | +LL | [_, 99..] => {}, + | ^^^^^^^^^ expected 3 elements + +error[E0308]: mismatched types + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 + | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` +LL | [_, 99..] => {}, + | ^^^^ expected struct `std::ops::Range`, found integer + | + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0308, E0527. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs index 3bf5da710e..95e58b1d48 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs @@ -2,7 +2,10 @@ fn main() { match [5..4, 99..105, 43..44] { - [..9, 99..100, _] => {}, //~ ERROR expected one of `,` or `]`, found `9` + [..9, 99..100, _] => {}, + //~^ ERROR `..X` range patterns are not supported + //~| ERROR mismatched types + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr index a09ba3562e..8907b875f8 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr @@ -1,8 +1,31 @@ -error: expected one of `,` or `]`, found `9` - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 +error: `..X` range patterns are not supported + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 | LL | [..9, 99..100, _] => {}, - | ^ expected one of `,` or `]` here + | ^^^ help: try using the minimum value for the type: `MIN..9` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 + | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` +LL | [..9, 99..100, _] => {}, + | ^^^ expected struct `std::ops::Range`, found integer + | + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 + | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` +LL | [..9, 99..100, _] => {}, + | ^^^^^^^ expected struct `std::ops::Range`, found integer + | + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/run-pass/exec-env.rs b/src/test/ui/exec-env.rs similarity index 94% rename from src/test/run-pass/exec-env.rs rename to src/test/ui/exec-env.rs index c1b8e08251..230fac10d3 100644 --- a/src/test/run-pass/exec-env.rs +++ b/src/test/ui/exec-env.rs @@ -1,3 +1,4 @@ +// run-pass // exec-env:TEST_EXEC_ENV=22 // ignore-cloudabi no env vars // ignore-emscripten FIXME: issue #31622 diff --git a/src/test/ui/exhaustive_integer_patterns.stderr b/src/test/ui/exhaustive_integer_patterns.stderr index 82b0b48414..6c4b7b0cc0 100644 --- a/src/test/ui/exhaustive_integer_patterns.stderr +++ b/src/test/ui/exhaustive_integer_patterns.stderr @@ -10,11 +10,11 @@ note: lint level defined here LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ -error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered +error[E0004]: non-exhaustive patterns: `128u8..=std::u8::MAX` not covered --> $DIR/exhaustive_integer_patterns.rs:28:11 | LL | match x { - | ^ pattern `128u8..=255u8` not covered + | ^ pattern `128u8..=std::u8::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -32,19 +32,19 @@ error: unreachable pattern LL | -2..=20 => {} | ^^^^^^^ -error[E0004]: non-exhaustive patterns: `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered +error[E0004]: non-exhaustive patterns: `std::i8::MIN..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered --> $DIR/exhaustive_integer_patterns.rs:41:11 | LL | match x { - | ^ patterns `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered + | ^ patterns `std::i8::MIN..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `-128i8` not covered +error[E0004]: non-exhaustive patterns: `std::i8::MIN` not covered --> $DIR/exhaustive_integer_patterns.rs:82:11 | LL | match 0i8 { - | ^^^ pattern `-128i8` not covered + | ^^^ pattern `std::i8::MIN` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -56,19 +56,19 @@ LL | match 0i16 { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered +error[E0004]: non-exhaustive patterns: `128u8..=std::u8::MAX` not covered --> $DIR/exhaustive_integer_patterns.rs:108:11 | LL | match 0u8 { - | ^^^ pattern `128u8..=255u8` not covered + | ^^^ pattern `128u8..=std::u8::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered +error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=std::u8::MAX, Some(_))` not covered --> $DIR/exhaustive_integer_patterns.rs:120:11 | LL | match (0u8, Some(())) { - | ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered + | ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=std::u8::MAX, Some(_))` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -80,19 +80,19 @@ LL | match (0u8, true) { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211455u128` not covered +error[E0004]: non-exhaustive patterns: `std::u128::MAX` not covered --> $DIR/exhaustive_integer_patterns.rs:145:11 | LL | match 0u128 { - | ^^^^^ pattern `340282366920938463463374607431768211455u128` not covered + | ^^^^^ pattern `std::u128::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `5u128..=340282366920938463463374607431768211455u128` not covered +error[E0004]: non-exhaustive patterns: `5u128..=std::u128::MAX` not covered --> $DIR/exhaustive_integer_patterns.rs:149:11 | LL | match 0u128 { - | ^^^^^ pattern `5u128..=340282366920938463463374607431768211455u128` not covered + | ^^^^^ pattern `5u128..=std::u128::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs deleted file mode 100644 index 96ab476061..0000000000 --- a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Crate that exports an existential type. Used for testing cross-crate. - -#![crate_type="rlib"] - -#![feature(existential_type)] - -pub existential type Foo: std::fmt::Debug; - -pub fn foo() -> Foo { - 5 -} diff --git a/src/test/ui/existential_types/declared_but_never_defined.rs b/src/test/ui/existential_types/declared_but_never_defined.rs deleted file mode 100644 index ff253391f2..0000000000 --- a/src/test/ui/existential_types/declared_but_never_defined.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(existential_type)] - -fn main() {} - -// declared but never defined -existential type Bar: std::fmt::Debug; //~ ERROR could not find defining uses diff --git a/src/test/ui/existential_types/declared_but_not_defined_in_scope.rs b/src/test/ui/existential_types/declared_but_not_defined_in_scope.rs deleted file mode 100644 index a6311ee964..0000000000 --- a/src/test/ui/existential_types/declared_but_not_defined_in_scope.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(existential_type)] - -fn main() {} - -mod boo { - // declared in module but not defined inside of it - pub existential type Boo: ::std::fmt::Debug; //~ ERROR could not find defining uses -} - -fn bomp() -> boo::Boo { - "" -} diff --git a/src/test/ui/existential_types/existential-types-with-cycle-error.rs b/src/test/ui/existential_types/existential-types-with-cycle-error.rs deleted file mode 100644 index 3f0190892e..0000000000 --- a/src/test/ui/existential_types/existential-types-with-cycle-error.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(existential_type)] - -existential type Foo: Fn() -> Foo; -//~^ ERROR: cycle detected when processing `Foo` - -fn crash(x: Foo) -> Foo { - x -} - -fn main() { - -} diff --git a/src/test/ui/existential_types/existential-types-with-cycle-error.stderr b/src/test/ui/existential_types/existential-types-with-cycle-error.stderr deleted file mode 100644 index 56057a9caa..0000000000 --- a/src/test/ui/existential_types/existential-types-with-cycle-error.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0391]: cycle detected when processing `Foo` - --> $DIR/existential-types-with-cycle-error.rs:3:1 - | -LL | existential type Foo: Fn() -> Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires processing `crash`... - --> $DIR/existential-types-with-cycle-error.rs:6:25 - | -LL | fn crash(x: Foo) -> Foo { - | _________________________^ -LL | | x -LL | | } - | |_^ - = note: ...which again requires processing `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/existential-types-with-cycle-error.rs:1:1 - | -LL | / #![feature(existential_type)] -LL | | -LL | | existential type Foo: Fn() -> Foo; -LL | | -... | -LL | | -LL | | } - | |_^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/existential_types/existential-types-with-cycle-error2.rs b/src/test/ui/existential_types/existential-types-with-cycle-error2.rs deleted file mode 100644 index 29410309ef..0000000000 --- a/src/test/ui/existential_types/existential-types-with-cycle-error2.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(existential_type)] - -pub trait Bar { - type Item; -} - -existential type Foo: Bar; -//~^ ERROR: cycle detected when processing `Foo` - -fn crash(x: Foo) -> Foo { - x -} - -fn main() { - -} diff --git a/src/test/ui/existential_types/existential-types-with-cycle-error2.stderr b/src/test/ui/existential_types/existential-types-with-cycle-error2.stderr deleted file mode 100644 index 8c7bf52470..0000000000 --- a/src/test/ui/existential_types/existential-types-with-cycle-error2.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0391]: cycle detected when processing `Foo` - --> $DIR/existential-types-with-cycle-error2.rs:7:1 - | -LL | existential type Foo: Bar; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires processing `crash`... - --> $DIR/existential-types-with-cycle-error2.rs:10:25 - | -LL | fn crash(x: Foo) -> Foo { - | _________________________^ -LL | | x -LL | | } - | |_^ - = note: ...which again requires processing `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/existential-types-with-cycle-error2.rs:1:1 - | -LL | / #![feature(existential_type)] -LL | | -LL | | pub trait Bar { -LL | | type Item; -... | -LL | | -LL | | } - | |_^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/existential_types/generic_duplicate_lifetime_param.rs b/src/test/ui/existential_types/generic_duplicate_lifetime_param.rs deleted file mode 100644 index e9943beddb..0000000000 --- a/src/test/ui/existential_types/generic_duplicate_lifetime_param.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(existential_type)] - -fn main() {} - -existential type Two<'a, 'b>: std::fmt::Debug; - -fn one<'a>(t: &'a ()) -> Two<'a, 'a> { //~ ERROR non-defining existential type use - t -} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use10.rs b/src/test/ui/existential_types/generic_duplicate_param_use10.rs deleted file mode 100644 index 10f2c63058..0000000000 --- a/src/test/ui/existential_types/generic_duplicate_param_use10.rs +++ /dev/null @@ -1,12 +0,0 @@ -// compile-pass -#![feature(existential_type)] - -use std::fmt::Debug; - -fn main() {} - -existential type Two: Debug; - -fn two(t: T, _: U) -> Two { - (t, 4u32) -} diff --git a/src/test/ui/existential_types/generic_lifetime_param.rs b/src/test/ui/existential_types/generic_lifetime_param.rs deleted file mode 100644 index a8bb0229f0..0000000000 --- a/src/test/ui/existential_types/generic_lifetime_param.rs +++ /dev/null @@ -1,11 +0,0 @@ -// compile-pass - -#![feature(existential_type)] - -fn main() {} - -existential type Region<'a>: std::fmt::Debug; - -fn region<'b>(a: &'b ()) -> Region<'b> { - a -} diff --git a/src/test/ui/existential_types/no_inferrable_concrete_type.rs b/src/test/ui/existential_types/no_inferrable_concrete_type.rs deleted file mode 100644 index 6bbe8bdc0c..0000000000 --- a/src/test/ui/existential_types/no_inferrable_concrete_type.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Issue 52985: Cause cycle error if user code provides no use case that allows an existential type -// to be inferred to a concrete type. This results in an infinite cycle during type normalization. - -#![feature(existential_type)] - -existential type Foo: Copy; //~ cycle detected - -// make compiler happy about using 'Foo' -fn bar(x: Foo) -> Foo { x } - -fn main() { - let _: Foo = std::mem::transmute(0u8); -} diff --git a/src/test/ui/existential_types/no_inferrable_concrete_type.stderr b/src/test/ui/existential_types/no_inferrable_concrete_type.stderr deleted file mode 100644 index 4605332ef5..0000000000 --- a/src/test/ui/existential_types/no_inferrable_concrete_type.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0391]: cycle detected when processing `Foo` - --> $DIR/no_inferrable_concrete_type.rs:6:1 - | -LL | existential type Foo: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires processing `bar`... - --> $DIR/no_inferrable_concrete_type.rs:9:23 - | -LL | fn bar(x: Foo) -> Foo { x } - | ^^^^^ - = note: ...which again requires processing `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/no_inferrable_concrete_type.rs:4:1 - | -LL | / #![feature(existential_type)] -LL | | -LL | | existential type Foo: Copy; -LL | | -... | -LL | | let _: Foo = std::mem::transmute(0u8); -LL | | } - | |_^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/existential_types/unused_generic_param.stderr b/src/test/ui/existential_types/unused_generic_param.stderr deleted file mode 100644 index 9d628d069d..0000000000 --- a/src/test/ui/existential_types/unused_generic_param.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: at least one trait must be specified - --> $DIR/unused_generic_param.rs:6:39 - | -LL | existential type PartiallyDefined: 'static; - | ^^^^^^^ - -error: at least one trait must be specified - --> $DIR/unused_generic_param.rs:13:40 - | -LL | existential type PartiallyDefined2: 'static; - | ^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/explain.rs b/src/test/ui/explain.rs index 3622ba7764..28973d6756 100644 --- a/src/test/ui/explain.rs +++ b/src/test/ui/explain.rs @@ -1,2 +1,2 @@ // compile-flags: --explain E0591 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) diff --git a/src/test/run-pass/explicit-i-suffix.rs b/src/test/ui/explicit-i-suffix.rs similarity index 93% rename from src/test/run-pass/explicit-i-suffix.rs rename to src/test/ui/explicit-i-suffix.rs index 119cce3087..40c7e47510 100644 --- a/src/test/run-pass/explicit-i-suffix.rs +++ b/src/test/ui/explicit-i-suffix.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/explore-issue-38412.stderr b/src/test/ui/explore-issue-38412.stderr index ceeaaafc2b..547874cefd 100644 --- a/src/test/ui/explore-issue-38412.stderr +++ b/src/test/ui/explore-issue-38412.stderr @@ -5,7 +5,7 @@ LL | let Record { a_stable_pub: _, a_unstable_declared_pub: _, a_unstable_un | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_undeclared' --> $DIR/explore-issue-38412.rs:30:5 @@ -14,7 +14,7 @@ LL | r.a_unstable_undeclared_pub; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0616]: field `b_crate` of struct `pub_and_stability::Record` is private --> $DIR/explore-issue-38412.rs:31:5 @@ -41,7 +41,7 @@ LL | t.2; | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0616]: field `3` of struct `pub_and_stability::Tuple` is private --> $DIR/explore-issue-38412.rs:38:5 @@ -68,7 +68,7 @@ LL | r.unstable_undeclared_trait_method(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_undeclared' --> $DIR/explore-issue-38412.rs:48:7 @@ -77,7 +77,7 @@ LL | r.unstable_undeclared(); | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0624]: method `pub_crate` is private --> $DIR/explore-issue-38412.rs:50:7 @@ -104,7 +104,7 @@ LL | t.unstable_undeclared_trait_method(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_undeclared' --> $DIR/explore-issue-38412.rs:61:7 @@ -113,7 +113,7 @@ LL | t.unstable_undeclared(); | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38412 - = help: add #![feature(unstable_undeclared)] to the crate attributes to enable + = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable error[E0624]: method `pub_crate` is private --> $DIR/explore-issue-38412.rs:63:7 diff --git a/src/test/run-pass/export-glob-imports-target.rs b/src/test/ui/export-glob-imports-target.rs similarity index 96% rename from src/test/run-pass/export-glob-imports-target.rs rename to src/test/ui/export-glob-imports-target.rs index 0ac80e6579..4df807ea4c 100644 --- a/src/test/run-pass/export-glob-imports-target.rs +++ b/src/test/ui/export-glob-imports-target.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_upper_case_globals)] #![allow(dead_code)] // Test that a glob-export functions as an import diff --git a/src/test/run-pass/export-multi.rs b/src/test/ui/export-multi.rs similarity index 92% rename from src/test/run-pass/export-multi.rs rename to src/test/ui/export-multi.rs index bfa2765d25..02bdbe8aff 100644 --- a/src/test/run-pass/export-multi.rs +++ b/src/test/ui/export-multi.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 use m::f; diff --git a/src/test/run-pass/export-non-interference2.rs b/src/test/ui/export-non-interference2.rs similarity index 92% rename from src/test/run-pass/export-non-interference2.rs rename to src/test/ui/export-non-interference2.rs index 30d5a0d9c0..6d18b03891 100644 --- a/src/test/run-pass/export-non-interference2.rs +++ b/src/test/ui/export-non-interference2.rs @@ -1,3 +1,5 @@ +// run-pass + mod foo { pub mod bar { pub fn y() { super::super::foo::x(); } diff --git a/src/test/run-pass/export-non-interference3.rs b/src/test/ui/export-non-interference3.rs similarity index 90% rename from src/test/run-pass/export-non-interference3.rs rename to src/test/ui/export-non-interference3.rs index a11ea3a045..0d6b6369f9 100644 --- a/src/test/run-pass/export-non-interference3.rs +++ b/src/test/ui/export-non-interference3.rs @@ -1,3 +1,5 @@ +// run-pass + pub mod foo { pub fn x() { ::bar::x(); } } diff --git a/src/test/run-pass/expr-block-fn.rs b/src/test/ui/expr-block-fn.rs similarity index 90% rename from src/test/run-pass/expr-block-fn.rs rename to src/test/ui/expr-block-fn.rs index 229e2b02bf..1cac2cac0a 100644 --- a/src/test/run-pass/expr-block-fn.rs +++ b/src/test/ui/expr-block-fn.rs @@ -1,3 +1,5 @@ +// run-pass + fn test_fn() { fn ten() -> isize { return 10; } let rs = ten; diff --git a/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/ui/expr-block-generic-unique1.rs similarity index 97% rename from src/test/run-pass/expr-block-generic-unique1.rs rename to src/test/ui/expr-block-generic-unique1.rs index b89f2f9660..c14191f2ff 100644 --- a/src/test/run-pass/expr-block-generic-unique1.rs +++ b/src/test/ui/expr-block-generic-unique1.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] fn test_generic(expected: Box, eq: F) where T: Clone, F: FnOnce(Box, Box) -> bool { diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/ui/expr-block-generic-unique2.rs similarity index 96% rename from src/test/run-pass/expr-block-generic-unique2.rs rename to src/test/ui/expr-block-generic-unique2.rs index 4c712abcc3..90ebc02931 100644 --- a/src/test/run-pass/expr-block-generic-unique2.rs +++ b/src/test/ui/expr-block-generic-unique2.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] fn test_generic(expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> bool { diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/ui/expr-block-generic.rs similarity index 97% rename from src/test/run-pass/expr-block-generic.rs rename to src/test/ui/expr-block-generic.rs index 5665790a84..ec93f59722 100644 --- a/src/test/run-pass/expr-block-generic.rs +++ b/src/test/ui/expr-block-generic.rs @@ -1,3 +1,5 @@ +// run-pass + fn test_generic(expected: T, eq: F) where F: FnOnce(T, T) -> bool { let actual: T = { expected.clone() }; assert!(eq(expected, actual)); diff --git a/src/test/run-pass/expr-block-slot.rs b/src/test/ui/expr-block-slot.rs similarity index 94% rename from src/test/run-pass/expr-block-slot.rs rename to src/test/ui/expr-block-slot.rs index 65d58e00bc..54bcbb328b 100644 --- a/src/test/run-pass/expr-block-slot.rs +++ b/src/test/ui/expr-block-slot.rs @@ -1,3 +1,4 @@ +// run-pass // Regression test for issue #377 diff --git a/src/test/run-pass/expr-block-unique.rs b/src/test/ui/expr-block-unique.rs similarity index 87% rename from src/test/run-pass/expr-block-unique.rs rename to src/test/ui/expr-block-unique.rs index a5b7bacec2..fe1a7d9f1f 100644 --- a/src/test/run-pass/expr-block-unique.rs +++ b/src/test/ui/expr-block-unique.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] pub fn main() { let x: Box<_> = { box 100 }; assert_eq!(*x, 100); } diff --git a/src/test/run-pass/expr-block.rs b/src/test/ui/expr-block.rs similarity index 97% rename from src/test/run-pass/expr-block.rs rename to src/test/ui/expr-block.rs index 222e5cfbcf..549ccf9774 100644 --- a/src/test/run-pass/expr-block.rs +++ b/src/test/ui/expr-block.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] diff --git a/src/test/run-pass/expr-copy.rs b/src/test/ui/expr-copy.rs similarity index 94% rename from src/test/run-pass/expr-copy.rs rename to src/test/ui/expr-copy.rs index fdea32f476..1c6ae03810 100644 --- a/src/test/run-pass/expr-copy.rs +++ b/src/test/ui/expr-copy.rs @@ -1,3 +1,5 @@ +// run-pass + fn f(arg: &mut A) { arg.a = 100; } diff --git a/src/test/run-pass/expr-empty-ret.rs b/src/test/ui/expr-empty-ret.rs similarity index 93% rename from src/test/run-pass/expr-empty-ret.rs rename to src/test/ui/expr-empty-ret.rs index 6bdf4350a9..ce8ffaf94d 100644 --- a/src/test/run-pass/expr-empty-ret.rs +++ b/src/test/ui/expr-empty-ret.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Issue #521 diff --git a/src/test/run-pass/expr-fn.rs b/src/test/ui/expr-fn.rs similarity index 98% rename from src/test/run-pass/expr-fn.rs rename to src/test/ui/expr-fn.rs index 9e0679b959..af809f563f 100644 --- a/src/test/run-pass/expr-fn.rs +++ b/src/test/ui/expr-fn.rs @@ -1,3 +1,5 @@ +// run-pass + fn test_int() { fn f() -> isize { 10 } assert_eq!(f(), 10); diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/ui/expr-if-generic.rs similarity index 98% rename from src/test/run-pass/expr-if-generic.rs rename to src/test/ui/expr-if-generic.rs index 3e3600c452..32ed6d9bee 100644 --- a/src/test/run-pass/expr-if-generic.rs +++ b/src/test/ui/expr-if-generic.rs @@ -1,3 +1,5 @@ +// run-pass + fn test_generic(expected: T, not_expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> bool, diff --git a/src/test/run-pass/expr-if-panic-all.rs b/src/test/ui/expr-if-panic-all.rs similarity index 94% rename from src/test/run-pass/expr-if-panic-all.rs rename to src/test/ui/expr-if-panic-all.rs index ea7f36f8a3..f915a7d9da 100644 --- a/src/test/run-pass/expr-if-panic-all.rs +++ b/src/test/ui/expr-if-panic-all.rs @@ -1,3 +1,4 @@ +// run-pass // When all branches of an if expression result in panic, the entire if // expression results in panic. diff --git a/src/test/run-pass/expr-if-panic.rs b/src/test/ui/expr-if-panic.rs similarity index 96% rename from src/test/run-pass/expr-if-panic.rs rename to src/test/ui/expr-if-panic.rs index ae92e3b125..6069cd835e 100644 --- a/src/test/run-pass/expr-if-panic.rs +++ b/src/test/ui/expr-if-panic.rs @@ -1,3 +1,5 @@ +// run-pass + fn test_if_panic() { let x = if false { panic!() } else { 10 }; assert_eq!(x, 10); diff --git a/src/test/run-pass/expr-if-unique.rs b/src/test/ui/expr-if-unique.rs similarity index 94% rename from src/test/run-pass/expr-if-unique.rs rename to src/test/ui/expr-if-unique.rs index ef76fb27e9..509d069d40 100644 --- a/src/test/run-pass/expr-if-unique.rs +++ b/src/test/ui/expr-if-unique.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] // Tests for if as expressions returning boxed types diff --git a/src/test/run-pass/expr-if.rs b/src/test/ui/expr-if.rs similarity index 99% rename from src/test/run-pass/expr-if.rs rename to src/test/ui/expr-if.rs index 4b8d363b02..2b8474ff45 100644 --- a/src/test/run-pass/expr-if.rs +++ b/src/test/ui/expr-if.rs @@ -1,3 +1,4 @@ +// run-pass // Tests for if as expressions fn test_if() { let rs: bool = if true { true } else { false }; assert!((rs)); } diff --git a/src/test/run-pass/expr-scope.rs b/src/test/ui/expr-scope.rs similarity index 90% rename from src/test/run-pass/expr-scope.rs rename to src/test/ui/expr-scope.rs index 15bb4a2eb0..9976b6814c 100644 --- a/src/test/run-pass/expr-scope.rs +++ b/src/test/ui/expr-scope.rs @@ -1,3 +1,4 @@ +// run-pass // Regression test for issue #762 // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/ext-expand-inner-exprs.rs b/src/test/ui/ext-expand-inner-exprs.rs similarity index 90% rename from src/test/run-pass/ext-expand-inner-exprs.rs rename to src/test/ui/ext-expand-inner-exprs.rs index a32b3d7f00..5bbdf5ec95 100644 --- a/src/test/run-pass/ext-expand-inner-exprs.rs +++ b/src/test/ui/ext-expand-inner-exprs.rs @@ -1,3 +1,5 @@ +// run-pass + static FOO : &'static str = concat!(concat!("hel", "lo"), "world"); pub fn main() { diff --git a/src/test/run-pass/extend-for-unit.rs b/src/test/ui/extend-for-unit.rs similarity index 92% rename from src/test/run-pass/extend-for-unit.rs rename to src/test/ui/extend-for-unit.rs index 1c1e61239b..01d743f70b 100644 --- a/src/test/run-pass/extend-for-unit.rs +++ b/src/test/ui/extend-for-unit.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let mut x = 0; { diff --git a/src/test/run-pass/exterior.rs b/src/test/ui/exterior.rs similarity index 97% rename from src/test/run-pass/exterior.rs rename to src/test/ui/exterior.rs index 01ed7dbac1..6f2c37926b 100644 --- a/src/test/run-pass/exterior.rs +++ b/src/test/ui/exterior.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] diff --git a/src/test/ui/extern-prelude-fail.stderr b/src/test/ui/extern-prelude-fail.stderr index 9cd56ea7f5..a59f4c952b 100644 --- a/src/test/ui/extern-prelude-fail.stderr +++ b/src/test/ui/extern-prelude-fail.stderr @@ -2,13 +2,13 @@ error[E0432]: unresolved import `extern_prelude` --> $DIR/extern-prelude-fail.rs:7:9 | LL | use extern_prelude::S; - | ^^^^^^^^^^^^^^ maybe a missing `extern crate extern_prelude;`? + | ^^^^^^^^^^^^^^ maybe a missing crate `extern_prelude`? -error[E0433]: failed to resolve: maybe a missing `extern crate extern_prelude;`? +error[E0433]: failed to resolve: maybe a missing crate `extern_prelude`? --> $DIR/extern-prelude-fail.rs:8:15 | LL | let s = ::extern_prelude::S; - | ^^^^^^^^^^^^^^ maybe a missing `extern crate extern_prelude;`? + | ^^^^^^^^^^^^^^ maybe a missing crate `extern_prelude`? error: aborting due to 2 previous errors diff --git a/src/test/ui/extern-prelude.rs b/src/test/ui/extern-prelude.rs index 0e52f2c515..50fed6034a 100644 --- a/src/test/ui/extern-prelude.rs +++ b/src/test/ui/extern-prelude.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--extern extern_prelude --extern Vec // aux-build:extern-prelude.rs // aux-build:extern-prelude-vec.rs diff --git a/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs b/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs similarity index 100% rename from src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs rename to src/test/ui/extern/auxiliary/extern-crosscrate-source.rs diff --git a/src/test/run-pass/extern/auxiliary/extern-take-value.rs b/src/test/ui/extern/auxiliary/extern-take-value.rs similarity index 100% rename from src/test/run-pass/extern/auxiliary/extern-take-value.rs rename to src/test/ui/extern/auxiliary/extern-take-value.rs diff --git a/src/test/run-pass/extern/auxiliary/extern_calling_convention.rs b/src/test/ui/extern/auxiliary/extern_calling_convention.rs similarity index 100% rename from src/test/run-pass/extern/auxiliary/extern_calling_convention.rs rename to src/test/ui/extern/auxiliary/extern_calling_convention.rs diff --git a/src/test/run-pass/extern/auxiliary/extern_mod_ordering_lib.rs b/src/test/ui/extern/auxiliary/extern_mod_ordering_lib.rs similarity index 100% rename from src/test/run-pass/extern/auxiliary/extern_mod_ordering_lib.rs rename to src/test/ui/extern/auxiliary/extern_mod_ordering_lib.rs diff --git a/src/test/run-pass/extern/auxiliary/fat_drop.rs b/src/test/ui/extern/auxiliary/fat_drop.rs similarity index 100% rename from src/test/run-pass/extern/auxiliary/fat_drop.rs rename to src/test/ui/extern/auxiliary/fat_drop.rs diff --git a/src/test/run-pass/extern/extern-1.rs b/src/test/ui/extern/extern-1.rs similarity index 100% rename from src/test/run-pass/extern/extern-1.rs rename to src/test/ui/extern/extern-1.rs diff --git a/src/test/run-pass/extern/extern-call-deep.rs b/src/test/ui/extern/extern-call-deep.rs similarity index 100% rename from src/test/run-pass/extern/extern-call-deep.rs rename to src/test/ui/extern/extern-call-deep.rs diff --git a/src/test/run-pass/extern/extern-call-deep2.rs b/src/test/ui/extern/extern-call-deep2.rs similarity index 100% rename from src/test/run-pass/extern/extern-call-deep2.rs rename to src/test/ui/extern/extern-call-deep2.rs diff --git a/src/test/run-pass/extern/extern-call-direct.rs b/src/test/ui/extern/extern-call-direct.rs similarity index 100% rename from src/test/run-pass/extern/extern-call-direct.rs rename to src/test/ui/extern/extern-call-direct.rs diff --git a/src/test/run-pass/extern/extern-call-indirect.rs b/src/test/ui/extern/extern-call-indirect.rs similarity index 100% rename from src/test/run-pass/extern/extern-call-indirect.rs rename to src/test/ui/extern/extern-call-indirect.rs diff --git a/src/test/run-pass/extern/extern-call-scrub.rs b/src/test/ui/extern/extern-call-scrub.rs similarity index 100% rename from src/test/run-pass/extern/extern-call-scrub.rs rename to src/test/ui/extern/extern-call-scrub.rs diff --git a/src/test/run-pass/extern/extern-calling-convention-test.rs b/src/test/ui/extern/extern-calling-convention-test.rs similarity index 100% rename from src/test/run-pass/extern/extern-calling-convention-test.rs rename to src/test/ui/extern/extern-calling-convention-test.rs diff --git a/src/test/run-pass/extern/extern-compare-with-return-type.rs b/src/test/ui/extern/extern-compare-with-return-type.rs similarity index 100% rename from src/test/run-pass/extern/extern-compare-with-return-type.rs rename to src/test/ui/extern/extern-compare-with-return-type.rs diff --git a/src/test/ui/extern/extern-crate-visibility.rs b/src/test/ui/extern/extern-crate-visibility.rs index b51e443903..e0a5cd5e98 100644 --- a/src/test/ui/extern/extern-crate-visibility.rs +++ b/src/test/ui/extern/extern-crate-visibility.rs @@ -3,10 +3,10 @@ mod foo { } // Check that private crates can be used from outside their modules, albeit with warnings -use foo::core::cell; //~ ERROR extern crate `core` is private +use foo::core::cell; //~ ERROR crate `core` is private fn f() { - foo::core::cell::Cell::new(0); //~ ERROR extern crate `core` is private + foo::core::cell::Cell::new(0); //~ ERROR crate `core` is private use foo::*; mod core {} // Check that private crates are not glob imported diff --git a/src/test/ui/extern/extern-crate-visibility.stderr b/src/test/ui/extern/extern-crate-visibility.stderr index 8bc9f9a67e..38c791ab83 100644 --- a/src/test/ui/extern/extern-crate-visibility.stderr +++ b/src/test/ui/extern/extern-crate-visibility.stderr @@ -1,10 +1,10 @@ -error[E0603]: extern crate `core` is private +error[E0603]: crate `core` is private --> $DIR/extern-crate-visibility.rs:6:10 | LL | use foo::core::cell; | ^^^^ -error[E0603]: extern crate `core` is private +error[E0603]: crate `core` is private --> $DIR/extern-crate-visibility.rs:9:10 | LL | foo::core::cell::Cell::new(0); diff --git a/src/test/run-pass/extern/extern-crosscrate.rs b/src/test/ui/extern/extern-crosscrate.rs similarity index 100% rename from src/test/run-pass/extern/extern-crosscrate.rs rename to src/test/ui/extern/extern-crosscrate.rs diff --git a/src/test/ui/extern/extern-ffi-fn-with-body.rs b/src/test/ui/extern/extern-ffi-fn-with-body.rs new file mode 100644 index 0000000000..4cf563514e --- /dev/null +++ b/src/test/ui/extern/extern-ffi-fn-with-body.rs @@ -0,0 +1,11 @@ +extern "C" { + fn foo() -> i32 { //~ ERROR incorrect `fn` inside `extern` block + return 0; + } +} + +extern "C" fn bar() -> i32 { + return 0; +} + +fn main() {} diff --git a/src/test/ui/extern/extern-ffi-fn-with-body.stderr b/src/test/ui/extern/extern-ffi-fn-with-body.stderr new file mode 100644 index 0000000000..4ac3ce1f93 --- /dev/null +++ b/src/test/ui/extern/extern-ffi-fn-with-body.stderr @@ -0,0 +1,18 @@ +error: incorrect `fn` inside `extern` block + --> $DIR/extern-ffi-fn-with-body.rs:2:8 + | +LL | extern "C" { + | ------ `extern` blocks define existing foreign functions and `fn`s inside of them cannot have a body +LL | fn foo() -> i32 { + | ________^^^__________- + | | | + | | can't have a body +LL | | return 0; +LL | | } + | |_____- this body is invalid here + | + = help: you might have meant to write a function accessible through ffi, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to previous error + diff --git a/src/test/run-pass/extern/extern-foreign-crate.rs b/src/test/ui/extern/extern-foreign-crate.rs similarity index 100% rename from src/test/run-pass/extern/extern-foreign-crate.rs rename to src/test/ui/extern/extern-foreign-crate.rs diff --git a/src/test/run-pass/extern/extern-methods.rs b/src/test/ui/extern/extern-methods.rs similarity index 100% rename from src/test/run-pass/extern/extern-methods.rs rename to src/test/ui/extern/extern-methods.rs diff --git a/src/test/run-pass/extern/extern-mod-abi.rs b/src/test/ui/extern/extern-mod-abi.rs similarity index 100% rename from src/test/run-pass/extern/extern-mod-abi.rs rename to src/test/ui/extern/extern-mod-abi.rs diff --git a/src/test/run-pass/extern/extern-mod-ordering-exe.rs b/src/test/ui/extern/extern-mod-ordering-exe.rs similarity index 100% rename from src/test/run-pass/extern/extern-mod-ordering-exe.rs rename to src/test/ui/extern/extern-mod-ordering-exe.rs diff --git a/src/test/run-pass/extern/extern-pass-TwoU16s.rs b/src/test/ui/extern/extern-pass-TwoU16s.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-TwoU16s.rs rename to src/test/ui/extern/extern-pass-TwoU16s.rs diff --git a/src/test/run-pass/extern/extern-pass-TwoU32s.rs b/src/test/ui/extern/extern-pass-TwoU32s.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-TwoU32s.rs rename to src/test/ui/extern/extern-pass-TwoU32s.rs diff --git a/src/test/run-pass/extern/extern-pass-TwoU64s.rs b/src/test/ui/extern/extern-pass-TwoU64s.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-TwoU64s.rs rename to src/test/ui/extern/extern-pass-TwoU64s.rs diff --git a/src/test/run-pass/extern/extern-pass-TwoU8s.rs b/src/test/ui/extern/extern-pass-TwoU8s.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-TwoU8s.rs rename to src/test/ui/extern/extern-pass-TwoU8s.rs diff --git a/src/test/run-pass/extern/extern-pass-char.rs b/src/test/ui/extern/extern-pass-char.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-char.rs rename to src/test/ui/extern/extern-pass-char.rs diff --git a/src/test/run-pass/extern/extern-pass-double.rs b/src/test/ui/extern/extern-pass-double.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-double.rs rename to src/test/ui/extern/extern-pass-double.rs diff --git a/src/test/run-pass/extern/extern-pass-empty.rs b/src/test/ui/extern/extern-pass-empty.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-empty.rs rename to src/test/ui/extern/extern-pass-empty.rs diff --git a/src/test/run-pass/extern/extern-pass-u32.rs b/src/test/ui/extern/extern-pass-u32.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-u32.rs rename to src/test/ui/extern/extern-pass-u32.rs diff --git a/src/test/run-pass/extern/extern-pass-u64.rs b/src/test/ui/extern/extern-pass-u64.rs similarity index 100% rename from src/test/run-pass/extern/extern-pass-u64.rs rename to src/test/ui/extern/extern-pass-u64.rs diff --git a/src/test/run-pass/extern/extern-prelude-core.rs b/src/test/ui/extern/extern-prelude-core.rs similarity index 100% rename from src/test/run-pass/extern/extern-prelude-core.rs rename to src/test/ui/extern/extern-prelude-core.rs diff --git a/src/test/run-pass/extern/extern-prelude-core.stderr b/src/test/ui/extern/extern-prelude-core.stderr similarity index 82% rename from src/test/run-pass/extern/extern-prelude-core.stderr rename to src/test/ui/extern/extern-prelude-core.stderr index 8d2a0b7425..f90eb933d3 100644 --- a/src/test/run-pass/extern/extern-prelude-core.stderr +++ b/src/test/ui/extern/extern-prelude-core.stderr @@ -4,5 +4,5 @@ warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer LL | #![feature(extern_prelude, lang_items, start)] | ^^^^^^^^^^^^^^ | - = note: #[warn(stable_features)] on by default + = note: `#[warn(stable_features)]` on by default diff --git a/src/test/run-pass/extern/extern-prelude-no-speculative.rs b/src/test/ui/extern/extern-prelude-no-speculative.rs similarity index 100% rename from src/test/run-pass/extern/extern-prelude-no-speculative.rs rename to src/test/ui/extern/extern-prelude-no-speculative.rs diff --git a/src/test/run-pass/extern/extern-prelude-std.rs b/src/test/ui/extern/extern-prelude-std.rs similarity index 100% rename from src/test/run-pass/extern/extern-prelude-std.rs rename to src/test/ui/extern/extern-prelude-std.rs diff --git a/src/test/run-pass/extern/extern-prelude-std.stderr b/src/test/ui/extern/extern-prelude-std.stderr similarity index 81% rename from src/test/run-pass/extern/extern-prelude-std.stderr rename to src/test/ui/extern/extern-prelude-std.stderr index f193c57146..73b1dcfd5e 100644 --- a/src/test/run-pass/extern/extern-prelude-std.stderr +++ b/src/test/ui/extern/extern-prelude-std.stderr @@ -4,5 +4,5 @@ warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer LL | #![feature(extern_prelude)] | ^^^^^^^^^^^^^^ | - = note: #[warn(stable_features)] on by default + = note: `#[warn(stable_features)]` on by default diff --git a/src/test/run-pass/extern/extern-pub.rs b/src/test/ui/extern/extern-pub.rs similarity index 100% rename from src/test/run-pass/extern/extern-pub.rs rename to src/test/ui/extern/extern-pub.rs diff --git a/src/test/run-pass/extern/extern-return-TwoU16s.rs b/src/test/ui/extern/extern-return-TwoU16s.rs similarity index 100% rename from src/test/run-pass/extern/extern-return-TwoU16s.rs rename to src/test/ui/extern/extern-return-TwoU16s.rs diff --git a/src/test/run-pass/extern/extern-return-TwoU32s.rs b/src/test/ui/extern/extern-return-TwoU32s.rs similarity index 100% rename from src/test/run-pass/extern/extern-return-TwoU32s.rs rename to src/test/ui/extern/extern-return-TwoU32s.rs diff --git a/src/test/run-pass/extern/extern-return-TwoU64s.rs b/src/test/ui/extern/extern-return-TwoU64s.rs similarity index 100% rename from src/test/run-pass/extern/extern-return-TwoU64s.rs rename to src/test/ui/extern/extern-return-TwoU64s.rs diff --git a/src/test/run-pass/extern/extern-return-TwoU8s.rs b/src/test/ui/extern/extern-return-TwoU8s.rs similarity index 100% rename from src/test/run-pass/extern/extern-return-TwoU8s.rs rename to src/test/ui/extern/extern-return-TwoU8s.rs diff --git a/src/test/run-pass/extern/extern-rust.rs b/src/test/ui/extern/extern-rust.rs similarity index 100% rename from src/test/run-pass/extern/extern-rust.rs rename to src/test/ui/extern/extern-rust.rs diff --git a/src/test/run-pass/extern/extern-take-value.rs b/src/test/ui/extern/extern-take-value.rs similarity index 100% rename from src/test/run-pass/extern/extern-take-value.rs rename to src/test/ui/extern/extern-take-value.rs diff --git a/src/test/run-pass/extern/extern-thiscall.rs b/src/test/ui/extern/extern-thiscall.rs similarity index 100% rename from src/test/run-pass/extern/extern-thiscall.rs rename to src/test/ui/extern/extern-thiscall.rs diff --git a/src/test/run-pass/extern/extern-types-inherent-impl.rs b/src/test/ui/extern/extern-types-inherent-impl.rs similarity index 100% rename from src/test/run-pass/extern/extern-types-inherent-impl.rs rename to src/test/ui/extern/extern-types-inherent-impl.rs diff --git a/src/test/run-pass/extern/extern-types-manual-sync-send.rs b/src/test/ui/extern/extern-types-manual-sync-send.rs similarity index 100% rename from src/test/run-pass/extern/extern-types-manual-sync-send.rs rename to src/test/ui/extern/extern-types-manual-sync-send.rs diff --git a/src/test/run-pass/extern/extern-types-pointer-cast.rs b/src/test/ui/extern/extern-types-pointer-cast.rs similarity index 100% rename from src/test/run-pass/extern/extern-types-pointer-cast.rs rename to src/test/ui/extern/extern-types-pointer-cast.rs diff --git a/src/test/run-pass/extern/extern-types-size_of_val.rs b/src/test/ui/extern/extern-types-size_of_val.rs similarity index 100% rename from src/test/run-pass/extern/extern-types-size_of_val.rs rename to src/test/ui/extern/extern-types-size_of_val.rs diff --git a/src/test/run-pass/extern/extern-types-thin-pointer.rs b/src/test/ui/extern/extern-types-thin-pointer.rs similarity index 100% rename from src/test/run-pass/extern/extern-types-thin-pointer.rs rename to src/test/ui/extern/extern-types-thin-pointer.rs diff --git a/src/test/run-pass/extern/extern-types-trait-impl.rs b/src/test/ui/extern/extern-types-trait-impl.rs similarity index 100% rename from src/test/run-pass/extern/extern-types-trait-impl.rs rename to src/test/ui/extern/extern-types-trait-impl.rs diff --git a/src/test/run-pass/extern/extern-vectorcall.rs b/src/test/ui/extern/extern-vectorcall.rs similarity index 100% rename from src/test/run-pass/extern/extern-vectorcall.rs rename to src/test/ui/extern/extern-vectorcall.rs diff --git a/src/test/run-pass/extern/extern_fat_drop.rs b/src/test/ui/extern/extern_fat_drop.rs similarity index 100% rename from src/test/run-pass/extern/extern_fat_drop.rs rename to src/test/ui/extern/extern_fat_drop.rs diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs index e17dda6556..4e89f7464d 100644 --- a/src/test/ui/extern/external-doc-error.rs +++ b/src/test/ui/extern/external-doc-error.rs @@ -4,7 +4,6 @@ #[doc(include = "not-a-file.md")] pub struct SomeStruct; //~^ ERROR couldn't read - //~| HELP external doc paths are relative to the crate root #[doc(include = "auxiliary/invalid-utf8.txt")] pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr index a3be3277de..b180cd66c5 100644 --- a/src/test/ui/extern/external-doc-error.stderr +++ b/src/test/ui/extern/external-doc-error.stderr @@ -3,35 +3,33 @@ error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2) | LL | #[doc(include = "not-a-file.md")] | ^^^^^^^^^^^^^^^ couldn't read file - | - = help: external doc paths are relative to the crate root error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file - --> $DIR/external-doc-error.rs:9:17 + --> $DIR/external-doc-error.rs:8:17 | LL | #[doc(include = "auxiliary/invalid-utf8.txt")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8 error: expected path to external documentation - --> $DIR/external-doc-error.rs:12:7 + --> $DIR/external-doc-error.rs:11:7 | LL | #[doc(include)] | ^^^^^^^ help: provide a file path with `=`: `include = ""` error: expected path to external documentation - --> $DIR/external-doc-error.rs:17:7 + --> $DIR/external-doc-error.rs:16:7 | LL | #[doc(include("../README.md"))] | ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"` error: expected path to external documentation - --> $DIR/external-doc-error.rs:22:7 + --> $DIR/external-doc-error.rs:21:7 | LL | #[doc(include = 123)] | ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = ""` error: expected path to external documentation - --> $DIR/external-doc-error.rs:27:7 + --> $DIR/external-doc-error.rs:26:7 | LL | #[doc(include(123))] | ^^^^^^^^^^^^ help: provide a file path with `=`: `include = ""` diff --git a/src/test/run-pass/extoption_env-not-defined.rs b/src/test/ui/extoption_env-not-defined.rs similarity index 86% rename from src/test/run-pass/extoption_env-not-defined.rs rename to src/test/ui/extoption_env-not-defined.rs index 7a2a2afad5..4014902ffe 100644 --- a/src/test/run-pass/extoption_env-not-defined.rs +++ b/src/test/ui/extoption_env-not-defined.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none()); } diff --git a/src/test/run-pass/fact.rs b/src/test/ui/fact.rs similarity index 96% rename from src/test/run-pass/fact.rs rename to src/test/ui/fact.rs index 0dd68c991a..c6c2f57e75 100644 --- a/src/test/run-pass/fact.rs +++ b/src/test/ui/fact.rs @@ -1,3 +1,5 @@ +// run-pass + fn f(x: isize) -> isize { // println!("in f:"); diff --git a/src/test/run-pass/fat-lto.rs b/src/test/ui/fat-lto.rs similarity index 88% rename from src/test/run-pass/fat-lto.rs rename to src/test/ui/fat-lto.rs index fb741200d3..c8d8095a26 100644 --- a/src/test/run-pass/fat-lto.rs +++ b/src/test/ui/fat-lto.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Clto=fat // no-prefer-dynamic diff --git a/src/test/run-pass/fat-ptr-cast.rs b/src/test/ui/fat-ptr-cast-rpass.rs similarity index 98% rename from src/test/run-pass/fat-ptr-cast.rs rename to src/test/ui/fat-ptr-cast-rpass.rs index 1943abe9e1..5f5e621d76 100644 --- a/src/test/run-pass/fat-ptr-cast.rs +++ b/src/test/ui/fat-ptr-cast-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(raw)] use std::mem; diff --git a/src/test/run-pass/fds-are-cloexec.rs b/src/test/ui/fds-are-cloexec.rs similarity index 99% rename from src/test/run-pass/fds-are-cloexec.rs rename to src/test/ui/fds-are-cloexec.rs index c4091f84af..2010b5b668 100644 --- a/src/test/run-pass/fds-are-cloexec.rs +++ b/src/test/ui/fds-are-cloexec.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-windows // ignore-android // ignore-cloudabi no processes diff --git a/src/test/ui/feature-gate-optimize_attribute.rs b/src/test/ui/feature-gate-optimize_attribute.rs index f252a3c153..7fc0fdde6f 100644 --- a/src/test/ui/feature-gate-optimize_attribute.rs +++ b/src/test/ui/feature-gate-optimize_attribute.rs @@ -1,17 +1,17 @@ #![crate_type="rlib"] -#![optimize(speed)] //~ ERROR #[optimize] attribute is an unstable feature +#![optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature -#[optimize(size)] //~ ERROR #[optimize] attribute is an unstable feature +#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature mod module { -#[optimize(size)] //~ ERROR #[optimize] attribute is an unstable feature +#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature fn size() {} -#[optimize(speed)] //~ ERROR #[optimize] attribute is an unstable feature +#[optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature fn speed() {} #[optimize(banana)] -//~^ ERROR #[optimize] attribute is an unstable feature +//~^ ERROR `#[optimize]` attribute is an unstable feature //~| ERROR E0722 fn not_known() {} diff --git a/src/test/ui/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gate-optimize_attribute.stderr index 5e7c0a708c..4ec512eaf3 100644 --- a/src/test/ui/feature-gate-optimize_attribute.stderr +++ b/src/test/ui/feature-gate-optimize_attribute.stderr @@ -1,47 +1,47 @@ -error[E0658]: #[optimize] attribute is an unstable feature +error[E0658]: `#[optimize]` attribute is an unstable feature --> $DIR/feature-gate-optimize_attribute.rs:7:1 | LL | #[optimize(size)] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54882 - = help: add #![feature(optimize_attribute)] to the crate attributes to enable + = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: #[optimize] attribute is an unstable feature +error[E0658]: `#[optimize]` attribute is an unstable feature --> $DIR/feature-gate-optimize_attribute.rs:10:1 | LL | #[optimize(speed)] | ^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54882 - = help: add #![feature(optimize_attribute)] to the crate attributes to enable + = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: #[optimize] attribute is an unstable feature +error[E0658]: `#[optimize]` attribute is an unstable feature --> $DIR/feature-gate-optimize_attribute.rs:13:1 | LL | #[optimize(banana)] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54882 - = help: add #![feature(optimize_attribute)] to the crate attributes to enable + = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: #[optimize] attribute is an unstable feature +error[E0658]: `#[optimize]` attribute is an unstable feature --> $DIR/feature-gate-optimize_attribute.rs:4:1 | LL | #[optimize(size)] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54882 - = help: add #![feature(optimize_attribute)] to the crate attributes to enable + = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: #[optimize] attribute is an unstable feature +error[E0658]: `#[optimize]` attribute is an unstable feature --> $DIR/feature-gate-optimize_attribute.rs:2:1 | LL | #![optimize(speed)] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54882 - = help: add #![feature(optimize_attribute)] to the crate attributes to enable + = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable error[E0722]: invalid argument --> $DIR/feature-gate-optimize_attribute.rs:13:12 diff --git a/src/test/ui/feature-gate/await-macro.rs b/src/test/ui/feature-gate/await-macro.rs deleted file mode 100644 index 291db9ba41..0000000000 --- a/src/test/ui/feature-gate/await-macro.rs +++ /dev/null @@ -1,12 +0,0 @@ -// gate-test-await_macro -// edition:2018 - -#![feature(async_await)] - -async fn bar() {} - -async fn foo() { - await!(bar()); //~ ERROR `await!()` macro syntax is unstable, and will soon be removed -} - -fn main() {} diff --git a/src/test/ui/feature-gate/await-macro.stderr b/src/test/ui/feature-gate/await-macro.stderr deleted file mode 100644 index 699a7a8886..0000000000 --- a/src/test/ui/feature-gate/await-macro.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: `await!()` macro syntax is unstable, and will soon be removed in favor of `.await` syntax. - --> $DIR/await-macro.rs:9:5 - | -LL | await!(bar()); - | ^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(await_macro)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate/feature-gate-c_variadic.stderr b/src/test/ui/feature-gate/feature-gate-c_variadic.stderr index 4367dee55a..a446b10548 100644 --- a/src/test/ui/feature-gate/feature-gate-c_variadic.stderr +++ b/src/test/ui/feature-gate/feature-gate-c_variadic.stderr @@ -5,7 +5,7 @@ LL | pub unsafe extern "C" fn test(_: i32, ap: ...) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44930 - = help: add #![feature(c_variadic)] to the crate attributes to enable + = help: add `#![feature(c_variadic)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs b/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs new file mode 100644 index 0000000000..308f68bd52 --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs @@ -0,0 +1,4 @@ +#[cfg(doctest)] //~ ERROR +pub struct SomeStruct; + +fn main() {} diff --git a/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr b/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr new file mode 100644 index 0000000000..5ab45e01e5 --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr @@ -0,0 +1,12 @@ +error[E0658]: `cfg(doctest)` is experimental and subject to change + --> $DIR/feature-gate-cfg_doctest.rs:1:7 + | +LL | #[cfg(doctest)] + | ^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62210 + = help: add `#![feature(cfg_doctest)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr index 4a653265f1..059559dd92 100644 --- a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr +++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr @@ -1,7 +1,7 @@ error[E0658]: kind="static-nobundle" is feature gated | = note: for more information, see https://github.com/rust-lang/rust/issues/37403 - = help: add #![feature(static_nobundle)] to the crate attributes to enable + = help: add `#![feature(static_nobundle)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs b/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs index 2d8868995f..31eee88d1f 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs @@ -1,17 +1,10 @@ -// error-pattern: `main` function not found - -// At time of authorship, a crate-level #![bench] with no `--test` -// will cause compilation to error unconditionally with "main function -// not found" (despite having one), similar to #[bench]. -// -// (The non-crate level cases are in -// issue-43106-gating-of-builtin-attrs.rs.) - +// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs. // See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is // handled in "weird places" when `--test` is passed. #![feature(custom_inner_attributes)] #![bench = "4100"] +//~^ ERROR cannot determine resolution for the attribute macro `bench` -fn main() { } +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index 503ef020d9..d0305c5160 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -1,7 +1,10 @@ -error[E0601]: `main` function not found in crate `issue_43106_gating_of_bench` +error: cannot determine resolution for the attribute macro `bench` + --> $DIR/issue-43106-gating-of-bench.rs:7:4 | - = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-bench.rs` +LL | #![bench = "4100"] + | ^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 3187b4cae5..6d51bb3f8a 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -32,6 +32,7 @@ // check-pass +#![feature(test)] #![warn(unused_attributes, unknown_lints)] // UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index e03b7124ac..864df35a79 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1,1185 +1,1185 @@ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:39:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:9 | LL | #![warn(x5400)] | ^^^^^ | note: lint level defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:35:28 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:28 | LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:10 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:41:10 | LL | #![allow(x5300)] | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:41:11 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:42:11 | LL | #![forbid(x5200)] | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:42:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:43:9 | LL | #![deny(x5100)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:100:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:101:8 | LL | #[warn(x5400)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:103:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:104:25 | LL | mod inner { #![warn(x5400)] } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:106:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:107:12 | LL | #[warn(x5400)] fn f() { } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:109:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:110:12 | LL | #[warn(x5400)] struct S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:113:12 | LL | #[warn(x5400)] type T = S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:12 | LL | #[warn(x5400)] impl S { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:9 | LL | #[allow(x5300)] | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:26 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:26 | LL | mod inner { #![allow(x5300)] } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:13 | LL | #[allow(x5300)] fn f() { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:129:13 | LL | #[allow(x5300)] struct S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:132:13 | LL | #[allow(x5300)] type T = S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:13 | LL | #[allow(x5300)] impl S { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:10 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:10 | LL | #[forbid(x5200)] | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:27 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:27 | LL | mod inner { #![forbid(x5200)] } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:14 | LL | #[forbid(x5200)] fn f() { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:148:14 | LL | #[forbid(x5200)] struct S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:151:14 | LL | #[forbid(x5200)] type T = S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:14 | LL | #[forbid(x5200)] impl S { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:8 | LL | #[deny(x5100)] | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:25 | LL | mod inner { #![deny(x5100)] } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:12 | LL | #[deny(x5100)] fn f() { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:167:12 | LL | #[deny(x5100)] struct S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:170:12 | LL | #[deny(x5100)] type T = S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:172:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:12 | LL | #[deny(x5100)] impl S { } | ^^^^^ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:456:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:17 | LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, #[macro_use] mod ... + = help: consider an outer attribute, `#[macro_use]` mod ... warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:89:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:12 | LL | #![feature(rust1)] | ^^^^^ | - = note: #[warn(stable_features)] on by default + = note: `#[warn(stable_features)]` on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:181:5 | LL | #[macro_use] fn f() { } | ^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:35:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 | LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:184:5 | LL | #[macro_use] struct S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:186:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:187:5 | LL | #[macro_use] type T = S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:189:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:190:5 | LL | #[macro_use] impl S { } | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:196:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:197:17 | LL | mod inner { #![macro_export] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:199:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:200:5 | LL | #[macro_export] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:202:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:203:5 | LL | #[macro_export] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:206:5 | LL | #[macro_export] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:208:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:209:5 | LL | #[macro_export] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:193:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:1 | LL | #[macro_export] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:215:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:17 | LL | mod inner { #![plugin_registrar] } | ^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:5 | LL | #[plugin_registrar] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:5 | LL | #[plugin_registrar] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:5 | LL | #[plugin_registrar] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:1 | LL | #[plugin_registrar] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:233:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:17 | LL | mod inner { #![main] } | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:239:5 | LL | #[main] struct S; | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:242:5 | LL | #[main] type T = S; | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:5 | LL | #[main] impl S { } | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:230:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:231:1 | LL | #[main] | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:251:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:252:17 | LL | mod inner { #![start] } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:5 | LL | #[start] struct S; | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:259:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:5 | LL | #[start] type T = S; | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:5 | LL | #[start] impl S { } | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:248:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:249:1 | LL | #[start] | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:315:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:5 | LL | #[path = "3800"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:319:5 | LL | #[path = "3800"] struct S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:322:5 | LL | #[path = "3800"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:325:5 | LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:331:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:17 | LL | mod inner { #![automatically_derived] } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:334:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5 | LL | #[automatically_derived] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:337:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:5 | LL | #[automatically_derived] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:340:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5 | LL | #[automatically_derived] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:343:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5 | LL | #[automatically_derived] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:329:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:363:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:17 | LL | mod inner { #![no_link] } | ^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:366:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5 | LL | #[no_link] fn f() { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:369:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5 | LL | #[no_link] struct S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:372:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5 | LL | #[no_link]type T = S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:375:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5 | LL | #[no_link] impl S { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:1 | LL | #[no_link] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:382:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:17 | LL | mod inner { #![should_panic] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:385:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5 | LL | #[should_panic] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:388:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:5 | LL | #[should_panic] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:391:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:5 | LL | #[should_panic] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:395:5 | LL | #[should_panic] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:1 | LL | #[should_panic] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:17 | LL | mod inner { #![ignore] } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:5 | LL | #[ignore] fn f() { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5 | LL | #[ignore] struct S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5 | LL | #[ignore] type T = S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:413:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5 | LL | #[ignore] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:1 | LL | #[ignore] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:17 | LL | mod inner { #![no_implicit_prelude] } | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:5 | LL | #[no_implicit_prelude] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5 | LL | #[no_implicit_prelude] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5 | LL | #[no_implicit_prelude] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5 | LL | #[no_implicit_prelude] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:1 | LL | #[no_implicit_prelude] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:439:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:440:17 | LL | mod inner { #![reexport_test_harness_main="2900"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:443:5 | LL | #[reexport_test_harness_main = "2900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:446:5 | LL | #[reexport_test_harness_main = "2900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:449:5 | LL | #[reexport_test_harness_main = "2900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:452:5 | LL | #[reexport_test_harness_main = "2900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:437:1 | LL | #[reexport_test_harness_main = "2900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5 | LL | #[macro_escape] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5 | LL | #[macro_escape] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5 | LL | #[macro_escape] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:5 | LL | #[macro_escape] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:484:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:484:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5 | LL | #[no_std] struct S; | ^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5 | LL | #[no_std] struct S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:491:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5 | LL | #[no_std] 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:491:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5 | LL | #[no_std] type T = S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:495:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:495:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:1 | LL | #[no_std] | ^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:1 | LL | #[no_std] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:634:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635: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:634:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:638:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639: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:638:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:642:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:643: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:642:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:643:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:646:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647: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:646:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:650:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651: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:650:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:630:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:631: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:630:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:631:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660: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:659:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:664: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:663:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:664:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:668: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:667:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:668:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672: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:671:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676: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:675:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:655:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:656: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:655:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:656:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:689: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:688:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:689:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693: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:692:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697: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:696:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701: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:700:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:681: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:680:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:681:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:714:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:714:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5 | LL | #[no_main] 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:722:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:1 | LL | #[no_main] | ^^^^^^^^^^ -warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:1 | LL | #[no_main] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:749: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:748:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:749:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753: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:752:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757: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:756:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:760:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761: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:760:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765: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:764:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745: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:744:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:774: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:773:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:774:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:778: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:777:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:778:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:782: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:781:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:782:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786: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:785:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790: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:789:5 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:769:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770: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:769:1 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:44:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:1 | LL | #![macro_export] | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1 | LL | #![plugin_registrar] | ^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:48:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:49:1 | LL | #![main] | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:49:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:50:1 | LL | #![start] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:52:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:1 | LL | #![repr()] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:54:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1 | LL | #![path = "3800"] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:1 | LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:57:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:58:1 | LL | #![no_link] | ^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1 | LL | #![should_panic] | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:61:1 | LL | #![ignore] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1 | LL | #![proc_macro_derive()] | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr index ef89a887fd..4310a0c7d5 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr @@ -4,7 +4,7 @@ warning: attribute must be of the form `#[inline]` or `#[inline(always|never)]` LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ | - = note: #[warn(ill_formed_attribute_input)] on by default + = note: `#[warn(ill_formed_attribute_input)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs index 98ca3444c9..dab946bb81 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs @@ -3,7 +3,7 @@ // `#![macro_escape]` is incompatible with crate-level `#![macro_use]` // already present in issue-43106-gating-of-builtin-attrs. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![macro_escape] //~^ WARN macro_escape is a deprecated synonym for macro_use diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index 9fb9633d9a..8575c1660c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -4,5 +4,5 @@ warning: macro_escape is a deprecated synonym for macro_use LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, #[macro_use] mod ... + = help: consider an outer attribute, `#[macro_use]` mod ... diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.rs b/src/test/ui/feature-gate/issue-43106-gating-of-test.rs index c0c49d3530..d343746955 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.rs @@ -1,12 +1,6 @@ -// error-pattern: `main` function not found - -// At time of authorship, crate-level #[test] attribute with no -// `--test` signals unconditional error complaining of missing main -// function (despite having one), similar to #[bench]. -// -// (The non-crate level cases are in -// issue-43106-gating-of-builtin-attrs.rs.) +// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs. #![test = "4200"] +//~^ ERROR cannot determine resolution for the attribute macro `test` -fn main() { } +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index 2ab35be43c..a7d3a1e168 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -1,7 +1,10 @@ -error[E0601]: `main` function not found in crate `issue_43106_gating_of_test` +error: cannot determine resolution for the attribute macro `test` + --> $DIR/issue-43106-gating-of-test.rs:3:4 | - = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-test.rs` +LL | #![test = "4200"] + | ^^^^ + | + = note: import resolution is stuck, try simplifying macro imports error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr b/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr index 83775322a2..314238a34d 100644 --- a/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr +++ b/src/test/ui/feature-gate/issue-49983-see-issue-0.stderr @@ -1,10 +1,10 @@ -error[E0658]: use of unstable library feature 'ptr_internals': use NonNull instead and consider PhantomData (if you also use #[may_dangle]), Send, and/or Sync +error[E0658]: use of unstable library feature 'ptr_internals': use `NonNull` instead and consider `PhantomData` (if you also use `#[may_dangle]`), `Send`, and/or `Sync` --> $DIR/issue-49983-see-issue-0.rs:4:30 | LL | #[allow(unused_imports)] use core::ptr::Unique; | ^^^^^^^^^^^^^^^^^ | - = help: add #![feature(ptr_internals)] to the crate attributes to enable + = help: add `#![feature(ptr_internals)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gate/rustc-private.rs b/src/test/ui/feature-gate/rustc-private.rs new file mode 100644 index 0000000000..7b8944bb0a --- /dev/null +++ b/src/test/ui/feature-gate/rustc-private.rs @@ -0,0 +1,5 @@ +// gate-test-rustc_private + +extern crate libc; //~ ERROR use of unstable library feature 'rustc_private' + +fn main() {} diff --git a/src/test/ui/feature-gate/rustc-private.stderr b/src/test/ui/feature-gate/rustc-private.stderr new file mode 100644 index 0000000000..be32071814 --- /dev/null +++ b/src/test/ui/feature-gate/rustc-private.stderr @@ -0,0 +1,12 @@ +error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? + --> $DIR/rustc-private.rs:3:1 + | +LL | extern crate libc; + | ^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/27812 + = help: add `#![feature(rustc_private)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gated-feature-in-macro-arg.stderr b/src/test/ui/feature-gated-feature-in-macro-arg.stderr index 5cbd1023b3..5ee05154c3 100644 --- a/src/test/ui/feature-gated-feature-in-macro-arg.stderr +++ b/src/test/ui/feature-gated-feature-in-macro-arg.stderr @@ -6,7 +6,7 @@ LL | | fn atomic_fence(); LL | | } | |_________^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/bench.rs b/src/test/ui/feature-gates/bench.rs new file mode 100644 index 0000000000..afe4dc7d54 --- /dev/null +++ b/src/test/ui/feature-gates/bench.rs @@ -0,0 +1,5 @@ +#[bench] //~ ERROR use of unstable library feature 'test' + //~| WARN this was previously accepted +fn bench() {} + +fn main() {} diff --git a/src/test/ui/feature-gates/bench.stderr b/src/test/ui/feature-gates/bench.stderr new file mode 100644 index 0000000000..b9e24e931d --- /dev/null +++ b/src/test/ui/feature-gates/bench.stderr @@ -0,0 +1,12 @@ +error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable + --> $DIR/bench.rs:1:3 + | +LL | #[bench] + | ^^^^^ + | + = note: `#[deny(soft_unstable)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #64266 + +error: aborting due to previous error + diff --git a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr index 0eb26ec829..0d2e355535 100644 --- a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr @@ -5,7 +5,7 @@ LL | extern "msp430-interrupt" fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr index e20ab0cb2f..88e0b8667b 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi.stderr @@ -4,7 +4,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" fn f1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:13:1 @@ -13,7 +13,7 @@ LL | extern "platform-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:14:1 @@ -21,7 +21,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn f3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:15:1 @@ -30,7 +30,7 @@ LL | extern "rust-call" fn f4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:16:1 @@ -39,7 +39,7 @@ LL | extern "msp430-interrupt" fn f5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:17:1 @@ -48,7 +48,7 @@ LL | extern "ptx-kernel" fn f6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:18:1 @@ -57,7 +57,7 @@ LL | extern "x86-interrupt" fn f7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:19:1 @@ -65,7 +65,7 @@ error[E0658]: thiscall is experimental and subject to change LL | extern "thiscall" fn f8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:20:1 @@ -74,7 +74,7 @@ LL | extern "amdgpu-kernel" fn f9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:24:5 @@ -82,7 +82,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:25:5 @@ -91,7 +91,7 @@ LL | extern "platform-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:26:5 @@ -99,7 +99,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn m3(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:27:5 @@ -108,7 +108,7 @@ LL | extern "rust-call" fn m4(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:28:5 @@ -117,7 +117,7 @@ LL | extern "msp430-interrupt" fn m5(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:29:5 @@ -126,7 +126,7 @@ LL | extern "ptx-kernel" fn m6(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:30:5 @@ -135,7 +135,7 @@ LL | extern "x86-interrupt" fn m7(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:31:5 @@ -143,7 +143,7 @@ error[E0658]: thiscall is experimental and subject to change LL | extern "thiscall" fn m8(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:32:5 @@ -152,7 +152,7 @@ LL | extern "amdgpu-kernel" fn m9(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:34:5 @@ -160,7 +160,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" fn dm1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:35:5 @@ -169,7 +169,7 @@ LL | extern "platform-intrinsic" fn dm2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:36:5 @@ -177,7 +177,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn dm3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:37:5 @@ -186,7 +186,7 @@ LL | extern "rust-call" fn dm4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:38:5 @@ -195,7 +195,7 @@ LL | extern "msp430-interrupt" fn dm5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:39:5 @@ -204,7 +204,7 @@ LL | extern "ptx-kernel" fn dm6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:40:5 @@ -213,7 +213,7 @@ LL | extern "x86-interrupt" fn dm7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:41:5 @@ -221,7 +221,7 @@ error[E0658]: thiscall is experimental and subject to change LL | extern "thiscall" fn dm8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:42:5 @@ -230,7 +230,7 @@ LL | extern "amdgpu-kernel" fn dm9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:49:5 @@ -238,7 +238,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:50:5 @@ -247,7 +247,7 @@ LL | extern "platform-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:51:5 @@ -255,7 +255,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn m3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:52:5 @@ -264,7 +264,7 @@ LL | extern "rust-call" fn m4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:53:5 @@ -273,7 +273,7 @@ LL | extern "msp430-interrupt" fn m5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:54:5 @@ -282,7 +282,7 @@ LL | extern "ptx-kernel" fn m6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:55:5 @@ -291,7 +291,7 @@ LL | extern "x86-interrupt" fn m7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:56:5 @@ -299,7 +299,7 @@ error[E0658]: thiscall is experimental and subject to change LL | extern "thiscall" fn m8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:57:5 @@ -308,7 +308,7 @@ LL | extern "amdgpu-kernel" fn m9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:62:5 @@ -316,7 +316,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:63:5 @@ -325,7 +325,7 @@ LL | extern "platform-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:64:5 @@ -333,7 +333,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" fn im3() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:65:5 @@ -342,7 +342,7 @@ LL | extern "rust-call" fn im4() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:66:5 @@ -351,7 +351,7 @@ LL | extern "msp430-interrupt" fn im5() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:67:5 @@ -360,7 +360,7 @@ LL | extern "ptx-kernel" fn im6() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:68:5 @@ -369,7 +369,7 @@ LL | extern "x86-interrupt" fn im7() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:69:5 @@ -377,7 +377,7 @@ error[E0658]: thiscall is experimental and subject to change LL | extern "thiscall" fn im8() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:70:5 @@ -386,7 +386,7 @@ LL | extern "amdgpu-kernel" fn im9() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:74:11 @@ -394,7 +394,7 @@ error[E0658]: intrinsics are subject to change LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:75:11 @@ -403,7 +403,7 @@ LL | type A2 = extern "platform-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:76:11 @@ -411,7 +411,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | type A3 = extern "vectorcall" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:77:11 @@ -420,7 +420,7 @@ LL | type A4 = extern "rust-call" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:78:11 @@ -429,7 +429,7 @@ LL | type A5 = extern "msp430-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:79:11 @@ -438,7 +438,7 @@ LL | type A6 = extern "ptx-kernel" fn (); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:80:11 @@ -447,7 +447,7 @@ LL | type A7 = extern "x86-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:81:11 @@ -455,7 +455,7 @@ error[E0658]: thiscall is experimental and subject to change LL | type A8 = extern "thiscall" fn(); | ^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:82:11 @@ -464,7 +464,7 @@ LL | type A9 = extern "amdgpu-kernel" fn(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:85:1 @@ -472,7 +472,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy --> $DIR/feature-gate-abi.rs:86:1 @@ -481,7 +481,7 @@ LL | extern "platform-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(platform_intrinsics)] to the crate attributes to enable + = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:87:1 @@ -489,7 +489,7 @@ error[E0658]: vectorcall is experimental and subject to change LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_vectorcall)] to the crate attributes to enable + = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-abi.rs:88:1 @@ -498,7 +498,7 @@ LL | extern "rust-call" {} | ^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:89:1 @@ -507,7 +507,7 @@ LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38487 - = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:90:1 @@ -516,7 +516,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/38788 - = help: add #![feature(abi_ptx)] to the crate attributes to enable + = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:91:1 @@ -525,7 +525,7 @@ LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/40180 - = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable + = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:92:1 @@ -533,7 +533,7 @@ error[E0658]: thiscall is experimental and subject to change LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(abi_thiscall)] to the crate attributes to enable + = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change --> $DIR/feature-gate-abi.rs:93:1 @@ -542,7 +542,7 @@ LL | extern "amdgpu-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51575 - = help: add #![feature(abi_amdgpu_kernel)] to the crate attributes to enable + = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error: aborting due to 63 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr index fb32ebb188..4954a7d1f7 100644 --- a/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr @@ -6,7 +6,7 @@ LL | | LL | | } | |_^ | - = help: add #![feature(abi_unadjusted)] to the crate attributes to enable + = help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs index df7c3ad6b3..17b4f775ad 100644 --- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs +++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs @@ -5,7 +5,7 @@ use core::alloc::Layout; -#[alloc_error_handler] //~ ERROR #[alloc_error_handler] is an unstable feature +#[alloc_error_handler] //~ ERROR `#[alloc_error_handler]` is an unstable feature fn oom(info: Layout) -> ! { loop {} } diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr index cb01b5caf8..d18cc09ffe 100644 --- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr +++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[alloc_error_handler] is an unstable feature +error[E0658]: `#[alloc_error_handler]` is an unstable feature --> $DIR/feature-gate-alloc-error-handler.rs:8:1 | LL | #[alloc_error_handler] | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51540 - = help: add #![feature(alloc_error_handler)] to the crate attributes to enable + = help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allocator_internals.stderr b/src/test/ui/feature-gates/feature-gate-allocator_internals.stderr index c41dca0ec4..6e276f7bcc 100644 --- a/src/test/ui/feature-gates/feature-gate-allocator_internals.stderr +++ b/src/test/ui/feature-gates/feature-gate-allocator_internals.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[default_lib_allocator]` attribute is an experimental featur LL | #![default_lib_allocator] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(allocator_internals)] to the crate attributes to enable + = help: add `#![feature(allocator_internals)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr b/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr index 27324d703a..72f5642e72 100644 --- a/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.stderr @@ -7,7 +7,7 @@ LL | #[allow_internal_unsafe] LL | bar!(); | ------- in this macro invocation | - = help: add #![feature(allow_internal_unsafe)] to the crate attributes to enable + = help: add `#![feature(allow_internal_unsafe)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr index 76afd217b8..7100594336 100644 --- a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.stderr @@ -7,7 +7,7 @@ LL | #[allow_internal_unstable()] LL | bar!(); | ------- in this macro invocation | - = help: add #![feature(allow_internal_unstable)] to the crate attributes to enable + = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr index d512e56d0a..a1acfd5537 100644 --- a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr @@ -4,7 +4,7 @@ error[E0658]: allow_internal_unstable side-steps feature gating and stability ch LL | #[allow_internal_unstable()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(allow_internal_unstable)] to the crate attributes to enable + = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable.stderr b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable.stderr index baba7f4bfb..3c1a4bfc7d 100644 --- a/src/test/ui/feature-gates/feature-gate-allow-internal-unstable.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow-internal-unstable.stderr @@ -4,7 +4,7 @@ error[E0658]: allow_internal_unstable side-steps feature gating and stability ch LL | #[allow_internal_unstable()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(allow_internal_unstable)] to the crate attributes to enable + = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr index af7c8de61d..37bf3a262a 100644 --- a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr @@ -5,7 +5,7 @@ LL | #[allow_fail] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/46488 - = help: add #![feature(allow_fail)] to the crate attributes to enable + = help: add `#![feature(allow_fail)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr b/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr index 8d061a9567..a70bf1f199 100644 --- a/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr +++ b/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr @@ -5,8 +5,8 @@ LL | fn foo(self: Ptr); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44874 - = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0658]: `Ptr` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/feature-gate-arbitrary-self-types.rs:22:18 @@ -15,8 +15,8 @@ LL | fn foo(self: Ptr) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44874 - = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0658]: `std::boxed::Box>` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/feature-gate-arbitrary-self-types.rs:26:18 @@ -25,8 +25,8 @@ LL | fn bar(self: Box>) {} | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44874 - = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr b/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr index eda2403e05..0f8863b871 100644 --- a/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr +++ b/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr @@ -5,8 +5,8 @@ LL | fn bar(self: *const Self); | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44874 - = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:4:18 @@ -15,8 +15,8 @@ LL | fn foo(self: *const Self) {} | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44874 - = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18 @@ -25,8 +25,8 @@ LL | fn bar(self: *const Self) {} | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44874 - = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    (P); diff --git a/src/test/ui/issues/issue-54062.rs b/src/test/ui/issues/issue-54062.rs new file mode 100644 index 0000000000..495b7343f2 --- /dev/null +++ b/src/test/ui/issues/issue-54062.rs @@ -0,0 +1,13 @@ +use std::sync::Mutex; + +struct Test { + comps: Mutex, +} + +fn main() {} + +fn testing(test: Test) { + let _ = test.comps.inner.lock().unwrap(); + //~^ ERROR: field `inner` of struct `std::sync::Mutex` is private + //~| ERROR: no method named `unwrap` found +} diff --git a/src/test/ui/issues/issue-54062.stderr b/src/test/ui/issues/issue-54062.stderr new file mode 100644 index 0000000000..082ac91edb --- /dev/null +++ b/src/test/ui/issues/issue-54062.stderr @@ -0,0 +1,16 @@ +error[E0616]: field `inner` of struct `std::sync::Mutex` is private + --> $DIR/issue-54062.rs:10:13 + | +LL | let _ = test.comps.inner.lock().unwrap(); + | ^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `unwrap` found for type `std::sys_common::mutex::MutexGuard<'_>` in the current scope + --> $DIR/issue-54062.rs:10:37 + | +LL | let _ = test.comps.inner.lock().unwrap(); + | ^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0599, E0616. +For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-54348.stderr b/src/test/ui/issues/issue-54348.stderr index e39a1cb20c..fa77bd6fd7 100644 --- a/src/test/ui/issues/issue-54348.stderr +++ b/src/test/ui/issues/issue-54348.stderr @@ -4,7 +4,7 @@ error: index out of bounds: the len is 1 but the index is 1 LL | [1][1.5 as usize]; | ^^^^^^^^^^^^^^^^^ | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: index out of bounds: the len is 1 but the index is 1 --> $DIR/issue-54348.rs:4:5 diff --git a/src/test/ui/issues/issue-54387.rs b/src/test/ui/issues/issue-54387.rs index ac1033add0..7aee500744 100644 --- a/src/test/ui/issues/issue-54387.rs +++ b/src/test/ui/issues/issue-54387.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct GstRc { _obj: *const (), diff --git a/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs b/src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs similarity index 98% rename from src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs rename to src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs index e7966b2978..412028bdcd 100644 --- a/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs +++ b/src/test/ui/issues/issue-54462-mutable-noalias-correctness.rs @@ -1,3 +1,4 @@ +// run-pass // // compile-flags: -Ccodegen-units=1 -O diff --git a/src/test/run-pass/issues/issue-54467.rs b/src/test/ui/issues/issue-54467.rs similarity index 98% rename from src/test/run-pass/issues/issue-54467.rs rename to src/test/ui/issues/issue-54467.rs index 52a9828b54..734bf2768c 100644 --- a/src/test/run-pass/issues/issue-54467.rs +++ b/src/test/ui/issues/issue-54467.rs @@ -1,3 +1,5 @@ +// run-pass + pub trait Stream { type Item; type Error; diff --git a/src/test/run-pass/issues/issue-54477-reduced-2.rs b/src/test/ui/issues/issue-54477-reduced-2.rs similarity index 98% rename from src/test/run-pass/issues/issue-54477-reduced-2.rs rename to src/test/ui/issues/issue-54477-reduced-2.rs index 28731d4b0d..199d69b454 100644 --- a/src/test/run-pass/issues/issue-54477-reduced-2.rs +++ b/src/test/ui/issues/issue-54477-reduced-2.rs @@ -1,3 +1,4 @@ +// run-pass // rust-lang/rust#54477: runtime bug in the VecDeque library that was // exposed by this test case, derived from test suite of crates.io // `collection` crate. diff --git a/src/test/ui/issues/issue-54521-1.rs b/src/test/ui/issues/issue-54521-1.rs index d6a14a6e11..9bda7635ef 100644 --- a/src/test/ui/issues/issue-54521-1.rs +++ b/src/test/ui/issues/issue-54521-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test checks that the `remove extra angle brackets` error doesn't happen for some // potential edge-cases.. diff --git a/src/test/run-pass/issues/issue-54696.rs b/src/test/ui/issues/issue-54696.rs similarity index 100% rename from src/test/run-pass/issues/issue-54696.rs rename to src/test/ui/issues/issue-54696.rs diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs index 8d3a4e72de..eca27819a4 100644 --- a/src/test/ui/issues/issue-54943-1.rs +++ b/src/test/ui/issues/issue-54943-1.rs @@ -1,7 +1,7 @@ // This test is a minimal version of an ICE in the dropck-eyepatch tests // found in the fix for #54943. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn foo(_t: T) { } diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs index 41ca7c1498..c32f85dbe1 100644 --- a/src/test/ui/issues/issue-54943-2.rs +++ b/src/test/ui/issues/issue-54943-2.rs @@ -2,7 +2,7 @@ // found in the fix for #54943. In particular, this test is in unreachable // code as the initial fix for this ICE only worked if the code was reachable. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn foo(_t: T) { } diff --git a/src/test/ui/issues/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs index 185077bd68..a9cc99c79d 100644 --- a/src/test/ui/issues/issue-54943-3.rs +++ b/src/test/ui/issues/issue-54943-3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // FIXME(#54943) This test targets the scenario where proving the WF requirements requires // knowing the value of the `_` type present in the user type annotation - unfortunately, figuring // out the value of that `_` requires type-checking the surrounding code, but that code is dead, diff --git a/src/test/ui/issues/issue-5500-1.rs b/src/test/ui/issues/issue-5500-1.rs index 56f5ce9901..edbbe33c66 100644 --- a/src/test/ui/issues/issue-5500-1.rs +++ b/src/test/ui/issues/issue-5500-1.rs @@ -2,7 +2,7 @@ // is OK because the test is here to check that the compiler doesn't ICE (cf. // #5500). -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct TrieMapIterator<'a> { node: &'a usize diff --git a/src/test/run-pass/issues/issue-5518.rs b/src/test/ui/issues/issue-5518.rs similarity index 100% rename from src/test/run-pass/issues/issue-5518.rs rename to src/test/ui/issues/issue-5518.rs diff --git a/src/test/run-pass/issues/issue-5521.rs b/src/test/ui/issues/issue-5521.rs similarity index 100% rename from src/test/run-pass/issues/issue-5521.rs rename to src/test/ui/issues/issue-5521.rs diff --git a/src/test/run-pass/issues/issue-5530.rs b/src/test/ui/issues/issue-5530.rs similarity index 100% rename from src/test/run-pass/issues/issue-5530.rs rename to src/test/ui/issues/issue-5530.rs diff --git a/src/test/run-pass/issues/issue-55376.rs b/src/test/ui/issues/issue-55376.rs similarity index 95% rename from src/test/run-pass/issues/issue-55376.rs rename to src/test/ui/issues/issue-55376.rs index fa92a85a44..4adff2b454 100644 --- a/src/test/run-pass/issues/issue-55376.rs +++ b/src/test/ui/issues/issue-55376.rs @@ -1,3 +1,4 @@ +// run-pass // Tests that paths in `pub(...)` don't fail HIR verification. #![allow(unused_imports)] diff --git a/src/test/run-pass/issues/issue-55380.rs b/src/test/ui/issues/issue-55380.rs similarity index 100% rename from src/test/run-pass/issues/issue-55380.rs rename to src/test/ui/issues/issue-55380.rs diff --git a/src/test/run-pass/issues/issue-5550.rs b/src/test/ui/issues/issue-5550.rs similarity index 100% rename from src/test/run-pass/issues/issue-5550.rs rename to src/test/ui/issues/issue-5550.rs diff --git a/src/test/ui/issues/issue-55511.rs b/src/test/ui/issues/issue-55511.rs index 4b9475ba62..055886bf36 100644 --- a/src/test/ui/issues/issue-55511.rs +++ b/src/test/ui/issues/issue-55511.rs @@ -1,5 +1,5 @@ +#![warn(indirect_structural_match)] use std::cell::Cell; - trait Foo<'a> { const C: Option>; } @@ -14,6 +14,8 @@ fn main() { //~^ ERROR `a` does not live long enough [E0597] match b { <() as Foo<'static>>::C => { } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release _ => { } } } diff --git a/src/test/ui/issues/issue-55511.stderr b/src/test/ui/issues/issue-55511.stderr index bf3e58e8cd..e094256f5c 100644 --- a/src/test/ui/issues/issue-55511.stderr +++ b/src/test/ui/issues/issue-55511.stderr @@ -1,3 +1,17 @@ +warning: to use a constant of type `std::cell::Cell` in a pattern, `std::cell::Cell` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/issue-55511.rs:16:9 + | +LL | <() as Foo<'static>>::C => { } + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/issue-55511.rs:1:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + error[E0597]: `a` does not live long enough --> $DIR/issue-55511.rs:13:28 | diff --git a/src/test/run-pass/issues/issue-5554.rs b/src/test/ui/issues/issue-5554.rs similarity index 100% rename from src/test/run-pass/issues/issue-5554.rs rename to src/test/ui/issues/issue-5554.rs diff --git a/src/test/ui/issues/issue-5572.rs b/src/test/ui/issues/issue-5572.rs index e5963a7c43..db26b0372a 100644 --- a/src/test/ui/issues/issue-5572.rs +++ b/src/test/ui/issues/issue-5572.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs index 3a3eccdc33..32d87586cf 100644 --- a/src/test/ui/issues/issue-56128.rs +++ b/src/test/ui/issues/issue-56128.rs @@ -1,7 +1,7 @@ // Regression test for #56128. When this `pub(super) use...` gets // exploded in the HIR, we were not handling ids correctly. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod bar { pub(super) use self::baz::{x, y}; diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs index bd222b7fe9..6d6f23d284 100644 --- a/src/test/ui/issues/issue-56202.rs +++ b/src/test/ui/issues/issue-56202.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait FooTrait {} diff --git a/src/test/run-pass/issues/issue-56237.rs b/src/test/ui/issues/issue-56237.rs similarity index 92% rename from src/test/run-pass/issues/issue-56237.rs rename to src/test/ui/issues/issue-56237.rs index 87e10e8361..534b85acec 100644 --- a/src/test/run-pass/issues/issue-56237.rs +++ b/src/test/ui/issues/issue-56237.rs @@ -1,3 +1,5 @@ +// run-pass + use std::ops::Deref; fn foo

    (_value:

    ::Target) diff --git a/src/test/ui/issues/issue-56411-aux.rs b/src/test/ui/issues/issue-56411-aux.rs index bd689e913a..6880a8a98d 100644 --- a/src/test/ui/issues/issue-56411-aux.rs +++ b/src/test/ui/issues/issue-56411-aux.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct T {} diff --git a/src/test/run-pass/issues/issue-5666.rs b/src/test/ui/issues/issue-5666.rs similarity index 100% rename from src/test/run-pass/issues/issue-5666.rs rename to src/test/ui/issues/issue-5666.rs diff --git a/src/test/ui/issues/issue-56762.rs b/src/test/ui/issues/issue-56762.rs index 8bb81b907c..5ba5b9847d 100644 --- a/src/test/ui/issues/issue-56762.rs +++ b/src/test/ui/issues/issue-56762.rs @@ -17,6 +17,8 @@ impl TooBigArray { } static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); +//~^ ERROR the type `[u8; 2305843009213693951]` is too big for the current architecture static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; +//~^ ERROR the type `[u8; 2305843009213693951]` is too big for the current architecture fn main() { } diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr index 83d5dc62e6..69626d4bc7 100644 --- a/src/test/ui/issues/issue-56762.stderr +++ b/src/test/ui/issues/issue-56762.stderr @@ -1,4 +1,15 @@ -error: the type `[u8; 2305843009213693951]` is too big for the current architecture +error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture + --> $DIR/issue-56762.rs:19:1 + | +LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture + --> $DIR/issue-56762.rs:21:1 + | +LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/issues/issue-56806.stderr b/src/test/ui/issues/issue-56806.stderr index 96979b9dc1..fae6a26720 100644 --- a/src/test/ui/issues/issue-56806.stderr +++ b/src/test/ui/issues/issue-56806.stderr @@ -5,7 +5,7 @@ LL | fn dyn_instead_of_self(self: Box); | ^^^^^^^^^^^^^^ | = note: type must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-56870.rs b/src/test/ui/issues/issue-56870.rs new file mode 100644 index 0000000000..137a0ede0b --- /dev/null +++ b/src/test/ui/issues/issue-56870.rs @@ -0,0 +1,38 @@ +// build-pass +// Regression test for #56870: Internal compiler error (traits & associated consts) + +use std::fmt::Debug; + +pub trait Foo { + const FOO: *const u8; +} + +impl Foo for dyn Debug { + const FOO: *const u8 = ::fmt as *const u8; +} + +pub trait Bar { + const BAR: *const u8; +} + +pub trait Baz { + type Data: Debug; +} + +pub struct BarStruct(S); + +impl Bar for BarStruct { + const BAR: *const u8 = ::Data>>::FOO; +} + +struct AnotherStruct; +#[derive(Debug)] +struct SomeStruct; + +impl Baz for AnotherStruct { + type Data = SomeStruct; +} + +fn main() { + let _x = as Bar>::BAR; +} diff --git a/src/test/run-pass/issues/issue-5688.rs b/src/test/ui/issues/issue-5688.rs similarity index 100% rename from src/test/run-pass/issues/issue-5688.rs rename to src/test/ui/issues/issue-5688.rs diff --git a/src/test/run-pass/issues/issue-5708.rs b/src/test/ui/issues/issue-5708.rs similarity index 100% rename from src/test/run-pass/issues/issue-5708.rs rename to src/test/ui/issues/issue-5708.rs diff --git a/src/test/ui/issues/issue-57156.rs b/src/test/ui/issues/issue-57156.rs index f20b0f41c7..b6cd8c927a 100644 --- a/src/test/ui/issues/issue-57156.rs +++ b/src/test/ui/issues/issue-57156.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo { type Output; diff --git a/src/test/ui/issues/issue-57162.rs b/src/test/ui/issues/issue-57162.rs index abe0887e92..7ba2f9cea8 100644 --- a/src/test/ui/issues/issue-57162.rs +++ b/src/test/ui/issues/issue-57162.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo {} impl Foo for dyn Send {} diff --git a/src/test/run-pass/issues/issue-5718.rs b/src/test/ui/issues/issue-5718.rs similarity index 100% rename from src/test/run-pass/issues/issue-5718.rs rename to src/test/ui/issues/issue-5718.rs diff --git a/src/test/run-pass/issues/issue-5741.rs b/src/test/ui/issues/issue-5741.rs similarity index 100% rename from src/test/run-pass/issues/issue-5741.rs rename to src/test/ui/issues/issue-5741.rs diff --git a/src/test/ui/issues/issue-57410-1.rs b/src/test/ui/issues/issue-57410-1.rs index dab77bd660..c4247b3b11 100644 --- a/src/test/ui/issues/issue-57410-1.rs +++ b/src/test/ui/issues/issue-57410-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Originally from #53925. // Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`. diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/issues/issue-57410.rs index 0d697e5619..de7ae4b3c0 100644 --- a/src/test/ui/issues/issue-57410.rs +++ b/src/test/ui/issues/issue-57410.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`. diff --git a/src/test/ui/issues/issue-5754.rs b/src/test/ui/issues/issue-5754.rs index 78e8701335..a629729d39 100644 --- a/src/test/ui/issues/issue-5754.rs +++ b/src/test/ui/issues/issue-5754.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(improper_ctypes)] diff --git a/src/test/run-pass/issues/issue-5791.rs b/src/test/ui/issues/issue-5791.rs similarity index 100% rename from src/test/run-pass/issues/issue-5791.rs rename to src/test/ui/issues/issue-5791.rs diff --git a/src/test/run-pass/issues/issue-58212.rs b/src/test/ui/issues/issue-58212.rs similarity index 86% rename from src/test/run-pass/issues/issue-58212.rs rename to src/test/ui/issues/issue-58212.rs index 7643763030..21dcdd56bf 100644 --- a/src/test/run-pass/issues/issue-58212.rs +++ b/src/test/ui/issues/issue-58212.rs @@ -1,9 +1,12 @@ +// run-pass + trait FromUnchecked { unsafe fn from_unchecked(); } impl FromUnchecked for [u8; 1] { unsafe fn from_unchecked() { + #[allow(deprecated)] let mut array: Self = std::mem::uninitialized(); let _ptr = &mut array as *mut [u8] as *mut u8; } diff --git a/src/test/ui/issues/issue-58375-monomorphize-default-impls.rs b/src/test/ui/issues/issue-58375-monomorphize-default-impls.rs new file mode 100644 index 0000000000..6da6f398df --- /dev/null +++ b/src/test/ui/issues/issue-58375-monomorphize-default-impls.rs @@ -0,0 +1,24 @@ +// Make sure that the mono-item collector does not crash when trying to +// instantiate a default impl for DecodeUtf16<::Item> +// See https://github.com/rust-lang/rust/issues/58375 + +// build-pass +// compile-flags:-C link-dead-code + +#![crate_type = "rlib"] + +pub struct DecodeUtf16(I); + +pub trait Arbitrary { + fn arbitrary() {} +} + +pub trait A { + type Item; +} + +impl A for u8 { + type Item = char; +} + +impl Arbitrary for DecodeUtf16<::Item> {} diff --git a/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs b/src/test/ui/issues/issue-58435-ice-with-assoc-const.rs similarity index 97% rename from src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs rename to src/test/ui/issues/issue-58435-ice-with-assoc-const.rs index 94e2b2563d..fac727d2d7 100644 --- a/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs +++ b/src/test/ui/issues/issue-58435-ice-with-assoc-const.rs @@ -1,3 +1,4 @@ +// run-pass // The const-evaluator was at one point ICE'ing while trying to // evaluate the body of `fn id` during the `s.id()` call in main. diff --git a/src/test/run-pass/issues/issue-58463.rs b/src/test/ui/issues/issue-58463.rs similarity index 100% rename from src/test/run-pass/issues/issue-58463.rs rename to src/test/ui/issues/issue-58463.rs diff --git a/src/test/ui/issues/issue-5884.rs b/src/test/ui/issues/issue-5884.rs index ad7067bb9b..acb3e19765 100644 --- a/src/test/ui/issues/issue-5884.rs +++ b/src/test/ui/issues/issue-5884.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-58856-2.rs b/src/test/ui/issues/issue-58856-2.rs index acc38e4c20..745f0300bd 100644 --- a/src/test/ui/issues/issue-58856-2.rs +++ b/src/test/ui/issues/issue-58856-2.rs @@ -9,6 +9,6 @@ impl Howness for () { Empty } } -//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, +//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, fn main() {} diff --git a/src/test/ui/issues/issue-58856-2.stderr b/src/test/ui/issues/issue-58856-2.stderr index b760fd6768..a83dd674a8 100644 --- a/src/test/ui/issues/issue-58856-2.stderr +++ b/src/test/ui/issues/issue-58856-2.stderr @@ -7,11 +7,11 @@ LL | fn how_are_you(&self -> Empty { | | help: `)` may belong here | unclosed delimiter -error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `)` +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `)` --> $DIR/issue-58856-2.rs:11:1 | LL | } - | - expected one of 11 possible tokens here + | - expected one of 10 possible tokens here LL | } | ^ unexpected token diff --git a/src/test/ui/issues/issue-5900.rs b/src/test/ui/issues/issue-5900.rs index 5ac7acc8e3..850e67db62 100644 --- a/src/test/ui/issues/issue-5900.rs +++ b/src/test/ui/issues/issue-5900.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-5917.rs b/src/test/ui/issues/issue-5917.rs similarity index 100% rename from src/test/run-pass/issues/issue-5917.rs rename to src/test/ui/issues/issue-5917.rs diff --git a/src/test/ui/issues/issue-5950.rs b/src/test/ui/issues/issue-5950.rs index 19e0cfc7f2..5c2250e25f 100644 --- a/src/test/ui/issues/issue-5950.rs +++ b/src/test/ui/issues/issue-5950.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-59508-1.stderr b/src/test/ui/issues/issue-59508-1.stderr index 8fb7d7c3c8..dd78c7c831 100644 --- a/src/test/ui/issues/issue-59508-1.stderr +++ b/src/test/ui/issues/issue-59508-1.stderr @@ -1,14 +1,16 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/issue-59508-1.rs:12:25 + | +LL | pub fn do_things() { + | ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>` + warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/issue-59508-1.rs:2:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ - -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-59508-1.rs:12:25 | -LL | pub fn do_things() { - | ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>` + = note: `#[warn(incomplete_features)]` on by default error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-5988.rs b/src/test/ui/issues/issue-5988.rs similarity index 100% rename from src/test/run-pass/issues/issue-5988.rs rename to src/test/ui/issues/issue-5988.rs diff --git a/src/test/run-pass/issues/issue-5997.rs b/src/test/ui/issues/issue-5997.rs similarity index 100% rename from src/test/run-pass/issues/issue-5997.rs rename to src/test/ui/issues/issue-5997.rs diff --git a/src/test/ui/issues/issue-60622.stderr b/src/test/ui/issues/issue-60622.stderr index 0c337c315f..da0ae1541b 100644 --- a/src/test/ui/issues/issue-60622.stderr +++ b/src/test/ui/issues/issue-60622.stderr @@ -12,7 +12,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(late_bound_lifetime_arguments)] implied by #[deny(warnings)] + = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs index fe4eaff742..dcf935c578 100644 --- a/src/test/ui/issues/issue-60662.rs +++ b/src/test/ui/issues/issue-60662.rs @@ -1,11 +1,11 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=hir -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] trait Animal { } fn main() { - pub existential type ServeFut: Animal; + pub type ServeFut = impl Animal; } diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout index 5acfdf9ed5..e2a88dec97 100644 --- a/src/test/ui/issues/issue-60662.stdout +++ b/src/test/ui/issues/issue-60662.stdout @@ -1,7 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=hir -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] #[prelude_import] use ::std::prelude::v1::*; #[macro_use] @@ -10,5 +10,5 @@ extern crate std; trait Animal { } fn main() { - pub existential type ServeFut : Animal; + pub type ServeFut = impl Animal; } diff --git a/src/test/run-pass/issues/issue-6117.rs b/src/test/ui/issues/issue-6117.rs similarity index 100% rename from src/test/run-pass/issues/issue-6117.rs rename to src/test/ui/issues/issue-6117.rs diff --git a/src/test/run-pass/issues/issue-6128.rs b/src/test/ui/issues/issue-6128.rs similarity index 100% rename from src/test/run-pass/issues/issue-6128.rs rename to src/test/ui/issues/issue-6128.rs diff --git a/src/test/run-pass/issues/issue-6130.rs b/src/test/ui/issues/issue-6130.rs similarity index 100% rename from src/test/run-pass/issues/issue-6130.rs rename to src/test/ui/issues/issue-6130.rs diff --git a/src/test/run-pass/issues/issue-6153.rs b/src/test/ui/issues/issue-6153.rs similarity index 100% rename from src/test/run-pass/issues/issue-6153.rs rename to src/test/ui/issues/issue-6153.rs diff --git a/src/test/run-pass/issues/issue-6157.rs b/src/test/ui/issues/issue-6157.rs similarity index 100% rename from src/test/run-pass/issues/issue-6157.rs rename to src/test/ui/issues/issue-6157.rs diff --git a/src/test/ui/issues/issue-61696.rs b/src/test/ui/issues/issue-61696.rs new file mode 100644 index 0000000000..dca52927fd --- /dev/null +++ b/src/test/ui/issues/issue-61696.rs @@ -0,0 +1,66 @@ +// run-pass + +pub enum Infallible {} + +// The check that the `bool` field of `V1` is encoding a "niche variant" +// (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect, +// causing valid `V1` values to be interpreted as other variants. +pub enum E1 { + V1 { f: bool }, + V2 { f: Infallible }, + V3, + V4, +} + +// Computing the discriminant used to be done using the niche type (here `u8`, +// from the `bool` field of `V1`), overflowing for variants with large enough +// indices (`V3` and `V4`), causing them to be interpreted as other variants. +pub enum E2 { + V1 { f: bool }, + + /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X), + _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X), + _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X), + _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X), + _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X), + _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X), + _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X), + _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X), + _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X), + _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X), + _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X), + _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X), + _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X), + _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X), + _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X), + _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X), + _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X), + _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X), + _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X), + _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X), + _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X), + _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X), + _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X), + _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X), + _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X), + _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X), + _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X), + _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X), + _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X), + _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X), + _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X), + _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X), + + V3, + V4, +} + +fn main() { + if let E1::V2 { .. } = (E1::V1 { f: true }) { + unreachable!() + } + + if let E2::V1 { .. } = E2::V3:: { + unreachable!() + } +} diff --git a/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs b/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs new file mode 100644 index 0000000000..8fc09c89f7 --- /dev/null +++ b/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs @@ -0,0 +1,11 @@ +// Issue 61711: A crate pub re-exporting `crate` was causing an +// infinite loop. + +// edition:2018 +// aux-build:xcrate-issue-61711-b.rs +// compile-flags:--extern xcrate_issue_61711_b + +// run-pass + +fn f(_: F) { } +fn main() { } diff --git a/src/test/run-pass/issues/issue-61894.rs b/src/test/ui/issues/issue-61894.rs similarity index 80% rename from src/test/run-pass/issues/issue-61894.rs rename to src/test/ui/issues/issue-61894.rs index 9ab969be46..c018ac73fb 100644 --- a/src/test/run-pass/issues/issue-61894.rs +++ b/src/test/ui/issues/issue-61894.rs @@ -1,6 +1,8 @@ +// run-pass + #![feature(core_intrinsics)] -use std::intrinsics::type_name; +use std::any::type_name; struct Bar(M); @@ -8,7 +10,7 @@ impl Bar { fn foo(&self) -> &'static str { fn f() {} fn type_name_of(_: T) -> &'static str { - unsafe { type_name::() } + type_name::() } type_name_of(f) } diff --git a/src/test/ui/issues/issue-62375.rs b/src/test/ui/issues/issue-62375.rs new file mode 100644 index 0000000000..a2c8fe551b --- /dev/null +++ b/src/test/ui/issues/issue-62375.rs @@ -0,0 +1,9 @@ +enum A { + Value(()) +} + +fn main() { + let a = A::Value(()); + a == A::Value; + //~^ ERROR binary operation `==` cannot be applied to type `A` +} diff --git a/src/test/ui/issues/issue-62375.stderr b/src/test/ui/issues/issue-62375.stderr new file mode 100644 index 0000000000..6db45630b9 --- /dev/null +++ b/src/test/ui/issues/issue-62375.stderr @@ -0,0 +1,13 @@ +error[E0369]: binary operation `==` cannot be applied to type `A` + --> $DIR/issue-62375.rs:7:7 + | +LL | a == A::Value; + | - ^^ -------- fn(()) -> A {A::Value} + | | + | A + | + = note: an implementation of `std::cmp::PartialEq` might be missing for `A` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issues/issue-62554.rs b/src/test/ui/issues/issue-62554.rs new file mode 100644 index 0000000000..3d50674e62 --- /dev/null +++ b/src/test/ui/issues/issue-62554.rs @@ -0,0 +1,5 @@ +fn main() {} + +fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { +//~^ ERROR expected `{`, found `macro_rules` +//~ ERROR this file contains an un-closed delimiter diff --git a/src/test/ui/issues/issue-62554.stderr b/src/test/ui/issues/issue-62554.stderr new file mode 100644 index 0000000000..9675d540e7 --- /dev/null +++ b/src/test/ui/issues/issue-62554.stderr @@ -0,0 +1,30 @@ +error: this file contains an un-closed delimiter + --> $DIR/issue-62554.rs:5:53 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | - - - - - un-closed delimiter + | | | | | + | | | | un-closed delimiter + | | | un-closed delimiter + | un-closed delimiter un-closed delimiter +LL | +LL | + | ^ + +error: expected `{`, found `macro_rules` + --> $DIR/issue-62554.rs:3:23 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | -- ^^^^^^^^^^^ expected `{` + | | + | this `if` statement has a condition, but no block +help: try placing this code inside a block + | +LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { +LL | +LL | +LL | } + | + +error: aborting due to 2 previous errors + diff --git a/src/test/run-pass/issues/issue-6318.rs b/src/test/ui/issues/issue-6318.rs similarity index 100% rename from src/test/run-pass/issues/issue-6318.rs rename to src/test/ui/issues/issue-6318.rs diff --git a/src/test/run-pass/issues/issue-6334.rs b/src/test/ui/issues/issue-6334.rs similarity index 100% rename from src/test/run-pass/issues/issue-6334.rs rename to src/test/ui/issues/issue-6334.rs diff --git a/src/test/ui/issues/issue-63364.rs b/src/test/ui/issues/issue-63364.rs new file mode 100644 index 0000000000..5223267a69 --- /dev/null +++ b/src/test/ui/issues/issue-63364.rs @@ -0,0 +1,10 @@ +fn part(_: u16) -> u32 { + 1 +} + +fn main() { + for n in 100_000.. { + //~^ ERROR: literal out of range for `u16` + let _ = part(n); + } +} diff --git a/src/test/ui/issues/issue-63364.stderr b/src/test/ui/issues/issue-63364.stderr new file mode 100644 index 0000000000..60ff318f35 --- /dev/null +++ b/src/test/ui/issues/issue-63364.stderr @@ -0,0 +1,10 @@ +error: literal out of range for `u16` + --> $DIR/issue-63364.rs:6:14 + | +LL | for n in 100_000.. { + | ^^^^^^^ + | + = note: `#[deny(overflowing_literals)]` on by default + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-6341.rs b/src/test/ui/issues/issue-6341.rs index 2b23ccd258..2fb0fee60b 100644 --- a/src/test/ui/issues/issue-6341.rs +++ b/src/test/ui/issues/issue-6341.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #[derive(PartialEq)] diff --git a/src/test/run-pass/issues/issue-6344-let.rs b/src/test/ui/issues/issue-6344-let.rs similarity index 100% rename from src/test/run-pass/issues/issue-6344-let.rs rename to src/test/ui/issues/issue-6344-let.rs diff --git a/src/test/run-pass/issues/issue-6344-match.rs b/src/test/ui/issues/issue-6344-match.rs similarity index 100% rename from src/test/run-pass/issues/issue-6344-match.rs rename to src/test/ui/issues/issue-6344-match.rs diff --git a/src/test/run-pass/issues/issue-6449.rs b/src/test/ui/issues/issue-6449.rs similarity index 100% rename from src/test/run-pass/issues/issue-6449.rs rename to src/test/ui/issues/issue-6449.rs diff --git a/src/test/ui/issues/issue-6458-4.stderr b/src/test/ui/issues/issue-6458-4.stderr index 90b493e163..ecf729e103 100644 --- a/src/test/ui/issues/issue-6458-4.stderr +++ b/src/test/ui/issues/issue-6458-4.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn foo(b: bool) -> Result { | --- ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | Err("bar".to_string()); | - help: consider removing this semicolon | diff --git a/src/test/ui/issues/issue-6470.rs b/src/test/ui/issues/issue-6470.rs index 49a313f90d..305f46c6d4 100644 --- a/src/test/ui/issues/issue-6470.rs +++ b/src/test/ui/issues/issue-6470.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(improper_ctypes)] diff --git a/src/test/ui/issues/issue-6557.rs b/src/test/ui/issues/issue-6557.rs index aa091ca594..70b301d3d9 100644 --- a/src/test/ui/issues/issue-6557.rs +++ b/src/test/ui/issues/issue-6557.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-6892.rs b/src/test/ui/issues/issue-6892.rs similarity index 100% rename from src/test/run-pass/issues/issue-6892.rs rename to src/test/ui/issues/issue-6892.rs diff --git a/src/test/ui/issues/issue-6898.rs b/src/test/ui/issues/issue-6898.rs index 608c0c8071..6bf20d71d1 100644 --- a/src/test/ui/issues/issue-6898.rs +++ b/src/test/ui/issues/issue-6898.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 use std::mem; diff --git a/src/test/run-pass/issues/issue-6919.rs b/src/test/ui/issues/issue-6919.rs similarity index 100% rename from src/test/run-pass/issues/issue-6919.rs rename to src/test/ui/issues/issue-6919.rs diff --git a/src/test/ui/issues/issue-6991.rs b/src/test/ui/issues/issue-6991.rs index e835edea11..aae67637f2 100644 --- a/src/test/ui/issues/issue-6991.rs +++ b/src/test/ui/issues/issue-6991.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/run-pass/issues/issue-7012.rs b/src/test/ui/issues/issue-7012.rs similarity index 100% rename from src/test/run-pass/issues/issue-7012.rs rename to src/test/ui/issues/issue-7012.rs diff --git a/src/test/run-pass/issues/issue-7178.rs b/src/test/ui/issues/issue-7178.rs similarity index 100% rename from src/test/run-pass/issues/issue-7178.rs rename to src/test/ui/issues/issue-7178.rs diff --git a/src/test/run-pass/issues/issue-7222.rs b/src/test/ui/issues/issue-7222.rs similarity index 100% rename from src/test/run-pass/issues/issue-7222.rs rename to src/test/ui/issues/issue-7222.rs diff --git a/src/test/ui/issues/issue-7268.rs b/src/test/ui/issues/issue-7268.rs index 0b94fabf38..69901e9789 100644 --- a/src/test/ui/issues/issue-7268.rs +++ b/src/test/ui/issues/issue-7268.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-7344.rs b/src/test/ui/issues/issue-7344.rs similarity index 100% rename from src/test/run-pass/issues/issue-7344.rs rename to src/test/ui/issues/issue-7344.rs diff --git a/src/test/run-pass/issues/issue-7519-match-unit-in-arg.rs b/src/test/ui/issues/issue-7519-match-unit-in-arg.rs similarity index 100% rename from src/test/run-pass/issues/issue-7519-match-unit-in-arg.rs rename to src/test/ui/issues/issue-7519-match-unit-in-arg.rs diff --git a/src/test/run-pass/issues/issue-7563.rs b/src/test/ui/issues/issue-7563.rs similarity index 100% rename from src/test/run-pass/issues/issue-7563.rs rename to src/test/ui/issues/issue-7563.rs diff --git a/src/test/run-pass/issues/issue-7575.rs b/src/test/ui/issues/issue-7575.rs similarity index 100% rename from src/test/run-pass/issues/issue-7575.rs rename to src/test/ui/issues/issue-7575.rs diff --git a/src/test/ui/issues/issue-7607-2.rs b/src/test/ui/issues/issue-7607-2.rs index 8b5c8505d3..e336e0b47b 100644 --- a/src/test/ui/issues/issue-7607-2.rs +++ b/src/test/ui/issues/issue-7607-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-7660.rs b/src/test/ui/issues/issue-7660.rs similarity index 100% rename from src/test/run-pass/issues/issue-7660.rs rename to src/test/ui/issues/issue-7660.rs diff --git a/src/test/run-pass/issues/issue-7663.rs b/src/test/ui/issues/issue-7663.rs similarity index 100% rename from src/test/run-pass/issues/issue-7663.rs rename to src/test/ui/issues/issue-7663.rs diff --git a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs index 619256c787..9570386730 100644 --- a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs similarity index 95% rename from src/test/run-pass/issues/issue-7784.rs rename to src/test/ui/issues/issue-7784.rs index b75e547079..5b70bd6e5f 100644 --- a/src/test/run-pass/issues/issue-7784.rs +++ b/src/test/ui/issues/issue-7784.rs @@ -24,7 +24,7 @@ fn main() { assert_eq!(d, "baz"); let out = bar("baz", "foo"); - let [a, xs.., d] = out; + let [a, xs @ .., d] = out; assert_eq!(a, "baz"); assert_eq!(xs, ["foo", "foo"]); assert_eq!(d, "baz"); diff --git a/src/test/run-pass/issues/issue-7899.rs b/src/test/ui/issues/issue-7899.rs similarity index 100% rename from src/test/run-pass/issues/issue-7899.rs rename to src/test/ui/issues/issue-7899.rs diff --git a/src/test/run-pass/issues/issue-7911.rs b/src/test/ui/issues/issue-7911.rs similarity index 100% rename from src/test/run-pass/issues/issue-7911.rs rename to src/test/ui/issues/issue-7911.rs diff --git a/src/test/run-pass/issues/issue-8044.rs b/src/test/ui/issues/issue-8044.rs similarity index 100% rename from src/test/run-pass/issues/issue-8044.rs rename to src/test/ui/issues/issue-8044.rs diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs index e4dafc073a..653d002fa6 100644 --- a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs +++ b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-8248.rs b/src/test/ui/issues/issue-8248.rs similarity index 100% rename from src/test/run-pass/issues/issue-8248.rs rename to src/test/ui/issues/issue-8248.rs diff --git a/src/test/run-pass/issues/issue-8249.rs b/src/test/ui/issues/issue-8249.rs similarity index 100% rename from src/test/run-pass/issues/issue-8249.rs rename to src/test/ui/issues/issue-8249.rs diff --git a/src/test/run-pass/issues/issue-8259.rs b/src/test/ui/issues/issue-8259.rs similarity index 100% rename from src/test/run-pass/issues/issue-8259.rs rename to src/test/ui/issues/issue-8259.rs diff --git a/src/test/run-pass/issues/issue-8351-1.rs b/src/test/ui/issues/issue-8351-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-8351-1.rs rename to src/test/ui/issues/issue-8351-1.rs diff --git a/src/test/run-pass/issues/issue-8351-2.rs b/src/test/ui/issues/issue-8351-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-8351-2.rs rename to src/test/ui/issues/issue-8351-2.rs diff --git a/src/test/run-pass/issues/issue-8391.rs b/src/test/ui/issues/issue-8391.rs similarity index 100% rename from src/test/run-pass/issues/issue-8391.rs rename to src/test/ui/issues/issue-8391.rs diff --git a/src/test/ui/issues/issue-8398.rs b/src/test/ui/issues/issue-8398.rs index a65c667b08..5fe88854b3 100644 --- a/src/test/ui/issues/issue-8398.rs +++ b/src/test/ui/issues/issue-8398.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-8401.rs b/src/test/ui/issues/issue-8401.rs similarity index 100% rename from src/test/run-pass/issues/issue-8401.rs rename to src/test/ui/issues/issue-8401.rs diff --git a/src/test/run-pass/issues/issue-8460.rs b/src/test/ui/issues/issue-8460.rs similarity index 100% rename from src/test/run-pass/issues/issue-8460.rs rename to src/test/ui/issues/issue-8460.rs diff --git a/src/test/run-pass/issues/issue-8498.rs b/src/test/ui/issues/issue-8498.rs similarity index 100% rename from src/test/run-pass/issues/issue-8498.rs rename to src/test/ui/issues/issue-8498.rs diff --git a/src/test/run-pass/issues/issue-8506.rs b/src/test/ui/issues/issue-8506.rs similarity index 100% rename from src/test/run-pass/issues/issue-8506.rs rename to src/test/ui/issues/issue-8506.rs diff --git a/src/test/ui/issues/issue-8521.rs b/src/test/ui/issues/issue-8521.rs index 7007c8a3a9..02a0e14d55 100644 --- a/src/test/ui/issues/issue-8521.rs +++ b/src/test/ui/issues/issue-8521.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo1 {} trait A {} diff --git a/src/test/ui/issues/issue-8578.rs b/src/test/ui/issues/issue-8578.rs index 4cc2123479..6ffb721372 100644 --- a/src/test/ui/issues/issue-8578.rs +++ b/src/test/ui/issues/issue-8578.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] diff --git a/src/test/run-pass/issues/issue-868.rs b/src/test/ui/issues/issue-868.rs similarity index 100% rename from src/test/run-pass/issues/issue-868.rs rename to src/test/ui/issues/issue-868.rs diff --git a/src/test/run-pass/issues/issue-8709.rs b/src/test/ui/issues/issue-8709.rs similarity index 100% rename from src/test/run-pass/issues/issue-8709.rs rename to src/test/ui/issues/issue-8709.rs diff --git a/src/test/ui/issues/issue-8727.stderr b/src/test/ui/issues/issue-8727.stderr index a7d020cb67..df01f42ce2 100644 --- a/src/test/ui/issues/issue-8727.stderr +++ b/src/test/ui/issues/issue-8727.stderr @@ -6,7 +6,7 @@ LL | fn generic() { LL | generic::>(); | ---------------------- recursive call site | - = note: #[warn(unconditional_recursion)] on by default + = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose error: reached the recursion limit while instantiating `generic::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` diff --git a/src/test/run-pass/issues/issue-8783.rs b/src/test/ui/issues/issue-8783.rs similarity index 100% rename from src/test/run-pass/issues/issue-8783.rs rename to src/test/ui/issues/issue-8783.rs diff --git a/src/test/run-pass/issues/issue-8827.rs b/src/test/ui/issues/issue-8827.rs similarity index 100% rename from src/test/run-pass/issues/issue-8827.rs rename to src/test/ui/issues/issue-8827.rs diff --git a/src/test/run-pass/issues/issue-8851.rs b/src/test/ui/issues/issue-8851.rs similarity index 100% rename from src/test/run-pass/issues/issue-8851.rs rename to src/test/ui/issues/issue-8851.rs diff --git a/src/test/run-pass/issues/issue-8860.rs b/src/test/ui/issues/issue-8860.rs similarity index 100% rename from src/test/run-pass/issues/issue-8860.rs rename to src/test/ui/issues/issue-8860.rs diff --git a/src/test/run-pass/issues/issue-8898.rs b/src/test/ui/issues/issue-8898.rs similarity index 100% rename from src/test/run-pass/issues/issue-8898.rs rename to src/test/ui/issues/issue-8898.rs diff --git a/src/test/run-pass/issues/issue-9047.rs b/src/test/ui/issues/issue-9047.rs similarity index 100% rename from src/test/run-pass/issues/issue-9047.rs rename to src/test/ui/issues/issue-9047.rs diff --git a/src/test/ui/issues/issue-9110.rs b/src/test/ui/issues/issue-9110.rs index 30acd61a34..f3bab42ee1 100644 --- a/src/test/ui/issues/issue-9110.rs +++ b/src/test/ui/issues/issue-9110.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 #![allow(non_snake_case)] diff --git a/src/test/run-pass/issues/issue-9123.rs b/src/test/ui/issues/issue-9123.rs similarity index 100% rename from src/test/run-pass/issues/issue-9123.rs rename to src/test/ui/issues/issue-9123.rs diff --git a/src/test/run-pass/issues/issue-9129.rs b/src/test/ui/issues/issue-9129.rs similarity index 100% rename from src/test/run-pass/issues/issue-9129.rs rename to src/test/ui/issues/issue-9129.rs diff --git a/src/test/run-pass/issues/issue-9155.rs b/src/test/ui/issues/issue-9155.rs similarity index 100% rename from src/test/run-pass/issues/issue-9155.rs rename to src/test/ui/issues/issue-9155.rs diff --git a/src/test/run-pass/issues/issue-9188.rs b/src/test/ui/issues/issue-9188.rs similarity index 100% rename from src/test/run-pass/issues/issue-9188.rs rename to src/test/ui/issues/issue-9188.rs diff --git a/src/test/ui/issues/issue-9243.rs b/src/test/ui/issues/issue-9243.rs index e877dd6492..78237421c9 100644 --- a/src/test/ui/issues/issue-9243.rs +++ b/src/test/ui/issues/issue-9243.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for issue 9243 #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-9249.rs b/src/test/ui/issues/issue-9249.rs index e4e9c45971..b1f2bd7569 100644 --- a/src/test/ui/issues/issue-9249.rs +++ b/src/test/ui/issues/issue-9249.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-9259.rs b/src/test/ui/issues/issue-9259.rs similarity index 100% rename from src/test/run-pass/issues/issue-9259.rs rename to src/test/ui/issues/issue-9259.rs diff --git a/src/test/run-pass/issues/issue-9382.rs b/src/test/ui/issues/issue-9382.rs similarity index 100% rename from src/test/run-pass/issues/issue-9382.rs rename to src/test/ui/issues/issue-9382.rs diff --git a/src/test/run-pass/issues/issue-9394-inherited-trait-calls.rs b/src/test/ui/issues/issue-9394-inherited-trait-calls.rs similarity index 100% rename from src/test/run-pass/issues/issue-9394-inherited-trait-calls.rs rename to src/test/ui/issues/issue-9394-inherited-trait-calls.rs diff --git a/src/test/run-pass/issues/issue-9396.rs b/src/test/ui/issues/issue-9396.rs similarity index 100% rename from src/test/run-pass/issues/issue-9396.rs rename to src/test/ui/issues/issue-9396.rs diff --git a/src/test/run-pass/issues/issue-9446.rs b/src/test/ui/issues/issue-9446.rs similarity index 100% rename from src/test/run-pass/issues/issue-9446.rs rename to src/test/ui/issues/issue-9446.rs diff --git a/src/test/ui/issues/issue-9719.rs b/src/test/ui/issues/issue-9719.rs index 1e38ab9c6c..58eb32b111 100644 --- a/src/test/ui/issues/issue-9719.rs +++ b/src/test/ui/issues/issue-9719.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-9737.rs b/src/test/ui/issues/issue-9737.rs similarity index 100% rename from src/test/run-pass/issues/issue-9737.rs rename to src/test/ui/issues/issue-9737.rs diff --git a/src/test/run-pass/issues/issue-979.rs b/src/test/ui/issues/issue-979.rs similarity index 100% rename from src/test/run-pass/issues/issue-979.rs rename to src/test/ui/issues/issue-979.rs diff --git a/src/test/run-pass/issues/issue-9837.rs b/src/test/ui/issues/issue-9837.rs similarity index 100% rename from src/test/run-pass/issues/issue-9837.rs rename to src/test/ui/issues/issue-9837.rs diff --git a/src/test/run-pass/issues/issue-9906.rs b/src/test/ui/issues/issue-9906.rs similarity index 100% rename from src/test/run-pass/issues/issue-9906.rs rename to src/test/ui/issues/issue-9906.rs diff --git a/src/test/run-pass/issues/issue-9918.rs b/src/test/ui/issues/issue-9918.rs similarity index 100% rename from src/test/run-pass/issues/issue-9918.rs rename to src/test/ui/issues/issue-9918.rs diff --git a/src/test/run-pass/issues/issue-9942.rs b/src/test/ui/issues/issue-9942.rs similarity index 100% rename from src/test/run-pass/issues/issue-9942.rs rename to src/test/ui/issues/issue-9942.rs diff --git a/src/test/run-pass/issues/issue-9951.rs b/src/test/ui/issues/issue-9951.rs similarity index 100% rename from src/test/run-pass/issues/issue-9951.rs rename to src/test/ui/issues/issue-9951.rs diff --git a/src/test/run-pass/issues/issue-9968.rs b/src/test/ui/issues/issue-9968.rs similarity index 100% rename from src/test/run-pass/issues/issue-9968.rs rename to src/test/ui/issues/issue-9968.rs diff --git a/src/test/run-pass/istr.rs b/src/test/ui/istr.rs similarity index 98% rename from src/test/run-pass/istr.rs rename to src/test/ui/istr.rs index af11e49e56..dca6d40d59 100644 --- a/src/test/run-pass/istr.rs +++ b/src/test/ui/istr.rs @@ -1,3 +1,5 @@ +// run-pass + use std::string::String; fn test_stack_assign() { diff --git a/src/test/run-pass/item-name-overload.rs b/src/test/ui/item-name-overload.rs similarity index 91% rename from src/test/run-pass/item-name-overload.rs rename to src/test/ui/item-name-overload.rs index 58ef977919..c8a302a2c5 100644 --- a/src/test/run-pass/item-name-overload.rs +++ b/src/test/ui/item-name-overload.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] diff --git a/src/test/run-pass/iterators/into-iterator-type-inference-shift.rs b/src/test/ui/iterators/into-iterator-type-inference-shift.rs similarity index 100% rename from src/test/run-pass/iterators/into-iterator-type-inference-shift.rs rename to src/test/ui/iterators/into-iterator-type-inference-shift.rs diff --git a/src/test/run-pass/iterators/iter-cloned-type-inference.rs b/src/test/ui/iterators/iter-cloned-type-inference.rs similarity index 100% rename from src/test/run-pass/iterators/iter-cloned-type-inference.rs rename to src/test/ui/iterators/iter-cloned-type-inference.rs diff --git a/src/test/run-pass/iterators/iter-range.rs b/src/test/ui/iterators/iter-range.rs similarity index 100% rename from src/test/run-pass/iterators/iter-range.rs rename to src/test/ui/iterators/iter-range.rs diff --git a/src/test/run-pass/iterators/iter-step-overflow-debug.rs b/src/test/ui/iterators/iter-step-overflow-debug.rs similarity index 100% rename from src/test/run-pass/iterators/iter-step-overflow-debug.rs rename to src/test/ui/iterators/iter-step-overflow-debug.rs diff --git a/src/test/run-pass/iterators/iter-step-overflow-ndebug.rs b/src/test/ui/iterators/iter-step-overflow-ndebug.rs similarity index 100% rename from src/test/run-pass/iterators/iter-step-overflow-ndebug.rs rename to src/test/ui/iterators/iter-step-overflow-ndebug.rs diff --git a/src/test/run-pass/iterators/iter-sum-overflow-debug.rs b/src/test/ui/iterators/iter-sum-overflow-debug.rs similarity index 100% rename from src/test/run-pass/iterators/iter-sum-overflow-debug.rs rename to src/test/ui/iterators/iter-sum-overflow-debug.rs diff --git a/src/test/run-pass/iterators/iter-sum-overflow-ndebug.rs b/src/test/ui/iterators/iter-sum-overflow-ndebug.rs similarity index 100% rename from src/test/run-pass/iterators/iter-sum-overflow-ndebug.rs rename to src/test/ui/iterators/iter-sum-overflow-ndebug.rs diff --git a/src/test/run-pass/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs similarity index 100% rename from src/test/run-pass/iterators/iter-sum-overflow-overflow-checks.rs rename to src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs diff --git a/src/test/run-pass/iterators/iter-zip.rs b/src/test/ui/iterators/iter-zip.rs similarity index 100% rename from src/test/run-pass/iterators/iter-zip.rs rename to src/test/ui/iterators/iter-zip.rs diff --git a/src/test/ui/json-and-color.rs b/src/test/ui/json-and-color.rs new file mode 100644 index 0000000000..efc07a541b --- /dev/null +++ b/src/test/ui/json-and-color.rs @@ -0,0 +1,4 @@ +// build-fail +// compile-flags: --json=artifacts --error-format=json --color never + +fn main() {} diff --git a/src/test/ui/json-and-color.stderr b/src/test/ui/json-and-color.stderr new file mode 100644 index 0000000000..1cda6af090 --- /dev/null +++ b/src/test/ui/json-and-color.stderr @@ -0,0 +1,2 @@ +error: cannot specify the `--color` option with `--json` + diff --git a/src/test/ui/json-and-error-format.rs b/src/test/ui/json-and-error-format.rs new file mode 100644 index 0000000000..6b369307fa --- /dev/null +++ b/src/test/ui/json-and-error-format.rs @@ -0,0 +1,4 @@ +// build-fail +// compile-flags: --json=artifacts --error-format=short + +fn main() {} diff --git a/src/test/ui/json-and-error-format.stderr b/src/test/ui/json-and-error-format.stderr new file mode 100644 index 0000000000..80e0221376 --- /dev/null +++ b/src/test/ui/json-and-error-format.stderr @@ -0,0 +1,2 @@ +error: using `--json` requires also using `--error-format=json` + diff --git a/src/test/ui/json-invalid.rs b/src/test/ui/json-invalid.rs new file mode 100644 index 0000000000..a8c0c819a0 --- /dev/null +++ b/src/test/ui/json-invalid.rs @@ -0,0 +1,4 @@ +// build-fail +// compile-flags: --json=foo --error-format=json + +fn main() {} diff --git a/src/test/ui/json-invalid.stderr b/src/test/ui/json-invalid.stderr new file mode 100644 index 0000000000..18bc76ab7e --- /dev/null +++ b/src/test/ui/json-invalid.stderr @@ -0,0 +1,2 @@ +error: unknown `--json` option `foo` + diff --git a/src/test/ui/json-multiple.nll.stderr b/src/test/ui/json-multiple.nll.stderr new file mode 100644 index 0000000000..c2cb8bcde1 --- /dev/null +++ b/src/test/ui/json-multiple.nll.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/json-multiple.nll/libjson_multiple.rlib","emit":"link"} diff --git a/src/test/ui/json-multiple.rs b/src/test/ui/json-multiple.rs new file mode 100644 index 0000000000..fb126339dc --- /dev/null +++ b/src/test/ui/json-multiple.rs @@ -0,0 +1,5 @@ +// build-pass +// ignore-pass (different metadata emitted in different modes) +// compile-flags: --json=diagnostic-short --json artifacts --error-format=json + +#![crate_type = "lib"] diff --git a/src/test/ui/json-multiple.stderr b/src/test/ui/json-multiple.stderr new file mode 100644 index 0000000000..7ed345113c --- /dev/null +++ b/src/test/ui/json-multiple.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/json-multiple/libjson_multiple.rlib","emit":"link"} diff --git a/src/test/ui/json-options.nll.stderr b/src/test/ui/json-options.nll.stderr new file mode 100644 index 0000000000..f19a9cd92a --- /dev/null +++ b/src/test/ui/json-options.nll.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/json-options.nll/libjson_options.rlib","emit":"link"} diff --git a/src/test/ui/json-options.rs b/src/test/ui/json-options.rs new file mode 100644 index 0000000000..8b6ba131eb --- /dev/null +++ b/src/test/ui/json-options.rs @@ -0,0 +1,5 @@ +// build-pass +// ignore-pass (different metadata emitted in different modes) +// compile-flags: --json=diagnostic-short,artifacts --error-format=json + +#![crate_type = "lib"] diff --git a/src/test/ui/json-options.stderr b/src/test/ui/json-options.stderr new file mode 100644 index 0000000000..24977731d1 --- /dev/null +++ b/src/test/ui/json-options.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/json-options/libjson_options.rlib","emit":"link"} diff --git a/src/test/ui/json-short.rs b/src/test/ui/json-short.rs new file mode 100644 index 0000000000..01a311b939 --- /dev/null +++ b/src/test/ui/json-short.rs @@ -0,0 +1,2 @@ +// build-fail +// compile-flags: --json=diagnostic-short --error-format=json diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json-short.stderr new file mode 100644 index 0000000000..dffbdb7e48 --- /dev/null +++ b/src/test/ui/json-short.stderr @@ -0,0 +1,19 @@ +{"message":"`main` function not found in crate `json_short`","code":{"code":"E0601","explanation":" +No `main` function was found in a binary crate. To fix this error, add a +`main` function. For example: + +``` +fn main() { + // Your program will start here. + println!(\"Hello world!\"); +} +``` + +If you don't know the basics of Rust, you can go look to the Rust Book to get +started: https://doc.rust-lang.org/book/ +"},"level":"error","spans":[],"children":[{"message":"consider adding a `main` function to `$DIR/json-short.rs`","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"error[E0601]: `main` function not found in crate `json_short` +"} +{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error +"} +{"message":"For more information about this error, try `rustc --explain E0601`.","code":null,"level":"","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0601`. +"} diff --git a/src/test/run-pass/keyword-changes-2012-07-31.rs b/src/test/ui/keyword-changes-2012-07-31.rs similarity index 93% rename from src/test/run-pass/keyword-changes-2012-07-31.rs rename to src/test/ui/keyword-changes-2012-07-31.rs index 73b0d07090..1b38527ec2 100644 --- a/src/test/run-pass/keyword-changes-2012-07-31.rs +++ b/src/test/ui/keyword-changes-2012-07-31.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // return -> return // mod -> module diff --git a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs b/src/test/ui/kindck-implicit-close-over-mut-var.rs similarity index 98% rename from src/test/run-pass/kindck-implicit-close-over-mut-var.rs rename to src/test/ui/kindck-implicit-close-over-mut-var.rs index 3b2991ede9..5b5d86eec2 100644 --- a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs +++ b/src/test/ui/kindck-implicit-close-over-mut-var.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(dead_code)] use std::thread; diff --git a/src/test/run-pass/kinds-in-metadata.rs b/src/test/ui/kinds-in-metadata.rs similarity index 96% rename from src/test/run-pass/kinds-in-metadata.rs rename to src/test/ui/kinds-in-metadata.rs index 7cfc28b12b..136037a7ac 100644 --- a/src/test/run-pass/kinds-in-metadata.rs +++ b/src/test/ui/kinds-in-metadata.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:kinds_in_metadata.rs // pretty-expanded FIXME #23616 diff --git a/src/test/ui/label/label_break_value_illegal_uses.stderr b/src/test/ui/label/label_break_value_illegal_uses.stderr index 0b9754c3c7..80b4329ad4 100644 --- a/src/test/ui/label/label_break_value_illegal_uses.stderr +++ b/src/test/ui/label/label_break_value_illegal_uses.stderr @@ -11,7 +11,7 @@ LL | if true 'b: {} | -- ^^---- | | | | | expected `{` - | | help: try placing this code inside a block: `{ 'b: { } }` + | | help: try placing this code inside a block: `{ 'b: {} }` | this `if` statement has a condition, but no block error: expected `{`, found `'b` @@ -21,7 +21,7 @@ LL | if true {} else 'b: {} | ^^---- | | | expected `{` - | help: try placing this code inside a block: `{ 'b: { } }` + | help: try placing this code inside a block: `{ 'b: {} }` error: expected one of `.`, `?`, `{`, or an operator, found `'b` --> $DIR/label_break_value_illegal_uses.rs:18:17 diff --git a/src/test/run-pass/lambda-infer-unresolved.rs b/src/test/ui/lambda-infer-unresolved.rs similarity index 96% rename from src/test/run-pass/lambda-infer-unresolved.rs rename to src/test/ui/lambda-infer-unresolved.rs index 751801e7c2..9cc466b28e 100644 --- a/src/test/run-pass/lambda-infer-unresolved.rs +++ b/src/test/ui/lambda-infer-unresolved.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_mut)] // This should typecheck even though the type of e is not fully // resolved when we finish typechecking the ||. diff --git a/src/test/run-pass/lambda-var-hygiene.rs b/src/test/ui/lambda-var-hygiene.rs similarity index 94% rename from src/test/run-pass/lambda-var-hygiene.rs rename to src/test/ui/lambda-var-hygiene.rs index 9cc4cc29bf..bf06765e5d 100644 --- a/src/test/run-pass/lambda-var-hygiene.rs +++ b/src/test/ui/lambda-var-hygiene.rs @@ -1,3 +1,4 @@ +// run-pass // shouldn't affect evaluation of $ex: macro_rules! bad_macro { ($ex:expr) => ({(|_x| { $ex }) (9) }) diff --git a/src/test/run-pass/large-records.rs b/src/test/ui/large-records.rs similarity index 97% rename from src/test/run-pass/large-records.rs rename to src/test/ui/large-records.rs index 9786ea7978..7f850a94e8 100644 --- a/src/test/run-pass/large-records.rs +++ b/src/test/ui/large-records.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] diff --git a/src/test/run-pass/last-use-in-block.rs b/src/test/ui/last-use-in-block.rs similarity index 96% rename from src/test/run-pass/last-use-in-block.rs rename to src/test/ui/last-use-in-block.rs index 2bfd982995..1ab847dcd8 100644 --- a/src/test/run-pass/last-use-in-block.rs +++ b/src/test/ui/last-use-in-block.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_parens)] // Issue #1818 diff --git a/src/test/run-pass/last-use-in-cap-clause.rs b/src/test/ui/last-use-in-cap-clause.rs similarity index 95% rename from src/test/run-pass/last-use-in-cap-clause.rs rename to src/test/ui/last-use-in-cap-clause.rs index 42dc6a4b06..98d4346328 100644 --- a/src/test/run-pass/last-use-in-cap-clause.rs +++ b/src/test/ui/last-use-in-cap-clause.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Make sure #1399 stays fixed diff --git a/src/test/run-pass/last-use-is-capture.rs b/src/test/ui/last-use-is-capture.rs similarity index 95% rename from src/test/run-pass/last-use-is-capture.rs rename to src/test/ui/last-use-is-capture.rs index 2fa85e2d5b..af23087779 100644 --- a/src/test/run-pass/last-use-is-capture.rs +++ b/src/test/ui/last-use-is-capture.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Make sure #1399 stays fixed diff --git a/src/test/ui/layout/issue-60431-unsized-tail-behind-projection.rs b/src/test/ui/layout/issue-60431-unsized-tail-behind-projection.rs new file mode 100644 index 0000000000..65845d2c9f --- /dev/null +++ b/src/test/ui/layout/issue-60431-unsized-tail-behind-projection.rs @@ -0,0 +1,35 @@ +// rust-lang/rust#60431: This is a scenario where to determine the size of +// `&Ref`, we need to know the concrete type of the last field in +// `Ref` (i.e. its "struct tail"), and determining that concrete type +// requires normalizing `Obstack::Dyn`. +// +// The old "struct tail" computation did not perform such normalization, and so +// the compiler would ICE when trying to figure out if `Ref` is a +// dynamically-sized type (DST). + +// run-pass + +use std::mem; + +pub trait Arena { + type Dyn : ?Sized; +} + +pub struct DynRef { + _dummy: [()], +} + +pub struct Ref { + _value: u8, + _dyn_arena: A::Dyn, +} + +pub struct Obstack; + +impl Arena for Obstack { + type Dyn = DynRef; +} + +fn main() { + assert_eq!(mem::size_of::<&Ref>(), mem::size_of::<&[()]>()); +} diff --git a/src/test/run-pass/lazy-and-or.rs b/src/test/ui/lazy-and-or.rs similarity index 95% rename from src/test/run-pass/lazy-and-or.rs rename to src/test/ui/lazy-and-or.rs index d1f564fbe4..0b44a70a56 100644 --- a/src/test/run-pass/lazy-and-or.rs +++ b/src/test/ui/lazy-and-or.rs @@ -1,3 +1,5 @@ +// run-pass + fn incr(x: &mut isize) -> bool { *x += 1; assert!((false)); return false; } pub fn main() { diff --git a/src/test/run-pass/lazy-init.rs b/src/test/ui/lazy-init.rs similarity index 91% rename from src/test/run-pass/lazy-init.rs rename to src/test/ui/lazy-init.rs index 1d7001b49e..a4b5d18bb3 100644 --- a/src/test/run-pass/lazy-init.rs +++ b/src/test/ui/lazy-init.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_mut)] diff --git a/src/test/run-pass/leak-unique-as-tydesc.rs b/src/test/ui/leak-unique-as-tydesc.rs similarity index 92% rename from src/test/run-pass/leak-unique-as-tydesc.rs rename to src/test/ui/leak-unique-as-tydesc.rs index 2293e3c823..752081b78f 100644 --- a/src/test/run-pass/leak-unique-as-tydesc.rs +++ b/src/test/ui/leak-unique-as-tydesc.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(box_syntax)] diff --git a/src/test/run-pass/lex-bare-cr-nondoc-comment.rs b/src/test/ui/lex-bare-cr-nondoc-comment.rs similarity index 92% rename from src/test/run-pass/lex-bare-cr-nondoc-comment.rs rename to src/test/ui/lex-bare-cr-nondoc-comment.rs index da18ab268f..5b528d6e1e 100644 --- a/src/test/run-pass/lex-bare-cr-nondoc-comment.rs +++ b/src/test/ui/lex-bare-cr-nondoc-comment.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-tidy-cr // nondoc comment with bare CR: ' ' diff --git a/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs b/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs similarity index 95% rename from src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs rename to src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs index f9d1b17b8d..ada253aacf 100644 --- a/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs +++ b/src/test/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-tidy-cr ignore-license // ignore-tidy-cr (repeated again because of tidy bug) // license is ignored because tidy can't handle the CRLF here properly. diff --git a/src/test/run-pass/lexical-scoping.rs b/src/test/ui/lexical-scoping.rs similarity index 96% rename from src/test/run-pass/lexical-scoping.rs rename to src/test/ui/lexical-scoping.rs index 15797eee9b..04904958a6 100644 --- a/src/test/run-pass/lexical-scoping.rs +++ b/src/test/ui/lexical-scoping.rs @@ -1,3 +1,4 @@ +// run-pass // Tests that items in subscopes can shadow type parameters and local variables (see issue #23880). #![allow(unused)] diff --git a/src/test/run-pass/lib-defaults.rs b/src/test/ui/lib-defaults.rs similarity index 96% rename from src/test/run-pass/lib-defaults.rs rename to src/test/ui/lib-defaults.rs index dcf537866c..cd0b0bb232 100644 --- a/src/test/run-pass/lib-defaults.rs +++ b/src/test/ui/lib-defaults.rs @@ -1,3 +1,4 @@ +// run-pass // dont-check-compiler-stderr (rust-lang/rust#54222) // ignore-wasm32-bare no libc to test ffi with diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index 8ae8018c2f..bacba10b55 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -12,15 +12,12 @@ error: expected type, found keyword `loop` --> $DIR/lifetime_starts_expressions.rs:6:26 | LL | loop { break 'label: loop { break 'label 42; }; } - | ^^^^ expecting a type here because of type ascription + | - ^^^^ expected type + | | + | tried to parse a type due to this type ascription | - = note: #![feature(type_ascription)] lets you annotate an expression with a type: `: ` -note: this expression expects an ascribed type after the colon - --> $DIR/lifetime_starts_expressions.rs:6:12 - | -LL | loop { break 'label: loop { break 'label 42; }; } - | ^^^^^^^^^^^^ - = help: this might be indicative of a syntax error elsewhere + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to 2 previous errors diff --git a/src/test/run-pass/link-cfg-works.rs b/src/test/ui/link-cfg-works.rs similarity index 95% rename from src/test/run-pass/link-cfg-works.rs rename to src/test/ui/link-cfg-works.rs index d7a248fd4d..fe1b569dff 100644 --- a/src/test/run-pass/link-cfg-works.rs +++ b/src/test/ui/link-cfg-works.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:link-cfg-works-transitive-rlib.rs // aux-build:link-cfg-works-transitive-dylib.rs diff --git a/src/test/run-pass/link-section.rs b/src/test/ui/link-section.rs similarity index 98% rename from src/test/run-pass/link-section.rs rename to src/test/ui/link-section.rs index 1c2d3eaaa3..6958eeda69 100644 --- a/src/test/run-pass/link-section.rs +++ b/src/test/ui/link-section.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_upper_case_globals)] #[cfg(not(target_os = "macos"))] #[link_section=".moretext"] diff --git a/src/test/ui/linkage-attr/linkage4.stderr b/src/test/ui/linkage-attr/linkage4.stderr index f2aab164bd..b46941067a 100644 --- a/src/test/ui/linkage-attr/linkage4.stderr +++ b/src/test/ui/linkage-attr/linkage4.stderr @@ -5,7 +5,7 @@ LL | #[linkage = "external"] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29603 - = help: add #![feature(linkage)] to the crate attributes to enable + = help: add `#![feature(linkage)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/linkage1.rs b/src/test/ui/linkage1.rs similarity index 98% rename from src/test/run-pass/linkage1.rs rename to src/test/ui/linkage1.rs index da07385ead..bda4da53db 100644 --- a/src/test/run-pass/linkage1.rs +++ b/src/test/ui/linkage1.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-windows // ignore-macos // ignore-emscripten doesn't support this linkage diff --git a/src/test/run-pass/lint-cap.rs b/src/test/ui/lint-cap.rs similarity index 88% rename from src/test/run-pass/lint-cap.rs rename to src/test/ui/lint-cap.rs index f03bb69189..461b923ccd 100644 --- a/src/test/run-pass/lint-cap.rs +++ b/src/test/ui/lint-cap.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --cap-lints allow #![deny(warnings)] diff --git a/src/test/run-pass/lint-dead-code-associated-type.rs b/src/test/ui/lint-dead-code-associated-type.rs similarity index 92% rename from src/test/run-pass/lint-dead-code-associated-type.rs rename to src/test/ui/lint-dead-code-associated-type.rs index 576ba6d170..1cf66e75a9 100644 --- a/src/test/run-pass/lint-dead-code-associated-type.rs +++ b/src/test/ui/lint-dead-code-associated-type.rs @@ -1,3 +1,5 @@ +// run-pass + #![deny(dead_code)] trait Foo { diff --git a/src/test/run-pass/lint-dead-code-variant.rs b/src/test/ui/lint-dead-code-variant.rs similarity index 90% rename from src/test/run-pass/lint-dead-code-variant.rs rename to src/test/ui/lint-dead-code-variant.rs index 3838b83e45..91c97232ee 100644 --- a/src/test/run-pass/lint-dead-code-variant.rs +++ b/src/test/ui/lint-dead-code-variant.rs @@ -1,3 +1,5 @@ +// run-pass + #![deny(dead_code)] enum Foo { diff --git a/src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs b/src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs similarity index 95% rename from src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs rename to src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs index 9ca3ecc72d..07a32904a5 100644 --- a/src/test/run-pass/lint-expr-stmt-attrs-for-early-lints.rs +++ b/src/test/ui/lint-expr-stmt-attrs-for-early-lints.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(stmt_expr_attributes)] #![deny(unused_parens)] diff --git a/src/test/run-pass/lint-unknown-lints-at-crate-level.rs b/src/test/ui/lint-unknown-lints-at-crate-level.rs similarity index 90% rename from src/test/run-pass/lint-unknown-lints-at-crate-level.rs rename to src/test/ui/lint-unknown-lints-at-crate-level.rs index fe2fbeabac..61d27f1eff 100644 --- a/src/test/run-pass/lint-unknown-lints-at-crate-level.rs +++ b/src/test/ui/lint-unknown-lints-at-crate-level.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -D warnings -D unknown-lints #![allow(unknown_lints)] diff --git a/src/test/ui/lint/command-line-lint-group-allow.rs b/src/test/ui/lint/command-line-lint-group-allow.rs index ac98724d03..f26e157bc7 100644 --- a/src/test/ui/lint/command-line-lint-group-allow.rs +++ b/src/test/ui/lint/command-line-lint-group-allow.rs @@ -1,5 +1,5 @@ // compile-flags: -A bad-style -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _InappropriateCamelCasing = true; diff --git a/src/test/ui/lint/command-line-lint-group-warn.rs b/src/test/ui/lint/command-line-lint-group-warn.rs index 73dd656f60..d3a4201ba6 100644 --- a/src/test/ui/lint/command-line-lint-group-warn.rs +++ b/src/test/ui/lint/command-line-lint-group-warn.rs @@ -1,5 +1,5 @@ // compile-flags: -W bad-style -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _InappropriateCamelCasing = true; diff --git a/src/test/ui/lint/deny-overflowing-literals.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr index c97872b522..7f59495023 100644 --- a/src/test/ui/lint/deny-overflowing-literals.stderr +++ b/src/test/ui/lint/deny-overflowing-literals.stderr @@ -4,7 +4,7 @@ error: literal out of range for `u8` LL | let x: u8 = 256; | ^^^ | - = note: #[deny(overflowing_literals)] on by default + = note: `#[deny(overflowing_literals)]` on by default error: range endpoint is out of range for `u8` --> $DIR/deny-overflowing-literals.rs:5:14 diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed index d52c651ce3..9fce66a0a8 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // run-rustfix #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.rs b/src/test/ui/lint/inclusive-range-pattern-syntax.rs index 5174a8b8b7..f886e778b5 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.rs +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // run-rustfix #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index 7d3fd441ae..4cb35e907c 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_syntax)] #![feature(box_patterns)] diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index 8fd98e0a3d..a0b34d220c 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ - = note: #[warn(unused_variables)] implied by #[warn(unused)] + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: unused variable: `mut_unused_var` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13 @@ -54,7 +54,7 @@ note: lint level defined here | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ - = note: #[warn(unused_assignments)] implied by #[warn(unused)] + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` = help: maybe it is overwritten before being read? warning: unused variable: `fire` @@ -112,7 +112,7 @@ note: lint level defined here | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ - = note: #[warn(unused_mut)] implied by #[warn(unused)] + = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]` warning: variable does not need to be mutable --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:10 diff --git a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs index 8872c0047f..47063a7c26 100644 --- a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs +++ b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_parens)] diff --git a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs index e4be1edc5d..3802e01a77 100644 --- a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs +++ b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![forbid(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.stderr b/src/test/ui/lint/issue-54180-unused-ref-field.stderr index 9f47554a1a..817d9a46e8 100644 --- a/src/test/ui/lint/issue-54180-unused-ref-field.stderr +++ b/src/test/ui/lint/issue-54180-unused-ref-field.stderr @@ -11,7 +11,7 @@ note: lint level defined here | LL | #![deny(unused)] | ^^^^^^ - = note: #[deny(unused_variables)] implied by #[deny(unused)] + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` error: unused variable: `x` --> $DIR/issue-54180-unused-ref-field.rs:29:45 diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs index 3a52996195..eda9e2cdfa 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(ellipsis_inclusive_range_patterns)] #![allow(unreachable_patterns)] diff --git a/src/test/ui/lint/lint-change-warnings.stderr b/src/test/ui/lint/lint-change-warnings.stderr index c4b8ab5fc1..336cb7ea84 100644 --- a/src/test/ui/lint/lint-change-warnings.stderr +++ b/src/test/ui/lint/lint-change-warnings.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(while_true)] implied by #[deny(warnings)] + = note: `#[deny(while_true)]` implied by `#[deny(warnings)]` warning: denote infinite loops with `loop { ... }` --> $DIR/lint-change-warnings.rs:15:5 @@ -17,7 +17,7 @@ warning: denote infinite loops with `loop { ... }` LL | while true {} | ^^^^^^^^^^ help: use `loop` | - = note: #[warn(while_true)] on by default + = note: `#[warn(while_true)]` on by default error: denote infinite loops with `loop { ... }` --> $DIR/lint-change-warnings.rs:20:5 @@ -30,7 +30,7 @@ note: lint level defined here | LL | #[forbid(warnings)] | ^^^^^^^^ - = note: #[forbid(while_true)] implied by #[forbid(warnings)] + = note: `#[forbid(while_true)]` implied by `#[forbid(warnings)]` error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/lint-group-nonstandard-style.stderr b/src/test/ui/lint/lint-group-nonstandard-style.stderr index a365204f12..1cc973d32c 100644 --- a/src/test/ui/lint/lint-group-nonstandard-style.stderr +++ b/src/test/ui/lint/lint-group-nonstandard-style.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ - = note: #[warn(non_camel_case_types)] implied by #[warn(nonstandard_style)] + = note: `#[warn(non_camel_case_types)]` implied by `#[warn(nonstandard_style)]` error: function `CamelCase` should have a snake case name --> $DIR/lint-group-nonstandard-style.rs:4:4 @@ -22,7 +22,7 @@ note: lint level defined here | LL | #![deny(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ - = note: #[deny(non_snake_case)] implied by #[deny(nonstandard_style)] + = note: `#[deny(non_snake_case)]` implied by `#[deny(nonstandard_style)]` error: function `CamelCase` should have a snake case name --> $DIR/lint-group-nonstandard-style.rs:12:12 @@ -35,7 +35,7 @@ note: lint level defined here | LL | #[forbid(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ - = note: #[forbid(non_snake_case)] implied by #[forbid(nonstandard_style)] + = note: `#[forbid(non_snake_case)]` implied by `#[forbid(nonstandard_style)]` error: static variable `bad` should have an upper case name --> $DIR/lint-group-nonstandard-style.rs:14:16 @@ -48,7 +48,7 @@ note: lint level defined here | LL | #[forbid(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ - = note: #[forbid(non_upper_case_globals)] implied by #[forbid(nonstandard_style)] + = note: `#[forbid(non_upper_case_globals)]` implied by `#[forbid(nonstandard_style)]` warning: function `CamelCase` should have a snake case name --> $DIR/lint-group-nonstandard-style.rs:20:12 @@ -61,7 +61,7 @@ note: lint level defined here | LL | #![warn(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ - = note: #[warn(non_snake_case)] implied by #[warn(nonstandard_style)] + = note: `#[warn(non_snake_case)]` implied by `#[warn(nonstandard_style)]` error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/lint-impl-fn.stderr b/src/test/ui/lint/lint-impl-fn.stderr index 56f85111d4..2c9a264287 100644 --- a/src/test/ui/lint/lint-impl-fn.stderr +++ b/src/test/ui/lint/lint-impl-fn.stderr @@ -11,25 +11,25 @@ LL | #[deny(while_true)] | ^^^^^^^^^^ error: denote infinite loops with `loop { ... }` - --> $DIR/lint-impl-fn.rs:27:5 + --> $DIR/lint-impl-fn.rs:18:25 | -LL | while true {} - | ^^^^^^^^^^ help: use `loop` +LL | fn foo(&self) { while true {} } + | ^^^^^^^^^^ help: use `loop` | note: lint level defined here - --> $DIR/lint-impl-fn.rs:25:8 + --> $DIR/lint-impl-fn.rs:13:8 | LL | #[deny(while_true)] | ^^^^^^^^^^ error: denote infinite loops with `loop { ... }` - --> $DIR/lint-impl-fn.rs:18:25 + --> $DIR/lint-impl-fn.rs:27:5 | -LL | fn foo(&self) { while true {} } - | ^^^^^^^^^^ help: use `loop` +LL | while true {} + | ^^^^^^^^^^ help: use `loop` | note: lint level defined here - --> $DIR/lint-impl-fn.rs:13:8 + --> $DIR/lint-impl-fn.rs:25:8 | LL | #[deny(while_true)] | ^^^^^^^^^^ diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr index 448cc953d4..5308bba440 100644 --- a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr +++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr @@ -7,7 +7,7 @@ LL | LL | impl Foo for dyn Send + Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | - = note: #[deny(order_dependent_trait_objects)] on by default + = note: `#[deny(order_dependent_trait_objects)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56484 diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs index 8ca5af2163..95da4efa59 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Issue #7526: lowercase static constants in patterns look like bindings // This is similar to lint-lowercase-static-const-pattern.rs, except it diff --git a/src/test/ui/lint/lint-misplaced-attr.stderr b/src/test/ui/lint/lint-misplaced-attr.stderr index 1419f858f8..cd4a89f91c 100644 --- a/src/test/ui/lint/lint-misplaced-attr.stderr +++ b/src/test/ui/lint/lint-misplaced-attr.stderr @@ -22,7 +22,7 @@ error: unused attribute LL | #[crate_type = "bin"] fn main() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` --> $DIR/lint-misplaced-attr.rs:11:1 | LL | #[crate_type = "bin"] fn main() {} diff --git a/src/test/ui/lint/lint-non-camel-case-variant.rs b/src/test/ui/lint/lint-non-camel-case-variant.rs index 1f06b28398..434e24c1d2 100644 --- a/src/test/ui/lint/lint-non-camel-case-variant.rs +++ b/src/test/ui/lint/lint-non-camel-case-variant.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(non_camel_case_types)] diff --git a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs index c2fdfb4fe4..d025ee9485 100644 --- a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs +++ b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // This is ok because we often use the trailing underscore to mean 'prime' diff --git a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs index 9a6487d254..5bec82ce1a 100644 --- a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs +++ b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode.rs b/src/test/ui/lint/lint-nonstandard-style-unicode.rs index a0b4130c3e..40f0a67638 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] diff --git a/src/test/ui/lint/lint-output-format-2.rs b/src/test/ui/lint/lint-output-format-2.rs index c9b33f06e2..32a4117996 100644 --- a/src/test/ui/lint/lint-output-format-2.rs +++ b/src/test/ui/lint/lint-output-format-2.rs @@ -1,7 +1,7 @@ // aux-build:lint_output_format.rs #![feature(unstable_test_feature)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate lint_output_format; use lint_output_format::{foo, bar}; diff --git a/src/test/ui/lint/lint-output-format-2.stderr b/src/test/ui/lint/lint-output-format-2.stderr index f4e6b06203..fcaf01488a 100644 --- a/src/test/ui/lint/lint-output-format-2.stderr +++ b/src/test/ui/lint/lint-output-format-2.stderr @@ -4,7 +4,7 @@ warning: use of deprecated item 'lint_output_format::foo': text LL | use lint_output_format::{foo, bar}; | ^^^ | - = note: #[warn(deprecated)] on by default + = note: `#[warn(deprecated)]` on by default warning: use of deprecated item 'lint_output_format::foo': text --> $DIR/lint-output-format-2.rs:12:14 diff --git a/src/test/ui/lint/lint-output-format.stderr b/src/test/ui/lint/lint-output-format.stderr index 21b12301e2..3bc1d6fc13 100644 --- a/src/test/ui/lint/lint-output-format.stderr +++ b/src/test/ui/lint/lint-output-format.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | extern crate lint_output_format; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-output-format.rs:7:31 @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | use lint_output_format::{foo, bar}; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-output-format.rs:11:14 @@ -20,7 +20,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _y = bar(); | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/lint-qualification.rs b/src/test/ui/lint/lint-qualification.rs index 2aa4526b81..1b24191a11 100644 --- a/src/test/ui/lint/lint-qualification.rs +++ b/src/test/ui/lint/lint-qualification.rs @@ -1,4 +1,5 @@ #![deny(unused_qualifications)] +#[allow(deprecated)] mod foo { pub fn bar() {} diff --git a/src/test/ui/lint/lint-qualification.stderr b/src/test/ui/lint/lint-qualification.stderr index 78f7e32a30..125aeb3db0 100644 --- a/src/test/ui/lint/lint-qualification.stderr +++ b/src/test/ui/lint/lint-qualification.stderr @@ -1,5 +1,5 @@ error: unnecessary qualification - --> $DIR/lint-qualification.rs:9:5 + --> $DIR/lint-qualification.rs:10:5 | LL | foo::bar(); | ^^^^^^^^ diff --git a/src/test/ui/lint/lint-removed-cmdline.stderr b/src/test/ui/lint/lint-removed-cmdline.stderr index d46ef6b923..69b0d2675c 100644 --- a/src/test/ui/lint/lint-removed-cmdline.stderr +++ b/src/test/ui/lint/lint-removed-cmdline.stderr @@ -13,7 +13,7 @@ note: lint level defined here | LL | #[deny(warnings)] | ^^^^^^^^ - = note: #[deny(unused_variables)] implied by #[deny(warnings)] + = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-removed.stderr b/src/test/ui/lint/lint-removed.stderr index cde494f22f..060ba31bce 100644 --- a/src/test/ui/lint/lint-removed.stderr +++ b/src/test/ui/lint/lint-removed.stderr @@ -4,7 +4,7 @@ warning: lint `raw_pointer_derive` has been removed: `using derive with raw poin LL | #[deny(raw_pointer_derive)] | ^^^^^^^^^^^^^^^^^^ | - = note: #[warn(renamed_and_removed_lints)] on by default + = note: `#[warn(renamed_and_removed_lints)]` on by default error: unused variable: `unused` --> $DIR/lint-removed.rs:8:17 diff --git a/src/test/ui/lint/lint-renamed-allow.stderr b/src/test/ui/lint/lint-renamed-allow.stderr index 383a800b54..1d984cb828 100644 --- a/src/test/ui/lint/lint-renamed-allow.stderr +++ b/src/test/ui/lint/lint-renamed-allow.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #[deny(unused)] | ^^^^^^ - = note: #[deny(unused_variables)] implied by #[deny(unused)] + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-renamed-cmdline.stderr b/src/test/ui/lint/lint-renamed-cmdline.stderr index 6247ee0aff..c978981a5c 100644 --- a/src/test/ui/lint/lint-renamed-cmdline.stderr +++ b/src/test/ui/lint/lint-renamed-cmdline.stderr @@ -13,7 +13,7 @@ note: lint level defined here | LL | #[deny(unused)] | ^^^^^^ - = note: #[deny(unused_variables)] implied by #[deny(unused)] + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-renamed.stderr b/src/test/ui/lint/lint-renamed.stderr index 2174b22ffb..ba8eadf23a 100644 --- a/src/test/ui/lint/lint-renamed.stderr +++ b/src/test/ui/lint/lint-renamed.stderr @@ -4,7 +4,7 @@ warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` LL | #[deny(bare_trait_object)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects` | - = note: #[warn(renamed_and_removed_lints)] on by default + = note: `#[warn(renamed_and_removed_lints)]` on by default error: unused variable: `unused` --> $DIR/lint-renamed.rs:4:17 @@ -17,7 +17,7 @@ note: lint level defined here | LL | #[deny(unused)] | ^^^^^^ - = note: #[deny(unused_variables)] implied by #[deny(unused)] + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-stability-2.stderr b/src/test/ui/lint/lint-stability-2.stderr index 808c16c95a..5b7537fa23 100644 --- a/src/test/ui/lint/lint-stability-2.stderr +++ b/src/test/ui/lint/lint-stability-2.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.method_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:42:9 @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Foo::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:44:9 @@ -20,7 +20,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:46:13 @@ -28,7 +28,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:48:9 @@ -36,7 +36,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:51:13 @@ -44,7 +44,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:53:9 @@ -52,7 +52,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:55:9 @@ -60,7 +60,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:57:13 @@ -68,7 +68,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:59:9 @@ -76,7 +76,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:62:13 @@ -84,7 +84,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.method_unstable(); | ^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:63:9 @@ -92,7 +92,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Foo::method_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:64:9 @@ -100,7 +100,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::method_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:65:13 @@ -108,7 +108,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_unstable(); | ^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:66:9 @@ -116,7 +116,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:68:13 @@ -124,7 +124,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | foo.method_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:70:9 @@ -132,7 +132,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | Foo::method_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:72:9 @@ -140,7 +140,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | ::method_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:74:13 @@ -148,7 +148,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | foo.trait_unstable_text(); | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:76:9 @@ -156,7 +156,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | ::trait_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:131:13 @@ -164,7 +164,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:133:9 @@ -172,7 +172,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:135:13 @@ -180,7 +180,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:137:9 @@ -188,7 +188,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:139:13 @@ -196,7 +196,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_unstable(); | ^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:140:9 @@ -204,7 +204,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:141:13 @@ -212,7 +212,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | foo.trait_unstable_text(); | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:143:9 @@ -220,7 +220,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | ::trait_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:154:13 @@ -228,7 +228,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:156:13 @@ -236,7 +236,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-2.rs:158:13 @@ -244,7 +244,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | foo.trait_unstable(); | ^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability-2.rs:159:13 @@ -252,7 +252,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | foo.trait_unstable_text(); | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to 32 previous errors diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index a2031c2189..5e747467a1 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -1,11 +1,10 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs // aux-build:stability-cfg2.rs // ignore-tidy-linelength #![warn(deprecated)] -#![allow(dead_code, unused_extern_crates)] #![feature(staged_api, unstable_test_feature)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index 811004ee12..8132a66df8 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -1,5 +1,5 @@ warning: use of deprecated item 'lint_stability::deprecated': text - --> $DIR/lint-stability-deprecated.rs:26:9 + --> $DIR/lint-stability-deprecated.rs:25:9 | LL | deprecated(); | ^^^^^^^^^^ @@ -11,625 +11,625 @@ LL | #![warn(deprecated)] | ^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:31:9 + --> $DIR/lint-stability-deprecated.rs:30:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:33:9 + --> $DIR/lint-stability-deprecated.rs:32:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:35:9 + --> $DIR/lint-stability-deprecated.rs:34:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:40:9 + --> $DIR/lint-stability-deprecated.rs:39:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:42:9 + --> $DIR/lint-stability-deprecated.rs:41:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:44:9 + --> $DIR/lint-stability-deprecated.rs:43:9 | LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:49:9 + --> $DIR/lint-stability-deprecated.rs:48:9 | LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:51:9 + --> $DIR/lint-stability-deprecated.rs:50:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:53:9 + --> $DIR/lint-stability-deprecated.rs:52:9 | LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:58:9 + --> $DIR/lint-stability-deprecated.rs:57:9 | LL | Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:60:9 + --> $DIR/lint-stability-deprecated.rs:59:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedStruct': text - --> $DIR/lint-stability-deprecated.rs:107:17 + --> $DIR/lint-stability-deprecated.rs:106:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct': text - --> $DIR/lint-stability-deprecated.rs:110:17 + --> $DIR/lint-stability-deprecated.rs:109:17 | LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:117:17 + --> $DIR/lint-stability-deprecated.rs:116:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:118:17 + --> $DIR/lint-stability-deprecated.rs:117:17 | LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Enum::DeprecatedVariant': text - --> $DIR/lint-stability-deprecated.rs:122:17 + --> $DIR/lint-stability-deprecated.rs:121:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant': text - --> $DIR/lint-stability-deprecated.rs:123:17 + --> $DIR/lint-stability-deprecated.rs:122:17 | LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:127:17 + --> $DIR/lint-stability-deprecated.rs:126:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:128:17 + --> $DIR/lint-stability-deprecated.rs:127:17 | LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:137:25 + --> $DIR/lint-stability-deprecated.rs:136:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:138:25 + --> $DIR/lint-stability-deprecated.rs:137:25 | LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:139:41 + --> $DIR/lint-stability-deprecated.rs:138:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:144:9 + --> $DIR/lint-stability-deprecated.rs:143:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:146:9 + --> $DIR/lint-stability-deprecated.rs:145:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:148:9 + --> $DIR/lint-stability-deprecated.rs:147:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:150:9 + --> $DIR/lint-stability-deprecated.rs:149:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:152:9 + --> $DIR/lint-stability-deprecated.rs:151:9 | LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:154:9 + --> $DIR/lint-stability-deprecated.rs:153:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:156:9 + --> $DIR/lint-stability-deprecated.rs:155:9 | LL | Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:158:9 + --> $DIR/lint-stability-deprecated.rs:157:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:186:10 + --> $DIR/lint-stability-deprecated.rs:185:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:188:25 + --> $DIR/lint-stability-deprecated.rs:187:25 | LL | trait LocalTrait2 : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text - --> $DIR/lint-stability-deprecated.rs:207:9 + --> $DIR/lint-stability-deprecated.rs:206:9 | LL | unstable_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::deprecated': text - --> $DIR/lint-stability-deprecated.rs:329:9 + --> $DIR/lint-stability-deprecated.rs:328:9 | LL | deprecated(); | ^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:334:9 + --> $DIR/lint-stability-deprecated.rs:333:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:336:9 + --> $DIR/lint-stability-deprecated.rs:335:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:338:9 + --> $DIR/lint-stability-deprecated.rs:337:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:343:9 + --> $DIR/lint-stability-deprecated.rs:342:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:345:9 + --> $DIR/lint-stability-deprecated.rs:344:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedStruct': text - --> $DIR/lint-stability-deprecated.rs:383:17 + --> $DIR/lint-stability-deprecated.rs:382:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedUnitStruct': text - --> $DIR/lint-stability-deprecated.rs:390:17 + --> $DIR/lint-stability-deprecated.rs:389:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text - --> $DIR/lint-stability-deprecated.rs:394:17 + --> $DIR/lint-stability-deprecated.rs:393:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTupleStruct': text - --> $DIR/lint-stability-deprecated.rs:398:17 + --> $DIR/lint-stability-deprecated.rs:397:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:405:9 + --> $DIR/lint-stability-deprecated.rs:404:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:407:9 + --> $DIR/lint-stability-deprecated.rs:406:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:409:9 + --> $DIR/lint-stability-deprecated.rs:408:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:411:9 + --> $DIR/lint-stability-deprecated.rs:410:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::test_fn_body::fn_in_body': text - --> $DIR/lint-stability-deprecated.rs:438:9 + --> $DIR/lint-stability-deprecated.rs:437:9 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:458:10 + --> $DIR/lint-stability-deprecated.rs:457:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedTrait': text - --> $DIR/lint-stability-deprecated.rs:460:24 + --> $DIR/lint-stability-deprecated.rs:459:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text - --> $DIR/lint-stability-deprecated.rs:446:13 + --> $DIR/lint-stability-deprecated.rs:445:13 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - --> $DIR/lint-stability-deprecated.rs:99:48 + --> $DIR/lint-stability-deprecated.rs:98:48 | LL | struct S2(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - --> $DIR/lint-stability-deprecated.rs:103:13 + --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:27:13 + --> $DIR/lint-stability-deprecated.rs:26:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:28:9 + --> $DIR/lint-stability-deprecated.rs:27:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:29:9 + --> $DIR/lint-stability-deprecated.rs:28:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:30:13 + --> $DIR/lint-stability-deprecated.rs:29:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:32:9 + --> $DIR/lint-stability-deprecated.rs:31:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:36:13 + --> $DIR/lint-stability-deprecated.rs:35:13 | LL | foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:37:9 + --> $DIR/lint-stability-deprecated.rs:36:9 | LL | Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:38:9 + --> $DIR/lint-stability-deprecated.rs:37:9 | LL | ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:39:13 + --> $DIR/lint-stability-deprecated.rs:38:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:41:9 + --> $DIR/lint-stability-deprecated.rs:40:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:45:13 + --> $DIR/lint-stability-deprecated.rs:44:13 | LL | foo.method_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:46:9 + --> $DIR/lint-stability-deprecated.rs:45:9 | LL | Foo::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:47:9 + --> $DIR/lint-stability-deprecated.rs:46:9 | LL | ::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:48:13 + --> $DIR/lint-stability-deprecated.rs:47:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:50:9 + --> $DIR/lint-stability-deprecated.rs:49:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:54:13 + --> $DIR/lint-stability-deprecated.rs:53:13 | LL | foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:55:9 + --> $DIR/lint-stability-deprecated.rs:54:9 | LL | Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:56:9 + --> $DIR/lint-stability-deprecated.rs:55:9 | LL | ::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:57:13 + --> $DIR/lint-stability-deprecated.rs:56:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:59:9 + --> $DIR/lint-stability-deprecated.rs:58:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text - --> $DIR/lint-stability-deprecated.rs:108:13 + --> $DIR/lint-stability-deprecated.rs:107:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i': text - --> $DIR/lint-stability-deprecated.rs:112:13 + --> $DIR/lint-stability-deprecated.rs:111:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:143:13 + --> $DIR/lint-stability-deprecated.rs:142:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:145:9 + --> $DIR/lint-stability-deprecated.rs:144:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:147:13 + --> $DIR/lint-stability-deprecated.rs:146:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:149:9 + --> $DIR/lint-stability-deprecated.rs:148:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:151:13 + --> $DIR/lint-stability-deprecated.rs:150:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:153:9 + --> $DIR/lint-stability-deprecated.rs:152:9 | LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:155:13 + --> $DIR/lint-stability-deprecated.rs:154:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:157:9 + --> $DIR/lint-stability-deprecated.rs:156:9 | LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:174:13 + --> $DIR/lint-stability-deprecated.rs:173:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:175:13 + --> $DIR/lint-stability-deprecated.rs:174:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text - --> $DIR/lint-stability-deprecated.rs:176:13 + --> $DIR/lint-stability-deprecated.rs:175:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - --> $DIR/lint-stability-deprecated.rs:177:13 + --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:330:13 + --> $DIR/lint-stability-deprecated.rs:329:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:331:9 + --> $DIR/lint-stability-deprecated.rs:330:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text - --> $DIR/lint-stability-deprecated.rs:332:9 + --> $DIR/lint-stability-deprecated.rs:331:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:333:13 + --> $DIR/lint-stability-deprecated.rs:332:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:335:9 + --> $DIR/lint-stability-deprecated.rs:334:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:339:13 + --> $DIR/lint-stability-deprecated.rs:338:13 | LL | foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:340:9 + --> $DIR/lint-stability-deprecated.rs:339:9 | LL | Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:341:9 + --> $DIR/lint-stability-deprecated.rs:340:9 | LL | ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:342:13 + --> $DIR/lint-stability-deprecated.rs:341:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:344:9 + --> $DIR/lint-stability-deprecated.rs:343:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::DeprecatedStruct::i': text - --> $DIR/lint-stability-deprecated.rs:385:13 + --> $DIR/lint-stability-deprecated.rs:384:13 | LL | i: 0 | ^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:404:13 + --> $DIR/lint-stability-deprecated.rs:403:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:406:9 + --> $DIR/lint-stability-deprecated.rs:405:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:408:13 + --> $DIR/lint-stability-deprecated.rs:407:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:410:9 + --> $DIR/lint-stability-deprecated.rs:409:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text - --> $DIR/lint-stability-deprecated.rs:427:13 + --> $DIR/lint-stability-deprecated.rs:426:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - --> $DIR/lint-stability-deprecated.rs:428:13 + --> $DIR/lint-stability-deprecated.rs:427:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/lint/lint-stability-fields.stderr b/src/test/ui/lint/lint-stability-fields.stderr index e80e745922..b6a08186b5 100644 --- a/src/test/ui/lint/lint-stability-fields.stderr +++ b/src/test/ui/lint/lint-stability-fields.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let x = Unstable { | ^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:61:13 @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Unstable { | ^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:67:13 @@ -20,7 +20,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Unstable | ^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:72:17 @@ -28,7 +28,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let x = reexport::Unstable2(1, 2, 3); | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:74:17 @@ -36,7 +36,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let x = Unstable2(1, 2, 3); | ^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:80:13 @@ -44,7 +44,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Unstable2 | ^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:85:13 @@ -52,7 +52,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Unstable2 | ^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:90:17 @@ -60,7 +60,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let x = Deprecated { | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:100:13 @@ -68,7 +68,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Deprecated { | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:106:13 @@ -76,7 +76,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Deprecated | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:110:17 @@ -84,7 +84,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:116:13 @@ -92,7 +92,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Deprecated2 | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:121:13 @@ -100,7 +100,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let Deprecated2 | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:21:13 @@ -108,7 +108,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override1: 2, | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:22:13 @@ -116,7 +116,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override2: 3, | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:26:17 @@ -124,7 +124,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.override1; | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:27:17 @@ -132,7 +132,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.override2; | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:31:13 @@ -140,7 +140,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override1: _, | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:32:13 @@ -148,7 +148,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override2: _ | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:40:17 @@ -156,7 +156,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.1; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:41:17 @@ -164,7 +164,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.2; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:44:20 @@ -172,7 +172,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | _, | ^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:45:20 @@ -180,7 +180,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | _) | ^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:52:13 @@ -188,7 +188,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | inherit: 1, | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:54:13 @@ -196,7 +196,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override2: 3, | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:57:17 @@ -204,7 +204,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.inherit; | ^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:59:17 @@ -212,7 +212,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.override2; | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:62:13 @@ -220,7 +220,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | inherit: _, | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:64:13 @@ -228,7 +228,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override2: _ | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:76:17 @@ -236,7 +236,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.0; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:78:17 @@ -244,7 +244,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.2; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:81:14 @@ -252,7 +252,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | (_, | ^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:83:14 @@ -260,7 +260,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | _) | ^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:91:13 @@ -268,7 +268,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | inherit: 1, | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:93:13 @@ -276,7 +276,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override2: 3, | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:96:17 @@ -284,7 +284,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.inherit; | ^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:98:17 @@ -292,7 +292,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.override2; | ^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:101:13 @@ -300,7 +300,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | inherit: _, | ^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:103:13 @@ -308,7 +308,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | override2: _ | ^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:112:17 @@ -316,7 +316,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.0; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:114:17 @@ -324,7 +324,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = x.2; | ^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:117:14 @@ -332,7 +332,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | (_, | ^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability-fields.rs:119:14 @@ -340,7 +340,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | _) | ^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to 43 previous errors diff --git a/src/test/ui/lint/lint-stability.stderr b/src/test/ui/lint/lint-stability.stderr index dd7f718253..167140ef92 100644 --- a/src/test/ui/lint/lint-stability.stderr +++ b/src/test/ui/lint/lint-stability.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | extern crate stability_cfg2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:45:9 @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:47:9 @@ -20,7 +20,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:49:9 @@ -28,7 +28,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:52:9 @@ -36,7 +36,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:54:9 @@ -44,7 +44,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:56:9 @@ -52,7 +52,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:59:9 @@ -60,7 +60,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | unstable(); | ^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:60:9 @@ -68,7 +68,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Trait::trait_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:61:9 @@ -76,7 +76,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability.rs:63:9 @@ -84,7 +84,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | unstable_text(); | ^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability.rs:65:9 @@ -92,7 +92,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | Trait::trait_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability.rs:67:9 @@ -100,7 +100,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | ::trait_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:99:17 @@ -108,7 +108,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:103:17 @@ -116,7 +116,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = UnstableStruct { i: 0 }; | ^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:107:17 @@ -124,7 +124,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:109:17 @@ -132,7 +132,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = UnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:113:17 @@ -140,7 +140,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:115:17 @@ -148,7 +148,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = Enum::UnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:119:17 @@ -156,7 +156,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:121:17 @@ -164,7 +164,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = UnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:130:25 @@ -172,7 +172,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:144:9 @@ -180,7 +180,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:146:9 @@ -188,7 +188,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:148:9 @@ -196,7 +196,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:150:9 @@ -204,7 +204,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:152:9 @@ -212,7 +212,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | Trait::trait_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:153:9 @@ -220,7 +220,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | ::trait_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability.rs:154:9 @@ -228,7 +228,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | Trait::trait_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': text --> $DIR/lint-stability.rs:156:9 @@ -236,7 +236,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature': text LL | ::trait_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:172:10 @@ -244,7 +244,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | impl UnstableTrait for S { } | ^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:174:24 @@ -252,7 +252,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | trait LocalTrait : UnstableTrait { } | ^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:179:9 @@ -260,7 +260,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | fn trait_unstable(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:184:5 @@ -268,7 +268,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | extern crate inherited_stability; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:185:9 @@ -276,7 +276,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | use self::inherited_stability::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:188:9 @@ -284,7 +284,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | unstable(); | ^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:191:9 @@ -292,7 +292,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | stable_mod::unstable(); | ^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:195:9 @@ -300,7 +300,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | unstable_mod::unstable(); | ^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:197:17 @@ -308,7 +308,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | let _ = Unstable::UnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:88:48 @@ -316,7 +316,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | struct S1(T::TypeUnstable); | ^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/lint-stability.rs:92:13 @@ -324,7 +324,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | TypeUnstable = u8, | ^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to 41 previous errors diff --git a/src/test/ui/lint/lint-unexported-no-mangle.rs b/src/test/ui/lint/lint-unexported-no-mangle.rs index 5945c90023..f260fc3230 100644 --- a/src/test/ui/lint/lint-unexported-no-mangle.rs +++ b/src/test/ui/lint/lint-unexported-no-mangle.rs @@ -6,10 +6,10 @@ fn foo() { #[allow(dead_code)] #[no_mangle] -const FOO: u64 = 1; //~ ERROR const items should never be #[no_mangle] +const FOO: u64 = 1; //~ ERROR const items should never be `#[no_mangle]` #[no_mangle] -pub const PUB_FOO: u64 = 1; //~ ERROR const items should never be #[no_mangle] +pub const PUB_FOO: u64 = 1; //~ ERROR const items should never be `#[no_mangle]` #[no_mangle] pub fn bar() { diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr index 586ee8ed41..c2cbf5feaa 100644 --- a/src/test/ui/lint/lint-unexported-no-mangle.stderr +++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr @@ -1,12 +1,12 @@ -warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported` +warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, `#[no_mangle]` functions always exported` | = note: requested on the command line with `-F private_no_mangle_fns` -warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported` +warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, `#[no_mangle]` statics always exported` | = note: requested on the command line with `-F private_no_mangle_statics` -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> $DIR/lint-unexported-no-mangle.rs:9:1 | LL | const FOO: u64 = 1; @@ -16,7 +16,7 @@ LL | const FOO: u64 = 1; | = note: requested on the command line with `-F no-mangle-const-items` -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> $DIR/lint-unexported-no-mangle.rs:12:1 | LL | pub const PUB_FOO: u64 = 1; diff --git a/src/test/ui/lint/lint-unknown-feature-default.rs b/src/test/ui/lint/lint-unknown-feature-default.rs index e04363faf4..aebc4f1808 100644 --- a/src/test/ui/lint/lint-unknown-feature-default.rs +++ b/src/test/ui/lint/lint-unknown-feature-default.rs @@ -4,7 +4,7 @@ // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { } diff --git a/src/test/ui/lint/lint-unknown-feature.rs b/src/test/ui/lint/lint-unknown-feature.rs index c372a980be..93fa7a6e96 100644 --- a/src/test/ui/lint/lint-unknown-feature.rs +++ b/src/test/ui/lint/lint-unknown-feature.rs @@ -4,7 +4,7 @@ // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/lint/lint-unnecessary-parens.rs b/src/test/ui/lint/lint-unnecessary-parens.rs index c36101043a..811bc87eb0 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.rs +++ b/src/test/ui/lint/lint-unnecessary-parens.rs @@ -19,6 +19,7 @@ fn main() { if (true) {} //~ ERROR unnecessary parentheses around `if` condition while (true) {} //~ ERROR unnecessary parentheses around `while` condition + //~^ WARN denote infinite loops with match (true) { //~ ERROR unnecessary parentheses around `match` head expression _ => {} } diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr index dfbefd7b03..83b247a4a6 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.stderr +++ b/src/test/ui/lint/lint-unnecessary-parens.stderr @@ -34,44 +34,52 @@ error: unnecessary parentheses around `while` condition LL | while (true) {} | ^^^^^^ help: remove these parentheses +warning: denote infinite loops with `loop { ... }` + --> $DIR/lint-unnecessary-parens.rs:21:5 + | +LL | while (true) {} + | ^^^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + error: unnecessary parentheses around `match` head expression - --> $DIR/lint-unnecessary-parens.rs:22:11 + --> $DIR/lint-unnecessary-parens.rs:23:11 | LL | match (true) { | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression - --> $DIR/lint-unnecessary-parens.rs:25:16 + --> $DIR/lint-unnecessary-parens.rs:26:16 | LL | if let 1 = (1) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around `let` head expression - --> $DIR/lint-unnecessary-parens.rs:26:19 + --> $DIR/lint-unnecessary-parens.rs:27:19 | LL | while let 1 = (2) {} | ^^^ help: remove these parentheses error: unnecessary parentheses around method argument - --> $DIR/lint-unnecessary-parens.rs:40:24 + --> $DIR/lint-unnecessary-parens.rs:41:24 | LL | X { y: false }.foo((true)); | ^^^^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:42:18 + --> $DIR/lint-unnecessary-parens.rs:43:18 | LL | let mut _a = (0); | ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:43:10 + --> $DIR/lint-unnecessary-parens.rs:44:10 | LL | _a = (0); | ^^^ help: remove these parentheses error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:44:11 + --> $DIR/lint-unnecessary-parens.rs:45:11 | LL | _a += (1); | ^^^ help: remove these parentheses diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs index 78609a6e24..2957f93111 100644 --- a/src/test/ui/lint/lint-unused-mut-variables.rs +++ b/src/test/ui/lint/lint-unused-mut-variables.rs @@ -1,12 +1,70 @@ +// edition:2018 + // Exercise the unused_mut attribute in some positive and negative cases -#![allow(unused_assignments)] -#![allow(unused_variables)] -#![allow(dead_code)] #![deny(unused_mut)] +#![feature(async_await, async_closure, param_attrs)] + +async fn baz_async( + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, +) {} +fn baz( + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) +) {} + +struct RefStruct {} +impl RefStruct { + async fn baz_async( + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + ) {} + fn baz( + &self, + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} +trait RefTrait { + fn baz( + &self, + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} +impl RefTrait for () { + fn baz( + &self, + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} fn main() { + let _ = async move | + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + | {}; + let _ = | + mut a: i32, + //~^ ERROR: variable does not need to be mutable + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + | {}; + // negative cases let mut a = 3; //~ ERROR: variable does not need to be mutable diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/lint-unused-mut-variables.stderr index 1a175c9683..92c2b68652 100644 --- a/src/test/ui/lint/lint-unused-mut-variables.stderr +++ b/src/test/ui/lint/lint-unused-mut-variables.stderr @@ -1,19 +1,83 @@ error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:46:14 + --> $DIR/lint-unused-mut-variables.rs:9:5 | -LL | let x = |mut y: isize| 10; - | ----^ - | | - | help: remove this `mut` +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` | note: lint level defined here - --> $DIR/lint-unused-mut-variables.rs:6:9 + --> $DIR/lint-unused-mut-variables.rs:5:9 | LL | #![deny(unused_mut)] | ^^^^^^^^^^ error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:11:9 + --> $DIR/lint-unused-mut-variables.rs:14:5 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:23:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:29:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:39:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:48:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:57:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:62:9 + | +LL | mut a: i32, + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:104:14 + | +LL | let x = |mut y: isize| 10; + | ----^ + | | + | help: remove this `mut` + +error: variable does not need to be mutable + --> $DIR/lint-unused-mut-variables.rs:69:9 | LL | let mut a = 3; | ----^ @@ -21,7 +85,7 @@ LL | let mut a = 3; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:13:9 + --> $DIR/lint-unused-mut-variables.rs:71:9 | LL | let mut a = 2; | ----^ @@ -29,7 +93,7 @@ LL | let mut a = 2; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:15:9 + --> $DIR/lint-unused-mut-variables.rs:73:9 | LL | let mut b = 3; | ----^ @@ -37,7 +101,7 @@ LL | let mut b = 3; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:17:9 + --> $DIR/lint-unused-mut-variables.rs:75:9 | LL | let mut a = vec![3]; | ----^ @@ -45,7 +109,7 @@ LL | let mut a = vec![3]; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:19:10 + --> $DIR/lint-unused-mut-variables.rs:77:10 | LL | let (mut a, b) = (1, 2); | ----^ @@ -53,7 +117,7 @@ LL | let (mut a, b) = (1, 2); | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:21:9 + --> $DIR/lint-unused-mut-variables.rs:79:9 | LL | let mut a; | ----^ @@ -61,7 +125,7 @@ LL | let mut a; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:25:9 + --> $DIR/lint-unused-mut-variables.rs:83:9 | LL | let mut b; | ----^ @@ -69,7 +133,7 @@ LL | let mut b; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:34:9 + --> $DIR/lint-unused-mut-variables.rs:92:9 | LL | mut x => {} | ----^ @@ -77,7 +141,7 @@ LL | mut x => {} | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:38:8 + --> $DIR/lint-unused-mut-variables.rs:96:8 | LL | (mut x, 1) | | ----^ @@ -85,7 +149,7 @@ LL | (mut x, 1) | | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:51:9 + --> $DIR/lint-unused-mut-variables.rs:109:9 | LL | let mut a = &mut 5; | ----^ @@ -93,7 +157,7 @@ LL | let mut a = &mut 5; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:56:9 + --> $DIR/lint-unused-mut-variables.rs:114:9 | LL | let mut b = (&mut a,); | ----^ @@ -101,7 +165,7 @@ LL | let mut b = (&mut a,); | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:59:9 + --> $DIR/lint-unused-mut-variables.rs:117:9 | LL | let mut x = &mut 1; | ----^ @@ -109,7 +173,7 @@ LL | let mut x = &mut 1; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:71:9 + --> $DIR/lint-unused-mut-variables.rs:129:9 | LL | let mut v : &mut Vec<()> = &mut vec![]; | ----^ @@ -117,7 +181,7 @@ LL | let mut v : &mut Vec<()> = &mut vec![]; | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:48:13 + --> $DIR/lint-unused-mut-variables.rs:106:13 | LL | fn what(mut foo: isize) {} | ----^^^ @@ -125,7 +189,7 @@ LL | fn what(mut foo: isize) {} | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:66:20 + --> $DIR/lint-unused-mut-variables.rs:124:20 | LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { | ----^^^ @@ -133,7 +197,7 @@ LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:138:9 + --> $DIR/lint-unused-mut-variables.rs:196:9 | LL | let mut b = vec![2]; | ----^ @@ -141,10 +205,10 @@ LL | let mut b = vec![2]; | help: remove this `mut` | note: lint level defined here - --> $DIR/lint-unused-mut-variables.rs:134:8 + --> $DIR/lint-unused-mut-variables.rs:192:8 | LL | #[deny(unused_mut)] | ^^^^^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 25 previous errors diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs new file mode 100644 index 0000000000..a1660d2351 --- /dev/null +++ b/src/test/ui/lint/lint-unused-variables.rs @@ -0,0 +1,64 @@ +// compile-flags: --cfg something +// edition:2018 + +#![feature(async_await, async_closure, param_attrs)] +#![deny(unused_variables)] + +async fn foo_async( + a: i32, + //~^ ERROR unused variable: `a` + #[allow(unused_variables)] b: i32, +) {} +fn foo( + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` +) {} + +struct RefStruct {} +impl RefStruct { + async fn bar_async( + &self, + a: i32, + //~^ ERROR unused variable: `a` + #[allow(unused_variables)] b: i32, + ) {} + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} +} +trait RefTrait { + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} +} +impl RefTrait for RefStruct { + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + ) {} +} + +fn main() { + let _: fn(_, _) = foo; + let a = async move | + a: i32, + //~^ ERROR unused variable: `a` + #[allow(unused_variables)] b: i32, + | {}; + let b = | + #[allow(unused_variables)] a: i32, + b: i32, + //~^ ERROR unused variable: `b` + | {}; + let _ = a(1, 2); + let _ = b(1, 2); +} diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/lint-unused-variables.stderr new file mode 100644 index 0000000000..7ed5669e33 --- /dev/null +++ b/src/test/ui/lint/lint-unused-variables.stderr @@ -0,0 +1,56 @@ +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:8:5 + | +LL | a: i32, + | ^ help: consider prefixing with an underscore: `_a` + | +note: lint level defined here + --> $DIR/lint-unused-variables.rs:5:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:14:5 + | +LL | b: i32, + | ^ help: consider prefixing with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:53:9 + | +LL | a: i32, + | ^ help: consider prefixing with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:59:9 + | +LL | b: i32, + | ^ help: consider prefixing with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:37:9 + | +LL | b: i32, + | ^ help: consider prefixing with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:22:9 + | +LL | a: i32, + | ^ help: consider prefixing with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:29:9 + | +LL | b: i32, + | ^ help: consider prefixing with an underscore: `_b` + +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:45:9 + | +LL | b: i32, + | ^ help: consider prefixing with an underscore: `_b` + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index 40c13231c1..9ea3795f89 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -15,7 +15,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unused_variables)] implied by #[warn(unused)] + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` error: structure field `X` should have a snake case name --> $DIR/lint-uppercase-variables.rs:10:5 diff --git a/src/test/ui/lint/lints-in-foreign-macros.rs b/src/test/ui/lint/lints-in-foreign-macros.rs index adef2f9e76..e381c81453 100644 --- a/src/test/ui/lint/lints-in-foreign-macros.rs +++ b/src/test/ui/lint/lints-in-foreign-macros.rs @@ -1,5 +1,5 @@ // aux-build:lints-in-foreign-macros.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_imports)] //~ missing documentation for crate [missing_docs] #![warn(missing_docs)] diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/must-use-ops.rs index 60baa23498..d0adf6a875 100644 --- a/src/test/ui/lint/must-use-ops.rs +++ b/src/test/ui/lint/must-use-ops.rs @@ -1,6 +1,6 @@ // Issue #50124 - Test warning for unused operator expressions -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/lint/not_found.rs b/src/test/ui/lint/not_found.rs index 0b5a4eb785..979a67b155 100644 --- a/src/test/ui/lint/not_found.rs +++ b/src/test/ui/lint/not_found.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // this tests the `unknown_lint` lint, especially the suggestions diff --git a/src/test/ui/lint/not_found.stderr b/src/test/ui/lint/not_found.stderr index 266cf10af8..70d49a4e69 100644 --- a/src/test/ui/lint/not_found.stderr +++ b/src/test/ui/lint/not_found.stderr @@ -4,7 +4,7 @@ warning: unknown lint: `FOO_BAR` LL | #[allow(FOO_BAR)] | ^^^^^^^ | - = note: #[warn(unknown_lints)] on by default + = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `DEAD_CODE` --> $DIR/not_found.rs:8:8 diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs index 84db885ac0..21c2ddd5ef 100644 --- a/src/test/ui/lint/reasons-erroneous.rs +++ b/src/test/ui/lint/reasons-erroneous.rs @@ -23,6 +23,6 @@ //~| NOTE reason in lint attribute must come last #![warn(missing_copy_implementations, reason)] //~^ WARN unknown lint -//~| NOTE #[warn(unknown_lints)] on by default +//~| NOTE `#[warn(unknown_lints)]` on by default fn main() {} diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr index ff4a0f36bb..3f925f19ef 100644 --- a/src/test/ui/lint/reasons-erroneous.stderr +++ b/src/test/ui/lint/reasons-erroneous.stderr @@ -46,7 +46,7 @@ warning: unknown lint: `reason` LL | #![warn(missing_copy_implementations, reason)] | ^^^^^^ | - = note: #[warn(unknown_lints)] on by default + = note: `#[warn(unknown_lints)]` on by default error: aborting due to 7 previous errors diff --git a/src/test/ui/lint/reasons.rs b/src/test/ui/lint/reasons.rs index eba91d92af..5320987040 100644 --- a/src/test/ui/lint/reasons.rs +++ b/src/test/ui/lint/reasons.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(lint_reasons)] diff --git a/src/test/ui/lint/reasons.stderr b/src/test/ui/lint/reasons.stderr index 3bb1480a30..cb5f4ddf47 100644 --- a/src/test/ui/lint/reasons.stderr +++ b/src/test/ui/lint/reasons.stderr @@ -24,5 +24,5 @@ note: lint level defined here | LL | nonstandard_style, | ^^^^^^^^^^^^^^^^^ - = note: #[warn(non_snake_case)] implied by #[warn(nonstandard_style)] + = note: `#[warn(non_snake_case)]` implied by `#[warn(nonstandard_style)]` diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs new file mode 100644 index 0000000000..057329a0a6 --- /dev/null +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs @@ -0,0 +1,11 @@ +#![feature(non_ascii_idents)] +#![deny(non_ascii_idents)] + +const חלודה: usize = 2; //~ ERROR identifier contains non-ASCII characters + +fn coöperation() {} //~ ERROR identifier contains non-ASCII characters + +fn main() { + let naïveté = 2; //~ ERROR identifier contains non-ASCII characters + println!("{}", naïveté); //~ ERROR identifier contains non-ASCII characters +} diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr new file mode 100644 index 0000000000..56925846e9 --- /dev/null +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr @@ -0,0 +1,32 @@ +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:4:7 + | +LL | const חלודה: usize = 2; + | ^^^^^ + | +note: lint level defined here + --> $DIR/lint-non-ascii-idents.rs:2:9 + | +LL | #![deny(non_ascii_idents)] + | ^^^^^^^^^^^^^^^^ + +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:6:4 + | +LL | fn coöperation() {} + | ^^^^^^^^^^^ + +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:9:9 + | +LL | let naïveté = 2; + | ^^^^^^^ + +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:10:20 + | +LL | println!("{}", naïveté); + | ^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs index 67bd6dd501..aa5518d1a7 100644 --- a/src/test/ui/lint/suggestions.rs +++ b/src/test/ui/lint/suggestions.rs @@ -4,7 +4,7 @@ #![feature(no_debug)] #[no_mangle] const DISCOVERY: usize = 1; -//~^ ERROR const items should never be #[no_mangle] +//~^ ERROR const items should never be `#[no_mangle]` //~| HELP try a static value #[no_mangle] @@ -20,7 +20,7 @@ mod badlands { // item is already `pub` (but triggered the lint because, e.g., it's in a // private module). (Issue #47383) #[no_mangle] pub const DAUNTLESS: bool = true; - //~^ ERROR const items should never be #[no_mangle] + //~^ ERROR const items should never be `#[no_mangle]` //~| HELP try a static value #[no_mangle] pub fn val_jean() {} //~^ WARN functions generic over types or consts must be mangled @@ -28,7 +28,7 @@ mod badlands { // ... but we can suggest just-`pub` instead of restricted #[no_mangle] pub(crate) const VETAR: bool = true; - //~^ ERROR const items should never be #[no_mangle] + //~^ ERROR const items should never be `#[no_mangle]` //~| HELP try a static value #[no_mangle] pub(crate) fn crossfield() {} //~^ WARN functions generic over types or consts must be mangled diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index 5aaa9947f9..2042ed7553 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -1,3 +1,11 @@ +warning: denote infinite loops with `loop { ... }` + --> $DIR/suggestions.rs:46:5 + | +LL | while true { + | ^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + warning: unnecessary parentheses around assigned value --> $DIR/suggestions.rs:49:31 | @@ -16,7 +24,7 @@ warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was LL | #[no_debug] // should suggest removal of deprecated attribute | ^^^^^^^^^^^ help: remove this attribute | - = note: #[warn(deprecated)] on by default + = note: `#[warn(deprecated)]` on by default warning: variable does not need to be mutable --> $DIR/suggestions.rs:49:13 @@ -44,7 +52,7 @@ LL | || b = 1; | |____________| | help: remove this `mut` -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> $DIR/suggestions.rs:6:14 | LL | #[no_mangle] const DISCOVERY: usize = 1; @@ -52,7 +60,7 @@ LL | #[no_mangle] const DISCOVERY: usize = 1; | | | help: try a static value: `pub static` | - = note: #[deny(no_mangle_const_items)] on by default + = note: `#[deny(no_mangle_const_items)]` on by default warning: functions generic over types or consts must be mangled --> $DIR/suggestions.rs:12:1 @@ -63,15 +71,7 @@ LL | LL | pub fn defiant(_t: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(no_mangle_generic_items)] on by default - -warning: denote infinite loops with `loop { ... }` - --> $DIR/suggestions.rs:46:5 - | -LL | while true { - | ^^^^^^^^^^ help: use `loop` - | - = note: #[warn(while_true)] on by default + = note: `#[warn(no_mangle_generic_items)]` on by default warning: the `warp_factor:` in this pattern is redundant --> $DIR/suggestions.rs:61:23 @@ -81,9 +81,9 @@ LL | Equinox { warp_factor: warp_factor } => {} | | | help: remove this | - = note: #[warn(non_shorthand_field_patterns)] on by default + = note: `#[warn(non_shorthand_field_patterns)]` on by default -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> $DIR/suggestions.rs:22:18 | LL | #[no_mangle] pub const DAUNTLESS: bool = true; @@ -99,7 +99,7 @@ LL | #[no_mangle] pub fn val_jean() {} | | | help: remove this attribute -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> $DIR/suggestions.rs:30:18 | LL | #[no_mangle] pub(crate) const VETAR: bool = true; diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index 64e5951207..c145bd256d 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(overflowing_literals)] fn main() { diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs new file mode 100644 index 0000000000..d816479bbb --- /dev/null +++ b/src/test/ui/lint/uninitialized-zeroed.rs @@ -0,0 +1,66 @@ +// ignore-tidy-linelength +// This test checks that calling `mem::{uninitialized,zeroed}` with certain types results +// in a lint. + +#![feature(never_type)] +#![allow(deprecated)] +#![deny(invalid_value)] + +use std::mem::{self, MaybeUninit}; + +enum Void {} + +struct Ref(&'static i32); +struct RefPair((&'static i32, i32)); + +struct Wrap { wrapped: T } +enum WrapEnum { Wrapped(T) } + +#[allow(unused)] +fn generic() { + unsafe { + let _val: &'static T = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: &'static T = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: Wrap<&'static T> = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: Wrap<&'static T> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + } +} + +fn main() { + unsafe { + let _val: ! = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: ! = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: (i32, !) = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: (i32, !) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: Void = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: Void = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: &'static i32 = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: &'static i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: Ref = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: Ref = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: fn() = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: fn() = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: Wrap = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: Wrap = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: WrapEnum = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: WrapEnum = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + let _val: Wrap<(RefPair, i32)> = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + + // Some types that should work just fine. + let _val: Option<&'static i32> = mem::zeroed(); + let _val: Option = mem::zeroed(); + let _val: MaybeUninit<&'static i32> = mem::zeroed(); + let _val: bool = mem::zeroed(); + let _val: i32 = mem::zeroed(); + } +} diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr new file mode 100644 index 0000000000..1b15fc2152 --- /dev/null +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -0,0 +1,289 @@ +error: the type `&'static T` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:22:32 + | +LL | let _val: &'static T = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: lint level defined here + --> $DIR/uninitialized-zeroed.rs:7:9 + | +LL | #![deny(invalid_value)] + | ^^^^^^^^^^^^^ + = note: References must be non-null + +error: the type `&'static T` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:23:32 + | +LL | let _val: &'static T = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: References must be non-null + +error: the type `Wrap<&'static T>` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:25:38 + | +LL | let _val: Wrap<&'static T> = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: References must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:16:18 + | +LL | struct Wrap { wrapped: T } + | ^^^^^^^^^^ + +error: the type `Wrap<&'static T>` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:26:38 + | +LL | let _val: Wrap<&'static T> = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: References must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:16:18 + | +LL | struct Wrap { wrapped: T } + | ^^^^^^^^^^ + +error: the type `!` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:32:23 + | +LL | let _val: ! = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: The never type (`!`) has no valid value + +error: the type `!` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:33:23 + | +LL | let _val: ! = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: The never type (`!`) has no valid value + +error: the type `(i32, !)` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:35:30 + | +LL | let _val: (i32, !) = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: The never type (`!`) has no valid value + +error: the type `(i32, !)` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:36:30 + | +LL | let _val: (i32, !) = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: The never type (`!`) has no valid value + +error: the type `Void` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:38:26 + | +LL | let _val: Void = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: 0-variant enums have no valid value + +error: the type `Void` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:39:26 + | +LL | let _val: Void = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: 0-variant enums have no valid value + +error: the type `&'static i32` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:41:34 + | +LL | let _val: &'static i32 = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: References must be non-null + +error: the type `&'static i32` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:42:34 + | +LL | let _val: &'static i32 = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: References must be non-null + +error: the type `Ref` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:44:25 + | +LL | let _val: Ref = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: References must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:13:12 + | +LL | struct Ref(&'static i32); + | ^^^^^^^^^^^^ + +error: the type `Ref` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:45:25 + | +LL | let _val: Ref = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: References must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:13:12 + | +LL | struct Ref(&'static i32); + | ^^^^^^^^^^^^ + +error: the type `fn()` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:47:26 + | +LL | let _val: fn() = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: Function pointers must be non-null + +error: the type `fn()` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:48:26 + | +LL | let _val: fn() = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | + = note: Function pointers must be non-null + +error: the type `Wrap` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:50:32 + | +LL | let _val: Wrap = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: Function pointers must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:16:18 + | +LL | struct Wrap { wrapped: T } + | ^^^^^^^^^^ + +error: the type `Wrap` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:51:32 + | +LL | let _val: Wrap = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: Function pointers must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:16:18 + | +LL | struct Wrap { wrapped: T } + | ^^^^^^^^^^ + +error: the type `WrapEnum` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:53:36 + | +LL | let _val: WrapEnum = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: Function pointers must be non-null (in this enum field) + --> $DIR/uninitialized-zeroed.rs:17:28 + | +LL | enum WrapEnum { Wrapped(T) } + | ^ + +error: the type `WrapEnum` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:54:36 + | +LL | let _val: WrapEnum = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: Function pointers must be non-null (in this enum field) + --> $DIR/uninitialized-zeroed.rs:17:28 + | +LL | enum WrapEnum { Wrapped(T) } + | ^ + +error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization + --> $DIR/uninitialized-zeroed.rs:56:42 + | +LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: References must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:14:16 + | +LL | struct RefPair((&'static i32, i32)); + | ^^^^^^^^^^^^^^^^^^^ + +error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized + --> $DIR/uninitialized-zeroed.rs:57:42 + | +LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead + | +note: References must be non-null (in this struct field) + --> $DIR/uninitialized-zeroed.rs:14:16 + | +LL | struct RefPair((&'static i32, i32)); + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 22 previous errors + diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.rs b/src/test/ui/lint/unreachable_pub-pub_crate.rs index 6739c7f096..27b437b22e 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.rs +++ b/src/test/ui/lint/unreachable_pub-pub_crate.rs @@ -4,7 +4,7 @@ // suggestions to use `crate` given when it is on). When that feature becomes // stable, this test can be deleted. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] diff --git a/src/test/ui/lint/unreachable_pub.rs b/src/test/ui/lint/unreachable_pub.rs index 12726b6eca..545281604e 100644 --- a/src/test/ui/lint/unreachable_pub.rs +++ b/src/test/ui/lint/unreachable_pub.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(crate_visibility_modifier)] diff --git a/src/test/ui/lint/unused_import_warning_issue_45268.rs b/src/test/ui/lint/unused_import_warning_issue_45268.rs index 0bd7751113..68a5819c9c 100644 --- a/src/test/ui/lint/unused_import_warning_issue_45268.rs +++ b/src/test/ui/lint/unused_import_warning_issue_45268.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_imports)] // Warning explanation here, it's OK diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index 26ab9fbe5c..d234a2fb1a 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -2,7 +2,7 @@ // should also deal with the edge cases where a label is shadowed, // within nested loops -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(label_break_value)] #![warn(unused_labels)] diff --git a/src/test/ui/lint/unused_parens_json_suggestion.fixed b/src/test/ui/lint/unused_parens_json_suggestion.fixed new file mode 100644 index 0000000000..4274071191 --- /dev/null +++ b/src/test/ui/lint/unused_parens_json_suggestion.fixed @@ -0,0 +1,27 @@ +// compile-flags: --error-format pretty-json -Zunstable-options +// build-pass (FIXME(62277): could be check-pass?) +// run-rustfix + +// The output for humans should just highlight the whole span without showing +// the suggested replacement, but we also want to test that suggested +// replacement only removes one set of parentheses, rather than naïvely +// stripping away any starting or ending parenthesis characters—hence this +// test of the JSON error format. + +#![warn(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not + // the malformed `1 / (2 + 3` + let _a = 1 / (2 + 3); + f(); +} + +fn f() -> bool { + loop { + if (break { return true }) { + } + } + false +} diff --git a/src/test/ui/lint/unused_parens_json_suggestion.rs b/src/test/ui/lint/unused_parens_json_suggestion.rs index 4462c53152..8719250398 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_json_suggestion.rs @@ -1,5 +1,6 @@ // compile-flags: --error-format pretty-json -Zunstable-options -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// run-rustfix // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested @@ -8,6 +9,7 @@ // test of the JSON error format. #![warn(unused_parens)] +#![allow(unreachable_code)] fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index 07d96d5c48..256c7555c9 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -8,10 +8,10 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 576, - "byte_end": 589, - "line_start": 15, - "line_end": 15, + "byte_start": 654, + "byte_end": 667, + "line_start": 17, + "line_end": 17, "column_start": 14, "column_end": 27, "is_primary": true, @@ -36,10 +36,10 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 422, - "byte_end": 435, - "line_start": 10, - "line_end": 10, + "byte_start": 472, + "byte_end": 485, + "line_start": 11, + "line_end": 11, "column_start": 9, "column_end": 22, "is_primary": true, @@ -66,10 +66,10 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 576, - "byte_end": 589, - "line_start": 15, - "line_end": 15, + "byte_start": 654, + "byte_end": 667, + "line_start": 17, + "line_end": 17, "column_start": 14, "column_end": 27, "is_primary": true, @@ -91,13 +91,13 @@ } ], "rendered": "warning: unnecessary parentheses around assigned value - --> $DIR/unused_parens_json_suggestion.rs:15:14 + --> $DIR/unused_parens_json_suggestion.rs:17:14 | LL | let _a = (1 / (2 + 3)); | ^^^^^^^^^^^^^ help: remove these parentheses | note: lint level defined here - --> $DIR/unused_parens_json_suggestion.rs:10:9 + --> $DIR/unused_parens_json_suggestion.rs:11:9 | LL | #![warn(unused_parens)] | ^^^^^^^^^^^^^ diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed new file mode 100644 index 0000000000..2459eb1ac5 --- /dev/null +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed @@ -0,0 +1,62 @@ +// compile-flags: --error-format pretty-json -Zunstable-options +// build-pass +// run-rustfix + +// The output for humans should just highlight the whole span without showing +// the suggested replacement, but we also want to test that suggested +// replacement only removes one set of parentheses, rather than naïvely +// stripping away any starting or ending parenthesis characters—hence this +// test of the JSON error format. + +#![warn(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + + let _b = false; + + if _b { + println!("hello"); + } + + f(); + +} + +fn f() -> bool { + let c = false; + + if c { + println!("next"); + } + + if c { + println!("prev"); + } + + while false && true { + if c { + println!("norm"); + } + + } + + while true && false { + for _ in 0 .. 3 { + println!("e~") + } + } + + for _ in 0 .. 3 { + while true && false { + println!("e~") + } + } + + + loop { + if (break { return true }) { + } + } + false +} diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs new file mode 100644 index 0000000000..0e9869b67d --- /dev/null +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs @@ -0,0 +1,62 @@ +// compile-flags: --error-format pretty-json -Zunstable-options +// build-pass +// run-rustfix + +// The output for humans should just highlight the whole span without showing +// the suggested replacement, but we also want to test that suggested +// replacement only removes one set of parentheses, rather than naïvely +// stripping away any starting or ending parenthesis characters—hence this +// test of the JSON error format. + +#![warn(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + + let _b = false; + + if (_b) { + println!("hello"); + } + + f(); + +} + +fn f() -> bool { + let c = false; + + if(c) { + println!("next"); + } + + if (c){ + println!("prev"); + } + + while (false && true){ + if (c) { + println!("norm"); + } + + } + + while(true && false) { + for _ in (0 .. 3){ + println!("e~") + } + } + + for _ in (0 .. 3) { + while (true && false) { + println!("e~") + } + } + + + loop { + if (break { return true }) { + } + } + false +} diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr new file mode 100644 index 0000000000..b4eab200dd --- /dev/null +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -0,0 +1,666 @@ +{ + "message": "unnecessary parentheses around `if` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 521, + "byte_end": 525, + "line_start": 18, + "line_end": 18, + "column_start": 8, + "column_end": 12, + "is_primary": true, + "text": [ + { + "text": " if (_b) {", + "highlight_start": 8, + "highlight_end": 12 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "lint level defined here", + "code": null, + "level": "note", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 435, + "byte_end": 448, + "line_start": 11, + "line_end": 11, + "column_start": 9, + "column_end": 22, + "is_primary": true, + "text": [ + { + "text": "#![warn(unused_parens)]", + "highlight_start": 9, + "highlight_end": 22 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [], + "rendered": null + }, + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 521, + "byte_end": 525, + "line_start": 18, + "line_end": 18, + "column_start": 8, + "column_end": 12, + "is_primary": true, + "text": [ + { + "text": " if (_b) {", + "highlight_start": 8, + "highlight_end": 12 + } + ], + "label": null, + "suggested_replacement": "_b", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:18:8 + | +LL | if (_b) { + | ^^^^ help: remove these parentheses + | +note: lint level defined here + --> $DIR/unused_parens_remove_json_suggestion.rs:11:9 + | +LL | #![warn(unused_parens)] + | ^^^^^^^^^^^^^ + +" +} +{ + "message": "unnecessary parentheses around `if` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 618, + "byte_end": 621, + "line_start": 29, + "line_end": 29, + "column_start": 7, + "column_end": 10, + "is_primary": true, + "text": [ + { + "text": " if(c) {", + "highlight_start": 7, + "highlight_end": 10 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 618, + "byte_end": 621, + "line_start": 29, + "line_end": 29, + "column_start": 7, + "column_end": 10, + "is_primary": true, + "text": [ + { + "text": " if(c) {", + "highlight_start": 7, + "highlight_end": 10 + } + ], + "label": null, + "suggested_replacement": " c", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:29:7 + | +LL | if(c) { + | ^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `if` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 664, + "byte_end": 667, + "line_start": 33, + "line_end": 33, + "column_start": 8, + "column_end": 11, + "is_primary": true, + "text": [ + { + "text": " if (c){", + "highlight_start": 8, + "highlight_end": 11 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 664, + "byte_end": 667, + "line_start": 33, + "line_end": 33, + "column_start": 8, + "column_end": 11, + "is_primary": true, + "text": [ + { + "text": " if (c){", + "highlight_start": 8, + "highlight_end": 11 + } + ], + "label": null, + "suggested_replacement": "c ", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:33:8 + | +LL | if (c){ + | ^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `while` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 712, + "byte_end": 727, + "line_start": 37, + "line_end": 37, + "column_start": 11, + "column_end": 26, + "is_primary": true, + "text": [ + { + "text": " while (false && true){", + "highlight_start": 11, + "highlight_end": 26 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 712, + "byte_end": 727, + "line_start": 37, + "line_end": 37, + "column_start": 11, + "column_end": 26, + "is_primary": true, + "text": [ + { + "text": " while (false && true){", + "highlight_start": 11, + "highlight_end": 26 + } + ], + "label": null, + "suggested_replacement": "false && true ", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `while` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:37:11 + | +LL | while (false && true){ + | ^^^^^^^^^^^^^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `if` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 740, + "byte_end": 743, + "line_start": 38, + "line_end": 38, + "column_start": 12, + "column_end": 15, + "is_primary": true, + "text": [ + { + "text": " if (c) {", + "highlight_start": 12, + "highlight_end": 15 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 740, + "byte_end": 743, + "line_start": 38, + "line_end": 38, + "column_start": 12, + "column_end": 15, + "is_primary": true, + "text": [ + { + "text": " if (c) {", + "highlight_start": 12, + "highlight_end": 15 + } + ], + "label": null, + "suggested_replacement": "c", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:38:12 + | +LL | if (c) { + | ^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `while` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 803, + "byte_end": 818, + "line_start": 44, + "line_end": 44, + "column_start": 10, + "column_end": 25, + "is_primary": true, + "text": [ + { + "text": " while(true && false) {", + "highlight_start": 10, + "highlight_end": 25 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 803, + "byte_end": 818, + "line_start": 44, + "line_end": 44, + "column_start": 10, + "column_end": 25, + "is_primary": true, + "text": [ + { + "text": " while(true && false) {", + "highlight_start": 10, + "highlight_end": 25 + } + ], + "label": null, + "suggested_replacement": " true && false", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `while` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:44:10 + | +LL | while(true && false) { + | ^^^^^^^^^^^^^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `for` head expression", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 838, + "byte_end": 846, + "line_start": 45, + "line_end": 45, + "column_start": 18, + "column_end": 26, + "is_primary": true, + "text": [ + { + "text": " for _ in (0 .. 3){", + "highlight_start": 18, + "highlight_end": 26 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 838, + "byte_end": 846, + "line_start": 45, + "line_end": 45, + "column_start": 18, + "column_end": 26, + "is_primary": true, + "text": [ + { + "text": " for _ in (0 .. 3){", + "highlight_start": 18, + "highlight_end": 26 + } + ], + "label": null, + "suggested_replacement": "0 .. 3 ", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `for` head expression + --> $DIR/unused_parens_remove_json_suggestion.rs:45:18 + | +LL | for _ in (0 .. 3){ + | ^^^^^^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `for` head expression", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 905, + "byte_end": 913, + "line_start": 50, + "line_end": 50, + "column_start": 14, + "column_end": 22, + "is_primary": true, + "text": [ + { + "text": " for _ in (0 .. 3) {", + "highlight_start": 14, + "highlight_end": 22 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 905, + "byte_end": 913, + "line_start": 50, + "line_end": 50, + "column_start": 14, + "column_end": 22, + "is_primary": true, + "text": [ + { + "text": " for _ in (0 .. 3) {", + "highlight_start": 14, + "highlight_end": 22 + } + ], + "label": null, + "suggested_replacement": "0 .. 3", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `for` head expression + --> $DIR/unused_parens_remove_json_suggestion.rs:50:14 + | +LL | for _ in (0 .. 3) { + | ^^^^^^^^ help: remove these parentheses + +" +} +{ + "message": "unnecessary parentheses around `while` condition", + "code": { + "code": "unused_parens", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 930, + "byte_end": 945, + "line_start": 51, + "line_end": 51, + "column_start": 15, + "column_end": 30, + "is_primary": true, + "text": [ + { + "text": " while (true && false) {", + "highlight_start": 15, + "highlight_end": 30 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "remove these parentheses", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", + "byte_start": 930, + "byte_end": 945, + "line_start": 51, + "line_end": 51, + "column_start": 15, + "column_end": 30, + "is_primary": true, + "text": [ + { + "text": " while (true && false) {", + "highlight_start": 15, + "highlight_end": 30 + } + ], + "label": null, + "suggested_replacement": "true && false", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unnecessary parentheses around `while` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:51:15 + | +LL | while (true && false) { + | ^^^^^^^^^^^^^^^ help: remove these parentheses + +" +} diff --git a/src/test/ui/lint/use-redundant.rs b/src/test/ui/lint/use-redundant.rs index 328f8232ba..6ec2af0680 100644 --- a/src/test/ui/lint/use-redundant.rs +++ b/src/test/ui/lint/use-redundant.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_imports)] use crate::foo::Bar; //~ WARNING first import diff --git a/src/test/ui/lint/use_suggestion_json.rs b/src/test/ui/lint/use_suggestion_json.rs index 9679ce4a2a..1828b8c2dc 100644 --- a/src/test/ui/lint/use_suggestion_json.rs +++ b/src/test/ui/lint/use_suggestion_json.rs @@ -1,6 +1,6 @@ // ignore-cloudabi // ignore-windows -// compile-flags: --error-format pretty-json -Zunstable-options --json-rendered=termcolor +// compile-flags: --error-format pretty-json --json=diagnostic-rendered-ansi // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index 632666db75..c7c53abcf4 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -73,8 +73,8 @@ mod foo { "spans": [ { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 484, - "byte_end": 488, + "byte_start": 471, + "byte_end": 475, "line_start": 12, "line_end": 12, "column_start": 12, @@ -101,8 +101,8 @@ mod foo { "spans": [ { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -124,8 +124,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -147,8 +147,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -170,8 +170,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -193,8 +193,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -216,8 +216,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -239,8 +239,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -262,8 +262,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -285,8 +285,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -308,8 +308,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -331,8 +331,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, @@ -354,8 +354,8 @@ mod foo { }, { "file_name": "$DIR/use_suggestion_json.rs", - "byte_start": 461, - "byte_end": 461, + "byte_start": 448, + "byte_end": 448, "line_start": 11, "line_end": 11, "column_start": 1, diff --git a/src/test/run-pass/list.rs b/src/test/ui/list.rs similarity index 94% rename from src/test/run-pass/list.rs rename to src/test/ui/list.rs index 62c04bcac7..2ac5733b41 100644 --- a/src/test/run-pass/list.rs +++ b/src/test/ui/list.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/liveness-assign-imm-local-after-ret.rs b/src/test/ui/liveness-assign-imm-local-after-ret.rs similarity index 92% rename from src/test/run-pass/liveness-assign-imm-local-after-ret.rs rename to src/test/ui/liveness-assign-imm-local-after-ret.rs index 3dc27dde52..b463f4368d 100644 --- a/src/test/run-pass/liveness-assign-imm-local-after-ret.rs +++ b/src/test/ui/liveness-assign-imm-local-after-ret.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unreachable_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/liveness/liveness-forgot-ret.stderr b/src/test/ui/liveness/liveness-forgot-ret.stderr index a970b80fdb..4baf351f7e 100644 --- a/src/test/ui/liveness/liveness-forgot-ret.stderr +++ b/src/test/ui/liveness/liveness-forgot-ret.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } | - ^^^^^ expected isize, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `isize` found type `()` diff --git a/src/test/ui/liveness/liveness-missing-ret2.stderr b/src/test/ui/liveness/liveness-missing-ret2.stderr index ab7d411880..1f60560b45 100644 --- a/src/test/ui/liveness/liveness-missing-ret2.stderr +++ b/src/test/ui/liveness/liveness-missing-ret2.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { | - ^^^^^ expected isize, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `isize` found type `()` diff --git a/src/test/ui/liveness/liveness-move-in-while.rs b/src/test/ui/liveness/liveness-move-in-while.rs index 420d1311f8..9f3ebf1362 100644 --- a/src/test/ui/liveness/liveness-move-in-while.rs +++ b/src/test/ui/liveness/liveness-move-in-while.rs @@ -6,5 +6,8 @@ fn main() { loop { println!("{}", y); //~ ERROR borrow of moved value: `y` while true { while true { while true { x = y; x.clone(); } } } + //~^ WARN denote infinite loops with + //~| WARN denote infinite loops with + //~| WARN denote infinite loops with } } diff --git a/src/test/ui/liveness/liveness-move-in-while.stderr b/src/test/ui/liveness/liveness-move-in-while.stderr index e1eed1b59f..8350f2708e 100644 --- a/src/test/ui/liveness/liveness-move-in-while.stderr +++ b/src/test/ui/liveness/liveness-move-in-while.stderr @@ -1,3 +1,23 @@ +warning: denote infinite loops with `loop { ... }` + --> $DIR/liveness-move-in-while.rs:8:9 + | +LL | while true { while true { while true { x = y; x.clone(); } } } + | ^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + +warning: denote infinite loops with `loop { ... }` + --> $DIR/liveness-move-in-while.rs:8:22 + | +LL | while true { while true { while true { x = y; x.clone(); } } } + | ^^^^^^^^^^ help: use `loop` + +warning: denote infinite loops with `loop { ... }` + --> $DIR/liveness-move-in-while.rs:8:35 + | +LL | while true { while true { while true { x = y; x.clone(); } } } + | ^^^^^^^^^^ help: use `loop` + error[E0382]: borrow of moved value: `y` --> $DIR/liveness-move-in-while.rs:7:24 | diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr index a5d9734c06..2497d93daa 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -5,7 +5,7 @@ LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } | --- ^^^ - help: consider removing this semicolon | | | | | expected i32, found () - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression ... LL | test!(); | -------- in this macro invocation @@ -19,7 +19,7 @@ error[E0308]: mismatched types LL | fn no_return() -> i32 {} | --------- ^^^ expected i32, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `i32` found type `()` @@ -30,7 +30,7 @@ error[E0308]: mismatched types LL | fn bar(x: u32) -> u32 { | --- ^^^ expected u32, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | x * 2; | - help: consider removing this semicolon | @@ -43,7 +43,7 @@ error[E0308]: mismatched types LL | fn baz(x: u64) -> u32 { | --- ^^^ expected u32, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `u32` found type `()` diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr index d6077111f7..40a677c08f 100644 --- a/src/test/ui/liveness/liveness-unused.stderr +++ b/src/test/ui/liveness/liveness-unused.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unreachable_code)] implied by #[warn(unused)] + = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` error: unused variable: `x` --> $DIR/liveness-unused.rs:8:7 diff --git a/src/test/run-pass/llvm-pr32379.rs b/src/test/ui/llvm-pr32379.rs similarity index 97% rename from src/test/run-pass/llvm-pr32379.rs rename to src/test/ui/llvm-pr32379.rs index a18a5386d8..8a1f03241b 100644 --- a/src/test/run-pass/llvm-pr32379.rs +++ b/src/test/ui/llvm-pr32379.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:llvm_pr32379.rs // LLVM PR #32379 (https://bugs.llvm.org/show_bug.cgi?id=32379), which diff --git a/src/test/run-pass/log-err-phi.rs b/src/test/ui/log-err-phi.rs similarity index 84% rename from src/test/run-pass/log-err-phi.rs rename to src/test/ui/log-err-phi.rs index fd12ffe36f..c0e04d2c97 100644 --- a/src/test/run-pass/log-err-phi.rs +++ b/src/test/ui/log-err-phi.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { if false { println!("{}", "foobar"); diff --git a/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs b/src/test/ui/log-knows-the-names-of-variants-in-std.rs similarity index 97% rename from src/test/run-pass/log-knows-the-names-of-variants-in-std.rs rename to src/test/ui/log-knows-the-names-of-variants-in-std.rs index 3f4d1c701b..c5a40edbee 100644 --- a/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs +++ b/src/test/ui/log-knows-the-names-of-variants-in-std.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] #[derive(Clone, Debug)] diff --git a/src/test/run-pass/log-knows-the-names-of-variants.rs b/src/test/ui/log-knows-the-names-of-variants.rs similarity index 96% rename from src/test/run-pass/log-knows-the-names-of-variants.rs rename to src/test/ui/log-knows-the-names-of-variants.rs index a16ff80237..cf2876b6ee 100644 --- a/src/test/run-pass/log-knows-the-names-of-variants.rs +++ b/src/test/ui/log-knows-the-names-of-variants.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] #[derive(Debug)] diff --git a/src/test/run-pass/log-poly.rs b/src/test/ui/log-poly.rs similarity index 93% rename from src/test/run-pass/log-poly.rs rename to src/test/ui/log-poly.rs index 32dbb95a72..14e1b40e16 100644 --- a/src/test/run-pass/log-poly.rs +++ b/src/test/ui/log-poly.rs @@ -1,3 +1,5 @@ +// run-pass + #[derive(Debug)] enum Numbers { Three diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/ui/logging-only-prints-once.rs similarity index 97% rename from src/test/run-pass/logging-only-prints-once.rs rename to src/test/ui/logging-only-prints-once.rs index 1a4c4d89e7..6b49c441d1 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/ui/logging-only-prints-once.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-windows // ignore-emscripten no threads support // exec-env:RUSTC_LOG=debug diff --git a/src/test/run-pass/logging_before_rt_started.rs b/src/test/ui/logging_before_rt_started.rs similarity index 97% rename from src/test/run-pass/logging_before_rt_started.rs rename to src/test/ui/logging_before_rt_started.rs index 69cfc54c46..540d2b4f58 100644 --- a/src/test/run-pass/logging_before_rt_started.rs +++ b/src/test/ui/logging_before_rt_started.rs @@ -1,3 +1,4 @@ +// run-pass // exec-env:RUSTC_LOG=std::ptr // In issue #9487, it was realized that std::ptr was invoking the logging diff --git a/src/test/run-pass/long-while.rs b/src/test/ui/long-while.rs similarity index 93% rename from src/test/run-pass/long-while.rs rename to src/test/ui/long-while.rs index 4a3ee6f971..529cca7b73 100644 --- a/src/test/run-pass/long-while.rs +++ b/src/test/ui/long-while.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![allow(unused_variables)] diff --git a/src/test/ui/loops/loop-break-unsize.rs b/src/test/ui/loops/loop-break-unsize.rs new file mode 100644 index 0000000000..974c63cea8 --- /dev/null +++ b/src/test/ui/loops/loop-break-unsize.rs @@ -0,0 +1,8 @@ +// Regression test for #62312 +// check-pass + +fn main() { + let _ = loop { + break Box::new(()) as Box; + }; +} diff --git a/src/test/ui/loops/loop-break-value.rs b/src/test/ui/loops/loop-break-value.rs index b80c847deb..7c2f63ec51 100644 --- a/src/test/ui/loops/loop-break-value.rs +++ b/src/test/ui/loops/loop-break-value.rs @@ -23,7 +23,7 @@ fn main() { }; }; - 'while_loop: while true { + 'while_loop: while true { //~ WARN denote infinite loops with break; break (); //~ ERROR `break` with value from a `while` loop loop { diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index 13fe508554..fef5b58730 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -1,3 +1,11 @@ +warning: denote infinite loops with `loop { ... }` + --> $DIR/loop-break-value.rs:26:5 + | +LL | 'while_loop: while true { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + error[E0571]: `break` with value from a `while` loop --> $DIR/loop-break-value.rs:28:9 | @@ -82,10 +90,10 @@ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:4:31 | LL | let val: ! = loop { break break; }; - | ^^^^^ expected (), found ! + | ^^^^^ expected !, found () | - = note: expected type `()` - found type `!` + = note: expected type `!` + found type `()` error[E0308]: mismatched types --> $DIR/loop-break-value.rs:11:19 @@ -145,10 +153,13 @@ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:90:9 | LL | break; - | ^^^^^ expected (), found integer + | ^^^^^ + | | + | expected integer, found () + | help: give it a value of the expected type: `break value` | - = note: expected type `()` - found type `{integer}` + = note: expected type `{integer}` + found type `()` error: aborting due to 16 previous errors diff --git a/src/test/ui/loops/loop-labeled-break-value.stderr b/src/test/ui/loops/loop-labeled-break-value.stderr index ad7cb4b0c2..8b9468cacc 100644 --- a/src/test/ui/loops/loop-labeled-break-value.stderr +++ b/src/test/ui/loops/loop-labeled-break-value.stderr @@ -2,28 +2,37 @@ error[E0308]: mismatched types --> $DIR/loop-labeled-break-value.rs:3:29 | LL | let _: i32 = loop { break }; - | ^^^^^ expected (), found i32 + | ^^^^^ + | | + | expected i32, found () + | help: give it a value of the expected type: `break 42` | - = note: expected type `()` - found type `i32` + = note: expected type `i32` + found type `()` error[E0308]: mismatched types --> $DIR/loop-labeled-break-value.rs:6:37 | LL | let _: i32 = 'inner: loop { break 'inner }; - | ^^^^^^^^^^^^ expected (), found i32 + | ^^^^^^^^^^^^ + | | + | expected i32, found () + | help: give it a value of the expected type: `break 'inner 42` | - = note: expected type `()` - found type `i32` + = note: expected type `i32` + found type `()` error[E0308]: mismatched types --> $DIR/loop-labeled-break-value.rs:9:45 | LL | let _: i32 = 'inner2: loop { loop { break 'inner2 } }; - | ^^^^^^^^^^^^^ expected (), found i32 + | ^^^^^^^^^^^^^ + | | + | expected i32, found () + | help: give it a value of the expected type: `break 'inner2 42` | - = note: expected type `()` - found type `i32` + = note: expected type `i32` + found type `()` error: aborting due to 3 previous errors diff --git a/src/test/ui/loops/loop-properly-diverging-2.stderr b/src/test/ui/loops/loop-properly-diverging-2.stderr index 6293fdb058..3758bbf9f6 100644 --- a/src/test/ui/loops/loop-properly-diverging-2.stderr +++ b/src/test/ui/loops/loop-properly-diverging-2.stderr @@ -2,10 +2,13 @@ error[E0308]: mismatched types --> $DIR/loop-properly-diverging-2.rs:2:23 | LL | let x: i32 = loop { break }; - | ^^^^^ expected (), found i32 + | ^^^^^ + | | + | expected i32, found () + | help: give it a value of the expected type: `break 42` | - = note: expected type `()` - found type `i32` + = note: expected type `i32` + found type `()` error: aborting due to previous error diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs index 93f322ab36..316ee64072 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-tidy-linelength diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs index 27f9862f70..5ed8b2f416 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-tidy-linelength diff --git a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs b/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs index 435ad3391a..9047fbb95a 100644 --- a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs +++ b/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs @@ -1,7 +1,7 @@ // Issue #21633: reject duplicate loop labels in function bodies. // This is testing interaction between lifetime-params and labels. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, unused_variables)] diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs index 656ed6576e..9bb6a253b7 100644 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs +++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, unused_variables)] diff --git a/src/test/run-pass/lto-many-codegen-units.rs b/src/test/ui/lto-many-codegen-units.rs similarity index 86% rename from src/test/run-pass/lto-many-codegen-units.rs rename to src/test/ui/lto-many-codegen-units.rs index 17c345beb8..f0f461ffec 100644 --- a/src/test/run-pass/lto-many-codegen-units.rs +++ b/src/test/ui/lto-many-codegen-units.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -C lto -C codegen-units=8 // no-prefer-dynamic diff --git a/src/test/run-pass/lto-still-runs-thread-dtors.rs b/src/test/ui/lto-still-runs-thread-dtors.rs similarity index 97% rename from src/test/run-pass/lto-still-runs-thread-dtors.rs rename to src/test/ui/lto-still-runs-thread-dtors.rs index 732681af03..635ad783b3 100644 --- a/src/test/run-pass/lto-still-runs-thread-dtors.rs +++ b/src/test/ui/lto-still-runs-thread-dtors.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -C lto // no-prefer-dynamic // ignore-emscripten no threads support diff --git a/src/test/run-pass/lub-glb-with-unbound-infer-var.rs b/src/test/ui/lub-glb-with-unbound-infer-var.rs similarity index 96% rename from src/test/run-pass/lub-glb-with-unbound-infer-var.rs rename to src/test/ui/lub-glb-with-unbound-infer-var.rs index 7e430d26b2..c9e117089f 100644 --- a/src/test/run-pass/lub-glb-with-unbound-infer-var.rs +++ b/src/test/ui/lub-glb-with-unbound-infer-var.rs @@ -1,3 +1,4 @@ +// run-pass // Test for a specific corner case: when we compute the LUB of two fn // types and their parameters have unbound variables. In that case, we // wind up relating those two variables. This was causing an ICE in an diff --git a/src/test/run-pass/macro-quote-cond.rs b/src/test/ui/macro-quote-cond.rs similarity index 98% rename from src/test/run-pass/macro-quote-cond.rs rename to src/test/ui/macro-quote-cond.rs index 4d6bcf501e..569451e425 100644 --- a/src/test/run-pass/macro-quote-cond.rs +++ b/src/test/ui/macro-quote-cond.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_parens)] // aux-build:cond_plugin.rs diff --git a/src/test/run-pass/macro-quote-test.rs b/src/test/ui/macro-quote-test.rs similarity index 94% rename from src/test/run-pass/macro-quote-test.rs rename to src/test/ui/macro-quote-test.rs index d00e8edf28..7815b8e6df 100644 --- a/src/test/run-pass/macro-quote-test.rs +++ b/src/test/ui/macro-quote-test.rs @@ -1,3 +1,4 @@ +// run-pass // Test that a macro can emit delimiters with nothing inside - `()`, `{}` // aux-build:hello_macro.rs diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.stderr index 239b53f233..e7bd141ccd 100644 --- a/src/test/ui/macro_backtrace/main.stderr +++ b/src/test/ui/macro_backtrace/main.stderr @@ -24,10 +24,10 @@ LL | ping!(); | ::: <::ping::ping macros>:1:1 | -LL | ( ) => { pong ! ( ) ; } - | ------------------------- - | | | - | | in this macro invocation +LL | () => { pong ! () ; } + | --------------------- + | | | + | | in this macro invocation | in this expansion of `ping!` error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error` @@ -44,34 +44,34 @@ LL | deep!(); | ::: <::ping::deep macros>:1:1 | -LL | ( ) => { foo ! ( ) ; } - | ------------------------ - | | | - | | in this macro invocation (#2) +LL | () => { foo ! () ; } + | -------------------- + | | | + | | in this macro invocation (#2) | in this expansion of `deep!` (#1) | ::: <::ping::foo macros>:1:1 | -LL | ( ) => { bar ! ( ) ; } - | ------------------------ - | | | - | | in this macro invocation (#3) +LL | () => { bar ! () ; } + | -------------------- + | | | + | | in this macro invocation (#3) | in this expansion of `foo!` (#2) | ::: <::ping::bar macros>:1:1 | -LL | ( ) => { ping ! ( ) ; } - | ------------------------- - | | | - | | in this macro invocation (#4) +LL | () => { ping ! () ; } + | --------------------- + | | | + | | in this macro invocation (#4) | in this expansion of `bar!` (#3) | ::: <::ping::ping macros>:1:1 | -LL | ( ) => { pong ! ( ) ; } - | ------------------------- - | | | - | | in this macro invocation (#5) +LL | () => { pong ! () ; } + | --------------------- + | | | + | | in this macro invocation (#5) | in this expansion of `ping!` (#4) error: aborting due to 3 previous errors diff --git a/src/test/run-pass/macros/assert-eq-macro-success.rs b/src/test/ui/macros/assert-eq-macro-success.rs similarity index 100% rename from src/test/run-pass/macros/assert-eq-macro-success.rs rename to src/test/ui/macros/assert-eq-macro-success.rs diff --git a/src/test/run-pass/macros/assert-eq-macro-unsized.rs b/src/test/ui/macros/assert-eq-macro-unsized.rs similarity index 100% rename from src/test/run-pass/macros/assert-eq-macro-unsized.rs rename to src/test/ui/macros/assert-eq-macro-unsized.rs diff --git a/src/test/run-pass/macros/assert-ne-macro-success.rs b/src/test/ui/macros/assert-ne-macro-success.rs similarity index 100% rename from src/test/run-pass/macros/assert-ne-macro-success.rs rename to src/test/ui/macros/assert-ne-macro-success.rs diff --git a/src/test/run-pass/macros/assert-ne-macro-unsized.rs b/src/test/ui/macros/assert-ne-macro-unsized.rs similarity index 100% rename from src/test/run-pass/macros/assert-ne-macro-unsized.rs rename to src/test/ui/macros/assert-ne-macro-unsized.rs diff --git a/src/test/ui/macros/auxiliary/deprecated-macros.rs b/src/test/ui/macros/auxiliary/deprecated-macros.rs new file mode 100644 index 0000000000..657a7252a3 --- /dev/null +++ b/src/test/ui/macros/auxiliary/deprecated-macros.rs @@ -0,0 +1,3 @@ +#[deprecated(since = "1.0.0", note = "deprecation note")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } diff --git a/src/test/ui/macros/auxiliary/dollar-crate-nested-encoding.rs b/src/test/ui/macros/auxiliary/dollar-crate-nested-encoding.rs new file mode 100644 index 0000000000..bbe6a48c5b --- /dev/null +++ b/src/test/ui/macros/auxiliary/dollar-crate-nested-encoding.rs @@ -0,0 +1,10 @@ +pub type S = u8; + +macro_rules! generate_exported { () => { + #[macro_export] + macro_rules! exported { + () => ($crate::S) + } +}} + +generate_exported!(); diff --git a/src/test/run-pass/macros/auxiliary/macro-comma-support.rs b/src/test/ui/macros/auxiliary/macro-comma-support.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/macro-comma-support.rs rename to src/test/ui/macros/auxiliary/macro-comma-support.rs diff --git a/src/test/run-pass/macros/auxiliary/macro-include-items-expr.rs b/src/test/ui/macros/auxiliary/macro-include-items-expr.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/macro-include-items-expr.rs rename to src/test/ui/macros/auxiliary/macro-include-items-expr.rs diff --git a/src/test/run-pass/macros/auxiliary/macro-include-items-item.rs b/src/test/ui/macros/auxiliary/macro-include-items-item.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/macro-include-items-item.rs rename to src/test/ui/macros/auxiliary/macro-include-items-item.rs diff --git a/src/test/run-pass/macros/auxiliary/macro_crate_def_only.rs b/src/test/ui/macros/auxiliary/macro_crate_def_only.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/macro_crate_def_only.rs rename to src/test/ui/macros/auxiliary/macro_crate_def_only.rs diff --git a/src/test/run-pass/macros/auxiliary/macro_export_inner_module.rs b/src/test/ui/macros/auxiliary/macro_export_inner_module.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/macro_export_inner_module.rs rename to src/test/ui/macros/auxiliary/macro_export_inner_module.rs diff --git a/src/test/run-pass/macros/auxiliary/macro_with_super_1.rs b/src/test/ui/macros/auxiliary/macro_with_super_1.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/macro_with_super_1.rs rename to src/test/ui/macros/auxiliary/macro_with_super_1.rs diff --git a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs new file mode 100644 index 0000000000..b50ed7ca92 --- /dev/null +++ b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs @@ -0,0 +1,36 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_span, proc_macro_hygiene, proc_macro_quote)] + +extern crate proc_macro; + +use proc_macro::{quote, Span, TokenStream}; + +fn assert_same_span(a: Span, b: Span) { + assert_eq!(a.start(), b.start()); + assert_eq!(a.end(), b.end()); +} + +// This macro generates a macro with the same macro definition as `manual_foo` in +// `same-sequence-span.rs` but with the same span for all sequences. +#[proc_macro] +pub fn make_foo(_: TokenStream) -> TokenStream { + let result = quote! { + macro_rules! generated_foo { + (1 $$x:expr $$($$y:tt,)* $$(= $$z:tt)*) => {}; + } + }; + + // Check that all spans are equal. + let mut span = None; + for tt in result.clone() { + match span { + None => span = Some(tt.span()), + Some(span) => assert_same_span(tt.span(), span), + } + } + + result +} diff --git a/src/test/run-pass/macros/auxiliary/two_macros.rs b/src/test/ui/macros/auxiliary/two_macros-rpass.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/two_macros.rs rename to src/test/ui/macros/auxiliary/two_macros-rpass.rs diff --git a/src/test/ui/macros/auxiliary/unstable-macros.rs b/src/test/ui/macros/auxiliary/unstable-macros.rs index b8d580702c..e928dc705d 100644 --- a/src/test/ui/macros/auxiliary/unstable-macros.rs +++ b/src/test/ui/macros/auxiliary/unstable-macros.rs @@ -1,6 +1,16 @@ +#![feature(decl_macro)] #![feature(staged_api)] #![stable(feature = "unit_test", since = "1.0.0")] #[unstable(feature = "unstable_macros", issue = "0")] #[macro_export] macro_rules! unstable_macro{ () => () } + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "deprecation reason")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } + +// FIXME: Cannot use a `pub` macro 2.0 in a staged API crate due to reachability issues. +// #[unstable(feature = "unstable_macros", issue = "0")] +// pub macro unstable_macro_modern() {} diff --git a/src/test/run-pass/macros/auxiliary/use-macro-self.rs b/src/test/ui/macros/auxiliary/use-macro-self.rs similarity index 100% rename from src/test/run-pass/macros/auxiliary/use-macro-self.rs rename to src/test/ui/macros/auxiliary/use-macro-self.rs diff --git a/src/test/ui/macros/builtin-prelude-no-accidents.rs b/src/test/ui/macros/builtin-prelude-no-accidents.rs new file mode 100644 index 0000000000..ac82f343ac --- /dev/null +++ b/src/test/ui/macros/builtin-prelude-no-accidents.rs @@ -0,0 +1,8 @@ +// Names of public modules in libstd and libcore don't accidentally get into prelude +// because macros with the same names are in prelude. + +fn main() { + env::current_dir; //~ ERROR use of undeclared type or module `env` + type A = panic::PanicInfo; //~ ERROR use of undeclared type or module `panic` + type B = vec::Vec; //~ ERROR use of undeclared type or module `vec` +} diff --git a/src/test/ui/macros/builtin-prelude-no-accidents.stderr b/src/test/ui/macros/builtin-prelude-no-accidents.stderr new file mode 100644 index 0000000000..914e906df5 --- /dev/null +++ b/src/test/ui/macros/builtin-prelude-no-accidents.stderr @@ -0,0 +1,21 @@ +error[E0433]: failed to resolve: use of undeclared type or module `env` + --> $DIR/builtin-prelude-no-accidents.rs:5:5 + | +LL | env::current_dir; + | ^^^ use of undeclared type or module `env` + +error[E0433]: failed to resolve: use of undeclared type or module `panic` + --> $DIR/builtin-prelude-no-accidents.rs:6:14 + | +LL | type A = panic::PanicInfo; + | ^^^^^ use of undeclared type or module `panic` + +error[E0433]: failed to resolve: use of undeclared type or module `vec` + --> $DIR/builtin-prelude-no-accidents.rs:7:14 + | +LL | type B = vec::Vec; + | ^^^ use of undeclared type or module `vec` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/macros/builtin-std-paths-fail.rs b/src/test/ui/macros/builtin-std-paths-fail.rs new file mode 100644 index 0000000000..33de3d5184 --- /dev/null +++ b/src/test/ui/macros/builtin-std-paths-fail.rs @@ -0,0 +1,21 @@ +#[derive( + core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` + core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` +)] +#[core::bench] //~ ERROR could not find `bench` in `core` +#[core::global_allocator] //~ ERROR could not find `global_allocator` in `core` +#[core::test_case] //~ ERROR could not find `test_case` in `core` +#[core::test] //~ ERROR could not find `test` in `core` +struct Core; + +#[derive( + std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` + std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` +)] +#[std::bench] //~ ERROR could not find `bench` in `std` +#[std::global_allocator] //~ ERROR could not find `global_allocator` in `std` +#[std::test_case] //~ ERROR could not find `test_case` in `std` +#[std::test] //~ ERROR could not find `test` in `std` +struct Std; + +fn main() {} diff --git a/src/test/ui/macros/builtin-std-paths-fail.stderr b/src/test/ui/macros/builtin-std-paths-fail.stderr new file mode 100644 index 0000000000..6de689076b --- /dev/null +++ b/src/test/ui/macros/builtin-std-paths-fail.stderr @@ -0,0 +1,75 @@ +error[E0433]: failed to resolve: could not find `bench` in `core` + --> $DIR/builtin-std-paths-fail.rs:5:9 + | +LL | #[core::bench] + | ^^^^^ could not find `bench` in `core` + +error[E0433]: failed to resolve: could not find `global_allocator` in `core` + --> $DIR/builtin-std-paths-fail.rs:6:9 + | +LL | #[core::global_allocator] + | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `core` + +error[E0433]: failed to resolve: could not find `test_case` in `core` + --> $DIR/builtin-std-paths-fail.rs:7:9 + | +LL | #[core::test_case] + | ^^^^^^^^^ could not find `test_case` in `core` + +error[E0433]: failed to resolve: could not find `test` in `core` + --> $DIR/builtin-std-paths-fail.rs:8:9 + | +LL | #[core::test] + | ^^^^ could not find `test` in `core` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` + --> $DIR/builtin-std-paths-fail.rs:2:11 + | +LL | core::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` + --> $DIR/builtin-std-paths-fail.rs:3:11 + | +LL | core::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` + +error[E0433]: failed to resolve: could not find `bench` in `std` + --> $DIR/builtin-std-paths-fail.rs:15:8 + | +LL | #[std::bench] + | ^^^^^ could not find `bench` in `std` + +error[E0433]: failed to resolve: could not find `global_allocator` in `std` + --> $DIR/builtin-std-paths-fail.rs:16:8 + | +LL | #[std::global_allocator] + | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `std` + +error[E0433]: failed to resolve: could not find `test_case` in `std` + --> $DIR/builtin-std-paths-fail.rs:17:8 + | +LL | #[std::test_case] + | ^^^^^^^^^ could not find `test_case` in `std` + +error[E0433]: failed to resolve: could not find `test` in `std` + --> $DIR/builtin-std-paths-fail.rs:18:8 + | +LL | #[std::test] + | ^^^^ could not find `test` in `std` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` + --> $DIR/builtin-std-paths-fail.rs:12:10 + | +LL | std::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` + +error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` + --> $DIR/builtin-std-paths-fail.rs:13:10 + | +LL | std::RustcDecodable, + | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/macros/builtin-std-paths.rs b/src/test/ui/macros/builtin-std-paths.rs new file mode 100644 index 0000000000..2083f9ba3d --- /dev/null +++ b/src/test/ui/macros/builtin-std-paths.rs @@ -0,0 +1,32 @@ +// check-pass + +#[derive( + core::clone::Clone, + core::marker::Copy, + core::fmt::Debug, + core::default::Default, + core::cmp::Eq, + core::hash::Hash, + core::cmp::Ord, + core::cmp::PartialEq, + core::cmp::PartialOrd, +)] +struct Core; + +#[derive( + std::clone::Clone, + std::marker::Copy, + std::fmt::Debug, + std::default::Default, + std::cmp::Eq, + std::hash::Hash, + std::cmp::Ord, + std::cmp::PartialEq, + std::cmp::PartialOrd, +)] +struct Std; + +fn main() { + core::column!(); + std::column!(); +} diff --git a/src/test/run-pass/macros/colorful-write-macros.rs b/src/test/ui/macros/colorful-write-macros.rs similarity index 100% rename from src/test/run-pass/macros/colorful-write-macros.rs rename to src/test/ui/macros/colorful-write-macros.rs diff --git a/src/test/run-pass/macros/conditional-debug-macro-on.rs b/src/test/ui/macros/conditional-debug-macro-on.rs similarity index 100% rename from src/test/run-pass/macros/conditional-debug-macro-on.rs rename to src/test/ui/macros/conditional-debug-macro-on.rs diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.rs b/src/test/ui/macros/derive-in-eager-expansion-hang.rs new file mode 100644 index 0000000000..0729e14d5b --- /dev/null +++ b/src/test/ui/macros/derive-in-eager-expansion-hang.rs @@ -0,0 +1,14 @@ +// Regression test for the issue #44692 + +macro_rules! hang { () => { + { //~ ERROR format argument must be a string literal + #[derive(Clone)] + struct S; + + "" + } +}} + +fn main() { + format_args!(hang!()); +} diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr new file mode 100644 index 0000000000..5ca4088e58 --- /dev/null +++ b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr @@ -0,0 +1,20 @@ +error: format argument must be a string literal + --> $DIR/derive-in-eager-expansion-hang.rs:4:5 + | +LL | / { +LL | | #[derive(Clone)] +LL | | struct S; +LL | | +LL | | "" +LL | | } + | |_____^ +... +LL | format_args!(hang!()); + | ------- in this macro invocation +help: you might be missing a string literal to format with + | +LL | format_args!("{}", hang!()); + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/run-pass/macros/die-macro.rs b/src/test/ui/macros/die-macro.rs similarity index 100% rename from src/test/run-pass/macros/die-macro.rs rename to src/test/ui/macros/die-macro.rs diff --git a/src/test/ui/macros/dollar-crate-nested-encoding.rs b/src/test/ui/macros/dollar-crate-nested-encoding.rs new file mode 100644 index 0000000000..5242f7830b --- /dev/null +++ b/src/test/ui/macros/dollar-crate-nested-encoding.rs @@ -0,0 +1,8 @@ +// check-pass +// aux-build:dollar-crate-nested-encoding.rs + +extern crate dollar_crate_nested_encoding; + +type A = dollar_crate_nested_encoding::exported!(); + +fn main() {} diff --git a/src/test/ui/macros/format-parse-errors.rs b/src/test/ui/macros/format-parse-errors.rs index 96aee5e6ae..ffa7a2817f 100644 --- a/src/test/ui/macros/format-parse-errors.rs +++ b/src/test/ui/macros/format-parse-errors.rs @@ -1,9 +1,15 @@ fn main() { + let foo = ""; + let bar = ""; format!(); //~ ERROR requires at least a format string argument format!(struct); //~ ERROR expected expression format!("s", name =); //~ ERROR expected expression - format!("s", foo = foo, bar); //~ ERROR expected `=` - format!("s", foo = struct); //~ ERROR expected expression + format!( + "s {foo} {} {}", + foo = foo, + bar, //~ ERROR positional arguments cannot follow named arguments + ); + format!("s {foo}", foo = struct); //~ ERROR expected expression format!("s", struct); //~ ERROR expected expression // This error should come after parsing errors to ensure they are non-fatal. diff --git a/src/test/ui/macros/format-parse-errors.stderr b/src/test/ui/macros/format-parse-errors.stderr index fd4f930919..906738d738 100644 --- a/src/test/ui/macros/format-parse-errors.stderr +++ b/src/test/ui/macros/format-parse-errors.stderr @@ -1,5 +1,5 @@ error: requires at least a format string argument - --> $DIR/format-parse-errors.rs:2:5 + --> $DIR/format-parse-errors.rs:4:5 | LL | format!(); | ^^^^^^^^^^ @@ -7,37 +7,39 @@ LL | format!(); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: expected expression, found keyword `struct` - --> $DIR/format-parse-errors.rs:3:13 + --> $DIR/format-parse-errors.rs:5:13 | LL | format!(struct); | ^^^^^^ expected expression error: expected expression, found end of macro arguments - --> $DIR/format-parse-errors.rs:4:24 + --> $DIR/format-parse-errors.rs:6:24 | LL | format!("s", name =); | ^ expected expression -error: expected `=`, found end of macro arguments - --> $DIR/format-parse-errors.rs:5:32 +error: positional arguments cannot follow named arguments + --> $DIR/format-parse-errors.rs:10:9 | -LL | format!("s", foo = foo, bar); - | ^ expected `=` +LL | foo = foo, + | --- named argument +LL | bar, + | ^^^ positional arguments must be before named arguments error: expected expression, found keyword `struct` - --> $DIR/format-parse-errors.rs:6:24 + --> $DIR/format-parse-errors.rs:12:30 | -LL | format!("s", foo = struct); - | ^^^^^^ expected expression +LL | format!("s {foo}", foo = struct); + | ^^^^^^ expected expression error: expected expression, found keyword `struct` - --> $DIR/format-parse-errors.rs:7:18 + --> $DIR/format-parse-errors.rs:13:18 | LL | format!("s", struct); | ^^^^^^ expected expression error: format argument must be a string literal - --> $DIR/format-parse-errors.rs:10:13 + --> $DIR/format-parse-errors.rs:16:13 | LL | format!(123); | ^^^ diff --git a/src/test/run-pass/macros/issue-25274.rs b/src/test/ui/macros/issue-25274.rs similarity index 95% rename from src/test/run-pass/macros/issue-25274.rs rename to src/test/ui/macros/issue-25274.rs index e81b2c7a72..65b29bba8c 100644 --- a/src/test/run-pass/macros/issue-25274.rs +++ b/src/test/ui/macros/issue-25274.rs @@ -1,3 +1,5 @@ +// run-pass + macro_rules! test { ( fn fun() -> Option>; diff --git a/src/test/ui/macros/issue-61053-different-kleene.rs b/src/test/ui/macros/issue-61053-different-kleene.rs new file mode 100644 index 0000000000..9b7babdbb7 --- /dev/null +++ b/src/test/ui/macros/issue-61053-different-kleene.rs @@ -0,0 +1,30 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; + //~^ ERROR meta-variable repeats with + ( $( $($j:ident),+ );* ) => { $( $( $j; )+ )+ }; //~ERROR meta-variable repeats with +} + +macro_rules! bar { + () => {}; + (test) => { + macro_rules! nested { + () => {}; + ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; + //~^ ERROR meta-variable repeats with + ( $( $($j:ident),+ );* ) => { $( $( $j; )+ )+ }; //~ERROR meta-variable repeats with + } + }; + ( $( $i:ident = $($j:ident),+ );* ) => { + $(macro_rules! $i { + () => { 0 $( + $j )* }; //~ ERROR meta-variable repeats with + })* + }; +} + +fn main() { + foo!(); + bar!(); +} diff --git a/src/test/ui/macros/issue-61053-different-kleene.stderr b/src/test/ui/macros/issue-61053-different-kleene.stderr new file mode 100644 index 0000000000..86474822a0 --- /dev/null +++ b/src/test/ui/macros/issue-61053-different-kleene.stderr @@ -0,0 +1,45 @@ +error: meta-variable repeats with different Kleene operator + --> $DIR/issue-61053-different-kleene.rs:5:57 + | +LL | ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; + | - expected repetition ^^ - conflicting repetition + | +note: lint level defined here + --> $DIR/issue-61053-different-kleene.rs:1:9 + | +LL | #![deny(meta_variable_misuse)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: meta-variable repeats with different Kleene operator + --> $DIR/issue-61053-different-kleene.rs:7:41 + | +LL | ( $( $($j:ident),+ );* ) => { $( $( $j; )+ )+ }; + | - ^^ - conflicting repetition + | | + | expected repetition + +error: meta-variable repeats with different Kleene operator + --> $DIR/issue-61053-different-kleene.rs:15:65 + | +LL | ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; + | - expected repetition ^^ - conflicting repetition + +error: meta-variable repeats with different Kleene operator + --> $DIR/issue-61053-different-kleene.rs:17:49 + | +LL | ( $( $($j:ident),+ );* ) => { $( $( $j; )+ )+ }; + | - ^^ - conflicting repetition + | | + | expected repetition + +error: meta-variable repeats with different Kleene operator + --> $DIR/issue-61053-different-kleene.rs:22:28 + | +LL | ( $( $i:ident = $($j:ident),+ );* ) => { + | - expected repetition +LL | $(macro_rules! $i { +LL | () => { 0 $( + $j )* }; + | ^^ - conflicting repetition + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/macros/issue-61053-duplicate-binder.rs b/src/test/ui/macros/issue-61053-duplicate-binder.rs new file mode 100644 index 0000000000..34aa571c11 --- /dev/null +++ b/src/test/ui/macros/issue-61053-duplicate-binder.rs @@ -0,0 +1,14 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + (error) => { + macro_rules! bar { + ($x:tt $x:tt) => { $x }; //~ ERROR duplicate matcher binding + } + }; +} + +fn main() { + foo!(); +} diff --git a/src/test/ui/macros/issue-61053-duplicate-binder.stderr b/src/test/ui/macros/issue-61053-duplicate-binder.stderr new file mode 100644 index 0000000000..fbd67b6c1e --- /dev/null +++ b/src/test/ui/macros/issue-61053-duplicate-binder.stderr @@ -0,0 +1,16 @@ +error: duplicate matcher binding + --> $DIR/issue-61053-duplicate-binder.rs:7:20 + | +LL | ($x:tt $x:tt) => { $x }; + | -- ^^ + | | + | previous declaration + | +note: lint level defined here + --> $DIR/issue-61053-duplicate-binder.rs:1:9 + | +LL | #![deny(meta_variable_misuse)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/macros/issue-61053-missing-repetition.rs b/src/test/ui/macros/issue-61053-missing-repetition.rs new file mode 100644 index 0000000000..6b36c730b8 --- /dev/null +++ b/src/test/ui/macros/issue-61053-missing-repetition.rs @@ -0,0 +1,28 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; + //~^ ERROR variable 'j' is still repeating +} + +macro_rules! bar { + () => {}; + (test) => { + macro_rules! nested { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; + //~^ ERROR variable 'j' is still repeating + } + }; + ( $( $i:ident = $($j:ident),+ );* ) => { + $(macro_rules! $i { + () => { $j }; //~ ERROR variable 'j' is still repeating + })* + }; +} + +fn main() { + foo!(); + bar!(); +} diff --git a/src/test/ui/macros/issue-61053-missing-repetition.stderr b/src/test/ui/macros/issue-61053-missing-repetition.stderr new file mode 100644 index 0000000000..6f89e276c1 --- /dev/null +++ b/src/test/ui/macros/issue-61053-missing-repetition.stderr @@ -0,0 +1,33 @@ +error: variable 'j' is still repeating at this depth + --> $DIR/issue-61053-missing-repetition.rs:5:52 + | +LL | ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; + | - ^^ + | | + | expected repetition + | +note: lint level defined here + --> $DIR/issue-61053-missing-repetition.rs:1:9 + | +LL | #![deny(meta_variable_misuse)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: variable 'j' is still repeating at this depth + --> $DIR/issue-61053-missing-repetition.rs:14:60 + | +LL | ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; + | - ^^ + | | + | expected repetition + +error: variable 'j' is still repeating at this depth + --> $DIR/issue-61053-missing-repetition.rs:20:21 + | +LL | ( $( $i:ident = $($j:ident),+ );* ) => { + | - expected repetition +LL | $(macro_rules! $i { +LL | () => { $j }; + | ^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/macros/issue-61053-unbound.rs b/src/test/ui/macros/issue-61053-unbound.rs new file mode 100644 index 0000000000..b75cdce0cf --- /dev/null +++ b/src/test/ui/macros/issue-61053-unbound.rs @@ -0,0 +1,28 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; + //~^ ERROR unknown macro variable +} + +macro_rules! bar { + () => {}; + (test) => { + macro_rules! nested { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; + //~^ ERROR unknown macro variable + } + }; + ( $( $i:ident = $($j:ident),+ );* ) => { + $(macro_rules! $i { + () => { $( $i = $k)+ }; //~ ERROR unknown macro variable + })* + }; +} + +fn main() { + foo!(); + bar!(); +} diff --git a/src/test/ui/macros/issue-61053-unbound.stderr b/src/test/ui/macros/issue-61053-unbound.stderr new file mode 100644 index 0000000000..0fc0a7e283 --- /dev/null +++ b/src/test/ui/macros/issue-61053-unbound.stderr @@ -0,0 +1,26 @@ +error: unknown macro variable `k` + --> $DIR/issue-61053-unbound.rs:5:55 + | +LL | ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; + | ^^ + | +note: lint level defined here + --> $DIR/issue-61053-unbound.rs:1:9 + | +LL | #![deny(meta_variable_misuse)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unknown macro variable `k` + --> $DIR/issue-61053-unbound.rs:14:63 + | +LL | ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; + | ^^ + +error: unknown macro variable `k` + --> $DIR/issue-61053-unbound.rs:20:29 + | +LL | () => { $( $i = $k)+ }; + | ^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/macros/issue-63102.rs b/src/test/ui/macros/issue-63102.rs new file mode 100644 index 0000000000..6af5b18680 --- /dev/null +++ b/src/test/ui/macros/issue-63102.rs @@ -0,0 +1,8 @@ +// check-pass + +#![feature(decl_macro)] +macro foo { + () => {}, +} + +fn main() {} diff --git a/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.rs b/src/test/ui/macros/log_syntax-trace_macros-macro-locations.rs similarity index 100% rename from src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.rs rename to src/test/ui/macros/log_syntax-trace_macros-macro-locations.rs diff --git a/src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.stdout b/src/test/ui/macros/log_syntax-trace_macros-macro-locations.stdout similarity index 100% rename from src/test/run-pass/macros/log_syntax-trace_macros-macro-locations.stdout rename to src/test/ui/macros/log_syntax-trace_macros-macro-locations.stdout diff --git a/src/test/run-pass/macros/macro-2.rs b/src/test/ui/macros/macro-2.rs similarity index 100% rename from src/test/run-pass/macros/macro-2.rs rename to src/test/ui/macros/macro-2.rs diff --git a/src/test/run-pass/macros/macro-as-fn-body.rs b/src/test/ui/macros/macro-as-fn-body.rs similarity index 100% rename from src/test/run-pass/macros/macro-as-fn-body.rs rename to src/test/ui/macros/macro-as-fn-body.rs diff --git a/src/test/run-pass/macros/macro-at-most-once-rep-2015.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-rpass.rs similarity index 100% rename from src/test/run-pass/macros/macro-at-most-once-rep-2015.rs rename to src/test/ui/macros/macro-at-most-once-rep-2015-rpass.rs diff --git a/src/test/run-pass/macros/macro-at-most-once-rep-2018.rs b/src/test/ui/macros/macro-at-most-once-rep-2018-rpass.rs similarity index 100% rename from src/test/run-pass/macros/macro-at-most-once-rep-2018.rs rename to src/test/ui/macros/macro-at-most-once-rep-2018-rpass.rs diff --git a/src/test/run-pass/macros/macro-attribute-expansion.rs b/src/test/ui/macros/macro-attribute-expansion.rs similarity index 100% rename from src/test/run-pass/macros/macro-attribute-expansion.rs rename to src/test/ui/macros/macro-attribute-expansion.rs diff --git a/src/test/run-pass/macros/macro-attributes.rs b/src/test/ui/macros/macro-attributes.rs similarity index 100% rename from src/test/run-pass/macros/macro-attributes.rs rename to src/test/ui/macros/macro-attributes.rs diff --git a/src/test/run-pass/macros/macro-block-nonterminal.rs b/src/test/ui/macros/macro-block-nonterminal.rs similarity index 100% rename from src/test/run-pass/macros/macro-block-nonterminal.rs rename to src/test/ui/macros/macro-block-nonterminal.rs diff --git a/src/test/run-pass/macros/macro-comma-behavior.rs b/src/test/ui/macros/macro-comma-behavior-rpass.rs similarity index 100% rename from src/test/run-pass/macros/macro-comma-behavior.rs rename to src/test/ui/macros/macro-comma-behavior-rpass.rs diff --git a/src/test/run-pass/macros/macro-comma-support.rs b/src/test/ui/macros/macro-comma-support-rpass.rs similarity index 99% rename from src/test/run-pass/macros/macro-comma-support.rs rename to src/test/ui/macros/macro-comma-support-rpass.rs index 12a612c153..50c0ef3451 100644 --- a/src/test/run-pass/macros/macro-comma-support.rs +++ b/src/test/ui/macros/macro-comma-support-rpass.rs @@ -15,6 +15,7 @@ #![cfg_attr(core, no_std)] +#![allow(deprecated)] // for deprecated `try!()` macro #![feature(concat_idents)] #[cfg(std)] use std::fmt; diff --git a/src/test/run-pass/macros/macro-crate-def-only.rs b/src/test/ui/macros/macro-crate-def-only.rs similarity index 100% rename from src/test/run-pass/macros/macro-crate-def-only.rs rename to src/test/ui/macros/macro-crate-def-only.rs diff --git a/src/test/run-pass/macros/macro-crate-nonterminal-renamed.rs b/src/test/ui/macros/macro-crate-nonterminal-renamed.rs similarity index 100% rename from src/test/run-pass/macros/macro-crate-nonterminal-renamed.rs rename to src/test/ui/macros/macro-crate-nonterminal-renamed.rs diff --git a/src/test/run-pass/macros/macro-crate-nonterminal.rs b/src/test/ui/macros/macro-crate-nonterminal.rs similarity index 100% rename from src/test/run-pass/macros/macro-crate-nonterminal.rs rename to src/test/ui/macros/macro-crate-nonterminal.rs diff --git a/src/test/run-pass/macros/macro-crate-use.rs b/src/test/ui/macros/macro-crate-use.rs similarity index 100% rename from src/test/run-pass/macros/macro-crate-use.rs rename to src/test/ui/macros/macro-crate-use.rs diff --git a/src/test/run-pass/macros/macro-deep_expansion.rs b/src/test/ui/macros/macro-deep_expansion.rs similarity index 100% rename from src/test/run-pass/macros/macro-deep_expansion.rs rename to src/test/ui/macros/macro-deep_expansion.rs diff --git a/src/test/run-pass/macros/macro-delimiter-significance.rs b/src/test/ui/macros/macro-delimiter-significance.rs similarity index 100% rename from src/test/run-pass/macros/macro-delimiter-significance.rs rename to src/test/ui/macros/macro-delimiter-significance.rs diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs new file mode 100644 index 0000000000..9636b48c2d --- /dev/null +++ b/src/test/ui/macros/macro-deprecation.rs @@ -0,0 +1,13 @@ +// check-pass +// aux-build:deprecated-macros.rs + +#[macro_use] extern crate deprecated_macros; + +#[deprecated(since = "1.0.0", note = "local deprecation note")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + +fn main() { + local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note + deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note +} diff --git a/src/test/ui/macros/macro-deprecation.stderr b/src/test/ui/macros/macro-deprecation.stderr new file mode 100644 index 0000000000..75915b9091 --- /dev/null +++ b/src/test/ui/macros/macro-deprecation.stderr @@ -0,0 +1,14 @@ +warning: use of deprecated item 'local_deprecated': local deprecation note + --> $DIR/macro-deprecation.rs:11:5 + | +LL | local_deprecated!(); + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(deprecated)]` on by default + +warning: use of deprecated item 'deprecated_macro': deprecation note + --> $DIR/macro-deprecation.rs:12:5 + | +LL | deprecated_macro!(); + | ^^^^^^^^^^^^^^^^ + diff --git a/src/test/run-pass/macros/macro-doc-comments.rs b/src/test/ui/macros/macro-doc-comments.rs similarity index 100% rename from src/test/run-pass/macros/macro-doc-comments.rs rename to src/test/ui/macros/macro-doc-comments.rs diff --git a/src/test/run-pass/macros/macro-doc-escapes.rs b/src/test/ui/macros/macro-doc-escapes.rs similarity index 100% rename from src/test/run-pass/macros/macro-doc-escapes.rs rename to src/test/ui/macros/macro-doc-escapes.rs diff --git a/src/test/run-pass/macros/macro-doc-raw-str-hashes.rs b/src/test/ui/macros/macro-doc-raw-str-hashes.rs similarity index 100% rename from src/test/run-pass/macros/macro-doc-raw-str-hashes.rs rename to src/test/ui/macros/macro-doc-raw-str-hashes.rs diff --git a/src/test/ui/macros/macro-error.stderr b/src/test/ui/macros/macro-error.stderr index b3aed8c2ce..2539a6d515 100644 --- a/src/test/ui/macros/macro-error.stderr +++ b/src/test/ui/macros/macro-error.stderr @@ -8,7 +8,7 @@ error: non-type macro in type position: cfg --> $DIR/macro-error.rs:8:12 | LL | let _: cfg!(foo) = (); - | ^^^ + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/macro-expanded-include/test.rs b/src/test/ui/macros/macro-expanded-include/test.rs index fe697db9fb..b8eb854b0b 100644 --- a/src/test/ui/macros/macro-expanded-include/test.rs +++ b/src/test/ui/macros/macro-expanded-include/test.rs @@ -1,5 +1,5 @@ // ignore-emscripten no asm! support -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(asm)] #![allow(unused)] diff --git a/src/test/run-pass/macros/macro-export-inner-module.rs b/src/test/ui/macros/macro-export-inner-module.rs similarity index 100% rename from src/test/run-pass/macros/macro-export-inner-module.rs rename to src/test/ui/macros/macro-export-inner-module.rs diff --git a/src/test/run-pass/macros/macro-first-set.rs b/src/test/ui/macros/macro-first-set.rs similarity index 98% rename from src/test/run-pass/macros/macro-first-set.rs rename to src/test/ui/macros/macro-first-set.rs index a21e4cd201..34529cdaa6 100644 --- a/src/test/run-pass/macros/macro-first-set.rs +++ b/src/test/ui/macros/macro-first-set.rs @@ -25,7 +25,7 @@ macro_rules! foo_26444 { } fn test_26444() { - assert_eq!("a , b , c , d , e", foo_26444!(a, b; c; d, e)); + assert_eq!("a, b, c, d, e", foo_26444!(a, b; c; d, e)); assert_eq!("f", foo_26444!(; f ;)); } diff --git a/src/test/run-pass/macros/macro-follow.rs b/src/test/ui/macros/macro-follow-rpass.rs similarity index 100% rename from src/test/run-pass/macros/macro-follow.rs rename to src/test/ui/macros/macro-follow-rpass.rs diff --git a/src/test/ui/macros/macro-follow.stderr b/src/test/ui/macros/macro-follow.stderr index d3f081bb4a..61ae79d235 100644 --- a/src/test/ui/macros/macro-follow.stderr +++ b/src/test/ui/macros/macro-follow.stderr @@ -1,24 +1,24 @@ error: `$p:pat` is followed by `(`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:8:14 + --> $DIR/macro-follow.rs:8:13 | LL | ($p:pat ()) => {}; - | ^ not allowed after `pat` fragments + | ^ not allowed after `pat` fragments | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` error: `$p:pat` is followed by `[`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:9:14 + --> $DIR/macro-follow.rs:9:13 | LL | ($p:pat []) => {}; - | ^ not allowed after `pat` fragments + | ^ not allowed after `pat` fragments | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` error: `$p:pat` is followed by `{`, which is not allowed for `pat` fragments - --> $DIR/macro-follow.rs:10:14 + --> $DIR/macro-follow.rs:10:13 | LL | ($p:pat {}) => {}; - | ^ not allowed after `pat` fragments + | ^ not allowed after `pat` fragments | = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` @@ -135,26 +135,26 @@ LL | ($p:pat $m:meta) => {}; = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` error: `$e:expr` is followed by `(`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:28:15 + --> $DIR/macro-follow.rs:28:14 | LL | ($e:expr ()) => {}; - | ^ not allowed after `expr` fragments + | ^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `[`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:29:15 + --> $DIR/macro-follow.rs:29:14 | LL | ($e:expr []) => {}; - | ^ not allowed after `expr` fragments + | ^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$e:expr` is followed by `{`, which is not allowed for `expr` fragments - --> $DIR/macro-follow.rs:30:15 + --> $DIR/macro-follow.rs:30:14 | LL | ($e:expr {}) => {}; - | ^ not allowed after `expr` fragments + | ^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` @@ -303,10 +303,10 @@ LL | ($e:expr $m:meta) => {}; = note: allowed there are: `=>`, `,` or `;` error: `$t:ty` is followed by `(`, which is not allowed for `ty` fragments - --> $DIR/macro-follow.rs:53:13 + --> $DIR/macro-follow.rs:53:12 | LL | ($t:ty ()) => {}; - | ^ not allowed after `ty` fragments + | ^ not allowed after `ty` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` @@ -407,26 +407,26 @@ LL | ($t:ty $m:meta) => {}; = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` error: `$s:stmt` is followed by `(`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:71:15 + --> $DIR/macro-follow.rs:71:14 | LL | ($s:stmt ()) => {}; - | ^ not allowed after `stmt` fragments + | ^ not allowed after `stmt` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `[`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:72:15 + --> $DIR/macro-follow.rs:72:14 | LL | ($s:stmt []) => {}; - | ^ not allowed after `stmt` fragments + | ^ not allowed after `stmt` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$s:stmt` is followed by `{`, which is not allowed for `stmt` fragments - --> $DIR/macro-follow.rs:73:15 + --> $DIR/macro-follow.rs:73:14 | LL | ($s:stmt {}) => {}; - | ^ not allowed after `stmt` fragments + | ^ not allowed after `stmt` fragments | = note: allowed there are: `=>`, `,` or `;` @@ -575,10 +575,10 @@ LL | ($s:stmt $m:meta) => {}; = note: allowed there are: `=>`, `,` or `;` error: `$p:path` is followed by `(`, which is not allowed for `path` fragments - --> $DIR/macro-follow.rs:95:15 + --> $DIR/macro-follow.rs:95:14 | LL | ($p:path ()) => {}; - | ^ not allowed after `path` fragments + | ^ not allowed after `path` fragments | = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` diff --git a/src/test/run-pass/macros/macro-followed-by-seq.rs b/src/test/ui/macros/macro-followed-by-seq.rs similarity index 100% rename from src/test/run-pass/macros/macro-followed-by-seq.rs rename to src/test/ui/macros/macro-followed-by-seq.rs diff --git a/src/test/run-pass/macros/macro-include-items.rs b/src/test/ui/macros/macro-include-items.rs similarity index 100% rename from src/test/run-pass/macros/macro-include-items.rs rename to src/test/ui/macros/macro-include-items.rs diff --git a/src/test/run-pass/macros/macro-interpolation.rs b/src/test/ui/macros/macro-interpolation.rs similarity index 100% rename from src/test/run-pass/macros/macro-interpolation.rs rename to src/test/ui/macros/macro-interpolation.rs diff --git a/src/test/run-pass/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs similarity index 100% rename from src/test/run-pass/macros/macro-invocation-in-count-expr-fixed-array-type.rs rename to src/test/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs diff --git a/src/test/run-pass/macros/macro-lifetime-used-with-bound.rs b/src/test/ui/macros/macro-lifetime-used-with-bound.rs similarity index 100% rename from src/test/run-pass/macros/macro-lifetime-used-with-bound.rs rename to src/test/ui/macros/macro-lifetime-used-with-bound.rs diff --git a/src/test/run-pass/macros/macro-lifetime-used-with-labels.rs b/src/test/ui/macros/macro-lifetime-used-with-labels.rs similarity index 100% rename from src/test/run-pass/macros/macro-lifetime-used-with-labels.rs rename to src/test/ui/macros/macro-lifetime-used-with-labels.rs diff --git a/src/test/run-pass/macros/macro-lifetime-used-with-labels.stderr b/src/test/ui/macros/macro-lifetime-used-with-labels.stderr similarity index 100% rename from src/test/run-pass/macros/macro-lifetime-used-with-labels.stderr rename to src/test/ui/macros/macro-lifetime-used-with-labels.stderr diff --git a/src/test/run-pass/macros/macro-lifetime-used-with-static.rs b/src/test/ui/macros/macro-lifetime-used-with-static.rs similarity index 100% rename from src/test/run-pass/macros/macro-lifetime-used-with-static.rs rename to src/test/ui/macros/macro-lifetime-used-with-static.rs diff --git a/src/test/run-pass/macros/macro-lifetime.rs b/src/test/ui/macros/macro-lifetime.rs similarity index 100% rename from src/test/run-pass/macros/macro-lifetime.rs rename to src/test/ui/macros/macro-lifetime.rs diff --git a/src/test/run-pass/macros/macro-literal.rs b/src/test/ui/macros/macro-literal.rs similarity index 100% rename from src/test/run-pass/macros/macro-literal.rs rename to src/test/ui/macros/macro-literal.rs diff --git a/src/test/run-pass/macros/macro-meta-items.rs b/src/test/ui/macros/macro-meta-items.rs similarity index 100% rename from src/test/run-pass/macros/macro-meta-items.rs rename to src/test/ui/macros/macro-meta-items.rs diff --git a/src/test/run-pass/macros/macro-method-issue-4621.rs b/src/test/ui/macros/macro-method-issue-4621.rs similarity index 100% rename from src/test/run-pass/macros/macro-method-issue-4621.rs rename to src/test/ui/macros/macro-method-issue-4621.rs diff --git a/src/test/run-pass/macros/macro-multiple-items.rs b/src/test/ui/macros/macro-multiple-items.rs similarity index 100% rename from src/test/run-pass/macros/macro-multiple-items.rs rename to src/test/ui/macros/macro-multiple-items.rs diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index a8930f243f..967f4f3c4a 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -2,7 +2,7 @@ error: cannot find macro `printlx!` in this scope --> $DIR/macro-name-typo.rs:2:5 | LL | printlx!("oh noes!"); - | ^^^^^^^ help: you could try the macro: `println` + | ^^^^^^^ help: a macro with a similar name exists: `println` error: aborting due to previous error diff --git a/src/test/run-pass/macros/macro-named-default.rs b/src/test/ui/macros/macro-named-default.rs similarity index 100% rename from src/test/run-pass/macros/macro-named-default.rs rename to src/test/ui/macros/macro-named-default.rs diff --git a/src/test/run-pass/macros/macro-nested_definition_issue-31946.rs b/src/test/ui/macros/macro-nested_definition_issue-31946.rs similarity index 100% rename from src/test/run-pass/macros/macro-nested_definition_issue-31946.rs rename to src/test/ui/macros/macro-nested_definition_issue-31946.rs diff --git a/src/test/run-pass/macros/macro-nested_expr.rs b/src/test/ui/macros/macro-nested_expr.rs similarity index 100% rename from src/test/run-pass/macros/macro-nested_expr.rs rename to src/test/ui/macros/macro-nested_expr.rs diff --git a/src/test/run-pass/macros/macro-nested_stmt_macros.rs b/src/test/ui/macros/macro-nested_stmt_macros.rs similarity index 100% rename from src/test/run-pass/macros/macro-nested_stmt_macros.rs rename to src/test/ui/macros/macro-nested_stmt_macros.rs diff --git a/src/test/run-pass/macros/macro-nt-list.rs b/src/test/ui/macros/macro-nt-list.rs similarity index 100% rename from src/test/run-pass/macros/macro-nt-list.rs rename to src/test/ui/macros/macro-nt-list.rs diff --git a/src/test/run-pass/macros/macro-of-higher-order.rs b/src/test/ui/macros/macro-of-higher-order.rs similarity index 100% rename from src/test/run-pass/macros/macro-of-higher-order.rs rename to src/test/ui/macros/macro-of-higher-order.rs diff --git a/src/test/run-pass/macros/macro-pat-follow.rs b/src/test/ui/macros/macro-pat-follow.rs similarity index 100% rename from src/test/run-pass/macros/macro-pat-follow.rs rename to src/test/ui/macros/macro-pat-follow.rs diff --git a/src/test/run-pass/macros/macro-pat-neg-lit.rs b/src/test/ui/macros/macro-pat-neg-lit.rs similarity index 100% rename from src/test/run-pass/macros/macro-pat-neg-lit.rs rename to src/test/ui/macros/macro-pat-neg-lit.rs diff --git a/src/test/run-pass/macros/macro-pat.rs b/src/test/ui/macros/macro-pat.rs similarity index 100% rename from src/test/run-pass/macros/macro-pat.rs rename to src/test/ui/macros/macro-pat.rs diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr index 7eeddb8854..96b8a24cff 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr @@ -2,7 +2,7 @@ error: cannot find macro `inline!` in this scope --> $DIR/macro-path-prelude-fail-3.rs:2:5 | LL | inline!(); - | ^^^^^^ help: you could try the macro: `line` + | ^^^^^^ help: a macro with a similar name exists: `line` error: aborting due to previous error diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.rs b/src/test/ui/macros/macro-path-prelude-fail-4.rs index 283427b9ac..0f93fcdaa5 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.rs +++ b/src/test/ui/macros/macro-path-prelude-fail-4.rs @@ -1,4 +1,4 @@ -#[derive(inline)] //~ ERROR expected a macro, found built-in attribute +#[derive(inline)] //~ ERROR expected derive macro, found built-in attribute `inline` struct S; fn main() {} diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.stderr b/src/test/ui/macros/macro-path-prelude-fail-4.stderr index f08445e1f7..dfd6818b67 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-4.stderr @@ -1,8 +1,8 @@ -error: expected a macro, found built-in attribute +error: expected derive macro, found built-in attribute `inline` --> $DIR/macro-path-prelude-fail-4.rs:1:10 | LL | #[derive(inline)] - | ^^^^^^ + | ^^^^^^ not a derive macro error: aborting due to previous error diff --git a/src/test/ui/macros/macro-path-prelude-pass.rs b/src/test/ui/macros/macro-path-prelude-pass.rs index 3d35d53f77..8daa1c84f1 100644 --- a/src/test/ui/macros/macro-path-prelude-pass.rs +++ b/src/test/ui/macros/macro-path-prelude-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_prelude)] diff --git a/src/test/ui/macros/macro-path-prelude-pass.stderr b/src/test/ui/macros/macro-path-prelude-pass.stderr index 3744e0198b..c6e7fd77cd 100644 --- a/src/test/ui/macros/macro-path-prelude-pass.stderr +++ b/src/test/ui/macros/macro-path-prelude-pass.stderr @@ -4,5 +4,5 @@ warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer LL | #![feature(extern_prelude)] | ^^^^^^^^^^^^^^ | - = note: #[warn(stable_features)] on by default + = note: `#[warn(stable_features)]` on by default diff --git a/src/test/ui/macros/macro-path-prelude-shadowing.stderr b/src/test/ui/macros/macro-path-prelude-shadowing.stderr index e7b381daf9..7bbb8eddb7 100644 --- a/src/test/ui/macros/macro-path-prelude-shadowing.stderr +++ b/src/test/ui/macros/macro-path-prelude-shadowing.stderr @@ -4,7 +4,7 @@ error[E0659]: `std` is ambiguous (glob import vs any other name from outer scope LL | std::panic!(); | ^^^ ambiguous name | - = note: `std` could refer to a built-in extern crate + = note: `std` could refer to a built-in crate note: `std` could also refer to the module imported here --> $DIR/macro-path-prelude-shadowing.rs:27:9 | diff --git a/src/test/run-pass/macros/macro-path.rs b/src/test/ui/macros/macro-path.rs similarity index 100% rename from src/test/run-pass/macros/macro-path.rs rename to src/test/ui/macros/macro-path.rs diff --git a/src/test/run-pass/macros/macro-pub-matcher.rs b/src/test/ui/macros/macro-pub-matcher.rs similarity index 100% rename from src/test/run-pass/macros/macro-pub-matcher.rs rename to src/test/ui/macros/macro-pub-matcher.rs diff --git a/src/test/ui/macros/macro-reexport-removed.rs b/src/test/ui/macros/macro-reexport-removed.rs index fb33794a5c..b69a1fa4df 100644 --- a/src/test/ui/macros/macro-reexport-removed.rs +++ b/src/test/ui/macros/macro-reexport-removed.rs @@ -2,7 +2,7 @@ #![feature(macro_reexport)] //~ ERROR feature has been removed -#[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown +#[macro_reexport(macro_one)] //~ ERROR cannot find attribute macro `macro_reexport` in this scope extern crate two_macros; fn main() {} diff --git a/src/test/ui/macros/macro-reexport-removed.stderr b/src/test/ui/macros/macro-reexport-removed.stderr index 742a72964d..25778fba68 100644 --- a/src/test/ui/macros/macro-reexport-removed.stderr +++ b/src/test/ui/macros/macro-reexport-removed.stderr @@ -10,16 +10,12 @@ note: subsumed by `pub use` LL | #![feature(macro_reexport)] | ^^^^^^^^^^^^^^ -error[E0658]: The attribute `macro_reexport` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `macro_reexport` in this scope --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to 2 previous errors -Some errors have detailed explanations: E0557, E0658. -For more information about an error, try `rustc --explain E0557`. +For more information about this error, try `rustc --explain E0557`. diff --git a/src/test/run-pass/macros/macro-seq-followed-by-seq.rs b/src/test/ui/macros/macro-seq-followed-by-seq.rs similarity index 100% rename from src/test/run-pass/macros/macro-seq-followed-by-seq.rs rename to src/test/ui/macros/macro-seq-followed-by-seq.rs diff --git a/src/test/ui/macros/macro-shadowing-relaxed.rs b/src/test/ui/macros/macro-shadowing-relaxed.rs index 2477226ce2..b2a639218b 100644 --- a/src/test/ui/macros/macro-shadowing-relaxed.rs +++ b/src/test/ui/macros/macro-shadowing-relaxed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:macro-in-other-crate.rs #![feature(decl_macro)] diff --git a/src/test/run-pass/macros/macro-stability.rs b/src/test/ui/macros/macro-stability-rpass.rs similarity index 84% rename from src/test/run-pass/macros/macro-stability.rs rename to src/test/ui/macros/macro-stability-rpass.rs index b471aa655e..817bddf695 100644 --- a/src/test/run-pass/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability-rpass.rs @@ -1,7 +1,7 @@ // run-pass // aux-build:unstable-macros.rs -#![feature(unstable_macros)] +#![feature(unstable_macros, local_unstable)] #[macro_use] extern crate unstable_macros; diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index 7d1ee6a43b..ab927e419b 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -1,12 +1,28 @@ // aux-build:unstable-macros.rs +#![feature(decl_macro)] #![feature(staged_api)] #[macro_use] extern crate unstable_macros; #[unstable(feature = "local_unstable", issue = "0")] macro_rules! local_unstable { () => () } +#[unstable(feature = "local_unstable", issue = "0")] +macro local_unstable_modern() {} + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "local deprecation reason")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + fn main() { - local_unstable!(); - unstable_macro!(); //~ ERROR: macro unstable_macro! is unstable + local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable' + local_unstable_modern!(); //~ ERROR use of unstable library feature 'local_unstable' + unstable_macro!(); //~ ERROR use of unstable library feature 'unstable_macros' + // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros' + + deprecated_macro!(); + //~^ WARN use of deprecated item 'deprecated_macro': deprecation reason + local_deprecated!(); + //~^ WARN use of deprecated item 'local_deprecated': local deprecation reason } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index a0e0c351a4..d357314d84 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -1,11 +1,41 @@ -error[E0658]: macro unstable_macro! is unstable - --> $DIR/macro-stability.rs:11:5 +error[E0658]: use of unstable library feature 'local_unstable' + --> $DIR/macro-stability.rs:19:5 + | +LL | local_unstable!(); + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(local_unstable)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'local_unstable' + --> $DIR/macro-stability.rs:20:5 + | +LL | local_unstable_modern!(); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(local_unstable)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_macros' + --> $DIR/macro-stability.rs:21:5 | LL | unstable_macro!(); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_macros)]` to the crate attributes to enable + +warning: use of deprecated item 'deprecated_macro': deprecation reason + --> $DIR/macro-stability.rs:24:5 + | +LL | deprecated_macro!(); + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(deprecated)]` on by default + +warning: use of deprecated item 'local_deprecated': local deprecation reason + --> $DIR/macro-stability.rs:26:5 | - = help: add #![feature(unstable_macros)] to the crate attributes to enable +LL | local_deprecated!(); + | ^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/macros/macro-stmt-matchers.rs b/src/test/ui/macros/macro-stmt-matchers.rs index 6e53eb0512..a643e50e99 100644 --- a/src/test/ui/macros/macro-stmt-matchers.rs +++ b/src/test/ui/macros/macro-stmt-matchers.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { diff --git a/src/test/run-pass/macros/macro-stmt.rs b/src/test/ui/macros/macro-stmt.rs similarity index 100% rename from src/test/run-pass/macros/macro-stmt.rs rename to src/test/ui/macros/macro-stmt.rs diff --git a/src/test/run-pass/macros/macro-stmt_macro_in_expr_macro.rs b/src/test/ui/macros/macro-stmt_macro_in_expr_macro.rs similarity index 100% rename from src/test/run-pass/macros/macro-stmt_macro_in_expr_macro.rs rename to src/test/ui/macros/macro-stmt_macro_in_expr_macro.rs diff --git a/src/test/run-pass/macros/macro-tt-followed-by-seq.rs b/src/test/ui/macros/macro-tt-followed-by-seq.rs similarity index 100% rename from src/test/run-pass/macros/macro-tt-followed-by-seq.rs rename to src/test/ui/macros/macro-tt-followed-by-seq.rs diff --git a/src/test/ui/macros/macro-tt-matchers.rs b/src/test/ui/macros/macro-tt-matchers.rs index 17df72f36d..2ee41b0880 100644 --- a/src/test/ui/macros/macro-tt-matchers.rs +++ b/src/test/ui/macros/macro-tt-matchers.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] macro_rules! foo { diff --git a/src/test/run-pass/macros/macro-use-all-and-none.rs b/src/test/ui/macros/macro-use-all-and-none.rs similarity index 50% rename from src/test/run-pass/macros/macro-use-all-and-none.rs rename to src/test/ui/macros/macro-use-all-and-none.rs index 5fdcda0f78..e5f67d458d 100644 --- a/src/test/run-pass/macros/macro-use-all-and-none.rs +++ b/src/test/ui/macros/macro-use-all-and-none.rs @@ -1,9 +1,11 @@ // run-pass -// aux-build:two_macros.rs +// aux-build:two_macros-rpass.rs + +#![warn(unused_attributes)] #[macro_use] #[macro_use()] -extern crate two_macros; +extern crate two_macros_rpass; pub fn main() { macro_one!(); diff --git a/src/test/ui/macros/macro-use-all-and-none.stderr b/src/test/ui/macros/macro-use-all-and-none.stderr new file mode 100644 index 0000000000..e7de7e7ad0 --- /dev/null +++ b/src/test/ui/macros/macro-use-all-and-none.stderr @@ -0,0 +1,12 @@ +warning: unused attribute + --> $DIR/macro-use-all-and-none.rs:7:1 + | +LL | #[macro_use()] + | ^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/macro-use-all-and-none.rs:4:9 + | +LL | #![warn(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + diff --git a/src/test/run-pass/macros/macro-use-all.rs b/src/test/ui/macros/macro-use-all.rs similarity index 100% rename from src/test/run-pass/macros/macro-use-all.rs rename to src/test/ui/macros/macro-use-all.rs diff --git a/src/test/ui/macros/macro-use-bad-args-1.rs b/src/test/ui/macros/macro-use-bad-args-1.rs index 061c5cc7b3..ec0b64a109 100644 --- a/src/test/ui/macros/macro-use-bad-args-1.rs +++ b/src/test/ui/macros/macro-use-bad-args-1.rs @@ -1,6 +1,5 @@ #![no_std] -#[allow(unused_extern_crates)] #[macro_use(foo(bar))] //~ ERROR bad macro import extern crate std; diff --git a/src/test/ui/macros/macro-use-bad-args-1.stderr b/src/test/ui/macros/macro-use-bad-args-1.stderr index f403c8a366..4e5482a518 100644 --- a/src/test/ui/macros/macro-use-bad-args-1.stderr +++ b/src/test/ui/macros/macro-use-bad-args-1.stderr @@ -1,5 +1,5 @@ error[E0466]: bad macro import - --> $DIR/macro-use-bad-args-1.rs:4:13 + --> $DIR/macro-use-bad-args-1.rs:3:13 | LL | #[macro_use(foo(bar))] | ^^^^^^^^ diff --git a/src/test/ui/macros/macro-use-bad-args-2.rs b/src/test/ui/macros/macro-use-bad-args-2.rs index cb231ce292..c5f8f62c18 100644 --- a/src/test/ui/macros/macro-use-bad-args-2.rs +++ b/src/test/ui/macros/macro-use-bad-args-2.rs @@ -1,6 +1,5 @@ #![no_std] -#[allow(unused_extern_crates)] #[macro_use(foo="bar")] //~ ERROR bad macro import extern crate std; diff --git a/src/test/ui/macros/macro-use-bad-args-2.stderr b/src/test/ui/macros/macro-use-bad-args-2.stderr index 93617edeea..c958104eac 100644 --- a/src/test/ui/macros/macro-use-bad-args-2.stderr +++ b/src/test/ui/macros/macro-use-bad-args-2.stderr @@ -1,5 +1,5 @@ error[E0466]: bad macro import - --> $DIR/macro-use-bad-args-2.rs:4:13 + --> $DIR/macro-use-bad-args-2.rs:3:13 | LL | #[macro_use(foo="bar")] | ^^^^^^^^^ diff --git a/src/test/run-pass/macros/macro-use-both.rs b/src/test/ui/macros/macro-use-both.rs similarity index 100% rename from src/test/run-pass/macros/macro-use-both.rs rename to src/test/ui/macros/macro-use-both.rs diff --git a/src/test/run-pass/macros/macro-use-one.rs b/src/test/ui/macros/macro-use-one.rs similarity index 100% rename from src/test/run-pass/macros/macro-use-one.rs rename to src/test/ui/macros/macro-use-one.rs diff --git a/src/test/ui/macros/macro-use-scope.rs b/src/test/ui/macros/macro-use-scope.rs index 03d57d2229..5e58fc9c1e 100644 --- a/src/test/ui/macros/macro-use-scope.rs +++ b/src/test/ui/macros/macro-use-scope.rs @@ -1,6 +1,6 @@ // aux-build:two_macros.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] fn f() { diff --git a/src/test/ui/macros/macro-use-wrong-name.stderr b/src/test/ui/macros/macro-use-wrong-name.stderr index d178d4e4a6..28f727d6a5 100644 --- a/src/test/ui/macros/macro-use-wrong-name.stderr +++ b/src/test/ui/macros/macro-use-wrong-name.stderr @@ -2,7 +2,7 @@ error: cannot find macro `macro_two!` in this scope --> $DIR/macro-use-wrong-name.rs:7:5 | LL | macro_two!(); - | ^^^^^^^^^ help: you could try the macro: `macro_one` + | ^^^^^^^^^ help: a macro with a similar name exists: `macro_one` error: aborting due to previous error diff --git a/src/test/run-pass/macros/macro-with-attrs1.rs b/src/test/ui/macros/macro-with-attrs1.rs similarity index 100% rename from src/test/run-pass/macros/macro-with-attrs1.rs rename to src/test/ui/macros/macro-with-attrs1.rs diff --git a/src/test/run-pass/macros/macro-with-attrs2.rs b/src/test/ui/macros/macro-with-attrs2.rs similarity index 100% rename from src/test/run-pass/macros/macro-with-attrs2.rs rename to src/test/ui/macros/macro-with-attrs2.rs diff --git a/src/test/run-pass/macros/macro-with-braces-in-expr-position.rs b/src/test/ui/macros/macro-with-braces-in-expr-position.rs similarity index 100% rename from src/test/run-pass/macros/macro-with-braces-in-expr-position.rs rename to src/test/ui/macros/macro-with-braces-in-expr-position.rs diff --git a/src/test/ui/macros/macro_undefined.stderr b/src/test/ui/macros/macro_undefined.stderr index b516f91c67..9239b2a51e 100644 --- a/src/test/ui/macros/macro_undefined.stderr +++ b/src/test/ui/macros/macro_undefined.stderr @@ -2,7 +2,7 @@ error: cannot find macro `k!` in this scope --> $DIR/macro_undefined.rs:11:5 | LL | k!(); - | ^ help: you could try the macro: `kl` + | ^ help: a macro with a similar name exists: `kl` error: aborting due to previous error diff --git a/src/test/run-pass/macros/macro_with_super_2.rs b/src/test/ui/macros/macro_with_super_2.rs similarity index 100% rename from src/test/run-pass/macros/macro_with_super_2.rs rename to src/test/ui/macros/macro_with_super_2.rs diff --git a/src/test/run-pass/macros/macros-in-extern.rs b/src/test/ui/macros/macros-in-extern-rpass.rs similarity index 100% rename from src/test/run-pass/macros/macros-in-extern.rs rename to src/test/ui/macros/macros-in-extern-rpass.rs diff --git a/src/test/ui/macros/macros-in-extern.stderr b/src/test/ui/macros/macros-in-extern.stderr index ec7c37402d..6ee33f4ab6 100644 --- a/src/test/ui/macros/macros-in-extern.stderr +++ b/src/test/ui/macros/macros-in-extern.stderr @@ -5,7 +5,7 @@ LL | returns_isize!(rust_get_test_int); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental --> $DIR/macros-in-extern.rs:28:5 @@ -14,7 +14,7 @@ LL | takes_u32_returns_u32!(rust_dbg_extern_identity_u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental --> $DIR/macros-in-extern.rs:30:5 @@ -23,7 +23,7 @@ LL | emits_nothing!(); | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/macros/meta-item-absolute-path.stderr b/src/test/ui/macros/meta-item-absolute-path.stderr index 23933f730a..711fa4dd40 100644 --- a/src/test/ui/macros/meta-item-absolute-path.stderr +++ b/src/test/ui/macros/meta-item-absolute-path.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing `extern crate Absolute;`? +error[E0433]: failed to resolve: maybe a missing crate `Absolute`? --> $DIR/meta-item-absolute-path.rs:1:12 | LL | #[derive(::Absolute)] - | ^^^^^^^^ maybe a missing `extern crate Absolute;`? + | ^^^^^^^^ maybe a missing crate `Absolute`? error: aborting due to previous error diff --git a/src/test/ui/macros/meta-variable-misuse.rs b/src/test/ui/macros/meta-variable-misuse.rs new file mode 100644 index 0000000000..99a2f94017 --- /dev/null +++ b/src/test/ui/macros/meta-variable-misuse.rs @@ -0,0 +1,34 @@ +// run-pass +#![deny(meta_variable_misuse)] + +macro_rules! foo { + ($($m:ident $($f:ident $v:tt)+),*) => { + $($(macro_rules! $f { () => { $v } })+)* + $(macro_rules! $m { () => { $(fn $f() -> i32 { $v })+ } })* + } +} + +foo!(m a 1 b 2, n c 3); +m!(); +n!(); + +macro_rules! no_shadow { + ($x:tt) => { macro_rules! bar { ($x:tt) => { 42 }; } }; +} +no_shadow!(z); + +macro_rules! make_plus { + ($n: ident $x:expr) => { macro_rules! $n { ($y:expr) => { $x + $y }; } }; +} +make_plus!(add3 3); + +fn main() { + assert_eq!(a!(), 1); + assert_eq!(b!(), 2); + assert_eq!(c!(), 3); + assert_eq!(a(), 1); + assert_eq!(b(), 2); + assert_eq!(c(), 3); + assert_eq!(bar!(z:tt), 42); + assert_eq!(add3!(9), 12); +} diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index d5b6d86b20..f96848f823 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -2,7 +2,7 @@ error: expected token: `,` --> $DIR/missing-comma.rs:19:19 | LL | println!("{}" a); - | ^ + | ^ expected `,` error: no rules expected the token `b` --> $DIR/missing-comma.rs:21:12 diff --git a/src/test/ui/macros/must-use-in-macro-55516.rs b/src/test/ui/macros/must-use-in-macro-55516.rs index a5de32e5d2..4b6b65ec48 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.rs +++ b/src/test/ui/macros/must-use-in-macro-55516.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Wunused // make sure write!() can't hide its unused Result diff --git a/src/test/run-pass/macros/parse-complex-macro-invoc-op.rs b/src/test/ui/macros/parse-complex-macro-invoc-op.rs similarity index 100% rename from src/test/run-pass/macros/parse-complex-macro-invoc-op.rs rename to src/test/ui/macros/parse-complex-macro-invoc-op.rs diff --git a/src/test/run-pass/macros/paths-in-macro-invocations.rs b/src/test/ui/macros/paths-in-macro-invocations.rs similarity index 85% rename from src/test/run-pass/macros/paths-in-macro-invocations.rs rename to src/test/ui/macros/paths-in-macro-invocations.rs index 4f745b85c2..622818a926 100644 --- a/src/test/run-pass/macros/paths-in-macro-invocations.rs +++ b/src/test/ui/macros/paths-in-macro-invocations.rs @@ -1,8 +1,8 @@ // run-pass #![allow(dead_code)] -// aux-build:two_macros.rs +// aux-build:two_macros-rpass.rs -extern crate two_macros; +extern crate two_macros_rpass as two_macros; ::two_macros::macro_one!(); two_macros::macro_one!(); diff --git a/src/test/run-pass/macros/pub-item-inside-macro.rs b/src/test/ui/macros/pub-item-inside-macro.rs similarity index 100% rename from src/test/run-pass/macros/pub-item-inside-macro.rs rename to src/test/ui/macros/pub-item-inside-macro.rs diff --git a/src/test/run-pass/macros/pub-method-inside-macro.rs b/src/test/ui/macros/pub-method-inside-macro.rs similarity index 100% rename from src/test/run-pass/macros/pub-method-inside-macro.rs rename to src/test/ui/macros/pub-method-inside-macro.rs diff --git a/src/test/ui/macros/restricted-shadowing-modern.rs b/src/test/ui/macros/restricted-shadowing-modern.rs index 448f623c22..a8818507d7 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.rs +++ b/src/test/ui/macros/restricted-shadowing-modern.rs @@ -80,17 +80,17 @@ struct Right; // struct Wrong; // not defined -#[rustc_transparent_macro] +#[rustc_macro_transparency = "transparent"] macro include() { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_outer() { macro m() { Wrong } } - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_inner() { macro m() { Right } } - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_invoc() { m!() } @@ -100,7 +100,7 @@ macro include() { fn check1() { macro m() {} { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_gen_inner_invoc() { gen_inner!(); m!(); //~ ERROR `m` is ambiguous @@ -112,7 +112,7 @@ macro include() { fn check5() { macro m() { Wrong } { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_inner_invoc() { macro m() { Right } m!(); // OK @@ -124,7 +124,7 @@ macro include() { fn check9() { macro m() { Wrong } { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_inner_gen_invoc() { macro m() { Right } gen_invoc!(); // OK @@ -145,7 +145,7 @@ macro include() { macro m() {} { gen_inner!(); - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous gen_invoc!(); } @@ -186,7 +186,7 @@ macro include() { fn check52() { gen_outer!(); { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_gen_inner_invoc() { gen_inner!(); m!(); //~ ERROR `m` is ambiguous @@ -198,7 +198,7 @@ macro include() { fn check56() { gen_outer!(); { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_inner_invoc() { macro m() { Right } m!(); // OK @@ -218,7 +218,7 @@ macro include() { fn check60() { gen_outer!(); { - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_inner_gen_invoc() { macro m() { Right } gen_invoc!(); // OK @@ -231,7 +231,7 @@ macro include() { gen_outer!(); { gen_inner!(); - #[rustc_transparent_macro] + #[rustc_macro_transparency = "transparent"] macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous gen_invoc!(); } diff --git a/src/test/ui/macros/same-sequence-span.rs b/src/test/ui/macros/same-sequence-span.rs new file mode 100644 index 0000000000..a4f70b6b68 --- /dev/null +++ b/src/test/ui/macros/same-sequence-span.rs @@ -0,0 +1,23 @@ +// aux-build:proc_macro_sequence.rs + +// Regression test for issue #62831: Check that multiple sequences with the same span in the +// left-hand side of a macro definition behave as if they had unique spans, and in particular that +// they don't crash the compiler. + +#![feature(proc_macro_hygiene)] +#![allow(unused_macros)] + +extern crate proc_macro_sequence; + +// When ignoring spans, this macro has the same macro definition as `generated_foo` in +// `proc_macro_sequence.rs`. +macro_rules! manual_foo { + (1 $x:expr $($y:tt,)* //~ERROR `$x:expr` may be followed by `$y:tt` + $(= $z:tt)* //~ERROR `$x:expr` may be followed by `=` + ) => {}; +} + +proc_macro_sequence::make_foo!(); //~ERROR `$x:expr` may be followed by `$y:tt` + //~^ERROR `$x:expr` may be followed by `=` + +fn main() {} diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr new file mode 100644 index 0000000000..aee1b4c9c5 --- /dev/null +++ b/src/test/ui/macros/same-sequence-span.stderr @@ -0,0 +1,34 @@ +error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:15:18 + | +LL | (1 $x:expr $($y:tt,)* + | ^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:16:18 + | +LL | $(= $z:tt)* + | ^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:20:1 + | +LL | proc_macro_sequence::make_foo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:20:1 + | +LL | proc_macro_sequence::make_foo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: aborting due to 4 previous errors + diff --git a/src/test/run-pass/macros/semi-after-macro-ty.rs b/src/test/ui/macros/semi-after-macro-ty.rs similarity index 100% rename from src/test/run-pass/macros/semi-after-macro-ty.rs rename to src/test/ui/macros/semi-after-macro-ty.rs diff --git a/src/test/run-pass/macros/stmt_expr_attr_macro_parse.rs b/src/test/ui/macros/stmt_expr_attr_macro_parse.rs similarity index 100% rename from src/test/run-pass/macros/stmt_expr_attr_macro_parse.rs rename to src/test/ui/macros/stmt_expr_attr_macro_parse.rs diff --git a/src/test/run-pass/macros/syntax-extension-cfg.rs b/src/test/ui/macros/syntax-extension-cfg.rs similarity index 100% rename from src/test/run-pass/macros/syntax-extension-cfg.rs rename to src/test/ui/macros/syntax-extension-cfg.rs diff --git a/src/test/run-pass/macros/syntax-extension-source-utils-files/includeme.fragment b/src/test/ui/macros/syntax-extension-source-utils-files/includeme.fragment similarity index 100% rename from src/test/run-pass/macros/syntax-extension-source-utils-files/includeme.fragment rename to src/test/ui/macros/syntax-extension-source-utils-files/includeme.fragment diff --git a/src/test/run-pass/macros/syntax-extension-source-utils.rs b/src/test/ui/macros/syntax-extension-source-utils.rs similarity index 87% rename from src/test/run-pass/macros/syntax-extension-source-utils.rs rename to src/test/ui/macros/syntax-extension-source-utils.rs index 1293115991..7e46260d51 100644 --- a/src/test/run-pass/macros/syntax-extension-source-utils.rs +++ b/src/test/ui/macros/syntax-extension-source-utils.rs @@ -18,7 +18,7 @@ pub fn main() { assert_eq!(column!(), 16); assert_eq!(indirect_line!(), 19); assert!((file!().ends_with("syntax-extension-source-utils.rs"))); - assert_eq!(stringify!((2*3) + 5).to_string(), "( 2 * 3 ) + 5".to_string()); + assert_eq!(stringify!((2*3) + 5).to_string(), "(2 * 3) + 5".to_string()); assert!(include!("syntax-extension-source-utils-files/includeme.\ fragment").to_string() == "victory robot 6".to_string()); @@ -33,5 +33,5 @@ pub fn main() { // The Windows tests are wrapped in an extra module for some reason assert!((m1::m2::where_am_i().ends_with("m1::m2"))); - assert_eq!((36, "( 2 * 3 ) + 5"), (line!(), stringify!((2*3) + 5))); + assert_eq!((36, "(2 * 3) + 5"), (line!(), stringify!((2*3) + 5))); } diff --git a/src/test/ui/macros/trace-macro.rs b/src/test/ui/macros/trace-macro.rs index efd658dd2b..576120811d 100644 --- a/src/test/ui/macros/trace-macro.rs +++ b/src/test/ui/macros/trace-macro.rs @@ -1,5 +1,5 @@ // compile-flags: -Z trace-macros -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { println!("Hello, World!"); diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr index ebfed41bc2..287f7b297d 100644 --- a/src/test/ui/macros/trace-macro.stderr +++ b/src/test/ui/macros/trace-macro.stderr @@ -5,5 +5,5 @@ LL | println!("Hello, World!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expanding `println! { "Hello, World!" }` - = note: to `{ $crate :: io :: _print ( format_args_nl ! ( "Hello, World!" ) ) ; }` + = note: to `{ $crate :: io :: _print (format_args_nl ! ("Hello, World!")) ; }` diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 233d3dcfcb..f06e6581ff 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -17,7 +17,7 @@ LL | my_faulty_macro!(); | ^^^^^^^^^^^^^^^^^^^ | = note: expanding `my_faulty_macro! { }` - = note: to `my_faulty_macro ! ( bcd ) ;` + = note: to `my_faulty_macro ! (bcd) ;` = note: expanding `my_faulty_macro! { bcd }` error: recursion limit reached while expanding the macro `my_recursive_macro` @@ -38,15 +38,13 @@ LL | my_recursive_macro!(); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: expanding `my_recursive_macro! { }` - = note: to `my_recursive_macro ! ( ) ;` + = note: to `my_recursive_macro ! () ;` = note: expanding `my_recursive_macro! { }` - = note: to `my_recursive_macro ! ( ) ;` + = note: to `my_recursive_macro ! () ;` = note: expanding `my_recursive_macro! { }` - = note: to `my_recursive_macro ! ( ) ;` + = note: to `my_recursive_macro ! () ;` = note: expanding `my_recursive_macro! { }` - = note: to `my_recursive_macro ! ( ) ;` - = note: expanding `my_recursive_macro! { }` - = note: to `my_recursive_macro ! ( ) ;` + = note: to `my_recursive_macro ! () ;` error: aborting due to 2 previous errors diff --git a/src/test/run-pass/macros/try-macro.rs b/src/test/ui/macros/try-macro.rs similarity index 95% rename from src/test/run-pass/macros/try-macro.rs rename to src/test/ui/macros/try-macro.rs index 83b30a8b7b..824c77d9de 100644 --- a/src/test/run-pass/macros/try-macro.rs +++ b/src/test/ui/macros/try-macro.rs @@ -1,4 +1,5 @@ // run-pass +#![allow(deprecated)] // for deprecated `try!()` macro use std::num::{ParseFloatError, ParseIntError}; fn main() { diff --git a/src/test/run-pass/macros/two-macro-use.rs b/src/test/ui/macros/two-macro-use.rs similarity index 100% rename from src/test/run-pass/macros/two-macro-use.rs rename to src/test/ui/macros/two-macro-use.rs diff --git a/src/test/run-pass/macros/type-macros-hlist.rs b/src/test/ui/macros/type-macros-hlist.rs similarity index 100% rename from src/test/run-pass/macros/type-macros-hlist.rs rename to src/test/ui/macros/type-macros-hlist.rs diff --git a/src/test/run-pass/macros/type-macros-simple.rs b/src/test/ui/macros/type-macros-simple.rs similarity index 100% rename from src/test/run-pass/macros/type-macros-simple.rs rename to src/test/ui/macros/type-macros-simple.rs diff --git a/src/test/run-pass/macros/typeck-macro-interaction-issue-8852.rs b/src/test/ui/macros/typeck-macro-interaction-issue-8852.rs similarity index 100% rename from src/test/run-pass/macros/typeck-macro-interaction-issue-8852.rs rename to src/test/ui/macros/typeck-macro-interaction-issue-8852.rs diff --git a/src/test/ui/macros/unknown-builtin.rs b/src/test/ui/macros/unknown-builtin.rs new file mode 100644 index 0000000000..a96b99ae4f --- /dev/null +++ b/src/test/ui/macros/unknown-builtin.rs @@ -0,0 +1,14 @@ +// error-pattern: cannot find a built-in macro with name `line` + +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown` + +#[rustc_builtin_macro] +macro_rules! line { () => () } + +fn main() { + line!(); + std::prelude::v1::line!(); +} diff --git a/src/test/ui/macros/unknown-builtin.stderr b/src/test/ui/macros/unknown-builtin.stderr new file mode 100644 index 0000000000..33b7b055b4 --- /dev/null +++ b/src/test/ui/macros/unknown-builtin.stderr @@ -0,0 +1,14 @@ +error: cannot find a built-in macro with name `unknown` + --> $DIR/unknown-builtin.rs:6:1 + | +LL | macro_rules! unknown { () => () } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot find a built-in macro with name `line` + --> <::core::macros::builtin::line macros>:1:1 + | +LL | () => { } + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/run-pass/macros/use-macro-self.rs b/src/test/ui/macros/use-macro-self.rs similarity index 100% rename from src/test/run-pass/macros/use-macro-self.rs rename to src/test/ui/macros/use-macro-self.rs diff --git a/src/test/ui/malformed/malformed-regressions.rs b/src/test/ui/malformed/malformed-regressions.rs index b5c992440d..c1a9d04e6d 100644 --- a/src/test/ui/malformed/malformed-regressions.rs +++ b/src/test/ui/malformed/malformed-regressions.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[doc] //~ WARN attribute must be of the form #[ignore()] //~ WARN attribute must be of the form diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr index 99a87f0c3a..eebb6f0623 100644 --- a/src/test/ui/malformed/malformed-regressions.stderr +++ b/src/test/ui/malformed/malformed-regressions.stderr @@ -4,7 +4,7 @@ warning: attribute must be of the form `#[doc(hidden|inline|...)]` or `#[doc = " LL | #[doc] | ^^^^^^ | - = note: #[warn(ill_formed_attribute_input)] on by default + = note: `#[warn(ill_formed_attribute_input)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 diff --git a/src/test/ui/match/issue-50900.rs b/src/test/ui/match/issue-50900.rs new file mode 100644 index 0000000000..27135af957 --- /dev/null +++ b/src/test/ui/match/issue-50900.rs @@ -0,0 +1,19 @@ +#[derive(PartialEq, Eq)] +pub struct Tag(pub Context, pub u16); + +#[derive(PartialEq, Eq)] +pub enum Context { + Tiff, + Exif, +} + +impl Tag { + const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665); +} + +fn main() { + match Tag::ExifIFDPointer { + //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered + Tag::ExifIFDPointer => {} + } +} diff --git a/src/test/ui/match/issue-50900.stderr b/src/test/ui/match/issue-50900.stderr new file mode 100644 index 0000000000..7192f11a5e --- /dev/null +++ b/src/test/ui/match/issue-50900.stderr @@ -0,0 +1,14 @@ +error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered + --> $DIR/issue-50900.rs:15:11 + | +LL | pub struct Tag(pub Context, pub u16); + | ------------------------------------- `Tag` defined here +... +LL | match Tag::ExifIFDPointer { + | ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/match/match-arm-resolving-to-never.rs b/src/test/ui/match/match-arm-resolving-to-never.rs new file mode 100644 index 0000000000..8f54023305 --- /dev/null +++ b/src/test/ui/match/match-arm-resolving-to-never.rs @@ -0,0 +1,19 @@ +enum E { + A, + B, + C, + D, + E, + F, +} + +fn main() { + match E::F { + E::A => 1, + E::B => 2, + E::C => 3, + E::D => 4, + E::E => unimplemented!(""), + E::F => "", //~ ERROR match arms have incompatible types + }; +} diff --git a/src/test/ui/match/match-arm-resolving-to-never.stderr b/src/test/ui/match/match-arm-resolving-to-never.stderr new file mode 100644 index 0000000000..24ce97f86e --- /dev/null +++ b/src/test/ui/match/match-arm-resolving-to-never.stderr @@ -0,0 +1,22 @@ +error[E0308]: match arms have incompatible types + --> $DIR/match-arm-resolving-to-never.rs:17:17 + | +LL | / match E::F { +LL | | E::A => 1, +LL | | E::B => 2, +LL | | E::C => 3, +LL | | E::D => 4, +LL | | E::E => unimplemented!(""), + | | ------------------ this and all prior arms are found to be of type `{integer}` +LL | | E::F => "", + | | ^^ expected integer, found reference +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected type `{integer}` + found type `&'static str` + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/match/match-non-exhaustive.stderr b/src/test/ui/match/match-non-exhaustive.stderr index 00c2bfff7e..211f333882 100644 --- a/src/test/ui/match/match-non-exhaustive.stderr +++ b/src/test/ui/match/match-non-exhaustive.stderr @@ -1,8 +1,8 @@ -error[E0004]: non-exhaustive patterns: `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered +error[E0004]: non-exhaustive patterns: `std::i32::MIN..=0i32` and `2i32..=std::i32::MAX` not covered --> $DIR/match-non-exhaustive.rs:2:11 | LL | match 0 { 1 => () } - | ^ patterns `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered + | ^ patterns `std::i32::MIN..=0i32` and `2i32..=std::i32::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/match/match-range-fail-dominate.stderr b/src/test/ui/match/match-range-fail-dominate.stderr index f481e56c85..d0ff4930a4 100644 --- a/src/test/ui/match/match-range-fail-dominate.stderr +++ b/src/test/ui/match/match-range-fail-dominate.stderr @@ -34,7 +34,7 @@ warning: floating-point types cannot be used in patterns LL | 0.01f64 ..= 6.5f64 => {} | ^^^^^^^ | - = note: #[warn(illegal_floating_point_literal_pattern)] on by default + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 diff --git a/src/test/ui/match/match-ref-mut-stability.rs b/src/test/ui/match/match-ref-mut-stability.rs index 795a3fc210..49e0dfaa3e 100644 --- a/src/test/ui/match/match-ref-mut-stability.rs +++ b/src/test/ui/match/match-ref-mut-stability.rs @@ -3,7 +3,7 @@ // run-pass -#![feature(nll, bind_by_move_pattern_guards)] +#![feature(bind_by_move_pattern_guards)] // Test that z always point to the same temporary. fn referent_stability() { diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/match/match-vec-mismatch.rs index 5e61c1b22a..a0ef92743a 100644 --- a/src/test/ui/match/match-vec-mismatch.rs +++ b/src/test/ui/match/match-vec-mismatch.rs @@ -19,10 +19,10 @@ fn main() { match [0, 1, 2] { [0] => {}, //~ ERROR pattern requires - [0, 1, x..] => { + [0, 1, x @ ..] => { let a: [_; 1] = x; } - [0, 1, 2, 3, x..] => {} //~ ERROR pattern requires + [0, 1, 2, 3, x @ ..] => {} //~ ERROR pattern requires }; match does_not_exist { //~ ERROR cannot find value `does_not_exist` in this scope diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/match/match-vec-mismatch.stderr index 47f9d48e26..2f1bbb7621 100644 --- a/src/test/ui/match/match-vec-mismatch.stderr +++ b/src/test/ui/match/match-vec-mismatch.stderr @@ -19,8 +19,8 @@ LL | [0] => {}, error[E0528]: pattern requires at least 4 elements but array has 3 --> $DIR/match-vec-mismatch.rs:25:9 | -LL | [0, 1, 2, 3, x..] => {} - | ^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements +LL | [0, 1, 2, 3, x @ ..] => {} + | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements error[E0282]: type annotations needed --> $DIR/match-vec-mismatch.rs:36:9 diff --git a/src/test/ui/match/match-vec-unreachable.rs b/src/test/ui/match/match-vec-unreachable.rs index 9e167f37ba..78810525ba 100644 --- a/src/test/ui/match/match-vec-unreachable.rs +++ b/src/test/ui/match/match-vec-unreachable.rs @@ -23,7 +23,7 @@ fn main() { let x: Vec = vec!['a', 'b', 'c']; let x: &[char] = &x; match *x { - ['a', 'b', 'c', ref _tail..] => {} + ['a', 'b', 'c', ref _tail @ ..] => {} ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern _ => {} } diff --git a/src/test/run-pass/max-min-classes.rs b/src/test/ui/max-min-classes.rs similarity index 97% rename from src/test/run-pass/max-min-classes.rs rename to src/test/ui/max-min-classes.rs index 9ae5bae19e..f9a39e486d 100644 --- a/src/test/run-pass/max-min-classes.rs +++ b/src/test/ui/max-min-classes.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_snake_case)] trait Product { fn product(&self) -> isize; diff --git a/src/test/ui/maybe-bounds-where-cpass.rs b/src/test/ui/maybe-bounds-where-cpass.rs index 860de200f6..d4bc05f7cb 100644 --- a/src/test/ui/maybe-bounds-where-cpass.rs +++ b/src/test/ui/maybe-bounds-where-cpass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(*const T) where T: ?Sized; diff --git a/src/test/run-pass/methods/auxiliary/method_self_arg1.rs b/src/test/ui/methods/auxiliary/method_self_arg1.rs similarity index 100% rename from src/test/run-pass/methods/auxiliary/method_self_arg1.rs rename to src/test/ui/methods/auxiliary/method_self_arg1.rs diff --git a/src/test/run-pass/methods/auxiliary/method_self_arg2.rs b/src/test/ui/methods/auxiliary/method_self_arg2.rs similarity index 100% rename from src/test/run-pass/methods/auxiliary/method_self_arg2.rs rename to src/test/ui/methods/auxiliary/method_self_arg2.rs diff --git a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr index 2b87ddfdf9..9f46a722a5 100644 --- a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -9,7 +9,9 @@ note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize` | LL | impl Me2 for usize { fn me(&self) -> usize { *self } } | ^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Me2::me(1_usize)` instead = note: candidate #2 is defined in an impl of the trait `ambig_impl_2_lib::Me` for the type `usize` + = help: to disambiguate the method call, write `ambig_impl_2_lib::Me::me(1_usize)` instead error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.rs b/src/test/ui/methods/method-ambig-two-traits-from-impls.rs new file mode 100644 index 0000000000..22bf840660 --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.rs @@ -0,0 +1,16 @@ +trait A { fn foo(self); } +trait B { fn foo(self); } + +struct AB {} + +impl A for AB { + fn foo(self) {} +} + +impl B for AB { + fn foo(self) {} +} + +fn main() { + AB {}.foo(); //~ ERROR E0034 +} diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr new file mode 100644 index 0000000000..0b3724e030 --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr @@ -0,0 +1,22 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-ambig-two-traits-from-impls.rs:15:11 + | +LL | AB {}.foo(); + | ^^^ multiple `foo` found + | +note: candidate #1 is defined in an impl of the trait `A` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls.rs:7:5 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^ + = help: to disambiguate the method call, write `A::foo(AB {})` instead +note: candidate #2 is defined in an impl of the trait `B` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls.rs:11:5 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^ + = help: to disambiguate the method call, write `B::foo(AB {})` instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.rs b/src/test/ui/methods/method-ambig-two-traits-from-impls2.rs new file mode 100644 index 0000000000..0a96c1223d --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.rs @@ -0,0 +1,16 @@ +trait A { fn foo(); } +trait B { fn foo(); } + +struct AB {} + +impl A for AB { + fn foo() {} +} + +impl B for AB { + fn foo() {} +} + +fn main() { + AB::foo(); //~ ERROR E0034 +} diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr new file mode 100644 index 0000000000..81c99b33c8 --- /dev/null +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr @@ -0,0 +1,22 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-ambig-two-traits-from-impls2.rs:15:5 + | +LL | AB::foo(); + | ^^^^^^^ multiple `foo` found + | +note: candidate #1 is defined in an impl of the trait `A` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls2.rs:7:5 + | +LL | fn foo() {} + | ^^^^^^^^ + = help: to disambiguate the method call, write `A::foo(...)` instead +note: candidate #2 is defined in an impl of the trait `B` for the type `AB` + --> $DIR/method-ambig-two-traits-from-impls2.rs:11:5 + | +LL | fn foo() {} + | ^^^^^^^^ + = help: to disambiguate the method call, write `B::foo(...)` instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr index 5d508d5702..dc8aef2503 100644 --- a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `Foo` for the type `usize` | LL | trait Foo { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Foo::method(1_usize)` instead note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize` --> $DIR/method-ambig-two-traits-with-default-method.rs:6:13 | LL | trait Bar { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Bar::method(1_usize)` instead error: aborting due to previous error diff --git a/src/test/run-pass/methods/method-argument-inference-associated-type.rs b/src/test/ui/methods/method-argument-inference-associated-type.rs similarity index 100% rename from src/test/run-pass/methods/method-argument-inference-associated-type.rs rename to src/test/ui/methods/method-argument-inference-associated-type.rs diff --git a/src/test/ui/methods/method-call-lifetime-args-subst-index.rs b/src/test/ui/methods/method-call-lifetime-args-subst-index.rs index 4ee09dcdf1..8df58a3486 100644 --- a/src/test/ui/methods/method-call-lifetime-args-subst-index.rs +++ b/src/test/ui/methods/method-call-lifetime-args-subst-index.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] struct S; diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index d6fac7025a..283ef8fcba 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -27,11 +27,13 @@ note: candidate #1 is defined in an impl of the trait `internal::X` for the type | LL | fn foo(self: Smaht) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `internal::X::foo(x)` instead note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ + = help: to disambiguate the method call, write `nuisance_foo::NuisanceFoo::foo(x)` instead note: candidate #3 is defined in the trait `FinalFoo` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:57:5 | diff --git a/src/test/run-pass/methods/method-early-bound-lifetimes-on-self.rs b/src/test/ui/methods/method-early-bound-lifetimes-on-self.rs similarity index 100% rename from src/test/run-pass/methods/method-early-bound-lifetimes-on-self.rs rename to src/test/ui/methods/method-early-bound-lifetimes-on-self.rs diff --git a/src/test/run-pass/methods/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs similarity index 100% rename from src/test/run-pass/methods/method-mut-self-modifies-mut-slice-lvalue.rs rename to src/test/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs diff --git a/src/test/run-pass/methods/method-normalize-bounds-issue-20604.rs b/src/test/ui/methods/method-normalize-bounds-issue-20604.rs similarity index 100% rename from src/test/run-pass/methods/method-normalize-bounds-issue-20604.rs rename to src/test/ui/methods/method-normalize-bounds-issue-20604.rs diff --git a/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs b/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs similarity index 99% rename from src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs rename to src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs index 8c8165a100..af362efe15 100644 --- a/src/test/run-pass/methods/method-probe-no-guessing-dyn-trait.rs +++ b/src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs @@ -1,3 +1,4 @@ +// run-pass // Check that method matching does not make "guesses" depending on // Deref impls that don't eventually end up being picked. diff --git a/src/test/run-pass/methods/method-projection.rs b/src/test/ui/methods/method-projection.rs similarity index 100% rename from src/test/run-pass/methods/method-projection.rs rename to src/test/ui/methods/method-projection.rs diff --git a/src/test/run-pass/methods/method-recursive-blanket-impl.rs b/src/test/ui/methods/method-recursive-blanket-impl.rs similarity index 100% rename from src/test/run-pass/methods/method-recursive-blanket-impl.rs rename to src/test/ui/methods/method-recursive-blanket-impl.rs diff --git a/src/test/run-pass/methods/method-self-arg-aux1.rs b/src/test/ui/methods/method-self-arg-aux1.rs similarity index 100% rename from src/test/run-pass/methods/method-self-arg-aux1.rs rename to src/test/ui/methods/method-self-arg-aux1.rs diff --git a/src/test/run-pass/methods/method-self-arg-aux2.rs b/src/test/ui/methods/method-self-arg-aux2.rs similarity index 100% rename from src/test/run-pass/methods/method-self-arg-aux2.rs rename to src/test/ui/methods/method-self-arg-aux2.rs diff --git a/src/test/run-pass/methods/method-self-arg-trait.rs b/src/test/ui/methods/method-self-arg-trait.rs similarity index 100% rename from src/test/run-pass/methods/method-self-arg-trait.rs rename to src/test/ui/methods/method-self-arg-trait.rs diff --git a/src/test/run-pass/methods/method-self-arg.rs b/src/test/ui/methods/method-self-arg.rs similarity index 100% rename from src/test/run-pass/methods/method-self-arg.rs rename to src/test/ui/methods/method-self-arg.rs diff --git a/src/test/ui/methods/method-trait-object-with-hrtb.rs b/src/test/ui/methods/method-trait-object-with-hrtb.rs index da2f13f5a2..d1bee676c2 100644 --- a/src/test/ui/methods/method-trait-object-with-hrtb.rs +++ b/src/test/ui/methods/method-trait-object-with-hrtb.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that method probing ObjectCandidate works in the presence of // auto traits and/or HRTBs. diff --git a/src/test/run-pass/methods/method-two-trait-defer-resolution-1.rs b/src/test/ui/methods/method-two-trait-defer-resolution-1.rs similarity index 100% rename from src/test/run-pass/methods/method-two-trait-defer-resolution-1.rs rename to src/test/ui/methods/method-two-trait-defer-resolution-1.rs diff --git a/src/test/run-pass/methods/method-two-trait-defer-resolution-2.rs b/src/test/ui/methods/method-two-trait-defer-resolution-2.rs similarity index 100% rename from src/test/run-pass/methods/method-two-trait-defer-resolution-2.rs rename to src/test/ui/methods/method-two-trait-defer-resolution-2.rs diff --git a/src/test/run-pass/methods/method-two-traits-distinguished-via-where-clause.rs b/src/test/ui/methods/method-two-traits-distinguished-via-where-clause.rs similarity index 100% rename from src/test/run-pass/methods/method-two-traits-distinguished-via-where-clause.rs rename to src/test/ui/methods/method-two-traits-distinguished-via-where-clause.rs diff --git a/src/test/run-pass/methods/method-where-clause.rs b/src/test/ui/methods/method-where-clause.rs similarity index 100% rename from src/test/run-pass/methods/method-where-clause.rs rename to src/test/ui/methods/method-where-clause.rs diff --git a/src/test/run-pass/mid-path-type-params.rs b/src/test/ui/mid-path-type-params.rs similarity index 97% rename from src/test/run-pass/mid-path-type-params.rs rename to src/test/ui/mid-path-type-params.rs index e8ed0424e4..a8128207c8 100644 --- a/src/test/run-pass/mid-path-type-params.rs +++ b/src/test/ui/mid-path-type-params.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/minmax-stability-issue-23687.rs b/src/test/ui/minmax-stability-issue-23687.rs similarity index 99% rename from src/test/run-pass/minmax-stability-issue-23687.rs rename to src/test/ui/minmax-stability-issue-23687.rs index d043a99688..9100bfbde9 100644 --- a/src/test/run-pass/minmax-stability-issue-23687.rs +++ b/src/test/ui/minmax-stability-issue-23687.rs @@ -1,3 +1,5 @@ +// run-pass + use std::fmt::Debug; use std::cmp::{self, PartialOrd, Ordering}; diff --git a/src/test/run-pass/mir/auxiliary/mir_external_refs.rs b/src/test/ui/mir/auxiliary/mir_external_refs.rs similarity index 100% rename from src/test/run-pass/mir/auxiliary/mir_external_refs.rs rename to src/test/ui/mir/auxiliary/mir_external_refs.rs diff --git a/src/test/run-pass/mir/mir-inlining/ice-issue-45493.rs b/src/test/ui/mir/mir-inlining/ice-issue-45493.rs similarity index 100% rename from src/test/run-pass/mir/mir-inlining/ice-issue-45493.rs rename to src/test/ui/mir/mir-inlining/ice-issue-45493.rs diff --git a/src/test/run-pass/mir/mir-inlining/ice-issue-45885.rs b/src/test/ui/mir/mir-inlining/ice-issue-45885.rs similarity index 100% rename from src/test/run-pass/mir/mir-inlining/ice-issue-45885.rs rename to src/test/ui/mir/mir-inlining/ice-issue-45885.rs diff --git a/src/test/run-pass/mir/mir-inlining/no-trait-method-issue-40473.rs b/src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs similarity index 100% rename from src/test/run-pass/mir/mir-inlining/no-trait-method-issue-40473.rs rename to src/test/ui/mir/mir-inlining/no-trait-method-issue-40473.rs diff --git a/src/test/run-pass/mir/mir-typeck-normalize-fn-sig.rs b/src/test/ui/mir/mir-typeck-normalize-fn-sig.rs similarity index 100% rename from src/test/run-pass/mir/mir-typeck-normalize-fn-sig.rs rename to src/test/ui/mir/mir-typeck-normalize-fn-sig.rs diff --git a/src/test/run-pass/mir/mir_adt_construction.rs b/src/test/ui/mir/mir_adt_construction.rs similarity index 100% rename from src/test/run-pass/mir/mir_adt_construction.rs rename to src/test/ui/mir/mir_adt_construction.rs diff --git a/src/test/run-pass/mir/mir_ascription_coercion.rs b/src/test/ui/mir/mir_ascription_coercion.rs similarity index 100% rename from src/test/run-pass/mir/mir_ascription_coercion.rs rename to src/test/ui/mir/mir_ascription_coercion.rs diff --git a/src/test/run-pass/mir/mir_augmented_assignments.rs b/src/test/ui/mir/mir_augmented_assignments.rs similarity index 100% rename from src/test/run-pass/mir/mir_augmented_assignments.rs rename to src/test/ui/mir/mir_augmented_assignments.rs diff --git a/src/test/run-pass/mir/mir_autoderef.rs b/src/test/ui/mir/mir_autoderef.rs similarity index 100% rename from src/test/run-pass/mir/mir_autoderef.rs rename to src/test/ui/mir/mir_autoderef.rs diff --git a/src/test/run-pass/mir/mir_boxing.rs b/src/test/ui/mir/mir_boxing.rs similarity index 100% rename from src/test/run-pass/mir/mir_boxing.rs rename to src/test/ui/mir/mir_boxing.rs diff --git a/src/test/run-pass/mir/mir_build_match_comparisons.rs b/src/test/ui/mir/mir_build_match_comparisons.rs similarity index 100% rename from src/test/run-pass/mir/mir_build_match_comparisons.rs rename to src/test/ui/mir/mir_build_match_comparisons.rs diff --git a/src/test/run-pass/mir/mir_call_with_associated_type.rs b/src/test/ui/mir/mir_call_with_associated_type.rs similarity index 100% rename from src/test/run-pass/mir/mir_call_with_associated_type.rs rename to src/test/ui/mir/mir_call_with_associated_type.rs diff --git a/src/test/run-pass/mir/mir_calls_to_shims.rs b/src/test/ui/mir/mir_calls_to_shims.rs similarity index 100% rename from src/test/run-pass/mir/mir_calls_to_shims.rs rename to src/test/ui/mir/mir_calls_to_shims.rs diff --git a/src/test/run-pass/mir/mir_cast_fn_ret.rs b/src/test/ui/mir/mir_cast_fn_ret.rs similarity index 100% rename from src/test/run-pass/mir/mir_cast_fn_ret.rs rename to src/test/ui/mir/mir_cast_fn_ret.rs diff --git a/src/test/run-pass/mir/mir_codegen_array.rs b/src/test/ui/mir/mir_codegen_array.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_array.rs rename to src/test/ui/mir/mir_codegen_array.rs diff --git a/src/test/run-pass/mir/mir_codegen_array_2.rs b/src/test/ui/mir/mir_codegen_array_2.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_array_2.rs rename to src/test/ui/mir/mir_codegen_array_2.rs diff --git a/src/test/run-pass/mir/mir_codegen_call_converging.rs b/src/test/ui/mir/mir_codegen_call_converging.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_call_converging.rs rename to src/test/ui/mir/mir_codegen_call_converging.rs diff --git a/src/test/run-pass/mir/mir_codegen_calls.rs b/src/test/ui/mir/mir_codegen_calls.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_calls.rs rename to src/test/ui/mir/mir_codegen_calls.rs diff --git a/src/test/run-pass/mir/mir_codegen_calls_variadic.rs b/src/test/ui/mir/mir_codegen_calls_variadic.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_calls_variadic.rs rename to src/test/ui/mir/mir_codegen_calls_variadic.rs diff --git a/src/test/run-pass/mir/mir_codegen_critical_edge.rs b/src/test/ui/mir/mir_codegen_critical_edge.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_critical_edge.rs rename to src/test/ui/mir/mir_codegen_critical_edge.rs diff --git a/src/test/run-pass/mir/mir_codegen_spike1.rs b/src/test/ui/mir/mir_codegen_spike1.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_spike1.rs rename to src/test/ui/mir/mir_codegen_spike1.rs diff --git a/src/test/run-pass/mir/mir_codegen_switch.rs b/src/test/ui/mir/mir_codegen_switch.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_switch.rs rename to src/test/ui/mir/mir_codegen_switch.rs diff --git a/src/test/run-pass/mir/mir_codegen_switchint.rs b/src/test/ui/mir/mir_codegen_switchint.rs similarity index 100% rename from src/test/run-pass/mir/mir_codegen_switchint.rs rename to src/test/ui/mir/mir_codegen_switchint.rs diff --git a/src/test/run-pass/mir/mir_coercion_casts.rs b/src/test/ui/mir/mir_coercion_casts.rs similarity index 100% rename from src/test/run-pass/mir/mir_coercion_casts.rs rename to src/test/ui/mir/mir_coercion_casts.rs diff --git a/src/test/run-pass/mir/mir_coercions.rs b/src/test/ui/mir/mir_coercions.rs similarity index 100% rename from src/test/run-pass/mir/mir_coercions.rs rename to src/test/ui/mir/mir_coercions.rs diff --git a/src/test/run-pass/mir/mir_constval_adts.rs b/src/test/ui/mir/mir_constval_adts.rs similarity index 100% rename from src/test/run-pass/mir/mir_constval_adts.rs rename to src/test/ui/mir/mir_constval_adts.rs diff --git a/src/test/run-pass/mir/mir_drop_order.rs b/src/test/ui/mir/mir_drop_order.rs similarity index 100% rename from src/test/run-pass/mir/mir_drop_order.rs rename to src/test/ui/mir/mir_drop_order.rs diff --git a/src/test/run-pass/mir/mir_early_return_scope.rs b/src/test/ui/mir/mir_early_return_scope.rs similarity index 100% rename from src/test/run-pass/mir/mir_early_return_scope.rs rename to src/test/ui/mir/mir_early_return_scope.rs diff --git a/src/test/run-pass/mir/mir_fat_ptr.rs b/src/test/ui/mir/mir_fat_ptr.rs similarity index 100% rename from src/test/run-pass/mir/mir_fat_ptr.rs rename to src/test/ui/mir/mir_fat_ptr.rs diff --git a/src/test/run-pass/mir/mir_fat_ptr_drop.rs b/src/test/ui/mir/mir_fat_ptr_drop.rs similarity index 100% rename from src/test/run-pass/mir/mir_fat_ptr_drop.rs rename to src/test/ui/mir/mir_fat_ptr_drop.rs diff --git a/src/test/run-pass/mir/mir_heavy_promoted.rs b/src/test/ui/mir/mir_heavy_promoted.rs similarity index 100% rename from src/test/run-pass/mir/mir_heavy_promoted.rs rename to src/test/ui/mir/mir_heavy_promoted.rs diff --git a/src/test/run-pass/mir/mir_match_arm_guard.rs b/src/test/ui/mir/mir_match_arm_guard.rs similarity index 100% rename from src/test/run-pass/mir/mir_match_arm_guard.rs rename to src/test/ui/mir/mir_match_arm_guard.rs diff --git a/src/test/run-pass/mir/mir_match_test.rs b/src/test/ui/mir/mir_match_test.rs similarity index 100% rename from src/test/run-pass/mir/mir_match_test.rs rename to src/test/ui/mir/mir_match_test.rs diff --git a/src/test/run-pass/mir/mir_misc_casts.rs b/src/test/ui/mir/mir_misc_casts.rs similarity index 100% rename from src/test/run-pass/mir/mir_misc_casts.rs rename to src/test/ui/mir/mir_misc_casts.rs diff --git a/src/test/run-pass/mir/mir_overflow_off.rs b/src/test/ui/mir/mir_overflow_off.rs similarity index 100% rename from src/test/run-pass/mir/mir_overflow_off.rs rename to src/test/ui/mir/mir_overflow_off.rs diff --git a/src/test/run-pass/mir/mir_raw_fat_ptr.rs b/src/test/ui/mir/mir_raw_fat_ptr.rs similarity index 100% rename from src/test/run-pass/mir/mir_raw_fat_ptr.rs rename to src/test/ui/mir/mir_raw_fat_ptr.rs diff --git a/src/test/run-pass/mir/mir_refs_correct.rs b/src/test/ui/mir/mir_refs_correct.rs similarity index 100% rename from src/test/run-pass/mir/mir_refs_correct.rs rename to src/test/ui/mir/mir_refs_correct.rs diff --git a/src/test/run-pass/mir/mir_small_agg_arg.rs b/src/test/ui/mir/mir_small_agg_arg.rs similarity index 100% rename from src/test/run-pass/mir/mir_small_agg_arg.rs rename to src/test/ui/mir/mir_small_agg_arg.rs diff --git a/src/test/run-pass/mir/mir_static_subtype.rs b/src/test/ui/mir/mir_static_subtype.rs similarity index 92% rename from src/test/run-pass/mir/mir_static_subtype.rs rename to src/test/ui/mir/mir_static_subtype.rs index 5b1ccd7ddf..d471b8f149 100644 --- a/src/test/run-pass/mir/mir_static_subtype.rs +++ b/src/test/ui/mir/mir_static_subtype.rs @@ -1,3 +1,4 @@ +// run-pass // Test that subtyping the body of a static doesn't cause an ICE. fn foo(_ : &()) {} diff --git a/src/test/run-pass/mir/mir_struct_with_assoc_ty.rs b/src/test/ui/mir/mir_struct_with_assoc_ty.rs similarity index 100% rename from src/test/run-pass/mir/mir_struct_with_assoc_ty.rs rename to src/test/ui/mir/mir_struct_with_assoc_ty.rs diff --git a/src/test/run-pass/mir/mir_temp_promotions.rs b/src/test/ui/mir/mir_temp_promotions.rs similarity index 100% rename from src/test/run-pass/mir/mir_temp_promotions.rs rename to src/test/ui/mir/mir_temp_promotions.rs diff --git a/src/test/run-pass/mir/mir_void_return.rs b/src/test/ui/mir/mir_void_return.rs similarity index 100% rename from src/test/run-pass/mir/mir_void_return.rs rename to src/test/ui/mir/mir_void_return.rs diff --git a/src/test/run-pass/mir/mir_void_return_2.rs b/src/test/ui/mir/mir_void_return_2.rs similarity index 100% rename from src/test/run-pass/mir/mir_void_return_2.rs rename to src/test/ui/mir/mir_void_return_2.rs diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr index a9347926bd..79a0807c33 100644 --- a/src/test/ui/mismatched_types/issue-38371.stderr +++ b/src/test/ui/mismatched_types/issue-38371.stderr @@ -2,11 +2,13 @@ error[E0308]: mismatched types --> $DIR/issue-38371.rs:4:8 | LL | fn foo(&foo: Foo) { - | ^^^^ expected struct `Foo`, found reference + | ^^^^------ + | | + | expected struct `Foo`, found reference + | help: did you mean `foo`: `&Foo` | = note: expected type `Foo` found type `&_` - = help: did you mean `foo: &Foo`? error[E0308]: mismatched types --> $DIR/issue-38371.rs:18:9 diff --git a/src/test/ui/missing/missing-allocator.stderr b/src/test/ui/missing/missing-allocator.stderr index 11e0085d1c..59648c42a5 100644 --- a/src/test/ui/missing/missing-allocator.stderr +++ b/src/test/ui/missing/missing-allocator.stderr @@ -1,4 +1,4 @@ -error: no global memory allocator found but one is required; link to std or add #[global_allocator] to a static item that implements the GlobalAlloc trait. +error: no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait. error: aborting due to previous error diff --git a/src/test/ui/missing/missing-return.stderr b/src/test/ui/missing/missing-return.stderr index 42466e2fc6..3c8ecdcfbc 100644 --- a/src/test/ui/missing/missing-return.stderr +++ b/src/test/ui/missing/missing-return.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { } | - ^^^^^ expected isize, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `isize` found type `()` diff --git a/src/test/ui/missing/missing-semicolon-warning.rs b/src/test/ui/missing/missing-semicolon-warning.rs index 11204af702..d962a52139 100644 --- a/src/test/ui/missing/missing-semicolon-warning.rs +++ b/src/test/ui/missing/missing-semicolon-warning.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] macro_rules! m { diff --git a/src/test/ui/missing_debug_impls.stderr b/src/test/ui/missing_debug_impls.stderr index bb8390a8f3..b953058778 100644 --- a/src/test/ui/missing_debug_impls.stderr +++ b/src/test/ui/missing_debug_impls.stderr @@ -1,4 +1,4 @@ -error: type does not implement `fmt::Debug`; consider adding #[derive(Debug)] or a manual implementation +error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation --> $DIR/missing_debug_impls.rs:7:1 | LL | pub enum A {} @@ -10,7 +10,7 @@ note: lint level defined here LL | #![deny(missing_debug_implementations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: type does not implement `fmt::Debug`; consider adding #[derive(Debug)] or a manual implementation +error: type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation --> $DIR/missing_debug_impls.rs:20:1 | LL | pub struct Foo; diff --git a/src/test/run-pass/modules/auxiliary/two_macros_2.rs b/src/test/ui/modules/auxiliary/two_macros_2.rs similarity index 100% rename from src/test/run-pass/modules/auxiliary/two_macros_2.rs rename to src/test/ui/modules/auxiliary/two_macros_2.rs diff --git a/src/test/run-pass/modules/mod-inside-fn.rs b/src/test/ui/modules/mod-inside-fn.rs similarity index 100% rename from src/test/run-pass/modules/mod-inside-fn.rs rename to src/test/ui/modules/mod-inside-fn.rs diff --git a/src/test/run-pass/modules/mod-view-items.rs b/src/test/ui/modules/mod-view-items.rs similarity index 100% rename from src/test/run-pass/modules/mod-view-items.rs rename to src/test/ui/modules/mod-view-items.rs diff --git a/src/test/run-pass/modules/mod_dir_implicit.rs b/src/test/ui/modules/mod_dir_implicit.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_implicit.rs rename to src/test/ui/modules/mod_dir_implicit.rs diff --git a/src/test/run-pass/modules/mod_dir_implicit_aux/compiletest-ignore-dir b/src/test/ui/modules/mod_dir_implicit_aux/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/modules/mod_dir_implicit_aux/compiletest-ignore-dir rename to src/test/ui/modules/mod_dir_implicit_aux/compiletest-ignore-dir diff --git a/src/test/run-pass/modules/mod_dir_implicit_aux/mod.rs b/src/test/ui/modules/mod_dir_implicit_aux/mod.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_implicit_aux/mod.rs rename to src/test/ui/modules/mod_dir_implicit_aux/mod.rs diff --git a/src/test/run-pass/modules/mod_dir_path.rs b/src/test/ui/modules/mod_dir_path.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_path.rs rename to src/test/ui/modules/mod_dir_path.rs diff --git a/src/test/run-pass/modules/mod_dir_path2.rs b/src/test/ui/modules/mod_dir_path2.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_path2.rs rename to src/test/ui/modules/mod_dir_path2.rs diff --git a/src/test/run-pass/modules/mod_dir_path3.rs b/src/test/ui/modules/mod_dir_path3.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_path3.rs rename to src/test/ui/modules/mod_dir_path3.rs diff --git a/src/test/run-pass/modules/mod_dir_path_multi.rs b/src/test/ui/modules/mod_dir_path_multi.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_path_multi.rs rename to src/test/ui/modules/mod_dir_path_multi.rs diff --git a/src/test/run-pass/modules/mod_dir_recursive.rs b/src/test/ui/modules/mod_dir_recursive.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_recursive.rs rename to src/test/ui/modules/mod_dir_recursive.rs diff --git a/src/test/run-pass/modules/mod_dir_simple.rs b/src/test/ui/modules/mod_dir_simple.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_simple.rs rename to src/test/ui/modules/mod_dir_simple.rs diff --git a/src/test/run-pass/modules/mod_dir_simple/compiletest-ignore-dir b/src/test/ui/modules/mod_dir_simple/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/modules/mod_dir_simple/compiletest-ignore-dir rename to src/test/ui/modules/mod_dir_simple/compiletest-ignore-dir diff --git a/src/test/run-pass/modules/mod_dir_simple/load_another_mod.rs b/src/test/ui/modules/mod_dir_simple/load_another_mod.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_simple/load_another_mod.rs rename to src/test/ui/modules/mod_dir_simple/load_another_mod.rs diff --git a/src/test/run-pass/modules/mod_dir_simple/test.rs b/src/test/ui/modules/mod_dir_simple/test.rs similarity index 100% rename from src/test/run-pass/modules/mod_dir_simple/test.rs rename to src/test/ui/modules/mod_dir_simple/test.rs diff --git a/src/test/run-pass/modules/mod_file.rs b/src/test/ui/modules/mod_file.rs similarity index 100% rename from src/test/run-pass/modules/mod_file.rs rename to src/test/ui/modules/mod_file.rs diff --git a/src/test/run-pass/modules/mod_file_aux.rs b/src/test/ui/modules/mod_file_aux.rs similarity index 100% rename from src/test/run-pass/modules/mod_file_aux.rs rename to src/test/ui/modules/mod_file_aux.rs diff --git a/src/test/run-pass/modules/mod_file_with_path_attr.rs b/src/test/ui/modules/mod_file_with_path_attr.rs similarity index 100% rename from src/test/run-pass/modules/mod_file_with_path_attr.rs rename to src/test/ui/modules/mod_file_with_path_attr.rs diff --git a/src/test/run-pass/modules/module-polymorphism3-files/compiletest-ignore-dir b/src/test/ui/modules/module-polymorphism3-files/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/modules/module-polymorphism3-files/compiletest-ignore-dir rename to src/test/ui/modules/module-polymorphism3-files/compiletest-ignore-dir diff --git a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs similarity index 58% rename from src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs rename to src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs index ae9811ac02..49d2b3d4b8 100644 --- a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f32.rs +++ b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs @@ -1 +1,3 @@ +// run-pass + pub type T = f32; diff --git a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs similarity index 58% rename from src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs rename to src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs index df276449c4..e2aad480e3 100644 --- a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_f64.rs +++ b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs @@ -1 +1,3 @@ +// run-pass + pub type T = f64; diff --git a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs similarity index 60% rename from src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs rename to src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs index 7a0d84f3a5..5828718cdd 100644 --- a/src/test/run-pass/modules/module-polymorphism3-files/float-template/inst_float.rs +++ b/src/test/ui/modules/module-polymorphism3-files/float-template/inst_float.rs @@ -1 +1,3 @@ +// run-pass + pub type T = float; diff --git a/src/test/run-pass/monad.rs b/src/test/ui/monad.rs similarity index 98% rename from src/test/run-pass/monad.rs rename to src/test/ui/monad.rs index f0781c2920..5d0612cf8d 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/ui/monad.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/monomorphize-abi-alignment.rs b/src/test/ui/monomorphize-abi-alignment.rs similarity index 98% rename from src/test/run-pass/monomorphize-abi-alignment.rs rename to src/test/ui/monomorphize-abi-alignment.rs index a26f324f7d..637b09fc04 100644 --- a/src/test/run-pass/monomorphize-abi-alignment.rs +++ b/src/test/ui/monomorphize-abi-alignment.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_upper_case_globals)] /*! * On x86_64-linux-gnu and possibly other platforms, structs get 8-byte "preferred" alignment, diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/ui/monomorphized-callees-with-ty-params-3314.rs similarity index 97% rename from src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs rename to src/test/ui/monomorphized-callees-with-ty-params-3314.rs index ec7ff2d8a5..bc314a39d8 100644 --- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs +++ b/src/test/ui/monomorphized-callees-with-ty-params-3314.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 trait Serializer { diff --git a/src/test/run-pass/moves/move-1-unique.rs b/src/test/ui/moves/move-1-unique.rs similarity index 100% rename from src/test/run-pass/moves/move-1-unique.rs rename to src/test/ui/moves/move-1-unique.rs diff --git a/src/test/run-pass/moves/move-2-unique.rs b/src/test/ui/moves/move-2-unique.rs similarity index 100% rename from src/test/run-pass/moves/move-2-unique.rs rename to src/test/ui/moves/move-2-unique.rs diff --git a/src/test/run-pass/moves/move-2.rs b/src/test/ui/moves/move-2.rs similarity index 100% rename from src/test/run-pass/moves/move-2.rs rename to src/test/ui/moves/move-2.rs diff --git a/src/test/run-pass/moves/move-3-unique.rs b/src/test/ui/moves/move-3-unique.rs similarity index 100% rename from src/test/run-pass/moves/move-3-unique.rs rename to src/test/ui/moves/move-3-unique.rs diff --git a/src/test/run-pass/moves/move-4-unique.rs b/src/test/ui/moves/move-4-unique.rs similarity index 100% rename from src/test/run-pass/moves/move-4-unique.rs rename to src/test/ui/moves/move-4-unique.rs diff --git a/src/test/run-pass/moves/move-4.rs b/src/test/ui/moves/move-4.rs similarity index 100% rename from src/test/run-pass/moves/move-4.rs rename to src/test/ui/moves/move-4.rs diff --git a/src/test/run-pass/moves/move-arg-2-unique.rs b/src/test/ui/moves/move-arg-2-unique.rs similarity index 100% rename from src/test/run-pass/moves/move-arg-2-unique.rs rename to src/test/ui/moves/move-arg-2-unique.rs diff --git a/src/test/run-pass/moves/move-arg-2.rs b/src/test/ui/moves/move-arg-2.rs similarity index 100% rename from src/test/run-pass/moves/move-arg-2.rs rename to src/test/ui/moves/move-arg-2.rs diff --git a/src/test/run-pass/moves/move-arg.rs b/src/test/ui/moves/move-arg.rs similarity index 100% rename from src/test/run-pass/moves/move-arg.rs rename to src/test/ui/moves/move-arg.rs diff --git a/src/test/run-pass/moves/move-nullary-fn.rs b/src/test/ui/moves/move-nullary-fn.rs similarity index 100% rename from src/test/run-pass/moves/move-nullary-fn.rs rename to src/test/ui/moves/move-nullary-fn.rs diff --git a/src/test/run-pass/moves/move-out-of-field.rs b/src/test/ui/moves/move-out-of-field.rs similarity index 100% rename from src/test/run-pass/moves/move-out-of-field.rs rename to src/test/ui/moves/move-out-of-field.rs diff --git a/src/test/run-pass/moves/move-scalar.rs b/src/test/ui/moves/move-scalar.rs similarity index 100% rename from src/test/run-pass/moves/move-scalar.rs rename to src/test/ui/moves/move-scalar.rs diff --git a/src/test/run-pass/moves/moves-based-on-type-capture-clause.rs b/src/test/ui/moves/moves-based-on-type-capture-clause.rs similarity index 100% rename from src/test/run-pass/moves/moves-based-on-type-capture-clause.rs rename to src/test/ui/moves/moves-based-on-type-capture-clause.rs diff --git a/src/test/run-pass/mpsc_stress.rs b/src/test/ui/mpsc_stress.rs similarity index 99% rename from src/test/run-pass/mpsc_stress.rs rename to src/test/ui/mpsc_stress.rs index cf8d92b227..bce5fdcd11 100644 --- a/src/test/run-pass/mpsc_stress.rs +++ b/src/test/ui/mpsc_stress.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags:--test // ignore-emscripten // ignore-sgx no thread sleep support diff --git a/src/test/run-pass/msvc-data-only.rs b/src/test/ui/msvc-data-only.rs similarity index 92% rename from src/test/run-pass/msvc-data-only.rs rename to src/test/ui/msvc-data-only.rs index ae4103e96c..f668b0b068 100644 --- a/src/test/run-pass/msvc-data-only.rs +++ b/src/test/ui/msvc-data-only.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:msvc-data-only-lib.rs extern crate msvc_data_only_lib; diff --git a/src/test/run-pass/multi-panic.rs b/src/test/ui/multi-panic.rs similarity index 99% rename from src/test/run-pass/multi-panic.rs rename to src/test/ui/multi-panic.rs index 8bc0002065..e4b41e4180 100644 --- a/src/test/run-pass/multi-panic.rs +++ b/src/test/ui/multi-panic.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes diff --git a/src/test/run-pass/multibyte.rs b/src/test/ui/multibyte.rs similarity index 91% rename from src/test/run-pass/multibyte.rs rename to src/test/ui/multibyte.rs index 889f0cb75c..7e3a577f9f 100644 --- a/src/test/run-pass/multibyte.rs +++ b/src/test/ui/multibyte.rs @@ -1,3 +1,4 @@ +// run-pass // // Test that multibyte characters don't crash the compiler diff --git a/src/test/run-pass/multidispatch-conditional-impl-not-considered.rs b/src/test/ui/multidispatch-conditional-impl-not-considered.rs similarity index 96% rename from src/test/run-pass/multidispatch-conditional-impl-not-considered.rs rename to src/test/ui/multidispatch-conditional-impl-not-considered.rs index 72aa9edd0f..f845e198aa 100644 --- a/src/test/run-pass/multidispatch-conditional-impl-not-considered.rs +++ b/src/test/ui/multidispatch-conditional-impl-not-considered.rs @@ -1,3 +1,4 @@ +// run-pass // Test that we correctly ignore the blanket impl // because (in this case) `T` does not impl `Clone`. // diff --git a/src/test/run-pass/multidispatch1.rs b/src/test/ui/multidispatch1.rs similarity index 97% rename from src/test/run-pass/multidispatch1.rs rename to src/test/ui/multidispatch1.rs index ac22aeac12..f2469e1490 100644 --- a/src/test/run-pass/multidispatch1.rs +++ b/src/test/ui/multidispatch1.rs @@ -1,3 +1,5 @@ +// run-pass + use std::fmt::Debug; trait MyTrait { diff --git a/src/test/run-pass/multidispatch2.rs b/src/test/ui/multidispatch2.rs similarity index 97% rename from src/test/run-pass/multidispatch2.rs rename to src/test/ui/multidispatch2.rs index 517f815748..20608aabb3 100644 --- a/src/test/run-pass/multidispatch2.rs +++ b/src/test/ui/multidispatch2.rs @@ -1,3 +1,5 @@ +// run-pass + use std::fmt::Debug; use std::default::Default; diff --git a/src/test/run-pass/multiline-comment.rs b/src/test/ui/multiline-comment.rs similarity index 88% rename from src/test/run-pass/multiline-comment.rs rename to src/test/ui/multiline-comment.rs index 76f9284eb3..01aaac2823 100644 --- a/src/test/run-pass/multiline-comment.rs +++ b/src/test/ui/multiline-comment.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 /* diff --git a/src/test/ui/multiple-main-2.rs b/src/test/ui/multiple-main-2.rs index 6bae664ab7..e4685b1e00 100644 --- a/src/test/ui/multiple-main-2.rs +++ b/src/test/ui/multiple-main-2.rs @@ -5,5 +5,5 @@ fn bar() { } #[main] -fn foo() { //~ ERROR multiple functions with a #[main] attribute +fn foo() { //~ ERROR multiple functions with a `#[main]` attribute } diff --git a/src/test/ui/multiple-main-2.stderr b/src/test/ui/multiple-main-2.stderr index ae33e01cd2..24bc9a8878 100644 --- a/src/test/ui/multiple-main-2.stderr +++ b/src/test/ui/multiple-main-2.stderr @@ -1,13 +1,13 @@ -error[E0137]: multiple functions with a #[main] attribute +error[E0137]: multiple functions with a `#[main]` attribute --> $DIR/multiple-main-2.rs:8:1 | LL | / fn bar() { LL | | } - | |_- first #[main] function + | |_- first `#[main]` function ... LL | / fn foo() { LL | | } - | |_^ additional #[main] function + | |_^ additional `#[main]` function error: aborting due to previous error diff --git a/src/test/ui/multiple-main-3.rs b/src/test/ui/multiple-main-3.rs index dbcf1ef489..d1b5ae9a83 100644 --- a/src/test/ui/multiple-main-3.rs +++ b/src/test/ui/multiple-main-3.rs @@ -6,6 +6,6 @@ fn main1() { mod foo { #[main] - fn main2() { //~ ERROR multiple functions with a #[main] attribute + fn main2() { //~ ERROR multiple functions with a `#[main]` attribute } } diff --git a/src/test/ui/multiple-main-3.stderr b/src/test/ui/multiple-main-3.stderr index b85637b8a5..ec171b76a2 100644 --- a/src/test/ui/multiple-main-3.stderr +++ b/src/test/ui/multiple-main-3.stderr @@ -1,13 +1,13 @@ -error[E0137]: multiple functions with a #[main] attribute +error[E0137]: multiple functions with a `#[main]` attribute --> $DIR/multiple-main-3.rs:9:5 | LL | / fn main1() { LL | | } - | |_- first #[main] function + | |_- first `#[main]` function ... LL | / fn main2() { LL | | } - | |_____^ additional #[main] function + | |_____^ additional `#[main]` function error: aborting due to previous error diff --git a/src/test/run-pass/multiple-reprs.rs b/src/test/ui/multiple-reprs.rs similarity index 99% rename from src/test/run-pass/multiple-reprs.rs rename to src/test/ui/multiple-reprs.rs index 97c5d930f7..4be503a0ef 100644 --- a/src/test/run-pass/multiple-reprs.rs +++ b/src/test/ui/multiple-reprs.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] use std::mem::{size_of, align_of}; diff --git a/src/test/run-pass/mut-function-arguments.rs b/src/test/ui/mut-function-arguments.rs similarity index 95% rename from src/test/run-pass/mut-function-arguments.rs rename to src/test/ui/mut-function-arguments.rs index 924d754b32..620d00edbb 100644 --- a/src/test/run-pass/mut-function-arguments.rs +++ b/src/test/ui/mut-function-arguments.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] fn f(mut y: Box) { diff --git a/src/test/run-pass/mut-vstore-expr.rs b/src/test/ui/mut-vstore-expr.rs similarity index 88% rename from src/test/run-pass/mut-vstore-expr.rs rename to src/test/ui/mut-vstore-expr.rs index d598e3b88d..75b309a483 100644 --- a/src/test/run-pass/mut-vstore-expr.rs +++ b/src/test/ui/mut-vstore-expr.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 pub fn main() { diff --git a/src/test/run-pass/mutual-recursion-group.rs b/src/test/ui/mutual-recursion-group.rs similarity index 95% rename from src/test/run-pass/mutual-recursion-group.rs rename to src/test/ui/mutual-recursion-group.rs index 3be87b5a49..86b0f1d840 100644 --- a/src/test/run-pass/mutual-recursion-group.rs +++ b/src/test/ui/mutual-recursion-group.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/run-pass/native-print-no-runtime.rs b/src/test/ui/native-print-no-runtime.rs similarity index 89% rename from src/test/run-pass/native-print-no-runtime.rs rename to src/test/ui/native-print-no-runtime.rs index e4d7eb82c6..f17c9fa6ca 100644 --- a/src/test/run-pass/native-print-no-runtime.rs +++ b/src/test/ui/native-print-no-runtime.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(start)] #[start] diff --git a/src/test/run-pass/negative.rs b/src/test/ui/negative.rs similarity index 85% rename from src/test/run-pass/negative.rs rename to src/test/ui/negative.rs index cc75d2ee86..9601e9118a 100644 --- a/src/test/run-pass/negative.rs +++ b/src/test/ui/negative.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { match -5 { -5 => {} diff --git a/src/test/run-pass/nested-block-comment.rs b/src/test/ui/nested-block-comment.rs similarity index 92% rename from src/test/run-pass/nested-block-comment.rs rename to src/test/ui/nested-block-comment.rs index 62d038024a..f8dfb5fa8c 100644 --- a/src/test/run-pass/nested-block-comment.rs +++ b/src/test/ui/nested-block-comment.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 /* This test checks that nested comments are supported diff --git a/src/test/run-pass/nested-class.rs b/src/test/ui/nested-class.rs similarity index 96% rename from src/test/run-pass/nested-class.rs rename to src/test/ui/nested-class.rs index 1b98291c37..303273618e 100644 --- a/src/test/run-pass/nested-class.rs +++ b/src/test/ui/nested-class.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] pub fn main() { diff --git a/src/test/run-pass/nested-function-names-issue-8587.rs b/src/test/ui/nested-function-names-issue-8587.rs similarity index 98% rename from src/test/run-pass/nested-function-names-issue-8587.rs rename to src/test/ui/nested-function-names-issue-8587.rs index 7a6164383d..8fafd41d9b 100644 --- a/src/test/run-pass/nested-function-names-issue-8587.rs +++ b/src/test/ui/nested-function-names-issue-8587.rs @@ -1,3 +1,4 @@ +// run-pass // Make sure nested functions are separate, even if they have // equal name. // diff --git a/src/test/run-pass/nested_item_main.rs b/src/test/ui/nested_item_main.rs similarity index 93% rename from src/test/run-pass/nested_item_main.rs rename to src/test/ui/nested_item_main.rs index 225619ad47..2fe00aede0 100644 --- a/src/test/run-pass/nested_item_main.rs +++ b/src/test/ui/nested_item_main.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:nested_item.rs diff --git a/src/test/ui/never-assign-dead-code.rs b/src/test/ui/never-assign-dead-code.rs index 6b047c3506..fd5fbc3061 100644 --- a/src/test/ui/never-assign-dead-code.rs +++ b/src/test/ui/never-assign-dead-code.rs @@ -1,7 +1,7 @@ // Test that an assignment of type ! makes the rest of the block dead code. #![feature(never_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/never-assign-dead-code.stderr b/src/test/ui/never-assign-dead-code.stderr index 6735310da8..779780a90a 100644 --- a/src/test/ui/never-assign-dead-code.stderr +++ b/src/test/ui/never-assign-dead-code.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unreachable_code)] implied by #[warn(unused)] + = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` warning: unreachable expression --> $DIR/never-assign-dead-code.rs:10:5 @@ -28,5 +28,5 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unused_variables)] implied by #[warn(unused)] + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` diff --git a/src/test/run-pass/never-result.rs b/src/test/ui/never-result.rs similarity index 96% rename from src/test/run-pass/never-result.rs rename to src/test/ui/never-result.rs index 808377ffa1..98ce326aa6 100644 --- a/src/test/run-pass/never-result.rs +++ b/src/test/ui/never-result.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] #![allow(unreachable_code)] // Test that we can extract a ! through pattern matching then use it as several different types. diff --git a/src/test/run-pass/never-type-rvalues.rs b/src/test/ui/never-type-rvalues.rs similarity index 97% rename from src/test/run-pass/never-type-rvalues.rs rename to src/test/ui/never-type-rvalues.rs index 2de8567924..9ccc73dbf9 100644 --- a/src/test/run-pass/never-type-rvalues.rs +++ b/src/test/ui/never-type-rvalues.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(never_type)] #![allow(dead_code)] #![allow(path_statements)] diff --git a/src/test/run-pass/never_coercions.rs b/src/test/ui/never_coercions.rs similarity index 95% rename from src/test/run-pass/never_coercions.rs rename to src/test/ui/never_coercions.rs index f32e297381..105c386353 100644 --- a/src/test/run-pass/never_coercions.rs +++ b/src/test/ui/never_coercions.rs @@ -1,3 +1,4 @@ +// run-pass // Test that having something of type ! doesn't screw up type-checking and that it coerces to the // LUB type of the other match arms. diff --git a/src/test/ui/never_transmute_never.rs b/src/test/ui/never_transmute_never.rs index ef78eaa212..5bad756b87 100644 --- a/src/test/ui/never_transmute_never.rs +++ b/src/test/ui/never_transmute_never.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type="lib"] diff --git a/src/test/run-pass/new-box-syntax.rs b/src/test/ui/new-box-syntax.rs similarity index 97% rename from src/test/run-pass/new-box-syntax.rs rename to src/test/ui/new-box-syntax.rs index a39803c2eb..418cf554b4 100644 --- a/src/test/run-pass/new-box-syntax.rs +++ b/src/test/ui/new-box-syntax.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 /* Any copyright is dedicated to the Public Domain. diff --git a/src/test/run-pass/new-box.rs b/src/test/ui/new-box.rs similarity index 97% rename from src/test/run-pass/new-box.rs rename to src/test/ui/new-box.rs index 5539518c37..d11f0d045a 100644 --- a/src/test/run-pass/new-box.rs +++ b/src/test/ui/new-box.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] fn f(x: Box) { diff --git a/src/test/run-pass/new-impl-syntax.rs b/src/test/ui/new-impl-syntax.rs similarity index 97% rename from src/test/run-pass/new-impl-syntax.rs rename to src/test/ui/new-impl-syntax.rs index d02136d930..e1f2bea9af 100644 --- a/src/test/run-pass/new-impl-syntax.rs +++ b/src/test/ui/new-impl-syntax.rs @@ -1,3 +1,5 @@ +// run-pass + use std::fmt; struct Thingy { diff --git a/src/test/run-pass/new-import-syntax.rs b/src/test/ui/new-import-syntax.rs similarity index 78% rename from src/test/run-pass/new-import-syntax.rs rename to src/test/ui/new-import-syntax.rs index 67cf5ab2e1..f132ed57ce 100644 --- a/src/test/run-pass/new-import-syntax.rs +++ b/src/test/ui/new-import-syntax.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { println!("Hello world!"); } diff --git a/src/test/run-pass/new-style-constants.rs b/src/test/ui/new-style-constants.rs similarity index 83% rename from src/test/run-pass/new-style-constants.rs rename to src/test/ui/new-style-constants.rs index 1ded0cd1c8..82ed7b5574 100644 --- a/src/test/run-pass/new-style-constants.rs +++ b/src/test/ui/new-style-constants.rs @@ -1,3 +1,5 @@ +// run-pass + static FOO: isize = 3; pub fn main() { diff --git a/src/test/run-pass/new-unicode-escapes.rs b/src/test/ui/new-unicode-escapes.rs similarity index 95% rename from src/test/run-pass/new-unicode-escapes.rs rename to src/test/ui/new-unicode-escapes.rs index 1bce71a9ed..850b0de44b 100644 --- a/src/test/run-pass/new-unicode-escapes.rs +++ b/src/test/ui/new-unicode-escapes.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let s = "\u{2603}"; assert_eq!(s, "☃"); diff --git a/src/test/run-pass/new-unsafe-pointers.rs b/src/test/ui/new-unsafe-pointers.rs similarity index 91% rename from src/test/run-pass/new-unsafe-pointers.rs rename to src/test/ui/new-unsafe-pointers.rs index a80ef14108..d99eb4cbd1 100644 --- a/src/test/run-pass/new-unsafe-pointers.rs +++ b/src/test/ui/new-unsafe-pointers.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 fn main() { diff --git a/src/test/run-pass/newlambdas-ret-infer.rs b/src/test/ui/newlambdas-ret-infer.rs similarity index 94% rename from src/test/run-pass/newlambdas-ret-infer.rs rename to src/test/ui/newlambdas-ret-infer.rs index 79c9f7dc01..9b629838ff 100644 --- a/src/test/run-pass/newlambdas-ret-infer.rs +++ b/src/test/ui/newlambdas-ret-infer.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Test that the lambda kind is inferred correctly as a return // expression diff --git a/src/test/run-pass/newlambdas-ret-infer2.rs b/src/test/ui/newlambdas-ret-infer2.rs similarity index 94% rename from src/test/run-pass/newlambdas-ret-infer2.rs rename to src/test/ui/newlambdas-ret-infer2.rs index 104f5be776..abe31a05f2 100644 --- a/src/test/run-pass/newlambdas-ret-infer2.rs +++ b/src/test/ui/newlambdas-ret-infer2.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Test that the lambda kind is inferred correctly as a return // expression diff --git a/src/test/run-pass/newlambdas.rs b/src/test/ui/newlambdas.rs similarity index 95% rename from src/test/run-pass/newlambdas.rs rename to src/test/ui/newlambdas.rs index 93199f8ccd..90de53856c 100644 --- a/src/test/run-pass/newlambdas.rs +++ b/src/test/ui/newlambdas.rs @@ -1,3 +1,4 @@ +// run-pass // Tests for the new |args| expr lambda syntax diff --git a/src/test/run-pass/newtype-polymorphic.rs b/src/test/ui/newtype-polymorphic.rs similarity index 97% rename from src/test/run-pass/newtype-polymorphic.rs rename to src/test/ui/newtype-polymorphic.rs index c79b76d646..a6a725211a 100644 --- a/src/test/run-pass/newtype-polymorphic.rs +++ b/src/test/ui/newtype-polymorphic.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/newtype-temporary.rs b/src/test/ui/newtype-temporary.rs similarity index 90% rename from src/test/run-pass/newtype-temporary.rs rename to src/test/ui/newtype-temporary.rs index f8d6cde2aa..8ee75b2fef 100644 --- a/src/test/run-pass/newtype-temporary.rs +++ b/src/test/ui/newtype-temporary.rs @@ -1,3 +1,5 @@ +// run-pass + #[derive(PartialEq, Debug)] struct Foo(usize); diff --git a/src/test/run-pass/newtype.rs b/src/test/ui/newtype.rs similarity index 97% rename from src/test/run-pass/newtype.rs rename to src/test/ui/newtype.rs index 56d908ad0b..f02b66f450 100644 --- a/src/test/run-pass/newtype.rs +++ b/src/test/ui/newtype.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #[derive(Copy, Clone)] struct mytype(Mytype); diff --git a/src/test/run-pass/nil-decl-in-foreign.rs b/src/test/ui/nil-decl-in-foreign.rs similarity index 93% rename from src/test/run-pass/nil-decl-in-foreign.rs rename to src/test/ui/nil-decl-in-foreign.rs index faff6b4873..98422665b9 100644 --- a/src/test/run-pass/nil-decl-in-foreign.rs +++ b/src/test/ui/nil-decl-in-foreign.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(improper_ctypes)] #![allow(dead_code)] // Issue #901 diff --git a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs index 8ed6554877..7679bf22e3 100644 --- a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs +++ b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that we propagate region relations from closures precisely when there is // more than one non-local lower bound. diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs index d1945f4864..1df7c6114e 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs @@ -4,7 +4,7 @@ // regions is erased. // compile-flags:-Zborrowck=mir -Zverbose -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/constant.rs b/src/test/ui/nll/constant.rs index 2bc40fcb32..b1ea2c906d 100644 --- a/src/test/ui/nll/constant.rs +++ b/src/test/ui/nll/constant.rs @@ -2,7 +2,7 @@ // arbitrary types without ICEs. // compile-flags:-Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) const HI: &str = "hi"; diff --git a/src/test/ui/nll/drop-may-dangle.rs b/src/test/ui/nll/drop-may-dangle.rs index 5c72225b11..0f3d27d066 100644 --- a/src/test/ui/nll/drop-may-dangle.rs +++ b/src/test/ui/nll/drop-may-dangle.rs @@ -3,7 +3,7 @@ // including) the call to `use_x`. The `else` branch is not included. // compile-flags:-Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![feature(dropck_eyepatch)] diff --git a/src/test/ui/nll/empty-type-predicate.rs b/src/test/ui/nll/empty-type-predicate.rs index 75431d40ce..48073f8749 100644 --- a/src/test/ui/nll/empty-type-predicate.rs +++ b/src/test/ui/nll/empty-type-predicate.rs @@ -3,7 +3,7 @@ // `dyn T:` is lowered to `dyn T: ReEmpty` - check that we don't ICE in NLL for // the unexpected region. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait T {} fn f() where dyn T: {} diff --git a/src/test/ui/nll/extra-unused-mut.rs b/src/test/ui/nll/extra-unused-mut.rs index 6d0d6e16a6..e9c8df4621 100644 --- a/src/test/ui/nll/extra-unused-mut.rs +++ b/src/test/ui/nll/extra-unused-mut.rs @@ -1,6 +1,6 @@ // extra unused mut lint tests for #51918 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(generators, nll)] #![deny(unused_mut)] diff --git a/src/test/ui/nll/generator-distinct-lifetime.rs b/src/test/ui/nll/generator-distinct-lifetime.rs index d479a61baa..1bd39db35d 100644 --- a/src/test/ui/nll/generator-distinct-lifetime.rs +++ b/src/test/ui/nll/generator-distinct-lifetime.rs @@ -6,7 +6,7 @@ // over a yield -- because the data that is borrowed (`*x`) is not // stored on the stack. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn foo(x: &mut u32) { move || { diff --git a/src/test/ui/nll/get_default.polonius.stderr b/src/test/ui/nll/get_default.polonius.stderr new file mode 100644 index 0000000000..2df6d5d61f --- /dev/null +++ b/src/test/ui/nll/get_default.polonius.stderr @@ -0,0 +1,15 @@ +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:32:17 + | +LL | match map.get() { + | --- immutable borrow occurs here +LL | Some(v) => { +LL | map.set(String::new()); // Both AST and MIR error here + | ^^^ mutable borrow occurs here +LL | +LL | return v; + | - immutable borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/issue-16223.rs b/src/test/ui/nll/issue-16223.rs index e753627506..c1205ba96a 100644 --- a/src/test/ui/nll/issue-16223.rs +++ b/src/test/ui/nll/issue-16223.rs @@ -13,7 +13,7 @@ // | // = note: move occurs because the value has type `A`, which does not implement the `Copy` trait -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_patterns)] diff --git a/src/test/ui/nll/issue-21114-ebfull.rs b/src/test/ui/nll/issue-21114-ebfull.rs index 1fe4fffa32..5a5db1a17f 100644 --- a/src/test/ui/nll/issue-21114-ebfull.rs +++ b/src/test/ui/nll/issue-21114-ebfull.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::collections::HashMap; use std::sync::Mutex; diff --git a/src/test/ui/nll/issue-21114-kixunil.rs b/src/test/ui/nll/issue-21114-kixunil.rs index 80a85293e5..32c97a651c 100644 --- a/src/test/ui/nll/issue-21114-kixunil.rs +++ b/src/test/ui/nll/issue-21114-kixunil.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn from_stdin(min: u64) -> Vec { use std::io::BufRead; diff --git a/src/test/ui/nll/issue-22323-temp-destruction.rs b/src/test/ui/nll/issue-22323-temp-destruction.rs index 6357c3ccef..1add91b1bd 100644 --- a/src/test/ui/nll/issue-22323-temp-destruction.rs +++ b/src/test/ui/nll/issue-22323-temp-destruction.rs @@ -1,7 +1,7 @@ // rust-lang/rust#22323: regression test demonstrating that NLL // precisely tracks temporary destruction order. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _s = construct().borrow().consume_borrowed(); diff --git a/src/test/ui/nll/issue-30104.rs b/src/test/ui/nll/issue-30104.rs index 27e519005f..3f4818a28c 100644 --- a/src/test/ui/nll/issue-30104.rs +++ b/src/test/ui/nll/issue-30104.rs @@ -1,6 +1,6 @@ // Regression test for #30104 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::{Deref, DerefMut}; diff --git a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs index 7e0ffd6cf3..bffff65015 100644 --- a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs +++ b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#32382: Borrow checker used to complain about // `foobar_3` in the `impl` below, presumably due to some interaction diff --git a/src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.rs b/src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.rs new file mode 100644 index 0000000000..f45370e5c2 --- /dev/null +++ b/src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.rs @@ -0,0 +1,13 @@ +// This test illustrates a case where full NLL (enabled by the feature +// switch below) produces superior diagnostics to the NLL-migrate +// mode. + +#![feature(nll)] + +fn doit(data: &'static mut ()) { + || doit(data); + //~^ ERROR lifetime may not live long enough + //~| ERROR `data` does not live long enough +} + +fn main() { } diff --git a/src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr b/src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr new file mode 100644 index 0000000000..4c70a8475f --- /dev/null +++ b/src/test/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr @@ -0,0 +1,26 @@ +error: lifetime may not live long enough + --> $DIR/issue-42574-diagnostic-in-nested-closure.rs:8:8 + | +LL | || doit(data); + | -- ^^^^^^^^^^ argument requires that `'1` must outlive `'static` + | | + | lifetime `'1` represents this closure's body + | + = note: closure implements `FnMut`, so references to captured variables can't escape the closure + +error[E0597]: `data` does not live long enough + --> $DIR/issue-42574-diagnostic-in-nested-closure.rs:8:13 + | +LL | || doit(data); + | -- -----^^^^- + | | | | + | | | borrowed value does not live long enough + | | argument requires that `data` is borrowed for `'static` + | value captured here +... +LL | } + | - `data` dropped here while still borrowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs index c50473511f..8bf9028690 100644 --- a/src/test/ui/nll/issue-43058.rs +++ b/src/test/ui/nll/issue-43058.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::borrow::Cow; diff --git a/src/test/ui/nll/issue-46589.rs b/src/test/ui/nll/issue-46589.rs index 8c0c356e96..0a4c20d151 100644 --- a/src/test/ui/nll/issue-46589.rs +++ b/src/test/ui/nll/issue-46589.rs @@ -1,3 +1,9 @@ +// This tests passes in Polonius mode, so is skipped in the automated compare-mode. +// We will manually check it passes in Polonius tests, as we can't have a test here +// which conditionally passes depending on a test revision/compile-flags. + +// ignore-compare-mode-polonius + struct Foo; impl Foo { diff --git a/src/test/ui/nll/issue-46589.stderr b/src/test/ui/nll/issue-46589.stderr index 397909a436..82cd364eef 100644 --- a/src/test/ui/nll/issue-46589.stderr +++ b/src/test/ui/nll/issue-46589.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `**other` as mutable more than once at a time - --> $DIR/issue-46589.rs:17:21 + --> $DIR/issue-46589.rs:23:21 | LL | *other = match (*other).get_self() { | -------- first mutable borrow occurs here diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs index 3f8e0f5ad3..ecd7071ecc 100644 --- a/src/test/ui/nll/issue-47022.rs +++ b/src/test/ui/nll/issue-47022.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct LoadedObject { bodies: Vec, diff --git a/src/test/run-pass/nll/issue-47153-generic-const.rs b/src/test/ui/nll/issue-47153-generic-const.rs similarity index 100% rename from src/test/run-pass/nll/issue-47153-generic-const.rs rename to src/test/ui/nll/issue-47153-generic-const.rs diff --git a/src/test/run-pass/nll/issue-47589.rs b/src/test/ui/nll/issue-47589.rs similarity index 100% rename from src/test/run-pass/nll/issue-47589.rs rename to src/test/ui/nll/issue-47589.rs diff --git a/src/test/run-pass/nll/issue-48623-closure.rs b/src/test/ui/nll/issue-48623-closure.rs similarity index 100% rename from src/test/run-pass/nll/issue-48623-closure.rs rename to src/test/ui/nll/issue-48623-closure.rs diff --git a/src/test/run-pass/nll/issue-48623-generator.rs b/src/test/ui/nll/issue-48623-generator.rs similarity index 100% rename from src/test/run-pass/nll/issue-48623-generator.rs rename to src/test/ui/nll/issue-48623-generator.rs diff --git a/src/test/run-pass/nll/issue-50343.rs b/src/test/ui/nll/issue-50343.rs similarity index 100% rename from src/test/run-pass/nll/issue-50343.rs rename to src/test/ui/nll/issue-50343.rs diff --git a/src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs b/src/test/ui/nll/issue-50461-used-mut-from-moves.rs similarity index 100% rename from src/test/run-pass/nll/issue-50461-used-mut-from-moves.rs rename to src/test/ui/nll/issue-50461-used-mut-from-moves.rs diff --git a/src/test/ui/nll/issue-50716-1.rs b/src/test/ui/nll/issue-50716-1.rs index ec992959a6..1e602f2724 100644 --- a/src/test/ui/nll/issue-50716-1.rs +++ b/src/test/ui/nll/issue-50716-1.rs @@ -3,7 +3,7 @@ // bounds derived from `Sized` requirements” that checks that the fixed compiler // accepts this code fragment with both AST and MIR borrow checkers. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Qey(Q); diff --git a/src/test/ui/nll/issue-51191.stderr b/src/test/ui/nll/issue-51191.stderr index e226de15dc..7fa355eabb 100644 --- a/src/test/ui/nll/issue-51191.stderr +++ b/src/test/ui/nll/issue-51191.stderr @@ -7,7 +7,7 @@ LL | LL | (&mut self).bar(); | ----------------- recursive call site | - = note: #[warn(unconditional_recursion)] on by default + = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable diff --git a/src/test/ui/nll/issue-51351.rs b/src/test/ui/nll/issue-51351.rs index b45477c7fb..efffe80aae 100644 --- a/src/test/ui/nll/issue-51351.rs +++ b/src/test/ui/nll/issue-51351.rs @@ -6,7 +6,7 @@ // of the closure, as they were not present in the closure's generic // declarations otherwise. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn creash<'a>() { let x: &'a () = &(); diff --git a/src/test/ui/nll/issue-52078.rs b/src/test/ui/nll/issue-52078.rs index 4b8e6c6807..935bf8cda5 100644 --- a/src/test/ui/nll/issue-52078.rs +++ b/src/test/ui/nll/issue-52078.rs @@ -2,7 +2,7 @@ // between `'a` and `'b` below due to inference variables introduced // during the normalization process. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Drain<'a, T: 'a> { _marker: ::std::marker::PhantomData<&'a T>, diff --git a/src/test/ui/nll/issue-53119.rs b/src/test/ui/nll/issue-53119.rs index 7a47a77f6b..f5400aaad8 100644 --- a/src/test/ui/nll/issue-53119.rs +++ b/src/test/ui/nll/issue-53119.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::Deref; diff --git a/src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs b/src/test/ui/nll/issue-53123-raw-pointer-cast.rs similarity index 100% rename from src/test/run-pass/nll/issue-53123-raw-pointer-cast.rs rename to src/test/ui/nll/issue-53123-raw-pointer-cast.rs diff --git a/src/test/ui/nll/issue-53570.rs b/src/test/ui/nll/issue-53570.rs index 81c50edfed..25c1929b22 100644 --- a/src/test/ui/nll/issue-53570.rs +++ b/src/test/ui/nll/issue-53570.rs @@ -6,7 +6,7 @@ // parameter `x` -- since `'b` cannot be expressed in the caller's // space, that got promoted th `'static`. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::{RefCell, Ref}; diff --git a/src/test/ui/nll/issue-55344.rs b/src/test/ui/nll/issue-55344.rs index 521d4d33d8..a65635585d 100644 --- a/src/test/ui/nll/issue-55344.rs +++ b/src/test/ui/nll/issue-55344.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_mut)] diff --git a/src/test/ui/nll/issue-55651.rs b/src/test/ui/nll/issue-55651.rs index 976098e40a..73fce288f8 100644 --- a/src/test/ui/nll/issue-55651.rs +++ b/src/test/ui/nll/issue-55651.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(untagged_unions)] diff --git a/src/test/ui/nll/issue-57280-1.rs b/src/test/ui/nll/issue-57280-1.rs index e02d6a0cb5..f9cea42e7c 100644 --- a/src/test/ui/nll/issue-57280-1.rs +++ b/src/test/ui/nll/issue-57280-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo<'a> { const C: &'a u32; diff --git a/src/test/ui/nll/issue-57280.rs b/src/test/ui/nll/issue-57280.rs index 776a0d359c..65ca23cc88 100644 --- a/src/test/ui/nll/issue-57280.rs +++ b/src/test/ui/nll/issue-57280.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo { const BLAH: &'static str; diff --git a/src/test/ui/nll/issue-61311-normalize.rs b/src/test/ui/nll/issue-61311-normalize.rs index 1164e9ef2d..9237c27f57 100644 --- a/src/test/ui/nll/issue-61311-normalize.rs +++ b/src/test/ui/nll/issue-61311-normalize.rs @@ -1,7 +1,7 @@ // Regression test for #61311 // We would ICE after failing to normalize `Self::Proj` in the `impl` below. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Unit; trait Obj {} diff --git a/src/test/ui/nll/issue-61320-normalize.rs b/src/test/ui/nll/issue-61320-normalize.rs index a36ccd3611..59bceed08f 100644 --- a/src/test/ui/nll/issue-61320-normalize.rs +++ b/src/test/ui/nll/issue-61320-normalize.rs @@ -1,7 +1,7 @@ // Regression test for #61320 // This is the same issue as #61311, just a larger test case. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct AndThen where diff --git a/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr new file mode 100644 index 0000000000..eb8442b31d --- /dev/null +++ b/src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr @@ -0,0 +1,15 @@ +error[E0506]: cannot assign to `data.0` because it is borrowed + --> $DIR/loan_ends_mid_block_pair.rs:12:5 + | +LL | let c = &mut data.0; + | ----------- borrow of `data.0` occurs here +LL | capitalize(c); +LL | data.0 = 'e'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here +... +LL | capitalize(c); + | - borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs index a3add8856d..94e4a76386 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.rs +++ b/src/test/ui/nll/match-cfg-fake-edges.rs @@ -1,7 +1,7 @@ // Test that we have enough false edges to avoid exposing the exact matching // algorithm in borrow checking. -#![feature(nll, bind_by_move_pattern_guards)] +#![feature(bind_by_move_pattern_guards)] fn guard_always_precedes_arm(y: i32) { let mut x; @@ -41,18 +41,4 @@ fn guard_may_be_taken(y: bool) { }; } -fn all_previous_tests_may_be_done(y: &mut (bool, bool)) { - let r = &mut y.1; - // We don't actually test y.1 to select the second arm, but we don't want - // borrowck results to be based on the order we match patterns. - match y { - (false, true) => 1, //~ ERROR cannot use `y.1` because it was mutably borrowed - (true, _) => { - r; - 2 - } - (false, _) => 3, - }; -} - fn main() {} diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index d37c52444a..b1e0fa7397 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -16,19 +16,7 @@ LL | true => { LL | x; | ^ value used here after move -error[E0503]: cannot use `y.1` because it was mutably borrowed - --> $DIR/match-cfg-fake-edges.rs:49:17 - | -LL | let r = &mut y.1; - | -------- borrow of `y.1` occurs here -... -LL | (false, true) => 1, - | ^^^^ use of borrowed `y.1` -LL | (true, _) => { -LL | r; - | - borrow later used here - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0381, E0382, E0503. +Some errors have detailed explanations: E0381, E0382. For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/match-cfg-fake-edges2.rs b/src/test/ui/nll/match-cfg-fake-edges2.rs new file mode 100644 index 0000000000..84c0dec2fe --- /dev/null +++ b/src/test/ui/nll/match-cfg-fake-edges2.rs @@ -0,0 +1,20 @@ +// Test that we have enough false edges to avoid exposing the exact matching +// algorithm in borrow checking. + +#![feature(nll)] + +fn all_previous_tests_may_be_done(y: &mut (bool, bool)) { + let r = &mut y.1; + // We don't actually test y.1 to select the second arm, but we don't want + // borrowck results to be based on the order we match patterns. + match y { + (false, true) => 1, //~ ERROR cannot use `y.1` because it was mutably borrowed + (true, _) => { + r; + 2 + } + (false, _) => 3, + }; +} + +fn main() {} diff --git a/src/test/ui/nll/match-cfg-fake-edges2.stderr b/src/test/ui/nll/match-cfg-fake-edges2.stderr new file mode 100644 index 0000000000..eab89658e7 --- /dev/null +++ b/src/test/ui/nll/match-cfg-fake-edges2.stderr @@ -0,0 +1,15 @@ +error[E0503]: cannot use `y.1` because it was mutably borrowed + --> $DIR/match-cfg-fake-edges2.rs:11:17 + | +LL | let r = &mut y.1; + | -------- borrow of `y.1` occurs here +... +LL | (false, true) => 1, + | ^^^^ use of borrowed `y.1` +LL | (true, _) => { +LL | r; + | - borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0503`. diff --git a/src/test/ui/nll/match-guards-partially-borrow.rs b/src/test/ui/nll/match-guards-partially-borrow.rs index 6e15871314..601c46ff86 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.rs +++ b/src/test/ui/nll/match-guards-partially-borrow.rs @@ -5,9 +5,7 @@ // Test that we don't allow mutating the value being matched on in a way that // changes which patterns it matches, until we have chosen an arm. - #![feature(bind_by_move_pattern_guards)] -#![feature(nll)] fn ok_mutation_in_guard(mut q: i32) { match q { diff --git a/src/test/ui/nll/match-guards-partially-borrow.stderr b/src/test/ui/nll/match-guards-partially-borrow.stderr index 3d9b67b4ea..b2951fd339 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.stderr +++ b/src/test/ui/nll/match-guards-partially-borrow.stderr @@ -1,5 +1,5 @@ error[E0510]: cannot assign `q` in match guard - --> $DIR/match-guards-partially-borrow.rs:59:13 + --> $DIR/match-guards-partially-borrow.rs:57:13 | LL | match q { | - value is immutable in match guard @@ -8,7 +8,7 @@ LL | q = true; | ^^^^^^^^ cannot assign error[E0510]: cannot assign `r` in match guard - --> $DIR/match-guards-partially-borrow.rs:71:13 + --> $DIR/match-guards-partially-borrow.rs:69:13 | LL | match r { | - value is immutable in match guard @@ -17,7 +17,7 @@ LL | r = true; | ^^^^^^^^ cannot assign error[E0510]: cannot assign `t` in match guard - --> $DIR/match-guards-partially-borrow.rs:95:13 + --> $DIR/match-guards-partially-borrow.rs:93:13 | LL | match t { | - value is immutable in match guard @@ -26,7 +26,7 @@ LL | t = true; | ^^^^^^^^ cannot assign error[E0510]: cannot mutably borrow `x.0` in match guard - --> $DIR/match-guards-partially-borrow.rs:109:22 + --> $DIR/match-guards-partially-borrow.rs:107:22 | LL | match x { | - value is immutable in match guard @@ -35,7 +35,7 @@ LL | Some(ref mut r) => *r = None, | ^^^^^^^^^ cannot mutably borrow error[E0506]: cannot assign to `t` because it is borrowed - --> $DIR/match-guards-partially-borrow.rs:121:13 + --> $DIR/match-guards-partially-borrow.rs:119:13 | LL | s if { | - borrow of `t` occurs here @@ -46,7 +46,7 @@ LL | } => (), // What value should `s` have in the arm? | - borrow later used here error[E0510]: cannot assign `y` in match guard - --> $DIR/match-guards-partially-borrow.rs:132:13 + --> $DIR/match-guards-partially-borrow.rs:130:13 | LL | match *y { | -- value is immutable in match guard @@ -55,7 +55,7 @@ LL | y = &true; | ^^^^^^^^^ cannot assign error[E0510]: cannot assign `z` in match guard - --> $DIR/match-guards-partially-borrow.rs:143:13 + --> $DIR/match-guards-partially-borrow.rs:141:13 | LL | match z { | - value is immutable in match guard @@ -64,7 +64,7 @@ LL | z = &true; | ^^^^^^^^^ cannot assign error[E0510]: cannot assign `a` in match guard - --> $DIR/match-guards-partially-borrow.rs:155:13 + --> $DIR/match-guards-partially-borrow.rs:153:13 | LL | match a { | - value is immutable in match guard @@ -73,7 +73,7 @@ LL | a = &true; | ^^^^^^^^^ cannot assign error[E0510]: cannot assign `b` in match guard - --> $DIR/match-guards-partially-borrow.rs:166:13 + --> $DIR/match-guards-partially-borrow.rs:164:13 | LL | match b { | - value is immutable in match guard diff --git a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs index 3415c3eeab..72212e9e70 100644 --- a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs +++ b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs @@ -1,5 +1,5 @@ // compile-flags: -Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] diff --git a/src/test/run-pass/nll/mutating_references.rs b/src/test/ui/nll/mutating_references.rs similarity index 100% rename from src/test/run-pass/nll/mutating_references.rs rename to src/test/ui/nll/mutating_references.rs diff --git a/src/test/ui/nll/polonius/assignment-kills-loans.rs b/src/test/ui/nll/polonius/assignment-kills-loans.rs new file mode 100644 index 0000000000..a80c62d19d --- /dev/null +++ b/src/test/ui/nll/polonius/assignment-kills-loans.rs @@ -0,0 +1,88 @@ +#![allow(dead_code)] + +// This tests the various kinds of assignments there are. Polonius used to generate `killed` +// facts only on simple assigments, but not projections, incorrectly causing errors to be emitted +// for code accepted by NLL. They are all variations from example code in the NLL RFC. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct List { + value: T, + next: Option>>, +} + +// Assignment to a local: the `list` assignment should clear the existing +// borrows of `list.value` and `list.next` +fn assignment_to_local(mut list: &mut List) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + return result; + } + } +} + +// Assignment to a deref projection: the `*list` assignment should clear the existing +// borrows of `list.value` and `list.next` +fn assignment_to_deref_projection(mut list: Box<&mut List>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + *list = n; + } else { + return result; + } + } +} + +// Assignment to a field projection: the `list.0` assignment should clear the existing +// borrows of `list.0.value` and `list.0.next` +fn assignment_to_field_projection(mut list: (&mut List,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.0.value); + if let Some(n) = list.0.next.as_mut() { + list.0 = n; + } else { + return result; + } + } +} + +// Assignment to a deref field projection: the `*list.0` assignment should clear the existing +// borrows of `list.0.value` and `list.0.next` +fn assignment_to_deref_field_projection(mut list: (Box<&mut List>,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.0.value); + if let Some(n) = list.0.next.as_mut() { + *list.0 = n; + } else { + return result; + } + } +} + +// Similar to `assignment_to_deref_field_projection` but through a longer projection chain +fn assignment_through_projection_chain( + mut list: (((((Box<&mut List>,),),),),), +) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut ((((list.0).0).0).0).0.value); + if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + *((((list.0).0).0).0).0 = n; + } else { + return result; + } + } +} + +fn main() { +} diff --git a/src/test/ui/nll/polonius/assignment-to-differing-field.rs b/src/test/ui/nll/polonius/assignment-to-differing-field.rs new file mode 100644 index 0000000000..c0ba1b983f --- /dev/null +++ b/src/test/ui/nll/polonius/assignment-to-differing-field.rs @@ -0,0 +1,50 @@ +#![allow(dead_code)] + +// Compared to `assignment-kills-loans.rs`, we check here +// that we do not kill too many borrows. Assignments to the `.1` +// field projections should leave the borrows on `.0` intact. + +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct List { + value: T, + next: Option>>, +} + + +fn assignment_to_field_projection<'a, T>( + mut list: (&'a mut List, &'a mut List), +) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut (list.0).value); + //~^ ERROR cannot borrow `list.0.value` as mutable + + if let Some(n) = (list.0).next.as_mut() { + //~^ ERROR cannot borrow `list.0.next` as mutable + list.1 = n; + } else { + return result; + } + } +} + +fn assignment_through_projection_chain<'a, T>( + mut list: (((((Box<&'a mut List>, Box<&'a mut List>),),),),), +) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut ((((list.0).0).0).0).0.value); + //~^ ERROR cannot borrow `list.0.0.0.0.0.value` as mutable + + if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + //~^ ERROR cannot borrow `list.0.0.0.0.0.next` as mutable + *((((list.0).0).0).0).1 = n; + } else { + return result; + } + } +} + +fn main() {} diff --git a/src/test/ui/nll/polonius/assignment-to-differing-field.stderr b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr new file mode 100644 index 0000000000..07ca021b53 --- /dev/null +++ b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr @@ -0,0 +1,51 @@ +error[E0499]: cannot borrow `list.0.value` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:21:21 + | +LL | fn assignment_to_field_projection<'a, T>( + | -- lifetime `'a` defined here +... +LL | result.push(&mut (list.0).value); + | ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop +... +LL | return result; + | ------ returning this value requires that `list.0.value` is borrowed for `'a` + +error[E0499]: cannot borrow `list.0.next` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:24:26 + | +LL | fn assignment_to_field_projection<'a, T>( + | -- lifetime `'a` defined here +... +LL | if let Some(n) = (list.0).next.as_mut() { + | ^^^^^^^^^^^^^--------- + | | + | mutable borrow starts here in previous iteration of loop + | argument requires that `list.0.next` is borrowed for `'a` + +error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:38:21 + | +LL | fn assignment_through_projection_chain<'a, T>( + | -- lifetime `'a` defined here +... +LL | result.push(&mut ((((list.0).0).0).0).0.value); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop +... +LL | return result; + | ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a` + +error[E0499]: cannot borrow `list.0.0.0.0.0.next` as mutable more than once at a time + --> $DIR/assignment-to-differing-field.rs:41:26 + | +LL | fn assignment_through_projection_chain<'a, T>( + | -- lifetime `'a` defined here +... +LL | if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^--------- + | | + | mutable borrow starts here in previous iteration of loop + | argument requires that `list.0.0.0.0.0.next` is borrowed for `'a` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/nll/polonius/call-kills-loans.rs b/src/test/ui/nll/polonius/call-kills-loans.rs new file mode 100644 index 0000000000..57dc140110 --- /dev/null +++ b/src/test/ui/nll/polonius/call-kills-loans.rs @@ -0,0 +1,24 @@ +// `Call` terminators can write to a local which has existing loans +// and those need to be killed like a regular assignment to a local. +// This is a simplified version of issue 47680, is correctly accepted +// by NLL but was incorrectly rejected by Polonius because of these +// missing `killed` facts. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct Thing; + +impl Thing { + fn next(&mut self) -> &mut Self { unimplemented!() } +} + +fn main() { + let mut temp = &mut Thing; + + loop { + let v = temp.next(); + temp = v; // accepted by NLL, was incorrectly rejected by Polonius + } +} diff --git a/src/test/ui/nll/polonius/issue-46589.rs b/src/test/ui/nll/polonius/issue-46589.rs new file mode 100644 index 0000000000..b5792587ff --- /dev/null +++ b/src/test/ui/nll/polonius/issue-46589.rs @@ -0,0 +1,32 @@ +// This test is a copy of `ui/nll/issue-46589.rs` which fails in NLL but succeeds in Polonius. +// As we can't have a test here which conditionally passes depending on a test +// revision/compile-flags. We ensure here that it passes in Polonius mode. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct Foo; + +impl Foo { + fn get_self(&mut self) -> Option<&mut Self> { + Some(self) + } + + fn new_self(&mut self) -> &mut Self { + self + } + + fn trigger_bug(&mut self) { + let other = &mut (&mut *self); + + *other = match (*other).get_self() { + Some(s) => s, + None => (*other).new_self() + }; + + let c = other; + } +} + +fn main() {} diff --git a/src/test/ui/nll/polonius-smoke-test.rs b/src/test/ui/nll/polonius/polonius-smoke-test.rs similarity index 100% rename from src/test/ui/nll/polonius-smoke-test.rs rename to src/test/ui/nll/polonius/polonius-smoke-test.rs diff --git a/src/test/ui/nll/polonius-smoke-test.stderr b/src/test/ui/nll/polonius/polonius-smoke-test.stderr similarity index 100% rename from src/test/ui/nll/polonius-smoke-test.stderr rename to src/test/ui/nll/polonius/polonius-smoke-test.stderr diff --git a/src/test/ui/nll/polonius/storagedead-kills-loans.rs b/src/test/ui/nll/polonius/storagedead-kills-loans.rs new file mode 100644 index 0000000000..ff801cbf9f --- /dev/null +++ b/src/test/ui/nll/polonius/storagedead-kills-loans.rs @@ -0,0 +1,29 @@ +// Whenever a `StorageDead` MIR statement destroys a value `x`, +// we should kill all loans of `x`. This is extracted from `rand 0.4.6`, +// is correctly accepted by NLL but was incorrectly rejected by +// Polonius because of these missing `killed` facts. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +use std::{io, mem}; +use std::io::Read; + +#[allow(dead_code)] +fn fill(r: &mut dyn Read, mut buf: &mut [u8]) -> io::Result<()> { + while buf.len() > 0 { + match r.read(buf).unwrap() { + 0 => return Err(io::Error::new(io::ErrorKind::Other, + "end of file reached")), + n => buf = &mut mem::replace(&mut buf, &mut [])[n..], + // ^- Polonius had multiple errors on the previous line (where NLL has none) + // as it didn't know `buf` was killed here, and would + // incorrectly reject both the borrow expression, and the assignment. + } + } + Ok(()) +} + +fn main() { +} diff --git a/src/test/run-pass/nll/process_or_insert_default.rs b/src/test/ui/nll/process_or_insert_default.rs similarity index 100% rename from src/test/run-pass/nll/process_or_insert_default.rs rename to src/test/ui/nll/process_or_insert_default.rs diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs index fdf3f59484..5c34043469 100644 --- a/src/test/ui/nll/projection-return.rs +++ b/src/test/ui/nll/projection-return.rs @@ -1,5 +1,5 @@ // compile-flags:-Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/run-pass/nll/rc-loop.rs b/src/test/ui/nll/rc-loop.rs similarity index 100% rename from src/test/run-pass/nll/rc-loop.rs rename to src/test/ui/nll/rc-loop.rs diff --git a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs index 23caa59b6b..1bbc896c27 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs +++ b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs @@ -6,7 +6,7 @@ // another -- effectively, the single lifetime `'a` is just inferred // to be the intersection of the two distinct lifetimes. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:-Zno-leak-check #![feature(nll)] diff --git a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs index bac9e26588..4e8599b2e3 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs +++ b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs @@ -2,7 +2,7 @@ // function returning always its first argument can be upcast to one // that returns either first or second argument. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:-Zno-leak-check #![feature(nll)] diff --git a/src/test/ui/nll/relate_tys/issue-48071.rs b/src/test/ui/nll/relate_tys/issue-48071.rs index 7298762984..36cd57a1b2 100644 --- a/src/test/ui/nll/relate_tys/issue-48071.rs +++ b/src/test/ui/nll/relate_tys/issue-48071.rs @@ -4,7 +4,7 @@ // placeholder region, but in NLL land it would fail because we had // rewritten `'static` to a region variable. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo { fn foo(&self) { } diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr new file mode 100644 index 0000000000..8e3cf59cff --- /dev/null +++ b/src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr @@ -0,0 +1,15 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/return-ref-mut-issue-46557.rs:4:21 + | +LL | let ref mut x = 1234543; + | ^^^^^^^ creates a temporary which is freed while still in use +LL | x + | - borrow later used here +LL | } + | - temporary value is freed at the end of this statement + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/nll/ty-outlives/issue-53789-1.rs b/src/test/ui/nll/ty-outlives/issue-53789-1.rs index dc67c1a68a..2293d7d4bb 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-1.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-1.rs @@ -1,6 +1,6 @@ // Regression test for #53789. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::collections::BTreeMap; diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs index 1b80be2eaf..313b615fe8 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs @@ -1,6 +1,6 @@ // Regression test for #53789. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::collections::BTreeMap; use std::ops::Range; diff --git a/src/test/ui/nll/ty-outlives/issue-55756.rs b/src/test/ui/nll/ty-outlives/issue-55756.rs index cda3915849..147ea20348 100644 --- a/src/test/ui/nll/ty-outlives/issue-55756.rs +++ b/src/test/ui/nll/ty-outlives/issue-55756.rs @@ -16,7 +16,7 @@ // Fixed by tweaking the solver to recognize that the constraint from // the environment duplicates one from the trait. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type="lib"] diff --git a/src/test/ui/nll/ty-outlives/projection-body.rs b/src/test/ui/nll/ty-outlives/projection-body.rs index 2e105ece8b..148120d848 100644 --- a/src/test/ui/nll/ty-outlives/projection-body.rs +++ b/src/test/ui/nll/ty-outlives/projection-body.rs @@ -1,7 +1,7 @@ // Test that when we infer the lifetime to a subset of the fn body, it // works out. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyTrait<'a> { type Output; diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs index 1245ce8583..fb50dce1af 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs @@ -1,10 +1,7 @@ -// compile-flags:-Zborrowck=mir -Zverbose - // Test that we can deduce when projections like `T::Item` outlive the // function body. Test that this does not imply that `T: 'a` holds. -#![allow(warnings)] -#![feature(rustc_attrs)] +// compile-flags:-Zborrowck=mir -Zverbose use std::cell::Cell; @@ -18,7 +15,6 @@ where f(&value, Cell::new(&n)); } -#[rustc_errors] fn generic1(value: T) { // No error here: twice(value, |value_ref, item| invoke1(item)); @@ -30,7 +26,6 @@ where { } -#[rustc_errors] fn generic2(value: T) { twice(value, |value_ref, item| invoke2(value_ref, item)); //~^ ERROR the parameter type `T` may not live long enough diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr index 9cdb78a102..9f0c60c1e1 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr @@ -1,5 +1,5 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/projection-implied-bounds.rs:35:18 + --> $DIR/projection-implied-bounds.rs:30:18 | LL | twice(value, |value_ref, item| invoke2(value_ref, item)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs index 452a8ea4f8..b9c9611e38 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs @@ -3,7 +3,7 @@ // we don't even propagate constraints from the closures to the callers. // compile-flags:-Zborrowck=mir -Zverbose -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs index 7314766611..4613dd29ef 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs @@ -4,7 +4,7 @@ // // Regression test for #53121. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyTrait<'a> { type Output; diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs index 7c7d64a8cb..89328c2ef1 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs @@ -4,7 +4,7 @@ // MyTrait<'a>>::Output: 'a` outlives `'a` (because the trait says // so). // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyTrait<'a> { type Output: 'a; diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs index f61f54f80a..a68c3cf12f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs +++ b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs @@ -1,12 +1,9 @@ // compile-flags:-Zborrowck=mir -Zverbose -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that we assume that universal types like `T` outlive the // function body. -#![allow(warnings)] -#![feature(rustc_attrs)] - use std::cell::Cell; fn twice(value: T, mut f: F) @@ -17,7 +14,6 @@ where f(Cell::new(&value)); } -#[rustc_errors] fn generic(value: T) { // No error here: twice(value, |r| invoke(r)); diff --git a/src/test/ui/nll/user-annotations/downcast-infer.rs b/src/test/ui/nll/user-annotations/downcast-infer.rs index 23b76bb196..3efea71363 100644 --- a/src/test/ui/nll/user-annotations/downcast-infer.rs +++ b/src/test/ui/nll/user-annotations/downcast-infer.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that we don't try to downcast `_` when type-checking the annotation. fn main() { diff --git a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs index 6b9d30f5ab..66b3110d2a 100644 --- a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs +++ b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test is reduced from a scenario pnkfelix encountered while // bootstrapping the compiler. diff --git a/src/test/run-pass/no-core-1.rs b/src/test/ui/no-core-1.rs similarity index 93% rename from src/test/run-pass/no-core-1.rs rename to src/test/ui/no-core-1.rs index 36a3050d3d..9374f546ac 100644 --- a/src/test/run-pass/no-core-1.rs +++ b/src/test/ui/no-core-1.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] #![feature(no_core, core)] #![no_core] diff --git a/src/test/run-pass/no-core-2.rs b/src/test/ui/no-core-2.rs similarity index 94% rename from src/test/run-pass/no-core-2.rs rename to src/test/ui/no-core-2.rs index e09f8f6b7a..b08e63dc7c 100644 --- a/src/test/run-pass/no-core-2.rs +++ b/src/test/ui/no-core-2.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code, unused_imports)] #![feature(no_core)] #![no_core] diff --git a/src/test/ui/no-implicit-prelude-nested.rs b/src/test/ui/no-implicit-prelude-nested.rs index fae52c0edc..c314967da4 100644 --- a/src/test/ui/no-implicit-prelude-nested.rs +++ b/src/test/ui/no-implicit-prelude-nested.rs @@ -9,7 +9,7 @@ mod foo { mod baz { struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope - impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope + impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope @@ -21,7 +21,7 @@ mod foo { struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope - impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope + impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope @@ -36,7 +36,7 @@ fn qux() { mod qux_inner { struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope - impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope + impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope diff --git a/src/test/ui/no-implicit-prelude-nested.stderr b/src/test/ui/no-implicit-prelude-nested.stderr index 79b9396d41..8d695e45da 100644 --- a/src/test/ui/no-implicit-prelude-nested.stderr +++ b/src/test/ui/no-implicit-prelude-nested.stderr @@ -8,12 +8,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude-nested.rs:12:14 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -72,12 +72,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude-nested.rs:24:10 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -136,12 +136,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude-nested.rs:39:14 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -192,5 +192,5 @@ LL | use std::prelude::v1::drop; error: aborting due to 18 previous errors -Some errors have detailed explanations: E0405, E0425. -For more information about an error, try `rustc --explain E0405`. +Some errors have detailed explanations: E0404, E0405, E0425. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/no-implicit-prelude.rs b/src/test/ui/no-implicit-prelude.rs index e2074bbb8c..4b0ca4d524 100644 --- a/src/test/ui/no-implicit-prelude.rs +++ b/src/test/ui/no-implicit-prelude.rs @@ -8,7 +8,7 @@ struct Test; impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope -impl Clone for Test {} //~ ERROR cannot find trait `Clone` in this scope +impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope diff --git a/src/test/ui/no-implicit-prelude.stderr b/src/test/ui/no-implicit-prelude.stderr index eac1fcb7b6..6ae889df60 100644 --- a/src/test/ui/no-implicit-prelude.stderr +++ b/src/test/ui/no-implicit-prelude.stderr @@ -8,12 +8,12 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Add; | -error[E0405]: cannot find trait `Clone` in this scope +error[E0404]: expected trait, found derive macro `Clone` --> $DIR/no-implicit-prelude.rs:11:6 | LL | impl Clone for Test {} - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope + | ^^^^^ not a trait +help: possible better candidates are found in other modules, you can import them into scope | LL | use std::clone::Clone; | @@ -64,5 +64,5 @@ LL | use std::prelude::v1::drop; error: aborting due to 6 previous errors -Some errors have detailed explanations: E0405, E0425. -For more information about an error, try `rustc --explain E0405`. +Some errors have detailed explanations: E0404, E0405, E0425. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/run-pass/no-landing-pads.rs b/src/test/ui/no-landing-pads.rs similarity index 96% rename from src/test/run-pass/no-landing-pads.rs rename to src/test/ui/no-landing-pads.rs index 4649786582..d9d5321061 100644 --- a/src/test/run-pass/no-landing-pads.rs +++ b/src/test/ui/no-landing-pads.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z no-landing-pads -C codegen-units=1 // ignore-emscripten no threads support diff --git a/src/test/ui/no-link.rs b/src/test/ui/no-link.rs index f97c1074df..939271832e 100644 --- a/src/test/ui/no-link.rs +++ b/src/test/ui/no-link.rs @@ -4,5 +4,5 @@ extern crate empty_struct; fn main() { - empty_struct::XEmpty1; //~ ERROR cannot find value `XEmpty1` in module `empty_struct` + empty_struct::XEmpty1; //~ ERROR cannot find value `XEmpty1` in crate `empty_struct` } diff --git a/src/test/ui/no-link.stderr b/src/test/ui/no-link.stderr index c9c8468eba..66a74ff656 100644 --- a/src/test/ui/no-link.stderr +++ b/src/test/ui/no-link.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `XEmpty1` in module `empty_struct` +error[E0425]: cannot find value `XEmpty1` in crate `empty_struct` --> $DIR/no-link.rs:7:19 | LL | empty_struct::XEmpty1; diff --git a/src/test/run-pass/no-std-1.rs b/src/test/ui/no-std-1.rs similarity index 86% rename from src/test/run-pass/no-std-1.rs rename to src/test/ui/no-std-1.rs index fecf7397c8..5b59e9b4eb 100644 --- a/src/test/run-pass/no-std-1.rs +++ b/src/test/ui/no-std-1.rs @@ -1,3 +1,5 @@ +// run-pass + #![no_std] extern crate std; diff --git a/src/test/run-pass/no-std-2.rs b/src/test/ui/no-std-2.rs similarity index 89% rename from src/test/run-pass/no-std-2.rs rename to src/test/ui/no-std-2.rs index 946f993ca8..487d41649f 100644 --- a/src/test/run-pass/no-std-2.rs +++ b/src/test/ui/no-std-2.rs @@ -1,3 +1,5 @@ +// run-pass + #![no_std] extern crate std; diff --git a/src/test/run-pass/no-std-3.rs b/src/test/ui/no-std-3.rs similarity index 94% rename from src/test/run-pass/no-std-3.rs rename to src/test/ui/no-std-3.rs index f937d2593a..f6c4ed5794 100644 --- a/src/test/run-pass/no-std-3.rs +++ b/src/test/ui/no-std-3.rs @@ -1,3 +1,5 @@ +// run-pass + #![no_std] extern crate std; diff --git a/src/test/ui/no-std-inject.rs b/src/test/ui/no-std-inject.rs index 09879c791f..e9664a4dd4 100644 --- a/src/test/ui/no-std-inject.rs +++ b/src/test/ui/no-std-inject.rs @@ -1,5 +1,4 @@ #![no_std] -#![allow(unused_extern_crates)] extern crate core; //~ ERROR: the name `core` is defined multiple times extern crate std; diff --git a/src/test/ui/no-std-inject.stderr b/src/test/ui/no-std-inject.stderr index 975f5c2f50..a82931e0fb 100644 --- a/src/test/ui/no-std-inject.stderr +++ b/src/test/ui/no-std-inject.stderr @@ -1,5 +1,5 @@ error[E0259]: the name `core` is defined multiple times - --> $DIR/no-std-inject.rs:4:1 + --> $DIR/no-std-inject.rs:3:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ `core` reimported here diff --git a/src/test/run-pass/no-stdio.rs b/src/test/ui/no-stdio.rs similarity index 99% rename from src/test/run-pass/no-stdio.rs rename to src/test/ui/no-stdio.rs index aae1d0b7f8..e72b7b26e2 100644 --- a/src/test/run-pass/no-stdio.rs +++ b/src/test/ui/no-stdio.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-android // ignore-cloudabi no processes // ignore-emscripten no processes diff --git a/src/test/ui/no-warn-on-field-replace-issue-34101.rs b/src/test/ui/no-warn-on-field-replace-issue-34101.rs index af6ccf35d5..eb701b9184 100644 --- a/src/test/ui/no-warn-on-field-replace-issue-34101.rs +++ b/src/test/ui/no-warn-on-field-replace-issue-34101.rs @@ -18,7 +18,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Foo(String); diff --git a/src/test/run-pass/non-built-in-quote.rs b/src/test/ui/non-built-in-quote.rs similarity index 90% rename from src/test/run-pass/non-built-in-quote.rs rename to src/test/ui/non-built-in-quote.rs index 75df2788d7..92efa99e39 100644 --- a/src/test/run-pass/non-built-in-quote.rs +++ b/src/test/ui/non-built-in-quote.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 macro_rules! quote_tokens { () => (()) } diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-match.rs index e888bcf516..0e5a9203c5 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-match.rs +++ b/src/test/ui/non-exhaustive/non-exhaustive-match.rs @@ -12,8 +12,8 @@ fn main() { match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered None => {} } - match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` - // and `(_, _, 5i32..=2147483647i32)` not covered + match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` + // and `(_, _, 5i32..=std::i32::MAX)` not covered (_, _, 4) => {} } match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` not covered @@ -32,14 +32,14 @@ fn main() { let vec = vec![Some(42), None, Some(21)]; let vec: &[Option] = &vec; match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered - [Some(..), None, ref tail..] => {} - [Some(..), Some(..), ref tail..] => {} + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} [None] => {} } let vec = vec![1]; let vec: &[isize] = &vec; match *vec { - [_, ref tail..] => (), + [_, ref tail @ ..] => (), [] => () } let vec = vec![0.5f32]; @@ -53,10 +53,10 @@ fn main() { let vec = vec![Some(42), None, Some(21)]; let vec: &[Option] = &vec; match *vec { - [Some(..), None, ref tail..] => {} - [Some(..), Some(..), ref tail..] => {} - [None, None, ref tail..] => {} - [None, Some(..), ref tail..] => {} + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} + [None, None, ref tail @ ..] => {} + [None, Some(..), ref tail @ ..] => {} [Some(_)] => {} [None] => {} [] => {} diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr index 58e3309fd2..5dba05e164 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr +++ b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr @@ -28,11 +28,11 @@ LL | match Some(10) { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered +error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered --> $DIR/non-exhaustive-match.rs:15:11 | LL | match (2, 3, 4) { - | ^^^^^^^^^ patterns `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered + | ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs index 9fcd4bdad7..4ca1cbcebc 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs +++ b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs @@ -77,7 +77,7 @@ fn vectors_with_nested_enums() { [Enum::Second(true), Enum::First] => (), [Enum::Second(true), Enum::Second(true)] => (), [Enum::Second(false), _] => (), - [_, _, ref tail.., _] => () + [_, _, ref tail @ .., _] => () } } diff --git a/src/test/run-pass/non-legacy-modes.rs b/src/test/ui/non-legacy-modes.rs similarity index 95% rename from src/test/run-pass/non-legacy-modes.rs rename to src/test/ui/non-legacy-modes.rs index a3abbeb815..38c83e00a6 100644 --- a/src/test/run-pass/non-legacy-modes.rs +++ b/src/test/ui/non-legacy-modes.rs @@ -1,3 +1,5 @@ +// run-pass + struct X { repr: isize } diff --git a/src/test/run-pass/non_modrs_mods/foors_mod.rs b/src/test/ui/non_modrs_mods/foors_mod.rs similarity index 93% rename from src/test/run-pass/non_modrs_mods/foors_mod.rs rename to src/test/ui/non_modrs_mods/foors_mod.rs index 1ed2e0d88d..5bf35fbf7f 100644 --- a/src/test/run-pass/non_modrs_mods/foors_mod.rs +++ b/src/test/ui/non_modrs_mods/foors_mod.rs @@ -1,3 +1,4 @@ +// run-pass // // ignore-test: not a test, used by non_modrs_mods.rs diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir b/src/test/ui/non_modrs_mods/foors_mod/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir rename to src/test/ui/non_modrs_mods/foors_mod/compiletest-ignore-dir diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs b/src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs rename to src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs index b76b4321d6..04585f918f 100644 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inline/somename.rs +++ b/src/test/ui/non_modrs_mods/foors_mod/inline/somename.rs @@ -1 +1,3 @@ +// run-pass + pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs rename to src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs index 68429e9831..4d8eb350bd 100644 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs @@ -1 +1,3 @@ +// run-pass + pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs rename to src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs index b76b4321d6..04585f918f 100644 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs @@ -1 +1,3 @@ +// run-pass + pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs rename to src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs index b76b4321d6..04585f918f 100644 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs @@ -1 +1,3 @@ +// run-pass + pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs rename to src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs index 68429e9831..4d8eb350bd 100644 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs +++ b/src/test/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs @@ -1 +1,3 @@ +// run-pass + pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir b/src/test/ui/non_modrs_mods/modrs_mod/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir rename to src/test/ui/non_modrs_mods/modrs_mod/compiletest-ignore-dir diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs b/src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs rename to src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs index b76b4321d6..04585f918f 100644 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inline/somename.rs +++ b/src/test/ui/non_modrs_mods/modrs_mod/inline/somename.rs @@ -1 +1,3 @@ +// run-pass + pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs rename to src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs index 68429e9831..4d8eb350bd 100644 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs @@ -1 +1,3 @@ +// run-pass + pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs rename to src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs index b76b4321d6..04585f918f 100644 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs @@ -1 +1,3 @@ +// run-pass + pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs rename to src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs index b76b4321d6..04585f918f 100644 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs @@ -1 +1,3 @@ +// run-pass + pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs rename to src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs index 68429e9831..4d8eb350bd 100644 --- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs +++ b/src/test/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs @@ -1 +1,3 @@ +// run-pass + pub mod innest; diff --git a/src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/modrs_mod/mod.rs similarity index 89% rename from src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs rename to src/test/ui/non_modrs_mods/modrs_mod/mod.rs index 46add00996..c8efa66d66 100644 --- a/src/test/run-pass/non_modrs_mods/modrs_mod/mod.rs +++ b/src/test/ui/non_modrs_mods/modrs_mod/mod.rs @@ -1,3 +1,5 @@ +// run-pass + pub mod inner_modrs_mod; pub mod inner_foors_mod; pub mod inline { diff --git a/src/test/run-pass/non_modrs_mods/non_modrs_mods.rs b/src/test/ui/non_modrs_mods/non_modrs_mods.rs similarity index 100% rename from src/test/run-pass/non_modrs_mods/non_modrs_mods.rs rename to src/test/ui/non_modrs_mods/non_modrs_mods.rs diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs similarity index 65% rename from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs rename to src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs index 97441eb5e5..7d5d5b9e5c 100644 --- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs +++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs @@ -1 +1,3 @@ +// run-pass + pub mod inner_modrs_mod; diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir rename to src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs new file mode 100644 index 0000000000..04585f918f --- /dev/null +++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs @@ -0,0 +1,3 @@ +// run-pass + +pub fn foo() {} diff --git a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs similarity index 55% rename from src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs rename to src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs index 68429e9831..4d8eb350bd 100644 --- a/src/test/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs +++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs @@ -1 +1,3 @@ +// run-pass + pub mod innest; diff --git a/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs b/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs index 25a9c2ed98..af6585aada 100644 --- a/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs +++ b/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod x; diff --git a/src/test/run-pass/nul-characters.rs b/src/test/ui/nul-characters.rs similarity index 98% rename from src/test/run-pass/nul-characters.rs rename to src/test/ui/nul-characters.rs index d93219d83d..11b6e9fe37 100644 --- a/src/test/run-pass/nul-characters.rs +++ b/src/test/ui/nul-characters.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let all_nuls1 = "\0\x00\u{0}\u{0}"; diff --git a/src/test/run-pass/nullable-pointer-ffi-compat.rs b/src/test/ui/nullable-pointer-ffi-compat.rs similarity index 98% rename from src/test/run-pass/nullable-pointer-ffi-compat.rs rename to src/test/ui/nullable-pointer-ffi-compat.rs index 0487052799..0647a18c3c 100644 --- a/src/test/run-pass/nullable-pointer-ffi-compat.rs +++ b/src/test/ui/nullable-pointer-ffi-compat.rs @@ -1,3 +1,4 @@ +// run-pass // #11303, #11040: // This would previously crash on i686 Linux due to abi differences // between returning an Option and T, where T is a non nullable diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/ui/nullable-pointer-iotareduction.rs similarity index 99% rename from src/test/run-pass/nullable-pointer-iotareduction.rs rename to src/test/ui/nullable-pointer-iotareduction.rs index 42aad550c1..4c6964f294 100644 --- a/src/test/run-pass/nullable-pointer-iotareduction.rs +++ b/src/test/ui/nullable-pointer-iotareduction.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(box_syntax)] // Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions, diff --git a/src/test/run-pass/nullable-pointer-size.rs b/src/test/ui/nullable-pointer-size.rs similarity index 98% rename from src/test/run-pass/nullable-pointer-size.rs rename to src/test/ui/nullable-pointer-size.rs index efd5cea6a4..63a106f129 100644 --- a/src/test/run-pass/nullable-pointer-size.rs +++ b/src/test/ui/nullable-pointer-size.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] use std::mem; diff --git a/src/test/run-pass/numbers-arithmetic/arith-0.rs b/src/test/ui/numbers-arithmetic/arith-0.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/arith-0.rs rename to src/test/ui/numbers-arithmetic/arith-0.rs diff --git a/src/test/run-pass/numbers-arithmetic/arith-1.rs b/src/test/ui/numbers-arithmetic/arith-1.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/arith-1.rs rename to src/test/ui/numbers-arithmetic/arith-1.rs diff --git a/src/test/run-pass/numbers-arithmetic/arith-2.rs b/src/test/ui/numbers-arithmetic/arith-2.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/arith-2.rs rename to src/test/ui/numbers-arithmetic/arith-2.rs diff --git a/src/test/run-pass/numbers-arithmetic/arith-unsigned.rs b/src/test/ui/numbers-arithmetic/arith-unsigned.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/arith-unsigned.rs rename to src/test/ui/numbers-arithmetic/arith-unsigned.rs diff --git a/src/test/run-pass/numbers-arithmetic/div-mod.rs b/src/test/ui/numbers-arithmetic/div-mod.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/div-mod.rs rename to src/test/ui/numbers-arithmetic/div-mod.rs diff --git a/src/test/run-pass/numbers-arithmetic/float-int-invalid-const-cast.rs b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float-int-invalid-const-cast.rs rename to src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs diff --git a/src/test/run-pass/numbers-arithmetic/float-literal-inference.rs b/src/test/ui/numbers-arithmetic/float-literal-inference.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float-literal-inference.rs rename to src/test/ui/numbers-arithmetic/float-literal-inference.rs diff --git a/src/test/run-pass/numbers-arithmetic/float-nan.rs b/src/test/ui/numbers-arithmetic/float-nan.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float-nan.rs rename to src/test/ui/numbers-arithmetic/float-nan.rs diff --git a/src/test/run-pass/numbers-arithmetic/float-signature.rs b/src/test/ui/numbers-arithmetic/float-signature.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float-signature.rs rename to src/test/ui/numbers-arithmetic/float-signature.rs diff --git a/src/test/run-pass/numbers-arithmetic/float.rs b/src/test/ui/numbers-arithmetic/float.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float.rs rename to src/test/ui/numbers-arithmetic/float.rs diff --git a/src/test/run-pass/numbers-arithmetic/float2.rs b/src/test/ui/numbers-arithmetic/float2.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float2.rs rename to src/test/ui/numbers-arithmetic/float2.rs diff --git a/src/test/run-pass/numbers-arithmetic/float_math.rs b/src/test/ui/numbers-arithmetic/float_math.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/float_math.rs rename to src/test/ui/numbers-arithmetic/float_math.rs diff --git a/src/test/run-pass/numbers-arithmetic/floatlits.rs b/src/test/ui/numbers-arithmetic/floatlits.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/floatlits.rs rename to src/test/ui/numbers-arithmetic/floatlits.rs diff --git a/src/test/run-pass/numbers-arithmetic/i128-ffi.rs b/src/test/ui/numbers-arithmetic/i128-ffi.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/i128-ffi.rs rename to src/test/ui/numbers-arithmetic/i128-ffi.rs diff --git a/src/test/run-pass/numbers-arithmetic/i128.rs b/src/test/ui/numbers-arithmetic/i128.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/i128.rs rename to src/test/ui/numbers-arithmetic/i128.rs diff --git a/src/test/run-pass/numbers-arithmetic/i32-sub.rs b/src/test/ui/numbers-arithmetic/i32-sub.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/i32-sub.rs rename to src/test/ui/numbers-arithmetic/i32-sub.rs diff --git a/src/test/run-pass/numbers-arithmetic/i8-incr.rs b/src/test/ui/numbers-arithmetic/i8-incr.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/i8-incr.rs rename to src/test/ui/numbers-arithmetic/i8-incr.rs diff --git a/src/test/run-pass/numbers-arithmetic/int-abs-overflow.rs b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/int-abs-overflow.rs rename to src/test/ui/numbers-arithmetic/int-abs-overflow.rs diff --git a/src/test/run-pass/numbers-arithmetic/int.rs b/src/test/ui/numbers-arithmetic/int.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/int.rs rename to src/test/ui/numbers-arithmetic/int.rs diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-radix.rs b/src/test/ui/numbers-arithmetic/integer-literal-radix.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/integer-literal-radix.rs rename to src/test/ui/numbers-arithmetic/integer-literal-radix.rs diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-2.rs rename to src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-3.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference-3.rs rename to src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs diff --git a/src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/integer-literal-suffix-inference.rs rename to src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs diff --git a/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-debug.rs rename to src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs diff --git a/src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs rename to src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs diff --git a/src/test/run-pass/numbers-arithmetic/num-wrapping.rs b/src/test/ui/numbers-arithmetic/num-wrapping.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/num-wrapping.rs rename to src/test/ui/numbers-arithmetic/num-wrapping.rs diff --git a/src/test/run-pass/numbers-arithmetic/numeric-method-autoexport.rs b/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/numeric-method-autoexport.rs rename to src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs diff --git a/src/test/run-pass/numbers-arithmetic/promoted_overflow_opt.rs b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/promoted_overflow_opt.rs rename to src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs diff --git a/src/test/run-pass/numbers-arithmetic/saturating-float-casts.rs b/src/test/ui/numbers-arithmetic/saturating-float-casts.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/saturating-float-casts.rs rename to src/test/ui/numbers-arithmetic/saturating-float-casts.rs diff --git a/src/test/run-pass/numbers-arithmetic/shift-near-oflo.rs b/src/test/ui/numbers-arithmetic/shift-near-oflo.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/shift-near-oflo.rs rename to src/test/ui/numbers-arithmetic/shift-near-oflo.rs diff --git a/src/test/run-pass/numbers-arithmetic/shift-various-types.rs b/src/test/ui/numbers-arithmetic/shift-various-types.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/shift-various-types.rs rename to src/test/ui/numbers-arithmetic/shift-various-types.rs diff --git a/src/test/run-pass/numbers-arithmetic/shift.rs b/src/test/ui/numbers-arithmetic/shift.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/shift.rs rename to src/test/ui/numbers-arithmetic/shift.rs diff --git a/src/test/run-pass/numbers-arithmetic/signed-shift-const-eval.rs b/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/signed-shift-const-eval.rs rename to src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs diff --git a/src/test/run-pass/numbers-arithmetic/u128-as-f32.rs b/src/test/ui/numbers-arithmetic/u128-as-f32.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/u128-as-f32.rs rename to src/test/ui/numbers-arithmetic/u128-as-f32.rs diff --git a/src/test/run-pass/numbers-arithmetic/u128.rs b/src/test/ui/numbers-arithmetic/u128.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/u128.rs rename to src/test/ui/numbers-arithmetic/u128.rs diff --git a/src/test/run-pass/numbers-arithmetic/u32-decr.rs b/src/test/ui/numbers-arithmetic/u32-decr.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/u32-decr.rs rename to src/test/ui/numbers-arithmetic/u32-decr.rs diff --git a/src/test/run-pass/numbers-arithmetic/u8-incr-decr.rs b/src/test/ui/numbers-arithmetic/u8-incr-decr.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/u8-incr-decr.rs rename to src/test/ui/numbers-arithmetic/u8-incr-decr.rs diff --git a/src/test/run-pass/numbers-arithmetic/u8-incr.rs b/src/test/ui/numbers-arithmetic/u8-incr.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/u8-incr.rs rename to src/test/ui/numbers-arithmetic/u8-incr.rs diff --git a/src/test/run-pass/numbers-arithmetic/uint.rs b/src/test/ui/numbers-arithmetic/uint.rs similarity index 100% rename from src/test/run-pass/numbers-arithmetic/uint.rs rename to src/test/ui/numbers-arithmetic/uint.rs diff --git a/src/test/run-pass/object-lifetime-default-default-to-static.rs b/src/test/ui/object-lifetime-default-default-to-static.rs similarity index 97% rename from src/test/run-pass/object-lifetime-default-default-to-static.rs rename to src/test/ui/object-lifetime-default-default-to-static.rs index cd61dea037..467767ae59 100644 --- a/src/test/run-pass/object-lifetime-default-default-to-static.rs +++ b/src/test/ui/object-lifetime-default-default-to-static.rs @@ -1,3 +1,4 @@ +// run-pass // Test that `Box` is equivalent to `Box`, both in // fields and fn arguments. diff --git a/src/test/run-pass/object-lifetime-default-from-rptr-box.rs b/src/test/ui/object-lifetime-default-from-rptr-box.rs similarity index 97% rename from src/test/run-pass/object-lifetime-default-from-rptr-box.rs rename to src/test/ui/object-lifetime-default-from-rptr-box.rs index 9212f2802c..8ac45b3db7 100644 --- a/src/test/run-pass/object-lifetime-default-from-rptr-box.rs +++ b/src/test/ui/object-lifetime-default-from-rptr-box.rs @@ -1,3 +1,4 @@ +// run-pass // Test that the lifetime from the enclosing `&` is "inherited" // through the `Box` struct. diff --git a/src/test/run-pass/object-lifetime-default-from-rptr-mut.rs b/src/test/ui/object-lifetime-default-from-rptr-mut.rs similarity index 97% rename from src/test/run-pass/object-lifetime-default-from-rptr-mut.rs rename to src/test/ui/object-lifetime-default-from-rptr-mut.rs index 061f3a116f..a09fc03ab9 100644 --- a/src/test/run-pass/object-lifetime-default-from-rptr-mut.rs +++ b/src/test/ui/object-lifetime-default-from-rptr-mut.rs @@ -1,3 +1,4 @@ +// run-pass // Test that the lifetime of the enclosing `&` is used for the object // lifetime bound. diff --git a/src/test/run-pass/object-lifetime-default-from-rptr.rs b/src/test/ui/object-lifetime-default-from-rptr.rs similarity index 98% rename from src/test/run-pass/object-lifetime-default-from-rptr.rs rename to src/test/ui/object-lifetime-default-from-rptr.rs index cfa4af0d7a..5093b1c27d 100644 --- a/src/test/run-pass/object-lifetime-default-from-rptr.rs +++ b/src/test/ui/object-lifetime-default-from-rptr.rs @@ -1,3 +1,4 @@ +// run-pass // Test that the lifetime of the enclosing `&` is used for the object // lifetime bound. diff --git a/src/test/ui/object-lifetime/object-lifetime-default.stderr b/src/test/ui/object-lifetime/object-lifetime-default.stderr index 2642cdff2b..f71c8cd0e0 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default.stderr @@ -1,20 +1,20 @@ -error: 'a,Ambiguous - --> $DIR/object-lifetime-default.rs:24:1 +error: BaseDefault + --> $DIR/object-lifetime-default.rs:6:1 | -LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct A(T); + | ^^^^^^^^^^^^^^^ -error: 'a,'b - --> $DIR/object-lifetime-default.rs:21:1 +error: BaseDefault + --> $DIR/object-lifetime-default.rs:9:1 | -LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct B<'a,T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: 'b - --> $DIR/object-lifetime-default.rs:18:1 +error: 'a + --> $DIR/object-lifetime-default.rs:12:1 | -LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct C<'a,T:'a>(&'a T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: Ambiguous --> $DIR/object-lifetime-default.rs:15:1 @@ -22,23 +22,23 @@ error: Ambiguous LL | struct D<'a,'b,T:'a+'b>(&'a T, &'b T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: 'a - --> $DIR/object-lifetime-default.rs:12:1 +error: 'b + --> $DIR/object-lifetime-default.rs:18:1 | -LL | struct C<'a,T:'a>(&'a T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: BaseDefault - --> $DIR/object-lifetime-default.rs:9:1 +error: 'a,'b + --> $DIR/object-lifetime-default.rs:21:1 | -LL | struct B<'a,T>(&'a (), T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: BaseDefault - --> $DIR/object-lifetime-default.rs:6:1 +error: 'a,Ambiguous + --> $DIR/object-lifetime-default.rs:24:1 | -LL | struct A(T); - | ^^^^^^^^^^^^^^^ +LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors diff --git a/src/test/run-pass/object-method-numbering.rs b/src/test/ui/object-method-numbering.rs similarity index 97% rename from src/test/run-pass/object-method-numbering.rs rename to src/test/ui/object-method-numbering.rs index 7f24ab2cbb..bf80a80f40 100644 --- a/src/test/run-pass/object-method-numbering.rs +++ b/src/test/ui/object-method-numbering.rs @@ -1,3 +1,4 @@ +// run-pass // Test for using an object with an associated type binding as the // instantiation for a generic type with a bound. diff --git a/src/test/ui/object-safety/object-safety-by-value-self.rs b/src/test/ui/object-safety/object-safety-by-value-self.rs index a8b1ddfaba..c74a4d1cbb 100644 --- a/src/test/ui/object-safety/object-safety-by-value-self.rs +++ b/src/test/ui/object-safety/object-safety-by-value-self.rs @@ -1,6 +1,6 @@ // Check that a trait with by-value self is considered object-safe. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(trivial_casts)] diff --git a/src/test/ui/object-safety/object-safety-phantom-fn.rs b/src/test/ui/object-safety/object-safety-phantom-fn.rs index 59ed12c78f..3ffeb81c1c 100644 --- a/src/test/ui/object-safety/object-safety-phantom-fn.rs +++ b/src/test/ui/object-safety/object-safety-phantom-fn.rs @@ -1,6 +1,6 @@ // Check that `Self` appearing in a phantom fn does not make a trait not object safe. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Baz { diff --git a/src/test/run-pass/objects-coerce-freeze-borrored.rs b/src/test/ui/objects-coerce-freeze-borrored.rs similarity index 98% rename from src/test/run-pass/objects-coerce-freeze-borrored.rs rename to src/test/ui/objects-coerce-freeze-borrored.rs index 47196f108c..704d77480b 100644 --- a/src/test/run-pass/objects-coerce-freeze-borrored.rs +++ b/src/test/ui/objects-coerce-freeze-borrored.rs @@ -1,3 +1,4 @@ +// run-pass // Test that we can coerce an `@Object` to an `&Object` diff --git a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs b/src/test/ui/objects-owned-object-borrowed-method-headerless.rs similarity index 98% rename from src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs rename to src/test/ui/objects-owned-object-borrowed-method-headerless.rs index 5832723749..9b88d8ea7b 100644 --- a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs +++ b/src/test/ui/objects-owned-object-borrowed-method-headerless.rs @@ -1,3 +1,4 @@ +// run-pass // Test invoked `&self` methods on owned objects where the values // closed over do not contain managed values, and thus the boxes do // not have headers. diff --git a/src/test/run-pass/objects-owned-object-owned-method.rs b/src/test/ui/objects-owned-object-owned-method.rs similarity index 97% rename from src/test/run-pass/objects-owned-object-owned-method.rs rename to src/test/ui/objects-owned-object-owned-method.rs index 69984fbb62..4b7b68f221 100644 --- a/src/test/run-pass/objects-owned-object-owned-method.rs +++ b/src/test/ui/objects-owned-object-owned-method.rs @@ -1,3 +1,4 @@ +// run-pass // Test invoked `&self` methods on owned objects where the values // closed over contain managed values. This implies that the boxes // will have headers that must be skipped over. diff --git a/src/test/ui/obsolete-in-place/bad.rs b/src/test/ui/obsolete-in-place/bad.rs index 67676857e8..3530862f76 100644 --- a/src/test/ui/obsolete-in-place/bad.rs +++ b/src/test/ui/obsolete-in-place/bad.rs @@ -3,7 +3,6 @@ fn foo() { let (x, y) = (0, 0); x <- y; //~ ERROR expected one of - //~^ ERROR mismatched types } fn main() { diff --git a/src/test/ui/obsolete-in-place/bad.stderr b/src/test/ui/obsolete-in-place/bad.stderr index 91ea82a657..373b7ea421 100644 --- a/src/test/ui/obsolete-in-place/bad.stderr +++ b/src/test/ui/obsolete-in-place/bad.stderr @@ -5,23 +5,10 @@ LL | x <- y; | ^^ expected one of 8 possible tokens here error: expected expression, found keyword `in` - --> $DIR/bad.rs:11:5 + --> $DIR/bad.rs:10:5 | LL | in(foo) { bar }; | ^^ expected expression -error[E0308]: mismatched types - --> $DIR/bad.rs:5:5 - | -LL | fn foo() { - | - possibly return type missing here? -LL | let (x, y) = (0, 0); -LL | x <- y; - | ^ expected (), found integer - | - = note: expected type `()` - found type `{integer}` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/run-pass/once-move-out-on-heap.rs b/src/test/ui/once-move-out-on-heap.rs similarity index 94% rename from src/test/run-pass/once-move-out-on-heap.rs rename to src/test/ui/once-move-out-on-heap.rs index 46e663417c..4e2e400cec 100644 --- a/src/test/run-pass/once-move-out-on-heap.rs +++ b/src/test/ui/once-move-out-on-heap.rs @@ -1,3 +1,4 @@ +// run-pass // Testing guarantees provided by once functions. diff --git a/src/test/run-pass/one-tuple.rs b/src/test/ui/one-tuple.rs similarity index 95% rename from src/test/run-pass/one-tuple.rs rename to src/test/ui/one-tuple.rs index fa54f95293..00fbadce1a 100644 --- a/src/test/run-pass/one-tuple.rs +++ b/src/test/ui/one-tuple.rs @@ -1,3 +1,4 @@ +// run-pass // Why one-tuples? Because macros. diff --git a/src/test/run-pass/op-assign-builtins-by-ref.rs b/src/test/ui/op-assign-builtins-by-ref.rs similarity index 99% rename from src/test/run-pass/op-assign-builtins-by-ref.rs rename to src/test/ui/op-assign-builtins-by-ref.rs index 8e0353e484..96853854d6 100644 --- a/src/test/run-pass/op-assign-builtins-by-ref.rs +++ b/src/test/ui/op-assign-builtins-by-ref.rs @@ -1,3 +1,5 @@ +// run-pass + fn main() { // test compound assignment operators with ref as right-hand side, // for each operator, with various types as operands. diff --git a/src/test/run-pass/opeq.rs b/src/test/ui/opeq.rs similarity index 95% rename from src/test/run-pass/opeq.rs rename to src/test/ui/opeq.rs index ea6c7647bb..9737be97fa 100644 --- a/src/test/run-pass/opeq.rs +++ b/src/test/ui/opeq.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let mut x: isize = 1; x *= 2; diff --git a/src/test/run-pass/operator-associativity.rs b/src/test/ui/operator-associativity.rs similarity index 88% rename from src/test/run-pass/operator-associativity.rs rename to src/test/ui/operator-associativity.rs index 69e3f699e9..4f40c80bc4 100644 --- a/src/test/run-pass/operator-associativity.rs +++ b/src/test/ui/operator-associativity.rs @@ -1,3 +1,4 @@ +// run-pass // Testcase for issue #130, operator associativity. pub fn main() { assert_eq!(3 * 5 / 2, 7); } diff --git a/src/test/run-pass/operator-multidispatch.rs b/src/test/ui/operator-multidispatch.rs similarity index 98% rename from src/test/run-pass/operator-multidispatch.rs rename to src/test/ui/operator-multidispatch.rs index cc546c903b..0d1dcfd8bd 100644 --- a/src/test/run-pass/operator-multidispatch.rs +++ b/src/test/ui/operator-multidispatch.rs @@ -1,3 +1,4 @@ +// run-pass // Test that we can overload the `+` operator for points so that two // points can be added, and a point can be added to an integer. diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/ui/operator-overloading.rs similarity index 99% rename from src/test/run-pass/operator-overloading.rs rename to src/test/ui/operator-overloading.rs index 026e2536ce..6b3abcbc76 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/ui/operator-overloading.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] use std::cmp; use std::ops; diff --git a/src/test/run-pass/optimization-fuel-0.rs b/src/test/ui/optimization-fuel-0.rs similarity index 95% rename from src/test/run-pass/optimization-fuel-0.rs rename to src/test/ui/optimization-fuel-0.rs index 77f21b3fcc..f86972b734 100644 --- a/src/test/run-pass/optimization-fuel-0.rs +++ b/src/test/ui/optimization-fuel-0.rs @@ -1,3 +1,5 @@ +// run-pass + #![crate_name="foo"] use std::mem::size_of; diff --git a/src/test/run-pass/optimization-fuel-0.stderr b/src/test/ui/optimization-fuel-0.stderr similarity index 100% rename from src/test/run-pass/optimization-fuel-0.stderr rename to src/test/ui/optimization-fuel-0.stderr diff --git a/src/test/run-pass/optimization-fuel-1.rs b/src/test/ui/optimization-fuel-1.rs similarity index 96% rename from src/test/run-pass/optimization-fuel-1.rs rename to src/test/ui/optimization-fuel-1.rs index 58778cac50..9828306636 100644 --- a/src/test/run-pass/optimization-fuel-1.rs +++ b/src/test/ui/optimization-fuel-1.rs @@ -1,3 +1,5 @@ +// run-pass + #![crate_name="foo"] use std::mem::size_of; diff --git a/src/test/run-pass/optimization-fuel-1.stderr b/src/test/ui/optimization-fuel-1.stderr similarity index 100% rename from src/test/run-pass/optimization-fuel-1.stderr rename to src/test/ui/optimization-fuel-1.stderr diff --git a/src/test/run-pass/option-ext.rs b/src/test/ui/option-ext.rs similarity index 90% rename from src/test/run-pass/option-ext.rs rename to src/test/ui/option-ext.rs index 0b21b8e5b5..76d0cf4398 100644 --- a/src/test/run-pass/option-ext.rs +++ b/src/test/ui/option-ext.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let thing = "{{ f }}"; let f = thing.find("{{"); diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/ui/option-unwrap.rs similarity index 97% rename from src/test/run-pass/option-unwrap.rs rename to src/test/ui/option-unwrap.rs index 6ad65c9924..173f803ee2 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/ui/option-unwrap.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] use std::cell::Cell; diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/ui/out-of-stack.rs similarity index 99% rename from src/test/run-pass/out-of-stack.rs rename to src/test/ui/out-of-stack.rs index f03935e3d2..5e9265be4b 100644 --- a/src/test/run-pass/out-of-stack.rs +++ b/src/test/ui/out-of-stack.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(unconditional_recursion)] // ignore-android: FIXME (#20004) diff --git a/src/test/run-pass/out-pointer-aliasing.rs b/src/test/ui/out-pointer-aliasing.rs similarity index 95% rename from src/test/run-pass/out-pointer-aliasing.rs rename to src/test/ui/out-pointer-aliasing.rs index 48fa9020b9..b28a091017 100644 --- a/src/test/run-pass/out-pointer-aliasing.rs +++ b/src/test/ui/out-pointer-aliasing.rs @@ -1,3 +1,5 @@ +// run-pass + #[derive(Copy, Clone)] pub struct Foo { f1: isize, diff --git a/src/test/run-pass/output-slot-variants.rs b/src/test/ui/output-slot-variants.rs similarity index 99% rename from src/test/run-pass/output-slot-variants.rs rename to src/test/ui/output-slot-variants.rs index f3cc2e99e0..af4caf7566 100644 --- a/src/test/run-pass/output-slot-variants.rs +++ b/src/test/ui/output-slot-variants.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unknown_lints)] diff --git a/src/test/run-pass/over-constrained-vregs.rs b/src/test/ui/over-constrained-vregs.rs similarity index 94% rename from src/test/run-pass/over-constrained-vregs.rs rename to src/test/ui/over-constrained-vregs.rs index 6d1b2d55e5..cc80814760 100644 --- a/src/test/run-pass/over-constrained-vregs.rs +++ b/src/test/ui/over-constrained-vregs.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] // Regression test for issue #152. pub fn main() { diff --git a/src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs similarity index 95% rename from src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs rename to src/test/ui/overlap-doesnt-conflict-with-specialization.rs index ddad0f5969..3d4069f368 100644 --- a/src/test/run-pass/overlap-doesnt-conflict-with-specialization.rs +++ b/src/test/ui/overlap-doesnt-conflict-with-specialization.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(overlapping_marker_traits)] #![feature(specialization)] diff --git a/src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs b/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs similarity index 97% rename from src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs rename to src/test/ui/overlap-permitted-for-annotated-marker-traits.rs index 53c5cfc813..3833139023 100644 --- a/src/test/run-pass/overlap-permitted-for-annotated-marker-traits.rs +++ b/src/test/ui/overlap-permitted-for-annotated-marker-traits.rs @@ -1,3 +1,4 @@ +// run-pass // Tests for RFC 1268: we allow overlapping impls of marker traits, // that is, traits with #[marker]. In this case, a type `T` is // `MyMarker` if it is either `Debug` or `Display`. diff --git a/src/test/run-pass/overloaded/auxiliary/overloaded_autoderef_xc.rs b/src/test/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs similarity index 100% rename from src/test/run-pass/overloaded/auxiliary/overloaded_autoderef_xc.rs rename to src/test/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs diff --git a/src/test/run-pass/overloaded/overloaded-autoderef-count.rs b/src/test/ui/overloaded/overloaded-autoderef-count.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-autoderef-count.rs rename to src/test/ui/overloaded/overloaded-autoderef-count.rs diff --git a/src/test/run-pass/overloaded/overloaded-autoderef-indexing.rs b/src/test/ui/overloaded/overloaded-autoderef-indexing.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-autoderef-indexing.rs rename to src/test/ui/overloaded/overloaded-autoderef-indexing.rs diff --git a/src/test/run-pass/overloaded/overloaded-autoderef-order.rs b/src/test/ui/overloaded/overloaded-autoderef-order.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-autoderef-order.rs rename to src/test/ui/overloaded/overloaded-autoderef-order.rs diff --git a/src/test/run-pass/overloaded/overloaded-autoderef-vtable.rs b/src/test/ui/overloaded/overloaded-autoderef-vtable.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-autoderef-vtable.rs rename to src/test/ui/overloaded/overloaded-autoderef-vtable.rs diff --git a/src/test/run-pass/overloaded/overloaded-autoderef-xcrate.rs b/src/test/ui/overloaded/overloaded-autoderef-xcrate.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-autoderef-xcrate.rs rename to src/test/ui/overloaded/overloaded-autoderef-xcrate.rs diff --git a/src/test/run-pass/overloaded/overloaded-autoderef.rs b/src/test/ui/overloaded/overloaded-autoderef.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-autoderef.rs rename to src/test/ui/overloaded/overloaded-autoderef.rs diff --git a/src/test/run-pass/overloaded/overloaded-calls-object-one-arg.rs b/src/test/ui/overloaded/overloaded-calls-object-one-arg.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-calls-object-one-arg.rs rename to src/test/ui/overloaded/overloaded-calls-object-one-arg.rs diff --git a/src/test/run-pass/overloaded/overloaded-calls-object-two-args.rs b/src/test/ui/overloaded/overloaded-calls-object-two-args.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-calls-object-two-args.rs rename to src/test/ui/overloaded/overloaded-calls-object-two-args.rs diff --git a/src/test/run-pass/overloaded/overloaded-calls-object-zero-args.rs b/src/test/ui/overloaded/overloaded-calls-object-zero-args.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-calls-object-zero-args.rs rename to src/test/ui/overloaded/overloaded-calls-object-zero-args.rs diff --git a/src/test/run-pass/overloaded/overloaded-calls-param-vtables.rs b/src/test/ui/overloaded/overloaded-calls-param-vtables.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-calls-param-vtables.rs rename to src/test/ui/overloaded/overloaded-calls-param-vtables.rs diff --git a/src/test/run-pass/overloaded/overloaded-calls-simple.rs b/src/test/ui/overloaded/overloaded-calls-simple.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-calls-simple.rs rename to src/test/ui/overloaded/overloaded-calls-simple.rs diff --git a/src/test/run-pass/overloaded/overloaded-calls-zero-args.rs b/src/test/ui/overloaded/overloaded-calls-zero-args.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-calls-zero-args.rs rename to src/test/ui/overloaded/overloaded-calls-zero-args.rs diff --git a/src/test/run-pass/overloaded/overloaded-deref-count.rs b/src/test/ui/overloaded/overloaded-deref-count.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-deref-count.rs rename to src/test/ui/overloaded/overloaded-deref-count.rs diff --git a/src/test/run-pass/overloaded/overloaded-deref.rs b/src/test/ui/overloaded/overloaded-deref.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-deref.rs rename to src/test/ui/overloaded/overloaded-deref.rs diff --git a/src/test/run-pass/overloaded/overloaded-index-assoc-list.rs b/src/test/ui/overloaded/overloaded-index-assoc-list.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-index-assoc-list.rs rename to src/test/ui/overloaded/overloaded-index-assoc-list.rs diff --git a/src/test/run-pass/overloaded/overloaded-index-autoderef.rs b/src/test/ui/overloaded/overloaded-index-autoderef.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-index-autoderef.rs rename to src/test/ui/overloaded/overloaded-index-autoderef.rs diff --git a/src/test/run-pass/overloaded/overloaded-index-in-field.rs b/src/test/ui/overloaded/overloaded-index-in-field.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-index-in-field.rs rename to src/test/ui/overloaded/overloaded-index-in-field.rs diff --git a/src/test/run-pass/overloaded/overloaded-index.rs b/src/test/ui/overloaded/overloaded-index.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded-index.rs rename to src/test/ui/overloaded/overloaded-index.rs diff --git a/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern.rs b/src/test/ui/overloaded/overloaded_deref_with_ref_pattern.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern.rs rename to src/test/ui/overloaded/overloaded_deref_with_ref_pattern.rs diff --git a/src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs b/src/test/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs similarity index 100% rename from src/test/run-pass/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs rename to src/test/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs diff --git a/src/test/run-pass/owned-implies-static.rs b/src/test/ui/owned-implies-static.rs similarity index 89% rename from src/test/run-pass/owned-implies-static.rs rename to src/test/ui/owned-implies-static.rs index 7101726ab6..2efa8cc02f 100644 --- a/src/test/run-pass/owned-implies-static.rs +++ b/src/test/ui/owned-implies-static.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 fn f(_x: T) {} diff --git a/src/test/run-pass/packed/auxiliary/packed.rs b/src/test/ui/packed/auxiliary/packed.rs similarity index 100% rename from src/test/run-pass/packed/auxiliary/packed.rs rename to src/test/ui/packed/auxiliary/packed.rs diff --git a/src/test/run-pass/packed/packed-struct-borrow-element.rs b/src/test/ui/packed/packed-struct-borrow-element.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-borrow-element.rs rename to src/test/ui/packed/packed-struct-borrow-element.rs diff --git a/src/test/run-pass/packed/packed-struct-drop-aligned.rs b/src/test/ui/packed/packed-struct-drop-aligned.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-drop-aligned.rs rename to src/test/ui/packed/packed-struct-drop-aligned.rs diff --git a/src/test/run-pass/packed/packed-struct-generic-layout.rs b/src/test/ui/packed/packed-struct-generic-layout.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-generic-layout.rs rename to src/test/ui/packed/packed-struct-generic-layout.rs diff --git a/src/test/run-pass/packed/packed-struct-generic-size.rs b/src/test/ui/packed/packed-struct-generic-size.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-generic-size.rs rename to src/test/ui/packed/packed-struct-generic-size.rs diff --git a/src/test/run-pass/packed/packed-struct-layout.rs b/src/test/ui/packed/packed-struct-layout.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-layout.rs rename to src/test/ui/packed/packed-struct-layout.rs diff --git a/src/test/run-pass/packed/packed-struct-match.rs b/src/test/ui/packed/packed-struct-match.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-match.rs rename to src/test/ui/packed/packed-struct-match.rs diff --git a/src/test/run-pass/packed/packed-struct-optimized-enum.rs b/src/test/ui/packed/packed-struct-optimized-enum.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-optimized-enum.rs rename to src/test/ui/packed/packed-struct-optimized-enum.rs diff --git a/src/test/run-pass/packed/packed-struct-size-xc.rs b/src/test/ui/packed/packed-struct-size-xc.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-size-xc.rs rename to src/test/ui/packed/packed-struct-size-xc.rs diff --git a/src/test/run-pass/packed/packed-struct-size.rs b/src/test/ui/packed/packed-struct-size.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-size.rs rename to src/test/ui/packed/packed-struct-size.rs diff --git a/src/test/run-pass/packed/packed-struct-vec.rs b/src/test/ui/packed/packed-struct-vec.rs similarity index 100% rename from src/test/run-pass/packed/packed-struct-vec.rs rename to src/test/ui/packed/packed-struct-vec.rs diff --git a/src/test/run-pass/packed/packed-tuple-struct-layout.rs b/src/test/ui/packed/packed-tuple-struct-layout.rs similarity index 100% rename from src/test/run-pass/packed/packed-tuple-struct-layout.rs rename to src/test/ui/packed/packed-tuple-struct-layout.rs diff --git a/src/test/run-pass/packed/packed-tuple-struct-size.rs b/src/test/ui/packed/packed-tuple-struct-size.rs similarity index 100% rename from src/test/run-pass/packed/packed-tuple-struct-size.rs rename to src/test/ui/packed/packed-tuple-struct-size.rs diff --git a/src/test/ui/packed/packed-with-inference-vars-issue-61402.rs b/src/test/ui/packed/packed-with-inference-vars-issue-61402.rs new file mode 100644 index 0000000000..659864c1d9 --- /dev/null +++ b/src/test/ui/packed/packed-with-inference-vars-issue-61402.rs @@ -0,0 +1,22 @@ +// run-pass +// If a struct is packed and its last field has drop glue, then that +// field needs to be Sized (to allow it to be destroyed out-of-place). +// +// This is checked by the compiler during wfcheck. That check used +// to have problems with associated types in the last field - test +// that this doesn't ICE. + +#![allow(unused_imports, dead_code)] + +pub struct S; + +pub trait Trait { type Assoc; } + +impl Trait for S { type Assoc = X; } + +#[repr(C, packed)] +struct PackedAssocSized { + pos: Box<>::Assoc>, +} + +fn main() { println!("Hello, world!"); } diff --git a/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs b/src/test/ui/panic-runtime/abort-link-to-unwinding-crates.rs similarity index 100% rename from src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs rename to src/test/ui/panic-runtime/abort-link-to-unwinding-crates.rs diff --git a/src/test/run-pass/panic-runtime/abort.rs b/src/test/ui/panic-runtime/abort.rs similarity index 100% rename from src/test/run-pass/panic-runtime/abort.rs rename to src/test/ui/panic-runtime/abort.rs diff --git a/src/test/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs b/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs similarity index 100% rename from src/test/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs rename to src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs diff --git a/src/test/run-pass/panic-runtime/link-to-abort.rs b/src/test/ui/panic-runtime/link-to-abort.rs similarity index 100% rename from src/test/run-pass/panic-runtime/link-to-abort.rs rename to src/test/ui/panic-runtime/link-to-abort.rs diff --git a/src/test/run-pass/panic-runtime/link-to-unwind.rs b/src/test/ui/panic-runtime/link-to-unwind.rs similarity index 100% rename from src/test/run-pass/panic-runtime/link-to-unwind.rs rename to src/test/ui/panic-runtime/link-to-unwind.rs diff --git a/src/test/run-pass/panic-runtime/lto-abort.rs b/src/test/ui/panic-runtime/lto-abort.rs similarity index 100% rename from src/test/run-pass/panic-runtime/lto-abort.rs rename to src/test/ui/panic-runtime/lto-abort.rs diff --git a/src/test/run-pass/panic-runtime/lto-unwind.rs b/src/test/ui/panic-runtime/lto-unwind.rs similarity index 100% rename from src/test/run-pass/panic-runtime/lto-unwind.rs rename to src/test/ui/panic-runtime/lto-unwind.rs diff --git a/src/test/ui/panic-runtime/needs-gate.stderr b/src/test/ui/panic-runtime/needs-gate.stderr index 72999a0de8..ab5d9f8cda 100644 --- a/src/test/ui/panic-runtime/needs-gate.stderr +++ b/src/test/ui/panic-runtime/needs-gate.stderr @@ -5,7 +5,7 @@ LL | #![panic_runtime] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32837 - = help: add #![feature(panic_runtime)] to the crate attributes to enable + = help: add `#![feature(panic_runtime)]` to the crate attributes to enable error[E0658]: the `#[needs_panic_runtime]` attribute is an experimental feature --> $DIR/needs-gate.rs:5:1 @@ -14,7 +14,7 @@ LL | #![needs_panic_runtime] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32837 - = help: add #![feature(needs_panic_runtime)] to the crate attributes to enable + = help: add `#![feature(needs_panic_runtime)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/run-pass/panic-uninitialized-zeroed.rs b/src/test/ui/panic-uninitialized-zeroed.rs similarity index 98% rename from src/test/run-pass/panic-uninitialized-zeroed.rs rename to src/test/ui/panic-uninitialized-zeroed.rs index 4ca4b407bd..b0d6629561 100644 --- a/src/test/run-pass/panic-uninitialized-zeroed.rs +++ b/src/test/ui/panic-uninitialized-zeroed.rs @@ -1,8 +1,10 @@ +// run-pass // ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding // This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results // in a runtime panic. #![feature(never_type)] +#![allow(deprecated, invalid_value)] use std::{mem, panic}; diff --git a/src/test/ui/panic_implementation-closures.rs b/src/test/ui/panic_implementation-closures.rs index 92c333b409..b96125aa95 100644 --- a/src/test/ui/panic_implementation-closures.rs +++ b/src/test/ui/panic_implementation-closures.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![no_std] diff --git a/src/test/run-pass/panics/panic-handler-chain.rs b/src/test/ui/panics/panic-handler-chain.rs similarity index 100% rename from src/test/run-pass/panics/panic-handler-chain.rs rename to src/test/ui/panics/panic-handler-chain.rs diff --git a/src/test/run-pass/panics/panic-handler-flail-wildly.rs b/src/test/ui/panics/panic-handler-flail-wildly.rs similarity index 100% rename from src/test/run-pass/panics/panic-handler-flail-wildly.rs rename to src/test/ui/panics/panic-handler-flail-wildly.rs diff --git a/src/test/run-pass/panics/panic-handler-set-twice.rs b/src/test/ui/panics/panic-handler-set-twice.rs similarity index 100% rename from src/test/run-pass/panics/panic-handler-set-twice.rs rename to src/test/ui/panics/panic-handler-set-twice.rs diff --git a/src/test/run-pass/panics/panic-in-dtor-drops-fields.rs b/src/test/ui/panics/panic-in-dtor-drops-fields.rs similarity index 100% rename from src/test/run-pass/panics/panic-in-dtor-drops-fields.rs rename to src/test/ui/panics/panic-in-dtor-drops-fields.rs diff --git a/src/test/run-pass/panics/panic-recover-propagate.rs b/src/test/ui/panics/panic-recover-propagate.rs similarity index 100% rename from src/test/run-pass/panics/panic-recover-propagate.rs rename to src/test/ui/panics/panic-recover-propagate.rs diff --git a/src/test/run-pass/panics/panic-safe.rs b/src/test/ui/panics/panic-safe.rs similarity index 100% rename from src/test/run-pass/panics/panic-safe.rs rename to src/test/ui/panics/panic-safe.rs diff --git a/src/test/run-pass/paren-free.rs b/src/test/ui/paren-free.rs similarity index 92% rename from src/test/run-pass/paren-free.rs rename to src/test/ui/paren-free.rs index 1f05ee0ed2..8e8bb8800e 100644 --- a/src/test/run-pass/paren-free.rs +++ b/src/test/ui/paren-free.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let x = true; if x { let mut i = 10; while i > 0 { i -= 1; } } diff --git a/src/test/run-pass/parse-assoc-type-lt.rs b/src/test/ui/parse-assoc-type-lt.rs similarity index 90% rename from src/test/run-pass/parse-assoc-type-lt.rs rename to src/test/ui/parse-assoc-type-lt.rs index e6b07c583f..d3fe6079a5 100644 --- a/src/test/run-pass/parse-assoc-type-lt.rs +++ b/src/test/ui/parse-assoc-type-lt.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/run-pass/parse-panic.rs b/src/test/ui/parse-panic.rs similarity index 90% rename from src/test/run-pass/parse-panic.rs rename to src/test/ui/parse-panic.rs index a08cd106ec..aeb2ba4faa 100644 --- a/src/test/run-pass/parse-panic.rs +++ b/src/test/ui/parse-panic.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unreachable_code)] diff --git a/src/test/run-pass/parser-unicode-whitespace.rs b/src/test/ui/parser-unicode-whitespace.rs similarity index 97% rename from src/test/run-pass/parser-unicode-whitespace.rs rename to src/test/ui/parser-unicode-whitespace.rs index 26e79b0617..2d1fa7dc42 100644 --- a/src/test/run-pass/parser-unicode-whitespace.rs +++ b/src/test/ui/parser-unicode-whitespace.rs @@ -1,3 +1,4 @@ +// run-pass // Beware editing: it has numerous whitespace characters which are important. // It contains one ranges from the 'PATTERN_WHITE_SPACE' property outlined in // http://unicode.org/Public/UNIDATA/PropList.txt diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr index 5111b40603..400a0276b3 100644 --- a/src/test/ui/parser/attr.stderr +++ b/src/test/ui/parser/attr.stderr @@ -1,8 +1,8 @@ error: an inner attribute is not permitted in this context - --> $DIR/attr.rs:5:3 + --> $DIR/attr.rs:5:1 | LL | #![lang = "foo"] - | ^ + | ^^^^^^^^^^^^^^^^ | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/parser/bounds-obj-parens.rs b/src/test/ui/parser/bounds-obj-parens.rs index 1e0f9e40cd..ae8112b61c 100644 --- a/src/test/ui/parser/bounds-obj-parens.rs +++ b/src/test/ui/parser/bounds-obj-parens.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(bare_trait_objects)] diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index ded088acfc..e199045134 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -1,8 +1,8 @@ -error: expected one of `async`, `const`, `existential`, `extern`, `fn`, `type`, or `unsafe`, found `pub` +error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found `pub` --> $DIR/default.rs:22:13 | LL | default pub fn foo() -> T { T::default() } - | ^^^ expected one of 7 possible tokens here + | ^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe` here error[E0449]: unnecessary visibility qualifier --> $DIR/default.rs:16:5 diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr index 9058e88d1d..d8884de1fe 100644 --- a/src/test/ui/parser/fn-arg-doc-comment.stderr +++ b/src/test/ui/parser/fn-arg-doc-comment.stderr @@ -23,7 +23,7 @@ LL | /// Comment | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60406 - = help: add #![feature(param_attrs)] to the crate attributes to enable + = help: add `#![feature(param_attrs)]` to the crate attributes to enable error[E0658]: attributes on function parameters are unstable --> $DIR/fn-arg-doc-comment.rs:8:5 @@ -32,7 +32,7 @@ LL | /// Other | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60406 - = help: add #![feature(param_attrs)] to the crate attributes to enable + = help: add `#![feature(param_attrs)]` to the crate attributes to enable error[E0308]: mismatched types --> $DIR/fn-arg-doc-comment.rs:22:7 diff --git a/src/test/ui/parser/impl-qpath.rs b/src/test/ui/parser/impl-qpath.rs index 78c41f481a..ab45649f4d 100644 --- a/src/test/ui/parser/impl-qpath.rs +++ b/src/test/ui/parser/impl-qpath.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z parse-only impl <*const u8>::AssocTy {} // OK diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.stderr b/src/test/ui/parser/inner-attr-after-doc-comment.stderr index 0dde49a291..b012abc25e 100644 --- a/src/test/ui/parser/inner-attr-after-doc-comment.stderr +++ b/src/test/ui/parser/inner-attr-after-doc-comment.stderr @@ -1,8 +1,13 @@ error: an inner attribute is not permitted following an outer doc comment - --> $DIR/inner-attr-after-doc-comment.rs:6:3 + --> $DIR/inner-attr-after-doc-comment.rs:6:1 | -LL | #![recursion_limit="100"] - | ^ +LL | / /** +LL | | * My module +LL | | */ + | |___- previous doc comment +LL | +LL | #![recursion_limit="100"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attibute | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/parser/inner-attr.stderr b/src/test/ui/parser/inner-attr.stderr index 11a37bc139..070d9f47d9 100644 --- a/src/test/ui/parser/inner-attr.stderr +++ b/src/test/ui/parser/inner-attr.stderr @@ -1,8 +1,11 @@ error: an inner attribute is not permitted following an outer attribute - --> $DIR/inner-attr.rs:3:3 + --> $DIR/inner-attr.rs:3:1 | +LL | #[feature(lang_items)] + | ---------------------- previous outer attribute +LL | LL | #![recursion_limit="100"] - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attibute | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/parser/issue-17383.stderr b/src/test/ui/parser/issue-17383.stderr index 486c405580..6a25c743e7 100644 --- a/src/test/ui/parser/issue-17383.stderr +++ b/src/test/ui/parser/issue-17383.stderr @@ -8,7 +8,7 @@ LL | B(usize) | -------- tuple variant defined here | = note: for more information, see https://github.com/rust-lang/rust/issues/60553 - = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/parser/issue-19096.rs b/src/test/ui/parser/issue-19096.rs index edc69e6f49..c5bfd10ee5 100644 --- a/src/test/ui/parser/issue-19096.rs +++ b/src/test/ui/parser/issue-19096.rs @@ -1,5 +1,10 @@ -fn main() { +fn main() { // we don't complain about the return type being `{integer}` let t = (42, 42); t.0::; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `::` - //~| ERROR mismatched types +} + +fn foo() -> usize { // we don't complain about the return type being unit + let t = (42, 42); + t.0::; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `::` + 42; } diff --git a/src/test/ui/parser/issue-19096.stderr b/src/test/ui/parser/issue-19096.stderr index 6aa97add7b..957b40dbd5 100644 --- a/src/test/ui/parser/issue-19096.stderr +++ b/src/test/ui/parser/issue-19096.stderr @@ -4,18 +4,11 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::` LL | t.0::; | ^^ expected one of `.`, `;`, `?`, `}`, or an operator here -error[E0308]: mismatched types - --> $DIR/issue-19096.rs:3:5 +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::` + --> $DIR/issue-19096.rs:8:8 | -LL | fn main() { - | - expected `()` because of default return type -LL | let t = (42, 42); LL | t.0::; - | ^^^ expected (), found integer - | - = note: expected type `()` - found type `{integer}` + | ^^ expected one of `.`, `;`, `?`, `}`, or an operator here error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issue-20711-2.rs b/src/test/ui/parser/issue-20711-2.rs index 49b8de03c3..0063a33418 100644 --- a/src/test/ui/parser/issue-20711-2.rs +++ b/src/test/ui/parser/issue-20711-2.rs @@ -1,11 +1,9 @@ -// ignore-tidy-linelength - struct Foo; impl Foo { fn foo() {} #[stable(feature = "rust1", since = "1.0.0")] -} //~ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, or +} //~ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or fn main() {} diff --git a/src/test/ui/parser/issue-20711-2.stderr b/src/test/ui/parser/issue-20711-2.stderr index f67dfa09ac..56749c107d 100644 --- a/src/test/ui/parser/issue-20711-2.stderr +++ b/src/test/ui/parser/issue-20711-2.stderr @@ -1,8 +1,8 @@ -error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `}` - --> $DIR/issue-20711-2.rs:9:1 +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `}` + --> $DIR/issue-20711-2.rs:7:1 | LL | #[stable(feature = "rust1", since = "1.0.0")] - | - expected one of 10 possible tokens here + | - expected one of 9 possible tokens here LL | } | ^ unexpected token diff --git a/src/test/ui/parser/issue-20711.rs b/src/test/ui/parser/issue-20711.rs index 8d8401da61..dc216167b8 100644 --- a/src/test/ui/parser/issue-20711.rs +++ b/src/test/ui/parser/issue-20711.rs @@ -1,9 +1,7 @@ -// ignore-tidy-linelength - struct Foo; impl Foo { #[stable(feature = "rust1", since = "1.0.0")] -} //~ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, or +} //~ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or fn main() {} diff --git a/src/test/ui/parser/issue-20711.stderr b/src/test/ui/parser/issue-20711.stderr index 26b819fa29..f7b99a91b5 100644 --- a/src/test/ui/parser/issue-20711.stderr +++ b/src/test/ui/parser/issue-20711.stderr @@ -1,8 +1,8 @@ -error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `}` - --> $DIR/issue-20711.rs:7:1 +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `}` + --> $DIR/issue-20711.rs:5:1 | LL | #[stable(feature = "rust1", since = "1.0.0")] - | - expected one of 10 possible tokens here + | - expected one of 9 possible tokens here LL | } | ^ unexpected token diff --git a/src/test/ui/parser/issue-33262.stderr b/src/test/ui/parser/issue-33262.stderr index c2491df903..2aff328393 100644 --- a/src/test/ui/parser/issue-33262.stderr +++ b/src/test/ui/parser/issue-33262.stderr @@ -2,7 +2,7 @@ error: expected type, found `{` --> $DIR/issue-33262.rs:4:22 | LL | for i in 0..a as { } - | ^ + | ^ expected type error: aborting due to previous error diff --git a/src/test/ui/parser/issue-41155.stderr b/src/test/ui/parser/issue-41155.stderr index 719845e699..624d1a3d11 100644 --- a/src/test/ui/parser/issue-41155.stderr +++ b/src/test/ui/parser/issue-41155.stderr @@ -1,8 +1,8 @@ -error: expected one of `(`, `async`, `const`, `default`, `existential`, `extern`, `fn`, `type`, or `unsafe`, found `}` +error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found `}` --> $DIR/issue-41155.rs:5:1 | LL | pub - | - expected one of 9 possible tokens here + | - expected one of 8 possible tokens here LL | } | ^ unexpected token diff --git a/src/test/ui/parser/issue-62881.stderr b/src/test/ui/parser/issue-62881.stderr index 85c3575fd9..3d58b6fba0 100644 --- a/src/test/ui/parser/issue-62881.stderr +++ b/src/test/ui/parser/issue-62881.stderr @@ -19,7 +19,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { fn f() -> isize {} pub f< | - ^^^^^ expected isize, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `isize` found type `()` diff --git a/src/test/ui/parser/issue-62895.stderr b/src/test/ui/parser/issue-62895.stderr index 882764cb94..39ce980964 100644 --- a/src/test/ui/parser/issue-62895.stderr +++ b/src/test/ui/parser/issue-62895.stderr @@ -30,7 +30,7 @@ error[E0412]: cannot find type `isizee` in this scope --> $DIR/issue-62895.rs:5:15 | LL | pub fn g() -> isizee { - | ^^^^^^ help: a primitive type with a similar name exists: `isize` + | ^^^^^^ help: a builtin type with a similar name exists: `isize` error[E0308]: mismatched types --> $DIR/issue-62895.rs:3:11 @@ -38,7 +38,7 @@ error[E0308]: mismatched types LL | fn v() -> isize { | - ^^^^^ expected isize, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `isize` found type `()` diff --git a/src/test/ui/parser/issue-62913.rs b/src/test/ui/parser/issue-62913.rs new file mode 100644 index 0000000000..cfa19a2a31 --- /dev/null +++ b/src/test/ui/parser/issue-62913.rs @@ -0,0 +1,3 @@ +"\u\\" +//~^ ERROR incorrect unicode escape sequence +//~| ERROR invalid trailing slash in literal diff --git a/src/test/ui/parser/issue-62913.stderr b/src/test/ui/parser/issue-62913.stderr new file mode 100644 index 0000000000..05c5c4d000 --- /dev/null +++ b/src/test/ui/parser/issue-62913.stderr @@ -0,0 +1,16 @@ +error: incorrect unicode escape sequence + --> $DIR/issue-62913.rs:1:2 + | +LL | "\u\" + | ^^^ incorrect unicode escape sequence + | + = help: format of unicode escape sequences is `\u{...}` + +error: invalid trailing slash in literal + --> $DIR/issue-62913.rs:1:5 + | +LL | "\u\" + | ^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/issue-62973.rs b/src/test/ui/parser/issue-62973.rs new file mode 100644 index 0000000000..18bc51e7ba --- /dev/null +++ b/src/test/ui/parser/issue-62973.rs @@ -0,0 +1,8 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 6 previous errors + +fn main() {} + +fn p() { match s { v, E { [) {) } + + diff --git a/src/test/ui/parser/issue-62973.stderr b/src/test/ui/parser/issue-62973.stderr new file mode 100644 index 0000000000..141076bf6b --- /dev/null +++ b/src/test/ui/parser/issue-62973.stderr @@ -0,0 +1,61 @@ +error: this file contains an un-closed delimiter + --> $DIR/issue-62973.rs:8:2 + | +LL | fn p() { match s { v, E { [) {) } + | - - un-closed delimiter + | | + | un-closed delimiter +LL | +LL | + | ^ + +error: expected one of `,` or `}`, found `{` + --> $DIR/issue-62973.rs:6:25 + | +LL | fn p() { match s { v, E { [) {) } + | - ^ expected one of `,` or `}` here + | | + | while parsing this struct + +error: struct literals are not allowed here + --> $DIR/issue-62973.rs:6:16 + | +LL | fn p() { match s { v, E { [) {) } + | ________________^ +LL | | +LL | | + | |_^ +help: surround the struct literal with parentheses + | +LL | fn p() { match (s { v, E { [) {) } +LL | +LL | ) + | + +error: expected one of `.`, `?`, `{`, or an operator, found `}` + --> $DIR/issue-62973.rs:8:1 + | +LL | fn p() { match s { v, E { [) {) } + | ----- while parsing this match expression +LL | +LL | + | ^ expected one of `.`, `?`, `{`, or an operator here + +error: incorrect close delimiter: `)` + --> $DIR/issue-62973.rs:6:28 + | +LL | fn p() { match s { v, E { [) {) } + | -^ incorrect close delimiter + | | + | un-closed delimiter + +error: incorrect close delimiter: `)` + --> $DIR/issue-62973.rs:6:31 + | +LL | fn p() { match s { v, E { [) {) } + | -^ incorrect close delimiter + | | + | un-closed delimiter + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issue-63115-range-pat-interpolated.rs b/src/test/ui/parser/issue-63115-range-pat-interpolated.rs new file mode 100644 index 0000000000..a7d10ca932 --- /dev/null +++ b/src/test/ui/parser/issue-63115-range-pat-interpolated.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(exclusive_range_pattern)] + +#![allow(ellipsis_inclusive_range_patterns)] + +fn main() { + macro_rules! mac_expr { + ($e:expr) => { + if let 2...$e = 3 {} + if let 2..=$e = 3 {} + if let 2..$e = 3 {} + } + } + mac_expr!(4); +} diff --git a/src/test/ui/parser/issue-63135.rs b/src/test/ui/parser/issue-63135.rs new file mode 100644 index 0000000000..d5f5f1469f --- /dev/null +++ b/src/test/ui/parser/issue-63135.rs @@ -0,0 +1,3 @@ +// error-pattern: aborting due to 6 previous errors + +fn i(n{...,f # diff --git a/src/test/ui/parser/issue-63135.stderr b/src/test/ui/parser/issue-63135.stderr new file mode 100644 index 0000000000..c0286d90af --- /dev/null +++ b/src/test/ui/parser/issue-63135.stderr @@ -0,0 +1,44 @@ +error: this file contains an un-closed delimiter + --> $DIR/issue-63135.rs:3:16 + | +LL | fn i(n{...,f # + | - - ^ + | | | + | | un-closed delimiter + | un-closed delimiter + +error: expected field pattern, found `...` + --> $DIR/issue-63135.rs:3:8 + | +LL | fn i(n{...,f # + | ^^^ help: to omit remaining fields, use one fewer `.`: `..` + +error: expected `}`, found `,` + --> $DIR/issue-63135.rs:3:11 + | +LL | fn i(n{...,f # + | ---^ + | | | + | | expected `}` + | `..` must be at the end and cannot have a trailing comma + +error: expected `[`, found `}` + --> $DIR/issue-63135.rs:3:15 + | +LL | fn i(n{...,f # + | ^ expected `[` + +error: expected `:`, found `)` + --> $DIR/issue-63135.rs:3:15 + | +LL | fn i(n{...,f # + | ^ expected `:` + +error: expected one of `->`, `where`, or `{`, found `` + --> $DIR/issue-63135.rs:3:15 + | +LL | fn i(n{...,f # + | ^ expected one of `->`, `where`, or `{` here + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/lex-bad-numeric-literals.stderr b/src/test/ui/parser/lex-bad-numeric-literals.stderr index 84e27f7366..151480dd01 100644 --- a/src/test/ui/parser/lex-bad-numeric-literals.stderr +++ b/src/test/ui/parser/lex-bad-numeric-literals.stderr @@ -53,10 +53,10 @@ LL | 0o; | ^^ error: expected at least one digit in exponent - --> $DIR/lex-bad-numeric-literals.rs:12:8 + --> $DIR/lex-bad-numeric-literals.rs:12:5 | LL | 1e+; - | ^ + | ^^^ error: hexadecimal float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:13:5 diff --git a/src/test/ui/parser/lex-bad-token.rs b/src/test/ui/parser/lex-bad-token.rs index feb670c3d3..9e48246111 100644 --- a/src/test/ui/parser/lex-bad-token.rs +++ b/src/test/ui/parser/lex-bad-token.rs @@ -1 +1,3 @@ ● //~ ERROR: unknown start of token + +fn main() {} diff --git a/src/test/ui/parser/lex-stray-backslash.rs b/src/test/ui/parser/lex-stray-backslash.rs index 90d359231a..bb27f44c27 100644 --- a/src/test/ui/parser/lex-stray-backslash.rs +++ b/src/test/ui/parser/lex-stray-backslash.rs @@ -1 +1,3 @@ \ //~ ERROR: unknown start of token: \ + +fn main() {} diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.rs b/src/test/ui/parser/macro-bad-delimiter-ident.rs index 987c955d1d..13dec95435 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.rs +++ b/src/test/ui/parser/macro-bad-delimiter-ident.rs @@ -1,3 +1,3 @@ fn main() { - foo! bar < //~ ERROR expected `(` or `{`, found `<` + foo! bar < //~ ERROR expected open delimiter } diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.stderr b/src/test/ui/parser/macro-bad-delimiter-ident.stderr index 6a17d39e8b..e97839a4f4 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.stderr +++ b/src/test/ui/parser/macro-bad-delimiter-ident.stderr @@ -1,8 +1,8 @@ -error: expected `(` or `{`, found `<` - --> $DIR/macro-bad-delimiter-ident.rs:2:14 +error: expected open delimiter + --> $DIR/macro-bad-delimiter-ident.rs:2:10 | LL | foo! bar < - | ^ expected `(` or `{` + | ^^^ expected open delimiter error: aborting due to previous error diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr index 19c5c82f82..f02f60e4bf 100644 --- a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr +++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr @@ -2,7 +2,7 @@ error: expected type, found `'static` --> $DIR/trait-object-macro-matcher.rs:9:8 | LL | m!('static); - | ^^^^^^^ + | ^^^^^^^ expected type error: aborting due to previous error diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs index e5e85ba8ca..00f4374b25 100644 --- a/src/test/ui/parser/match-vec-invalid.rs +++ b/src/test/ui/parser/match-vec-invalid.rs @@ -1,7 +1,13 @@ fn main() { - let a = Vec::new(); + let a: &[u8] = &[]; match a { - [1, tail.., tail..] => {}, //~ ERROR: expected one of `,` or `@`, found `..` + [1, tail @ .., tail @ ..] => {}, + //~^ ERROR identifier `tail` is bound more than once in the same pattern + //~| ERROR subslice patterns are unstable + //~| ERROR subslice patterns are unstable + //~| ERROR `..` can only be used once per slice pattern _ => () } } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr index fee8d248dc..0956ac21b7 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/parser/match-vec-invalid.stderr @@ -1,8 +1,45 @@ -error: expected one of `,` or `@`, found `..` - --> $DIR/match-vec-invalid.rs:4:25 +error[E0416]: identifier `tail` is bound more than once in the same pattern + --> $DIR/match-vec-invalid.rs:4:24 | -LL | [1, tail.., tail..] => {}, - | ^^ expected one of `,` or `@` here +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^ used in a pattern more than once -error: aborting due to previous error +error[E0658]: subslice patterns are unstable + --> $DIR/match-vec-invalid.rs:4:13 + | +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable + +error[E0658]: subslice patterns are unstable + --> $DIR/match-vec-invalid.rs:4:24 + | +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable + +error: `..` can only be used once per slice pattern + --> $DIR/match-vec-invalid.rs:4:31 + | +LL | [1, tail @ .., tail @ ..] => {}, + | -- ^^ can only be used once per slice pattern + | | + | previously used here + +error[E0308]: mismatched types + --> $DIR/match-vec-invalid.rs:13:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` + +error: aborting due to 5 previous errors +Some errors have detailed explanations: E0308, E0416, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs index 9bad0cb25c..7b97218309 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.rs +++ b/src/test/ui/parser/pat-lt-bracket-6.rs @@ -1,3 +1,9 @@ fn main() { + struct Test(&'static u8, [u8; 0]); + let x = Test(&0, []); + let Test(&desc[..]) = x; //~ ERROR: expected one of `)`, `,`, or `@`, found `[` + //~^ ERROR subslice patterns are unstable } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr index 2ee4bdb20f..201465b2c8 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.stderr +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -1,8 +1,28 @@ error: expected one of `)`, `,`, or `@`, found `[` - --> $DIR/pat-lt-bracket-6.rs:2:19 + --> $DIR/pat-lt-bracket-6.rs:5:19 | LL | let Test(&desc[..]) = x; | ^ expected one of `)`, `,`, or `@` here -error: aborting due to previous error +error[E0658]: subslice patterns are unstable + --> $DIR/pat-lt-bracket-6.rs:5:20 + | +LL | let Test(&desc[..]) = x; + | ^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable + +error[E0308]: mismatched types + --> $DIR/pat-lt-bracket-6.rs:9:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs index 36c0d77337..020fdb845e 100644 --- a/src/test/ui/parser/pat-lt-bracket-7.rs +++ b/src/test/ui/parser/pat-lt-bracket-7.rs @@ -1,3 +1,8 @@ fn main() { - for thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[` + struct Thing(u8, [u8; 0]); + let foo = core::iter::empty(); + + for Thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[` } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr index 5552ea46d9..17557efa49 100644 --- a/src/test/ui/parser/pat-lt-bracket-7.stderr +++ b/src/test/ui/parser/pat-lt-bracket-7.stderr @@ -1,8 +1,18 @@ error: expected one of `)`, `,`, or `@`, found `[` - --> $DIR/pat-lt-bracket-7.rs:2:16 + --> $DIR/pat-lt-bracket-7.rs:5:16 | -LL | for thing(x[]) in foo {} +LL | for Thing(x[]) in foo {} | ^ expected one of `)`, `,`, or `@` here -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/pat-lt-bracket-7.rs:8:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs index fd25499381..a8f3debd3d 100644 --- a/src/test/ui/parser/pat-tuple-2.rs +++ b/src/test/ui/parser/pat-tuple-2.rs @@ -1,6 +1,7 @@ +// check-pass + fn main() { match (0, 1, 2) { (pat, ..,) => {} - //~^ ERROR trailing comma is not permitted after `..` } } diff --git a/src/test/ui/parser/pat-tuple-2.stderr b/src/test/ui/parser/pat-tuple-2.stderr deleted file mode 100644 index c3a5c39a8e..0000000000 --- a/src/test/ui/parser/pat-tuple-2.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: trailing comma is not permitted after `..` - --> $DIR/pat-tuple-2.rs:3:17 - | -LL | (pat, ..,) => {} - | ^ trailing comma is not permitted after `..` - -error: aborting due to previous error - diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs index e1e975d3c3..1486ab231a 100644 --- a/src/test/ui/parser/pat-tuple-3.rs +++ b/src/test/ui/parser/pat-tuple-3.rs @@ -1,6 +1,6 @@ fn main() { match (0, 1, 2) { (.., pat, ..) => {} - //~^ ERROR `..` can only be used once per tuple or tuple struct pattern + //~^ ERROR `..` can only be used once per tuple pattern } } diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr index c9f14bb904..9ac0611c5c 100644 --- a/src/test/ui/parser/pat-tuple-3.stderr +++ b/src/test/ui/parser/pat-tuple-3.stderr @@ -1,10 +1,10 @@ -error: `..` can only be used once per tuple or tuple struct pattern +error: `..` can only be used once per tuple pattern --> $DIR/pat-tuple-3.rs:3:19 | LL | (.., pat, ..) => {} - | -- ^^ can only be used once per pattern + | -- ^^ can only be used once per tuple pattern | | - | previously present here + | previously used here error: aborting due to previous error diff --git a/src/test/ui/parser/pat-tuple-4.rs b/src/test/ui/parser/pat-tuple-4.rs index 76f60d94bc..2f03160430 100644 --- a/src/test/ui/parser/pat-tuple-4.rs +++ b/src/test/ui/parser/pat-tuple-4.rs @@ -1,5 +1,11 @@ fn main() { + const PAT: u8 = 0; + match 0 { - (.. pat) => {} //~ ERROR expected one of `)` or `,`, found `pat` + (.. PAT) => {} + //~^ ERROR `..X` range patterns are not supported + //~| ERROR exclusive range pattern syntax is experimental } } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-tuple-4.stderr b/src/test/ui/parser/pat-tuple-4.stderr index 26b92fae31..af3ecce184 100644 --- a/src/test/ui/parser/pat-tuple-4.stderr +++ b/src/test/ui/parser/pat-tuple-4.stderr @@ -1,8 +1,28 @@ -error: expected one of `)` or `,`, found `pat` - --> $DIR/pat-tuple-4.rs:3:13 +error: `..X` range patterns are not supported + --> $DIR/pat-tuple-4.rs:5:10 | -LL | (.. pat) => {} - | ^^^ expected one of `)` or `,` here +LL | (.. PAT) => {} + | ^^^^^^ help: try using the minimum value for the type: `MIN..PAT` -error: aborting due to previous error +error[E0658]: exclusive range pattern syntax is experimental + --> $DIR/pat-tuple-4.rs:5:10 + | +LL | (.. PAT) => {} + | ^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/37854 + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable + +error[E0308]: mismatched types + --> $DIR/pat-tuple-4.rs:11:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-tuple-5.rs b/src/test/ui/parser/pat-tuple-5.rs index d4f05a5eb5..5334ef93bb 100644 --- a/src/test/ui/parser/pat-tuple-5.rs +++ b/src/test/ui/parser/pat-tuple-5.rs @@ -1,5 +1,10 @@ fn main() { + const PAT: u8 = 0; + match (0, 1) { - (pat ..) => {} //~ ERROR unexpected token: `)` + (PAT ..) => {} + //~^ ERROR `X..` range patterns are not supported + //~| ERROR exclusive range pattern syntax is experimental + //~| ERROR mismatched types } } diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index f9832214c6..09ebdc29a2 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -1,8 +1,30 @@ -error: unexpected token: `)` - --> $DIR/pat-tuple-5.rs:3:16 +error: `X..` range patterns are not supported + --> $DIR/pat-tuple-5.rs:5:10 | -LL | (pat ..) => {} - | ^ +LL | (PAT ..) => {} + | ^^^^^^ help: try using the maximum value for the type: `PAT..MAX` -error: aborting due to previous error +error[E0658]: exclusive range pattern syntax is experimental + --> $DIR/pat-tuple-5.rs:5:10 + | +LL | (PAT ..) => {} + | ^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/37854 + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable + +error[E0308]: mismatched types + --> $DIR/pat-tuple-5.rs:5:10 + | +LL | match (0, 1) { + | ------ this match expression has type `({integer}, {integer})` +LL | (PAT ..) => {} + | ^^^^^^ expected tuple, found u8 + | + = note: expected type `({integer}, {integer})` + found type `u8` + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/raw-byte-string-eof.stderr b/src/test/ui/parser/raw-byte-string-eof.stderr index 2ba50e8fb2..65fa89f2a8 100644 --- a/src/test/ui/parser/raw-byte-string-eof.stderr +++ b/src/test/ui/parser/raw-byte-string-eof.stderr @@ -1,8 +1,8 @@ error: unterminated raw string - --> $DIR/raw-byte-string-eof.rs:2:6 + --> $DIR/raw-byte-string-eof.rs:2:5 | LL | br##"a"#; - | ^ unterminated raw string + | ^ unterminated raw string | = note: this raw string should be terminated with `"##` diff --git a/src/test/ui/parser/raw-byte-string-literals.stderr b/src/test/ui/parser/raw-byte-string-literals.stderr index 4880d1fdbe..4076fe334e 100644 --- a/src/test/ui/parser/raw-byte-string-literals.stderr +++ b/src/test/ui/parser/raw-byte-string-literals.stderr @@ -11,10 +11,10 @@ LL | br"é"; | ^ error: found invalid character; only `#` is allowed in raw string delimitation: ~ - --> $DIR/raw-byte-string-literals.rs:6:6 + --> $DIR/raw-byte-string-literals.rs:6:5 | LL | br##~"a"~##; - | ^^^ + | ^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/raw-str-delim.stderr b/src/test/ui/parser/raw-str-delim.stderr index b86b9e90e7..8a04f99a12 100644 --- a/src/test/ui/parser/raw-str-delim.stderr +++ b/src/test/ui/parser/raw-str-delim.stderr @@ -2,7 +2,7 @@ error: found invalid character; only `#` is allowed in raw string delimitation: --> $DIR/raw-str-delim.rs:2:5 | LL | r#~"#"~# - | ^^ + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw-literal-keywords.rs b/src/test/ui/parser/raw/raw-literal-keywords.rs index f51e565c2d..6b055fbb11 100644 --- a/src/test/ui/parser/raw/raw-literal-keywords.rs +++ b/src/test/ui/parser/raw/raw-literal-keywords.rs @@ -1,16 +1,25 @@ fn test_if() { r#if true { } //~ ERROR found `true` - //~| ERROR cannot find value `if` in this scope } fn test_struct() { r#struct Test; //~ ERROR found `Test` - //~| ERROR cannot find value `struct` in this scope } fn test_union() { r#union Test; //~ ERROR found `Test` - //~| ERROR cannot find value `union` in this scope +} + +fn test_if_2() { + let _ = r#if; //~ ERROR cannot find value `if` in this scope +} + +fn test_struct_2() { + let _ = r#struct; //~ ERROR cannot find value `struct` in this scope +} + +fn test_union_2() { + let _ = r#union; //~ ERROR cannot find value `union` in this scope } fn main() {} diff --git a/src/test/ui/parser/raw/raw-literal-keywords.stderr b/src/test/ui/parser/raw/raw-literal-keywords.stderr index 8b8b71373b..f39e29cfaa 100644 --- a/src/test/ui/parser/raw/raw-literal-keywords.stderr +++ b/src/test/ui/parser/raw/raw-literal-keywords.stderr @@ -5,34 +5,34 @@ LL | r#if true { } | ^^^^ expected one of 8 possible tokens here error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` - --> $DIR/raw-literal-keywords.rs:7:14 + --> $DIR/raw-literal-keywords.rs:6:14 | LL | r#struct Test; | ^^^^ expected one of 8 possible tokens here error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` - --> $DIR/raw-literal-keywords.rs:12:13 + --> $DIR/raw-literal-keywords.rs:10:13 | LL | r#union Test; | ^^^^ expected one of 8 possible tokens here error[E0425]: cannot find value `if` in this scope - --> $DIR/raw-literal-keywords.rs:2:5 + --> $DIR/raw-literal-keywords.rs:14:13 | -LL | r#if true { } - | ^^^^ not found in this scope +LL | let _ = r#if; + | ^^^^ not found in this scope error[E0425]: cannot find value `struct` in this scope - --> $DIR/raw-literal-keywords.rs:7:5 + --> $DIR/raw-literal-keywords.rs:18:13 | -LL | r#struct Test; - | ^^^^^^^^ not found in this scope +LL | let _ = r#struct; + | ^^^^^^^^ not found in this scope error[E0425]: cannot find value `union` in this scope - --> $DIR/raw-literal-keywords.rs:12:5 + --> $DIR/raw-literal-keywords.rs:22:13 | -LL | r#union Test; - | ^^^^^^^ not found in this scope +LL | let _ = r#union; + | ^^^^^^^ not found in this scope error: aborting due to 6 previous errors diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr index 9ed2e6f5eb..2311887a6f 100644 --- a/src/test/ui/parser/recover-enum2.stderr +++ b/src/test/ui/parser/recover-enum2.stderr @@ -2,7 +2,7 @@ error: expected type, found `{` --> $DIR/recover-enum2.rs:6:18 | LL | abc: {}, - | ^ + | ^ expected type error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{` --> $DIR/recover-enum2.rs:25:22 diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.rs b/src/test/ui/parser/recover-for-loop-parens-around-head.rs new file mode 100644 index 0000000000..e6c59fcf22 --- /dev/null +++ b/src/test/ui/parser/recover-for-loop-parens-around-head.rs @@ -0,0 +1,15 @@ +// Here we test that the parser is able to recover in a situation like +// `for ( $pat in $expr )` since that is familiar syntax in other languages. +// Instead we suggest that the user writes `for $pat in $expr`. + +#![deny(unused)] // Make sure we don't trigger `unused_parens`. + +fn main() { + let vec = vec![1, 2, 3]; + + for ( elem in vec ) { + //~^ ERROR expected one of `)`, `,`, or `@`, found `in` + //~| ERROR unexpected closing `)` + const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types + } +} diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr new file mode 100644 index 0000000000..c160e646c2 --- /dev/null +++ b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr @@ -0,0 +1,27 @@ +error: expected one of `)`, `,`, or `@`, found `in` + --> $DIR/recover-for-loop-parens-around-head.rs:10:16 + | +LL | for ( elem in vec ) { + | ^^ expected one of `)`, `,`, or `@` here + +error: unexpected closing `)` + --> $DIR/recover-for-loop-parens-around-head.rs:10:23 + | +LL | for ( elem in vec ) { + | --------------^ + | | + | opening `(` + | help: remove parenthesis in `for` loop: `elem in vec` + +error[E0308]: mismatched types + --> $DIR/recover-for-loop-parens-around-head.rs:13:38 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr index 150d74f074..b46d3ca9c2 100644 --- a/src/test/ui/parser/recover-from-bad-variant.stderr +++ b/src/test/ui/parser/recover-from-bad-variant.stderr @@ -2,15 +2,12 @@ error: expected type, found `3` --> $DIR/recover-from-bad-variant.rs:7:26 | LL | let x = Enum::Foo(a: 3, b: 4); - | ^ expecting a type here because of type ascription + | - ^ expected type + | | + | tried to parse a type due to this type ascription | - = note: #![feature(type_ascription)] lets you annotate an expression with a type: `: ` -note: this expression expects an ascribed type after the colon - --> $DIR/recover-from-bad-variant.rs:7:23 - | -LL | let x = Enum::Foo(a: 3, b: 4); - | ^ - = help: this might be indicative of a syntax error elsewhere + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo` --> $DIR/recover-from-bad-variant.rs:10:9 diff --git a/src/test/ui/parser/recover-from-homoglyph.rs b/src/test/ui/parser/recover-from-homoglyph.rs new file mode 100644 index 0000000000..99ce0d1a63 --- /dev/null +++ b/src/test/ui/parser/recover-from-homoglyph.rs @@ -0,0 +1,4 @@ +fn main() { + println!(""); //~ ERROR unknown start of token: \u{37e} + let x: usize = (); //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/recover-from-homoglyph.stderr b/src/test/ui/parser/recover-from-homoglyph.stderr new file mode 100644 index 0000000000..424d492b7b --- /dev/null +++ b/src/test/ui/parser/recover-from-homoglyph.stderr @@ -0,0 +1,22 @@ +error: unknown start of token: \u{37e} + --> $DIR/recover-from-homoglyph.rs:2:17 + | +LL | println!(""); + | ^ +help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not + | +LL | println!(""); + | ^ + +error[E0308]: mismatched types + --> $DIR/recover-from-homoglyph.rs:3:20 + | +LL | let x: usize = (); + | ^^ expected usize, found () + | + = note: expected type `usize` + found type `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs new file mode 100644 index 0000000000..260e108315 --- /dev/null +++ b/src/test/ui/parser/recover-range-pats.rs @@ -0,0 +1,151 @@ +// Here we test all kinds of range patterns in terms of parsing / recovery. +// We want to ensure that: +// 1. Things parse as they should. +// 2. Or at least we have parser recovery if they don't. + +#![feature(exclusive_range_pattern)] +#![deny(ellipsis_inclusive_range_patterns)] + +fn main() {} + +const X: u8 = 0; +const Y: u8 = 3; + +fn exclusive_from_to() { + if let 0..3 = 0 {} // OK. + if let 0..Y = 0 {} // OK. + if let X..3 = 0 {} // OK. + if let X..Y = 0 {} // OK. + if let true..Y = 0 {} //~ ERROR only char and numeric types + if let X..true = 0 {} //~ ERROR only char and numeric types + if let .0..Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + if let X.. .0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part +} + +fn inclusive_from_to() { + if let 0..=3 = 0 {} // OK. + if let 0..=Y = 0 {} // OK. + if let X..=3 = 0 {} // OK. + if let X..=Y = 0 {} // OK. + if let true..=Y = 0 {} //~ ERROR only char and numeric types + if let X..=true = 0 {} //~ ERROR only char and numeric types + if let .0..=Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + if let X..=.0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part +} + +fn inclusive2_from_to() { + if let 0...3 = 0 {} //~ ERROR `...` range patterns are deprecated + if let 0...Y = 0 {} //~ ERROR `...` range patterns are deprecated + if let X...3 = 0 {} //~ ERROR `...` range patterns are deprecated + if let X...Y = 0 {} //~ ERROR `...` range patterns are deprecated + if let true...Y = 0 {} //~ ERROR only char and numeric types + //~^ ERROR `...` range patterns are deprecated + if let X...true = 0 {} //~ ERROR only char and numeric types + //~^ ERROR `...` range patterns are deprecated + if let .0...Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated + if let X... .0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated +} + +fn exclusive_from() { + if let 0.. = 0 {} //~ ERROR `X..` range patterns are not supported + if let X.. = 0 {} //~ ERROR `X..` range patterns are not supported + if let true.. = 0 {} //~ ERROR `X..` range patterns are not supported + //~^ ERROR only char and numeric types + if let .0.. = 0 {} //~ ERROR `X..` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive_from() { + if let 0..= = 0 {} //~ ERROR `X..=` range patterns are not supported + if let X..= = 0 {} //~ ERROR `X..=` range patterns are not supported + if let true..= = 0 {} //~ ERROR `X..=` range patterns are not supported + //~| ERROR only char and numeric types + if let .0..= = 0 {} //~ ERROR `X..=` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive2_from() { + if let 0... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let X... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let true... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + //~| ERROR only char and numeric types + if let .0... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated + //~| ERROR mismatched types +} + +fn exclusive_to() { + if let ..0 = 0 {} //~ ERROR `..X` range patterns are not supported + if let ..Y = 0 {} //~ ERROR `..X` range patterns are not supported + if let ..true = 0 {} //~ ERROR `..X` range patterns are not supported + //~| ERROR only char and numeric types + if let .. .0 = 0 {} //~ ERROR `..X` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive_to() { + if let ..=3 = 0 {} //~ ERROR `..=X` range patterns are not supported + if let ..=Y = 0 {} //~ ERROR `..=X` range patterns are not supported + if let ..=true = 0 {} //~ ERROR `..=X` range patterns are not supported + //~| ERROR only char and numeric types + if let ..=.0 = 0 {} //~ ERROR `..=X` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types +} + +fn inclusive2_to() { + if let ...3 = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let ...Y = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let ...true = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + //~| ERROR only char and numeric types + if let ....3 = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated + //~| ERROR mismatched types +} + +fn with_macro_expr_var() { + macro_rules! mac2 { + ($e1:expr, $e2:expr) => { + let $e1..$e2; + let $e1...$e2; + //~^ ERROR `...` range patterns are deprecated + let $e1..=$e2; + } + } + + mac2!(0, 1); + + macro_rules! mac { + ($e:expr) => { + let ..$e; //~ ERROR `..X` range patterns are not supported + let ...$e; //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + let ..=$e; //~ ERROR `..=X` range patterns are not supported + let $e..; //~ ERROR `X..` range patterns are not supported + let $e...; //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + let $e..=; //~ ERROR `X..=` range patterns are not supported + } + } + + mac!(0); +} diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr new file mode 100644 index 0000000000..89ec059cb8 --- /dev/null +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -0,0 +1,619 @@ +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:21:12 + | +LL | if let .0..Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:23:16 + | +LL | if let X.. .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:34:12 + | +LL | if let .0..=Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:36:16 + | +LL | if let X..=.0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:49:12 + | +LL | if let .0...Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:52:17 + | +LL | if let X... .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:58:12 + | +LL | if let 0.. = 0 {} + | ^^^ help: try using the maximum value for the type: `0..MAX` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:59:12 + | +LL | if let X.. = 0 {} + | ^^^ help: try using the maximum value for the type: `X..MAX` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:60:12 + | +LL | if let true.. = 0 {} + | ^^^^^^ help: try using the maximum value for the type: `true..MAX` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:62:12 + | +LL | if let .0.. = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:62:12 + | +LL | if let .0.. = 0 {} + | ^^^^ help: try using the maximum value for the type: `0.0..MAX` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:68:12 + | +LL | if let 0..= = 0 {} + | ^^^^ help: try using the maximum value for the type: `0..=MAX` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:69:12 + | +LL | if let X..= = 0 {} + | ^^^^ help: try using the maximum value for the type: `X..=MAX` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:70:12 + | +LL | if let true..= = 0 {} + | ^^^^^^^ help: try using the maximum value for the type: `true..=MAX` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:72:12 + | +LL | if let .0..= = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:72:12 + | +LL | if let .0..= = 0 {} + | ^^^^^ help: try using the maximum value for the type: `0.0..=MAX` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:78:12 + | +LL | if let 0... = 0 {} + | ^^^^ help: try using the maximum value for the type: `0...MAX` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:80:12 + | +LL | if let X... = 0 {} + | ^^^^ help: try using the maximum value for the type: `X...MAX` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:82:12 + | +LL | if let true... = 0 {} + | ^^^^^^^ help: try using the maximum value for the type: `true...MAX` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:85:12 + | +LL | if let .0... = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:85:12 + | +LL | if let .0... = 0 {} + | ^^^^^ help: try using the maximum value for the type: `0.0...MAX` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:92:12 + | +LL | if let ..0 = 0 {} + | ^^^ help: try using the minimum value for the type: `MIN..0` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:93:12 + | +LL | if let ..Y = 0 {} + | ^^^ help: try using the minimum value for the type: `MIN..Y` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:94:12 + | +LL | if let ..true = 0 {} + | ^^^^^^ help: try using the minimum value for the type: `MIN..true` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:96:15 + | +LL | if let .. .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:96:12 + | +LL | if let .. .0 = 0 {} + | ^^^^^ help: try using the minimum value for the type: `MIN..0.0` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:102:12 + | +LL | if let ..=3 = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN..=3` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:103:12 + | +LL | if let ..=Y = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN..=Y` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:104:12 + | +LL | if let ..=true = 0 {} + | ^^^^^^^ help: try using the minimum value for the type: `MIN..=true` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:106:15 + | +LL | if let ..=.0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:106:12 + | +LL | if let ..=.0 = 0 {} + | ^^^^^ help: try using the minimum value for the type: `MIN..=0.0` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:112:12 + | +LL | if let ...3 = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN...3` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:114:12 + | +LL | if let ...Y = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN...Y` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:116:12 + | +LL | if let ...true = 0 {} + | ^^^^^^^ help: try using the minimum value for the type: `MIN...true` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:119:15 + | +LL | if let ....3 = 0 {} + | ^^ help: must have an integer part: `0.3` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:119:12 + | +LL | if let ....3 = 0 {} + | ^^^^^ help: try using the minimum value for the type: `MIN...0.3` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:139:17 + | +LL | let ..$e; + | ^^ help: try using the minimum value for the type: `MIN..0` +... +LL | mac!(0); + | -------- in this macro invocation + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:140:17 + | +LL | let ...$e; + | ^^^ help: try using the minimum value for the type: `MIN...0` +... +LL | mac!(0); + | -------- in this macro invocation + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:142:17 + | +LL | let ..=$e; + | ^^^ help: try using the minimum value for the type: `MIN..=0` +... +LL | mac!(0); + | -------- in this macro invocation + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:143:19 + | +LL | let $e..; + | ^^ help: try using the maximum value for the type: `0..MAX` +... +LL | mac!(0); + | -------- in this macro invocation + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:144:19 + | +LL | let $e...; + | ^^^ help: try using the maximum value for the type: `0...MAX` +... +LL | mac!(0); + | -------- in this macro invocation + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:146:19 + | +LL | let $e..=; + | ^^^ help: try using the maximum value for the type: `0..=MAX` +... +LL | mac!(0); + | -------- in this macro invocation + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:41:13 + | +LL | if let 0...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + | +note: lint level defined here + --> $DIR/recover-range-pats.rs:7:9 + | +LL | #![deny(ellipsis_inclusive_range_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:42:13 + | +LL | if let 0...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:43:13 + | +LL | if let X...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:44:13 + | +LL | if let X...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:45:16 + | +LL | if let true...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:47:13 + | +LL | if let X...true = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:49:14 + | +LL | if let .0...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:52:13 + | +LL | if let X... .0 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:78:13 + | +LL | if let 0... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:80:13 + | +LL | if let X... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:82:16 + | +LL | if let true... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:85:14 + | +LL | if let .0... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:112:12 + | +LL | if let ...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:114:12 + | +LL | if let ...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:116:12 + | +LL | if let ...true = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:119:12 + | +LL | if let ....3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:129:20 + | +LL | let $e1...$e2; + | ^^^ help: use `..=` for an inclusive range +... +LL | mac2!(0, 1); + | ------------ in this macro invocation + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:140:17 + | +LL | let ...$e; + | ^^^ help: use `..=` for an inclusive range +... +LL | mac!(0); + | -------- in this macro invocation + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:144:19 + | +LL | let $e...; + | ^^^ help: use `..=` for an inclusive range +... +LL | mac!(0); + | -------- in this macro invocation + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:19:12 + | +LL | if let true..Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:20:15 + | +LL | if let X..true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:21:12 + | +LL | if let .0..Y = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:23:12 + | +LL | if let X.. .0 = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:32:12 + | +LL | if let true..=Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:33:16 + | +LL | if let X..=true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:34:12 + | +LL | if let .0..=Y = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:36:12 + | +LL | if let X..=.0 = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:45:12 + | +LL | if let true...Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:47:16 + | +LL | if let X...true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:49:12 + | +LL | if let .0...Y = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:52:12 + | +LL | if let X... .0 = 0 {} + | ^^^^^^^ expected integer, found floating-point number + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:60:12 + | +LL | if let true.. = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: [type error] + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:62:12 + | +LL | if let .0.. = 0 {} + | ^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:70:12 + | +LL | if let true..= = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: [type error] + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:72:12 + | +LL | if let .0..= = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:82:12 + | +LL | if let true... = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: [type error] + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:85:12 + | +LL | if let .0... = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:94:14 + | +LL | if let ..true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:96:12 + | +LL | if let .. .0 = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:104:15 + | +LL | if let ..=true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:106:12 + | +LL | if let ..=.0 = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:116:15 + | +LL | if let ...true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:119:12 + | +LL | if let ....3 = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error: aborting due to 85 previous errors + +Some errors have detailed explanations: E0029, E0308. +For more information about an error, try `rustc --explain E0029`. diff --git a/src/test/ui/parser/recover-tuple-pat.rs b/src/test/ui/parser/recover-tuple-pat.rs index 488e8db6b8..7fded752d6 100644 --- a/src/test/ui/parser/recover-tuple-pat.rs +++ b/src/test/ui/parser/recover-tuple-pat.rs @@ -1,12 +1,12 @@ +// NOTE: This doesn't recover anymore. + fn main() { let x = (1, 2, 3, 4); match x { (1, .., 4) => {} (1, .=., 4) => { let _: usize = ""; } //~^ ERROR expected pattern, found `.` - //~| ERROR mismatched types (.=., 4) => {} - //~^ ERROR expected pattern, found `.` (1, 2, 3, 4) => {} } } diff --git a/src/test/ui/parser/recover-tuple-pat.stderr b/src/test/ui/parser/recover-tuple-pat.stderr index 5919aa7235..93a6a66a63 100644 --- a/src/test/ui/parser/recover-tuple-pat.stderr +++ b/src/test/ui/parser/recover-tuple-pat.stderr @@ -1,24 +1,8 @@ error: expected pattern, found `.` - --> $DIR/recover-tuple-pat.rs:5:13 + --> $DIR/recover-tuple-pat.rs:7:13 | LL | (1, .=., 4) => { let _: usize = ""; } | ^ expected pattern -error: expected pattern, found `.` - --> $DIR/recover-tuple-pat.rs:8:10 - | -LL | (.=., 4) => {} - | ^ expected pattern - -error[E0308]: mismatched types - --> $DIR/recover-tuple-pat.rs:5:41 - | -LL | (1, .=., 4) => { let _: usize = ""; } - | ^^ expected usize, found reference - | - = note: expected type `usize` - found type `&'static str` - -error: aborting due to 3 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr index a759716b5a..02b518e251 100644 --- a/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr +++ b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr @@ -2,7 +2,7 @@ error: expected type, found keyword `mut` --> $DIR/removed-syntax-mut-vec-ty.rs:1:11 | LL | type v = [mut isize]; - | ^^^ + | ^^^ expected type error: aborting due to previous error diff --git a/src/test/ui/parser/removed-syntax-record.stderr b/src/test/ui/parser/removed-syntax-record.stderr index 730d5e2712..0a1655840b 100644 --- a/src/test/ui/parser/removed-syntax-record.stderr +++ b/src/test/ui/parser/removed-syntax-record.stderr @@ -2,7 +2,7 @@ error: expected type, found `{` --> $DIR/removed-syntax-record.rs:1:10 | LL | type t = { f: () }; - | ^ + | ^ expected type error: aborting due to previous error diff --git a/src/test/ui/parser/removed-syntax-static-fn.rs b/src/test/ui/parser/removed-syntax-static-fn.rs index df3964196b..0caddb9855 100644 --- a/src/test/ui/parser/removed-syntax-static-fn.rs +++ b/src/test/ui/parser/removed-syntax-static-fn.rs @@ -1,10 +1,8 @@ -// ignore-tidy-linelength - struct S; impl S { static fn f() {} + //~^ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, } -//~^^ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, fn main() {} diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr index 84e0432c48..21cb71df65 100644 --- a/src/test/ui/parser/removed-syntax-static-fn.stderr +++ b/src/test/ui/parser/removed-syntax-static-fn.stderr @@ -1,8 +1,8 @@ -error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `static` - --> $DIR/removed-syntax-static-fn.rs:6:5 +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `static` + --> $DIR/removed-syntax-static-fn.rs:4:5 | LL | impl S { - | - expected one of 11 possible tokens here + | - expected one of 10 possible tokens here LL | static fn f() {} | ^^^^^^ unexpected token diff --git a/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs b/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs new file mode 100644 index 0000000000..ee14c55d29 --- /dev/null +++ b/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs @@ -0,0 +1,10 @@ +// Issue #62863 +// ignore-tidy-cr + +// Note: if you see ^M in this file, that's how your editor renders literal `\r` + +/// This do c comment contains three isolated `\r` symbols +//~^ ERROR bare CR not allowed in doc-comment +//~| ERROR bare CR not allowed in doc-comment +//~| ERROR bare CR not allowed in doc-comment +fn main() {} diff --git a/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr b/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr new file mode 100644 index 0000000000..07066fc22e --- /dev/null +++ b/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr @@ -0,0 +1,20 @@ +error: bare CR not allowed in doc-comment + --> $DIR/several-carriage-returns-in-doc-comment.rs:6:12 + | +LL | /// This do c comment contains three isolated `\r` symbols + | ^ + +error: bare CR not allowed in doc-comment + --> $DIR/several-carriage-returns-in-doc-comment.rs:6:32 + | +LL | /// This do c comment contains three isolated `\r` symbols + | ^ + +error: bare CR not allowed in doc-comment + --> $DIR/several-carriage-returns-in-doc-comment.rs:6:52 + | +LL | /// This do c comment contains three isolated `\r` symbols + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr index 13b46c6e8b..70acc70e09 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr @@ -18,7 +18,7 @@ LL | Other2(usize, usize), | -------------------- tuple variant defined here | = note: for more information, see https://github.com/rust-lang/rust/issues/60553 - = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/parser/trailing-plus-in-bounds.rs b/src/test/ui/parser/trailing-plus-in-bounds.rs index 3213e06805..33c30d7310 100644 --- a/src/test/ui/parser/trailing-plus-in-bounds.rs +++ b/src/test/ui/parser/trailing-plus-in-bounds.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_syntax)] #![allow(bare_trait_objects)] diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr index a31b7aea8f..7ffc26e9ed 100644 --- a/src/test/ui/parser/trait-object-lifetime-parens.stderr +++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr @@ -29,7 +29,7 @@ error: expected type, found `'a` --> $DIR/trait-object-lifetime-parens.rs:9:17 | LL | let _: Box<('a) + Trait>; - | - ^^ + | - ^^ expected type | | | while parsing the type for `_` diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr index e3fb8a0113..03fb764ee0 100644 --- a/src/test/ui/parser/trait-object-trait-parens.stderr +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -16,7 +16,7 @@ warning: trait objects without an explicit `dyn` are deprecated LL | let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Copy) + (?Sized) + (for<'a> Trait<'a>)` | - = note: #[warn(bare_trait_objects)] on by default + = note: `#[warn(bare_trait_objects)]` on by default warning: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:9:16 diff --git a/src/test/ui/parser/trait-plusequal-splitting.rs b/src/test/ui/parser/trait-plusequal-splitting.rs index c655a15d26..26ac3ead6a 100644 --- a/src/test/ui/parser/trait-plusequal-splitting.rs +++ b/src/test/ui/parser/trait-plusequal-splitting.rs @@ -1,6 +1,6 @@ // Fixes issue where `+` in generics weren't parsed if they were part of a `+=`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Whitespace { t: T } struct TokenSplit { t: T } diff --git a/src/test/ui/parser/underscore-suffix-for-string.rs b/src/test/ui/parser/underscore-suffix-for-string.rs index bcd0b24c75..dd0599b4ab 100644 --- a/src/test/ui/parser/underscore-suffix-for-string.rs +++ b/src/test/ui/parser/underscore-suffix-for-string.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _ = "Foo"_; diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs index 69644211b8..1812dad81a 100644 --- a/src/test/ui/parser/unicode-quote-chars.rs +++ b/src/test/ui/parser/unicode-quote-chars.rs @@ -4,4 +4,7 @@ fn main() { println!(“hello world”); //~^ ERROR unknown start of token: \u{201c} //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not + //~^^^ ERROR unknown start of token: \u{201d} + //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not + //~^^^^^ ERROR expected token: `,` } diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr index 4a09ed7560..84e45ecd87 100644 --- a/src/test/ui/parser/unicode-quote-chars.stderr +++ b/src/test/ui/parser/unicode-quote-chars.stderr @@ -8,5 +8,21 @@ help: Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Dou LL | println!("hello world"); | ^^^^^^^^^^^^^ -error: aborting due to previous error +error: unknown start of token: \u{201d} + --> $DIR/unicode-quote-chars.rs:4:26 + | +LL | println!(“hello world”); + | ^ +help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not + | +LL | println!(“hello world"); + | ^ + +error: expected token: `,` + --> $DIR/unicode-quote-chars.rs:4:21 + | +LL | println!(“hello world”); + | ^^^^^ expected `,` + +error: aborting due to 3 previous errors diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr index 50593e4523..197848e428 100644 --- a/src/test/ui/path-lookahead.stderr +++ b/src/test/ui/path-lookahead.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unused_parens)] implied by #[warn(unused)] + = note: `#[warn(unused_parens)]` implied by `#[warn(unused)]` warning: function is never used: `with_parens` --> $DIR/path-lookahead.rs:7:1 @@ -22,7 +22,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(dead_code)] implied by #[warn(unused)] + = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` warning: function is never used: `no_parens` --> $DIR/path-lookahead.rs:11:1 diff --git a/src/test/run-pass/path.rs b/src/test/ui/path.rs similarity index 90% rename from src/test/run-pass/path.rs rename to src/test/ui/path.rs index 7a9b04c070..4c137de82d 100644 --- a/src/test/run-pass/path.rs +++ b/src/test/ui/path.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 mod foo { diff --git a/src/test/run-pass/paths-containing-nul.rs b/src/test/ui/paths-containing-nul.rs similarity index 99% rename from src/test/run-pass/paths-containing-nul.rs rename to src/test/ui/paths-containing-nul.rs index 64ee7319fd..c9bf710b8e 100644 --- a/src/test/run-pass/paths-containing-nul.rs +++ b/src/test/ui/paths-containing-nul.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(deprecated)] // ignore-cloudabi no files or I/O // ignore-wasm32-bare no files or I/O diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs new file mode 100644 index 0000000000..36a45a3ccd --- /dev/null +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -0,0 +1,82 @@ +// Here we test that rest patterns, i.e. `..`, are not allowed +// outside of slice (+ ident patterns witin those), tuple, +// and tuple struct patterns and that duplicates are caught in these contexts. + +#![feature(slice_patterns, box_patterns)] + +fn main() {} + +macro_rules! mk_pat { + () => { .. } //~ ERROR `..` patterns are not allowed here +} + +fn rest_patterns() { + let mk_pat!(); + + // Top level: + fn foo(..: u8) {} //~ ERROR `..` patterns are not allowed here + let ..; //~ ERROR `..` patterns are not allowed here + + // Box patterns: + let box ..; //~ ERROR `..` patterns are not allowed here + + // In or-patterns: + match 1 { + 1 | .. => {} //~ ERROR `..` patterns are not allowed here + } + + // Ref patterns: + let &..; //~ ERROR `..` patterns are not allowed here + let &mut ..; //~ ERROR `..` patterns are not allowed here + + // Ident patterns: + let x @ ..; //~ ERROR `..` patterns are not allowed here + let ref x @ ..; //~ ERROR `..` patterns are not allowed here + let ref mut x @ ..; //~ ERROR `..` patterns are not allowed here + + // Tuple: + let (..): (u8,); // OK. + let (..,): (u8,); // OK. + let ( + .., + .., //~ ERROR `..` can only be used once per tuple pattern + .. //~ ERROR `..` can only be used once per tuple pattern + ): (u8, u8, u8); + let ( + .., + x, + .. //~ ERROR `..` can only be used once per tuple pattern + ): (u8, u8, u8); + + struct A(u8, u8, u8); + + // Tuple struct (same idea as for tuple patterns): + let A(..); // OK. + let A(..,); // OK. + let A( + .., + .., //~ ERROR `..` can only be used once per tuple struct pattern + .. //~ ERROR `..` can only be used once per tuple struct pattern + ); + let A( + .., + x, + .. //~ ERROR `..` can only be used once per tuple struct pattern + ); + + // Array/Slice: + let [..]: &[u8]; // OK. + let [..,]: &[u8]; // OK. + let [ + .., + .., //~ ERROR `..` can only be used once per slice pattern + .. //~ ERROR `..` can only be used once per slice pattern + ]: &[u8]; + let [ + .., + ref x @ .., //~ ERROR `..` can only be used once per slice pattern + ref mut y @ .., //~ ERROR `..` can only be used once per slice pattern + (ref z @ ..), //~ ERROR `..` patterns are not allowed here + .. //~ ERROR `..` can only be used once per slice pattern + ]: &[u8]; +} diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr new file mode 100644 index 0000000000..826f76b356 --- /dev/null +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -0,0 +1,188 @@ +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:10:13 + | +LL | () => { .. } + | ^^ +... +LL | let mk_pat!(); + | --------- in this macro invocation + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:18:9 + | +LL | let ..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:21:13 + | +LL | let box ..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:25:13 + | +LL | 1 | .. => {} + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:29:10 + | +LL | let &..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:30:14 + | +LL | let &mut ..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:33:13 + | +LL | let x @ ..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:34:17 + | +LL | let ref x @ ..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:35:21 + | +LL | let ref mut x @ ..; + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` can only be used once per tuple pattern + --> $DIR/rest-pat-semantic-disallowed.rs:42:9 + | +LL | .., + | -- previously used here +LL | .., + | ^^ can only be used once per tuple pattern + +error: `..` can only be used once per tuple pattern + --> $DIR/rest-pat-semantic-disallowed.rs:43:9 + | +LL | .., + | -- previously used here +LL | .., +LL | .. + | ^^ can only be used once per tuple pattern + +error: `..` can only be used once per tuple pattern + --> $DIR/rest-pat-semantic-disallowed.rs:48:9 + | +LL | .., + | -- previously used here +LL | x, +LL | .. + | ^^ can only be used once per tuple pattern + +error: `..` can only be used once per tuple struct pattern + --> $DIR/rest-pat-semantic-disallowed.rs:58:9 + | +LL | .., + | -- previously used here +LL | .., + | ^^ can only be used once per tuple struct pattern + +error: `..` can only be used once per tuple struct pattern + --> $DIR/rest-pat-semantic-disallowed.rs:59:9 + | +LL | .., + | -- previously used here +LL | .., +LL | .. + | ^^ can only be used once per tuple struct pattern + +error: `..` can only be used once per tuple struct pattern + --> $DIR/rest-pat-semantic-disallowed.rs:64:9 + | +LL | .., + | -- previously used here +LL | x, +LL | .. + | ^^ can only be used once per tuple struct pattern + +error: `..` can only be used once per slice pattern + --> $DIR/rest-pat-semantic-disallowed.rs:72:9 + | +LL | .., + | -- previously used here +LL | .., + | ^^ can only be used once per slice pattern + +error: `..` can only be used once per slice pattern + --> $DIR/rest-pat-semantic-disallowed.rs:73:9 + | +LL | .., + | -- previously used here +LL | .., +LL | .. + | ^^ can only be used once per slice pattern + +error: `..` can only be used once per slice pattern + --> $DIR/rest-pat-semantic-disallowed.rs:77:17 + | +LL | .., + | -- previously used here +LL | ref x @ .., + | ^^ can only be used once per slice pattern + +error: `..` can only be used once per slice pattern + --> $DIR/rest-pat-semantic-disallowed.rs:78:21 + | +LL | .., + | -- previously used here +LL | ref x @ .., +LL | ref mut y @ .., + | ^^ can only be used once per slice pattern + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:79:18 + | +LL | (ref z @ ..), + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: `..` can only be used once per slice pattern + --> $DIR/rest-pat-semantic-disallowed.rs:80:9 + | +LL | .., + | -- previously used here +... +LL | .. + | ^^ can only be used once per slice pattern + +error: `..` patterns are not allowed here + --> $DIR/rest-pat-semantic-disallowed.rs:17:12 + | +LL | fn foo(..: u8) {} + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error: aborting due to 22 previous errors + diff --git a/src/test/ui/pattern/rest-pat-syntactic.rs b/src/test/ui/pattern/rest-pat-syntactic.rs new file mode 100644 index 0000000000..9656a0b5de --- /dev/null +++ b/src/test/ui/pattern/rest-pat-syntactic.rs @@ -0,0 +1,70 @@ +// Here we test that `..` is allowed in all pattern locations *syntactically*. +// The semantic test is in `rest-pat-semantic-disallowed.rs`. + +// check-pass + +fn main() {} + +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!(..); + +#[cfg(FALSE)] +fn rest_patterns() { + // Top level: + fn foo(..: u8) {} + let ..; + + // Box patterns: + let box ..; + + // In or-patterns: + match x { + .. | .. => {} + } + + // Ref patterns: + let &..; + let &mut ..; + + // Ident patterns: + let x @ ..; + let ref x @ ..; + let ref mut x @ ..; + + // Tuple: + let (..); // This is interpreted as a tuple pattern, not a parenthesis one. + let (..,); // Allowing trailing comma. + let (.., .., ..); // Duplicates also. + let (.., P, ..); // Including with things in between. + + // Tuple struct (same idea as for tuple patterns): + let A(..); + let A(..,); + let A(.., .., ..); + let A(.., P, ..); + + // Array/Slice (like with tuple patterns): + let [..]; + let [..,]; + let [.., .., ..]; + let [.., P, ..]; + + // Random walk to guard against special casing: + match x { + .. | + [ + ( + box .., + &(..), + &mut .., + x @ .. + ), + ref x @ .., + ] | + ref mut x @ .. + => {} + } +} diff --git a/src/test/ui/precise_pointer_size_matching.stderr b/src/test/ui/precise_pointer_size_matching.stderr index 6f0322fd9b..2c2c2aa04c 100644 --- a/src/test/ui/precise_pointer_size_matching.stderr +++ b/src/test/ui/precise_pointer_size_matching.stderr @@ -1,16 +1,16 @@ -error[E0004]: non-exhaustive patterns: `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered +error[E0004]: non-exhaustive patterns: `std::isize::MIN..=-6isize` and `21isize..=std::isize::MAX` not covered --> $DIR/precise_pointer_size_matching.rs:24:11 | LL | match 0isize { - | ^^^^^^ patterns `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered + | ^^^^^^ patterns `std::isize::MIN..=-6isize` and `21isize..=std::isize::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=$USIZE_MAX` not covered +error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=std::usize::MAX` not covered --> $DIR/precise_pointer_size_matching.rs:29:11 | LL | match 0usize { - | ^^^^^^ patterns `0usize` and `21usize..=$USIZE_MAX` not covered + | ^^^^^^ patterns `0usize` and `21usize..=std::usize::MAX` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/print-fuel/print-fuel.rs b/src/test/ui/print-fuel/print-fuel.rs index 1bd3924266..e443469544 100644 --- a/src/test/ui/print-fuel/print-fuel.rs +++ b/src/test/ui/print-fuel/print-fuel.rs @@ -3,7 +3,7 @@ // (#55495: The --error-format is to sidestep an issue in our test harness) // compile-flags: --error-format human -Z print-fuel=foo -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S1(u8, u16, u8); struct S2(u8, u16, u8); diff --git a/src/test/run-pass/print-stdout-eprint-stderr.rs b/src/test/ui/print-stdout-eprint-stderr.rs similarity index 98% rename from src/test/run-pass/print-stdout-eprint-stderr.rs rename to src/test/ui/print-stdout-eprint-stderr.rs index 65130a1a9f..70c083e080 100644 --- a/src/test/run-pass/print-stdout-eprint-stderr.rs +++ b/src/test/ui/print-stdout-eprint-stderr.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported // ignore-sgx no processes diff --git a/src/test/ui/print_type_sizes/anonymous.rs b/src/test/ui/print_type_sizes/anonymous.rs index 4d2a0e27fd..b96348640f 100644 --- a/src/test/ui/print_type_sizes/anonymous.rs +++ b/src/test/ui/print_type_sizes/anonymous.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // All of the types that occur in this function are uninteresting, in // that one cannot control the sizes of these types with the same sort diff --git a/src/test/ui/print_type_sizes/generics.rs b/src/test/ui/print_type_sizes/generics.rs index ecfc03717d..f165526dff 100644 --- a/src/test/ui/print_type_sizes/generics.rs +++ b/src/test/ui/print_type_sizes/generics.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/multiple_types.rs b/src/test/ui/print_type_sizes/multiple_types.rs index 1b1d817420..4cb7ae03b5 100644 --- a/src/test/ui/print_type_sizes/multiple_types.rs +++ b/src/test/ui/print_type_sizes/multiple_types.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file illustrates that when multiple structural types occur in // a function, every one of them is included in the output. diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 98b506b1f0..d9845fd6d7 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/no_duplicates.rs b/src/test/ui/print_type_sizes/no_duplicates.rs index f1b8a28ae3..4495a7770a 100644 --- a/src/test/ui/print_type_sizes/no_duplicates.rs +++ b/src/test/ui/print_type_sizes/no_duplicates.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/packed.rs b/src/test/ui/print_type_sizes/packed.rs index a8d409a91a..dce4a61ef3 100644 --- a/src/test/ui/print_type_sizes/packed.rs +++ b/src/test/ui/print_type_sizes/packed.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/padding.rs b/src/test/ui/print_type_sizes/padding.rs index c6d927cb1e..1f894c5e25 100644 --- a/src/test/ui/print_type_sizes/padding.rs +++ b/src/test/ui/print_type_sizes/padding.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file illustrates how padding is handled: alignment // requirements can lead to the introduction of padding, either before diff --git a/src/test/ui/print_type_sizes/repr-align.rs b/src/test/ui/print_type_sizes/repr-align.rs index 3b5248b6f7..1e6f7ccca4 100644 --- a/src/test/ui/print_type_sizes/repr-align.rs +++ b/src/test/ui/print_type_sizes/repr-align.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/repr_int_c.rs b/src/test/ui/print_type_sizes/repr_int_c.rs index 6816bb71a0..7aad2715bc 100644 --- a/src/test/ui/print_type_sizes/repr_int_c.rs +++ b/src/test/ui/print_type_sizes/repr_int_c.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-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). diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index c33965c4f5..ae4e492456 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/variants.rs b/src/test/ui/print_type_sizes/variants.rs index aa2d25a392..77e2b4befb 100644 --- a/src/test/ui/print_type_sizes/variants.rs +++ b/src/test/ui/print_type_sizes/variants.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file illustrates two things: // diff --git a/src/test/run-pass/privacy/auxiliary/priv-impl-prim-ty.rs b/src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs similarity index 100% rename from src/test/run-pass/privacy/auxiliary/priv-impl-prim-ty.rs rename to src/test/ui/privacy/auxiliary/priv-impl-prim-ty.rs diff --git a/src/test/run-pass/privacy/auxiliary/privacy_reexport.rs b/src/test/ui/privacy/auxiliary/privacy_reexport.rs similarity index 100% rename from src/test/run-pass/privacy/auxiliary/privacy_reexport.rs rename to src/test/ui/privacy/auxiliary/privacy_reexport.rs diff --git a/src/test/run-pass/privacy/auxiliary/pub_use_mods_xcrate.rs b/src/test/ui/privacy/auxiliary/pub_use_mods_xcrate.rs similarity index 100% rename from src/test/run-pass/privacy/auxiliary/pub_use_mods_xcrate.rs rename to src/test/ui/privacy/auxiliary/pub_use_mods_xcrate.rs diff --git a/src/test/run-pass/privacy/auxiliary/pub_use_xcrate1.rs b/src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs similarity index 100% rename from src/test/run-pass/privacy/auxiliary/pub_use_xcrate1.rs rename to src/test/ui/privacy/auxiliary/pub_use_xcrate1.rs diff --git a/src/test/run-pass/privacy/auxiliary/pub_use_xcrate2.rs b/src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs similarity index 100% rename from src/test/run-pass/privacy/auxiliary/pub_use_xcrate2.rs rename to src/test/ui/privacy/auxiliary/pub_use_xcrate2.rs diff --git a/src/test/ui/privacy/issue-57264-1.rs b/src/test/ui/privacy/issue-57264-1.rs index dcffdc3d4e..5ef6a61fea 100644 --- a/src/test/ui/privacy/issue-57264-1.rs +++ b/src/test/ui/privacy/issue-57264-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:issue-57264-1.rs extern crate issue_57264_1; diff --git a/src/test/ui/privacy/issue-57264-2.rs b/src/test/ui/privacy/issue-57264-2.rs index 79d0d2c7cd..4d5c9cfa1d 100644 --- a/src/test/ui/privacy/issue-57264-2.rs +++ b/src/test/ui/privacy/issue-57264-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:issue-57264-2.rs extern crate issue_57264_2; diff --git a/src/test/ui/privacy/legacy-ctor-visibility.stderr b/src/test/ui/privacy/legacy-ctor-visibility.stderr index f0590951c0..69b6e08bef 100644 --- a/src/test/ui/privacy/legacy-ctor-visibility.stderr +++ b/src/test/ui/privacy/legacy-ctor-visibility.stderr @@ -4,7 +4,7 @@ error: private struct constructors are not usable through re-exports in outer mo LL | S(10); | ^ | - = note: #[deny(legacy_constructor_visibility)] on by default + = note: `#[deny(legacy_constructor_visibility)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #39207 diff --git a/src/test/run-pass/privacy/priv-impl-prim-ty.rs b/src/test/ui/privacy/priv-impl-prim-ty.rs similarity index 100% rename from src/test/run-pass/privacy/priv-impl-prim-ty.rs rename to src/test/ui/privacy/priv-impl-prim-ty.rs diff --git a/src/test/run-pass/privacy/privacy-ns.rs b/src/test/ui/privacy/privacy-ns.rs similarity index 100% rename from src/test/run-pass/privacy/privacy-ns.rs rename to src/test/ui/privacy/privacy-ns.rs diff --git a/src/test/run-pass/privacy/privacy-reexport.rs b/src/test/ui/privacy/privacy-reexport.rs similarity index 100% rename from src/test/run-pass/privacy/privacy-reexport.rs rename to src/test/ui/privacy/privacy-reexport.rs diff --git a/src/test/run-pass/privacy/privacy1.rs b/src/test/ui/privacy/privacy1-rpass.rs similarity index 100% rename from src/test/run-pass/privacy/privacy1.rs rename to src/test/ui/privacy/privacy1-rpass.rs diff --git a/src/test/ui/privacy/privacy5.stderr b/src/test/ui/privacy/privacy5.stderr index 7568c346b2..532d1ac1e2 100644 --- a/src/test/ui/privacy/privacy5.stderr +++ b/src/test/ui/privacy/privacy5.stderr @@ -3,288 +3,384 @@ error[E0603]: tuple struct `A` is private | LL | let a = a::A(()); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:52:16 | LL | let b = a::B(2); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:53:16 | LL | let c = a::C(2, 3); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:56:12 | LL | let a::A(()) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:57:12 | LL | let a::A(_) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:58:18 | LL | match a { a::A(()) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:59:18 | LL | match a { a::A(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:61:12 | LL | let a::B(_) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:62:12 | LL | let a::B(_b) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:63:18 | LL | match b { a::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:64:18 | LL | match b { a::B(_b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:65:18 | LL | match b { a::B(1) => {} a::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:65:32 | LL | match b { a::B(1) => {} a::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:68:12 | LL | let a::C(_, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:69:12 | LL | let a::C(_a, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:70:12 | LL | let a::C(_, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:71:12 | LL | let a::C(_a, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:72:18 | LL | match c { a::C(_, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:73:18 | LL | match c { a::C(_a, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:74:18 | LL | match c { a::C(_, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:75:18 | LL | match c { a::C(_a, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:83:17 | LL | let a2 = a::A; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:84:17 | LL | let b2 = a::B; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:85:17 | LL | let c2 = a::C; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:90:20 | LL | let a = other::A(()); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:91:20 | LL | let b = other::B(2); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:92:20 | LL | let c = other::C(2, 3); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:95:16 | LL | let other::A(()) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:96:16 | LL | let other::A(_) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:97:22 | LL | match a { other::A(()) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:98:22 | LL | match a { other::A(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:100:16 | LL | let other::B(_) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:101:16 | LL | let other::B(_b) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:102:22 | LL | match b { other::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:103:22 | LL | match b { other::B(_b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:104:22 | LL | match b { other::B(1) => {} other::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:104:40 | LL | match b { other::B(1) => {} other::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:107:16 | LL | let other::C(_, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:108:16 | LL | let other::C(_a, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:109:16 | LL | let other::C(_, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:110:16 | LL | let other::C(_a, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:111:22 | LL | match c { other::C(_, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:112:22 | LL | match c { other::C(_a, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:113:22 | LL | match c { other::C(_, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:114:22 | LL | match c { other::C(_a, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:122:21 | LL | let a2 = other::A; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:123:21 | LL | let b2 = other::B; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:124:21 | LL | let c2 = other::C; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error: aborting due to 48 previous errors diff --git a/src/test/run-pass/privacy/private-class-field.rs b/src/test/ui/privacy/private-class-field.rs similarity index 100% rename from src/test/run-pass/privacy/private-class-field.rs rename to src/test/ui/privacy/private-class-field.rs diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.rs b/src/test/ui/privacy/private-in-public-assoc-ty.rs index 81d23959fd..3c42f24d5f 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.rs +++ b/src/test/ui/privacy/private-in-public-assoc-ty.rs @@ -1,7 +1,8 @@ // Private types and traits are not allowed in interfaces of associated types. // This test also ensures that the checks are performed even inside private modules. -#![feature(associated_type_defaults, existential_type)] +#![feature(associated_type_defaults)] +#![feature(type_alias_impl_trait)] mod m { struct Priv; @@ -31,7 +32,7 @@ mod m { type Alias1 = Priv; //~^ ERROR private type `m::Priv` in public interface - existential type Exist: PrivTr; + type Exist = impl PrivTr; //~^ ERROR private trait `m::PrivTr` in public interface fn infer_exist() -> Self::Exist { Priv } } diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr index 81d70ee770..158862f922 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr +++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr @@ -1,5 +1,5 @@ warning: private trait `m::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-assoc-ty.rs:15:5 + --> $DIR/private-in-public-assoc-ty.rs:16:5 | LL | / pub trait PubTr { LL | | @@ -10,12 +10,12 @@ LL | | fn infer_exist() -> Self::Exist; LL | | } | |_____^ | - = note: #[warn(private_in_public)] on by default + = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 warning: private type `m::Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:15:5 + --> $DIR/private-in-public-assoc-ty.rs:16:5 | LL | / pub trait PubTr { LL | | @@ -30,7 +30,7 @@ LL | | } = note: for more information, see issue #34537 error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:24:9 + --> $DIR/private-in-public-assoc-ty.rs:25:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -39,7 +39,7 @@ LL | type Alias4 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:31:9 + --> $DIR/private-in-public-assoc-ty.rs:32:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -48,13 +48,13 @@ LL | type Alias1 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0445]: private trait `m::PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:34:9 + --> $DIR/private-in-public-assoc-ty.rs:35:9 | LL | trait PrivTr {} | - `m::PrivTr` declared as private ... -LL | existential type Exist: PrivTr; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait +LL | type Exist = impl PrivTr; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait error: aborting due to 3 previous errors diff --git a/src/test/ui/privacy/private-in-public-expr-pat.rs b/src/test/ui/privacy/private-in-public-expr-pat.rs index a3e53bdf45..5c9ecd13b0 100644 --- a/src/test/ui/privacy/private-in-public-expr-pat.rs +++ b/src/test/ui/privacy/private-in-public-expr-pat.rs @@ -1,6 +1,6 @@ // Patterns and expressions are not interface parts and don't produce private-in-public errors. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Priv1(usize); struct Priv2; diff --git a/src/test/ui/privacy/private-in-public-non-principal.stderr b/src/test/ui/privacy/private-in-public-non-principal.stderr index 578f4380b4..4f2a5ea45a 100644 --- a/src/test/ui/privacy/private-in-public-non-principal.stderr +++ b/src/test/ui/privacy/private-in-public-non-principal.stderr @@ -4,7 +4,7 @@ warning: private trait `PrivNonPrincipal` in public interface (error E0445) LL | pub fn leak_dyn_nonprincipal() -> Box { loop {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(private_in_public)] on by default + = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 diff --git a/src/test/ui/privacy/private-in-public-existential.rs b/src/test/ui/privacy/private-in-public-type-alias-impl-trait.rs similarity index 62% rename from src/test/ui/privacy/private-in-public-existential.rs rename to src/test/ui/privacy/private-in-public-type-alias-impl-trait.rs index 61c6130e47..40bba720b0 100644 --- a/src/test/ui/privacy/private-in-public-existential.rs +++ b/src/test/ui/privacy/private-in-public-type-alias-impl-trait.rs @@ -1,9 +1,9 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] #![deny(private_in_public)] -pub existential type Pub: Default; +pub type Pub = impl Default; #[derive(Default)] struct Priv; @@ -18,7 +18,7 @@ pub trait Trait { } impl Trait for u8 { - existential type Pub: Default; + type Pub = impl Default; fn method() -> Self::Pub { Priv } } diff --git a/src/test/ui/privacy/private-in-public-warn.stderr b/src/test/ui/privacy/private-in-public-warn.stderr index 16b7e51032..9741f3b6d0 100644 --- a/src/test/ui/privacy/private-in-public-warn.stderr +++ b/src/test/ui/privacy/private-in-public-warn.stderr @@ -339,7 +339,7 @@ warning: bounds on generic parameters are not enforced in type aliases LL | pub type Alias = T; | ^^^^^^ | - = note: #[warn(type_alias_bounds)] on by default + = note: `#[warn(type_alias_bounds)]` on by default = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases diff --git a/src/test/run-pass/privacy/private-method.rs b/src/test/ui/privacy/private-method-rpass.rs similarity index 100% rename from src/test/run-pass/privacy/private-method.rs rename to src/test/ui/privacy/private-method-rpass.rs diff --git a/src/test/run-pass/privacy/pub-extern-privacy.rs b/src/test/ui/privacy/pub-extern-privacy.rs similarity index 100% rename from src/test/run-pass/privacy/pub-extern-privacy.rs rename to src/test/ui/privacy/pub-extern-privacy.rs diff --git a/src/test/run-pass/privacy/pub-use-xcrate.rs b/src/test/ui/privacy/pub-use-xcrate.rs similarity index 100% rename from src/test/run-pass/privacy/pub-use-xcrate.rs rename to src/test/ui/privacy/pub-use-xcrate.rs diff --git a/src/test/run-pass/privacy/pub_use_mods_xcrate_exe.rs b/src/test/ui/privacy/pub_use_mods_xcrate_exe.rs similarity index 100% rename from src/test/run-pass/privacy/pub_use_mods_xcrate_exe.rs rename to src/test/ui/privacy/pub_use_mods_xcrate_exe.rs diff --git a/src/test/ui/privacy/restricted/lookup-ignores-private.rs b/src/test/ui/privacy/restricted/lookup-ignores-private.rs index 419d521748..240ce1e2b0 100644 --- a/src/test/ui/privacy/restricted/lookup-ignores-private.rs +++ b/src/test/ui/privacy/restricted/lookup-ignores-private.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] mod foo { diff --git a/src/test/ui/privacy/restricted/test.rs b/src/test/ui/privacy/restricted/test.rs index f208696c86..a8c269378c 100644 --- a/src/test/ui/privacy/restricted/test.rs +++ b/src/test/ui/privacy/restricted/test.rs @@ -47,6 +47,6 @@ fn main() { } mod pathological { - pub(in bad::path) mod m1 {} //~ ERROR failed to resolve: maybe a missing `extern crate bad;`? + pub(in bad::path) mod m1 {} //~ ERROR failed to resolve: maybe a missing crate `bad`? pub(in foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules } diff --git a/src/test/ui/privacy/restricted/test.stderr b/src/test/ui/privacy/restricted/test.stderr index fa78ae759c..a23973d085 100644 --- a/src/test/ui/privacy/restricted/test.stderr +++ b/src/test/ui/privacy/restricted/test.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing `extern crate bad;`? +error[E0433]: failed to resolve: maybe a missing crate `bad`? --> $DIR/test.rs:50:12 | LL | pub(in bad::path) mod m1 {} - | ^^^ maybe a missing `extern crate bad;`? + | ^^^ maybe a missing crate `bad`? error: visibilities can only be restricted to ancestor modules --> $DIR/test.rs:51:12 diff --git a/src/test/run-pass/proc-macro/add-impl.rs b/src/test/ui/proc-macro/add-impl.rs similarity index 92% rename from src/test/run-pass/proc-macro/add-impl.rs rename to src/test/ui/proc-macro/add-impl.rs index 239074b4e4..ff2897a5e8 100644 --- a/src/test/run-pass/proc-macro/add-impl.rs +++ b/src/test/ui/proc-macro/add-impl.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:add-impl.rs #[macro_use] diff --git a/src/test/run-pass/proc-macro/append-impl.rs b/src/test/ui/proc-macro/append-impl.rs similarity index 95% rename from src/test/run-pass/proc-macro/append-impl.rs rename to src/test/ui/proc-macro/append-impl.rs index a49fd82780..a493840134 100644 --- a/src/test/run-pass/proc-macro/append-impl.rs +++ b/src/test/ui/proc-macro/append-impl.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:append-impl.rs #![allow(warnings)] diff --git a/src/test/run-pass/proc-macro/attr-args.rs b/src/test/ui/proc-macro/attr-args.rs similarity index 95% rename from src/test/run-pass/proc-macro/attr-args.rs rename to src/test/ui/proc-macro/attr-args.rs index 6ff6ccacf7..764f507abf 100644 --- a/src/test/run-pass/proc-macro/attr-args.rs +++ b/src/test/ui/proc-macro/attr-args.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:attr-args.rs #![allow(warnings)] diff --git a/src/test/run-pass/proc-macro/attr-cfg.rs b/src/test/ui/proc-macro/attr-cfg.rs similarity index 96% rename from src/test/run-pass/proc-macro/attr-cfg.rs rename to src/test/ui/proc-macro/attr-cfg.rs index 7816576eb5..2aed9e2e81 100644 --- a/src/test/run-pass/proc-macro/attr-cfg.rs +++ b/src/test/ui/proc-macro/attr-cfg.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:attr-cfg.rs // revisions: foo bar diff --git a/src/test/run-pass/proc-macro/attr-on-trait.rs b/src/test/ui/proc-macro/attr-on-trait.rs similarity index 94% rename from src/test/run-pass/proc-macro/attr-on-trait.rs rename to src/test/ui/proc-macro/attr-on-trait.rs index 4a8fac4110..e0edee630a 100644 --- a/src/test/run-pass/proc-macro/attr-on-trait.rs +++ b/src/test/ui/proc-macro/attr-on-trait.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:attr-on-trait.rs extern crate attr_on_trait; diff --git a/src/test/run-pass/proc-macro/attr-stmt-expr.rs b/src/test/ui/proc-macro/attr-stmt-expr-rpass.rs similarity index 86% rename from src/test/run-pass/proc-macro/attr-stmt-expr.rs rename to src/test/ui/proc-macro/attr-stmt-expr-rpass.rs index 3f10754985..16b8fabfc3 100644 --- a/src/test/run-pass/proc-macro/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/attr-stmt-expr-rpass.rs @@ -1,8 +1,9 @@ -// aux-build:attr-stmt-expr.rs +// run-pass +// aux-build:attr-stmt-expr-rpass.rs #![feature(stmt_expr_attributes, proc_macro_hygiene)] -extern crate attr_stmt_expr; +extern crate attr_stmt_expr_rpass as attr_stmt_expr; use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr, no_output, noop}; diff --git a/src/test/ui/proc-macro/attr-stmt-expr.rs b/src/test/ui/proc-macro/attr-stmt-expr.rs index 5fdaf93de4..14a392db4e 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/attr-stmt-expr.rs @@ -9,7 +9,7 @@ fn print_str(string: &'static str) { // macros are handled a bit differently #[expect_print_expr] //~^ ERROR attributes on expressions are experimental - //~| HELP add #![feature(stmt_expr_attributes)] to the crate attributes to enable + //~| HELP add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable println!("{}", string) } @@ -22,6 +22,6 @@ fn main() { #[expect_expr] //~^ ERROR attributes on expressions are experimental - //~| HELP add #![feature(stmt_expr_attributes)] to the crate attributes to enable + //~| HELP add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable print_str("string") } diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stderr b/src/test/ui/proc-macro/attr-stmt-expr.stderr index 3928a973ea..d931a25dd4 100644 --- a/src/test/ui/proc-macro/attr-stmt-expr.stderr +++ b/src/test/ui/proc-macro/attr-stmt-expr.stderr @@ -5,7 +5,7 @@ LL | #[expect_print_expr] | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/attr-stmt-expr.rs:23:5 @@ -14,7 +14,7 @@ LL | #[expect_expr] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/attribute-spans-preserved.stdout b/src/test/ui/proc-macro/attribute-spans-preserved.stdout index b1487fcd5e..faf3171215 100644 --- a/src/test/ui/proc-macro/attribute-spans-preserved.stdout +++ b/src/test/ui/proc-macro/attribute-spans-preserved.stdout @@ -1 +1 @@ -fn main ( ) { let y : u32 = "z" ; { let x : u32 = "y" ; } } +fn main () { let y : u32 = "z" ; { let x : u32 = "y" ; } } diff --git a/src/test/ui/proc-macro/attribute.rs b/src/test/ui/proc-macro/attribute.rs index 04c88dcef5..5531b32362 100644 --- a/src/test/ui/proc-macro/attribute.rs +++ b/src/test/ui/proc-macro/attribute.rs @@ -40,8 +40,7 @@ pub fn foo8(input: TokenStream) -> TokenStream { input } //~^ ERROR: `self` cannot be a name of derive macro pub fn foo9(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive(PartialEq)] -//~^ ERROR: cannot override a built-in derive macro +#[proc_macro_derive(PartialEq)] // OK pub fn foo10(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d11, a)] diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr index e632875cb1..1503f62cb6 100644 --- a/src/test/ui/proc-macro/attribute.stderr +++ b/src/test/ui/proc-macro/attribute.stderr @@ -40,56 +40,50 @@ error: `self` cannot be a name of derive macro LL | #[proc_macro_derive(self)] | ^^^^ -error: cannot override a built-in derive macro - --> $DIR/attribute.rs:43:21 - | -LL | #[proc_macro_derive(PartialEq)] - | ^^^^^^^^^ - error: second argument must be `attributes` - --> $DIR/attribute.rs:47:26 + --> $DIR/attribute.rs:46:26 | LL | #[proc_macro_derive(d11, a)] | ^ error: attribute must be of form: `attributes(foo, bar)` - --> $DIR/attribute.rs:47:26 + --> $DIR/attribute.rs:46:26 | LL | #[proc_macro_derive(d11, a)] | ^ error: attribute must be of form: `attributes(foo, bar)` - --> $DIR/attribute.rs:52:26 + --> $DIR/attribute.rs:51:26 | LL | #[proc_macro_derive(d12, attributes)] | ^^^^^^^^^^ error: not a meta item - --> $DIR/attribute.rs:56:37 + --> $DIR/attribute.rs:55:37 | LL | #[proc_macro_derive(d13, attributes("a"))] | ^^^ error: must only be one word - --> $DIR/attribute.rs:60:37 + --> $DIR/attribute.rs:59:37 | LL | #[proc_macro_derive(d14, attributes(a = ""))] | ^^^^^^ error: must only be one word - --> $DIR/attribute.rs:64:37 + --> $DIR/attribute.rs:63:37 | LL | #[proc_macro_derive(d15, attributes(m::a))] | ^^^^ error: must only be one word - --> $DIR/attribute.rs:68:37 + --> $DIR/attribute.rs:67:37 | LL | #[proc_macro_derive(d16, attributes(a(b)))] | ^^^^ error: `self` cannot be a name of derive helper attribute - --> $DIR/attribute.rs:72:37 + --> $DIR/attribute.rs:71:37 | LL | #[proc_macro_derive(d17, attributes(self))] | ^^^^ @@ -106,5 +100,5 @@ error: malformed `proc_macro_derive` attribute input LL | #[proc_macro_derive = ""] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: aborting due to 18 previous errors +error: aborting due to 17 previous errors diff --git a/src/test/ui/proc-macro/attributes-included.rs b/src/test/ui/proc-macro/attributes-included.rs index 0ab17a1f3b..4769607ff3 100644 --- a/src/test/ui/proc-macro/attributes-included.rs +++ b/src/test/ui/proc-macro/attributes-included.rs @@ -1,5 +1,5 @@ // aux-build:attributes-included.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/proc-macro/attributes-included.stderr b/src/test/ui/proc-macro/attributes-included.stderr index fcd77b2d38..0f74f45e10 100644 --- a/src/test/ui/proc-macro/attributes-included.stderr +++ b/src/test/ui/proc-macro/attributes-included.stderr @@ -9,5 +9,5 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unused_variables)] implied by #[warn(unused)] + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` diff --git a/src/test/run-pass/proc-macro/auxiliary/add-impl.rs b/src/test/ui/proc-macro/auxiliary/add-impl.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/add-impl.rs rename to src/test/ui/proc-macro/auxiliary/add-impl.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/append-impl.rs b/src/test/ui/proc-macro/auxiliary/append-impl.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/append-impl.rs rename to src/test/ui/proc-macro/auxiliary/append-impl.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/attr-args.rs b/src/test/ui/proc-macro/auxiliary/attr-args.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/attr-args.rs rename to src/test/ui/proc-macro/auxiliary/attr-args.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs b/src/test/ui/proc-macro/auxiliary/attr-cfg.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs rename to src/test/ui/proc-macro/auxiliary/attr-cfg.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs b/src/test/ui/proc-macro/auxiliary/attr-on-trait.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs rename to src/test/ui/proc-macro/auxiliary/attr-on-trait.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs similarity index 90% rename from src/test/run-pass/proc-macro/auxiliary/attr-stmt-expr.rs rename to src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs index d81e16d9d2..f1de3709b1 100644 --- a/src/test/run-pass/proc-macro/auxiliary/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs @@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string);"); + assert_eq!(item.to_string(), "println!(\"{}\", string);"); item } @@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string)"); + assert_eq!(item.to_string(), "println!(\"{}\", string)"); item } diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs index 0a82cbedd7..d2180def5b 100644 --- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs @@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string);"); + assert_eq!(item.to_string(), "println!(\"{}\", string);"); item } @@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string)"); + assert_eq!(item.to_string(), "println!(\"{}\", string)"); item } diff --git a/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs b/src/test/ui/proc-macro/auxiliary/bang-macro.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/bang-macro.rs rename to src/test/ui/proc-macro/auxiliary/bang-macro.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/call-site.rs b/src/test/ui/proc-macro/auxiliary/call-site.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/call-site.rs rename to src/test/ui/proc-macro/auxiliary/call-site.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs b/src/test/ui/proc-macro/auxiliary/count_compound_ops.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs rename to src/test/ui/proc-macro/auxiliary/count_compound_ops.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/src/test/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs rename to src/test/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-a.rs b/src/test/ui/proc-macro/auxiliary/derive-a.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-a.rs rename to src/test/ui/proc-macro/auxiliary/derive-a.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs b/src/test/ui/proc-macro/auxiliary/derive-atob.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-atob.rs rename to src/test/ui/proc-macro/auxiliary/derive-atob.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs b/src/test/ui/proc-macro/auxiliary/derive-attr-cfg.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs rename to src/test/ui/proc-macro/auxiliary/derive-attr-cfg.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-b.rs b/src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs similarity index 86% rename from src/test/run-pass/proc-macro/auxiliary/derive-b.rs rename to src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs index fd056d605a..3e6af67a9f 100644 --- a/src/test/run-pass/proc-macro/auxiliary/derive-b.rs +++ b/src/test/ui/proc-macro/auxiliary/derive-b-rpass.rs @@ -10,7 +10,7 @@ use proc_macro::TokenStream; #[proc_macro_derive(B, attributes(B, C))] pub fn derive(input: TokenStream) -> TokenStream { let input = input.to_string(); - assert!(input.contains("#[B [ arbitrary tokens ]]")); + assert!(input.contains("#[B[arbitrary tokens]]")); assert!(input.contains("struct B {")); assert!(input.contains("#[C]")); "".parse().unwrap() diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs b/src/test/ui/proc-macro/auxiliary/derive-ctod.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs rename to src/test/ui/proc-macro/auxiliary/derive-ctod.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs b/src/test/ui/proc-macro/auxiliary/derive-nothing.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs rename to src/test/ui/proc-macro/auxiliary/derive-nothing.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs b/src/test/ui/proc-macro/auxiliary/derive-same-struct.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs rename to src/test/ui/proc-macro/auxiliary/derive-same-struct.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs b/src/test/ui/proc-macro/auxiliary/derive-two-attrs.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs rename to src/test/ui/proc-macro/auxiliary/derive-two-attrs.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/derive-union.rs b/src/test/ui/proc-macro/auxiliary/derive-union.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/derive-union.rs rename to src/test/ui/proc-macro/auxiliary/derive-union.rs diff --git a/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs b/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs index d5d393b5a6..bdcdb7922c 100644 --- a/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs +++ b/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs @@ -14,3 +14,9 @@ macro_rules! external { struct D($crate::S); }; } + +#[macro_export] +macro_rules! issue_62325 { () => { + #[print_attr] + struct B(identity!($crate::S)); +}} diff --git a/src/test/run-pass/proc-macro/auxiliary/double.rs b/src/test/ui/proc-macro/auxiliary/double.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/double.rs rename to src/test/ui/proc-macro/auxiliary/double.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs b/src/test/ui/proc-macro/auxiliary/empty-crate.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/empty-crate.rs rename to src/test/ui/proc-macro/auxiliary/empty-crate.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/ui/proc-macro/auxiliary/expand-with-a-macro.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs rename to src/test/ui/proc-macro/auxiliary/expand-with-a-macro.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs b/src/test/ui/proc-macro/auxiliary/external-crate-var.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs rename to src/test/ui/proc-macro/auxiliary/external-crate-var.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs b/src/test/ui/proc-macro/auxiliary/gen-lifetime-token.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs rename to src/test/ui/proc-macro/auxiliary/gen-lifetime-token.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs b/src/test/ui/proc-macro/auxiliary/hygiene_example.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs rename to src/test/ui/proc-macro/auxiliary/hygiene_example.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs b/src/test/ui/proc-macro/auxiliary/hygiene_example_codegen.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs rename to src/test/ui/proc-macro/auxiliary/hygiene_example_codegen.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/issue-39889.rs b/src/test/ui/proc-macro/auxiliary/issue-39889.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/issue-39889.rs rename to src/test/ui/proc-macro/auxiliary/issue-39889.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs b/src/test/ui/proc-macro/auxiliary/issue-42708.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/issue-42708.rs rename to src/test/ui/proc-macro/auxiliary/issue-42708.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/issue-50061.rs b/src/test/ui/proc-macro/auxiliary/issue-50061.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/issue-50061.rs rename to src/test/ui/proc-macro/auxiliary/issue-50061.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/lifetimes.rs b/src/test/ui/proc-macro/auxiliary/lifetimes-rpass.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/lifetimes.rs rename to src/test/ui/proc-macro/auxiliary/lifetimes-rpass.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/modify-ast.rs b/src/test/ui/proc-macro/auxiliary/modify-ast.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/modify-ast.rs rename to src/test/ui/proc-macro/auxiliary/modify-ast.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/negative-token.rs b/src/test/ui/proc-macro/auxiliary/negative-token.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/negative-token.rs rename to src/test/ui/proc-macro/auxiliary/negative-token.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/not-joint.rs b/src/test/ui/proc-macro/auxiliary/not-joint.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/not-joint.rs rename to src/test/ui/proc-macro/auxiliary/not-joint.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs b/src/test/ui/proc-macro/auxiliary/span-api-tests.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs rename to src/test/ui/proc-macro/auxiliary/span-api-tests.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs b/src/test/ui/proc-macro/auxiliary/span-test-macros.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs rename to src/test/ui/proc-macro/auxiliary/span-test-macros.rs diff --git a/src/test/run-pass/proc-macro/auxiliary/test-macros.rs b/src/test/ui/proc-macro/auxiliary/test-macros-rpass.rs similarity index 100% rename from src/test/run-pass/proc-macro/auxiliary/test-macros.rs rename to src/test/ui/proc-macro/auxiliary/test-macros-rpass.rs diff --git a/src/test/run-pass/proc-macro/bang-macro.rs b/src/test/ui/proc-macro/bang-macro.rs similarity index 94% rename from src/test/run-pass/proc-macro/bang-macro.rs rename to src/test/ui/proc-macro/bang-macro.rs index 6f04bb10b9..7073c71538 100644 --- a/src/test/run-pass/proc-macro/bang-macro.rs +++ b/src/test/ui/proc-macro/bang-macro.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:bang-macro.rs #![feature(proc_macro_hygiene)] diff --git a/src/test/run-pass/proc-macro/call-site.rs b/src/test/ui/proc-macro/call-site.rs similarity index 94% rename from src/test/run-pass/proc-macro/call-site.rs rename to src/test/ui/proc-macro/call-site.rs index f31b418e3b..096d0ec533 100644 --- a/src/test/run-pass/proc-macro/call-site.rs +++ b/src/test/ui/proc-macro/call-site.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] #![allow(unused_imports)] // aux-build:call-site.rs diff --git a/src/test/run-pass/proc-macro/count_compound_ops.rs b/src/test/ui/proc-macro/count_compound_ops.rs similarity index 94% rename from src/test/run-pass/proc-macro/count_compound_ops.rs rename to src/test/ui/proc-macro/count_compound_ops.rs index f42d82ce04..966ab616cd 100644 --- a/src/test/run-pass/proc-macro/count_compound_ops.rs +++ b/src/test/ui/proc-macro/count_compound_ops.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:count_compound_ops.rs #![feature(proc_macro_hygiene)] diff --git a/src/test/run-pass/proc-macro/crate-var.rs b/src/test/ui/proc-macro/crate-var.rs similarity index 98% rename from src/test/run-pass/proc-macro/crate-var.rs rename to src/test/ui/proc-macro/crate-var.rs index 4d551f65cd..c0518e4b08 100644 --- a/src/test/run-pass/proc-macro/crate-var.rs +++ b/src/test/ui/proc-macro/crate-var.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:double.rs // aux-build:external-crate-var.rs diff --git a/src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs b/src/test/ui/proc-macro/custom-attr-only-one-derive.rs similarity index 94% rename from src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs rename to src/test/ui/proc-macro/custom-attr-only-one-derive.rs index 993d331559..2cd5b48730 100644 --- a/src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs +++ b/src/test/ui/proc-macro/custom-attr-only-one-derive.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:custom-attr-only-one-derive.rs #![feature(rust_2018_preview)] diff --git a/src/test/run-pass/proc-macro/derive-attr-cfg.rs b/src/test/ui/proc-macro/derive-attr-cfg.rs similarity index 93% rename from src/test/run-pass/proc-macro/derive-attr-cfg.rs rename to src/test/ui/proc-macro/derive-attr-cfg.rs index c23ab9fb68..3947746286 100644 --- a/src/test/run-pass/proc-macro/derive-attr-cfg.rs +++ b/src/test/ui/proc-macro/derive-attr-cfg.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // aux-build:derive-attr-cfg.rs diff --git a/src/test/run-pass/proc-macro/derive-b.rs b/src/test/ui/proc-macro/derive-b.rs similarity index 75% rename from src/test/run-pass/proc-macro/derive-b.rs rename to src/test/ui/proc-macro/derive-b.rs index da67534364..a026c2bd77 100644 --- a/src/test/run-pass/proc-macro/derive-b.rs +++ b/src/test/ui/proc-macro/derive-b.rs @@ -1,6 +1,7 @@ -// aux-build:derive-b.rs +// run-pass +// aux-build:derive-b-rpass.rs -extern crate derive_b; +extern crate derive_b_rpass as derive_b; #[derive(Debug, PartialEq, derive_b::B, Eq, Copy, Clone)] #[cfg_attr(all(), B[arbitrary tokens])] diff --git a/src/test/ui/proc-macro/derive-helper-shadowed.rs b/src/test/ui/proc-macro/derive-helper-shadowed.rs index 0388e647b5..e299454e0f 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowed.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs // aux-build:derive-helper-shadowed-2.rs diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs index cdc0d6da94..59ba1390e1 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs @@ -19,7 +19,7 @@ struct S { struct U; mod inner { - #[empty_helper] //~ ERROR attribute `empty_helper` is currently unknown + #[empty_helper] //~ ERROR cannot find attribute macro `empty_helper` in this scope struct V; } diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index ed6d305165..149f6eef44 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -1,11 +1,8 @@ -error[E0658]: The attribute `empty_helper` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `empty_helper` in this scope --> $DIR/derive-helper-shadowing.rs:22:15 | LL | #[empty_helper] | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name) --> $DIR/derive-helper-shadowing.rs:8:3 @@ -27,5 +24,4 @@ LL | use test_macros::empty_attr as empty_helper; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0659. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/proc-macro/derive-in-mod.rs b/src/test/ui/proc-macro/derive-in-mod.rs index e6b91324f9..8b5d4e9d09 100644 --- a/src/test/ui/proc-macro/derive-in-mod.rs +++ b/src/test/ui/proc-macro/derive-in-mod.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs extern crate test_macros; diff --git a/src/test/run-pass/proc-macro/derive-same-struct.rs b/src/test/ui/proc-macro/derive-same-struct.rs similarity index 93% rename from src/test/run-pass/proc-macro/derive-same-struct.rs rename to src/test/ui/proc-macro/derive-same-struct.rs index 1840152508..528b0f22a8 100644 --- a/src/test/run-pass/proc-macro/derive-same-struct.rs +++ b/src/test/ui/proc-macro/derive-same-struct.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(path_statements)] #![allow(dead_code)] // aux-build:derive-same-struct.rs diff --git a/src/test/run-pass/proc-macro/derive-same-struct.stdout b/src/test/ui/proc-macro/derive-same-struct.stdout similarity index 100% rename from src/test/run-pass/proc-macro/derive-same-struct.stdout rename to src/test/ui/proc-macro/derive-same-struct.stdout diff --git a/src/test/ui/proc-macro/derive-still-gated.rs b/src/test/ui/proc-macro/derive-still-gated.rs index d895d26f26..4e6f9b0722 100644 --- a/src/test/ui/proc-macro/derive-still-gated.rs +++ b/src/test/ui/proc-macro/derive-still-gated.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate test_macros; -#[derive_Empty] //~ ERROR attribute `derive_Empty` is currently unknown +#[derive_Empty] //~ ERROR cannot find attribute macro `derive_Empty` in this scope struct A; fn main() {} diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr index f299b5abdb..4df1715db9 100644 --- a/src/test/ui/proc-macro/derive-still-gated.stderr +++ b/src/test/ui/proc-macro/derive-still-gated.stderr @@ -1,12 +1,8 @@ -error[E0658]: The attribute `derive_Empty` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `derive_Empty` in this scope --> $DIR/derive-still-gated.rs:6:3 | LL | #[derive_Empty] | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/proc-macro/derive-test.rs b/src/test/ui/proc-macro/derive-test.rs similarity index 96% rename from src/test/run-pass/proc-macro/derive-test.rs rename to src/test/ui/proc-macro/derive-test.rs index edb0201ba7..b81e38432e 100644 --- a/src/test/run-pass/proc-macro/derive-test.rs +++ b/src/test/ui/proc-macro/derive-test.rs @@ -1,3 +1,4 @@ +// run-pass // no-prefer-dynamic // compile-flags: --test diff --git a/src/test/run-pass/proc-macro/derive-two-attrs.rs b/src/test/ui/proc-macro/derive-two-attrs.rs similarity index 92% rename from src/test/run-pass/proc-macro/derive-two-attrs.rs rename to src/test/ui/proc-macro/derive-two-attrs.rs index a93ba8184f..08225b8e3f 100644 --- a/src/test/run-pass/proc-macro/derive-two-attrs.rs +++ b/src/test/ui/proc-macro/derive-two-attrs.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // aux-build:derive-two-attrs.rs diff --git a/src/test/run-pass/proc-macro/derive-union.rs b/src/test/ui/proc-macro/derive-union.rs similarity index 93% rename from src/test/run-pass/proc-macro/derive-union.rs rename to src/test/ui/proc-macro/derive-union.rs index 6e8b1b726e..e83eee0936 100644 --- a/src/test/run-pass/proc-macro/derive-union.rs +++ b/src/test/ui/proc-macro/derive-union.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] // aux-build:derive-union.rs diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs index 2615db3e11..2495e72751 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // aux-build:test-macros.rs diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout index 0611fcb13f..0fe02a9a34 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout @@ -1,4 +1,4 @@ -PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ }, ] PRINT-ATTR INPUT (DISPLAY): struct A(crate::S); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.rs b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs new file mode 100644 index 0000000000..b7b152e669 --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs @@ -0,0 +1,27 @@ +// check-pass +// edition:2018 +// aux-build:test-macros.rs +// aux-build:dollar-crate-external.rs + +// Anonymize unstable non-dummy spans while still showing dummy spans `0..0`. +// normalize-stdout-test "bytes\([^0]\w*\.\.(\w+)\)" -> "bytes(LO..$1)" +// normalize-stdout-test "bytes\((\w+)\.\.[^0]\w*\)" -> "bytes($1..HI)" + +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate test_macros; +extern crate dollar_crate_external; + +type S = u8; + +macro_rules! m { () => { + #[print_attr] + struct A(identity!($crate::S)); +}} + +m!(); + +dollar_crate_external::issue_62325!(); + +fn main() {} diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout new file mode 100644 index 0000000000..a499e1362e --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -0,0 +1,112 @@ +PRINT-ATTR INPUT (DISPLAY): struct A(identity!(crate :: S)); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A (identity ! ($crate :: S)) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: #2 bytes(LO..HI), + }, + Ident { + ident: "A", + span: #2 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "identity", + span: #2 bytes(LO..HI), + }, + Punct { + ch: '!', + spacing: Alone, + span: #2 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "$crate", + span: #2 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Joint, + span: #2 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Alone, + span: #2 bytes(LO..HI), + }, + Ident { + ident: "S", + span: #2 bytes(LO..HI), + }, + ], + span: #2 bytes(LO..HI), + }, + ], + span: #2 bytes(LO..HI), + }, + Punct { + ch: ';', + spacing: Alone, + span: #2 bytes(LO..HI), + }, +] +PRINT-ATTR INPUT (DISPLAY): struct B(identity!(::dollar_crate_external :: S)); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct B (identity ! ($crate :: S)) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: #7 bytes(LO..HI), + }, + Ident { + ident: "B", + span: #7 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "identity", + span: #7 bytes(LO..HI), + }, + Punct { + ch: '!', + spacing: Alone, + span: #7 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "$crate", + span: #7 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Joint, + span: #7 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Alone, + span: #7 bytes(LO..HI), + }, + Ident { + ident: "S", + span: #7 bytes(LO..HI), + }, + ], + span: #7 bytes(LO..HI), + }, + ], + span: #7 bytes(LO..HI), + }, + Punct { + ch: ';', + spacing: Alone, + span: #7 bytes(LO..HI), + }, +] diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index 3c88ee9984..da1d7549d0 100644 --- a/src/test/ui/proc-macro/dollar-crate.stdout +++ b/src/test/ui/proc-macro/dollar-crate.stdout @@ -1,4 +1,4 @@ -PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ }, ] PRINT-ATTR INPUT (DISPLAY): struct A(crate::S); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -80,7 +80,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ }, ] PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S); -PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ; +PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ($crate :: S) ; PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -120,125 +120,125 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ span: #2 bytes(LO..HI), }, ] -PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "M", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "S", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ], - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ] PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "A", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "S", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ], - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ] PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S); -PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ; +PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ($crate :: S) ; PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "D", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Ident { ident: "S", - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ], - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #10 bytes(LO..HI), + span: #9 bytes(LO..HI), }, ] diff --git a/src/test/ui/proc-macro/edition-imports-2018.rs b/src/test/ui/proc-macro/edition-imports-2018.rs index f8d6bc5e07..5a77cd4ef4 100644 --- a/src/test/ui/proc-macro/edition-imports-2018.rs +++ b/src/test/ui/proc-macro/edition-imports-2018.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // aux-build:edition-imports-2015.rs diff --git a/src/test/run-pass/proc-macro/empty-crate.rs b/src/test/ui/proc-macro/empty-crate.rs similarity index 89% rename from src/test/run-pass/proc-macro/empty-crate.rs rename to src/test/ui/proc-macro/empty-crate.rs index 84104a3f5c..3e54c9feeb 100644 --- a/src/test/run-pass/proc-macro/empty-crate.rs +++ b/src/test/ui/proc-macro/empty-crate.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] // aux-build:empty-crate.rs diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.rs b/src/test/ui/proc-macro/expand-to-unstable-2.rs index 4b4ba52ecd..da7c89fdd4 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.rs +++ b/src/test/ui/proc-macro/expand-to-unstable-2.rs @@ -1,12 +1,13 @@ // aux-build:derive-unstable-2.rs -#![allow(warnings)] +#![feature(custom_attribute)] #[macro_use] extern crate derive_unstable_2; #[derive(Unstable)] -//~^ ERROR: reserved for internal compiler +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler + struct A; fn main() { diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr index e2f51dd3d5..01e6a4a8ab 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr @@ -1,11 +1,11 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/expand-to-unstable-2.rs:8:10 | LL | #[derive(Unstable)] | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/proc-macro/expand-to-unstable.stderr b/src/test/ui/proc-macro/expand-to-unstable.stderr index 29a1287955..6df0076586 100644 --- a/src/test/ui/proc-macro/expand-to-unstable.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are LL | #[derive(Unstable)] | ^^^^^^^^ | - = help: add #![feature(core_intrinsics)] to the crate attributes to enable + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/proc-macro/expand-with-a-macro.rs b/src/test/ui/proc-macro/expand-with-a-macro.rs similarity index 96% rename from src/test/run-pass/proc-macro/expand-with-a-macro.rs rename to src/test/ui/proc-macro/expand-with-a-macro.rs index 097520b993..418178d0f0 100644 --- a/src/test/run-pass/proc-macro/expand-with-a-macro.rs +++ b/src/test/ui/proc-macro/expand-with-a-macro.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:expand-with-a-macro.rs // ignore-wasm32-bare compiled with panic=abort by default diff --git a/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs index 25a2a37614..a6e64e1b1b 100644 --- a/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs +++ b/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 extern crate proc_macro; diff --git a/src/test/run-pass/proc-macro/gen-lifetime-token.rs b/src/test/ui/proc-macro/gen-lifetime-token.rs similarity index 92% rename from src/test/run-pass/proc-macro/gen-lifetime-token.rs rename to src/test/ui/proc-macro/gen-lifetime-token.rs index 1659b87440..588bd2b76c 100644 --- a/src/test/run-pass/proc-macro/gen-lifetime-token.rs +++ b/src/test/ui/proc-macro/gen-lifetime-token.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:gen-lifetime-token.rs extern crate gen_lifetime_token as bar; diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index 1b828b4f03..51bbb23da7 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -28,7 +28,7 @@ warning: cannot find type `FromOutside` in this scope LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | - = note: #[warn(proc_macro_derive_resolution_fallback)] on by default + = note: `#[warn(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #50504 diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs b/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs index 6d3e5ec198..2e20a3de6b 100644 --- a/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs +++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #[macro_use(Empty)] diff --git a/src/test/run-pass/proc-macro/hygiene_example.rs b/src/test/ui/proc-macro/hygiene_example.rs similarity index 97% rename from src/test/run-pass/proc-macro/hygiene_example.rs rename to src/test/ui/proc-macro/hygiene_example.rs index 3e5bab6bb1..56ea9daacc 100644 --- a/src/test/run-pass/proc-macro/hygiene_example.rs +++ b/src/test/ui/proc-macro/hygiene_example.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_macros)] // aux-build:hygiene_example_codegen.rs // aux-build:hygiene_example.rs diff --git a/src/test/run-pass/proc-macro/issue-39889.rs b/src/test/ui/proc-macro/issue-39889.rs similarity index 92% rename from src/test/run-pass/proc-macro/issue-39889.rs rename to src/test/ui/proc-macro/issue-39889.rs index 91c8d48b87..ada125a215 100644 --- a/src/test/run-pass/proc-macro/issue-39889.rs +++ b/src/test/ui/proc-macro/issue-39889.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // aux-build:issue-39889.rs diff --git a/src/test/ui/proc-macro/issue-41211.rs b/src/test/ui/proc-macro/issue-41211.rs index ee9246e1c9..491b89b2f5 100644 --- a/src/test/ui/proc-macro/issue-41211.rs +++ b/src/test/ui/proc-macro/issue-41211.rs @@ -3,11 +3,11 @@ // FIXME: https://github.com/rust-lang/rust/issues/41430 // This is a temporary regression test for the ICE reported in #41211 +#![feature(custom_attribute)] #![feature(custom_inner_attributes)] #![identity_attr] -//~^ ERROR attribute `identity_attr` is currently unknown to the compiler -//~| ERROR inconsistent resolution for a macro: first custom attribute, then attribute macro +//~^ ERROR inconsistent resolution for a macro: first custom attribute, then attribute macro extern crate test_macros; use test_macros::identity_attr; diff --git a/src/test/ui/proc-macro/issue-41211.stderr b/src/test/ui/proc-macro/issue-41211.stderr index 1de6b293ec..f01cba0c93 100644 --- a/src/test/ui/proc-macro/issue-41211.stderr +++ b/src/test/ui/proc-macro/issue-41211.stderr @@ -1,18 +1,8 @@ -error[E0658]: The attribute `identity_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-41211.rs:8:4 - | -LL | #![identity_attr] - | ^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable - error: inconsistent resolution for a macro: first custom attribute, then attribute macro - --> $DIR/issue-41211.rs:8:4 + --> $DIR/issue-41211.rs:9:4 | LL | #![identity_attr] | ^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/proc-macro/issue-42708.rs b/src/test/ui/proc-macro/issue-42708.rs similarity index 96% rename from src/test/run-pass/proc-macro/issue-42708.rs rename to src/test/ui/proc-macro/issue-42708.rs index 466021c16e..e8f445aaaf 100644 --- a/src/test/run-pass/proc-macro/issue-42708.rs +++ b/src/test/ui/proc-macro/issue-42708.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:issue-42708.rs #![feature(decl_macro)] diff --git a/src/test/run-pass/proc-macro/issue-50061.rs b/src/test/ui/proc-macro/issue-50061.rs similarity index 96% rename from src/test/run-pass/proc-macro/issue-50061.rs rename to src/test/ui/proc-macro/issue-50061.rs index b0dad493eb..01c6b80b46 100644 --- a/src/test/run-pass/proc-macro/issue-50061.rs +++ b/src/test/ui/proc-macro/issue-50061.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(path_statements)] // aux-build:issue-50061.rs diff --git a/src/test/ui/proc-macro/issue-53481.rs b/src/test/ui/proc-macro/issue-53481.rs index 2fbde5fedb..ae10a3baa3 100644 --- a/src/test/ui/proc-macro/issue-53481.rs +++ b/src/test/ui/proc-macro/issue-53481.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #[macro_use] diff --git a/src/test/run-pass/proc-macro/lifetimes.rs b/src/test/ui/proc-macro/lifetimes-rpass.rs similarity index 81% rename from src/test/run-pass/proc-macro/lifetimes.rs rename to src/test/ui/proc-macro/lifetimes-rpass.rs index e462a53ec2..a1d33ddca7 100644 --- a/src/test/run-pass/proc-macro/lifetimes.rs +++ b/src/test/ui/proc-macro/lifetimes-rpass.rs @@ -1,7 +1,9 @@ +// run-pass + #![allow(unused_variables)] -// aux-build:lifetimes.rs +// aux-build:lifetimes-rpass.rs -extern crate lifetimes; +extern crate lifetimes_rpass as lifetimes; use lifetimes::*; lifetimes_bang! { diff --git a/src/test/ui/proc-macro/lifetimes.stderr b/src/test/ui/proc-macro/lifetimes.stderr index 2356a11953..6e91201405 100644 --- a/src/test/ui/proc-macro/lifetimes.stderr +++ b/src/test/ui/proc-macro/lifetimes.stderr @@ -2,7 +2,7 @@ error: expected type, found `'` --> $DIR/lifetimes.rs:9:10 | LL | type A = single_quote_alone!(); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ this macro call doesn't expand to a type error: aborting due to previous error diff --git a/src/test/run-pass/proc-macro/load-two.rs b/src/test/ui/proc-macro/load-two.rs similarity index 95% rename from src/test/run-pass/proc-macro/load-two.rs rename to src/test/ui/proc-macro/load-two.rs index 24585e1e06..5ce0e65452 100644 --- a/src/test/run-pass/proc-macro/load-two.rs +++ b/src/test/ui/proc-macro/load-two.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(path_statements)] #![allow(dead_code)] // aux-build:derive-atob.rs diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs index 583640aa81..8a26df9e76 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs @@ -25,22 +25,32 @@ fn check_bang1() { my_macro!(); //~ ERROR can't use a procedural macro from the same crate that defines it } fn check_bang2() { - my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines it + my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr!` in this scope + crate::my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines + //~| ERROR expected macro, found attribute macro `crate::my_macro_attr` } fn check_bang3() { - MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it + MyTrait!(); //~ ERROR cannot find macro `MyTrait!` in this scope + crate::MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR expected macro, found derive macro `crate::MyTrait` } -#[my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it +#[my_macro] //~ ERROR cannot find attribute macro `my_macro` in this scope +#[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR expected attribute, found macro `crate::my_macro` fn check_attr1() {} #[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it fn check_attr2() {} #[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR expected attribute, found derive macro `MyTrait` fn check_attr3() {} -#[derive(my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines it +#[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope +#[derive(crate::my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines + //~| ERROR expected derive macro, found macro `crate::my_macro` struct CheckDerive1; #[derive(my_macro_attr)] //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR expected derive macro, found attribute macro `my_macro_attr` struct CheckDerive2; #[derive(MyTrait)] //~ ERROR can't use a procedural macro from the same crate that defines it struct CheckDerive3; diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index 548f9e3051..b2f1247882 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -5,52 +5,112 @@ LL | my_macro!(); | ^^^^^^^^ error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:28:5 + --> $DIR/macro-namespace-reserved-2.rs:29:5 | -LL | my_macro_attr!(); - | ^^^^^^^^^^^^^ +LL | crate::my_macro_attr!(); + | ^^^^^^^^^^^^^^^^^^^^ -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:31:5 +error: expected macro, found attribute macro `crate::my_macro_attr` + --> $DIR/macro-namespace-reserved-2.rs:29:5 | -LL | MyTrait!(); - | ^^^^^^^ +LL | crate::my_macro_attr!(); + | ^^^^^^^^^^^^^^^^^^^^ not a macro error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:34:3 + --> $DIR/macro-namespace-reserved-2.rs:34:5 | -LL | #[my_macro] - | ^^^^^^^^ +LL | crate::MyTrait!(); + | ^^^^^^^^^^^^^^ + +error: expected macro, found derive macro `crate::MyTrait` + --> $DIR/macro-namespace-reserved-2.rs:34:5 + | +LL | crate::MyTrait!(); + | ^^^^^^^^^^^^^^ not a macro error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:36:3 + --> $DIR/macro-namespace-reserved-2.rs:42:3 | LL | #[my_macro_attr] | ^^^^^^^^^^^^^ error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:38:3 + --> $DIR/macro-namespace-reserved-2.rs:44:3 | LL | #[MyTrait] | ^^^^^^^ -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:41:10 +error: expected attribute, found derive macro `MyTrait` + --> $DIR/macro-namespace-reserved-2.rs:44:3 | -LL | #[derive(my_macro)] - | ^^^^^^^^ +LL | #[MyTrait] + | ^^^^^^^ not an attribute error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:43:10 + --> $DIR/macro-namespace-reserved-2.rs:52:10 | LL | #[derive(my_macro_attr)] | ^^^^^^^^^^^^^ +error: expected derive macro, found attribute macro `my_macro_attr` + --> $DIR/macro-namespace-reserved-2.rs:52:10 + | +LL | #[derive(my_macro_attr)] + | ^^^^^^^^^^^^^ not a derive macro + error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:45:10 + --> $DIR/macro-namespace-reserved-2.rs:55:10 | LL | #[derive(MyTrait)] | ^^^^^^^ -error: aborting due to 9 previous errors +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:39:3 + | +LL | #[crate::my_macro] + | ^^^^^^^^^^^^^^^ + +error: expected attribute, found macro `crate::my_macro` + --> $DIR/macro-namespace-reserved-2.rs:39:3 + | +LL | #[crate::my_macro] + | ^^^^^^^^^^^^^^^ not an attribute + +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:49:10 + | +LL | #[derive(crate::my_macro)] + | ^^^^^^^^^^^^^^^ + +error: expected derive macro, found macro `crate::my_macro` + --> $DIR/macro-namespace-reserved-2.rs:49:10 + | +LL | #[derive(crate::my_macro)] + | ^^^^^^^^^^^^^^^ not a derive macro + +error: cannot find attribute macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:38:3 + | +LL | #[my_macro] + | ^^^^^^^^ + +error: cannot find derive macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:48:10 + | +LL | #[derive(my_macro)] + | ^^^^^^^^ + +error: cannot find macro `my_macro_attr!` in this scope + --> $DIR/macro-namespace-reserved-2.rs:28:5 + | +LL | my_macro_attr!(); + | ^^^^^^^^^^^^^ + +error: cannot find macro `MyTrait!` in this scope + --> $DIR/macro-namespace-reserved-2.rs:33:5 + | +LL | MyTrait!(); + | ^^^^^^^ + +error: aborting due to 19 previous errors diff --git a/src/test/ui/proc-macro/macro-use-attr.rs b/src/test/ui/proc-macro/macro-use-attr.rs index d1b1430fb5..b101c09ed5 100644 --- a/src/test/ui/proc-macro/macro-use-attr.rs +++ b/src/test/ui/proc-macro/macro-use-attr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #[macro_use] diff --git a/src/test/ui/proc-macro/macro-use-bang.rs b/src/test/ui/proc-macro/macro-use-bang.rs index d39c42267f..9d30f48846 100644 --- a/src/test/ui/proc-macro/macro-use-bang.rs +++ b/src/test/ui/proc-macro/macro-use-bang.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #![feature(proc_macro_hygiene)] diff --git a/src/test/run-pass/proc-macro/macros-in-extern.rs b/src/test/ui/proc-macro/macros-in-extern-rpass.rs similarity index 84% rename from src/test/run-pass/proc-macro/macros-in-extern.rs rename to src/test/ui/proc-macro/macros-in-extern-rpass.rs index 99e3f7d14f..a30a287a10 100644 --- a/src/test/run-pass/proc-macro/macros-in-extern.rs +++ b/src/test/ui/proc-macro/macros-in-extern-rpass.rs @@ -1,9 +1,10 @@ -// aux-build:test-macros.rs +// run-pass +// aux-build:test-macros-rpass.rs // ignore-wasm32 #![feature(macros_in_extern)] -extern crate test_macros; +extern crate test_macros_rpass as test_macros; use test_macros::{nop_attr, no_output, emit_input}; diff --git a/src/test/ui/proc-macro/macros-in-extern.stderr b/src/test/ui/proc-macro/macros-in-extern.stderr index 592c91553a..6049c2aa44 100644 --- a/src/test/ui/proc-macro/macros-in-extern.stderr +++ b/src/test/ui/proc-macro/macros-in-extern.stderr @@ -5,7 +5,7 @@ LL | #[empty_attr] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental --> $DIR/macros-in-extern.rs:18:5 @@ -14,7 +14,7 @@ LL | #[identity_attr] | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental --> $DIR/macros-in-extern.rs:22:5 @@ -23,7 +23,7 @@ LL | identity!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/run-pass/proc-macro/modify-ast.rs b/src/test/ui/proc-macro/modify-ast.rs similarity index 96% rename from src/test/run-pass/proc-macro/modify-ast.rs rename to src/test/ui/proc-macro/modify-ast.rs index a96c61f1cb..ea9bf837c2 100644 --- a/src/test/run-pass/proc-macro/modify-ast.rs +++ b/src/test/ui/proc-macro/modify-ast.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:modify-ast.rs extern crate modify_ast; diff --git a/src/test/ui/proc-macro/more-gates.stderr b/src/test/ui/proc-macro/more-gates.stderr index 80985ce752..ad96f78c77 100644 --- a/src/test/ui/proc-macro/more-gates.stderr +++ b/src/test/ui/proc-macro/more-gates.stderr @@ -5,7 +5,7 @@ LL | #[attr2mac1] | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot expand to macro definitions --> $DIR/more-gates.rs:12:1 @@ -14,7 +14,7 @@ LL | #[attr2mac2] | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot expand to macro definitions --> $DIR/more-gates.rs:16:1 @@ -23,7 +23,7 @@ LL | mac2mac1!(); | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot expand to macro definitions --> $DIR/more-gates.rs:17:1 @@ -32,7 +32,7 @@ LL | mac2mac2!(); | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot expand to macro definitions --> $DIR/more-gates.rs:19:1 @@ -41,7 +41,7 @@ LL | tricky!(); | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/run-pass/proc-macro/negative-token.rs b/src/test/ui/proc-macro/negative-token.rs similarity index 94% rename from src/test/run-pass/proc-macro/negative-token.rs rename to src/test/ui/proc-macro/negative-token.rs index 751d1a43a0..3d018fe60a 100644 --- a/src/test/run-pass/proc-macro/negative-token.rs +++ b/src/test/ui/proc-macro/negative-token.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:negative-token.rs #![feature(proc_macro_hygiene)] diff --git a/src/test/ui/proc-macro/no-missing-docs.rs b/src/test/ui/proc-macro/no-missing-docs.rs index e5a5f8beb4..e1e8218582 100644 --- a/src/test/ui/proc-macro/no-missing-docs.rs +++ b/src/test/ui/proc-macro/no-missing-docs.rs @@ -1,7 +1,7 @@ //! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs` //! warnings. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // force-host // no-prefer-dynamic diff --git a/src/test/run-pass/proc-macro/not-joint.rs b/src/test/ui/proc-macro/not-joint.rs similarity index 95% rename from src/test/run-pass/proc-macro/not-joint.rs rename to src/test/ui/proc-macro/not-joint.rs index b360e4e1bb..30da2811ed 100644 --- a/src/test/run-pass/proc-macro/not-joint.rs +++ b/src/test/ui/proc-macro/not-joint.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:not-joint.rs extern crate not_joint as bar; diff --git a/src/test/ui/proc-macro/proc-macro-attributes.rs b/src/test/ui/proc-macro/proc-macro-attributes.rs index 062053453e..04215226c6 100644 --- a/src/test/ui/proc-macro/proc-macro-attributes.rs +++ b/src/test/ui/proc-macro/proc-macro-attributes.rs @@ -4,7 +4,7 @@ extern crate derive_b; #[B] //~ ERROR `B` is ambiguous -#[C] //~ ERROR attribute `C` is currently unknown to the compiler +#[C] //~ ERROR cannot find attribute macro `C` in this scope #[B(D)] //~ ERROR `B` is ambiguous #[B(E = "foo")] //~ ERROR `B` is ambiguous #[B(arbitrary tokens)] //~ ERROR `B` is ambiguous diff --git a/src/test/ui/proc-macro/proc-macro-attributes.stderr b/src/test/ui/proc-macro/proc-macro-attributes.stderr index 5117c7e155..b068c6bc83 100644 --- a/src/test/ui/proc-macro/proc-macro-attributes.stderr +++ b/src/test/ui/proc-macro/proc-macro-attributes.stderr @@ -1,11 +1,8 @@ -error[E0658]: The attribute `C` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `C` in this scope --> $DIR/proc-macro-attributes.rs:7:3 | LL | #[C] - | ^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + | ^ help: a derive helper attribute with a similar name exists: `B` error[E0659]: `B` is ambiguous (derive helper attribute vs any other name) --> $DIR/proc-macro-attributes.rs:6:3 @@ -77,5 +74,4 @@ LL | #[macro_use] error: aborting due to 5 previous errors -Some errors have detailed explanations: E0658, E0659. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/proc-macro/proc-macro-gates.stderr b/src/test/ui/proc-macro/proc-macro-gates.stderr index f53ad222a0..8462b564ec 100644 --- a/src/test/ui/proc-macro/proc-macro-gates.stderr +++ b/src/test/ui/proc-macro/proc-macro-gates.stderr @@ -5,7 +5,7 @@ LL | #![empty_attr] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54726 - = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable error[E0658]: non-builtin inner attributes are unstable --> $DIR/proc-macro-gates.rs:17:5 @@ -14,7 +14,7 @@ LL | #![empty_attr] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54726 - = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to modules --> $DIR/proc-macro-gates.rs:13:1 @@ -23,7 +23,7 @@ LL | #[empty_attr] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to modules --> $DIR/proc-macro-gates.rs:17:5 @@ -32,9 +32,9 @@ LL | #![empty_attr] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable -error: custom attribute invocations must be of the form #[foo] or #[foo(..)], the macro name must only be followed by a delimiter token +error: custom attribute invocations must be of the form `#[foo]` or `#[foo(..)]`, the macro name must only be followed by a delimiter token --> $DIR/proc-macro-gates.rs:21:1 | LL | #[empty_attr = "y"] @@ -47,7 +47,7 @@ LL | #[empty_attr] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to statements --> $DIR/proc-macro-gates.rs:34:5 @@ -56,7 +56,7 @@ LL | #[empty_attr] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to statements --> $DIR/proc-macro-gates.rs:38:5 @@ -65,7 +65,7 @@ LL | #[empty_attr] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to expressions --> $DIR/proc-macro-gates.rs:42:14 @@ -74,7 +74,7 @@ LL | let _x = #[identity_attr] 2; | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to expressions --> $DIR/proc-macro-gates.rs:45:15 @@ -83,7 +83,7 @@ LL | let _x = [#[identity_attr] 2]; | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: custom attributes cannot be applied to expressions --> $DIR/proc-macro-gates.rs:48:14 @@ -92,7 +92,7 @@ LL | let _x = #[identity_attr] println!(); | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to types --> $DIR/proc-macro-gates.rs:53:13 @@ -101,7 +101,7 @@ LL | let _x: identity!(u32) = 3; | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to patterns --> $DIR/proc-macro-gates.rs:54:12 @@ -110,7 +110,7 @@ LL | if let identity!(Some(_x)) = Some(3) {} | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to statements --> $DIR/proc-macro-gates.rs:57:5 @@ -119,7 +119,7 @@ LL | empty!(struct S;); | ^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to statements --> $DIR/proc-macro-gates.rs:58:5 @@ -128,7 +128,7 @@ LL | empty!(let _x = 3;); | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to expressions --> $DIR/proc-macro-gates.rs:60:14 @@ -137,7 +137,7 @@ LL | let _x = identity!(3); | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to expressions --> $DIR/proc-macro-gates.rs:61:15 @@ -146,7 +146,7 @@ LL | let _x = [empty!(3)]; | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 - = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable error: aborting due to 17 previous errors diff --git a/src/test/ui/proc-macro/proc-macro-gates2.stderr b/src/test/ui/proc-macro/proc-macro-gates2.stderr index 8eeca99ab3..a7f6f8bfb1 100644 --- a/src/test/ui/proc-macro/proc-macro-gates2.stderr +++ b/src/test/ui/proc-macro/proc-macro-gates2.stderr @@ -1,20 +1,20 @@ -error[E0658]: The attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/proc-macro-gates2.rs:12:11 | LL | fn _test6<#[empty_attr] T>() {} | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/proc-macro-gates2.rs:17:9 | LL | #[empty_attr] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/reserved-macro-names.rs b/src/test/ui/proc-macro/reserved-macro-names.rs index 7c66af172f..9f56eccb7a 100644 --- a/src/test/ui/proc-macro/reserved-macro-names.rs +++ b/src/test/ui/proc-macro/reserved-macro-names.rs @@ -8,18 +8,18 @@ use proc_macro::*; #[proc_macro_attribute] pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream { - //~^ ERROR name `cfg` is reserved in macro namespace + //~^ ERROR name `cfg` is reserved in attribute namespace input } #[proc_macro_attribute] pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream { - //~^ ERROR name `cfg_attr` is reserved in macro namespace + //~^ ERROR name `cfg_attr` is reserved in attribute namespace input } #[proc_macro_attribute] pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream { - //~^ ERROR name `derive` is reserved in macro namespace + //~^ ERROR name `derive` is reserved in attribute namespace input } diff --git a/src/test/ui/proc-macro/reserved-macro-names.stderr b/src/test/ui/proc-macro/reserved-macro-names.stderr index 5ebe62a496..f871e43ce5 100644 --- a/src/test/ui/proc-macro/reserved-macro-names.stderr +++ b/src/test/ui/proc-macro/reserved-macro-names.stderr @@ -1,16 +1,16 @@ -error: name `cfg` is reserved in macro namespace +error: name `cfg` is reserved in attribute namespace --> $DIR/reserved-macro-names.rs:10:8 | LL | pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream { | ^^^ -error: name `cfg_attr` is reserved in macro namespace +error: name `cfg_attr` is reserved in attribute namespace --> $DIR/reserved-macro-names.rs:16:8 | LL | pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream { | ^^^^^^^^ -error: name `derive` is reserved in macro namespace +error: name `derive` is reserved in attribute namespace --> $DIR/reserved-macro-names.rs:22:8 | LL | pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream { diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs index 1298c08df8..0a7861aba6 100644 --- a/src/test/ui/proc-macro/resolve-error.rs +++ b/src/test/ui/proc-macro/resolve-error.rs @@ -24,11 +24,11 @@ macro_rules! attr_proc_mac { struct Foo; // Interpreted as a feature gated custom attribute -#[attr_proc_macra] //~ ERROR attribute `attr_proc_macra` is currently unknown +#[attr_proc_macra] //~ ERROR cannot find attribute macro `attr_proc_macra` in this scope struct Bar; // Interpreted as a feature gated custom attribute -#[FooWithLongNan] //~ ERROR attribute `FooWithLongNan` is currently unknown +#[FooWithLongNan] //~ ERROR cannot find attribute macro `FooWithLongNan` in this scope struct Asdf; #[derive(Dlone)] diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index f9f116c15d..3c9b2baacb 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,38 +1,32 @@ -error[E0658]: The attribute `attr_proc_macra` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find derive macro `FooWithLongNan` in this scope + --> $DIR/resolve-error.rs:22:10 + | +LL | #[derive(FooWithLongNan)] + | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + +error: cannot find attribute macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:27:3 | LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` -error[E0658]: The attribute `FooWithLongNan` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:31:3 | LL | #[FooWithLongNan] | ^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable - -error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:22:10 - | -LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:34:10 | LL | #[derive(Dlone)] - | ^^^^^ help: try: `Clone` + | ^^^^^ help: a derive macro with a similar name exists: `Clone` error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:38:10 | LL | #[derive(Dlona)] - | ^^^^^ help: try: `Clona` + | ^^^^^ help: a derive macro with a similar name exists: `Clona` error: cannot find derive macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:42:10 @@ -44,13 +38,13 @@ error: cannot find macro `FooWithLongNama!` in this scope --> $DIR/resolve-error.rs:47:5 | LL | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam` + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` error: cannot find macro `attr_proc_macra!` in this scope --> $DIR/resolve-error.rs:50:5 | LL | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac` + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` error: cannot find macro `Dlona!` in this scope --> $DIR/resolve-error.rs:53:5 @@ -62,8 +56,7 @@ error: cannot find macro `bang_proc_macrp!` in this scope --> $DIR/resolve-error.rs:56:5 | LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro` + | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/proc-macro/smoke.rs b/src/test/ui/proc-macro/smoke.rs similarity index 95% rename from src/test/run-pass/proc-macro/smoke.rs rename to src/test/ui/proc-macro/smoke.rs index 26fbce3ebf..04625559b9 100644 --- a/src/test/run-pass/proc-macro/smoke.rs +++ b/src/test/ui/proc-macro/smoke.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(path_statements)] // aux-build:derive-a.rs diff --git a/src/test/run-pass/proc-macro/span-api-tests.rs b/src/test/ui/proc-macro/span-api-tests.rs similarity index 99% rename from src/test/run-pass/proc-macro/span-api-tests.rs rename to src/test/ui/proc-macro/span-api-tests.rs index 9b977b8fa7..3667e14c9e 100644 --- a/src/test/run-pass/proc-macro/span-api-tests.rs +++ b/src/test/ui/proc-macro/span-api-tests.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:span-api-tests.rs // aux-build:span-test-macros.rs diff --git a/src/test/run-pass/proc-macro/struct-field-macro.rs b/src/test/ui/proc-macro/struct-field-macro.rs similarity index 93% rename from src/test/run-pass/proc-macro/struct-field-macro.rs rename to src/test/ui/proc-macro/struct-field-macro.rs index 58663cc6c3..460f4d9f72 100644 --- a/src/test/run-pass/proc-macro/struct-field-macro.rs +++ b/src/test/ui/proc-macro/struct-field-macro.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // aux-build:derive-nothing.rs diff --git a/src/test/run-pass/proc_macro.rs b/src/test/ui/proc_macro.rs similarity index 98% rename from src/test/run-pass/proc_macro.rs rename to src/test/ui/proc_macro.rs index afdf2b8baa..7ff9464900 100644 --- a/src/test/run-pass/proc_macro.rs +++ b/src/test/ui/proc_macro.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:proc_macro_def.rs // ignore-cross-compile diff --git a/src/test/run-pass/process/process-envs.rs b/src/test/ui/process/process-envs.rs similarity index 98% rename from src/test/run-pass/process/process-envs.rs rename to src/test/ui/process/process-envs.rs index a7779c55f1..62a4733f89 100644 --- a/src/test/run-pass/process/process-envs.rs +++ b/src/test/ui/process/process-envs.rs @@ -2,6 +2,7 @@ // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes +// ignore-vxworks no 'env' use std::process::Command; use std::env; diff --git a/src/test/run-pass/process/process-exit.rs b/src/test/ui/process/process-exit.rs similarity index 100% rename from src/test/run-pass/process/process-exit.rs rename to src/test/ui/process/process-exit.rs diff --git a/src/test/run-pass/process/process-remove-from-env.rs b/src/test/ui/process/process-remove-from-env.rs similarity index 97% rename from src/test/run-pass/process/process-remove-from-env.rs rename to src/test/ui/process/process-remove-from-env.rs index 32cbb6ac85..3fee9e2abb 100644 --- a/src/test/run-pass/process/process-remove-from-env.rs +++ b/src/test/ui/process/process-remove-from-env.rs @@ -2,6 +2,7 @@ // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes +// ignore-vxworks no 'env' use std::process::Command; use std::env; diff --git a/src/test/run-pass/process/process-sigpipe.rs b/src/test/ui/process/process-sigpipe.rs similarity index 97% rename from src/test/run-pass/process/process-sigpipe.rs rename to src/test/ui/process/process-sigpipe.rs index bf58909600..36303440ee 100644 --- a/src/test/run-pass/process/process-sigpipe.rs +++ b/src/test/ui/process/process-sigpipe.rs @@ -14,6 +14,7 @@ // ignore-cloudabi no subprocesses support // ignore-emscripten no threads support +// ignore-vxworks no 'sh' use std::process; use std::thread; diff --git a/src/test/run-pass/process/process-spawn-nonexistent.rs b/src/test/ui/process/process-spawn-nonexistent.rs similarity index 100% rename from src/test/run-pass/process/process-spawn-nonexistent.rs rename to src/test/ui/process/process-spawn-nonexistent.rs diff --git a/src/test/run-pass/process/process-spawn-with-unicode-params.rs b/src/test/ui/process/process-spawn-with-unicode-params.rs similarity index 100% rename from src/test/run-pass/process/process-spawn-with-unicode-params.rs rename to src/test/ui/process/process-spawn-with-unicode-params.rs diff --git a/src/test/run-pass/process/process-status-inherits-stdin.rs b/src/test/ui/process/process-status-inherits-stdin.rs similarity index 100% rename from src/test/run-pass/process/process-status-inherits-stdin.rs rename to src/test/ui/process/process-status-inherits-stdin.rs diff --git a/src/test/run-pass/project-cache-issue-31849.rs b/src/test/ui/project-cache-issue-31849.rs similarity index 99% rename from src/test/run-pass/project-cache-issue-31849.rs rename to src/test/ui/project-cache-issue-31849.rs index 4920678af1..07fb6abaea 100644 --- a/src/test/run-pass/project-cache-issue-31849.rs +++ b/src/test/ui/project-cache-issue-31849.rs @@ -1,3 +1,4 @@ +// run-pass // Regression test for #31849: the problem here was actually a performance // cliff, but I'm adding the test for reference. diff --git a/src/test/run-pass/project-cache-issue-37154.rs b/src/test/ui/project-cache-issue-37154.rs similarity index 97% rename from src/test/run-pass/project-cache-issue-37154.rs rename to src/test/ui/project-cache-issue-37154.rs index 8b07b9c98a..b10239c22d 100644 --- a/src/test/run-pass/project-cache-issue-37154.rs +++ b/src/test/ui/project-cache-issue-37154.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Regression test for #37154: the problem here was that the cache // results in a false error because it was caching placeholder results diff --git a/src/test/run-pass/project-defer-unification.rs b/src/test/ui/project-defer-unification.rs similarity index 99% rename from src/test/run-pass/project-defer-unification.rs rename to src/test/ui/project-defer-unification.rs index 548c4d29cb..547ff45c22 100644 --- a/src/test/run-pass/project-defer-unification.rs +++ b/src/test/ui/project-defer-unification.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_variables)] #![allow(unreachable_code)] diff --git a/src/test/run-pass/ptr-coercion.rs b/src/test/ui/ptr-coercion-rpass.rs similarity index 97% rename from src/test/run-pass/ptr-coercion.rs rename to src/test/ui/ptr-coercion-rpass.rs index 0dd2b5467d..1c3ce33039 100644 --- a/src/test/run-pass/ptr-coercion.rs +++ b/src/test/ui/ptr-coercion-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] // Test coercions between pointers which don't do anything fancy like unsizing. diff --git a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr index 61c148bf2d..0b44c5a652 100644 --- a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr +++ b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr @@ -4,7 +4,7 @@ error: extern crate `core` is private, and cannot be re-exported (error E0365), LL | pub use core as reexported_core; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[deny(pub_use_of_private_extern_crate)] on by default + = note: `#[deny(pub_use_of_private_extern_crate)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 diff --git a/src/test/run-pass/pure-sum.rs b/src/test/ui/pure-sum.rs similarity index 98% rename from src/test/run-pass/pure-sum.rs rename to src/test/ui/pure-sum.rs index d000c8488a..2ff6f935a0 100644 --- a/src/test/run-pass/pure-sum.rs +++ b/src/test/ui/pure-sum.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Check that functions can modify local state. diff --git a/src/test/run-pass/purity-infer.rs b/src/test/ui/purity-infer.rs similarity index 88% rename from src/test/run-pass/purity-infer.rs rename to src/test/ui/purity-infer.rs index 3b2b418601..dc0eb89bfa 100644 --- a/src/test/run-pass/purity-infer.rs +++ b/src/test/ui/purity-infer.rs @@ -1,3 +1,5 @@ +// run-pass + fn something(f: F) where F: FnOnce() { f(); } pub fn main() { something(|| println!("hi!") ); diff --git a/src/test/run-pass/range-type-infer.rs b/src/test/ui/range-type-infer.rs similarity index 97% rename from src/test/run-pass/range-type-infer.rs rename to src/test/ui/range-type-infer.rs index 777286d855..f07c041717 100644 --- a/src/test/run-pass/range-type-infer.rs +++ b/src/test/ui/range-type-infer.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] // Make sure the type inference for the new range expression work as // good as the old one. Check out issue #21672, #21595 and #21649 for diff --git a/src/test/run-pass/range.rs b/src/test/ui/range.rs similarity index 98% rename from src/test/run-pass/range.rs rename to src/test/ui/range.rs index a3667d8761..82983e37ea 100644 --- a/src/test/run-pass/range.rs +++ b/src/test/ui/range.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_comparisons)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/src/test/ui/range/range_traits-4.rs b/src/test/ui/range/range_traits-4.rs index 52c706080f..b8e88559b1 100644 --- a/src/test/ui/range/range_traits-4.rs +++ b/src/test/ui/range/range_traits-4.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::*; diff --git a/src/test/ui/range/range_traits-5.rs b/src/test/ui/range/range_traits-5.rs index a8c3e9b0d6..4aec7a4159 100644 --- a/src/test/ui/range/range_traits-5.rs +++ b/src/test/ui/range/range_traits-5.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::*; diff --git a/src/test/ui/range/range_traits-7.rs b/src/test/ui/range/range_traits-7.rs index 548676063c..c7b310562d 100644 --- a/src/test/ui/range/range_traits-7.rs +++ b/src/test/ui/range/range_traits-7.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::*; diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/ui/range_inclusive.rs similarity index 99% rename from src/test/run-pass/range_inclusive.rs rename to src/test/ui/range_inclusive.rs index 31c3c39403..68d9bf7d26 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/ui/range_inclusive.rs @@ -1,3 +1,4 @@ +// run-pass // Test inclusive range syntax. #![feature(range_is_empty)] diff --git a/src/test/run-pass/range_inclusive_gate.rs b/src/test/ui/range_inclusive_gate.rs similarity index 96% rename from src/test/run-pass/range_inclusive_gate.rs rename to src/test/ui/range_inclusive_gate.rs index d4d830ef22..e26e31b44a 100644 --- a/src/test/run-pass/range_inclusive_gate.rs +++ b/src/test/ui/range_inclusive_gate.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_comparisons)] // Test that you only need the syntax gate if you don't mention the structs. // (Obsoleted since both features are stabilized) diff --git a/src/test/run-pass/ranges-precedence.rs b/src/test/ui/ranges-precedence.rs similarity index 98% rename from src/test/run-pass/ranges-precedence.rs rename to src/test/ui/ranges-precedence.rs index 86862993d4..db241ed0cc 100644 --- a/src/test/run-pass/ranges-precedence.rs +++ b/src/test/ui/ranges-precedence.rs @@ -1,3 +1,4 @@ +// run-pass // Test that the precedence of ranges is correct diff --git a/src/test/run-pass/raw-fat-ptr.rs b/src/test/ui/raw-fat-ptr.rs similarity index 99% rename from src/test/run-pass/raw-fat-ptr.rs rename to src/test/ui/raw-fat-ptr.rs index 511a35b25a..9f50659ed6 100644 --- a/src/test/run-pass/raw-fat-ptr.rs +++ b/src/test/ui/raw-fat-ptr.rs @@ -1,3 +1,4 @@ +// run-pass // check raw fat pointer ops use std::mem; diff --git a/src/test/run-pass/raw-str.rs b/src/test/ui/raw-str.rs similarity index 98% rename from src/test/run-pass/raw-str.rs rename to src/test/ui/raw-str.rs index 8861ec3f85a1162351daad71b8dcfe2df1e1599f..0916dddbb7be66fce440a30d4afde4678005f948 100644 GIT binary patch delta 20 bcmX@icAkw#Utgi9G*7o6vACFPgEKP#M1lrl delta 8 PcmX@lc9?A=k25m>4$A_f diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/ui/rcvr-borrowed-to-region.rs similarity index 97% rename from src/test/run-pass/rcvr-borrowed-to-region.rs rename to src/test/ui/rcvr-borrowed-to-region.rs index b1b2535897..37113bc0a0 100644 --- a/src/test/run-pass/rcvr-borrowed-to-region.rs +++ b/src/test/ui/rcvr-borrowed-to-region.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![feature(box_syntax)] diff --git a/src/test/run-pass/reachable-unnameable-items.rs b/src/test/ui/reachable-unnameable-items.rs similarity index 99% rename from src/test/run-pass/reachable-unnameable-items.rs rename to src/test/ui/reachable-unnameable-items.rs index a745404740..f1e53a0d8b 100644 --- a/src/test/run-pass/reachable-unnameable-items.rs +++ b/src/test/ui/reachable-unnameable-items.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare compiled with panic=abort by default // aux-build:reachable-unnameable-items.rs diff --git a/src/test/run-pass/reachable-unnameable-type-alias.rs b/src/test/ui/reachable-unnameable-type-alias.rs similarity index 96% rename from src/test/run-pass/reachable-unnameable-type-alias.rs rename to src/test/ui/reachable-unnameable-type-alias.rs index a632ce186e..461355f87c 100644 --- a/src/test/run-pass/reachable-unnameable-type-alias.rs +++ b/src/test/ui/reachable-unnameable-type-alias.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(staged_api)] #![stable(feature = "a", since = "b")] diff --git a/src/test/ui/reachable/expr_andand.rs b/src/test/ui/reachable/expr_andand.rs index 173116ae35..d37eb0a3b8 100644 --- a/src/test/ui/reachable/expr_andand.rs +++ b/src/test/ui/reachable/expr_andand.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_oror.rs b/src/test/ui/reachable/expr_oror.rs index ecfa072aa8..e95062de4d 100644 --- a/src/test/ui/reachable/expr_oror.rs +++ b/src/test/ui/reachable/expr_oror.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs index 36a3e3dd96..10a4b69939 100644 --- a/src/test/ui/reachable/expr_while.rs +++ b/src/test/ui/reachable/expr_while.rs @@ -5,8 +5,8 @@ fn foo() { while {return} { + //~^ ERROR unreachable block in `while` expression println!("Hello, world!"); - //~^ ERROR unreachable } } @@ -20,11 +20,10 @@ fn bar() { fn baz() { // Here, we cite the `while` loop as dead. while {return} { + //~^ ERROR unreachable block in `while` expression println!("I am dead."); - //~^ ERROR unreachable } println!("I am, too."); - //~^ ERROR unreachable } fn main() { } diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr index d2f5588568..fc528926b4 100644 --- a/src/test/ui/reachable/expr_while.stderr +++ b/src/test/ui/reachable/expr_while.stderr @@ -1,31 +1,28 @@ -error: unreachable statement - --> $DIR/expr_while.rs:8:9 +error: unreachable block in `while` expression + --> $DIR/expr_while.rs:7:20 | -LL | println!("Hello, world!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | while {return} { + | ____________________^ +LL | | +LL | | println!("Hello, world!"); +LL | | } + | |_____^ | note: lint level defined here --> $DIR/expr_while.rs:4:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: unreachable statement - --> $DIR/expr_while.rs:23:9 +error: unreachable block in `while` expression + --> $DIR/expr_while.rs:22:20 | -LL | println!("I am dead."); - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -error: unreachable statement - --> $DIR/expr_while.rs:26:5 - | -LL | println!("I am, too."); - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) +LL | while {return} { + | ____________________^ +LL | | +LL | | println!("I am dead."); +LL | | } + | |_____^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/src/test/run-pass/readalias.rs b/src/test/ui/readalias.rs similarity index 93% rename from src/test/run-pass/readalias.rs rename to src/test/ui/readalias.rs index 444d447123..a6bf61803c 100644 --- a/src/test/run-pass/readalias.rs +++ b/src/test/ui/readalias.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] diff --git a/src/test/run-pass/realloc-16687.rs b/src/test/ui/realloc-16687.rs similarity index 99% rename from src/test/run-pass/realloc-16687.rs rename to src/test/ui/realloc-16687.rs index e283d5b6de..69292d241c 100644 --- a/src/test/run-pass/realloc-16687.rs +++ b/src/test/ui/realloc-16687.rs @@ -1,3 +1,4 @@ +// run-pass // alloc::heap::reallocate test. // // Ideally this would be revised to use no_std, but for now it serves diff --git a/src/test/ui/recursion/recursive-reexports.rs b/src/test/ui/recursion/recursive-reexports.rs index 3d9fda35c6..0e17f22511 100644 --- a/src/test/ui/recursion/recursive-reexports.rs +++ b/src/test/ui/recursion/recursive-reexports.rs @@ -2,6 +2,6 @@ extern crate recursive_reexports; -fn f() -> recursive_reexports::S {} //~ ERROR cannot find type `S` in module `recursive_reexports` +fn f() -> recursive_reexports::S {} //~ ERROR cannot find type `S` in crate `recursive_reexports` fn main() {} diff --git a/src/test/ui/recursion/recursive-reexports.stderr b/src/test/ui/recursion/recursive-reexports.stderr index 01afc1458a..f39d0a0d5e 100644 --- a/src/test/ui/recursion/recursive-reexports.stderr +++ b/src/test/ui/recursion/recursive-reexports.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `S` in module `recursive_reexports` +error[E0412]: cannot find type `S` in crate `recursive_reexports` --> $DIR/recursive-reexports.rs:5:32 | LL | fn f() -> recursive_reexports::S {} diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr deleted file mode 100644 index eee331d95b..0000000000 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/recursive-types-are-not-uninhabited.rs:6:9 - | -LL | let Ok(x) = res; - | ^^^^^ pattern `Err(_)` not covered - -error[E0381]: use of possibly uninitialized variable: `x` - --> $DIR/recursive-types-are-not-uninhabited.rs:8:5 - | -LL | x - | ^ use of possibly uninitialized `x` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0005, E0381. -For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs index a618aba941..45910c3c3a 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs @@ -6,9 +6,7 @@ fn foo(res: Result) -> u32 { let Ok(x) = res; //~^ ERROR refutable pattern x - //~^ WARN use of possibly uninitialized variable: `x` - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will + //~^ ERROR use of possibly uninitialized variable: `x` } fn main() { diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index 9203f893fd..eee331d95b 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -4,17 +4,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered LL | let Ok(x) = res; | ^^^^^ pattern `Err(_)` not covered -warning[E0381]: use of possibly uninitialized variable: `x` +error[E0381]: use of possibly uninitialized variable: `x` --> $DIR/recursive-types-are-not-uninhabited.rs:8:5 | LL | x | ^ use of possibly uninitialized `x` - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -error: aborting due to previous error +error: aborting due to 2 previous errors Some errors have detailed explanations: E0005, E0381. For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/run-pass/reexport-should-still-link.rs b/src/test/ui/reexport-should-still-link.rs similarity index 93% rename from src/test/run-pass/reexport-should-still-link.rs rename to src/test/ui/reexport-should-still-link.rs index 733f8f9c1f..913da56a18 100644 --- a/src/test/run-pass/reexport-should-still-link.rs +++ b/src/test/ui/reexport-should-still-link.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:reexport-should-still-link.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/reexport-star.rs b/src/test/ui/reexport-star.rs similarity index 92% rename from src/test/run-pass/reexport-star.rs rename to src/test/ui/reexport-star.rs index ae48f97a9d..639ab1a0f3 100644 --- a/src/test/run-pass/reexport-star.rs +++ b/src/test/ui/reexport-star.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 mod a { diff --git a/src/test/run-pass/reexport-test-harness-main.rs b/src/test/ui/reexport-test-harness-main.rs similarity index 94% rename from src/test/run-pass/reexport-test-harness-main.rs rename to src/test/ui/reexport-test-harness-main.rs index 5171c1c173..2582975e21 100644 --- a/src/test/run-pass/reexport-test-harness-main.rs +++ b/src/test/ui/reexport-test-harness-main.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags:--test #![reexport_test_harness_main = "test_main"] diff --git a/src/test/run-pass/refer-to-other-statics-by-value.rs b/src/test/ui/refer-to-other-statics-by-value.rs similarity index 86% rename from src/test/run-pass/refer-to-other-statics-by-value.rs rename to src/test/ui/refer-to-other-statics-by-value.rs index e08700c57c..90f1980f85 100644 --- a/src/test/run-pass/refer-to-other-statics-by-value.rs +++ b/src/test/ui/refer-to-other-statics-by-value.rs @@ -1,3 +1,5 @@ +// run-pass + static A: usize = 42; static B: usize = A; diff --git a/src/test/ui/refutable-pattern-errors.rs b/src/test/ui/refutable-pattern-errors.rs index 05db247288..aa5fa76bb8 100644 --- a/src/test/ui/refutable-pattern-errors.rs +++ b/src/test/ui/refutable-pattern-errors.rs @@ -3,5 +3,5 @@ fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) { } fn main() { let (1, (Some(1), 2..=3)) = (1, (None, 2)); - //~^ ERROR refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered + //~^ ERROR refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` not covered } diff --git a/src/test/ui/refutable-pattern-errors.stderr b/src/test/ui/refutable-pattern-errors.stderr index b7001e34d5..c67ae7c6d4 100644 --- a/src/test/ui/refutable-pattern-errors.stderr +++ b/src/test/ui/refutable-pattern-errors.stderr @@ -4,11 +4,11 @@ error[E0005]: refutable pattern in function argument: `(_, _)` not covered LL | fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) { } | ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered -error[E0005]: refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered +error[E0005]: refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` not covered --> $DIR/refutable-pattern-errors.rs:5:9 | LL | let (1, (Some(1), 2..=3)) = (1, (None, 2)); - | ^^^^^^^^^^^^^^^^^^^^^ pattern `(-2147483648i32..=0i32, _)` not covered + | ^^^^^^^^^^^^^^^^^^^^^ pattern `(std::i32::MIN..=0i32, _)` not covered error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs index 5cbfe6ebeb..ee9e7a364b 100644 --- a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs +++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs @@ -8,7 +8,7 @@ // follow the same lifetime-elision rules used elsehwere. See // rust-lang/rust#56537 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str { let free_dumb = |_x| { p }; // no type annotation at all diff --git a/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs b/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs index d6b36af9bd..49de70ae01 100644 --- a/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs +++ b/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs @@ -1,7 +1,7 @@ // Test related to #22779. In this case, the impl is an inherent impl, // so it doesn't have to match any trait, so no error results. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct MySlice<'a, T:'a>(&'a mut [T]); diff --git a/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr b/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr index d455902ee8..c720b26aa0 100644 --- a/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr +++ b/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr @@ -7,7 +7,7 @@ LL | LL | (|x| f(x))(call_rec(f)) | ----------- recursive call site | - = note: #[warn(unconditional_recursion)] on by default + = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose error[E0505]: cannot move out of `f` because it is borrowed diff --git a/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs b/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs index deef9ab15b..4ce5daf384 100644 --- a/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs +++ b/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs @@ -1,7 +1,7 @@ // Test related to #22779, but where the `'a:'b` relation // appears in the trait too. No error here. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Tr<'a, T> { fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b; diff --git a/src/test/ui/regions/region-object-lifetime-1.rs b/src/test/ui/regions/region-object-lifetime-1.rs index ab24eda2c2..e58bd31d9c 100644 --- a/src/test/ui/regions/region-object-lifetime-1.rs +++ b/src/test/ui/regions/region-object-lifetime-1.rs @@ -1,7 +1,7 @@ // Various tests related to testing how region inference works // with respect to the object receivers. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] trait Foo { diff --git a/src/test/ui/regions/region-object-lifetime-3.rs b/src/test/ui/regions/region-object-lifetime-3.rs index cda4834706..c3c7c51767 100644 --- a/src/test/ui/regions/region-object-lifetime-3.rs +++ b/src/test/ui/regions/region-object-lifetime-3.rs @@ -1,7 +1,7 @@ // Various tests related to testing how region inference works // with respect to the object receivers. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] trait Foo { diff --git a/src/test/run-pass/regions/regions-addr-of-interior-of-unique-box.rs b/src/test/ui/regions/regions-addr-of-interior-of-unique-box.rs similarity index 100% rename from src/test/run-pass/regions/regions-addr-of-interior-of-unique-box.rs rename to src/test/ui/regions/regions-addr-of-interior-of-unique-box.rs diff --git a/src/test/run-pass/regions/regions-addr-of-ret.rs b/src/test/ui/regions/regions-addr-of-ret.rs similarity index 100% rename from src/test/run-pass/regions/regions-addr-of-ret.rs rename to src/test/ui/regions/regions-addr-of-ret.rs diff --git a/src/test/run-pass/regions/regions-assoc-type-region-bound.rs b/src/test/ui/regions/regions-assoc-type-region-bound.rs similarity index 100% rename from src/test/run-pass/regions/regions-assoc-type-region-bound.rs rename to src/test/ui/regions/regions-assoc-type-region-bound.rs diff --git a/src/test/run-pass/regions/regions-assoc-type-static-bound.rs b/src/test/ui/regions/regions-assoc-type-static-bound.rs similarity index 100% rename from src/test/run-pass/regions/regions-assoc-type-static-bound.rs rename to src/test/ui/regions/regions-assoc-type-static-bound.rs diff --git a/src/test/run-pass/regions/regions-borrow-at.rs b/src/test/ui/regions/regions-borrow-at.rs similarity index 100% rename from src/test/run-pass/regions/regions-borrow-at.rs rename to src/test/ui/regions/regions-borrow-at.rs diff --git a/src/test/run-pass/regions/regions-borrow-evec-fixed.rs b/src/test/ui/regions/regions-borrow-evec-fixed.rs similarity index 100% rename from src/test/run-pass/regions/regions-borrow-evec-fixed.rs rename to src/test/ui/regions/regions-borrow-evec-fixed.rs diff --git a/src/test/run-pass/regions/regions-borrow-evec-uniq.rs b/src/test/ui/regions/regions-borrow-evec-uniq.rs similarity index 100% rename from src/test/run-pass/regions/regions-borrow-evec-uniq.rs rename to src/test/ui/regions/regions-borrow-evec-uniq.rs diff --git a/src/test/run-pass/regions/regions-borrow-uniq.rs b/src/test/ui/regions/regions-borrow-uniq.rs similarity index 100% rename from src/test/run-pass/regions/regions-borrow-uniq.rs rename to src/test/ui/regions/regions-borrow-uniq.rs diff --git a/src/test/run-pass/regions/regions-bot.rs b/src/test/ui/regions/regions-bot.rs similarity index 100% rename from src/test/run-pass/regions/regions-bot.rs rename to src/test/ui/regions/regions-bot.rs diff --git a/src/test/run-pass/regions/regions-bound-lists-feature-gate-2.rs b/src/test/ui/regions/regions-bound-lists-feature-gate-2.rs similarity index 100% rename from src/test/run-pass/regions/regions-bound-lists-feature-gate-2.rs rename to src/test/ui/regions/regions-bound-lists-feature-gate-2.rs diff --git a/src/test/run-pass/regions/regions-bound-lists-feature-gate.rs b/src/test/ui/regions/regions-bound-lists-feature-gate.rs similarity index 100% rename from src/test/run-pass/regions/regions-bound-lists-feature-gate.rs rename to src/test/ui/regions/regions-bound-lists-feature-gate.rs diff --git a/src/test/run-pass/regions/regions-close-over-type-parameter-successfully.rs b/src/test/ui/regions/regions-close-over-type-parameter-successfully.rs similarity index 100% rename from src/test/run-pass/regions/regions-close-over-type-parameter-successfully.rs rename to src/test/ui/regions/regions-close-over-type-parameter-successfully.rs diff --git a/src/test/run-pass/regions/regions-copy-closure.rs b/src/test/ui/regions/regions-copy-closure.rs similarity index 100% rename from src/test/run-pass/regions/regions-copy-closure.rs rename to src/test/ui/regions/regions-copy-closure.rs diff --git a/src/test/run-pass/regions/regions-creating-enums2.rs b/src/test/ui/regions/regions-creating-enums2.rs similarity index 100% rename from src/test/run-pass/regions/regions-creating-enums2.rs rename to src/test/ui/regions/regions-creating-enums2.rs diff --git a/src/test/run-pass/regions/regions-creating-enums5.rs b/src/test/ui/regions/regions-creating-enums5.rs similarity index 100% rename from src/test/run-pass/regions/regions-creating-enums5.rs rename to src/test/ui/regions/regions-creating-enums5.rs diff --git a/src/test/run-pass/regions/regions-debruijn-of-object.rs b/src/test/ui/regions/regions-debruijn-of-object.rs similarity index 100% rename from src/test/run-pass/regions/regions-debruijn-of-object.rs rename to src/test/ui/regions/regions-debruijn-of-object.rs diff --git a/src/test/run-pass/regions/regions-dependent-addr-of.rs b/src/test/ui/regions/regions-dependent-addr-of.rs similarity index 100% rename from src/test/run-pass/regions/regions-dependent-addr-of.rs rename to src/test/ui/regions/regions-dependent-addr-of.rs diff --git a/src/test/run-pass/regions/regions-dependent-autofn.rs b/src/test/ui/regions/regions-dependent-autofn.rs similarity index 100% rename from src/test/run-pass/regions/regions-dependent-autofn.rs rename to src/test/ui/regions/regions-dependent-autofn.rs diff --git a/src/test/run-pass/regions/regions-dependent-autoslice.rs b/src/test/ui/regions/regions-dependent-autoslice.rs similarity index 100% rename from src/test/run-pass/regions/regions-dependent-autoslice.rs rename to src/test/ui/regions/regions-dependent-autoslice.rs diff --git a/src/test/run-pass/regions/regions-dependent-let-ref.rs b/src/test/ui/regions/regions-dependent-let-ref.rs similarity index 100% rename from src/test/run-pass/regions/regions-dependent-let-ref.rs rename to src/test/ui/regions/regions-dependent-let-ref.rs diff --git a/src/test/run-pass/regions/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs similarity index 100% rename from src/test/run-pass/regions/regions-early-bound-lifetime-in-assoc-fn.rs rename to src/test/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs diff --git a/src/test/run-pass/regions/regions-early-bound-trait-param.rs b/src/test/ui/regions/regions-early-bound-trait-param.rs similarity index 100% rename from src/test/run-pass/regions/regions-early-bound-trait-param.rs rename to src/test/ui/regions/regions-early-bound-trait-param.rs diff --git a/src/test/run-pass/regions/regions-early-bound-used-in-bound-method.rs b/src/test/ui/regions/regions-early-bound-used-in-bound-method.rs similarity index 100% rename from src/test/run-pass/regions/regions-early-bound-used-in-bound-method.rs rename to src/test/ui/regions/regions-early-bound-used-in-bound-method.rs diff --git a/src/test/run-pass/regions/regions-early-bound-used-in-bound.rs b/src/test/ui/regions/regions-early-bound-used-in-bound.rs similarity index 100% rename from src/test/run-pass/regions/regions-early-bound-used-in-bound.rs rename to src/test/ui/regions/regions-early-bound-used-in-bound.rs diff --git a/src/test/run-pass/regions/regions-early-bound-used-in-type-param.rs b/src/test/ui/regions/regions-early-bound-used-in-type-param.rs similarity index 100% rename from src/test/run-pass/regions/regions-early-bound-used-in-type-param.rs rename to src/test/ui/regions/regions-early-bound-used-in-type-param.rs diff --git a/src/test/run-pass/regions/regions-escape-into-other-fn.rs b/src/test/ui/regions/regions-escape-into-other-fn.rs similarity index 100% rename from src/test/run-pass/regions/regions-escape-into-other-fn.rs rename to src/test/ui/regions/regions-escape-into-other-fn.rs diff --git a/src/test/run-pass/regions/regions-expl-self.rs b/src/test/ui/regions/regions-expl-self.rs similarity index 100% rename from src/test/run-pass/regions/regions-expl-self.rs rename to src/test/ui/regions/regions-expl-self.rs diff --git a/src/test/run-pass/regions/regions-fn-subtyping-2.rs b/src/test/ui/regions/regions-fn-subtyping-2.rs similarity index 100% rename from src/test/run-pass/regions/regions-fn-subtyping-2.rs rename to src/test/ui/regions/regions-fn-subtyping-2.rs diff --git a/src/test/run-pass/regions/regions-fn-subtyping.rs b/src/test/ui/regions/regions-fn-subtyping.rs similarity index 100% rename from src/test/run-pass/regions/regions-fn-subtyping.rs rename to src/test/ui/regions/regions-fn-subtyping.rs diff --git a/src/test/run-pass/regions/regions-free-region-outlives-static-outlives-free-region.rs b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs similarity index 100% rename from src/test/run-pass/regions/regions-free-region-outlives-static-outlives-free-region.rs rename to src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs index d407bee416..dcad2e81a5 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs @@ -2,7 +2,7 @@ // "projection gap": in this test, we know that `T: 'x`, and that is // enough to conclude that `T::Foo: 'x`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs index c19fa98e91..ff2e10804a 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs @@ -2,7 +2,7 @@ // "projection gap": in this test, we know that `T::Foo: 'x`, and that // is (naturally) enough to conclude that `T::Foo: 'x`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs index 7a19d17152..3596bf7e8c 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs @@ -2,7 +2,7 @@ // "projection gap": in this test, we know that `T: 'x`, and that // is (naturally) enough to conclude that `T: 'x`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/run-pass/regions/regions-infer-borrow-scope-addr-of.rs b/src/test/ui/regions/regions-infer-borrow-scope-addr-of.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-borrow-scope-addr-of.rs rename to src/test/ui/regions/regions-infer-borrow-scope-addr-of.rs diff --git a/src/test/run-pass/regions/regions-infer-borrow-scope-view.rs b/src/test/ui/regions/regions-infer-borrow-scope-view.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-borrow-scope-view.rs rename to src/test/ui/regions/regions-infer-borrow-scope-view.rs diff --git a/src/test/run-pass/regions/regions-infer-borrow-scope-within-loop-ok.rs b/src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-borrow-scope-within-loop-ok.rs rename to src/test/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs diff --git a/src/test/run-pass/regions/regions-infer-borrow-scope.rs b/src/test/ui/regions/regions-infer-borrow-scope.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-borrow-scope.rs rename to src/test/ui/regions/regions-infer-borrow-scope.rs diff --git a/src/test/run-pass/regions/regions-infer-call-2.rs b/src/test/ui/regions/regions-infer-call-2.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-call-2.rs rename to src/test/ui/regions/regions-infer-call-2.rs diff --git a/src/test/run-pass/regions/regions-infer-call.rs b/src/test/ui/regions/regions-infer-call.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-call.rs rename to src/test/ui/regions/regions-infer-call.rs diff --git a/src/test/run-pass/regions/regions-infer-contravariance-due-to-ret.rs b/src/test/ui/regions/regions-infer-contravariance-due-to-ret.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-contravariance-due-to-ret.rs rename to src/test/ui/regions/regions-infer-contravariance-due-to-ret.rs diff --git a/src/test/run-pass/regions/regions-infer-reborrow-ref-mut-recurse.rs b/src/test/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-reborrow-ref-mut-recurse.rs rename to src/test/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs diff --git a/src/test/run-pass/regions/regions-infer-region-in-fn-but-not-type.rs b/src/test/ui/regions/regions-infer-region-in-fn-but-not-type.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-region-in-fn-but-not-type.rs rename to src/test/ui/regions/regions-infer-region-in-fn-but-not-type.rs diff --git a/src/test/run-pass/regions/regions-infer-static-from-proc.rs b/src/test/ui/regions/regions-infer-static-from-proc.rs similarity index 100% rename from src/test/run-pass/regions/regions-infer-static-from-proc.rs rename to src/test/ui/regions/regions-infer-static-from-proc.rs diff --git a/src/test/run-pass/regions/regions-issue-21422.rs b/src/test/ui/regions/regions-issue-21422.rs similarity index 100% rename from src/test/run-pass/regions/regions-issue-21422.rs rename to src/test/ui/regions/regions-issue-21422.rs diff --git a/src/test/run-pass/regions/regions-issue-22246.rs b/src/test/ui/regions/regions-issue-22246.rs similarity index 100% rename from src/test/run-pass/regions/regions-issue-22246.rs rename to src/test/ui/regions/regions-issue-22246.rs diff --git a/src/test/run-pass/regions/regions-lifetime-nonfree-late-bound.rs b/src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs similarity index 100% rename from src/test/run-pass/regions/regions-lifetime-nonfree-late-bound.rs rename to src/test/ui/regions/regions-lifetime-nonfree-late-bound.rs diff --git a/src/test/run-pass/regions/regions-lifetime-static-items-enclosing-scopes.rs b/src/test/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs similarity index 100% rename from src/test/run-pass/regions/regions-lifetime-static-items-enclosing-scopes.rs rename to src/test/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs diff --git a/src/test/run-pass/regions/regions-link-fn-args.rs b/src/test/ui/regions/regions-link-fn-args.rs similarity index 100% rename from src/test/run-pass/regions/regions-link-fn-args.rs rename to src/test/ui/regions/regions-link-fn-args.rs diff --git a/src/test/run-pass/regions/regions-lub-ref-ref-rc.rs b/src/test/ui/regions/regions-lub-ref-ref-rc.rs similarity index 100% rename from src/test/run-pass/regions/regions-lub-ref-ref-rc.rs rename to src/test/ui/regions/regions-lub-ref-ref-rc.rs diff --git a/src/test/run-pass/regions/regions-mock-codegen.rs b/src/test/ui/regions/regions-mock-codegen.rs similarity index 100% rename from src/test/run-pass/regions/regions-mock-codegen.rs rename to src/test/ui/regions/regions-mock-codegen.rs diff --git a/src/test/run-pass/regions/regions-no-bound-in-argument-cleanup.rs b/src/test/ui/regions/regions-no-bound-in-argument-cleanup.rs similarity index 100% rename from src/test/run-pass/regions/regions-no-bound-in-argument-cleanup.rs rename to src/test/ui/regions/regions-no-bound-in-argument-cleanup.rs diff --git a/src/test/run-pass/regions/regions-no-variance-from-fn-generics.rs b/src/test/ui/regions/regions-no-variance-from-fn-generics.rs similarity index 100% rename from src/test/run-pass/regions/regions-no-variance-from-fn-generics.rs rename to src/test/ui/regions/regions-no-variance-from-fn-generics.rs diff --git a/src/test/run-pass/regions/regions-nullary-variant.rs b/src/test/ui/regions/regions-nullary-variant.rs similarity index 100% rename from src/test/run-pass/regions/regions-nullary-variant.rs rename to src/test/ui/regions/regions-nullary-variant.rs diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs index 045d289149..fc4d161840 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs index e087d65a5c..d716cb9c55 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs index 20b391c263..39eb0842d3 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -//compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs index 7f84441903..561cad790f 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs index 07daa35a80..e1287c34ba 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs index 59da5fb0dc..7f22ae23b8 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs index 096069c0ca..367f7a3020 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs index 3c8c4a1ef5..f780275b68 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-projection-hrtype.rs b/src/test/ui/regions/regions-outlives-projection-hrtype.rs index a6e976ebf8..e7fe7b6c16 100644 --- a/src/test/ui/regions/regions-outlives-projection-hrtype.rs +++ b/src/test/ui/regions/regions-outlives-projection-hrtype.rs @@ -5,7 +5,7 @@ // `'r` is bound, that leads to badness. This test checks that // everything works. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait TheTrait { diff --git a/src/test/ui/regions/regions-outlives-projection-trait-def.rs b/src/test/ui/regions/regions-outlives-projection-trait-def.rs index bad476d277..928ed4baaa 100644 --- a/src/test/ui/regions/regions-outlives-projection-trait-def.rs +++ b/src/test/ui/regions/regions-outlives-projection-trait-def.rs @@ -1,7 +1,7 @@ // Test that `>::Type: 'b`, where `trait Foo<'a> { Type: // 'a; }`, does not require that `F: 'b`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait SomeTrait<'a> { diff --git a/src/test/ui/regions/regions-outlives-scalar.rs b/src/test/ui/regions/regions-outlives-scalar.rs index ca012c4e1e..5d0ed99938 100644 --- a/src/test/ui/regions/regions-outlives-scalar.rs +++ b/src/test/ui/regions/regions-outlives-scalar.rs @@ -1,7 +1,7 @@ // Test that scalar values outlive all regions. // Rule OutlivesScalar from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo<'a> { diff --git a/src/test/run-pass/regions/regions-params.rs b/src/test/ui/regions/regions-params.rs similarity index 100% rename from src/test/run-pass/regions/regions-params.rs rename to src/test/ui/regions/regions-params.rs diff --git a/src/test/run-pass/regions/regions-reassign-let-bound-pointer.rs b/src/test/ui/regions/regions-reassign-let-bound-pointer.rs similarity index 100% rename from src/test/run-pass/regions/regions-reassign-let-bound-pointer.rs rename to src/test/ui/regions/regions-reassign-let-bound-pointer.rs diff --git a/src/test/run-pass/regions/regions-reassign-match-bound-pointer.rs b/src/test/ui/regions/regions-reassign-match-bound-pointer.rs similarity index 100% rename from src/test/run-pass/regions/regions-reassign-match-bound-pointer.rs rename to src/test/ui/regions/regions-reassign-match-bound-pointer.rs diff --git a/src/test/run-pass/regions/regions-refcell.rs b/src/test/ui/regions/regions-refcell.rs similarity index 100% rename from src/test/run-pass/regions/regions-refcell.rs rename to src/test/ui/regions/regions-refcell.rs diff --git a/src/test/run-pass/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs b/src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs similarity index 100% rename from src/test/run-pass/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs rename to src/test/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs diff --git a/src/test/run-pass/regions/regions-return-interior-of-option.rs b/src/test/ui/regions/regions-return-interior-of-option.rs similarity index 100% rename from src/test/run-pass/regions/regions-return-interior-of-option.rs rename to src/test/ui/regions/regions-return-interior-of-option.rs diff --git a/src/test/run-pass/regions/regions-scope-chain-example.rs b/src/test/ui/regions/regions-scope-chain-example.rs similarity index 100% rename from src/test/run-pass/regions/regions-scope-chain-example.rs rename to src/test/ui/regions/regions-scope-chain-example.rs diff --git a/src/test/run-pass/regions/regions-self-impls.rs b/src/test/ui/regions/regions-self-impls.rs similarity index 100% rename from src/test/run-pass/regions/regions-self-impls.rs rename to src/test/ui/regions/regions-self-impls.rs diff --git a/src/test/run-pass/regions/regions-self-in-enums.rs b/src/test/ui/regions/regions-self-in-enums.rs similarity index 100% rename from src/test/run-pass/regions/regions-self-in-enums.rs rename to src/test/ui/regions/regions-self-in-enums.rs diff --git a/src/test/run-pass/regions/regions-simple.rs b/src/test/ui/regions/regions-simple.rs similarity index 100% rename from src/test/run-pass/regions/regions-simple.rs rename to src/test/ui/regions/regions-simple.rs diff --git a/src/test/run-pass/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound-rpass.rs similarity index 100% rename from src/test/run-pass/regions/regions-static-bound.rs rename to src/test/ui/regions/regions-static-bound-rpass.rs diff --git a/src/test/run-pass/regions/regions-static-closure.rs b/src/test/ui/regions/regions-static-closure.rs similarity index 100% rename from src/test/run-pass/regions/regions-static-closure.rs rename to src/test/ui/regions/regions-static-closure.rs diff --git a/src/test/run-pass/regions/regions-trait-object-1.rs b/src/test/ui/regions/regions-trait-object-1.rs similarity index 100% rename from src/test/run-pass/regions/regions-trait-object-1.rs rename to src/test/ui/regions/regions-trait-object-1.rs diff --git a/src/test/run-pass/regions/regions-variance-contravariant-use-contravariant.rs b/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs similarity index 100% rename from src/test/run-pass/regions/regions-variance-contravariant-use-contravariant.rs rename to src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs diff --git a/src/test/run-pass/regions/regions-variance-covariant-use-covariant.rs b/src/test/ui/regions/regions-variance-covariant-use-covariant.rs similarity index 100% rename from src/test/run-pass/regions/regions-variance-covariant-use-covariant.rs rename to src/test/ui/regions/regions-variance-covariant-use-covariant.rs diff --git a/src/test/ui/removing-extern-crate.fixed b/src/test/ui/removing-extern-crate.fixed index 71728e8a73..d2993dbc4a 100644 --- a/src/test/ui/removing-extern-crate.fixed +++ b/src/test/ui/removing-extern-crate.fixed @@ -1,7 +1,7 @@ // edition:2018 // aux-build:removing-extern-crate.rs // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_idioms)] #![allow(unused_imports)] diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs index b9cc1810e7..22fdfc2b0e 100644 --- a/src/test/ui/removing-extern-crate.rs +++ b/src/test/ui/removing-extern-crate.rs @@ -1,7 +1,7 @@ // edition:2018 // aux-build:removing-extern-crate.rs // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_idioms)] #![allow(unused_imports)] diff --git a/src/test/ui/removing-extern-crate.stderr b/src/test/ui/removing-extern-crate.stderr index fbdcb15825..18d0756e9f 100644 --- a/src/test/ui/removing-extern-crate.stderr +++ b/src/test/ui/removing-extern-crate.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ - = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] + = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]` warning: unused extern crate --> $DIR/removing-extern-crate.rs:10:1 diff --git a/src/test/run-pass/repeat-expr-in-static.rs b/src/test/ui/repeat-expr-in-static.rs similarity index 90% rename from src/test/run-pass/repeat-expr-in-static.rs rename to src/test/ui/repeat-expr-in-static.rs index 928509e1bd..0b89537933 100644 --- a/src/test/run-pass/repeat-expr-in-static.rs +++ b/src/test/ui/repeat-expr-in-static.rs @@ -1,3 +1,5 @@ +// run-pass + static FOO: [isize; 4] = [32; 4]; static BAR: [isize; 4] = [32, 32, 32, 32]; diff --git a/src/test/ui/repeat-to-run-dtor-twice.rs b/src/test/ui/repeat-to-run-dtor-twice.rs index 80eff2acdd..d857178166 100644 --- a/src/test/ui/repeat-to-run-dtor-twice.rs +++ b/src/test/ui/repeat-to-run-dtor-twice.rs @@ -15,5 +15,5 @@ impl Drop for Foo { fn main() { let a = Foo { x: 3 }; let _ = [ a; 5 ]; - //~^ ERROR `Foo: std::marker::Copy` is not satisfied + //~^ ERROR the trait bound `Foo: std::marker::Copy` is not satisfied [E0277] } diff --git a/src/test/run-pass/repr_c_int_align.rs b/src/test/ui/repr_c_int_align.rs similarity index 98% rename from src/test/run-pass/repr_c_int_align.rs rename to src/test/ui/repr_c_int_align.rs index 9bb08cb6c6..fdd14fc2db 100644 --- a/src/test/run-pass/repr_c_int_align.rs +++ b/src/test/ui/repr_c_int_align.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -O #![allow(dead_code)] diff --git a/src/test/ui/reserved/reserved-attr-on-macro.rs b/src/test/ui/reserved/reserved-attr-on-macro.rs index 96c63ba4db..fddb991da8 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.rs +++ b/src/test/ui/reserved/reserved-attr-on-macro.rs @@ -1,5 +1,7 @@ #[rustc_attribute_should_be_reserved] -//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +//~^ ERROR cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope +//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler + macro_rules! foo { () => (()); } diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr index c8738d1ed3..d4b97d290e 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.stderr +++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr @@ -1,20 +1,26 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/reserved-attr-on-macro.rs:1:3 | LL | #[rustc_attribute_should_be_reserved] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + +error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope + --> $DIR/reserved-attr-on-macro.rs:1:3 + | +LL | #[rustc_attribute_should_be_reserved] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot determine resolution for the macro `foo` - --> $DIR/reserved-attr-on-macro.rs:8:5 + --> $DIR/reserved-attr-on-macro.rs:10:5 | LL | foo!(); | ^^^ | = note: import resolution is stuck, try simplifying macro imports -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/resolve-issue-2428.rs b/src/test/ui/resolve-issue-2428.rs similarity index 93% rename from src/test/run-pass/resolve-issue-2428.rs rename to src/test/ui/resolve-issue-2428.rs index 7e730f6156..5f3473e9fe 100644 --- a/src/test/run-pass/resolve-issue-2428.rs +++ b/src/test/ui/resolve-issue-2428.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] diff --git a/src/test/run-pass/resolve-pseudo-shadowing.rs b/src/test/ui/resolve-pseudo-shadowing.rs similarity index 94% rename from src/test/run-pass/resolve-pseudo-shadowing.rs rename to src/test/ui/resolve-pseudo-shadowing.rs index 1a8ce9682e..85c684ca03 100644 --- a/src/test/run-pass/resolve-pseudo-shadowing.rs +++ b/src/test/ui/resolve-pseudo-shadowing.rs @@ -1,3 +1,4 @@ +// run-pass // check that type parameters can't "shadow" qualified paths. fn check(_c: Clone) { diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr index 3e812c2694..d2209236a4 100644 --- a/src/test/ui/resolve/enums-are-namespaced-xc.stderr +++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `A` in module `namespaced_enums` +error[E0425]: cannot find value `A` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:5:31 | LL | let _ = namespaced_enums::A; @@ -8,7 +8,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use namespaced_enums::Foo::A; | -error[E0425]: cannot find function `B` in module `namespaced_enums` +error[E0425]: cannot find function `B` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:7:31 | LL | let _ = namespaced_enums::B(10); @@ -18,7 +18,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use namespaced_enums::Foo::B; | -error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums` +error[E0422]: cannot find struct, variant or union type `C` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:9:31 | LL | let _ = namespaced_enums::C { a: 10 }; diff --git a/src/test/ui/resolve/issue-57523.rs b/src/test/ui/resolve/issue-57523.rs index c2a2f28254..5dc467d97e 100644 --- a/src/test/ui/resolve/issue-57523.rs +++ b/src/test/ui/resolve/issue-57523.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(u8); diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index 7af2cdf7b5..2e3c0f5448 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -2,7 +2,7 @@ error[E0412]: cannot find type `esize` in this scope --> $DIR/levenshtein.rs:5:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. - | ^^^^^ help: a primitive type with a similar name exists: `isize` + | ^^^^^ help: a builtin type with a similar name exists: `isize` error[E0412]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:10:10 diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index a1a8714ab3..2538bbbf80 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -195,8 +195,14 @@ LL | let _: Z = m::n::Z::Unit {}; error[E0308]: mismatched types --> $DIR/privacy-enum-ctor.rs:27:20 | +LL | Fn(u8), + | ------ fn(u8) -> m::n::Z {m::n::Z::Fn} defined here +... LL | let _: Z = Z::Fn; - | ^^^^^ expected enum `m::n::Z`, found fn item + | ^^^^^ + | | + | expected enum `m::n::Z`, found fn item + | help: use parentheses to instantiate this tuple variant: `Z::Fn(_)` | = note: expected type `m::n::Z` found type `fn(u8) -> m::n::Z {m::n::Z::Fn}` @@ -219,8 +225,14 @@ LL | let _ = Z::Unit; error[E0308]: mismatched types --> $DIR/privacy-enum-ctor.rs:43:16 | +LL | Fn(u8), + | ------ fn(u8) -> m::E {m::E::Fn} defined here +... LL | let _: E = m::E::Fn; - | ^^^^^^^^ expected enum `m::E`, found fn item + | ^^^^^^^^ + | | + | expected enum `m::E`, found fn item + | help: use parentheses to instantiate this tuple variant: `m::E::Fn(_)` | = note: expected type `m::E` found type `fn(u8) -> m::E {m::E::Fn}` @@ -243,8 +255,14 @@ LL | let _: E = m::E::Unit; error[E0308]: mismatched types --> $DIR/privacy-enum-ctor.rs:51:16 | +LL | Fn(u8), + | ------ fn(u8) -> m::E {m::E::Fn} defined here +... LL | let _: E = E::Fn; - | ^^^^^ expected enum `m::E`, found fn item + | ^^^^^ + | | + | expected enum `m::E`, found fn item + | help: use parentheses to instantiate this tuple variant: `E::Fn(_)` | = note: expected type `m::E` found type `fn(u8) -> m::E {m::E::Fn}` diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index 9bf7d19117..72d62fe45c 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -34,36 +34,48 @@ error[E0603]: tuple struct `Z` is private | LL | n::Z; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 | LL | m::S; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 | LL | let _: S = m::S(2); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 | LL | m::n::Z; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `S` is private --> $DIR/privacy-struct-ctor.rs:41:16 | LL | xcrate::m::S; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:45:19 | LL | xcrate::m::n::Z; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error: aborting due to 10 previous errors diff --git a/src/test/ui/resolve/resolve-bad-visibility.rs b/src/test/ui/resolve/resolve-bad-visibility.rs index d86c300c93..7d48bb97b1 100644 --- a/src/test/ui/resolve/resolve-bad-visibility.rs +++ b/src/test/ui/resolve/resolve-bad-visibility.rs @@ -4,8 +4,8 @@ trait Tr {} pub(in E) struct S; //~ ERROR expected module, found enum `E` pub(in Tr) struct Z; //~ ERROR expected module, found trait `Tr` pub(in std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules -pub(in nonexistent) struct G; //~ ERROR cannot find module `nonexistent` in the crate root -pub(in too_soon) struct H; //~ ERROR cannot find module `too_soon` in the crate root +pub(in nonexistent) struct G; //~ ERROR failed to resolve +pub(in too_soon) struct H; //~ ERROR failed to resolve // Visibilities are resolved eagerly without waiting for modules becoming fully populated. // Visibilities can only use ancestor modules legally which are always available in time, diff --git a/src/test/ui/resolve/resolve-bad-visibility.stderr b/src/test/ui/resolve/resolve-bad-visibility.stderr index b8004a48a6..d2fb7c7a9e 100644 --- a/src/test/ui/resolve/resolve-bad-visibility.stderr +++ b/src/test/ui/resolve/resolve-bad-visibility.stderr @@ -1,9 +1,3 @@ -error: visibilities can only be restricted to ancestor modules - --> $DIR/resolve-bad-visibility.rs:6:8 - | -LL | pub(in std::vec) struct F; - | ^^^^^^^^ - error[E0577]: expected module, found enum `E` --> $DIR/resolve-bad-visibility.rs:4:8 | @@ -16,17 +10,24 @@ error[E0577]: expected module, found trait `Tr` LL | pub(in Tr) struct Z; | ^^ not a module -error[E0578]: cannot find module `nonexistent` in the crate root +error: visibilities can only be restricted to ancestor modules + --> $DIR/resolve-bad-visibility.rs:6:8 + | +LL | pub(in std::vec) struct F; + | ^^^^^^^^ + +error[E0433]: failed to resolve: maybe a missing crate `nonexistent`? --> $DIR/resolve-bad-visibility.rs:7:8 | LL | pub(in nonexistent) struct G; - | ^^^^^^^^^^^ not found in the crate root + | ^^^^^^^^^^^ maybe a missing crate `nonexistent`? -error[E0578]: cannot find module `too_soon` in the crate root +error[E0433]: failed to resolve: maybe a missing crate `too_soon`? --> $DIR/resolve-bad-visibility.rs:8:8 | LL | pub(in too_soon) struct H; - | ^^^^^^^^ not found in the crate root + | ^^^^^^^^ maybe a missing crate `too_soon`? error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs index e4bb0d3294..3cb6ab52e0 100644 --- a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs +++ b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs @@ -1,4 +1,3 @@ -#[allow(unused_extern_crates)] extern crate std; //~^ ERROR the name `std` is defined multiple times diff --git a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr index 9e43cd4839..ea6cb9eb00 100644 --- a/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr +++ b/src/test/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr @@ -1,8 +1,4 @@ error[E0259]: the name `std` is defined multiple times - --> $DIR/resolve-conflict-extern-crate-vs-extern-crate.rs:2:1 - | -LL | extern crate std; - | ^^^^^^^^^^^^^^^^^ `std` reimported here | = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import diff --git a/src/test/ui/resolve/resolve-inconsistent-names.rs b/src/test/ui/resolve/resolve-inconsistent-names.rs index 59baa57d91..2fb803c4b2 100644 --- a/src/test/ui/resolve/resolve-inconsistent-names.rs +++ b/src/test/ui/resolve/resolve-inconsistent-names.rs @@ -1,7 +1,36 @@ +#![allow(non_camel_case_types)] + +enum E { A, B, c } + +mod m { + const CONST1: usize = 10; + const Const2: usize = 20; +} + fn main() { let y = 1; match y { a | b => {} //~ ERROR variable `a` is not bound in all patterns - //~^ ERROR variable `b` is not bound in all patterns + //~| ERROR variable `b` is not bound in all patterns + } + + let x = (E::A, E::B); + match x { + (A, B) | (ref B, c) | (c, A) => () + //~^ ERROR variable `A` is not bound in all patterns + //~| ERROR variable `B` is not bound in all patterns + //~| ERROR variable `B` is bound in inconsistent ways + //~| ERROR mismatched types + //~| ERROR variable `c` is not bound in all patterns + //~| HELP consider making the path in the pattern qualified: `?::A` + } + + let z = (10, 20); + match z { + (CONST1, _) | (_, Const2) => () + //~^ ERROR variable `CONST1` is not bound in all patterns + //~| HELP consider making the path in the pattern qualified: `?::CONST1` + //~| ERROR variable `Const2` is not bound in all patterns + //~| HELP consider making the path in the pattern qualified: `?::Const2` } } diff --git a/src/test/ui/resolve/resolve-inconsistent-names.stderr b/src/test/ui/resolve/resolve-inconsistent-names.stderr index c75718149f..f02867a002 100644 --- a/src/test/ui/resolve/resolve-inconsistent-names.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-names.stderr @@ -1,5 +1,5 @@ error[E0408]: variable `a` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:4:12 + --> $DIR/resolve-inconsistent-names.rs:13:12 | LL | a | b => {} | - ^ pattern doesn't bind `a` @@ -7,13 +7,92 @@ LL | a | b => {} | variable not in all patterns error[E0408]: variable `b` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:4:8 + --> $DIR/resolve-inconsistent-names.rs:13:8 | LL | a | b => {} | ^ - variable not in all patterns | | | pattern doesn't bind `b` -error: aborting due to 2 previous errors +error[E0408]: variable `A` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:19:18 + | +LL | (A, B) | (ref B, c) | (c, A) => () + | - ^^^^^^^^^^ - variable not in all patterns + | | | + | | pattern doesn't bind `A` + | variable not in all patterns + | +help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::A` + --> $DIR/resolve-inconsistent-names.rs:19:10 + | +LL | (A, B) | (ref B, c) | (c, A) => () + | ^ + +error[E0408]: variable `B` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:19:31 + | +LL | (A, B) | (ref B, c) | (c, A) => () + | - - ^^^^^^ pattern doesn't bind `B` + | | | + | | variable not in all patterns + | variable not in all patterns + +error[E0408]: variable `c` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:19:9 + | +LL | (A, B) | (ref B, c) | (c, A) => () + | ^^^^^^ - - variable not in all patterns + | | | + | | variable not in all patterns + | pattern doesn't bind `c` + +error[E0409]: variable `B` is bound in inconsistent ways within the same match arm + --> $DIR/resolve-inconsistent-names.rs:19:23 + | +LL | (A, B) | (ref B, c) | (c, A) => () + | - ^ bound in different ways + | | + | first binding + +error[E0408]: variable `CONST1` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:30:23 + | +LL | (CONST1, _) | (_, Const2) => () + | ------ ^^^^^^^^^^^ pattern doesn't bind `CONST1` + | | + | variable not in all patterns + | +help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::CONST1` + --> $DIR/resolve-inconsistent-names.rs:30:10 + | +LL | (CONST1, _) | (_, Const2) => () + | ^^^^^^ + +error[E0408]: variable `Const2` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:30:9 + | +LL | (CONST1, _) | (_, Const2) => () + | ^^^^^^^^^^^ ------ variable not in all patterns + | | + | pattern doesn't bind `Const2` + | +help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::Const2` + --> $DIR/resolve-inconsistent-names.rs:30:27 + | +LL | (CONST1, _) | (_, Const2) => () + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/resolve-inconsistent-names.rs:19:19 + | +LL | (A, B) | (ref B, c) | (c, A) => () + | ^^^^^ expected enum `E`, found &E + | + = note: expected type `E` + found type `&E` + +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0408`. +Some errors have detailed explanations: E0308, E0408, E0409. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/resolve/token-error-correct-3.rs b/src/test/ui/resolve/token-error-correct-3.rs index 212b88ac8b..5b08234c0a 100644 --- a/src/test/ui/resolve/token-error-correct-3.rs +++ b/src/test/ui/resolve/token-error-correct-3.rs @@ -15,7 +15,6 @@ pub mod raw { callback(path.as_ref(); //~^ ERROR expected one of fs::create_dir_all(path.as_ref()).map(|()| true) - //~^ ERROR mismatched types } else { //~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `)` Ok(false); diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index 607573f276..57dd7c9f03 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -7,11 +7,10 @@ LL | callback(path.as_ref(); | unclosed delimiter error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` - --> $DIR/token-error-correct-3.rs:19:9 + --> $DIR/token-error-correct-3.rs:18:9 | LL | fs::create_dir_all(path.as_ref()).map(|()| true) | - expected one of `.`, `;`, `?`, `}`, or an operator here -LL | LL | } else { | ^ unexpected token @@ -21,18 +20,6 @@ error[E0425]: cannot find function `is_directory` in this scope LL | if !is_directory(path.as_ref()) { | ^^^^^^^^^^^^ not found in this scope -error[E0308]: mismatched types - --> $DIR/token-error-correct-3.rs:17:13 - | -LL | fs::create_dir_all(path.as_ref()).map(|()| true) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;` - | | - | expected (), found enum `std::result::Result` - | - = note: expected type `()` - found type `std::result::Result` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0308, E0425. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/visibility-indeterminate.rs b/src/test/ui/resolve/visibility-indeterminate.rs new file mode 100644 index 0000000000..595eaf440c --- /dev/null +++ b/src/test/ui/resolve/visibility-indeterminate.rs @@ -0,0 +1,5 @@ +// edition:2018 + +foo!(); //~ ERROR cannot find macro `foo!` in this scope + +pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility diff --git a/src/test/ui/resolve/visibility-indeterminate.stderr b/src/test/ui/resolve/visibility-indeterminate.stderr new file mode 100644 index 0000000000..a259c8090b --- /dev/null +++ b/src/test/ui/resolve/visibility-indeterminate.stderr @@ -0,0 +1,19 @@ +error[E0578]: cannot determine resolution for the visibility + --> $DIR/visibility-indeterminate.rs:5:8 + | +LL | pub(in ::bar) struct Baz {} + | ^^^^^ + +error: cannot find macro `foo!` in this scope + --> $DIR/visibility-indeterminate.rs:3:1 + | +LL | foo!(); + | ^^^ + +error[E0601]: `main` function not found in crate `visibility_indeterminate` + | + = note: consider adding a `main` function to `$DIR/visibility-indeterminate.rs` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs index a9423830d9..a14ec5b729 100644 --- a/src/test/ui/resolve_self_super_hint.rs +++ b/src/test/ui/resolve_self_super_hint.rs @@ -1,5 +1,3 @@ -#![allow(unused_extern_crates)] - mod a { extern crate alloc; use alloc::HashMap; diff --git a/src/test/ui/resolve_self_super_hint.stderr b/src/test/ui/resolve_self_super_hint.stderr index 14cdae97d1..bc862553b5 100644 --- a/src/test/ui/resolve_self_super_hint.stderr +++ b/src/test/ui/resolve_self_super_hint.stderr @@ -1,17 +1,17 @@ error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:5:9 + --> $DIR/resolve_self_super_hint.rs:3:9 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `self::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:10:13 + --> $DIR/resolve_self_super_hint.rs:8:13 | LL | use alloc::HashMap; | ^^^^^ help: a similar path exists: `super::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:15:17 + --> $DIR/resolve_self_super_hint.rs:13:17 | LL | use alloc::HashMap; | ^^^^^ @@ -20,7 +20,7 @@ LL | use alloc::HashMap; | help: a similar path exists: `a::alloc` error[E0432]: unresolved import `alloc` - --> $DIR/resolve_self_super_hint.rs:20:21 + --> $DIR/resolve_self_super_hint.rs:18:21 | LL | use alloc::HashMap; | ^^^^^ diff --git a/src/test/run-pass/resource-assign-is-not-copy.rs b/src/test/ui/resource-assign-is-not-copy.rs similarity index 97% rename from src/test/run-pass/resource-assign-is-not-copy.rs rename to src/test/ui/resource-assign-is-not-copy.rs index c26473da5e..c1de139a9a 100644 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ b/src/test/ui/resource-assign-is-not-copy.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] use std::cell::Cell; diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/ui/resource-destruct.rs similarity index 98% rename from src/test/run-pass/resource-destruct.rs rename to src/test/ui/resource-destruct.rs index 066ce46f0b..c4756a21a0 100644 --- a/src/test/run-pass/resource-destruct.rs +++ b/src/test/ui/resource-destruct.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] use std::cell::Cell; diff --git a/src/test/run-pass/result-opt-conversions.rs b/src/test/ui/result-opt-conversions.rs similarity index 98% rename from src/test/run-pass/result-opt-conversions.rs rename to src/test/ui/result-opt-conversions.rs index 14b562160d..57f258aab6 100644 --- a/src/test/run-pass/result-opt-conversions.rs +++ b/src/test/ui/result-opt-conversions.rs @@ -1,3 +1,5 @@ +// run-pass + #[derive(Copy, Clone, Debug, PartialEq)] struct BadNumErr; diff --git a/src/test/run-pass/ret-bang.rs b/src/test/ui/ret-bang.rs similarity index 94% rename from src/test/run-pass/ret-bang.rs rename to src/test/ui/ret-bang.rs index eb69ee6f88..6618992e03 100644 --- a/src/test/run-pass/ret-bang.rs +++ b/src/test/ui/ret-bang.rs @@ -1,3 +1,5 @@ +// run-pass + fn my_err(s: String) -> ! { println!("{}", s); panic!(); } fn okay(i: usize) -> isize { diff --git a/src/test/run-pass/ret-none.rs b/src/test/ui/ret-none.rs similarity index 94% rename from src/test/run-pass/ret-none.rs rename to src/test/ui/ret-none.rs index f23461faaf..d595506e33 100644 --- a/src/test/run-pass/ret-none.rs +++ b/src/test/ui/ret-none.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/run-pass/return-nil.rs b/src/test/ui/return-nil.rs similarity index 89% rename from src/test/run-pass/return-nil.rs rename to src/test/ui/return-nil.rs index f24df19723..fd5203ff0e 100644 --- a/src/test/run-pass/return-nil.rs +++ b/src/test/ui/return-nil.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 fn f() { let x: () = (); return x; } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs index 7b499af632..e43c8541e6 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs @@ -2,7 +2,7 @@ // rust-lang/rust#2329), that starts passing with this feature in // place. -// compile-pass +// run-pass #![feature(bind_by_move_pattern_guards)] @@ -12,6 +12,7 @@ fn main() { let (tx, rx) = channel(); let x = Some(rx); tx.send(false); + tx.send(false); match x { Some(z) if z.recv().unwrap() => { panic!() }, Some(z) => { assert!(!z.recv().unwrap()); }, diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr index 34e8b0e143..fe1f699074 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr @@ -1,5 +1,5 @@ error: compilation successful - --> $DIR/feature-gate.rs:41:1 + --> $DIR/feature-gate.rs:36:1 | LL | / fn main() { LL | | foo(107) diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr index 34e8b0e143..fe1f699074 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr @@ -1,5 +1,5 @@ error: compilation successful - --> $DIR/feature-gate.rs:41:1 + --> $DIR/feature-gate.rs:36:1 | LL | / fn main() { LL | | foo(107) diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr index 2a1a04b3f4..7a7b1c2535 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr @@ -1,10 +1,10 @@ error[E0008]: cannot bind by-move into a pattern guard - --> $DIR/feature-gate.rs:33:16 + --> $DIR/feature-gate.rs:28:16 | LL | A { a: v } if *v == 42 => v, | ^ moves value into pattern guard | - = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable + = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs index 97f90f7762..69fce0bc77 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs @@ -6,7 +6,7 @@ // gate-test-bind_by_move_pattern_guards -// revisions: no_gate gate_and_2015 gate_and_2018 gate_and_znll gate_and_feature_nll +// revisions: no_gate gate_and_2015 gate_and_2018 // (We're already testing NLL behavior quite explicitly, no need for compare-mode=nll.) // ignore-compare-mode-nll @@ -15,14 +15,9 @@ #![cfg_attr(gate_and_2015, feature(bind_by_move_pattern_guards))] #![cfg_attr(gate_and_2018, feature(bind_by_move_pattern_guards))] -#![cfg_attr(gate_and_znll, feature(bind_by_move_pattern_guards))] -#![cfg_attr(gate_and_feature_nll, feature(bind_by_move_pattern_guards))] - -#![cfg_attr(gate_and_feature_nll, feature(nll))] //[gate_and_2015] edition:2015 //[gate_and_2018] edition:2018 -//[gate_and_znll] compile-flags: -Z borrowck=mir struct A { a: Box } @@ -43,5 +38,3 @@ fn main() { } //[gate_and_2015]~^^^ ERROR compilation successful //[gate_and_2018]~^^^^ ERROR compilation successful -//[gate_and_znll]~^^^^^ ERROR compilation successful -//[gate_and_feature_nll]~^^^^^^ ERROR compilation successful diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs index aca6aa5f0f..eccb4e417b 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs @@ -1,6 +1,6 @@ #![feature(bind_by_move_pattern_guards)] -// compile-pass +// run-pass struct A { a: Box } @@ -8,32 +8,38 @@ impl A { fn get(&self) -> i32 { *self.a } } -fn foo(n: i32) { +fn foo(n: i32) -> i32 { let x = A { a: Box::new(n) }; let y = match x { A { a: v } if *v == 42 => v, _ => Box::new(0), }; + *y } -fn bar(n: i32) { +fn bar(n: i32) -> i32 { let x = A { a: Box::new(n) }; let y = match x { A { a: v } if x.get() == 42 => v, _ => Box::new(0), }; + *y } -fn baz(n: i32) { +fn baz(n: i32) -> i32 { let x = A { a: Box::new(n) }; let y = match x { A { a: v } if *v.clone() == 42 => v, _ => Box::new(0), }; + *y } fn main() { - foo(107); - bar(107); - baz(107); + assert_eq!(foo(107), 0); + assert_eq!(foo(42), 42); + assert_eq!(bar(107), 0); + assert_eq!(bar(42), 42); + assert_eq!(baz(107), 0); + assert_eq!(baz(42), 42); } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs index bf387d01b6..602a8e15cb 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs @@ -1,4 +1,3 @@ -#![feature(nll)] #![feature(bind_by_move_pattern_guards)] enum VecWrapper { A(Vec) } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr index f6e4e5bd49..c9e8fc8ee5 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `v` in pattern guard - --> $DIR/rfc-reject-double-move-across-arms.rs:8:36 + --> $DIR/rfc-reject-double-move-across-arms.rs:7:36 | LL | VecWrapper::A(v) if { drop(v); false } => 1, | ^ move occurs because `v` has type `std::vec::Vec`, which does not implement the `Copy` trait diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs index ba999e9b3a..77252a1ce1 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs @@ -1,4 +1,3 @@ -#![feature(nll)] #![feature(bind_by_move_pattern_guards)] struct A { a: Box } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr index ec133b028e..a345022cee 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `v` in pattern guard - --> $DIR/rfc-reject-double-move-in-first-arm.rs:9:30 + --> $DIR/rfc-reject-double-move-in-first-arm.rs:8:30 | LL | A { a: v } if { drop(v); true } => v, | ^ move occurs because `v` has type `std::boxed::Box`, which does not implement the `Copy` trait diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index fd85bf7f16..1484b8c4a1 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -4,6 +4,6 @@ pub fn main() { let sl: &[u8] = b"foo"; match sl { //~ ERROR non-exhaustive patterns - [first, remainder..] => {}, + [first, remainder @ ..] => {}, }; } diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr index 96040f11b5..d75a376286 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr @@ -15,6 +15,8 @@ error[E0603]: tuple struct `TupleStruct` is private | LL | let ts_explicit = structs::TupleStruct(640, 480); | ^^^^^^^^^^^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: unit struct `UnitStruct` is private --> $DIR/struct.rs:32:32 diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs index 97061310d1..221b5cf6bf 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs @@ -1,5 +1,5 @@ // aux-build:uninhabited.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] diff --git a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr index d9d6ea21b8..ac0025ec75 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr @@ -3,6 +3,8 @@ error[E0603]: tuple variant `Tuple` is private | LL | let variant_tuple = NonExhaustiveVariants::Tuple(640); | ^^^^^ + | + = note: a tuple variant constructor is private if any of its fields is private error[E0603]: unit variant `Unit` is private --> $DIR/variant.rs:14:47 @@ -21,12 +23,16 @@ error[E0603]: tuple variant `Tuple` is private | LL | NonExhaustiveVariants::Tuple(fe_tpl) => "", | ^^^^^ + | + = note: a tuple variant constructor is private if any of its fields is private error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:26:35 | LL | if let NonExhaustiveVariants::Tuple(fe_tpl) = variant_struct { | ^^^^^ + | + = note: a tuple variant constructor is private if any of its fields is private error[E0639]: cannot create non-exhaustive variant using struct expression --> $DIR/variant.rs:8:26 diff --git a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs index 62f6e4463f..dacaf489a9 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:variants.rs extern crate variants; diff --git a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs index 438923e292..b662685ae2 100644 --- a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs +++ b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs @@ -6,7 +6,7 @@ // strange errors. This test ensures that we do not give compilation // errors. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyIterator<'a>: Iterator where Self::Item: 'a { } diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs index dd21de75aa..acb4bbebe7 100644 --- a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs +++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs @@ -3,7 +3,7 @@ // Tests that arbitrary crates (other than `core`, `std` and `meta`) // aren't allowed without `--extern`, even if they're in the sysroot. use alloc; //~ ERROR unresolved import `alloc` -use test; //~ ERROR cannot import a built-in macro +use test; // OK, imports the built-in attribute macro `#[test]`, but not the `test` crate. use proc_macro; // OK, imports the built-in `proc_macro` attribute, but not the `proc_macro` crate. fn main() {} diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr index 4e3fff98e6..f324378d4c 100644 --- a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr +++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr @@ -1,15 +1,9 @@ -error: cannot import a built-in macro - --> $DIR/not-whitelisted.rs:6:5 - | -LL | use test; - | ^^^^ - error[E0432]: unresolved import `alloc` --> $DIR/not-whitelisted.rs:5:5 | LL | use alloc; | ^^^^^ no `alloc` external crate -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.rs b/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.rs index c16f46451b..72e50d78bc 100644 --- a/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.rs +++ b/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.rs @@ -6,6 +6,6 @@ use crate; //~ ERROR crate root imports need to be explicitly named: `use crate use *; //~ ERROR cannot glob-import all possible crates fn main() { - let s = ::xcrate; //~ ERROR expected value, found module `xcrate` + let s = ::xcrate; //~ ERROR expected value, found crate `xcrate` //~^ NOTE not a value } diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.stderr index 396a798c82..253cc1bc57 100644 --- a/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.stderr +++ b/src/test/ui/rfc-2126-extern-absolute-paths/single-segment.stderr @@ -10,7 +10,7 @@ error: cannot glob-import all possible crates LL | use *; | ^ -error[E0423]: expected value, found module `xcrate` +error[E0423]: expected value, found crate `xcrate` --> $DIR/single-segment.rs:9:13 | LL | let s = ::xcrate; diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/rfc-2166-underscore-imports/basic.rs index 968da9c8d5..4766d75c8f 100644 --- a/src/test/ui/rfc-2166-underscore-imports/basic.rs +++ b/src/test/ui/rfc-2166-underscore-imports/basic.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:underscore-imports.rs #![warn(unused_imports, unused_extern_crates)] diff --git a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs b/src/test/ui/rfc-2166-underscore-imports/duplicate.rs index 95f7cae0b8..3662a466de 100644 --- a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs +++ b/src/test/ui/rfc-2166-underscore-imports/duplicate.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:duplicate.rs extern crate duplicate; diff --git a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs b/src/test/ui/rfc-2166-underscore-imports/intercrate.rs index 8b5bb8b326..1cccc67e9a 100644 --- a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs +++ b/src/test/ui/rfc-2166-underscore-imports/intercrate.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:underscore-imports.rs extern crate underscore_imports; diff --git a/src/test/ui/rfc-2306/convert-id-const-with-gate.rs b/src/test/ui/rfc-2306/convert-id-const-with-gate.rs index a82feb961f..762dfbe484 100644 --- a/src/test/ui/rfc-2306/convert-id-const-with-gate.rs +++ b/src/test/ui/rfc-2306/convert-id-const-with-gate.rs @@ -1,6 +1,6 @@ // This test should pass since 'identity' is const fn. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { const _FOO: u8 = ::std::convert::identity(42u8); diff --git a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs index e66d465756..710fdd57ed 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=expanded fn main() { diff --git a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout index a6b15f9bbf..c88f50c681 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout +++ b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout @@ -4,7 +4,7 @@ use ::std::prelude::v1::*; #[macro_use] extern crate std; -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=expanded fn main() { if let 0 = 1 { } } diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index 207d0d6d6b..4edc00efc7 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -4,18 +4,6 @@ error: expected one of `,` or `>`, found `&&` LL | true && let 1 = 1 | ^^ expected one of `,` or `>` here -warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/disallowed-positions.rs:20:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - -warning: the feature `let_chains` is incomplete and may cause the compiler to crash - --> $DIR/disallowed-positions.rs:22:12 - | -LL | #![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test. - | ^^^^^^^^^^ - error: `let` expressions are not supported here --> $DIR/disallowed-positions.rs:32:9 | @@ -511,6 +499,20 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if`- and `while`-expressions = note: as well as when nested within `&&` and parenthesis in those conditions +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/disallowed-positions.rs:20:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `let_chains` is incomplete and may cause the compiler to crash + --> $DIR/disallowed-positions.rs:22:12 + | +LL | #![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test. + | ^^^^^^^^^^ + error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:32:8 | diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr index 6167427fa9..abe200944b 100644 --- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr @@ -14,7 +14,7 @@ LL | if (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:18:11 @@ -23,7 +23,7 @@ LL | if (((let 0 = 1))) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:22:16 @@ -32,7 +32,7 @@ LL | if true && let 0 = 1 {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:26:8 @@ -41,7 +41,7 @@ LL | if let 0 = 1 && true {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:30:9 @@ -50,7 +50,7 @@ LL | if (let 0 = 1) && true {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:34:17 @@ -59,7 +59,7 @@ LL | if true && (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:38:9 @@ -68,7 +68,7 @@ LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:38:24 @@ -77,7 +77,7 @@ LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:44:8 @@ -86,7 +86,7 @@ LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:44:21 @@ -95,7 +95,7 @@ LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:44:35 @@ -104,7 +104,7 @@ LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:44:48 @@ -113,7 +113,7 @@ LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:44:61 @@ -122,7 +122,7 @@ LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:56:8 @@ -131,7 +131,7 @@ LL | if let Range { start: _, end: _ } = (true..true) && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:64:12 @@ -140,7 +140,7 @@ LL | while (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:68:14 @@ -149,7 +149,7 @@ LL | while (((let 0 = 1))) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:72:19 @@ -158,7 +158,7 @@ LL | while true && let 0 = 1 {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:76:11 @@ -167,7 +167,7 @@ LL | while let 0 = 1 && true {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:80:12 @@ -176,7 +176,7 @@ LL | while (let 0 = 1) && true {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:84:20 @@ -185,7 +185,7 @@ LL | while true && (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:88:12 @@ -194,7 +194,7 @@ LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:88:27 @@ -203,7 +203,7 @@ LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:94:11 @@ -212,7 +212,7 @@ LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) { | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:94:24 @@ -221,7 +221,7 @@ LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) { | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:94:38 @@ -230,7 +230,7 @@ LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) { | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:94:51 @@ -239,7 +239,7 @@ LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) { | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:94:64 @@ -248,7 +248,7 @@ LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) { | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:106:11 @@ -257,7 +257,7 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:129:20 @@ -266,7 +266,7 @@ LL | #[cfg(FALSE)] (let 0 = 1); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:114:17 @@ -275,7 +275,7 @@ LL | noop_expr!((let 0 = 1)); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:123:16 @@ -284,7 +284,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental --> $DIR/feature-gate.rs:126:16 @@ -293,7 +293,7 @@ LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53667 - = help: add #![feature(let_chains)] to the crate attributes to enable + = help: add `#![feature(let_chains)]` to the crate attributes to enable error: `let` expressions are not supported here --> $DIR/feature-gate.rs:14:9 diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs new file mode 100644 index 0000000000..71815e3c08 --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs @@ -0,0 +1,34 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +macro_rules! checker { + ($attr_name:ident, $expected:literal) => { + #[proc_macro_attribute] + pub fn $attr_name(attr: TokenStream, input: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(input.to_string(), $expected); + TokenStream::new() + } + } +} + +checker!(attr_extern, r#"extern "C" { + fn ffi(#[a1] arg1: i32, #[a2] ...); +}"#); +checker!(attr_extern_cvar, r#"unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) { }"#); +checker!(attr_alias, "type Alias = fn(#[a1] u8, #[a2] ...);"); +checker!(attr_free, "fn free(#[a1] arg1: u8) { let lam = |#[a2] W(x), #[a3] y| (); }"); +checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1: u8) { }"); +checker!(attr_inherent_2, "fn inherent2(#[a1] &self, #[a2] arg1: u8) { }"); +checker!(attr_inherent_3, "fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) { }"); +checker!(attr_inherent_4, "fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) { }"); +checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8);"); +checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8);"); +checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);"); +checker!(attr_trait_4, "fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec);"); diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs index c521d04fda..5eeda66173 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs @@ -1,189 +1,66 @@ +// check-pass // compile-flags: --cfg something -// compile-pass +#![deny(unused_mut)] #![feature(param_attrs)] extern "C" { fn ffi( - #[allow(C)] a: i32, + #[allow(unused_mut)] a: i32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] c: i32, - #[deny(C)] d: i32, - #[forbid(C)] #[warn(C)] ... + #[deny(unused_mut)] d: i32, + #[forbid(unused_mut)] #[warn(unused_mut)] ... ); } type FnType = fn( - #[allow(C)] a: i32, + #[allow(unused_mut)] a: i32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] c: i32, - #[deny(C)] d: i32, - #[forbid(C)] #[warn(C)] e: i32 + #[deny(unused_mut)] d: i32, + #[forbid(unused_mut)] #[warn(unused_mut)] e: i32 ); pub fn foo( - #[allow(C)] a: i32, + #[allow(unused_mut)] a: i32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] c: i32, - #[deny(C)] d: i32, - #[forbid(C)] #[warn(C)] e: i32 + #[deny(unused_mut)] d: i32, + #[forbid(unused_mut)] #[warn(unused_mut)] _e: i32 ) {} -// self, &self and &mut self +// self struct SelfStruct {} impl SelfStruct { fn foo( - #[allow(C)] self, + #[allow(unused_mut)] self, #[cfg(something)] a: i32, #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, + #[deny(unused_mut)] b: i32, ) {} } struct RefStruct {} impl RefStruct { fn foo( - #[allow(C)] &self, + #[allow(unused_mut)] &self, #[cfg(something)] a: i32, #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, + #[deny(unused_mut)] b: i32, ) {} } trait RefTrait { fn foo( - #[forbid(C)] &self, - #[warn(C)] a: i32 + #[forbid(unused_mut)] &self, + #[warn(unused_mut)] a: i32 ) {} } impl RefTrait for RefStruct { fn foo( - #[forbid(C)] &self, - #[warn(C)] a: i32 - ) {} -} - -struct MutStruct {} -impl MutStruct { - fn foo( - #[allow(C)] &mut self, - #[cfg(something)] a: i32, - #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, - ) {} -} -trait MutTrait { - fn foo( - #[forbid(C)] &mut self, - #[warn(C)] a: i32 - ) {} -} -impl MutTrait for MutStruct { - fn foo( - #[forbid(C)] &mut self, - #[warn(C)] a: i32 - ) {} -} - -// self: Self, self: &Self and self: &mut Self - -struct NamedSelfSelfStruct {} -impl NamedSelfSelfStruct { - fn foo( - #[allow(C)] self: Self, - #[cfg(something)] a: i32, - #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, - ) {} -} - -struct NamedSelfRefStruct {} -impl NamedSelfRefStruct { - fn foo( - #[allow(C)] self: &Self, - #[cfg(something)] a: i32, - #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, - ) {} -} -trait NamedSelfRefTrait { - fn foo( - #[forbid(C)] self: &Self, - #[warn(C)] a: i32 - ) {} -} -impl NamedSelfRefTrait for NamedSelfRefStruct { - fn foo( - #[forbid(C)] self: &Self, - #[warn(C)] a: i32 - ) {} -} - -struct NamedSelfMutStruct {} -impl NamedSelfMutStruct { - fn foo( - #[allow(C)] self: &mut Self, - #[cfg(something)] a: i32, - #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, - ) {} -} -trait NamedSelfMutTrait { - fn foo( - #[forbid(C)] self: &mut Self, - #[warn(C)] a: i32 - ) {} -} -impl NamedSelfMutTrait for NamedSelfMutStruct { - fn foo( - #[forbid(C)] self: &mut Self, - #[warn(C)] a: i32 - ) {} -} - -// &'a self and &'a mut self - -struct NamedLifetimeRefStruct {} -impl NamedLifetimeRefStruct { - fn foo<'a>( - #[allow(C)] self: &'a Self, - #[cfg(something)] a: i32, - #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, - ) {} -} -trait NamedLifetimeRefTrait { - fn foo<'a>( - #[forbid(C)] &'a self, - #[warn(C)] a: i32 - ) {} -} -impl NamedLifetimeRefTrait for NamedLifetimeRefStruct { - fn foo<'a>( - #[forbid(C)] &'a self, - #[warn(C)] a: i32 - ) {} -} - -struct NamedLifetimeMutStruct {} -impl NamedLifetimeMutStruct { - fn foo<'a>( - #[allow(C)] self: &'a mut Self, - #[cfg(something)] a: i32, - #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, - ) {} -} -trait NamedLifetimeMutTrait { - fn foo<'a>( - #[forbid(C)] &'a mut self, - #[warn(C)] a: i32 - ) {} -} -impl NamedLifetimeMutTrait for NamedLifetimeMutStruct { - fn foo<'a>( - #[forbid(C)] &'a mut self, - #[warn(C)] a: i32 + #[forbid(unused_mut)] &self, + #[warn(unused_mut)] a: i32 ) {} } @@ -192,22 +69,22 @@ impl NamedLifetimeMutTrait for NamedLifetimeMutStruct { struct BoxSelfStruct {} impl BoxSelfStruct { fn foo( - #[allow(C)] self: Box, + #[allow(unused_mut)] self: Box, #[cfg(something)] a: i32, #[cfg_attr(something, cfg(nothing))] - #[deny(C)] b: i32, + #[deny(unused_mut)] b: i32, ) {} } trait BoxSelfTrait { fn foo( - #[forbid(C)] self: Box, - #[warn(C)] a: i32 + #[forbid(unused_mut)] self: Box, + #[warn(unused_mut)] a: i32 ) {} } impl BoxSelfTrait for BoxSelfStruct { fn foo( - #[forbid(C)] self: Box, - #[warn(C)] a: i32 + #[forbid(unused_mut)] self: Box, + #[warn(unused_mut)] a: i32 ) {} } @@ -216,10 +93,10 @@ fn main() { let _: fn(_, _, _, _) = foo; let _: FnType = |_, _, _, _| {}; let c = | - #[allow(C)] a: u32, + #[allow(unused_mut)] a: u32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] - #[deny(C)] c: i32, + #[deny(unused_mut)] c: i32, | {}; let _ = c(1, 2); } diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs index 352375729b..b957c673a4 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs @@ -5,7 +5,7 @@ extern "C" { /// Foo //~^ ERROR documentation comments cannot be applied to function #[test] a: i32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -21,7 +21,7 @@ type FnType = fn( /// Foo //~^ ERROR documentation comments cannot be applied to function #[test] a: u32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -36,7 +36,7 @@ pub fn foo( /// Foo //~^ ERROR documentation comments cannot be applied to function #[test] a: u32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -56,7 +56,7 @@ impl SelfStruct { /// Bar //~^ ERROR documentation comments cannot be applied to function #[test] a: i32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -77,7 +77,7 @@ impl RefStruct { /// Bar //~^ ERROR documentation comments cannot be applied to function #[test] a: i32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -96,7 +96,7 @@ trait RefTrait { /// Bar //~^ ERROR documentation comments cannot be applied to function #[test] a: i32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -115,7 +115,7 @@ impl RefTrait for RefStruct { /// Bar //~^ ERROR documentation comments cannot be applied to function #[test] a: i32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] @@ -132,7 +132,7 @@ fn main() { /// Foo //~^ ERROR documentation comments cannot be applied to function #[test] a: u32, - //~^ ERROR The attribute `test` is currently unknown to the compiler and may have + //~^ ERROR the attribute `test` is currently unknown to the compiler and may have /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr index e6f3efc04c..a57572abb3 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr @@ -262,77 +262,77 @@ error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-i LL | #[no_mangle] b: i32 | ^^^^^^^^^^^^ -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:7:9 | LL | #[test] a: i32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:23:5 | LL | #[test] a: u32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:38:5 | LL | #[test] a: u32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:58:9 | LL | #[test] a: i32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:79:9 | LL | #[test] a: i32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:98:9 | LL | #[test] a: i32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:117:9 | LL | #[test] a: i32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/param-attrs-builtin-attrs.rs:134:9 | LL | #[test] a: u32, | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 52 previous errors diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs index 977b5d9ce3..069332ffa2 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs @@ -1,6 +1,7 @@ // compile-flags: --cfg something +// edition:2018 -#![feature(param_attrs)] +#![feature(async_await, async_closure, param_attrs)] #![deny(unused_variables)] extern "C" { @@ -19,24 +20,35 @@ type FnType = fn( #[cfg_attr(something, cfg(nothing))] d: i32, ); +async fn foo_async( + #[cfg(something)] a: i32, + //~^ ERROR unused variable: `a` + #[cfg(nothing)] b: i32, +) {} fn foo( #[cfg(nothing)] a: i32, #[cfg(something)] b: i32, - //~^ ERROR unused variable: `b` [unused_variables] + //~^ ERROR unused variable: `b` #[cfg_attr(nothing, cfg(nothing))] c: i32, - //~^ ERROR unused variable: `c` [unused_variables] + //~^ ERROR unused variable: `c` #[cfg_attr(something, cfg(nothing))] d: i32, ) {} struct RefStruct {} impl RefStruct { + async fn bar_async( + &self, + #[cfg(something)] a: i32, + //~^ ERROR unused variable: `a` + #[cfg(nothing)] b: i32, + ) {} fn bar( &self, #[cfg(nothing)] a: i32, #[cfg(something)] b: i32, - //~^ ERROR unused variable: `b` [unused_variables] + //~^ ERROR unused variable: `b` #[cfg_attr(nothing, cfg(nothing))] c: i32, - //~^ ERROR unused variable: `c` [unused_variables] + //~^ ERROR unused variable: `c` #[cfg_attr(something, cfg(nothing))] d: i32, ) {} } @@ -45,9 +57,9 @@ trait RefTrait { &self, #[cfg(nothing)] a: i32, #[cfg(something)] b: i32, - //~^ ERROR unused variable: `b` [unused_variables] + //~^ ERROR unused variable: `b` #[cfg_attr(nothing, cfg(nothing))] c: i32, - //~^ ERROR unused variable: `c` [unused_variables] + //~^ ERROR unused variable: `c` #[cfg_attr(something, cfg(nothing))] d: i32, ) {} } @@ -56,9 +68,9 @@ impl RefTrait for RefStruct { &self, #[cfg(nothing)] a: i32, #[cfg(something)] b: i32, - //~^ ERROR unused variable: `b` [unused_variables] + //~^ ERROR unused variable: `b` #[cfg_attr(nothing, cfg(nothing))] c: i32, - //~^ ERROR unused variable: `c` [unused_variables] + //~^ ERROR unused variable: `c` #[cfg_attr(something, cfg(nothing))] d: i32, ) {} } @@ -67,13 +79,19 @@ fn main() { let _: unsafe extern "C" fn(_, ...) = ffi; let _: fn(_, _) = foo; let _: FnType = |_, _| {}; + let a = async move | + #[cfg(something)] a: i32, + //~^ ERROR unused variable: `a` + #[cfg(nothing)] b: i32, + | {}; let c = | #[cfg(nothing)] a: i32, #[cfg(something)] b: i32, - //~^ ERROR unused variable: `b` [unused_variables] + //~^ ERROR unused variable: `b` #[cfg_attr(nothing, cfg(nothing))] c: i32, - //~^ ERROR unused variable: `c` [unused_variables] + //~^ ERROR unused variable: `c` #[cfg_attr(something, cfg(nothing))] d: i32, | {}; + let _ = a(1); let _ = c(1, 2); } diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr index c97190324e..3232e2a041 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -1,68 +1,86 @@ -error: unused variable: `b` +error: unused variable: `a` --> $DIR/param-attrs-cfg.rs:24:23 | -LL | #[cfg(something)] b: i32, - | ^ help: consider prefixing with an underscore: `_b` +LL | #[cfg(something)] a: i32, + | ^ help: consider prefixing with an underscore: `_a` | note: lint level defined here - --> $DIR/param-attrs-cfg.rs:4:9 + --> $DIR/param-attrs-cfg.rs:5:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ +error: unused variable: `b` + --> $DIR/param-attrs-cfg.rs:30:23 + | +LL | #[cfg(something)] b: i32, + | ^ help: consider prefixing with an underscore: `_b` + error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:26:40 + --> $DIR/param-attrs-cfg.rs:32:40 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: consider prefixing with an underscore: `_c` +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:83:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: consider prefixing with an underscore: `_a` + error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:72:27 + --> $DIR/param-attrs-cfg.rs:89:27 | LL | #[cfg(something)] b: i32, | ^ help: consider prefixing with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:74:44 + --> $DIR/param-attrs-cfg.rs:91:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: consider prefixing with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:47:27 + --> $DIR/param-attrs-cfg.rs:59:27 | LL | #[cfg(something)] b: i32, | ^ help: consider prefixing with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:49:44 + --> $DIR/param-attrs-cfg.rs:61:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: consider prefixing with an underscore: `_c` +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:41:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: consider prefixing with an underscore: `_a` + error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:36:27 + --> $DIR/param-attrs-cfg.rs:48:27 | LL | #[cfg(something)] b: i32, | ^ help: consider prefixing with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:38:44 + --> $DIR/param-attrs-cfg.rs:50:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: consider prefixing with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:58:27 + --> $DIR/param-attrs-cfg.rs:70:27 | LL | #[cfg(something)] b: i32, | ^ help: consider prefixing with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:60:44 + --> $DIR/param-attrs-cfg.rs:72:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: consider prefixing with an underscore: `_c` -error: aborting due to 10 previous errors +error: aborting due to 13 previous errors diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs index c5a6514efb..a7f4855915 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs @@ -1,12 +1,14 @@ // gate-test-param_attrs +#![deny(unused_variables)] + fn foo( /// Foo //~^ ERROR documentation comments cannot be applied to function parameters //~| NOTE doc comments are not allowed here //~| ERROR attributes on function parameters are unstable //~| NOTE https://github.com/rust-lang/rust/issues/60406 - #[allow(C)] a: u8 + #[allow(unused_variables)] a: u8 //~^ ERROR attributes on function parameters are unstable //~| NOTE https://github.com/rust-lang/rust/issues/60406 ) {} diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr index 82f21e7fdb..0bb9d05dca 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr @@ -1,26 +1,26 @@ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-feature-gate.rs:4:5 + --> $DIR/param-attrs-feature-gate.rs:6:5 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error[E0658]: attributes on function parameters are unstable - --> $DIR/param-attrs-feature-gate.rs:4:5 + --> $DIR/param-attrs-feature-gate.rs:6:5 | LL | /// Foo | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60406 - = help: add #![feature(param_attrs)] to the crate attributes to enable + = help: add `#![feature(param_attrs)]` to the crate attributes to enable error[E0658]: attributes on function parameters are unstable - --> $DIR/param-attrs-feature-gate.rs:9:5 + --> $DIR/param-attrs-feature-gate.rs:11:5 | -LL | #[allow(C)] a: u8 - | ^^^^^^^^^^^ +LL | #[allow(unused_variables)] a: u8 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60406 - = help: add #![feature(param_attrs)] to the crate attributes to enable + = help: add `#![feature(param_attrs)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs new file mode 100644 index 0000000000..1a7e948174 --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs @@ -0,0 +1,56 @@ +// aux-build:param-attrs.rs + +// check-pass + +#![feature(param_attrs)] +#![feature(c_variadic)] + +extern crate param_attrs; + +use param_attrs::*; + +struct W(u8); + +#[attr_extern] +extern "C" { fn ffi(#[a1] arg1: i32, #[a2] ...); } + +#[attr_extern_cvar] +unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) {} + +#[attr_alias] +type Alias = fn(#[a1] u8, #[a2] ...); + +#[attr_free] +fn free(#[a1] arg1: u8) { + let lam = |#[a2] W(x), #[a3] y| (); +} + +impl W { + #[attr_inherent_1] + fn inherent1(#[a1] self, #[a2] arg1: u8) {} + + #[attr_inherent_2] + fn inherent2(#[a1] &self, #[a2] arg1: u8) {} + + #[attr_inherent_3] + fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) {} + + #[attr_inherent_4] + fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) {} +} + +trait A { + #[attr_trait_1] + fn trait1(#[a1] self, #[a2] arg1: u8); + + #[attr_trait_2] + fn trait2(#[a1] &self, #[a2] arg1: u8); + + #[attr_trait_3] + fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8); + + #[attr_trait_4] + fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec); +} + +fn main() {} diff --git a/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs new file mode 100644 index 0000000000..b90a750cc1 --- /dev/null +++ b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs @@ -0,0 +1,24 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapEmbedded(*const NoDerive); + +const WRAP_UNSAFE_EMBEDDED: WrapEmbedded = WrapEmbedded(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_EMBEDDED { + WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs new file mode 100644 index 0000000000..1076b9f25d --- /dev/null +++ b/src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs @@ -0,0 +1,24 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(*const X); + +const WRAP_UNSAFE_PARAM: WrapParam = WrapParam(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_PARAM { + WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs new file mode 100644 index 0000000000..a4b832d377 --- /dev/null +++ b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs @@ -0,0 +1,24 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapEmbedded(*const NoDerive); + +const WRAP_UNSAFE_EMBEDDED: & &WrapEmbedded = & &WrapEmbedded(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_EMBEDDED { + WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs new file mode 100644 index 0000000000..47b70e2e9c --- /dev/null +++ b/src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs @@ -0,0 +1,24 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(*const X); + +const WRAP_UNSAFE_PARAM: & &WrapParam = & &WrapParam(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_PARAM { + WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs b/src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs new file mode 100644 index 0000000000..dca8aaef15 --- /dev/null +++ b/src/test/ui/rfc1445/allow-use-behind-cousin-variant.rs @@ -0,0 +1,59 @@ +// rust-lang/rust#62614: we want to allow matching on constants of types that +// have non-structural-match variants, *if* the constant itself does not use +// any such variant. + +// NOTE: for now, deliberately leaving the lint `indirect_structural_match` set +// to its default, so that we will not issue a diangostic even if +// rust-lang/rust#62614 remains an open issue. + +// run-pass + +struct Sum(u32, u32); + +impl PartialEq for Sum { + fn eq(&self, other: &Self) -> bool { self.0 + self.1 == other.0 + other.1 } +} + +impl Eq for Sum { } + +#[derive(PartialEq, Eq)] +enum Eek { + TheConst, + UnusedByTheConst(Sum) +} + +const THE_CONST: Eek = Eek::TheConst; +const SUM_THREE: Eek = Eek::UnusedByTheConst(Sum(3,0)); + +const EEK_ZERO: &[Eek] = &[]; +const EEK_ONE: &[Eek] = &[THE_CONST]; + +pub fn main() { + match Eek::UnusedByTheConst(Sum(1,2)) { + ref sum if sum == &SUM_THREE => { println!("Hello 0"); } + _ => { println!("Gbye"); } + } + + match Eek::TheConst { + THE_CONST => { println!("Hello 1"); } + _ => { println!("Gbye"); } + } + + + match & &Eek::TheConst { + & & THE_CONST => { println!("Hello 2"); } + _ => { println!("Gbye"); } + } + + match & & &[][..] { + & & EEK_ZERO => { println!("Hello 3"); } + & & EEK_ONE => { println!("Gbye"); } + _ => { println!("Gbye"); } + } + + match & & &[Eek::TheConst][..] { + & & EEK_ZERO => { println!("Gby"); } + & & EEK_ONE => { println!("Hello 4"); } + _ => { println!("Gbye"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs new file mode 100644 index 0000000000..b8949ae8b5 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs @@ -0,0 +1,26 @@ +// This is part of a set of tests exploring the different ways a +// `#[structural_match]` ADT might try to hold a +// non-`#[structural_match]` in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapInline(NoDerive); + +const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0)); + +fn main() { + match WRAP_DIRECT_INLINE { + WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } + //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + _ => { println!("WRAP_DIRECT_INLINE did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr new file mode 100644 index 0000000000..c73a6cf132 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.stderr @@ -0,0 +1,8 @@ +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9 + | +LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs new file mode 100644 index 0000000000..584e7a00f0 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs @@ -0,0 +1,26 @@ +// This is part of a set of tests exploring the different ways a +// `#[structural_match]` ADT might try to hold a +// non-`#[structural_match]` in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(T); + +const WRAP_DIRECT_PARAM: WrapParam = WrapParam(NoDerive(0)); + +fn main() { + match WRAP_DIRECT_PARAM { + WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } + //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + _ => { println!("WRAP_DIRECT_PARAM did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr new file mode 100644 index 0000000000..6fdf9db89b --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.stderr @@ -0,0 +1,8 @@ +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-direct-struct-param.rs:22:9 + | +LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs new file mode 100644 index 0000000000..0328db5a49 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs @@ -0,0 +1,29 @@ +// This is part of a set of tests exploring the different ways a +// `#[structural_match]` ADT might try to hold a +// non-`#[structural_match]` in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapInline<'a>(&'a &'a NoDerive); + +const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0)); + +fn main() { + match WRAP_DOUBLY_INDIRECT_INLINE { + WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release + _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr new file mode 100644 index 0000000000..5281d57606 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr @@ -0,0 +1,14 @@ +warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9 + | +LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs new file mode 100644 index 0000000000..54579e487a --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs @@ -0,0 +1,29 @@ +// This is part of a set of tests exploring the different ways a +// `#[structural_match]` ADT might try to hold a +// non-`#[structural_match]` in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam<'a, T>(&'a &'a T); + +const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam = & &WrapParam(& & NoDerive(0)); + +fn main() { + match WRAP_DOUBLY_INDIRECT_PARAM { + WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release + _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr new file mode 100644 index 0000000000..5d601c2c00 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr @@ -0,0 +1,14 @@ +warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9 + | +LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs new file mode 100644 index 0000000000..2a24316898 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs @@ -0,0 +1,29 @@ +// This is part of a set of tests exploring the different ways a +// `#[structural_match]` ADT might try to hold a +// non-`#[structural_match]` in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapInline(NoDerive); + +const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); + +fn main() { + match WRAP_INDIRECT_INLINE { + WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release + _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr new file mode 100644 index 0000000000..4ac19afa70 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.stderr @@ -0,0 +1,14 @@ +warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9 + | +LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } + | ^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs new file mode 100644 index 0000000000..64e777f232 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs @@ -0,0 +1,29 @@ +// This is part of a set of tests exploring the different ways a +// `#[structural_match]` ADT might try to hold a +// non-`#[structural_match]` in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(T); + +const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); + +fn main() { + match WRAP_INDIRECT_PARAM { + WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release + _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); } + } +} diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr new file mode 100644 index 0000000000..4000a47987 --- /dev/null +++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr @@ -0,0 +1,14 @@ +warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9 + | +LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } + | ^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + diff --git a/src/test/ui/rfc1445/feature-gate.no_gate.stderr b/src/test/ui/rfc1445/feature-gate.no_gate.stderr index 3a2014fab0..fa87937162 100644 --- a/src/test/ui/rfc1445/feature-gate.no_gate.stderr +++ b/src/test/ui/rfc1445/feature-gate.no_gate.stderr @@ -5,7 +5,7 @@ LL | #[structural_match] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/31434 - = help: add #![feature(structural_match)] to the crate attributes to enable + = help: add `#![feature(structural_match)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs b/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs new file mode 100644 index 0000000000..5b378fb2a5 --- /dev/null +++ b/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs @@ -0,0 +1,135 @@ +// run-pass + +// This file checks that fn ptrs are considered structurally matchable. +// See also rust-lang/rust#63479. + +fn main() { + let mut count = 0; + + // A type which is not structurally matchable: + struct NotSM; + + // And one that is: + #[derive(PartialEq, Eq)] + struct SM; + + fn trivial() {} + + fn sm_to(_: SM) {} + fn not_sm_to(_: NotSM) {} + fn to_sm() -> SM { SM } + fn to_not_sm() -> NotSM { NotSM } + + // To recreate the scenario of interest in #63479, we need to add + // a ref-level-of-indirection so that we descend into the type. + + fn r_sm_to(_: &SM) {} + fn r_not_sm_to(_: &NotSM) {} + fn r_to_r_sm(_: &()) -> &SM { &SM } + fn r_to_r_not_sm(_: &()) -> &NotSM { &NotSM } + + #[derive(PartialEq, Eq)] + struct Wrap(T); + + // In the code below, we put the match input into a local so that + // we can assign it an explicit type that is an fn ptr instead of + // a singleton type of the fn itself that the type inference would + // otherwise assign. + + // Check that fn() is #[structural_match] + const CFN1: Wrap = Wrap(trivial); + let input: Wrap = Wrap(trivial); + match Wrap(input) { + Wrap(CFN1) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is #[structural_match] when T is too. + const CFN2: Wrap = Wrap(sm_to); + let input: Wrap = Wrap(sm_to); + match Wrap(input) { + Wrap(CFN2) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is #[structural_match] when T is too. + const CFN3: Wrap SM> = Wrap(to_sm); + let input: Wrap SM> = Wrap(to_sm); + match Wrap(input) { + Wrap(CFN3) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is #[structural_match] even if T is not. + const CFN4: Wrap = Wrap(not_sm_to); + let input: Wrap = Wrap(not_sm_to); + match Wrap(input) { + Wrap(CFN4) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is #[structural_match] even if T is not. + const CFN5: Wrap NotSM> = Wrap(to_not_sm); + let input: Wrap NotSM> = Wrap(to_not_sm); + match Wrap(input) { + Wrap(CFN5) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(&T) is #[structural_match] when T is too. + const CFN6: Wrap = Wrap(r_sm_to); + let input: Wrap = Wrap(r_sm_to); + match Wrap(input) { + Wrap(CFN6) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> &T is #[structural_match] when T is too. + const CFN7: Wrap &SM> = Wrap(r_to_r_sm); + let input: Wrap &SM> = Wrap(r_to_r_sm); + match Wrap(input) { + Wrap(CFN7) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is #[structural_match] even if T is not. + const CFN8: Wrap = Wrap(r_not_sm_to); + let input: Wrap = Wrap(r_not_sm_to); + match Wrap(input) { + Wrap(CFN8) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is #[structural_match] even if T is not. + const CFN9: Wrap &NotSM> = Wrap(r_to_r_not_sm); + let input: Wrap &NotSM> = Wrap(r_to_r_not_sm); + match Wrap(input) { + Wrap(CFN9) => count += 1, + Wrap(_) => {} + }; + + // Check that a type which has fn ptrs is `#[structural_match]`. + #[derive(PartialEq, Eq)] + struct Foo { + alpha: fn(NotSM), + beta: fn() -> NotSM, + gamma: fn(SM), + delta: fn() -> SM, + } + + const CFOO: Foo = Foo { + alpha: not_sm_to, + beta: to_not_sm, + gamma: sm_to, + delta: to_sm, + }; + + let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm }; + match input { + CFOO => count += 1, + Foo { .. } => {} + }; + + // Final count must be 10 now if all + assert_eq!(count, 10); +} diff --git a/src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.rs b/src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.rs new file mode 100644 index 0000000000..9a96628cac --- /dev/null +++ b/src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.rs @@ -0,0 +1,19 @@ +// Issue 61118 pointed out a case where we hit an ICE during code gen: +// the compiler assumed that `PartialEq` was always implemented on any +// use of a `const` item in a pattern context, but the pre-existing +// checking for the presence of `#[structural_match]` was too shallow +// (see rust-lang/rust#62307), and so we hit cases where we were +// trying to dispatch to `PartialEq` on types that did not implement +// that trait. + +struct B(i32); + +const A: &[B] = &[]; + +pub fn main() { + match &[][..] { + A => (), + //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + _ => (), + } +} diff --git a/src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.stderr b/src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.stderr new file mode 100644 index 0000000000..e8141f6108 --- /dev/null +++ b/src/test/ui/rfc1445/issue-61118-match-slice-forbidden-without-eq.stderr @@ -0,0 +1,8 @@ +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/issue-61118-match-slice-forbidden-without-eq.rs:15:9 + | +LL | A => (), + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs new file mode 100644 index 0000000000..98943a9666 --- /dev/null +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -0,0 +1,43 @@ +// RFC 1445 introduced `#[structural_match]`; this attribute must +// appear on the `struct`/`enum` definition for any `const` used in a +// pattern. +// +// This is our (forever-unstable) way to mark a datatype as having a +// `PartialEq` implementation that is equivalent to recursion over its +// substructure. This avoids (at least in the short term) any need to +// resolve the question of what semantics is used for such matching. +// (See RFC 1445 for more details and discussion.) + +// Issue 62307 pointed out a case where the checking for +// `#[structural_match]` was too shallow. +#![warn(indirect_structural_match)] +// run-pass + +#[derive(Debug)] +struct B(i32); + +// Overriding `PartialEq` to use this strange notion of "equality" exposes +// whether `match` is using structural-equality or method-dispatch +// under the hood, which is the antithesis of rust-lang/rfcs#1445 +impl PartialEq for B { + fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 } +} + +fn main() { + const RR_B0: & & B = & & B(0); + const RR_B1: & & B = & & B(1); + + match RR_B0 { + RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release + _ => { } + } + + match RR_B1 { + RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } + //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| WARN will become a hard error in a future release + _ => { } + } +} diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr new file mode 100644 index 0000000000..0e158c2fda --- /dev/null +++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -0,0 +1,23 @@ +warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9 + | +LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } + | ^^^^^ + | +note: lint level defined here + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 + | +LL | #![warn(indirect_structural_match)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + +warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9 + | +LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } + | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 + diff --git a/src/test/ui/rfc1445/issue-63479-match-fnptr.rs b/src/test/ui/rfc1445/issue-63479-match-fnptr.rs new file mode 100644 index 0000000000..b3c91cec58 --- /dev/null +++ b/src/test/ui/rfc1445/issue-63479-match-fnptr.rs @@ -0,0 +1,36 @@ +// run-pass + +// The actual regression test from #63479. (Including this because my +// first draft at fn-ptr-is-structurally-matchable.rs failed to actually +// cover the case this hit; I've since expanded it accordingly, but the +// experience left me wary of leaving this regression test out.) + +#[derive(Eq)] +struct A { + a: i64 +} + +impl PartialEq for A { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.a.eq(&other.a) + } +} + +type Fn = fn(&[A]); + +fn my_fn(_args: &[A]) { + println!("hello world"); +} + +const TEST: Fn = my_fn; + +struct B(Fn); + +fn main() { + let s = B(my_fn); + match s { + B(TEST) => println!("matched"), + _ => panic!("didn't match") + }; +} diff --git a/src/test/ui/rfc1445/match-empty-array-allowed-without-eq-issue-62336.rs b/src/test/ui/rfc1445/match-empty-array-allowed-without-eq-issue-62336.rs new file mode 100644 index 0000000000..7ba0f3a9e8 --- /dev/null +++ b/src/test/ui/rfc1445/match-empty-array-allowed-without-eq-issue-62336.rs @@ -0,0 +1,17 @@ +// Pre-existing behavior has been to reject patterns with consts +// denoting non-empty arrays of non-`Eq` types, but *accept* empty +// arrays of such types. +// +// See rust-lang/rust#62336. + +// run-pass + +#[derive(PartialEq, Debug)] +struct B(i32); + +fn main() { + const FOO: [B; 0] = []; + match [] { + FOO => { } + } +} diff --git a/src/test/ui/rfc1445/match-forbidden-without-eq.stderr b/src/test/ui/rfc1445/match-forbidden-without-eq.stderr index 4ec1e8ddb9..c05bb8f19f 100644 --- a/src/test/ui/rfc1445/match-forbidden-without-eq.stderr +++ b/src/test/ui/rfc1445/match-forbidden-without-eq.stderr @@ -10,7 +10,7 @@ warning: floating-point types cannot be used in patterns LL | f32::INFINITY => { } | ^^^^^^^^^^^^^ | - = note: #[warn(illegal_floating_point_literal_pattern)] on by default + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 diff --git a/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs new file mode 100644 index 0000000000..3d56fb05dc --- /dev/null +++ b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.rs @@ -0,0 +1,19 @@ +// Issue 62307 pointed out a case where the checking for +// `#[structural_match]` was too shallow. +// +// Here we check similar behavior for non-empty arrays of types that +// do not derive `Eq`. +// +// (Current behavior for empty arrays differs and thus is not tested +// here; see rust-lang/rust#62336.) + +#[derive(PartialEq, Debug)] +struct B(i32); + +fn main() { + const FOO: [B; 1] = [B(0)]; + match [B(1)] { + FOO => { } + //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + } +} diff --git a/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr new file mode 100644 index 0000000000..371f8a0aa1 --- /dev/null +++ b/src/test/ui/rfc1445/match-nonempty-array-forbidden-without-eq.stderr @@ -0,0 +1,8 @@ +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/match-nonempty-array-forbidden-without-eq.rs:16:9 + | +LL | FOO => { } + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.stderr b/src/test/ui/rfc1598-generic-associated-types/collections.stderr index d0fe5035bc..fa8fcc9924 100644 --- a/src/test/ui/rfc1598-generic-associated-types/collections.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/collections.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0109]: type arguments are not allowed for this type --> $DIR/collections.rs:56:90 diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr index b2dd523c8f..ab161ae21b 100644 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0109]: lifetime arguments are not allowed for this type --> $DIR/construct_with_other_type.rs:17:46 diff --git a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr index 5b98302924..749032dbcc 100644 --- a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr @@ -9,6 +9,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error: aborting due to previous error diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr b/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr index 27b1d73d04..fb43a50df7 100644 --- a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr @@ -5,7 +5,7 @@ LL | type Item<'b> = &'b Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.stderr b/src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.stderr index 6953a28a23..d75f9fb845 100644 --- a/src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.stderr @@ -3,4 +3,6 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr index b323104048..0d319a7a59 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr @@ -3,4 +3,6 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr index f8c0a1f3bf..40ea42f624 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0261]: use of undeclared lifetime name `'b` --> $DIR/generic_associated_type_undeclared_lifetimes.rs:13:37 diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr index 6d5d0cc382..51246d3c90 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0109]: lifetime arguments are not allowed for this type --> $DIR/iterable.rs:11:47 diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr index 817d911184..65dbd00c5b 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0109]: lifetime arguments are not allowed for this type --> $DIR/parameter_number_and_kind.rs:17:27 diff --git a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs index 589e5fcc00..9fc32d7cc5 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs +++ b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z parse-only #![feature(generic_associated_types)] diff --git a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs index 7fa71e4dd1..7974ee9d39 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs +++ b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z parse-only #![feature(generic_associated_types)] diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr index 0966f8f942..626495350a 100644 --- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0109]: type arguments are not allowed for this type --> $DIR/pointer_family.rs:37:21 diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs index 82a7c2510e..03492631cb 100644 --- a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs +++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs @@ -3,7 +3,7 @@ //FIXME(#44265): The lifetime shadowing and type parameter shadowing // should cause an error. Now it compiles (erroneously) and this will be addressed // by a future PR. Then remove the following: -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Shadow<'a> { type Bar<'a>; // Error: shadowed lifetime diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr index cba6bbd851..9526df258c 100644 --- a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr @@ -3,4 +3,6 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr index 5fc1e3dddb..09dd654b57 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr @@ -3,6 +3,8 @@ warning: the feature `generic_associated_types` is incomplete and may cause the | LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0109]: lifetime arguments are not allowed for this type --> $DIR/streaming_iterator.rs:18:41 diff --git a/src/test/ui/rfc1717/missing-link-attr.stderr b/src/test/ui/rfc1717/missing-link-attr.stderr index 30555e8094..d836741f9e 100644 --- a/src/test/ui/rfc1717/missing-link-attr.stderr +++ b/src/test/ui/rfc1717/missing-link-attr.stderr @@ -1,4 +1,4 @@ -error: renaming of the library `foo` was specified, however this crate contains no #[link(...)] attributes referencing this library. +error: renaming of the library `foo` was specified, however this crate contains no `#[link(...)]` attributes referencing this library. error: aborting due to previous error diff --git a/src/test/run-pass/rfcs/rfc-1014-2.rs b/src/test/ui/rfcs/rfc-1014-2.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1014-2.rs rename to src/test/ui/rfcs/rfc-1014-2.rs diff --git a/src/test/run-pass/rfcs/rfc-1014.rs b/src/test/ui/rfcs/rfc-1014.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1014.rs rename to src/test/ui/rfcs/rfc-1014.rs diff --git a/src/test/run-pass/rfcs/rfc-1789-as-cell/from-mut.rs b/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1789-as-cell/from-mut.rs rename to src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs diff --git a/src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs rename to src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/box.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/box.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/constref.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/constref.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/enum.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/for.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/general.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/general.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/lit.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/range.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/range.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/ref-region.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/reset-mode.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs similarity index 91% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs index 939a3c4a1f..38b0941aad 100644 --- a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs @@ -5,7 +5,7 @@ fn slice_pat() { let sl: &[u8] = b"foo"; match sl { - [first, remainder..] => { + [first, remainder @ ..] => { let _: &u8 = first; assert_eq!(first, &b'f'); assert_eq!(remainder, b"oo"); diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/struct.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs diff --git a/src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2005-default-binding-mode/tuple.rs rename to src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2151-raw-identifiers/attr.rs rename to src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/basic.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2151-raw-identifiers/basic.rs rename to src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/items.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2151-raw-identifiers/items.rs rename to src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs similarity index 96% rename from src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs rename to src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs index 51a3b46d46..0ab7e17f87 100644 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs +++ b/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs @@ -1,7 +1,7 @@ // run-pass #![feature(decl_macro)] -r#macro_rules! r#struct { +macro_rules! r#struct { ($r#struct:expr) => { $r#struct } } diff --git a/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs b/src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs rename to src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs diff --git a/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs b/src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs rename to src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs diff --git a/src/test/run-pass/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs rename to src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs diff --git a/src/test/run-pass/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs b/src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs rename to src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs diff --git a/src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs b/src/test/ui/rfcs/rfc1445/eq-allows-match.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc1445/eq-allows-match.rs rename to src/test/ui/rfcs/rfc1445/eq-allows-match.rs diff --git a/src/test/run-pass/rfcs/rfc1623.rs b/src/test/ui/rfcs/rfc1623.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc1623.rs rename to src/test/ui/rfcs/rfc1623.rs diff --git a/src/test/run-pass/rfcs/rfc1717/auxiliary/clibrary.rs b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc1717/auxiliary/clibrary.rs rename to src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs diff --git a/src/test/run-pass/rfcs/rfc1717/library-override.rs b/src/test/ui/rfcs/rfc1717/library-override.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc1717/library-override.rs rename to src/test/ui/rfcs/rfc1717/library-override.rs diff --git a/src/test/run-pass/rfcs/rfc1857-drop-order.rs b/src/test/ui/rfcs/rfc1857-drop-order.rs similarity index 100% rename from src/test/run-pass/rfcs/rfc1857-drop-order.rs rename to src/test/ui/rfcs/rfc1857-drop-order.rs diff --git a/src/test/ui/rmeta-lib-pass.rs b/src/test/ui/rmeta-lib-pass.rs index 4ab4117dd6..fdd0516e4d 100644 --- a/src/test/ui/rmeta-lib-pass.rs +++ b/src/test/ui/rmeta-lib-pass.rs @@ -1,7 +1,7 @@ // compile-flags: --emit=metadata // aux-build:rmeta-rlib.rs // no-prefer-dynamic -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that building a metadata crate works with a dependent, rlib crate. // This is a cfail test since there is no executable to run. diff --git a/src/test/ui/rmeta-pass.rs b/src/test/ui/rmeta-pass.rs index 9c88de7a03..4f0db23f47 100644 --- a/src/test/ui/rmeta-pass.rs +++ b/src/test/ui/rmeta-pass.rs @@ -1,7 +1,7 @@ // compile-flags: --emit=metadata // aux-build:rmeta-meta.rs // no-prefer-dynamic -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that building a metadata crate works with a dependent, metadata-only // crate. diff --git a/src/test/ui/rmeta-priv-warn.rs b/src/test/ui/rmeta-priv-warn.rs index 823ce80623..430c1f06f4 100644 --- a/src/test/ui/rmeta-priv-warn.rs +++ b/src/test/ui/rmeta-priv-warn.rs @@ -1,6 +1,6 @@ // compile-flags: --emit=metadata // no-prefer-dynamic -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[deny(warnings)] diff --git a/src/test/run-pass/rmeta.rs b/src/test/ui/rmeta-rpass.rs similarity index 86% rename from src/test/run-pass/rmeta.rs rename to src/test/ui/rmeta-rpass.rs index cbbdd78dc2..5a63b5b859 100644 --- a/src/test/run-pass/rmeta.rs +++ b/src/test/ui/rmeta-rpass.rs @@ -1,8 +1,9 @@ +// run-pass // Test that using rlibs and rmeta dep crates work together. Specifically, that // there can be both an rmeta and an rlib file and rustc will prefer the rlib. // aux-build:rmeta-rmeta.rs -// aux-build:rmeta-rlib.rs +// aux-build:rmeta-rlib-rpass.rs extern crate rmeta_aux; use rmeta_aux::Foo; diff --git a/src/test/run-pass/running-with-no-runtime.rs b/src/test/ui/running-with-no-runtime.rs similarity index 99% rename from src/test/run-pass/running-with-no-runtime.rs rename to src/test/ui/running-with-no-runtime.rs index ab1bf3a5b9..3fc631be60 100644 --- a/src/test/run-pass/running-with-no-runtime.rs +++ b/src/test/ui/running-with-no-runtime.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported // ignore-sgx no processes diff --git a/src/test/ui/rust-2018/async-ident-allowed.stderr b/src/test/ui/rust-2018/async-ident-allowed.stderr index d3e450e9be..2394bff118 100644 --- a/src/test/ui/rust-2018/async-ident-allowed.stderr +++ b/src/test/ui/rust-2018/async-ident-allowed.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: #[deny(keyword_idents)] implied by #[deny(rust_2018_compatibility)] + = note: `#[deny(keyword_idents)]` implied by `#[deny(rust_2018_compatibility)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #49716 diff --git a/src/test/ui/rust-2018/edition-lint-paths-2018.rs b/src/test/ui/rust-2018/edition-lint-paths-2018.rs index 09b31beb77..2005d8f4d7 100644 --- a/src/test/ui/rust-2018/edition-lint-paths-2018.rs +++ b/src/test/ui/rust-2018/edition-lint-paths-2018.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags:--extern edition_lint_paths // aux-build:edition-lint-paths.rs diff --git a/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs b/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs index 323c6e105f..950ad1f504 100644 --- a/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs +++ b/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] #![deny(explicit_outlives_requirements)] diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr index 13980c70a8..12a6110bfb 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ - = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)] + = note: `#[deny(unused_extern_crates)]` implied by `#[deny(rust_2018_idioms)]` error: aborting due to previous error diff --git a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr index 49aaff620d..957a04cd98 100644 --- a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr +++ b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr @@ -12,7 +12,7 @@ note: lint level defined here | LL | #![deny(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ - = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)] + = note: `#[deny(unused_extern_crates)]` implied by `#[deny(rust_2018_idioms)]` error: aborting due to previous error diff --git a/src/test/ui/rust-2018/macro-use-warned-against.rs b/src/test/ui/rust-2018/macro-use-warned-against.rs index 368b8daf24..6cd54aa68a 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.rs +++ b/src/test/ui/rust-2018/macro-use-warned-against.rs @@ -1,6 +1,6 @@ // aux-build:macro-use-warned-against.rs // aux-build:macro-use-warned-against2.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(macro_use_extern_crate, unused)] diff --git a/src/test/ui/rust-2018/macro-use-warned-against.stderr b/src/test/ui/rust-2018/macro-use-warned-against.stderr index c3e459606e..944b56e957 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.stderr +++ b/src/test/ui/rust-2018/macro-use-warned-against.stderr @@ -21,5 +21,5 @@ note: lint level defined here | LL | #![warn(macro_use_extern_crate, unused)] | ^^^^^^ - = note: #[warn(unused_imports)] implied by #[warn(unused)] + = note: `#[warn(unused_imports)]` implied by `#[warn(unused)]` diff --git a/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs b/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs index 3311ded553..2d4cb6514e 100644 --- a/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs +++ b/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // force-host // no-prefer-dynamic diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed index 14575d18c2..7ddd2f547f 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.fixed +++ b/src/test/ui/rust-2018/remove-extern-crate.fixed @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs index 0ee85f34e4..298b161402 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.rs +++ b/src/test/ui/rust-2018/remove-extern-crate.rs @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate diff --git a/src/test/ui/rust-2018/remove-extern-crate.stderr b/src/test/ui/rust-2018/remove-extern-crate.stderr index 5de0dfe961..4777565452 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.stderr +++ b/src/test/ui/rust-2018/remove-extern-crate.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ - = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)] + = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]` warning: `extern crate` is not idiomatic in the new edition --> $DIR/remove-extern-crate.rs:32:5 diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed b/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed index f0ca24714e..7d136667b6 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed @@ -2,7 +2,7 @@ // edition:2015 // run-rustfix // rustfix-only-machine-applicable -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.rs b/src/test/ui/rust-2018/suggestions-not-always-applicable.rs index f0ca24714e..7d136667b6 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.rs +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.rs @@ -2,7 +2,7 @@ // edition:2015 // run-rustfix // rustfix-only-machine-applicable -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr index 19e87b664c..5add50e87f 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: #[warn(absolute_paths_not_starting_with_crate)] implied by #[warn(rust_2018_compatibility)] + = note: `#[warn(absolute_paths_not_starting_with_crate)]` implied by `#[warn(rust_2018_compatibility)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #53130 diff --git a/src/test/ui/rust-2018/try-ident.fixed b/src/test/ui/rust-2018/try-ident.fixed index 5af13934e8..f86a401cdf 100644 --- a/src/test/ui/rust-2018/try-ident.fixed +++ b/src/test/ui/rust-2018/try-ident.fixed @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-ident.rs b/src/test/ui/rust-2018/try-ident.rs index faac13ab77..6cc6aa12ff 100644 --- a/src/test/ui/rust-2018/try-ident.rs +++ b/src/test/ui/rust-2018/try-ident.rs @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr index 9494603589..852e3e5aed 100644 --- a/src/test/ui/rust-2018/try-ident.stderr +++ b/src/test/ui/rust-2018/try-ident.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: #[warn(keyword_idents)] implied by #[warn(rust_2018_compatibility)] + = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #49716 diff --git a/src/test/ui/rust-2018/try-macro.fixed b/src/test/ui/rust-2018/try-macro.fixed index c65f0fc30e..a7b7d3faf5 100644 --- a/src/test/ui/rust-2018/try-macro.fixed +++ b/src/test/ui/rust-2018/try-macro.fixed @@ -1,11 +1,12 @@ // Test that `try!` macros are rewritten. // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] #![allow(unused_variables)] #![allow(dead_code)] +#![allow(deprecated)] fn foo() -> Result { let x: Result = Ok(22); diff --git a/src/test/ui/rust-2018/try-macro.rs b/src/test/ui/rust-2018/try-macro.rs index f435890a61..986e158eb6 100644 --- a/src/test/ui/rust-2018/try-macro.rs +++ b/src/test/ui/rust-2018/try-macro.rs @@ -1,11 +1,12 @@ // Test that `try!` macros are rewritten. // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] #![allow(unused_variables)] #![allow(dead_code)] +#![allow(deprecated)] fn foo() -> Result { let x: Result = Ok(22); diff --git a/src/test/ui/rust-2018/try-macro.stderr b/src/test/ui/rust-2018/try-macro.stderr index 40a4564cc3..fad1bb9f1b 100644 --- a/src/test/ui/rust-2018/try-macro.stderr +++ b/src/test/ui/rust-2018/try-macro.stderr @@ -1,5 +1,5 @@ warning: `try` is a keyword in the 2018 edition - --> $DIR/try-macro.rs:12:5 + --> $DIR/try-macro.rs:13:5 | LL | try!(x); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: #[warn(keyword_idents)] implied by #[warn(rust_2018_compatibility)] + = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #49716 diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr index 0414490909..27b8d0e216 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr @@ -4,8 +4,8 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolutio LL | pub use std::io; | ^^^ ambiguous name | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously + = note: `std` could refer to a built-in crate + = help: use `::std` to refer to this crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity-macros-nested.rs:13:13 | diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr index 71726371b7..44b34d2682 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr @@ -4,8 +4,8 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolutio LL | use std::io; | ^^^ ambiguous name | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously + = note: `std` could refer to a built-in crate + = help: use `::std` to refer to this crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity-macros.rs:12:9 | diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr index 1d22a39c3a..4129930bdb 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr @@ -4,8 +4,8 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolutio LL | pub use std::io; | ^^^ ambiguous name | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously + = note: `std` could refer to a built-in crate + = help: use `::std` to refer to this crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity-nested.rs:11:5 | diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr index 45751c9f64..e123b323e7 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr @@ -4,8 +4,8 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolutio LL | use std::io; | ^^^ ambiguous name | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously + = note: `std` could refer to a built-in crate + = help: use `::std` to refer to this crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity.rs:8:1 | diff --git a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs index 0c2da1884b..c6525869b0 100644 --- a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs +++ b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 fn main() { diff --git a/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs b/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs index 5c3c753f9a..9af520a076 100644 --- a/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs +++ b/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(decl_macro)] diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs index 9ec3a64113..446b2d0571 100644 --- a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs +++ b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags: --extern issue_56596_2 // aux-build:issue-56596-2.rs diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr b/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr index b1c0b461db..e39840d34d 100644 --- a/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr +++ b/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr @@ -4,8 +4,8 @@ error[E0659]: `issue_56596` is ambiguous (name vs any other name during import r LL | use issue_56596; | ^^^^^^^^^^^ ambiguous name | - = note: `issue_56596` could refer to an extern crate passed with `--extern` - = help: use `::issue_56596` to refer to this extern crate unambiguously + = note: `issue_56596` could refer to a crate passed with `--extern` + = help: use `::issue_56596` to refer to this crate unambiguously note: `issue_56596` could also refer to the module imported here --> $DIR/issue-56596.rs:11:5 | diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs index d717884c90..48c33d720d 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs @@ -1,11 +1,6 @@ // edition:2018 -// Built-in macro -use env as env_imported; //~ ERROR cannot import a built-in macro - // Tool attribute use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt` -fn main() { - env_imported!("PATH"); -} +fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr index 42daf7c6fb..97d4c73675 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr @@ -1,15 +1,9 @@ -error: cannot import a built-in macro - --> $DIR/prelude-fail.rs:4:5 - | -LL | use env as env_imported; - | ^^^^^^^^^^^^^^^^^^^ - error[E0432]: unresolved import `rustfmt` - --> $DIR/prelude-fail.rs:7:5 + --> $DIR/prelude-fail.rs:4:5 | LL | use rustfmt::skip as imported_rustfmt_skip; | ^^^^^^^ `rustfmt` is a tool module, not a module -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/rust-2018/uniform-paths/prelude.rs b/src/test/ui/rust-2018/uniform-paths/prelude.rs index 9a326b4c72..65763614ce 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // Macro imported with `#[macro_use] extern crate` @@ -10,9 +10,13 @@ use Vec as ImportedVec; // Built-in type use u8 as imported_u8; +// Built-in macro +use env as env_imported; + type A = imported_u8; fn main() { imported_vec![0]; ImportedVec::::new(); + env_imported!("PATH"); } diff --git a/src/test/ui/rust-unstable-column-gated.rs b/src/test/ui/rust-unstable-column-gated.rs index ed5e6f2489..053806ead2 100644 --- a/src/test/ui/rust-unstable-column-gated.rs +++ b/src/test/ui/rust-unstable-column-gated.rs @@ -1,4 +1,4 @@ fn main() { println!("{}", __rust_unstable_column!()); - //~^ERROR the __rust_unstable_column macro is unstable + //~^ ERROR use of unstable library feature '__rust_unstable_column' } diff --git a/src/test/ui/rust-unstable-column-gated.stderr b/src/test/ui/rust-unstable-column-gated.stderr index b9f1df2bcc..7db1b01fb0 100644 --- a/src/test/ui/rust-unstable-column-gated.stderr +++ b/src/test/ui/rust-unstable-column-gated.stderr @@ -1,8 +1,11 @@ -error: the __rust_unstable_column macro is unstable +error[E0658]: use of unstable library feature '__rust_unstable_column': internal implementation detail of the `panic` macro --> $DIR/rust-unstable-column-gated.rs:2:20 | LL | println!("{}", __rust_unstable_column!()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(__rust_unstable_column)]` to the crate attributes to enable error: aborting due to previous error +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/rustc-rust-log.rs b/src/test/ui/rustc-rust-log.rs similarity index 97% rename from src/test/run-pass/rustc-rust-log.rs rename to src/test/ui/rustc-rust-log.rs index b664257241..1c4252b23e 100644 --- a/src/test/run-pass/rustc-rust-log.rs +++ b/src/test/ui/rustc-rust-log.rs @@ -1,3 +1,4 @@ +// run-pass // This test is just checking that we won't ICE if logging is turned // on; don't bother trying to compare that (copious) output. (Note // also that this test potentially silly, since we do not build+test diff --git a/src/test/run-pass/rvalue-static-promotion.rs b/src/test/ui/rvalue-static-promotion.rs similarity index 96% rename from src/test/run-pass/rvalue-static-promotion.rs rename to src/test/ui/rvalue-static-promotion.rs index 0066217774..2d7e4ab398 100644 --- a/src/test/run-pass/rvalue-static-promotion.rs +++ b/src/test/ui/rvalue-static-promotion.rs @@ -1,3 +1,5 @@ +// run-pass + use std::cell::Cell; const NONE_CELL_STRING: Option> = None; diff --git a/src/test/ui/safe-extern-statics.stderr b/src/test/ui/safe-extern-statics.stderr index 86976a2c93..0948fad74e 100644 --- a/src/test/ui/safe-extern-statics.stderr +++ b/src/test/ui/safe-extern-statics.stderr @@ -4,7 +4,7 @@ error: use of extern static is unsafe and requires unsafe function or block (err LL | let a = A; | ^ | - = note: #[deny(safe_extern_statics)] on by default + = note: `#[deny(safe_extern_statics)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #36247 = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior diff --git a/src/test/ui/save-analysis/emit-notifications.polonius.stderr b/src/test/ui/save-analysis/emit-notifications.polonius.stderr new file mode 100644 index 0000000000..a1a1b8c63d --- /dev/null +++ b/src/test/ui/save-analysis/emit-notifications.polonius.stderr @@ -0,0 +1,2 @@ +{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications.polonius/save-analysis/libemit_notifications.json","emit":"save-analysis"} +{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications.polonius/libemit_notifications.rlib","emit":"link"} diff --git a/src/test/ui/save-analysis/emit-notifications.rs b/src/test/ui/save-analysis/emit-notifications.rs index ebc2717499..9179944a62 100644 --- a/src/test/ui/save-analysis/emit-notifications.rs +++ b/src/test/ui/save-analysis/emit-notifications.rs @@ -1,5 +1,5 @@ -// compile-pass -// compile-flags: -Zsave-analysis -Zemit-artifact-notifications +// build-pass (FIXME(62277): could be check-pass?) +// compile-flags: -Zsave-analysis --json artifacts // compile-flags: --crate-type rlib --error-format=json // ignore-pass // ^-- needed because otherwise, the .stderr file changes with --pass check diff --git a/src/test/run-pass/segfault-no-out-of-stack.rs b/src/test/ui/segfault-no-out-of-stack.rs similarity index 99% rename from src/test/run-pass/segfault-no-out-of-stack.rs rename to src/test/ui/segfault-no-out-of-stack.rs index e90efface6..626de4ed5b 100644 --- a/src/test/run-pass/segfault-no-out-of-stack.rs +++ b/src/test/ui/segfault-no-out-of-stack.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] // ignore-cloudabi can't run commands // ignore-emscripten can't run commands diff --git a/src/test/ui/self/explicit-self-closures.rs b/src/test/ui/self/explicit-self-closures.rs index 1217823da1..b409dfd7a1 100644 --- a/src/test/ui/self/explicit-self-closures.rs +++ b/src/test/ui/self/explicit-self-closures.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test to make sure that explicit self params work inside closures diff --git a/src/test/ui/self/self-in-typedefs.rs b/src/test/ui/self/self-in-typedefs.rs index e4fe7324ef..73f23a9cc1 100644 --- a/src/test/ui/self/self-in-typedefs.rs +++ b/src/test/ui/self/self-in-typedefs.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(untagged_unions)] diff --git a/src/test/ui/self/self-type-param.rs b/src/test/ui/self/self-type-param.rs index 57e01caa69..5eb8c3622e 100644 --- a/src/test/ui/self/self-type-param.rs +++ b/src/test/ui/self/self-type-param.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/semistatement-in-lambda.rs b/src/test/ui/semistatement-in-lambda.rs similarity index 96% rename from src/test/run-pass/semistatement-in-lambda.rs rename to src/test/ui/semistatement-in-lambda.rs index f00fbc363d..ebd55e0ba0 100644 --- a/src/test/run-pass/semistatement-in-lambda.rs +++ b/src/test/ui/semistatement-in-lambda.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] pub fn main() { diff --git a/src/test/run-pass/sepcomp/auxiliary/sepcomp-extern-lib.rs b/src/test/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs similarity index 100% rename from src/test/run-pass/sepcomp/auxiliary/sepcomp-extern-lib.rs rename to src/test/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs diff --git a/src/test/run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs b/src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs similarity index 100% rename from src/test/run-pass/sepcomp/auxiliary/sepcomp_cci_lib.rs rename to src/test/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs diff --git a/src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs b/src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs similarity index 100% rename from src/test/run-pass/sepcomp/auxiliary/sepcomp_lib.rs rename to src/test/ui/sepcomp/auxiliary/sepcomp_lib.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-cci.rs b/src/test/ui/sepcomp/sepcomp-cci.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-cci.rs rename to src/test/ui/sepcomp/sepcomp-cci.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-extern.rs b/src/test/ui/sepcomp/sepcomp-extern.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-extern.rs rename to src/test/ui/sepcomp/sepcomp-extern.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs b/src/test/ui/sepcomp/sepcomp-fns-backwards.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs rename to src/test/ui/sepcomp/sepcomp-fns-backwards.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-fns.rs b/src/test/ui/sepcomp/sepcomp-fns.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-fns.rs rename to src/test/ui/sepcomp/sepcomp-fns.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-lib-lto.rs b/src/test/ui/sepcomp/sepcomp-lib-lto.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-lib-lto.rs rename to src/test/ui/sepcomp/sepcomp-lib-lto.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-lib.rs b/src/test/ui/sepcomp/sepcomp-lib.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-lib.rs rename to src/test/ui/sepcomp/sepcomp-lib.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-statics.rs b/src/test/ui/sepcomp/sepcomp-statics.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-statics.rs rename to src/test/ui/sepcomp/sepcomp-statics.rs diff --git a/src/test/run-pass/sepcomp/sepcomp-unwind.rs b/src/test/ui/sepcomp/sepcomp-unwind.rs similarity index 100% rename from src/test/run-pass/sepcomp/sepcomp-unwind.rs rename to src/test/ui/sepcomp/sepcomp-unwind.rs diff --git a/src/test/run-pass/seq-compare.rs b/src/test/ui/seq-compare.rs similarity index 97% rename from src/test/run-pass/seq-compare.rs rename to src/test/ui/seq-compare.rs index cb90e3be0a..4078326b55 100644 --- a/src/test/run-pass/seq-compare.rs +++ b/src/test/ui/seq-compare.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { assert!(("hello".to_string() < "hellr".to_string())); assert!(("hello ".to_string() > "hello".to_string())); diff --git a/src/test/run-pass/shadow.rs b/src/test/ui/shadow.rs similarity index 97% rename from src/test/run-pass/shadow.rs rename to src/test/ui/shadow.rs index 03338d79da..2495c8f47e 100644 --- a/src/test/run-pass/shadow.rs +++ b/src/test/ui/shadow.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] fn foo(c: Vec ) { diff --git a/src/test/run-pass/shadowed-use-visibility.rs b/src/test/ui/shadowed-use-visibility.rs similarity index 91% rename from src/test/run-pass/shadowed-use-visibility.rs rename to src/test/ui/shadowed-use-visibility.rs index 83f9c0bedc..350fbfeaeb 100644 --- a/src/test/run-pass/shadowed-use-visibility.rs +++ b/src/test/ui/shadowed-use-visibility.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] mod foo { pub fn f() {} diff --git a/src/test/run-pass/shebang.rs b/src/test/ui/shebang.rs similarity index 63% rename from src/test/run-pass/shebang.rs rename to src/test/ui/shebang.rs index a5fbda1c1e..3d3ba468be 100644 --- a/src/test/run-pass/shebang.rs +++ b/src/test/ui/shebang.rs @@ -1,5 +1,5 @@ #!/usr/bin/env rustx -// http://rust-lang.org/COPYRIGHT. -// + +// run-pass pub fn main() { println!("Hello World"); } diff --git a/src/test/run-pass/signal-alternate-stack-cleanup.rs b/src/test/ui/signal-alternate-stack-cleanup.rs similarity index 98% rename from src/test/run-pass/signal-alternate-stack-cleanup.rs rename to src/test/ui/signal-alternate-stack-cleanup.rs index 6f2fa2a370..787ff51799 100644 --- a/src/test/run-pass/signal-alternate-stack-cleanup.rs +++ b/src/test/ui/signal-alternate-stack-cleanup.rs @@ -1,3 +1,4 @@ +// run-pass // Previously memory for alternate signal stack have been unmapped during // main thread exit while still being in use by signal handlers. This test // triggers this situation by sending signal from atexit handler. diff --git a/src/test/run-pass/signal-exit-status.rs b/src/test/ui/signal-exit-status.rs similarity index 97% rename from src/test/run-pass/signal-exit-status.rs rename to src/test/ui/signal-exit-status.rs index c22c035228..bd34a21816 100644 --- a/src/test/run-pass/signal-exit-status.rs +++ b/src/test/ui/signal-exit-status.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes diff --git a/src/test/run-pass/sigpipe-should-be-ignored.rs b/src/test/ui/sigpipe-should-be-ignored.rs similarity index 98% rename from src/test/run-pass/sigpipe-should-be-ignored.rs rename to src/test/ui/sigpipe-should-be-ignored.rs index 6c5bbd45a3..f472029b82 100644 --- a/src/test/run-pass/sigpipe-should-be-ignored.rs +++ b/src/test/ui/sigpipe-should-be-ignored.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] // Be sure that when a SIGPIPE would have been received that the entire process // doesn't die in a ball of fire, but rather it's gracefully handled. diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs index 8e67c27ef2..9a6dbe9d9a 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs @@ -30,13 +30,10 @@ fn main() { let z = f32x4(0.0, 0.0, 0.0, 0.0); unsafe { - simd_reduce_add_ordered(z, 0_f32); - simd_reduce_mul_ordered(z, 1_f32); - - simd_reduce_add_ordered(z, 2_f32); - //~^ ERROR accumulator of simd_reduce_add_ordered is not 0.0 - simd_reduce_mul_ordered(z, 3_f32); - //~^ ERROR accumulator of simd_reduce_mul_ordered is not 1.0 + simd_reduce_add_ordered(z, 0); + //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32` + simd_reduce_mul_ordered(z, 1); + //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32` let _: f32 = simd_reduce_and(x); //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32` @@ -56,16 +53,5 @@ fn main() { //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` let _: bool = simd_reduce_any(z); //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` - - foo(0_f32); } } - -#[inline(never)] -unsafe fn foo(x: f32) { - let z = f32x4(0.0, 0.0, 0.0, 0.0); - simd_reduce_add_ordered(z, x); - //~^ ERROR accumulator of simd_reduce_add_ordered is not a constant - simd_reduce_mul_ordered(z, x); - //~^ ERROR accumulator of simd_reduce_mul_ordered is not a constant -} diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr index 144571cb26..3863eeac3f 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr @@ -1,74 +1,62 @@ -error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not 0.0 - --> $DIR/simd-intrinsic-generic-reduction.rs:36:9 +error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` + --> $DIR/simd-intrinsic-generic-reduction.rs:33:9 | -LL | simd_reduce_add_ordered(z, 2_f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_reduce_add_ordered(z, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not 1.0 - --> $DIR/simd-intrinsic-generic-reduction.rs:38:9 +error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` + --> $DIR/simd-intrinsic-generic-reduction.rs:35:9 | -LL | simd_reduce_mul_ordered(z, 3_f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_reduce_mul_ordered(z, 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:41:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:38:22 | LL | let _: f32 = simd_reduce_and(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:43:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:40:22 | LL | let _: f32 = simd_reduce_or(x); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:45:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:42:22 | LL | let _: f32 = simd_reduce_xor(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:48:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:45:22 | LL | let _: f32 = simd_reduce_and(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:50:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:47:22 | LL | let _: f32 = simd_reduce_or(z); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:52:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:49:22 | LL | let _: f32 = simd_reduce_xor(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` - --> $DIR/simd-intrinsic-generic-reduction.rs:55:23 + --> $DIR/simd-intrinsic-generic-reduction.rs:52:23 | LL | let _: bool = simd_reduce_all(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` - --> $DIR/simd-intrinsic-generic-reduction.rs:57:23 + --> $DIR/simd-intrinsic-generic-reduction.rs:54:23 | LL | let _: bool = simd_reduce_any(z); | ^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not a constant - --> $DIR/simd-intrinsic-generic-reduction.rs:67:5 - | -LL | simd_reduce_add_ordered(z, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not a constant - --> $DIR/simd-intrinsic-generic-reduction.rs:69:5 - | -LL | simd_reduce_mul_ordered(z, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/run-pass/simd/simd-generics.rs b/src/test/ui/simd/simd-generics.rs similarity index 100% rename from src/test/run-pass/simd/simd-generics.rs rename to src/test/ui/simd/simd-generics.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-float-math.rs b/src/test/ui/simd/simd-intrinsic-float-math.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-float-math.rs rename to src/test/ui/simd/simd-intrinsic-float-math.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-float-minmax.rs b/src/test/ui/simd/simd-intrinsic-float-minmax.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-float-minmax.rs rename to src/test/ui/simd/simd-intrinsic-float-minmax.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-arithmetic-saturating.rs rename to src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-arithmetic.rs rename to src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-bitmask.rs rename to src/test/ui/simd/simd-intrinsic-generic-bitmask.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs b/src/test/ui/simd/simd-intrinsic-generic-cast.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-cast.rs rename to src/test/ui/simd/simd-intrinsic-generic-cast.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-comparison.rs b/src/test/ui/simd/simd-intrinsic-generic-comparison.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-comparison.rs rename to src/test/ui/simd/simd-intrinsic-generic-comparison.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-elements.rs b/src/test/ui/simd/simd-intrinsic-generic-elements.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-elements.rs rename to src/test/ui/simd/simd-intrinsic-generic-elements.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-gather.rs b/src/test/ui/simd/simd-intrinsic-generic-gather.rs similarity index 100% rename from src/test/run-pass/simd/simd-intrinsic-generic-gather.rs rename to src/test/ui/simd/simd-intrinsic-generic-gather.rs diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs similarity index 94% rename from src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs rename to src/test/ui/simd/simd-intrinsic-generic-reduction.rs index e3faa7c625..4195444a73 100644 --- a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-reduction.rs @@ -2,7 +2,7 @@ #![allow(non_camel_case_types)] // ignore-emscripten -// ignore-aarch64 FIXME: https://github.com/rust-lang/rust/issues/54510 +// min-system-llvm-version: 9.0 // Test that the simd_reduce_{op} intrinsics produce the correct results. @@ -124,14 +124,14 @@ fn main() { assert_eq!(r, 6_f32); let r: f32 = simd_reduce_mul_unordered(x); assert_eq!(r, -24_f32); - // FIXME: only works correctly for accumulator, 0: - // https://bugs.llvm.org/show_bug.cgi?id=36734 let r: f32 = simd_reduce_add_ordered(x, 0.); assert_eq!(r, 6_f32); - // FIXME: only works correctly for accumulator, 1: - // https://bugs.llvm.org/show_bug.cgi?id=36734 let r: f32 = simd_reduce_mul_ordered(x, 1.); assert_eq!(r, -24_f32); + let r: f32 = simd_reduce_add_ordered(x, 1.); + assert_eq!(r, 7_f32); + let r: f32 = simd_reduce_mul_ordered(x, 2.); + assert_eq!(r, -48_f32); let r: f32 = simd_reduce_min(x); assert_eq!(r, -2_f32); diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs b/src/test/ui/simd/simd-intrinsic-generic-select.rs similarity index 93% rename from src/test/run-pass/simd/simd-intrinsic-generic-select.rs rename to src/test/ui/simd/simd-intrinsic-generic-select.rs index f79b140494..22bda4fc9d 100644 --- a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-select.rs @@ -2,6 +2,10 @@ #![allow(non_camel_case_types)] // ignore-emscripten +// ignore-mips behavior of simd_select_bitmask is endian-specific +// ignore-mips64 behavior of simd_select_bitmask is endian-specific +// ignore-powerpc behavior of simd_select_bitmask is endian-specific +// ignore-powerpc64 behavior of simd_select_bitmask is endian-specific // Test that the simd_select intrinsics produces correct results. diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/ui/simd/simd-size-align.rs similarity index 100% rename from src/test/run-pass/simd/simd-size-align.rs rename to src/test/ui/simd/simd-size-align.rs diff --git a/src/test/run-pass/simd/simd-target-feature-mixup.rs b/src/test/ui/simd/simd-target-feature-mixup.rs similarity index 100% rename from src/test/run-pass/simd/simd-target-feature-mixup.rs rename to src/test/ui/simd/simd-target-feature-mixup.rs diff --git a/src/test/run-pass/simd/simd-type.rs b/src/test/ui/simd/simd-type.rs similarity index 100% rename from src/test/run-pass/simd/simd-type.rs rename to src/test/ui/simd/simd-type.rs diff --git a/src/test/run-pass/simple-infer.rs b/src/test/ui/simple-infer.rs similarity index 85% rename from src/test/run-pass/simple-infer.rs rename to src/test/ui/simple-infer.rs index 020c9c2651..561e4fdec7 100644 --- a/src/test/run-pass/simple-infer.rs +++ b/src/test/ui/simple-infer.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_mut)] diff --git a/src/test/run-pass/simple_global_asm.rs b/src/test/ui/simple_global_asm.rs similarity index 96% rename from src/test/run-pass/simple_global_asm.rs rename to src/test/ui/simple_global_asm.rs index c6ede34b29..d95fefebc0 100644 --- a/src/test/run-pass/simple_global_asm.rs +++ b/src/test/ui/simple_global_asm.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(global_asm)] #![feature(naked_functions)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs index 900e8434d4..ff9d6bd01c 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.rs @@ -9,4 +9,14 @@ fn a<'a>(x: &'a u32) { //~ ERROR `'a` only used once //~^ HELP elide the single-use lifetime } +struct Single<'a> { x: &'a u32 } +struct Double<'a, 'b> { f: &'a &'b u32 } + +fn center<'m>(_: Single<'m>) {} //~ ERROR `'m` only used once +//~^ HELP elide the single-use lifetime +fn left<'x, 'y>(foo: Double<'x, 'y>) -> &'x u32 { foo.f } //~ ERROR `'y` only used once +//~^ HELP elide the single-use lifetime +fn right<'x, 'y>(foo: Double<'x, 'y>) -> &'y u32 { foo.f } //~ ERROR `'x` only used once +//~^ HELP elide the single-use lifetime + fn main() { } diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr index 4bf08534b8..faaa7e2f1b 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr @@ -16,5 +16,37 @@ help: elide the single-use lifetime LL | fn a(x: &u32) { | -- -- -error: aborting due to previous error +error: lifetime parameter `'m` only used once + --> $DIR/one-use-in-fn-argument.rs:15:11 + | +LL | fn center<'m>(_: Single<'m>) {} + | ^^ -- ...is used only here + | | + | this lifetime... +help: elide the single-use lifetime + | +LL | fn center(_: Single<'_>) {} + | -- ^^ + +error: lifetime parameter `'y` only used once + --> $DIR/one-use-in-fn-argument.rs:17:13 + | +LL | fn left<'x, 'y>(foo: Double<'x, 'y>) -> &'x u32 { foo.f } + | ^^ this lifetime... -- ...is used only here +help: elide the single-use lifetime + | +LL | fn left<'x>(foo: Double<'x, '_>) -> &'x u32 { foo.f } + | -- ^^ + +error: lifetime parameter `'x` only used once + --> $DIR/one-use-in-fn-argument.rs:19:10 + | +LL | fn right<'x, 'y>(foo: Double<'x, 'y>) -> &'y u32 { foo.f } + | ^^ this lifetime... -- ...is used only here +help: elide the single-use lifetime + | +LL | fn right<'y>(foo: Double<'_, 'y>) -> &'y u32 { foo.f } + | -- ^^ + +error: aborting due to 4 previous errors diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs index 92b25cbf58..d9d7e66d0c 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs @@ -5,7 +5,7 @@ // (Normally, using `'static` would be preferred, but there are // times when that is not what you want.) -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-struct.rs b/src/test/ui/single-use-lifetime/one-use-in-struct.rs index 6c4d2a4a7a..7285324ef6 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-struct.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-struct.rs @@ -2,7 +2,7 @@ // even when they are only used once (since to not use a named // lifetime is illegal!) // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs b/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs index 4cdf1530a9..8efe806b6e 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs @@ -1,7 +1,7 @@ // Test that we DO NOT warn when lifetime name is used in // both the argument and return. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs b/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs index 375366e41c..09b01d8b05 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs @@ -1,7 +1,7 @@ // Test that we DO NOT warn when lifetime name is used multiple // arguments, or more than once in a single argument. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs b/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs index 63d03a2cf0..eb85a148e6 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs @@ -1,6 +1,6 @@ // Test that we DO NOT warn for a lifetime used twice in an impl. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs b/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs index d4a0d71713..fd8c899f4f 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs @@ -1,7 +1,7 @@ // Test that we DO NOT warn for a lifetime on an impl used in both // header and in an associated type. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/run-pass/size-and-align.rs b/src/test/ui/size-and-align.rs similarity index 97% rename from src/test/run-pass/size-and-align.rs rename to src/test/ui/size-and-align.rs index fb7ba68ffe..a32b5de729 100644 --- a/src/test/run-pass/size-and-align.rs +++ b/src/test/ui/size-and-align.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] enum clam { a(T, isize), b, } diff --git a/src/test/run-pass/sized-borrowed-pointer.rs b/src/test/ui/sized-borrowed-pointer.rs similarity index 93% rename from src/test/run-pass/sized-borrowed-pointer.rs rename to src/test/ui/sized-borrowed-pointer.rs index e5d5576153..319b802695 100644 --- a/src/test/run-pass/sized-borrowed-pointer.rs +++ b/src/test/ui/sized-borrowed-pointer.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Possibly-dynamic size of typaram should be cleared at pointer boundary. diff --git a/src/test/run-pass/sized-owned-pointer.rs b/src/test/ui/sized-owned-pointer.rs similarity index 94% rename from src/test/run-pass/sized-owned-pointer.rs rename to src/test/ui/sized-owned-pointer.rs index 8dd3227ba8..2abf0a1e0c 100644 --- a/src/test/run-pass/sized-owned-pointer.rs +++ b/src/test/ui/sized-owned-pointer.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Possibly-dynamic size of typaram should be cleared at pointer boundary. diff --git a/src/test/run-pass/sleep.rs b/src/test/ui/sleep.rs similarity index 97% rename from src/test/run-pass/sleep.rs rename to src/test/ui/sleep.rs index 7128b3cc7c..757578b847 100644 --- a/src/test/run-pass/sleep.rs +++ b/src/test/ui/sleep.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten no threads support // ignore-sgx no thread sleep support diff --git a/src/test/run-pass/slowparse-bstring.rs b/src/test/ui/slowparse-bstring.rs similarity index 99% rename from src/test/run-pass/slowparse-bstring.rs rename to src/test/ui/slowparse-bstring.rs index ee6be75be2..f3a6a66837 100644 --- a/src/test/run-pass/slowparse-bstring.rs +++ b/src/test/ui/slowparse-bstring.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-tidy-linelength // Issue #16624 diff --git a/src/test/run-pass/slowparse-string.rs b/src/test/ui/slowparse-string.rs similarity index 99% rename from src/test/run-pass/slowparse-string.rs rename to src/test/ui/slowparse-string.rs index a2bf26f1e2..6ebc61dae7 100644 --- a/src/test/run-pass/slowparse-string.rs +++ b/src/test/ui/slowparse-string.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-tidy-linelength // Issue #16624 diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr index 938edbe463..e0af720187 100644 --- a/src/test/ui/span/gated-features-attr-spans.stderr +++ b/src/test/ui/span/gated-features-attr-spans.stderr @@ -5,7 +5,7 @@ LL | #[repr(simd)] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(repr_simd)] to the crate attributes to enable + = help: add `#![feature(repr_simd)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs index 82899fc896..f51ea55d4e 100644 --- a/src/test/ui/span/issue-24690.rs +++ b/src/test/ui/span/issue-24690.rs @@ -1,7 +1,7 @@ //! A test to ensure that helpful `note` messages aren't emitted more often //! than necessary. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Although there are three warnings, we should only get two "lint level defined // here" notes pointing at the `warnings` span, one for each error type. diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index 0864497911..b2160e66a7 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unused_variables)] implied by #[warn(unused)] + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: variable `theTwo` should have a snake case name --> $DIR/issue-24690.rs:12:9 @@ -17,7 +17,7 @@ warning: variable `theTwo` should have a snake case name LL | let theTwo = 2; | ^^^^^^ help: convert the identifier to snake case: `the_two` | - = note: #[warn(non_snake_case)] on by default + = note: `#[warn(non_snake_case)]` on by default warning: variable `theOtherTwo` should have a snake case name --> $DIR/issue-24690.rs:13:9 diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr index 46f424b192..88dfee1cad 100644 --- a/src/test/ui/span/issue-27522.stderr +++ b/src/test/ui/span/issue-27522.stderr @@ -5,7 +5,7 @@ LL | fn handler(self: &SomeType); | ^^^^^^^^^ | = note: type must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error: aborting due to previous error diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs index e11be9e17f..14b2c8644e 100644 --- a/src/test/ui/span/issue-36530.rs +++ b/src/test/ui/span/issue-36530.rs @@ -1,9 +1,10 @@ // gate-test-custom_inner_attributes -#[foo] //~ ERROR is currently unknown to the compiler +#![feature(custom_attribute)] + +#[foo] mod foo { - #![foo] //~ ERROR is currently unknown to the compiler - //~| ERROR non-builtin inner attributes are unstable + #![foo] //~ ERROR non-builtin inner attributes are unstable } fn main() {} diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr index ee479d6c79..c6b7895e65 100644 --- a/src/test/ui/span/issue-36530.stderr +++ b/src/test/ui/span/issue-36530.stderr @@ -1,30 +1,12 @@ -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-36530.rs:3:3 - | -LL | #[foo] - | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable - error[E0658]: non-builtin inner attributes are unstable - --> $DIR/issue-36530.rs:5:5 + --> $DIR/issue-36530.rs:7:5 | LL | #![foo] | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54726 - = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable - -error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-36530.rs:5:8 - | -LL | #![foo] - | ^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.rs b/src/test/ui/span/issue-43927-non-ADT-derive.rs index add1758ddd..8f1599a5ab 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.rs +++ b/src/test/ui/span/issue-43927-non-ADT-derive.rs @@ -2,6 +2,9 @@ #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! //~^ ERROR `derive` may only be applied to structs, enums and unions +//~| ERROR cannot determine resolution for the derive macro `Debug` +//~| ERROR cannot determine resolution for the derive macro `PartialEq` +//~| ERROR cannot determine resolution for the derive macro `Eq` struct DerivedOn; fn main() {} diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.stderr b/src/test/ui/span/issue-43927-non-ADT-derive.stderr index e09a8a0e8f..47ce718600 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.stderr +++ b/src/test/ui/span/issue-43927-non-ADT-derive.stderr @@ -4,5 +4,29 @@ error: `derive` may only be applied to structs, enums and unions LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Debug, PartialEq, Eq)]` -error: aborting due to previous error +error: cannot determine resolution for the derive macro `Debug` + --> $DIR/issue-43927-non-ADT-derive.rs:3:11 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `PartialEq` + --> $DIR/issue-43927-non-ADT-derive.rs:3:18 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: cannot determine resolution for the derive macro `Eq` + --> $DIR/issue-43927-non-ADT-derive.rs:3:29 + | +LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | ^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to 4 previous errors diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 614638752f..36db5bea86 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -61,9 +61,11 @@ note: the candidate is defined in the trait `ManyImplTrait` LL | fn is_str() -> bool { | ^^^^^^^^^^^^^^^^^^^ = help: to disambiguate the method call, write `ManyImplTrait::is_str(t)` instead - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `is_str`, perhaps you need to implement it: - candidate #1: `ManyImplTrait` + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `is_str`, perhaps you need to restrict type parameter `T` with it: + | +LL | fn param_bound(t: T) -> bool { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.rs b/src/test/ui/span/issue28498-reject-lifetime-param.rs index 9bc01766be..1e71901578 100644 --- a/src/test/ui/span/issue28498-reject-lifetime-param.rs +++ b/src/test/ui/span/issue28498-reject-lifetime-param.rs @@ -16,9 +16,8 @@ struct Foo<'a>(u32, &'a ScribbleOnDrop); impl<'a> Drop for Foo<'a> { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is unsound, - // because destructor accesses borrowed data in `self.1` - // and we must force that to strictly outlive `self`. + // Use of `may_dangle` is unsound, because destructor accesses borrowed data + // in `self.1` and we must force that to strictly outlive `self`. println!("Dropping Foo({}, {:?})", self.0, self.1); } } diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.stderr b/src/test/ui/span/issue28498-reject-lifetime-param.stderr index 1dcb40e5d9..3119ddd03c 100644 --- a/src/test/ui/span/issue28498-reject-lifetime-param.stderr +++ b/src/test/ui/span/issue28498-reject-lifetime-param.stderr @@ -1,5 +1,5 @@ error[E0597]: `first_dropped` does not live long enough - --> $DIR/issue28498-reject-lifetime-param.rs:33:19 + --> $DIR/issue28498-reject-lifetime-param.rs:32:19 | LL | foo1 = Foo(1, &first_dropped); | ^^^^^^^^^^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.rs b/src/test/ui/span/issue28498-reject-passed-to-fn.rs index c59de5df41..dcd2e9ad4b 100644 --- a/src/test/ui/span/issue28498-reject-passed-to-fn.rs +++ b/src/test/ui/span/issue28498-reject-passed-to-fn.rs @@ -16,8 +16,7 @@ struct Foo(u32, T, Box fn(&'r T) -> String>); impl Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is unsound, - // because we pass `T` to the callback in `self.2` + // Use of `may_dangle` is unsound, because we pass `T` to the callback in `self.2` // below, and thus potentially read from borrowed data. println!("Dropping Foo({}, {})", self.0, (self.2)(&self.1)); } diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr index 214a6f6d65..60e8a648cd 100644 --- a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr +++ b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr @@ -1,5 +1,5 @@ error[E0597]: `first_dropped` does not live long enough - --> $DIR/issue28498-reject-passed-to-fn.rs:35:19 + --> $DIR/issue28498-reject-passed-to-fn.rs:34:19 | LL | foo1 = Foo(1, &first_dropped, Box::new(callback)); | ^^^^^^^^^^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/span/issue28498-reject-trait-bound.rs b/src/test/ui/span/issue28498-reject-trait-bound.rs index 8813180c89..444cebb19a 100644 --- a/src/test/ui/span/issue28498-reject-trait-bound.rs +++ b/src/test/ui/span/issue28498-reject-trait-bound.rs @@ -14,13 +14,12 @@ impl Drop for ScribbleOnDrop { } } -struct Foo(u32, T); +struct Foo(u32, T); -impl Drop for Foo { +impl Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is unsound, - // because we access `T` fmt method when we pass `self.1` - // below, and thus potentially read from borrowed data. + // Use of `may_dangle` is unsound, because we access `T` fmt method when we pass + // `self.1` below, and thus potentially read from borrowed data. println!("Dropping Foo({}, {:?})", self.0, self.1); } } diff --git a/src/test/ui/span/issue28498-reject-trait-bound.stderr b/src/test/ui/span/issue28498-reject-trait-bound.stderr index d4fe291bef..22e4a8205b 100644 --- a/src/test/ui/span/issue28498-reject-trait-bound.stderr +++ b/src/test/ui/span/issue28498-reject-trait-bound.stderr @@ -1,5 +1,5 @@ error[E0597]: `first_dropped` does not live long enough - --> $DIR/issue28498-reject-trait-bound.rs:35:19 + --> $DIR/issue28498-reject-trait-bound.rs:34:19 | LL | foo1 = Foo(1, &first_dropped); | ^^^^^^^^^^^^^^ borrowed value does not live long enough diff --git a/src/test/ui/span/macro-span-replacement.rs b/src/test/ui/span/macro-span-replacement.rs index c5998c1b40..04c7ab0ea5 100644 --- a/src/test/ui/span/macro-span-replacement.rs +++ b/src/test/ui/span/macro-span-replacement.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index 128e4ec121..8b65e798b6 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -12,5 +12,5 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(dead_code)] implied by #[warn(unused)] + = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` diff --git a/src/test/ui/span/multispan-import-lint.rs b/src/test/ui/span/multispan-import-lint.rs index 753c359997..a49c60e127 100644 --- a/src/test/ui/span/multispan-import-lint.rs +++ b/src/test/ui/span/multispan-import-lint.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/span/multispan-import-lint.stderr b/src/test/ui/span/multispan-import-lint.stderr index a730d081b7..a54c86cdb0 100644 --- a/src/test/ui/span/multispan-import-lint.stderr +++ b/src/test/ui/span/multispan-import-lint.stderr @@ -9,5 +9,5 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(unused_imports)] implied by #[warn(unused)] + = note: `#[warn(unused_imports)]` implied by `#[warn(unused)]` diff --git a/src/test/ui/span/unused-warning-point-at-signature.stderr b/src/test/ui/span/unused-warning-point-at-signature.stderr index 3007d90c99..83e2ec1987 100644 --- a/src/test/ui/span/unused-warning-point-at-signature.stderr +++ b/src/test/ui/span/unused-warning-point-at-signature.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(dead_code)] implied by #[warn(unused)] + = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` warning: struct is never constructed: `Struct` --> $DIR/unused-warning-point-at-signature.rs:12:1 diff --git a/src/test/ui/span/visibility-ty-params.stderr b/src/test/ui/span/visibility-ty-params.stderr index cdbede3c19..c2f0711b0c 100644 --- a/src/test/ui/span/visibility-ty-params.stderr +++ b/src/test/ui/span/visibility-ty-params.stderr @@ -4,19 +4,17 @@ error: unexpected generic arguments in path LL | m!{ S } | ^^^^^ +error[E0577]: expected module, found struct `S` + --> $DIR/visibility-ty-params.rs:6:5 + | +LL | m!{ S } + | ^^^^^ not a module + error: unexpected generic arguments in path --> $DIR/visibility-ty-params.rs:10:9 | LL | m!{ m<> } | ^^^ -error[E0577]: expected module, found struct `S` - --> $DIR/visibility-ty-params.rs:6:5 - | -LL | m!{ S } - | -^^^^ - | | - | help: a module with a similar name exists: `m` - error: aborting due to 3 previous errors diff --git a/src/test/run-pass/specialization/README.md b/src/test/ui/specialization/README-rpass.md similarity index 100% rename from src/test/run-pass/specialization/README.md rename to src/test/ui/specialization/README-rpass.md diff --git a/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs b/src/test/ui/specialization/assoc-ty-graph-cycle.rs similarity index 100% rename from src/test/run-pass/specialization/assoc-ty-graph-cycle.rs rename to src/test/ui/specialization/assoc-ty-graph-cycle.rs diff --git a/src/test/run-pass/specialization/auxiliary/cross_crates_defaults.rs b/src/test/ui/specialization/auxiliary/cross_crates_defaults.rs similarity index 100% rename from src/test/run-pass/specialization/auxiliary/cross_crates_defaults.rs rename to src/test/ui/specialization/auxiliary/cross_crates_defaults.rs diff --git a/src/test/run-pass/specialization/auxiliary/go_trait.rs b/src/test/ui/specialization/auxiliary/go_trait.rs similarity index 100% rename from src/test/run-pass/specialization/auxiliary/go_trait.rs rename to src/test/ui/specialization/auxiliary/go_trait.rs diff --git a/src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs b/src/test/ui/specialization/auxiliary/specialization_cross_crate.rs similarity index 100% rename from src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs rename to src/test/ui/specialization/auxiliary/specialization_cross_crate.rs diff --git a/src/test/run-pass/specialization/cross-crate-defaults.rs b/src/test/ui/specialization/cross-crate-defaults.rs similarity index 100% rename from src/test/run-pass/specialization/cross-crate-defaults.rs rename to src/test/ui/specialization/cross-crate-defaults.rs diff --git a/src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs rename to src/test/ui/specialization/defaultimpl/allowed-cross-crate.rs diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs b/src/test/ui/specialization/defaultimpl/auxiliary/go_trait.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs rename to src/test/ui/specialization/defaultimpl/auxiliary/go_trait.rs diff --git a/src/test/run-pass/specialization/defaultimpl/out-of-order.rs b/src/test/ui/specialization/defaultimpl/out-of-order.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/out-of-order.rs rename to src/test/ui/specialization/defaultimpl/out-of-order.rs diff --git a/src/test/run-pass/specialization/defaultimpl/overlap-projection.rs b/src/test/ui/specialization/defaultimpl/overlap-projection.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/overlap-projection.rs rename to src/test/ui/specialization/defaultimpl/overlap-projection.rs diff --git a/src/test/run-pass/specialization/defaultimpl/projection.rs b/src/test/ui/specialization/defaultimpl/projection.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/projection.rs rename to src/test/ui/specialization/defaultimpl/projection.rs diff --git a/src/test/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr b/src/test/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr index b95e62edaa..2cf6c586e4 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: for more information, see https://github.com/rust-lang/rust/issues/31844 - = help: add #![feature(specialization)] to the crate attributes to enable + = help: add `#![feature(specialization)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs rename to src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs diff --git a/src/test/ui/specialization/issue-36804.rs b/src/test/ui/specialization/issue-36804.rs new file mode 100644 index 0000000000..36cb939bc4 --- /dev/null +++ b/src/test/ui/specialization/issue-36804.rs @@ -0,0 +1,31 @@ +// check-pass +#![feature(specialization)] + +pub struct Cloned(I); + +impl<'a, I, T: 'a> Iterator for Cloned +where + I: Iterator, + T: Clone, +{ + type Item = T; + + fn next(&mut self) -> Option { + unimplemented!() + } +} + +impl<'a, I, T: 'a> Iterator for Cloned +where + I: Iterator, + T: Copy, +{ + fn count(self) -> usize { + unimplemented!() + } +} + +fn main() { + let a = [1,2,3,4]; + Cloned(a.iter()).count(); +} diff --git a/src/test/run-pass/specialization/issue-50452.rs b/src/test/ui/specialization/issue-50452.rs similarity index 100% rename from src/test/run-pass/specialization/issue-50452.rs rename to src/test/ui/specialization/issue-50452.rs diff --git a/src/test/run-pass/specialization/specialization-allowed-cross-crate.rs b/src/test/ui/specialization/specialization-allowed-cross-crate.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-allowed-cross-crate.rs rename to src/test/ui/specialization/specialization-allowed-cross-crate.rs diff --git a/src/test/run-pass/specialization/specialization-assoc-fns.rs b/src/test/ui/specialization/specialization-assoc-fns.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-assoc-fns.rs rename to src/test/ui/specialization/specialization-assoc-fns.rs diff --git a/src/test/run-pass/specialization/specialization-basics.rs b/src/test/ui/specialization/specialization-basics.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-basics.rs rename to src/test/ui/specialization/specialization-basics.rs diff --git a/src/test/run-pass/specialization/specialization-cross-crate-no-gate.rs b/src/test/ui/specialization/specialization-cross-crate-no-gate.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-cross-crate-no-gate.rs rename to src/test/ui/specialization/specialization-cross-crate-no-gate.rs diff --git a/src/test/run-pass/specialization/specialization-cross-crate.rs b/src/test/ui/specialization/specialization-cross-crate.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-cross-crate.rs rename to src/test/ui/specialization/specialization-cross-crate.rs diff --git a/src/test/run-pass/specialization/specialization-default-methods.rs b/src/test/ui/specialization/specialization-default-methods.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-default-methods.rs rename to src/test/ui/specialization/specialization-default-methods.rs diff --git a/src/test/ui/specialization/specialization-feature-gate-default.stderr b/src/test/ui/specialization/specialization-feature-gate-default.stderr index e649f2aa47..df2ad8a9b2 100644 --- a/src/test/ui/specialization/specialization-feature-gate-default.stderr +++ b/src/test/ui/specialization/specialization-feature-gate-default.stderr @@ -5,7 +5,7 @@ LL | default fn foo(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/31844 - = help: add #![feature(specialization)] to the crate attributes to enable + = help: add `#![feature(specialization)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/specialization/specialization-on-projection.rs b/src/test/ui/specialization/specialization-on-projection.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-on-projection.rs rename to src/test/ui/specialization/specialization-on-projection.rs diff --git a/src/test/run-pass/specialization/specialization-out-of-order.rs b/src/test/ui/specialization/specialization-out-of-order.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-out-of-order.rs rename to src/test/ui/specialization/specialization-out-of-order.rs diff --git a/src/test/run-pass/specialization/specialization-overlap-projection.rs b/src/test/ui/specialization/specialization-overlap-projection.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-overlap-projection.rs rename to src/test/ui/specialization/specialization-overlap-projection.rs diff --git a/src/test/run-pass/specialization/specialization-projection-alias.rs b/src/test/ui/specialization/specialization-projection-alias.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-projection-alias.rs rename to src/test/ui/specialization/specialization-projection-alias.rs diff --git a/src/test/run-pass/specialization/specialization-projection.rs b/src/test/ui/specialization/specialization-projection.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-projection.rs rename to src/test/ui/specialization/specialization-projection.rs diff --git a/src/test/run-pass/specialization/specialization-super-traits.rs b/src/test/ui/specialization/specialization-super-traits.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-super-traits.rs rename to src/test/ui/specialization/specialization-super-traits.rs diff --git a/src/test/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs rename to src/test/ui/specialization/specialization-translate-projections-with-lifetimes.rs diff --git a/src/test/run-pass/specialization/specialization-translate-projections-with-params.rs b/src/test/ui/specialization/specialization-translate-projections-with-params.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-translate-projections-with-params.rs rename to src/test/ui/specialization/specialization-translate-projections-with-params.rs diff --git a/src/test/run-pass/specialization/specialization-translate-projections.rs b/src/test/ui/specialization/specialization-translate-projections.rs similarity index 100% rename from src/test/run-pass/specialization/specialization-translate-projections.rs rename to src/test/ui/specialization/specialization-translate-projections.rs diff --git a/src/test/run-pass/sse2.rs b/src/test/ui/sse2.rs similarity index 98% rename from src/test/run-pass/sse2.rs rename to src/test/ui/sse2.rs index c58bf4520c..74f112464c 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/ui/sse2.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no std::env #![allow(stable_features)] diff --git a/src/test/ui/stability-attribute/stability-attribute-issue.stderr b/src/test/ui/stability-attribute/stability-attribute-issue.stderr index 7e6fbe1600..3463e77ec7 100644 --- a/src/test/ui/stability-attribute/stability-attribute-issue.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-issue.stderr @@ -5,7 +5,7 @@ LL | unstable(); | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/1 - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_test_feature': message --> $DIR/stability-attribute-issue.rs:10:5 @@ -14,7 +14,7 @@ LL | unstable_msg(); | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/2 - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/run-pass/stable-addr-of.rs b/src/test/ui/stable-addr-of.rs similarity index 90% rename from src/test/run-pass/stable-addr-of.rs rename to src/test/ui/stable-addr-of.rs index 2a256bbfa3..99839166e3 100644 --- a/src/test/run-pass/stable-addr-of.rs +++ b/src/test/ui/stable-addr-of.rs @@ -1,3 +1,4 @@ +// run-pass // Issue #2040 diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/ui/stack-probes-lto.rs similarity index 96% rename from src/test/run-pass/stack-probes-lto.rs rename to src/test/ui/stack-probes-lto.rs index 1274f032a3..9018ff4bfc 100644 --- a/src/test/run-pass/stack-probes-lto.rs +++ b/src/test/ui/stack-probes-lto.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-arm // ignore-aarch64 // ignore-mips diff --git a/src/test/run-pass/stack-probes.rs b/src/test/ui/stack-probes.rs similarity index 98% rename from src/test/run-pass/stack-probes.rs rename to src/test/ui/stack-probes.rs index 92a0cc3a07..1ab1d6df66 100644 --- a/src/test/run-pass/stack-probes.rs +++ b/src/test/ui/stack-probes.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-arm // ignore-aarch64 // ignore-mips @@ -49,6 +50,7 @@ fn main() { #[allow(unconditional_recursion)] fn recurse(array: &[u64]) { unsafe { black_box(array.as_ptr() as u64); } + #[allow(deprecated)] let local: [_; 1024] = unsafe { mem::uninitialized() }; recurse(&local); } diff --git a/src/test/ui/static/static-extern-type.rs b/src/test/ui/static/static-extern-type.rs index 3666982b4e..4fa48fa133 100644 --- a/src/test/ui/static/static-extern-type.rs +++ b/src/test/ui/static/static-extern-type.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_types)] pub mod a { diff --git a/src/test/ui/static_sized_requirement.rs b/src/test/ui/static_sized_requirement.rs index 0ee0637232..074280b7b6 100644 --- a/src/test/ui/static_sized_requirement.rs +++ b/src/test/ui/static_sized_requirement.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(no_core, lang_items)] #![no_core] diff --git a/src/test/run-pass/statics/auxiliary/static-function-pointer-aux.rs b/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs similarity index 100% rename from src/test/run-pass/statics/auxiliary/static-function-pointer-aux.rs rename to src/test/ui/statics/auxiliary/static-function-pointer-aux.rs diff --git a/src/test/run-pass/statics/auxiliary/static-methods-crate.rs b/src/test/ui/statics/auxiliary/static-methods-crate.rs similarity index 100% rename from src/test/run-pass/statics/auxiliary/static-methods-crate.rs rename to src/test/ui/statics/auxiliary/static-methods-crate.rs diff --git a/src/test/run-pass/statics/auxiliary/static_fn_inline_xc_aux.rs b/src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs similarity index 100% rename from src/test/run-pass/statics/auxiliary/static_fn_inline_xc_aux.rs rename to src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs diff --git a/src/test/run-pass/statics/auxiliary/static_fn_trait_xc_aux.rs b/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs similarity index 100% rename from src/test/run-pass/statics/auxiliary/static_fn_trait_xc_aux.rs rename to src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs diff --git a/src/test/run-pass/statics/auxiliary/static_mut_xc.rs b/src/test/ui/statics/auxiliary/static_mut_xc.rs similarity index 100% rename from src/test/run-pass/statics/auxiliary/static_mut_xc.rs rename to src/test/ui/statics/auxiliary/static_mut_xc.rs diff --git a/src/test/run-pass/statics/static-fn-inline-xc.rs b/src/test/ui/statics/static-fn-inline-xc.rs similarity index 100% rename from src/test/run-pass/statics/static-fn-inline-xc.rs rename to src/test/ui/statics/static-fn-inline-xc.rs diff --git a/src/test/run-pass/statics/static-fn-trait-xc.rs b/src/test/ui/statics/static-fn-trait-xc.rs similarity index 100% rename from src/test/run-pass/statics/static-fn-trait-xc.rs rename to src/test/ui/statics/static-fn-trait-xc.rs diff --git a/src/test/run-pass/statics/static-function-pointer-xc.rs b/src/test/ui/statics/static-function-pointer-xc.rs similarity index 100% rename from src/test/run-pass/statics/static-function-pointer-xc.rs rename to src/test/ui/statics/static-function-pointer-xc.rs diff --git a/src/test/run-pass/statics/static-function-pointer.rs b/src/test/ui/statics/static-function-pointer.rs similarity index 100% rename from src/test/run-pass/statics/static-function-pointer.rs rename to src/test/ui/statics/static-function-pointer.rs diff --git a/src/test/run-pass/statics/static-impl.rs b/src/test/ui/statics/static-impl.rs similarity index 100% rename from src/test/run-pass/statics/static-impl.rs rename to src/test/ui/statics/static-impl.rs diff --git a/src/test/run-pass/statics/static-method-in-trait-with-tps-intracrate.rs b/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs similarity index 100% rename from src/test/run-pass/statics/static-method-in-trait-with-tps-intracrate.rs rename to src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs diff --git a/src/test/run-pass/statics/static-method-xcrate.rs b/src/test/ui/statics/static-method-xcrate.rs similarity index 100% rename from src/test/run-pass/statics/static-method-xcrate.rs rename to src/test/ui/statics/static-method-xcrate.rs diff --git a/src/test/run-pass/statics/static-methods-in-traits.rs b/src/test/ui/statics/static-methods-in-traits.rs similarity index 100% rename from src/test/run-pass/statics/static-methods-in-traits.rs rename to src/test/ui/statics/static-methods-in-traits.rs diff --git a/src/test/run-pass/statics/static-methods-in-traits2.rs b/src/test/ui/statics/static-methods-in-traits2.rs similarity index 100% rename from src/test/run-pass/statics/static-methods-in-traits2.rs rename to src/test/ui/statics/static-methods-in-traits2.rs diff --git a/src/test/run-pass/statics/static-mut-foreign.rs b/src/test/ui/statics/static-mut-foreign.rs similarity index 100% rename from src/test/run-pass/statics/static-mut-foreign.rs rename to src/test/ui/statics/static-mut-foreign.rs diff --git a/src/test/run-pass/statics/static-mut-xc.rs b/src/test/ui/statics/static-mut-xc.rs similarity index 100% rename from src/test/run-pass/statics/static-mut-xc.rs rename to src/test/ui/statics/static-mut-xc.rs diff --git a/src/test/run-pass/statics/static-recursive.rs b/src/test/ui/statics/static-recursive.rs similarity index 100% rename from src/test/run-pass/statics/static-recursive.rs rename to src/test/ui/statics/static-recursive.rs diff --git a/src/test/run-pass/stdio-is-blocking.rs b/src/test/ui/stdio-is-blocking.rs similarity index 99% rename from src/test/run-pass/stdio-is-blocking.rs rename to src/test/ui/stdio-is-blocking.rs index 1824162b8b..e96406e46b 100644 --- a/src/test/run-pass/stdio-is-blocking.rs +++ b/src/test/ui/stdio-is-blocking.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes diff --git a/src/test/ui/stmt_expr_attrs_no_feature.stderr b/src/test/ui/stmt_expr_attrs_no_feature.stderr index 01372cc164..b6d0f9ec3d 100644 --- a/src/test/ui/stmt_expr_attrs_no_feature.stderr +++ b/src/test/ui/stmt_expr_attrs_no_feature.stderr @@ -5,7 +5,7 @@ LL | #[rustfmt::skip] | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:95:18 @@ -14,7 +14,7 @@ LL | fn y(a: [u8; #[rustc_dummy] 5]); | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:102:19 @@ -23,7 +23,7 @@ LL | const Y: u8 = #[rustc_dummy] 5; | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:108:19 @@ -32,7 +32,7 @@ LL | const Y: [u8; #[rustc_dummy] 5]; | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:114:18 @@ -41,7 +41,7 @@ LL | field2: [u8; #[rustc_dummy] 5] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:119:10 @@ -50,7 +50,7 @@ LL | [u8; #[rustc_dummy] 5] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:125:14 @@ -59,7 +59,7 @@ LL | [u8; #[rustc_dummy] 5] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:130:22 @@ -68,7 +68,7 @@ LL | field2: [u8; #[rustc_dummy] 5] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental --> $DIR/stmt_expr_attrs_no_feature.rs:138:14 @@ -77,7 +77,7 @@ LL | 6 => #[rustc_dummy] (), | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error: aborting due to 9 previous errors diff --git a/src/test/run-pass/str-concat.rs b/src/test/ui/str-concat.rs similarity index 94% rename from src/test/run-pass/str-concat.rs rename to src/test/ui/str-concat.rs index a0392f479c..fa2fc97d7b 100644 --- a/src/test/run-pass/str-concat.rs +++ b/src/test/ui/str-concat.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let a: String = "hello".to_string(); let b: String = "world".to_string(); diff --git a/src/test/run-pass/str-multiline.rs b/src/test/ui/str-multiline.rs similarity index 95% rename from src/test/run-pass/str-multiline.rs rename to src/test/ui/str-multiline.rs index faf992fabf..2b2e001d8b 100644 --- a/src/test/run-pass/str-multiline.rs +++ b/src/test/ui/str-multiline.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let a: String = "this \ is a test".to_string(); diff --git a/src/test/run-pass/string-box-error.rs b/src/test/ui/string-box-error.rs similarity index 97% rename from src/test/run-pass/string-box-error.rs rename to src/test/ui/string-box-error.rs index 944157d0b2..11a5bd07c3 100644 --- a/src/test/run-pass/string-box-error.rs +++ b/src/test/ui/string-box-error.rs @@ -1,3 +1,4 @@ +// run-pass // Ensure that both `Box` and `Box` can be // obtained from `String`. diff --git a/src/test/run-pass/string-escapes.rs b/src/test/ui/string-escapes.rs similarity index 88% rename from src/test/run-pass/string-escapes.rs rename to src/test/ui/string-escapes.rs index 6013173f31..cee5e27786 100644 --- a/src/test/run-pass/string-escapes.rs +++ b/src/test/ui/string-escapes.rs @@ -1,3 +1,5 @@ +// run-pass + fn main() { let x = "\\\\\ "; diff --git a/src/test/run-pass/struct-ctor-mangling.rs b/src/test/ui/struct-ctor-mangling.rs similarity index 95% rename from src/test/run-pass/struct-ctor-mangling.rs rename to src/test/ui/struct-ctor-mangling.rs index 5f5ee7cfe4..f242cb8457 100644 --- a/src/test/run-pass/struct-ctor-mangling.rs +++ b/src/test/ui/struct-ctor-mangling.rs @@ -1,3 +1,5 @@ +// run-pass + fn size_of_val(_: &T) -> usize { std::mem::size_of::() } diff --git a/src/test/run-pass/structs-enums/align-enum.rs b/src/test/ui/structs-enums/align-enum.rs similarity index 100% rename from src/test/run-pass/structs-enums/align-enum.rs rename to src/test/ui/structs-enums/align-enum.rs diff --git a/src/test/run-pass/structs-enums/align-struct.rs b/src/test/ui/structs-enums/align-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/align-struct.rs rename to src/test/ui/structs-enums/align-struct.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class.rs b/src/test/ui/structs-enums/auxiliary/cci_class.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class.rs rename to src/test/ui/structs-enums/auxiliary/cci_class.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class_2.rs b/src/test/ui/structs-enums/auxiliary/cci_class_2.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class_2.rs rename to src/test/ui/structs-enums/auxiliary/cci_class_2.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class_3.rs b/src/test/ui/structs-enums/auxiliary/cci_class_3.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class_3.rs rename to src/test/ui/structs-enums/auxiliary/cci_class_3.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class_4.rs b/src/test/ui/structs-enums/auxiliary/cci_class_4.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class_4.rs rename to src/test/ui/structs-enums/auxiliary/cci_class_4.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class_6.rs b/src/test/ui/structs-enums/auxiliary/cci_class_6.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class_6.rs rename to src/test/ui/structs-enums/auxiliary/cci_class_6.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class_cast.rs b/src/test/ui/structs-enums/auxiliary/cci_class_cast.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class_cast.rs rename to src/test/ui/structs-enums/auxiliary/cci_class_cast.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/cci_class_trait.rs b/src/test/ui/structs-enums/auxiliary/cci_class_trait.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/cci_class_trait.rs rename to src/test/ui/structs-enums/auxiliary/cci_class_trait.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/empty-struct.rs b/src/test/ui/structs-enums/auxiliary/empty-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/empty-struct.rs rename to src/test/ui/structs-enums/auxiliary/empty-struct.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs b/src/test/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs rename to src/test/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/namespaced_enums.rs b/src/test/ui/structs-enums/auxiliary/namespaced_enums.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/namespaced_enums.rs rename to src/test/ui/structs-enums/auxiliary/namespaced_enums.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/newtype_struct_xc.rs b/src/test/ui/structs-enums/auxiliary/newtype_struct_xc.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/newtype_struct_xc.rs rename to src/test/ui/structs-enums/auxiliary/newtype_struct_xc.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/struct_destructuring_cross_crate.rs b/src/test/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/struct_destructuring_cross_crate.rs rename to src/test/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/struct_variant_xc_aux.rs b/src/test/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/struct_variant_xc_aux.rs rename to src/test/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs diff --git a/src/test/run-pass/structs-enums/auxiliary/xcrate_struct_aliases.rs b/src/test/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs similarity index 100% rename from src/test/run-pass/structs-enums/auxiliary/xcrate_struct_aliases.rs rename to src/test/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs diff --git a/src/test/run-pass/structs-enums/borrow-tuple-fields.rs b/src/test/ui/structs-enums/borrow-tuple-fields.rs similarity index 100% rename from src/test/run-pass/structs-enums/borrow-tuple-fields.rs rename to src/test/ui/structs-enums/borrow-tuple-fields.rs diff --git a/src/test/run-pass/structs-enums/class-cast-to-trait-cross-crate-2.rs b/src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-cast-to-trait-cross-crate-2.rs rename to src/test/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs diff --git a/src/test/run-pass/structs-enums/class-cast-to-trait-multiple-types.rs b/src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-cast-to-trait-multiple-types.rs rename to src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs diff --git a/src/test/run-pass/structs-enums/class-cast-to-trait.rs b/src/test/ui/structs-enums/class-cast-to-trait.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-cast-to-trait.rs rename to src/test/ui/structs-enums/class-cast-to-trait.rs diff --git a/src/test/run-pass/structs-enums/class-dtor.rs b/src/test/ui/structs-enums/class-dtor.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-dtor.rs rename to src/test/ui/structs-enums/class-dtor.rs diff --git a/src/test/run-pass/structs-enums/class-exports.rs b/src/test/ui/structs-enums/class-exports.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-exports.rs rename to src/test/ui/structs-enums/class-exports.rs diff --git a/src/test/run-pass/structs-enums/class-impl-very-parameterized-trait.rs b/src/test/ui/structs-enums/class-impl-very-parameterized-trait.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-impl-very-parameterized-trait.rs rename to src/test/ui/structs-enums/class-impl-very-parameterized-trait.rs diff --git a/src/test/run-pass/structs-enums/class-implement-trait-cross-crate.rs b/src/test/ui/structs-enums/class-implement-trait-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-implement-trait-cross-crate.rs rename to src/test/ui/structs-enums/class-implement-trait-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/class-implement-traits.rs b/src/test/ui/structs-enums/class-implement-traits.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-implement-traits.rs rename to src/test/ui/structs-enums/class-implement-traits.rs diff --git a/src/test/run-pass/structs-enums/class-method-cross-crate.rs b/src/test/ui/structs-enums/class-method-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-method-cross-crate.rs rename to src/test/ui/structs-enums/class-method-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/class-methods-cross-crate.rs b/src/test/ui/structs-enums/class-methods-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-methods-cross-crate.rs rename to src/test/ui/structs-enums/class-methods-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/class-methods.rs b/src/test/ui/structs-enums/class-methods.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-methods.rs rename to src/test/ui/structs-enums/class-methods.rs diff --git a/src/test/run-pass/structs-enums/class-poly-methods-cross-crate.rs b/src/test/ui/structs-enums/class-poly-methods-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-poly-methods-cross-crate.rs rename to src/test/ui/structs-enums/class-poly-methods-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/class-poly-methods.rs b/src/test/ui/structs-enums/class-poly-methods.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-poly-methods.rs rename to src/test/ui/structs-enums/class-poly-methods.rs diff --git a/src/test/run-pass/structs-enums/class-separate-impl.rs b/src/test/ui/structs-enums/class-separate-impl.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-separate-impl.rs rename to src/test/ui/structs-enums/class-separate-impl.rs diff --git a/src/test/run-pass/structs-enums/class-str-field.rs b/src/test/ui/structs-enums/class-str-field.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-str-field.rs rename to src/test/ui/structs-enums/class-str-field.rs diff --git a/src/test/run-pass/structs-enums/class-typarams.rs b/src/test/ui/structs-enums/class-typarams.rs similarity index 100% rename from src/test/run-pass/structs-enums/class-typarams.rs rename to src/test/ui/structs-enums/class-typarams.rs diff --git a/src/test/run-pass/structs-enums/classes-cross-crate.rs b/src/test/ui/structs-enums/classes-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/classes-cross-crate.rs rename to src/test/ui/structs-enums/classes-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/classes-self-referential.rs b/src/test/ui/structs-enums/classes-self-referential.rs similarity index 100% rename from src/test/run-pass/structs-enums/classes-self-referential.rs rename to src/test/ui/structs-enums/classes-self-referential.rs diff --git a/src/test/run-pass/structs-enums/classes-simple-cross-crate.rs b/src/test/ui/structs-enums/classes-simple-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/classes-simple-cross-crate.rs rename to src/test/ui/structs-enums/classes-simple-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/classes-simple-method.rs b/src/test/ui/structs-enums/classes-simple-method.rs similarity index 100% rename from src/test/run-pass/structs-enums/classes-simple-method.rs rename to src/test/ui/structs-enums/classes-simple-method.rs diff --git a/src/test/run-pass/structs-enums/classes-simple.rs b/src/test/ui/structs-enums/classes-simple.rs similarity index 100% rename from src/test/run-pass/structs-enums/classes-simple.rs rename to src/test/ui/structs-enums/classes-simple.rs diff --git a/src/test/run-pass/structs-enums/classes.rs b/src/test/ui/structs-enums/classes.rs similarity index 100% rename from src/test/run-pass/structs-enums/classes.rs rename to src/test/ui/structs-enums/classes.rs diff --git a/src/test/run-pass/structs-enums/codegen-tag-static-padding.rs b/src/test/ui/structs-enums/codegen-tag-static-padding.rs similarity index 100% rename from src/test/run-pass/structs-enums/codegen-tag-static-padding.rs rename to src/test/ui/structs-enums/codegen-tag-static-padding.rs diff --git a/src/test/run-pass/structs-enums/compare-generic-enums.rs b/src/test/ui/structs-enums/compare-generic-enums.rs similarity index 100% rename from src/test/run-pass/structs-enums/compare-generic-enums.rs rename to src/test/ui/structs-enums/compare-generic-enums.rs diff --git a/src/test/run-pass/structs-enums/discrim-explicit-23030.rs b/src/test/ui/structs-enums/discrim-explicit-23030.rs similarity index 100% rename from src/test/run-pass/structs-enums/discrim-explicit-23030.rs rename to src/test/ui/structs-enums/discrim-explicit-23030.rs diff --git a/src/test/run-pass/structs-enums/empty-struct-braces.rs b/src/test/ui/structs-enums/empty-struct-braces.rs similarity index 100% rename from src/test/run-pass/structs-enums/empty-struct-braces.rs rename to src/test/ui/structs-enums/empty-struct-braces.rs diff --git a/src/test/run-pass/structs-enums/empty-tag.rs b/src/test/ui/structs-enums/empty-tag.rs similarity index 100% rename from src/test/run-pass/structs-enums/empty-tag.rs rename to src/test/ui/structs-enums/empty-tag.rs diff --git a/src/test/run-pass/structs-enums/enum-alignment.rs b/src/test/ui/structs-enums/enum-alignment.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-alignment.rs rename to src/test/ui/structs-enums/enum-alignment.rs diff --git a/src/test/run-pass/structs-enums/enum-clike-ffi-as-int.rs b/src/test/ui/structs-enums/enum-clike-ffi-as-int.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-clike-ffi-as-int.rs rename to src/test/ui/structs-enums/enum-clike-ffi-as-int.rs diff --git a/src/test/run-pass/structs-enums/enum-discr.rs b/src/test/ui/structs-enums/enum-discr.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-discr.rs rename to src/test/ui/structs-enums/enum-discr.rs diff --git a/src/test/run-pass/structs-enums/enum-discrim-autosizing.rs b/src/test/ui/structs-enums/enum-discrim-autosizing.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-discrim-autosizing.rs rename to src/test/ui/structs-enums/enum-discrim-autosizing.rs diff --git a/src/test/run-pass/structs-enums/enum-discrim-manual-sizing.rs b/src/test/ui/structs-enums/enum-discrim-manual-sizing.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-discrim-manual-sizing.rs rename to src/test/ui/structs-enums/enum-discrim-manual-sizing.rs diff --git a/src/test/run-pass/structs-enums/enum-discrim-range-overflow.rs b/src/test/ui/structs-enums/enum-discrim-range-overflow.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-discrim-range-overflow.rs rename to src/test/ui/structs-enums/enum-discrim-range-overflow.rs diff --git a/src/test/run-pass/structs-enums/enum-discrim-width-stuff.rs b/src/test/ui/structs-enums/enum-discrim-width-stuff.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-discrim-width-stuff.rs rename to src/test/ui/structs-enums/enum-discrim-width-stuff.rs diff --git a/src/test/run-pass/structs-enums/enum-disr-val-pretty.rs b/src/test/ui/structs-enums/enum-disr-val-pretty.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-disr-val-pretty.rs rename to src/test/ui/structs-enums/enum-disr-val-pretty.rs diff --git a/src/test/run-pass/structs-enums/enum-export-inheritance.rs b/src/test/ui/structs-enums/enum-export-inheritance.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-export-inheritance.rs rename to src/test/ui/structs-enums/enum-export-inheritance.rs diff --git a/src/test/run-pass/structs-enums/enum-layout-optimization.rs b/src/test/ui/structs-enums/enum-layout-optimization.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-layout-optimization.rs rename to src/test/ui/structs-enums/enum-layout-optimization.rs diff --git a/src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs b/src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs similarity index 99% rename from src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs rename to src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs index c971f567d9..78d8e5e3a5 100644 --- a/src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs +++ b/src/test/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs @@ -69,6 +69,7 @@ fn main() { unsafe { // This should be safe, because we don't match on it unless it's fully formed, // and it doesn't have a destructor. + #[allow(deprecated)] let mut dest: MyEnum = mem::uninitialized(); while buf.len() > 0 { match parse_my_enum(&mut dest, &mut buf) { diff --git a/src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs b/src/test/ui/structs-enums/enum-non-c-like-repr-c.rs similarity index 99% rename from src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs rename to src/test/ui/structs-enums/enum-non-c-like-repr-c.rs index 57ccf11450..1209533efd 100644 --- a/src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs +++ b/src/test/ui/structs-enums/enum-non-c-like-repr-c.rs @@ -69,6 +69,7 @@ fn main() { unsafe { // This should be safe, because we don't match on it unless it's fully formed, // and it doesn't have a destructor. + #[allow(deprecated)] let mut dest: MyEnum = mem::uninitialized(); while buf.len() > 0 { match parse_my_enum(&mut dest, &mut buf) { diff --git a/src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs b/src/test/ui/structs-enums/enum-non-c-like-repr-int.rs similarity index 99% rename from src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs rename to src/test/ui/structs-enums/enum-non-c-like-repr-int.rs index d297c895da..5dd9c1863d 100644 --- a/src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs +++ b/src/test/ui/structs-enums/enum-non-c-like-repr-int.rs @@ -65,6 +65,7 @@ fn main() { unsafe { // This should be safe, because we don't match on it unless it's fully formed, // and it doesn't have a destructor. + #[allow(deprecated)] let mut dest: MyEnum = mem::uninitialized(); while buf.len() > 0 { match parse_my_enum(&mut dest, &mut buf) { diff --git a/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs b/src/test/ui/structs-enums/enum-null-pointer-opt.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-null-pointer-opt.rs rename to src/test/ui/structs-enums/enum-null-pointer-opt.rs diff --git a/src/test/run-pass/structs-enums/enum-nullable-const-null-with-fields.rs b/src/test/ui/structs-enums/enum-nullable-const-null-with-fields.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-nullable-const-null-with-fields.rs rename to src/test/ui/structs-enums/enum-nullable-const-null-with-fields.rs diff --git a/src/test/run-pass/structs-enums/enum-nullable-simplifycfg-misopt.rs b/src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-nullable-simplifycfg-misopt.rs rename to src/test/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs diff --git a/src/test/run-pass/structs-enums/enum-univariant-repr.rs b/src/test/ui/structs-enums/enum-univariant-repr.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-univariant-repr.rs rename to src/test/ui/structs-enums/enum-univariant-repr.rs diff --git a/src/test/run-pass/structs-enums/enum-variants.rs b/src/test/ui/structs-enums/enum-variants.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-variants.rs rename to src/test/ui/structs-enums/enum-variants.rs diff --git a/src/test/run-pass/structs-enums/enum-vec-initializer.rs b/src/test/ui/structs-enums/enum-vec-initializer.rs similarity index 100% rename from src/test/run-pass/structs-enums/enum-vec-initializer.rs rename to src/test/ui/structs-enums/enum-vec-initializer.rs diff --git a/src/test/run-pass/structs-enums/export-abstract-tag.rs b/src/test/ui/structs-enums/export-abstract-tag.rs similarity index 100% rename from src/test/run-pass/structs-enums/export-abstract-tag.rs rename to src/test/ui/structs-enums/export-abstract-tag.rs diff --git a/src/test/run-pass/structs-enums/export-tag-variant.rs b/src/test/ui/structs-enums/export-tag-variant.rs similarity index 100% rename from src/test/run-pass/structs-enums/export-tag-variant.rs rename to src/test/ui/structs-enums/export-tag-variant.rs diff --git a/src/test/run-pass/structs-enums/expr-if-struct.rs b/src/test/ui/structs-enums/expr-if-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/expr-if-struct.rs rename to src/test/ui/structs-enums/expr-if-struct.rs diff --git a/src/test/run-pass/structs-enums/expr-match-struct.rs b/src/test/ui/structs-enums/expr-match-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/expr-match-struct.rs rename to src/test/ui/structs-enums/expr-match-struct.rs diff --git a/src/test/run-pass/structs-enums/field-destruction-order.rs b/src/test/ui/structs-enums/field-destruction-order.rs similarity index 100% rename from src/test/run-pass/structs-enums/field-destruction-order.rs rename to src/test/ui/structs-enums/field-destruction-order.rs diff --git a/src/test/run-pass/structs-enums/foreign-struct.rs b/src/test/ui/structs-enums/foreign-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/foreign-struct.rs rename to src/test/ui/structs-enums/foreign-struct.rs diff --git a/src/test/run-pass/structs-enums/functional-struct-upd.rs b/src/test/ui/structs-enums/functional-struct-upd.rs similarity index 100% rename from src/test/run-pass/structs-enums/functional-struct-upd.rs rename to src/test/ui/structs-enums/functional-struct-upd.rs diff --git a/src/test/run-pass/structs-enums/ivec-tag.rs b/src/test/ui/structs-enums/ivec-tag.rs similarity index 100% rename from src/test/run-pass/structs-enums/ivec-tag.rs rename to src/test/ui/structs-enums/ivec-tag.rs diff --git a/src/test/run-pass/structs-enums/module-qualified-struct-destructure.rs b/src/test/ui/structs-enums/module-qualified-struct-destructure.rs similarity index 100% rename from src/test/run-pass/structs-enums/module-qualified-struct-destructure.rs rename to src/test/ui/structs-enums/module-qualified-struct-destructure.rs diff --git a/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat-xc.rs b/src/test/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs similarity index 100% rename from src/test/run-pass/structs-enums/namespaced-enum-emulate-flat-xc.rs rename to src/test/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs diff --git a/src/test/run-pass/structs-enums/namespaced-enum-emulate-flat.rs b/src/test/ui/structs-enums/namespaced-enum-emulate-flat.rs similarity index 100% rename from src/test/run-pass/structs-enums/namespaced-enum-emulate-flat.rs rename to src/test/ui/structs-enums/namespaced-enum-emulate-flat.rs diff --git a/src/test/run-pass/structs-enums/namespaced-enum-glob-import-xcrate.rs b/src/test/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs similarity index 100% rename from src/test/run-pass/structs-enums/namespaced-enum-glob-import-xcrate.rs rename to src/test/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs diff --git a/src/test/run-pass/structs-enums/namespaced-enum-glob-import.rs b/src/test/ui/structs-enums/namespaced-enum-glob-import.rs similarity index 100% rename from src/test/run-pass/structs-enums/namespaced-enum-glob-import.rs rename to src/test/ui/structs-enums/namespaced-enum-glob-import.rs diff --git a/src/test/run-pass/structs-enums/namespaced-enums-xcrate.rs b/src/test/ui/structs-enums/namespaced-enums-xcrate.rs similarity index 100% rename from src/test/run-pass/structs-enums/namespaced-enums-xcrate.rs rename to src/test/ui/structs-enums/namespaced-enums-xcrate.rs diff --git a/src/test/run-pass/structs-enums/namespaced-enums.rs b/src/test/ui/structs-enums/namespaced-enums.rs similarity index 100% rename from src/test/run-pass/structs-enums/namespaced-enums.rs rename to src/test/ui/structs-enums/namespaced-enums.rs diff --git a/src/test/run-pass/structs-enums/nested-enum-same-names.rs b/src/test/ui/structs-enums/nested-enum-same-names.rs similarity index 100% rename from src/test/run-pass/structs-enums/nested-enum-same-names.rs rename to src/test/ui/structs-enums/nested-enum-same-names.rs diff --git a/src/test/run-pass/structs-enums/newtype-struct-drop-run.rs b/src/test/ui/structs-enums/newtype-struct-drop-run.rs similarity index 100% rename from src/test/run-pass/structs-enums/newtype-struct-drop-run.rs rename to src/test/ui/structs-enums/newtype-struct-drop-run.rs diff --git a/src/test/run-pass/structs-enums/newtype-struct-with-dtor.rs b/src/test/ui/structs-enums/newtype-struct-with-dtor.rs similarity index 100% rename from src/test/run-pass/structs-enums/newtype-struct-with-dtor.rs rename to src/test/ui/structs-enums/newtype-struct-with-dtor.rs diff --git a/src/test/run-pass/structs-enums/newtype-struct-xc-2.rs b/src/test/ui/structs-enums/newtype-struct-xc-2.rs similarity index 100% rename from src/test/run-pass/structs-enums/newtype-struct-xc-2.rs rename to src/test/ui/structs-enums/newtype-struct-xc-2.rs diff --git a/src/test/run-pass/structs-enums/newtype-struct-xc.rs b/src/test/ui/structs-enums/newtype-struct-xc.rs similarity index 100% rename from src/test/run-pass/structs-enums/newtype-struct-xc.rs rename to src/test/ui/structs-enums/newtype-struct-xc.rs diff --git a/src/test/run-pass/structs-enums/nonzero-enum.rs b/src/test/ui/structs-enums/nonzero-enum.rs similarity index 100% rename from src/test/run-pass/structs-enums/nonzero-enum.rs rename to src/test/ui/structs-enums/nonzero-enum.rs diff --git a/src/test/run-pass/structs-enums/numeric-fields.rs b/src/test/ui/structs-enums/numeric-fields.rs similarity index 100% rename from src/test/run-pass/structs-enums/numeric-fields.rs rename to src/test/ui/structs-enums/numeric-fields.rs diff --git a/src/test/run-pass/structs-enums/object-lifetime-default-from-ref-struct.rs b/src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/object-lifetime-default-from-ref-struct.rs rename to src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs diff --git a/src/test/run-pass/structs-enums/object-lifetime-default-from-rptr-struct.rs b/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/object-lifetime-default-from-rptr-struct.rs rename to src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs diff --git a/src/test/run-pass/structs-enums/rec-align-u32.rs b/src/test/ui/structs-enums/rec-align-u32.rs similarity index 100% rename from src/test/run-pass/structs-enums/rec-align-u32.rs rename to src/test/ui/structs-enums/rec-align-u32.rs diff --git a/src/test/run-pass/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs similarity index 100% rename from src/test/run-pass/structs-enums/rec-align-u64.rs rename to src/test/ui/structs-enums/rec-align-u64.rs diff --git a/src/test/run-pass/structs-enums/rec-auto.rs b/src/test/ui/structs-enums/rec-auto.rs similarity index 100% rename from src/test/run-pass/structs-enums/rec-auto.rs rename to src/test/ui/structs-enums/rec-auto.rs diff --git a/src/test/run-pass/structs-enums/rec-extend.rs b/src/test/ui/structs-enums/rec-extend.rs similarity index 100% rename from src/test/run-pass/structs-enums/rec-extend.rs rename to src/test/ui/structs-enums/rec-extend.rs diff --git a/src/test/run-pass/structs-enums/rec-tup.rs b/src/test/ui/structs-enums/rec-tup.rs similarity index 100% rename from src/test/run-pass/structs-enums/rec-tup.rs rename to src/test/ui/structs-enums/rec-tup.rs diff --git a/src/test/run-pass/structs-enums/rec.rs b/src/test/ui/structs-enums/rec.rs similarity index 100% rename from src/test/run-pass/structs-enums/rec.rs rename to src/test/ui/structs-enums/rec.rs diff --git a/src/test/run-pass/structs-enums/record-pat.rs b/src/test/ui/structs-enums/record-pat.rs similarity index 100% rename from src/test/run-pass/structs-enums/record-pat.rs rename to src/test/ui/structs-enums/record-pat.rs diff --git a/src/test/run-pass/structs-enums/resource-in-struct.rs b/src/test/ui/structs-enums/resource-in-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/resource-in-struct.rs rename to src/test/ui/structs-enums/resource-in-struct.rs diff --git a/src/test/run-pass/structs-enums/simple-generic-tag.rs b/src/test/ui/structs-enums/simple-generic-tag.rs similarity index 100% rename from src/test/run-pass/structs-enums/simple-generic-tag.rs rename to src/test/ui/structs-enums/simple-generic-tag.rs diff --git a/src/test/run-pass/structs-enums/simple-match-generic-tag.rs b/src/test/ui/structs-enums/simple-match-generic-tag.rs similarity index 100% rename from src/test/run-pass/structs-enums/simple-match-generic-tag.rs rename to src/test/ui/structs-enums/simple-match-generic-tag.rs diff --git a/src/test/run-pass/structs-enums/small-enum-range-edge.rs b/src/test/ui/structs-enums/small-enum-range-edge.rs similarity index 100% rename from src/test/run-pass/structs-enums/small-enum-range-edge.rs rename to src/test/ui/structs-enums/small-enum-range-edge.rs diff --git a/src/test/run-pass/structs-enums/small-enums-with-fields.rs b/src/test/ui/structs-enums/small-enums-with-fields.rs similarity index 100% rename from src/test/run-pass/structs-enums/small-enums-with-fields.rs rename to src/test/ui/structs-enums/small-enums-with-fields.rs diff --git a/src/test/run-pass/structs-enums/struct-aliases-xcrate.rs b/src/test/ui/structs-enums/struct-aliases-xcrate.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-aliases-xcrate.rs rename to src/test/ui/structs-enums/struct-aliases-xcrate.rs diff --git a/src/test/run-pass/structs-enums/struct-aliases.rs b/src/test/ui/structs-enums/struct-aliases.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-aliases.rs rename to src/test/ui/structs-enums/struct-aliases.rs diff --git a/src/test/run-pass/structs-enums/struct-destructuring-cross-crate.rs b/src/test/ui/structs-enums/struct-destructuring-cross-crate.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-destructuring-cross-crate.rs rename to src/test/ui/structs-enums/struct-destructuring-cross-crate.rs diff --git a/src/test/run-pass/structs-enums/struct-field-shorthand.rs b/src/test/ui/structs-enums/struct-field-shorthand.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-field-shorthand.rs rename to src/test/ui/structs-enums/struct-field-shorthand.rs diff --git a/src/test/run-pass/structs-enums/struct-like-variant-construct.rs b/src/test/ui/structs-enums/struct-like-variant-construct.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-like-variant-construct.rs rename to src/test/ui/structs-enums/struct-like-variant-construct.rs diff --git a/src/test/run-pass/structs-enums/struct-like-variant-match.rs b/src/test/ui/structs-enums/struct-like-variant-match.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-like-variant-match.rs rename to src/test/ui/structs-enums/struct-like-variant-match.rs diff --git a/src/test/run-pass/structs-enums/struct-lit-functional-no-fields.rs b/src/test/ui/structs-enums/struct-lit-functional-no-fields.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-lit-functional-no-fields.rs rename to src/test/ui/structs-enums/struct-lit-functional-no-fields.rs diff --git a/src/test/run-pass/structs-enums/struct-literal-dtor.rs b/src/test/ui/structs-enums/struct-literal-dtor.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-literal-dtor.rs rename to src/test/ui/structs-enums/struct-literal-dtor.rs diff --git a/src/test/run-pass/structs-enums/struct-new-as-field-name.rs b/src/test/ui/structs-enums/struct-new-as-field-name.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-new-as-field-name.rs rename to src/test/ui/structs-enums/struct-new-as-field-name.rs diff --git a/src/test/run-pass/structs-enums/struct-order-of-eval-1.rs b/src/test/ui/structs-enums/struct-order-of-eval-1.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-order-of-eval-1.rs rename to src/test/ui/structs-enums/struct-order-of-eval-1.rs diff --git a/src/test/run-pass/structs-enums/struct-order-of-eval-2.rs b/src/test/ui/structs-enums/struct-order-of-eval-2.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-order-of-eval-2.rs rename to src/test/ui/structs-enums/struct-order-of-eval-2.rs diff --git a/src/test/run-pass/structs-enums/struct-order-of-eval-3.rs b/src/test/ui/structs-enums/struct-order-of-eval-3.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-order-of-eval-3.rs rename to src/test/ui/structs-enums/struct-order-of-eval-3.rs diff --git a/src/test/run-pass/structs-enums/struct-order-of-eval-4.rs b/src/test/ui/structs-enums/struct-order-of-eval-4.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-order-of-eval-4.rs rename to src/test/ui/structs-enums/struct-order-of-eval-4.rs diff --git a/src/test/run-pass/structs-enums/struct-partial-move-1.rs b/src/test/ui/structs-enums/struct-partial-move-1.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-partial-move-1.rs rename to src/test/ui/structs-enums/struct-partial-move-1.rs diff --git a/src/test/run-pass/structs-enums/struct-partial-move-2.rs b/src/test/ui/structs-enums/struct-partial-move-2.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-partial-move-2.rs rename to src/test/ui/structs-enums/struct-partial-move-2.rs diff --git a/src/test/run-pass/structs-enums/struct-path-associated-type.rs b/src/test/ui/structs-enums/struct-path-associated-type.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-path-associated-type.rs rename to src/test/ui/structs-enums/struct-path-associated-type.rs diff --git a/src/test/run-pass/structs-enums/struct-path-self.rs b/src/test/ui/structs-enums/struct-path-self.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-path-self.rs rename to src/test/ui/structs-enums/struct-path-self.rs diff --git a/src/test/run-pass/structs-enums/struct-pattern-matching.rs b/src/test/ui/structs-enums/struct-pattern-matching.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-pattern-matching.rs rename to src/test/ui/structs-enums/struct-pattern-matching.rs diff --git a/src/test/run-pass/structs-enums/struct-return.rs b/src/test/ui/structs-enums/struct-return.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-return.rs rename to src/test/ui/structs-enums/struct-return.rs diff --git a/src/test/run-pass/structs-enums/struct-variant-field-visibility.rs b/src/test/ui/structs-enums/struct-variant-field-visibility.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct-variant-field-visibility.rs rename to src/test/ui/structs-enums/struct-variant-field-visibility.rs diff --git a/src/test/run-pass/structs-enums/struct_variant_xc.rs b/src/test/ui/structs-enums/struct_variant_xc.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct_variant_xc.rs rename to src/test/ui/structs-enums/struct_variant_xc.rs diff --git a/src/test/run-pass/structs-enums/struct_variant_xc_match.rs b/src/test/ui/structs-enums/struct_variant_xc_match.rs similarity index 100% rename from src/test/run-pass/structs-enums/struct_variant_xc_match.rs rename to src/test/ui/structs-enums/struct_variant_xc_match.rs diff --git a/src/test/run-pass/structs-enums/tag-align-dyn-u64.rs b/src/test/ui/structs-enums/tag-align-dyn-u64.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-align-dyn-u64.rs rename to src/test/ui/structs-enums/tag-align-dyn-u64.rs diff --git a/src/test/run-pass/structs-enums/tag-align-dyn-variants.rs b/src/test/ui/structs-enums/tag-align-dyn-variants.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-align-dyn-variants.rs rename to src/test/ui/structs-enums/tag-align-dyn-variants.rs diff --git a/src/test/run-pass/structs-enums/tag-align-shape.rs b/src/test/ui/structs-enums/tag-align-shape.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-align-shape.rs rename to src/test/ui/structs-enums/tag-align-shape.rs diff --git a/src/test/run-pass/structs-enums/tag-align-u64.rs b/src/test/ui/structs-enums/tag-align-u64.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-align-u64.rs rename to src/test/ui/structs-enums/tag-align-u64.rs diff --git a/src/test/run-pass/structs-enums/tag-disr-val-shape.rs b/src/test/ui/structs-enums/tag-disr-val-shape.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-disr-val-shape.rs rename to src/test/ui/structs-enums/tag-disr-val-shape.rs diff --git a/src/test/run-pass/structs-enums/tag-exports.rs b/src/test/ui/structs-enums/tag-exports.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-exports.rs rename to src/test/ui/structs-enums/tag-exports.rs diff --git a/src/test/run-pass/structs-enums/tag-in-block.rs b/src/test/ui/structs-enums/tag-in-block.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-in-block.rs rename to src/test/ui/structs-enums/tag-in-block.rs diff --git a/src/test/run-pass/structs-enums/tag-variant-disr-type-mismatch.rs b/src/test/ui/structs-enums/tag-variant-disr-type-mismatch.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-variant-disr-type-mismatch.rs rename to src/test/ui/structs-enums/tag-variant-disr-type-mismatch.rs diff --git a/src/test/run-pass/structs-enums/tag-variant-disr-val.rs b/src/test/ui/structs-enums/tag-variant-disr-val.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag-variant-disr-val.rs rename to src/test/ui/structs-enums/tag-variant-disr-val.rs diff --git a/src/test/run-pass/structs-enums/tag.rs b/src/test/ui/structs-enums/tag.rs similarity index 100% rename from src/test/run-pass/structs-enums/tag.rs rename to src/test/ui/structs-enums/tag.rs diff --git a/src/test/run-pass/structs-enums/tuple-struct-construct.rs b/src/test/ui/structs-enums/tuple-struct-construct.rs similarity index 100% rename from src/test/run-pass/structs-enums/tuple-struct-construct.rs rename to src/test/ui/structs-enums/tuple-struct-construct.rs diff --git a/src/test/run-pass/structs-enums/tuple-struct-constructor-pointer.rs b/src/test/ui/structs-enums/tuple-struct-constructor-pointer.rs similarity index 100% rename from src/test/run-pass/structs-enums/tuple-struct-constructor-pointer.rs rename to src/test/ui/structs-enums/tuple-struct-constructor-pointer.rs diff --git a/src/test/run-pass/structs-enums/tuple-struct-destructuring.rs b/src/test/ui/structs-enums/tuple-struct-destructuring.rs similarity index 100% rename from src/test/run-pass/structs-enums/tuple-struct-destructuring.rs rename to src/test/ui/structs-enums/tuple-struct-destructuring.rs diff --git a/src/test/run-pass/structs-enums/tuple-struct-matching.rs b/src/test/ui/structs-enums/tuple-struct-matching.rs similarity index 100% rename from src/test/run-pass/structs-enums/tuple-struct-matching.rs rename to src/test/ui/structs-enums/tuple-struct-matching.rs diff --git a/src/test/run-pass/structs-enums/tuple-struct-trivial.rs b/src/test/ui/structs-enums/tuple-struct-trivial.rs similarity index 100% rename from src/test/run-pass/structs-enums/tuple-struct-trivial.rs rename to src/test/ui/structs-enums/tuple-struct-trivial.rs diff --git a/src/test/run-pass/structs-enums/uninstantiable-struct.rs b/src/test/ui/structs-enums/uninstantiable-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/uninstantiable-struct.rs rename to src/test/ui/structs-enums/uninstantiable-struct.rs diff --git a/src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs b/src/test/ui/structs-enums/unit-like-struct-drop-run.rs similarity index 100% rename from src/test/run-pass/structs-enums/unit-like-struct-drop-run.rs rename to src/test/ui/structs-enums/unit-like-struct-drop-run.rs diff --git a/src/test/run-pass/structs-enums/unit-like-struct.rs b/src/test/ui/structs-enums/unit-like-struct.rs similarity index 100% rename from src/test/run-pass/structs-enums/unit-like-struct.rs rename to src/test/ui/structs-enums/unit-like-struct.rs diff --git a/src/test/run-pass/structs-enums/variant-structs-trivial.rs b/src/test/ui/structs-enums/variant-structs-trivial.rs similarity index 100% rename from src/test/run-pass/structs-enums/variant-structs-trivial.rs rename to src/test/ui/structs-enums/variant-structs-trivial.rs diff --git a/src/test/run-pass/structured-compare.rs b/src/test/ui/structured-compare.rs similarity index 98% rename from src/test/run-pass/structured-compare.rs rename to src/test/ui/structured-compare.rs index 56acc6bd7d..63d30c4da8 100644 --- a/src/test/run-pass/structured-compare.rs +++ b/src/test/ui/structured-compare.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] diff --git a/src/test/ui/substs-ppaux.normal.stderr b/src/test/ui/substs-ppaux.normal.stderr index 123dd86b90..b3b879ef9a 100644 --- a/src/test/ui/substs-ppaux.normal.stderr +++ b/src/test/ui/substs-ppaux.normal.stderr @@ -1,8 +1,14 @@ error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:16:17 | +LL | fn bar<'a, T>() where T: 'a {} + | --------------------------- fn() {>::bar::<'static, char>} defined here +... LL | let x: () = >::bar::<'static, char>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `>::bar::<'static, char>()` | = note: expected type `()` found type `fn() {>::bar::<'static, char>}` @@ -10,8 +16,14 @@ LL | let x: () = >::bar::<'static, char>; error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:25:17 | +LL | fn bar<'a, T>() where T: 'a {} + | --------------------------- fn() {>::bar::<'static, char>} defined here +... LL | let x: () = >::bar::<'static, char>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `>::bar::<'static, char>()` | = note: expected type `()` found type `fn() {>::bar::<'static, char>}` @@ -19,8 +31,14 @@ LL | let x: () = >::bar::<'static, char>; error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:33:17 | +LL | fn baz() {} + | -------- fn() {>::baz} defined here +... LL | let x: () = >::baz; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `>::baz()` | = note: expected type `()` found type `fn() {>::baz}` @@ -28,8 +46,14 @@ LL | let x: () = >::baz; error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:41:17 | +LL | fn foo<'z>() where &'z (): Sized { + | -------------------------------- fn() {foo::<'static>} defined here +... LL | let x: () = foo::<'static>; - | ^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `foo::<'static>()` | = note: expected type `()` found type `fn() {foo::<'static>}` diff --git a/src/test/ui/substs-ppaux.verbose.stderr b/src/test/ui/substs-ppaux.verbose.stderr index 9167346282..363018db23 100644 --- a/src/test/ui/substs-ppaux.verbose.stderr +++ b/src/test/ui/substs-ppaux.verbose.stderr @@ -1,8 +1,14 @@ error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:16:17 | +LL | fn bar<'a, T>() where T: 'a {} + | --------------------------- fn() {>::bar::} defined here +... LL | let x: () = >::bar::<'static, char>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `>::bar::<'static, char>()` | = note: expected type `()` found type `fn() {>::bar::}` @@ -10,8 +16,14 @@ LL | let x: () = >::bar::<'static, char>; error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:25:17 | +LL | fn bar<'a, T>() where T: 'a {} + | --------------------------- fn() {>::bar::} defined here +... LL | let x: () = >::bar::<'static, char>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `>::bar::<'static, char>()` | = note: expected type `()` found type `fn() {>::bar::}` @@ -19,8 +31,14 @@ LL | let x: () = >::bar::<'static, char>; error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:33:17 | +LL | fn baz() {} + | -------- fn() {>::baz} defined here +... LL | let x: () = >::baz; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `>::baz()` | = note: expected type `()` found type `fn() {>::baz}` @@ -28,8 +46,14 @@ LL | let x: () = >::baz; error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:41:17 | +LL | fn foo<'z>() where &'z (): Sized { + | -------------------------------- fn() {foo::} defined here +... LL | let x: () = foo::<'static>; - | ^^^^^^^^^^^^^^ expected (), found fn item + | ^^^^^^^^^^^^^^ + | | + | expected (), found fn item + | help: use parentheses to call this function: `foo::<'static>()` | = note: expected type `()` found type `fn() {foo::}` diff --git a/src/test/ui/suggestions/assoc-type-in-method-return.rs b/src/test/ui/suggestions/assoc-type-in-method-return.rs new file mode 100644 index 0000000000..9bde65998d --- /dev/null +++ b/src/test/ui/suggestions/assoc-type-in-method-return.rs @@ -0,0 +1,7 @@ +trait A { + type Bla; + fn to_bla(&self) -> Bla; + //~^ ERROR cannot find type `Bla` in this scope +} + +fn main() {} diff --git a/src/test/ui/suggestions/assoc-type-in-method-return.stderr b/src/test/ui/suggestions/assoc-type-in-method-return.stderr new file mode 100644 index 0000000000..bf908d36d2 --- /dev/null +++ b/src/test/ui/suggestions/assoc-type-in-method-return.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Bla` in this scope + --> $DIR/assoc-type-in-method-return.rs:3:25 + | +LL | fn to_bla(&self) -> Bla; + | ^^^ help: try: `Self::Bla` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs index 13c6308b97..74f63f2b0e 100644 --- a/src/test/ui/suggestions/attribute-typos.rs +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -1,13 +1,11 @@ -#[deprcated] //~ ERROR E0658 -fn foo() {} //~| HELP a built-in attribute with a similar name exists - //~| SUGGESTION deprecated - //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable +#[deprcated] //~ ERROR cannot find attribute macro `deprcated` in this scope +fn foo() {} -#[tests] //~ ERROR E0658 -fn bar() {} //~| HELP a built-in attribute with a similar name exists - //~| SUGGESTION test - //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable +#[tests] //~ ERROR cannot find attribute macro `tests` in this scope +fn bar() {} -#[rustc_err] //~ ERROR E0658 -fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable - // don't suggest rustc attributes +#[rustc_err] +//~^ ERROR cannot find attribute macro `rustc_err` in this scope +//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler + +fn main() {} diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index 8367ff20aa..6b2f591b9e 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -1,30 +1,30 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/attribute-typos.rs:11:3 +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_err] | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/attribute-typos.rs:6:3 +error: cannot find attribute macro `rustc_err` in this scope + --> $DIR/attribute-typos.rs:7:3 | -LL | #[tests] - | ^^^^^ help: a built-in attribute with a similar name exists: `test` +LL | #[rustc_err] + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error` + +error: cannot find attribute macro `tests` in this scope + --> $DIR/attribute-typos.rs:4:3 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable +LL | #[tests] + | ^^^^^ help: an attribute macro with a similar name exists: `test` -error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/auxiliary/issue-61963-1.rs b/src/test/ui/suggestions/auxiliary/issue-61963-1.rs new file mode 100644 index 0000000000..6c2df7e84e --- /dev/null +++ b/src/test/ui/suggestions/auxiliary/issue-61963-1.rs @@ -0,0 +1,40 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Group, TokenStream, TokenTree}; + +// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. + +#[proc_macro_derive(DomObject)] +pub fn expand_token_stream(input: TokenStream) -> TokenStream { + // Construct a dummy span - `#0 bytes(0..0)` - which is present in the input because + // of the specially crafted generated tokens in the `attribute-crate` proc-macro. + let dummy_span = input.clone().into_iter().nth(0).unwrap().span(); + + // Define what the macro would output if constructed properly from the source using syn/quote. + let output: TokenStream = "impl Bar for ((), Qux >) { } + impl Bar for ((), Box) { }".parse().unwrap(); + + let mut tokens: Vec<_> = output.into_iter().collect(); + // Adjust token spans to match the original crate (which would use `quote`). Some of the + // generated tokens point to the dummy span. + for token in tokens.iter_mut() { + if let TokenTree::Group(group) = token { + let mut tokens: Vec<_> = group.stream().into_iter().collect(); + for token in tokens.iter_mut().skip(2) { + token.set_span(dummy_span); + } + + let mut stream = TokenStream::new(); + stream.extend(tokens); + *group = Group::new(group.delimiter(), stream); + } + } + + let mut output = TokenStream::new(); + output.extend(tokens); + output +} diff --git a/src/test/ui/suggestions/auxiliary/issue-61963.rs b/src/test/ui/suggestions/auxiliary/issue-61963.rs new file mode 100644 index 0000000000..e86f1610ab --- /dev/null +++ b/src/test/ui/suggestions/auxiliary/issue-61963.rs @@ -0,0 +1,41 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Group, Spacing, Punct, TokenTree, TokenStream}; + +// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. + +#[proc_macro_attribute] +pub fn dom_struct(_: TokenStream, input: TokenStream) -> TokenStream { + // Construct the expected output tokens - the input but with a `#[derive(DomObject)]` applied. + let attributes: TokenStream = + "#[derive(DomObject)]".to_string().parse().unwrap(); + let output: TokenStream = attributes.into_iter() + .chain(input.into_iter()).collect(); + + let mut tokens: Vec<_> = output.into_iter().collect(); + // Adjust the spacing of `>` tokens to match what `quote` would produce. + for token in tokens.iter_mut() { + if let TokenTree::Group(group) = token { + let mut tokens: Vec<_> = group.stream().into_iter().collect(); + for token in tokens.iter_mut() { + if let TokenTree::Punct(p) = token { + if p.as_char() == '>' { + *p = Punct::new('>', Spacing::Alone); + } + } + } + + let mut stream = TokenStream::new(); + stream.extend(tokens); + *group = Group::new(group.delimiter(), stream); + } + } + + let mut output = TokenStream::new(); + output.extend(tokens); + output +} diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs new file mode 100644 index 0000000000..a8ea3faefe --- /dev/null +++ b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs @@ -0,0 +1,19 @@ +fn foo(a: usize, b: usize) -> usize { a } + +struct S(usize, usize); + +trait T { + fn baz(x: usize, y: usize) -> usize { x } +} + +fn main() { + let _: usize = foo(_, _); + //~^ ERROR expected expression + //~| ERROR expected expression + let _: S = S(_, _); + //~^ ERROR expected expression + //~| ERROR expected expression + let _: usize = T::baz(_, _); + //~^ ERROR expected expression + //~| ERROR expected expression +} diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr new file mode 100644 index 0000000000..a6d1c4b859 --- /dev/null +++ b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr @@ -0,0 +1,38 @@ +error: expected expression, found reserved identifier `_` + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24 + | +LL | let _: usize = foo(_, _); + | ^ expected expression + +error: expected expression, found reserved identifier `_` + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27 + | +LL | let _: usize = foo(_, _); + | ^ expected expression + +error: expected expression, found reserved identifier `_` + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:18 + | +LL | let _: S = S(_, _); + | ^ expected expression + +error: expected expression, found reserved identifier `_` + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:21 + | +LL | let _: S = S(_, _); + | ^ expected expression + +error: expected expression, found reserved identifier `_` + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:27 + | +LL | let _: usize = T::baz(_, _); + | ^ expected expression + +error: expected expression, found reserved identifier `_` + --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:30 + | +LL | let _: usize = T::baz(_, _); + | ^ expected expression + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs new file mode 100644 index 0000000000..9b6b107481 --- /dev/null +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs @@ -0,0 +1,45 @@ +fn foo(a: usize, b: usize) -> usize { a } + +fn bar() -> usize { 42 } + +struct S(usize, usize); +enum E { + A(usize), + B { a: usize }, +} +struct V(); + +trait T { + fn baz(x: usize, y: usize) -> usize { x } + fn bat(x: usize) -> usize { 42 } + fn bax(x: usize) -> usize { 42 } + fn bach(x: usize) -> usize; + fn ban(&self) -> usize { 42 } + fn bal(&self) -> usize; +} + +struct X; + +impl T for X { + fn bach(x: usize) -> usize { 42 } + fn bal(&self) -> usize { 42 } +} + +fn main() { + let _: usize = foo; //~ ERROR mismatched types + let _: S = S; //~ ERROR mismatched types + let _: usize = bar; //~ ERROR mismatched types + let _: V = V; //~ ERROR mismatched types + let _: usize = T::baz; //~ ERROR mismatched types + let _: usize = T::bat; //~ ERROR mismatched types + let _: E = E::A; //~ ERROR mismatched types + let _: E = E::B; //~ ERROR expected value, found struct variant `E::B` + let _: usize = X::baz; //~ ERROR mismatched types + let _: usize = X::bat; //~ ERROR mismatched types + let _: usize = X::bax; //~ ERROR mismatched types + let _: usize = X::bach; //~ ERROR mismatched types + let _: usize = X::ban; //~ ERROR mismatched types + let _: usize = X::bal; //~ ERROR mismatched types + let _: usize = X.ban; //~ ERROR attempted to take value of method + let _: usize = X.bal; //~ ERROR attempted to take value of method +} diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr new file mode 100644 index 0000000000..0686b56f97 --- /dev/null +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -0,0 +1,220 @@ +error[E0423]: expected value, found struct variant `E::B` + --> $DIR/fn-or-tuple-struct-without-args.rs:36:16 + | +LL | let _: E = E::B; + | ^^^- + | | | + | | help: a tuple variant with a similar name exists: `A` + | did you mean `E::B { /* fields */ }`? + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:29:20 + | +LL | fn foo(a: usize, b: usize) -> usize { a } + | ----------------------------------- fn(usize, usize) -> usize {foo} defined here +... +LL | let _: usize = foo; + | ^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `foo(a, b)` + | + = note: expected type `usize` + found type `fn(usize, usize) -> usize {foo}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:30:16 + | +LL | struct S(usize, usize); + | ----------------------- fn(usize, usize) -> S {S} defined here +... +LL | let _: S = S; + | ^ + | | + | expected struct `S`, found fn item + | help: use parentheses to instantiate this tuple struct: `S(_, _)` + | + = note: expected type `S` + found type `fn(usize, usize) -> S {S}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:31:20 + | +LL | fn bar() -> usize { 42 } + | ----------------- fn() -> usize {bar} defined here +... +LL | let _: usize = bar; + | ^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `bar()` + | + = note: expected type `usize` + found type `fn() -> usize {bar}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:32:16 + | +LL | struct V(); + | ----------- fn() -> V {V} defined here +... +LL | let _: V = V; + | ^ + | | + | expected struct `V`, found fn item + | help: use parentheses to instantiate this tuple struct: `V()` + | + = note: expected type `V` + found type `fn() -> V {V}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:33:20 + | +LL | fn baz(x: usize, y: usize) -> usize { x } + | ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here +... +LL | let _: usize = T::baz; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `T::baz(x, y)` + | + = note: expected type `usize` + found type `fn(usize, usize) -> usize {<_ as T>::baz}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:34:20 + | +LL | fn bat(x: usize) -> usize { 42 } + | ------------------------- fn(usize) -> usize {<_ as T>::bat} defined here +... +LL | let _: usize = T::bat; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `T::bat(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {<_ as T>::bat}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:35:16 + | +LL | A(usize), + | -------- fn(usize) -> E {E::A} defined here +... +LL | let _: E = E::A; + | ^^^^ + | | + | expected enum `E`, found fn item + | help: use parentheses to instantiate this tuple variant: `E::A(_)` + | + = note: expected type `E` + found type `fn(usize) -> E {E::A}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:37:20 + | +LL | fn baz(x: usize, y: usize) -> usize { x } + | ----------------------------------- fn(usize, usize) -> usize {::baz} defined here +... +LL | let _: usize = X::baz; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::baz(x, y)` + | + = note: expected type `usize` + found type `fn(usize, usize) -> usize {::baz}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:38:20 + | +LL | fn bat(x: usize) -> usize { 42 } + | ------------------------- fn(usize) -> usize {::bat} defined here +... +LL | let _: usize = X::bat; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bat(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {::bat}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:39:20 + | +LL | fn bax(x: usize) -> usize { 42 } + | ------------------------- fn(usize) -> usize {::bax} defined here +... +LL | let _: usize = X::bax; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bax(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {::bax}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:40:20 + | +LL | fn bach(x: usize) -> usize; + | --------------------------- fn(usize) -> usize {::bach} defined here +... +LL | let _: usize = X::bach; + | ^^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bach(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {::bach}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:41:20 + | +LL | fn ban(&self) -> usize { 42 } + | ---------------------- for<'r> fn(&'r X) -> usize {::ban} defined here +... +LL | let _: usize = X::ban; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::ban(_)` + | + = note: expected type `usize` + found type `for<'r> fn(&'r X) -> usize {::ban}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:42:20 + | +LL | fn bal(&self) -> usize; + | ----------------------- for<'r> fn(&'r X) -> usize {::bal} defined here +... +LL | let _: usize = X::bal; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bal(_)` + | + = note: expected type `usize` + found type `for<'r> fn(&'r X) -> usize {::bal}` + +error[E0615]: attempted to take value of method `ban` on type `X` + --> $DIR/fn-or-tuple-struct-without-args.rs:43:22 + | +LL | let _: usize = X.ban; + | ^^^ help: use parentheses to call the method: `ban()` + +error[E0615]: attempted to take value of method `bal` on type `X` + --> $DIR/fn-or-tuple-struct-without-args.rs:44:22 + | +LL | let _: usize = X.bal; + | ^^^ help: use parentheses to call the method: `bal()` + +error: aborting due to 16 previous errors + +Some errors have detailed explanations: E0308, E0423, E0615. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/issue-21673.rs b/src/test/ui/suggestions/issue-21673.rs new file mode 100644 index 0000000000..9d66cae056 --- /dev/null +++ b/src/test/ui/suggestions/issue-21673.rs @@ -0,0 +1,13 @@ +trait Foo { + fn method(&self) {} +} + +fn call_method(x: &T) { + x.method() //~ ERROR E0599 +} + +fn call_method_2(x: T) { + x.method() //~ ERROR E0599 +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-21673.stderr b/src/test/ui/suggestions/issue-21673.stderr new file mode 100644 index 0000000000..6cf71c8b7c --- /dev/null +++ b/src/test/ui/suggestions/issue-21673.stderr @@ -0,0 +1,27 @@ +error[E0599]: no method named `method` found for type `&T` in the current scope + --> $DIR/issue-21673.rs:6:7 + | +LL | x.method() + | ^^^^^^ + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it: + | +LL | fn call_method(x: &T) { + | ^^^^^^^^ + +error[E0599]: no method named `method` found for type `T` in the current scope + --> $DIR/issue-21673.rs:10:7 + | +LL | x.method() + | ^^^^^^ + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it: + | +LL | fn call_method_2(x: T) { + | ^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/issue-57672.rs b/src/test/ui/suggestions/issue-57672.rs index 1773f72fc7..0881a631f3 100644 --- a/src/test/ui/suggestions/issue-57672.rs +++ b/src/test/ui/suggestions/issue-57672.rs @@ -1,6 +1,6 @@ // aux-build:foo.rs // compile-flags:--extern foo -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![deny(unused_extern_crates)] diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs new file mode 100644 index 0000000000..e83b0b4d63 --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.rs @@ -0,0 +1,5 @@ +struct X {} +fn main() { + vec![X]; //… + //~^ ERROR expected value, found struct `X` +} diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr new file mode 100644 index 0000000000..6d7d98ac6a --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -0,0 +1,9 @@ +error[E0423]: expected value, found struct `X` + --> $DIR/issue-61226.rs:3:10 + | +LL | vec![X]; //… + | ^ did you mean `X { /* fields */ }`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/suggestions/issue-61963.rs b/src/test/ui/suggestions/issue-61963.rs new file mode 100644 index 0000000000..c9d738f5a2 --- /dev/null +++ b/src/test/ui/suggestions/issue-61963.rs @@ -0,0 +1,24 @@ +// aux-build:issue-61963.rs +// aux-build:issue-61963-1.rs +#![deny(bare_trait_objects)] + +#[macro_use] +extern crate issue_61963; +#[macro_use] +extern crate issue_61963_1; + +// This test checks that the bare trait object lint does not trigger on macro attributes that +// generate code which would trigger the lint. + +pub struct Baz; +pub trait Bar { } +pub struct Qux(T); + +#[dom_struct] +pub struct Foo { + qux: Qux>, + bar: Box, + //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr new file mode 100644 index 0000000000..46943f4006 --- /dev/null +++ b/src/test/ui/suggestions/issue-61963.stderr @@ -0,0 +1,14 @@ +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:20:14 + | +LL | bar: Box, + | ^^^ help: use `dyn`: `dyn Bar` + | +note: lint level defined here + --> $DIR/issue-61963.rs:3:9 + | +LL | #![deny(bare_trait_objects)] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/issue-62843.rs b/src/test/ui/suggestions/issue-62843.rs new file mode 100644 index 0000000000..d96b12fd15 --- /dev/null +++ b/src/test/ui/suggestions/issue-62843.rs @@ -0,0 +1,5 @@ +fn main() { + let line = String::from("abc"); + let pattern = String::from("bc"); + println!("{:?}", line.find(pattern)); //~ ERROR E0277 +} diff --git a/src/test/ui/suggestions/issue-62843.stderr b/src/test/ui/suggestions/issue-62843.stderr new file mode 100644 index 0000000000..cc27b5b49b --- /dev/null +++ b/src/test/ui/suggestions/issue-62843.stderr @@ -0,0 +1,13 @@ +error[E0277]: expected a `std::ops::FnMut<(char,)>` closure, found `std::string::String` + --> $DIR/issue-62843.rs:4:27 + | +LL | println!("{:?}", line.find(pattern)); + | ^^^^ expected an `FnMut<(char,)>` closure, found `std::string::String` + | + = help: the trait `std::ops::FnMut<(char,)>` is not implemented for `std::string::String` + = note: borrowing the `std::string::String` might fix the problem + = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `std::string::String` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/suggest-variants.stderr b/src/test/ui/suggestions/suggest-variants.stderr index ef0ba70c34..b4338e2055 100644 --- a/src/test/ui/suggestions/suggest-variants.stderr +++ b/src/test/ui/suggestions/suggest-variants.stderr @@ -23,9 +23,7 @@ LL | enum Shape { | ---------- variant `Rombus` not found here ... LL | println!("My shape is {:?}", Shape::Rombus{ size: 5}); - | -------^^^^^^ - | | - | variant not found in `Shape` + | ^^^^^^ variant not found in `Shape` error[E0599]: no variant or associated item named `Squareee` found for type `Shape` in the current scope --> $DIR/suggest-variants.rs:15:12 diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr index 15ec087b1c..4a8d2f57d8 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr @@ -2,9 +2,12 @@ error: expected type, found `"foo"` --> $DIR/type-ascription-instead-of-method.rs:2:13 | LL | Box:new("foo".to_string()) - | - ^^^^^ expecting a type here because of type ascription + | - ^^^^^ expected type | | - | help: maybe you meant to write a path separator here: `::` + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to previous error diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.rs b/src/test/ui/suggestions/type-ascription-instead-of-path.rs index 4c0fe6d8b5..e92087e294 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.rs @@ -1,5 +1,5 @@ fn main() { std:io::stdin(); //~^ ERROR failed to resolve: use of undeclared type or module `io` - //~| ERROR expected value, found module + //~| ERROR expected value, found crate } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr index 0f9b31fb52..fd2fedc764 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: use of undeclared type or module `io` LL | std:io::stdin(); | ^^ use of undeclared type or module `io` -error[E0423]: expected value, found module `std` +error[E0423]: expected value, found crate `std` --> $DIR/type-ascription-instead-of-path.rs:2:5 | LL | std:io::stdin(); diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr index 5719a667a8..7e9a31c06c 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr @@ -2,9 +2,12 @@ error: expected type, found `""` --> $DIR/type-ascription-instead-of-variant.rs:2:25 | LL | let _ = Option:Some(""); - | - ^^ expecting a type here because of type ascription + | - ^^ expected type | | - | help: maybe you meant to write a path separator here: `::` + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to previous error diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.fixed b/src/test/ui/suggestions/vec-macro-in-pattern.fixed new file mode 100644 index 0000000000..e1695d6820 --- /dev/null +++ b/src/test/ui/suggestions/vec-macro-in-pattern.fixed @@ -0,0 +1,8 @@ +// run-rustfix +fn main() { + // everything after `.as_ref` should be suggested + match Some(vec![3]).as_ref().map(|v| v.as_slice()) { + Some([_x]) => (), //~ ERROR unexpected `(` after qualified path + _ => (), + } +} diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.rs b/src/test/ui/suggestions/vec-macro-in-pattern.rs new file mode 100644 index 0000000000..4843629fbc --- /dev/null +++ b/src/test/ui/suggestions/vec-macro-in-pattern.rs @@ -0,0 +1,8 @@ +// run-rustfix +fn main() { + // everything after `.as_ref` should be suggested + match Some(vec![3]).as_ref().map(|v| v.as_slice()) { + Some(vec![_x]) => (), //~ ERROR unexpected `(` after qualified path + _ => (), + } +} diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.stderr b/src/test/ui/suggestions/vec-macro-in-pattern.stderr new file mode 100644 index 0000000000..59ca8ebbf6 --- /dev/null +++ b/src/test/ui/suggestions/vec-macro-in-pattern.stderr @@ -0,0 +1,15 @@ +error: unexpected `(` after qualified path + --> $DIR/vec-macro-in-pattern.rs:5:14 + | +LL | Some(vec![_x]) => (), + | ^^^^^^^^ + | | + | unexpected `(` after qualified path + | in this macro invocation + | help: use a slice pattern here instead: `[_x]` + | + = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/run-pass/super-fast-paren-parsing.rs b/src/test/ui/super-fast-paren-parsing.rs similarity index 98% rename from src/test/run-pass/super-fast-paren-parsing.rs rename to src/test/ui/super-fast-paren-parsing.rs index c86f2b8f9c..60c8db53a8 100644 --- a/src/test/run-pass/super-fast-paren-parsing.rs +++ b/src/test/ui/super-fast-paren-parsing.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_upper_case_globals)] #![allow(dead_code)] // exec-env:RUST_MIN_STACK=16000000 diff --git a/src/test/run-pass/super.rs b/src/test/ui/super.rs similarity index 93% rename from src/test/run-pass/super.rs rename to src/test/ui/super.rs index e378aac8be..86c720288c 100644 --- a/src/test/run-pass/super.rs +++ b/src/test/ui/super.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/supported-cast.rs b/src/test/ui/supported-cast.rs similarity index 99% rename from src/test/run-pass/supported-cast.rs rename to src/test/ui/supported-cast.rs index 9d875c59d8..ff41ce6c79 100644 --- a/src/test/run-pass/supported-cast.rs +++ b/src/test/ui/supported-cast.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let f = 1_usize as *const String; println!("{:?}", f as isize); diff --git a/src/test/run-pass/svh-add-nothing.rs b/src/test/ui/svh-add-nothing.rs similarity index 95% rename from src/test/run-pass/svh-add-nothing.rs rename to src/test/ui/svh-add-nothing.rs index b673fa55e3..d7d037f0b3 100644 --- a/src/test/run-pass/svh-add-nothing.rs +++ b/src/test/ui/svh-add-nothing.rs @@ -1,3 +1,4 @@ +// run-pass // note that these aux-build directives must be in this order // aux-build:svh-a-base.rs // aux-build:svh-b.rs diff --git a/src/test/run-pass/swap-1.rs b/src/test/ui/swap-1.rs similarity index 91% rename from src/test/run-pass/swap-1.rs rename to src/test/ui/swap-1.rs index 55f9c1b6fa..d87114748d 100644 --- a/src/test/run-pass/swap-1.rs +++ b/src/test/ui/swap-1.rs @@ -1,3 +1,5 @@ +// run-pass + use std::mem::swap; pub fn main() { diff --git a/src/test/run-pass/swap-2.rs b/src/test/ui/swap-2.rs similarity index 95% rename from src/test/run-pass/swap-2.rs rename to src/test/ui/swap-2.rs index 42b17ef8b7..c8f298ec0e 100644 --- a/src/test/run-pass/swap-2.rs +++ b/src/test/ui/swap-2.rs @@ -1,3 +1,5 @@ +// run-pass + use std::mem::swap; pub fn main() { diff --git a/src/test/run-pass/swap-overlapping.rs b/src/test/ui/swap-overlapping.rs similarity index 98% rename from src/test/run-pass/swap-overlapping.rs rename to src/test/ui/swap-overlapping.rs index 31fd9ce7d1..85b357e0c0 100644 --- a/src/test/run-pass/swap-overlapping.rs +++ b/src/test/ui/swap-overlapping.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same diff --git a/src/test/ui/syntax-trait-polarity-feature-gate.stderr b/src/test/ui/syntax-trait-polarity-feature-gate.stderr index 86b4bc1157..c546bc4ef7 100644 --- a/src/test/ui/syntax-trait-polarity-feature-gate.stderr +++ b/src/test/ui/syntax-trait-polarity-feature-gate.stderr @@ -5,7 +5,7 @@ LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/13231 - = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable + = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/tail-call-arg-leak.rs b/src/test/ui/tail-call-arg-leak.rs similarity index 94% rename from src/test/run-pass/tail-call-arg-leak.rs rename to src/test/ui/tail-call-arg-leak.rs index 53ec5ea7ff..a60944b632 100644 --- a/src/test/run-pass/tail-call-arg-leak.rs +++ b/src/test/ui/tail-call-arg-leak.rs @@ -1,3 +1,4 @@ +// run-pass // use of tail calls causes arg slot leaks, issue #160. // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/tail-cps.rs b/src/test/ui/tail-cps.rs similarity index 97% rename from src/test/run-pass/tail-cps.rs rename to src/test/ui/tail-cps.rs index c945f3de0c..f186683ea6 100644 --- a/src/test/run-pass/tail-cps.rs +++ b/src/test/ui/tail-cps.rs @@ -1,3 +1,5 @@ +// run-pass + fn checktrue(rs: bool) -> bool { assert!((rs)); return true; } pub fn main() { let k = checktrue; evenk(42, k); oddk(45, k); } diff --git a/src/test/run-pass/tail-direct.rs b/src/test/ui/tail-direct.rs similarity index 94% rename from src/test/run-pass/tail-direct.rs rename to src/test/ui/tail-direct.rs index 47847ee6db..c67c5b7a55 100644 --- a/src/test/run-pass/tail-direct.rs +++ b/src/test/ui/tail-direct.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { assert!((even(42))); assert!((odd(45))); } fn even(n: isize) -> bool { if n == 0 { return true; } else { return odd(n - 1); } } diff --git a/src/test/ui/target-feature-gate.stderr b/src/test/ui/target-feature-gate.stderr index c7adba868e..9f17110b6d 100644 --- a/src/test/ui/target-feature-gate.stderr +++ b/src/test/ui/target-feature-gate.stderr @@ -5,7 +5,7 @@ LL | #[target_feature(enable = "avx512bw")] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44839 - = help: add #![feature(avx512_target_feature)] to the crate attributes to enable + = help: add `#![feature(avx512_target_feature)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs index ac02c9cc64..646a98763e 100644 --- a/src/test/ui/target-feature-wrong.rs +++ b/src/test/ui/target-feature-wrong.rs @@ -25,7 +25,7 @@ unsafe fn foo() {} #[target_feature(enable = "sse2")] -//~^ ERROR #[target_feature(..)] can only be applied to `unsafe` functions +//~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions //~| NOTE can only be applied to `unsafe` functions fn bar() {} //~^ NOTE not an `unsafe` function @@ -36,7 +36,7 @@ mod another {} //~^ NOTE not a function #[inline(always)] -//~^ ERROR: cannot use #[inline(always)] +//~^ ERROR: cannot use `#[inline(always)]` #[target_feature(enable = "sse2")] unsafe fn test() {} diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr index ff9678efdd..47ca5a5ca4 100644 --- a/src/test/ui/target-feature-wrong.stderr +++ b/src/test/ui/target-feature-wrong.stderr @@ -22,7 +22,7 @@ error: malformed `target_feature` attribute input LL | #[target_feature(disable = "baz")] | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."` -error: #[target_feature(..)] can only be applied to `unsafe` functions +error: `#[target_feature(..)]` can only be applied to `unsafe` functions --> $DIR/target-feature-wrong.rs:27:1 | LL | #[target_feature(enable = "sse2")] @@ -40,7 +40,7 @@ LL | LL | mod another {} | -------------- not a function -error: cannot use #[inline(always)] with #[target_feature] +error: cannot use `#[inline(always)]` with `#[target_feature]` --> $DIR/target-feature-wrong.rs:38:1 | LL | #[inline(always)] diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/ui/tcp-stress.rs similarity index 99% rename from src/test/run-pass/tcp-stress.rs rename to src/test/ui/tcp-stress.rs index 391cbbdd42..1f1948fa8f 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/ui/tcp-stress.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-android needs extra network permissions // ignore-cloudabi no global network namespace access // ignore-emscripten no threads or sockets support diff --git a/src/test/run-pass/terminate-in-initializer.rs b/src/test/ui/terminate-in-initializer.rs similarity index 98% rename from src/test/run-pass/terminate-in-initializer.rs rename to src/test/ui/terminate-in-initializer.rs index cd9d093160..c9cb932e62 100644 --- a/src/test/run-pass/terminate-in-initializer.rs +++ b/src/test/ui/terminate-in-initializer.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten no threads support // Issue #787 diff --git a/src/test/run-pass/test-allow-dead-extern-static-no-warning.rs b/src/test/ui/test-allow-dead-extern-static-no-warning.rs similarity index 90% rename from src/test/run-pass/test-allow-dead-extern-static-no-warning.rs rename to src/test/ui/test-allow-dead-extern-static-no-warning.rs index aa95f55e88..2583e431ec 100644 --- a/src/test/run-pass/test-allow-dead-extern-static-no-warning.rs +++ b/src/test/ui/test-allow-dead-extern-static-no-warning.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --test #![deny(dead_code)] diff --git a/src/test/run-pass/test-allow-fail-attr.rs b/src/test/ui/test-allow-fail-attr.rs similarity index 94% rename from src/test/run-pass/test-allow-fail-attr.rs rename to src/test/ui/test-allow-fail-attr.rs index 0c3c2a4248..1a478460ef 100644 --- a/src/test/run-pass/test-allow-fail-attr.rs +++ b/src/test/ui/test-allow-fail-attr.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare compiled with panic=abort by default // compile-flags: --test #![feature(allow_fail)] diff --git a/src/test/ui/test-attr-non-associated-functions.rs b/src/test/ui/test-attr-non-associated-functions.rs index 5ed85abaaa..e475f5b4a7 100644 --- a/src/test/ui/test-attr-non-associated-functions.rs +++ b/src/test/ui/test-attr-non-associated-functions.rs @@ -6,7 +6,7 @@ struct A {} impl A { #[test] - fn new() -> A { //~ ERROR #[test] attribute is only allowed on non associated functions + fn new() -> A { //~ ERROR `#[test]` attribute is only allowed on non associated functions A {} } } diff --git a/src/test/ui/test-attr-non-associated-functions.stderr b/src/test/ui/test-attr-non-associated-functions.stderr index 6176aa03d8..cb3ae51823 100644 --- a/src/test/ui/test-attr-non-associated-functions.stderr +++ b/src/test/ui/test-attr-non-associated-functions.stderr @@ -1,4 +1,4 @@ -error: #[test] attribute is only allowed on non associated functions +error: `#[test]` attribute is only allowed on non associated functions --> $DIR/test-attr-non-associated-functions.rs:9:5 | LL | / fn new() -> A { diff --git a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs b/src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs similarity index 93% rename from src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs rename to src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs index a9d09d0398..ff62d84925 100644 --- a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs +++ b/src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(test)] // compile-flags: --test diff --git a/src/test/run-pass/test-main-not-dead-attr.rs b/src/test/ui/test-main-not-dead-attr.rs similarity index 88% rename from src/test/run-pass/test-main-not-dead-attr.rs rename to src/test/ui/test-main-not-dead-attr.rs index fb596dade8..628b1896ac 100644 --- a/src/test/run-pass/test-main-not-dead-attr.rs +++ b/src/test/ui/test-main-not-dead-attr.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --test #![feature(main)] diff --git a/src/test/run-pass/test-main-not-dead.rs b/src/test/ui/test-main-not-dead.rs similarity index 85% rename from src/test/run-pass/test-main-not-dead.rs rename to src/test/ui/test-main-not-dead.rs index 97ab2e3083..30a9c85e3d 100644 --- a/src/test/run-pass/test-main-not-dead.rs +++ b/src/test/ui/test-main-not-dead.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --test #![deny(dead_code)] diff --git a/src/test/ui/test-on-macro.rs b/src/test/ui/test-on-macro.rs index ad7424a1bb..a238db6d71 100644 --- a/src/test/ui/test-on-macro.rs +++ b/src/test/ui/test-on-macro.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--test #![deny(warnings)] diff --git a/src/test/ui/test-on-macro.stderr b/src/test/ui/test-on-macro.stderr index 1af38829cc..256a41722f 100644 --- a/src/test/ui/test-on-macro.stderr +++ b/src/test/ui/test-on-macro.stderr @@ -1,4 +1,4 @@ -warning: #[test] attribute should not be used on macros. Use #[cfg(test)] instead. +warning: `#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead. --> $DIR/test-on-macro.rs:11:1 | LL | foo!(); diff --git a/src/test/run-pass/test-runner-hides-buried-main.rs b/src/test/ui/test-runner-hides-buried-main.rs similarity index 93% rename from src/test/run-pass/test-runner-hides-buried-main.rs rename to src/test/ui/test-runner-hides-buried-main.rs index 4295f8bbf4..917c09801e 100644 --- a/src/test/run-pass/test-runner-hides-buried-main.rs +++ b/src/test/ui/test-runner-hides-buried-main.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --test #![feature(main)] diff --git a/src/test/run-pass/test-runner-hides-main.rs b/src/test/ui/test-runner-hides-main.rs similarity index 91% rename from src/test/run-pass/test-runner-hides-main.rs rename to src/test/ui/test-runner-hides-main.rs index 664d9153ca..0de1d64f0f 100644 --- a/src/test/run-pass/test-runner-hides-main.rs +++ b/src/test/ui/test-runner-hides-main.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags:--test // Building as a test runner means that a synthetic main will be run, // not ours diff --git a/src/test/run-pass/test-runner-hides-start.rs b/src/test/ui/test-runner-hides-start.rs similarity index 90% rename from src/test/run-pass/test-runner-hides-start.rs rename to src/test/ui/test-runner-hides-start.rs index 2634df10f2..56212bb6f4 100644 --- a/src/test/run-pass/test-runner-hides-start.rs +++ b/src/test/ui/test-runner-hides-start.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --test #![feature(start)] diff --git a/src/test/ui/test-shadowing/test-cant-be-shadowed.rs b/src/test/ui/test-shadowing/test-cant-be-shadowed.rs index b1c2a000d4..831372d450 100644 --- a/src/test/ui/test-shadowing/test-cant-be-shadowed.rs +++ b/src/test/ui/test-shadowing/test-cant-be-shadowed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test_macro.rs // compile-flags:--test diff --git a/src/test/run-pass/test-should-fail-good-message.rs b/src/test/ui/test-should-fail-good-message.rs similarity index 95% rename from src/test/run-pass/test-should-fail-good-message.rs rename to src/test/ui/test-should-fail-good-message.rs index d7d9c6c1ed..9fa759f9eb 100644 --- a/src/test/run-pass/test-should-fail-good-message.rs +++ b/src/test/ui/test-should-fail-good-message.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare compiled with panic=abort by default // compile-flags: --test #[test] diff --git a/src/test/ui/test-should-panic-attr.rs b/src/test/ui/test-should-panic-attr.rs index f936dd5758..9c38322fe9 100644 --- a/src/test/ui/test-should-panic-attr.rs +++ b/src/test/ui/test-should-panic-attr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: --test #[test] diff --git a/src/test/run-pass/test-vs-cfg-test.rs b/src/test/ui/test-vs-cfg-test.rs similarity index 91% rename from src/test/run-pass/test-vs-cfg-test.rs rename to src/test/ui/test-vs-cfg-test.rs index 75f4d0c8db..cd1cd33c28 100644 --- a/src/test/run-pass/test-vs-cfg-test.rs +++ b/src/test/ui/test-vs-cfg-test.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: --cfg test // Make sure `--cfg test` does not inject test harness diff --git a/src/test/run-pass/thin-lto-global-allocator.rs b/src/test/ui/thin-lto-global-allocator.rs similarity index 91% rename from src/test/run-pass/thin-lto-global-allocator.rs rename to src/test/ui/thin-lto-global-allocator.rs index 18869cf66d..e00c5caf97 100644 --- a/src/test/run-pass/thin-lto-global-allocator.rs +++ b/src/test/ui/thin-lto-global-allocator.rs @@ -1,3 +1,4 @@ +// run-pass // compile-flags: -Z thinlto -C codegen-units=2 #[global_allocator] diff --git a/src/test/run-pass/thinlto/all-crates.rs b/src/test/ui/thinlto/all-crates.rs similarity index 100% rename from src/test/run-pass/thinlto/all-crates.rs rename to src/test/ui/thinlto/all-crates.rs diff --git a/src/test/run-pass/thinlto/auxiliary/dylib.rs b/src/test/ui/thinlto/auxiliary/dylib.rs similarity index 100% rename from src/test/run-pass/thinlto/auxiliary/dylib.rs rename to src/test/ui/thinlto/auxiliary/dylib.rs diff --git a/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs b/src/test/ui/thinlto/auxiliary/msvc-imp-present.rs similarity index 100% rename from src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs rename to src/test/ui/thinlto/auxiliary/msvc-imp-present.rs diff --git a/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs b/src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs similarity index 100% rename from src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs rename to src/test/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs diff --git a/src/test/run-pass/thinlto/dylib-works.rs b/src/test/ui/thinlto/dylib-works.rs similarity index 100% rename from src/test/run-pass/thinlto/dylib-works.rs rename to src/test/ui/thinlto/dylib-works.rs diff --git a/src/test/run-pass/thinlto/msvc-imp-present.rs b/src/test/ui/thinlto/msvc-imp-present.rs similarity index 100% rename from src/test/run-pass/thinlto/msvc-imp-present.rs rename to src/test/ui/thinlto/msvc-imp-present.rs diff --git a/src/test/run-pass/thinlto/thin-lto-inlines.rs b/src/test/ui/thinlto/thin-lto-inlines.rs similarity index 100% rename from src/test/run-pass/thinlto/thin-lto-inlines.rs rename to src/test/ui/thinlto/thin-lto-inlines.rs diff --git a/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/ui/thinlto/thin-lto-inlines2.rs similarity index 100% rename from src/test/run-pass/thinlto/thin-lto-inlines2.rs rename to src/test/ui/thinlto/thin-lto-inlines2.rs diff --git a/src/test/run-pass/thinlto/weak-works.rs b/src/test/ui/thinlto/weak-works.rs similarity index 100% rename from src/test/run-pass/thinlto/weak-works.rs rename to src/test/ui/thinlto/weak-works.rs diff --git a/src/test/run-pass/thread-local-not-in-prelude.rs b/src/test/ui/thread-local-not-in-prelude.rs similarity index 87% rename from src/test/run-pass/thread-local-not-in-prelude.rs rename to src/test/ui/thread-local-not-in-prelude.rs index 6825b0338f..0397498262 100644 --- a/src/test/run-pass/thread-local-not-in-prelude.rs +++ b/src/test/ui/thread-local-not-in-prelude.rs @@ -1,3 +1,5 @@ +// run-pass + #![no_std] extern crate std; diff --git a/src/test/run-pass/threads-sendsync/auxiliary/thread-local-extern-static.rs b/src/test/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/auxiliary/thread-local-extern-static.rs rename to src/test/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs diff --git a/src/test/run-pass/threads-sendsync/comm.rs b/src/test/ui/threads-sendsync/comm.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/comm.rs rename to src/test/ui/threads-sendsync/comm.rs diff --git a/src/test/run-pass/threads-sendsync/send-is-not-static-par-for.rs b/src/test/ui/threads-sendsync/send-is-not-static-par-for.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/send-is-not-static-par-for.rs rename to src/test/ui/threads-sendsync/send-is-not-static-par-for.rs diff --git a/src/test/run-pass/threads-sendsync/send-resource.rs b/src/test/ui/threads-sendsync/send-resource.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/send-resource.rs rename to src/test/ui/threads-sendsync/send-resource.rs diff --git a/src/test/run-pass/threads-sendsync/send-type-inference.rs b/src/test/ui/threads-sendsync/send-type-inference.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/send-type-inference.rs rename to src/test/ui/threads-sendsync/send-type-inference.rs diff --git a/src/test/run-pass/threads-sendsync/send_str_hashmap.rs b/src/test/ui/threads-sendsync/send_str_hashmap.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/send_str_hashmap.rs rename to src/test/ui/threads-sendsync/send_str_hashmap.rs diff --git a/src/test/run-pass/threads-sendsync/send_str_treemap.rs b/src/test/ui/threads-sendsync/send_str_treemap.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/send_str_treemap.rs rename to src/test/ui/threads-sendsync/send_str_treemap.rs diff --git a/src/test/run-pass/threads-sendsync/sendable-class.rs b/src/test/ui/threads-sendsync/sendable-class.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sendable-class.rs rename to src/test/ui/threads-sendsync/sendable-class.rs diff --git a/src/test/run-pass/threads-sendsync/sendfn-is-a-block.rs b/src/test/ui/threads-sendsync/sendfn-is-a-block.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sendfn-is-a-block.rs rename to src/test/ui/threads-sendsync/sendfn-is-a-block.rs diff --git a/src/test/run-pass/threads-sendsync/sendfn-spawn-with-fn-arg.rs b/src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sendfn-spawn-with-fn-arg.rs rename to src/test/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs diff --git a/src/test/run-pass/threads-sendsync/spawn-fn.rs b/src/test/ui/threads-sendsync/spawn-fn.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/spawn-fn.rs rename to src/test/ui/threads-sendsync/spawn-fn.rs diff --git a/src/test/run-pass/threads-sendsync/spawn-types.rs b/src/test/ui/threads-sendsync/spawn-types.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/spawn-types.rs rename to src/test/ui/threads-sendsync/spawn-types.rs diff --git a/src/test/run-pass/threads-sendsync/spawn.rs b/src/test/ui/threads-sendsync/spawn.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/spawn.rs rename to src/test/ui/threads-sendsync/spawn.rs diff --git a/src/test/run-pass/threads-sendsync/spawn2.rs b/src/test/ui/threads-sendsync/spawn2.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/spawn2.rs rename to src/test/ui/threads-sendsync/spawn2.rs diff --git a/src/test/run-pass/threads-sendsync/spawning-with-debug.rs b/src/test/ui/threads-sendsync/spawning-with-debug.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/spawning-with-debug.rs rename to src/test/ui/threads-sendsync/spawning-with-debug.rs diff --git a/src/test/run-pass/threads-sendsync/std-sync-right-kind-impls.rs b/src/test/ui/threads-sendsync/std-sync-right-kind-impls.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/std-sync-right-kind-impls.rs rename to src/test/ui/threads-sendsync/std-sync-right-kind-impls.rs diff --git a/src/test/run-pass/threads-sendsync/sync-send-atomics.rs b/src/test/ui/threads-sendsync/sync-send-atomics.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sync-send-atomics.rs rename to src/test/ui/threads-sendsync/sync-send-atomics.rs diff --git a/src/test/run-pass/threads-sendsync/sync-send-in-std.rs b/src/test/ui/threads-sendsync/sync-send-in-std.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sync-send-in-std.rs rename to src/test/ui/threads-sendsync/sync-send-in-std.rs diff --git a/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs rename to src/test/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs diff --git a/src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcore.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcore.rs rename to src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-0.rs b/src/test/ui/threads-sendsync/task-comm-0.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-0.rs rename to src/test/ui/threads-sendsync/task-comm-0.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-1.rs b/src/test/ui/threads-sendsync/task-comm-1.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-1.rs rename to src/test/ui/threads-sendsync/task-comm-1.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-10.rs b/src/test/ui/threads-sendsync/task-comm-10.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-10.rs rename to src/test/ui/threads-sendsync/task-comm-10.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-11.rs b/src/test/ui/threads-sendsync/task-comm-11.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-11.rs rename to src/test/ui/threads-sendsync/task-comm-11.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-12.rs b/src/test/ui/threads-sendsync/task-comm-12.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-12.rs rename to src/test/ui/threads-sendsync/task-comm-12.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-13.rs b/src/test/ui/threads-sendsync/task-comm-13.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-13.rs rename to src/test/ui/threads-sendsync/task-comm-13.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-14.rs b/src/test/ui/threads-sendsync/task-comm-14.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-14.rs rename to src/test/ui/threads-sendsync/task-comm-14.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-15.rs b/src/test/ui/threads-sendsync/task-comm-15.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-15.rs rename to src/test/ui/threads-sendsync/task-comm-15.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-16.rs b/src/test/ui/threads-sendsync/task-comm-16.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-16.rs rename to src/test/ui/threads-sendsync/task-comm-16.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-17.rs b/src/test/ui/threads-sendsync/task-comm-17.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-17.rs rename to src/test/ui/threads-sendsync/task-comm-17.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-3.rs b/src/test/ui/threads-sendsync/task-comm-3.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-3.rs rename to src/test/ui/threads-sendsync/task-comm-3.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-4.rs b/src/test/ui/threads-sendsync/task-comm-4.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-4.rs rename to src/test/ui/threads-sendsync/task-comm-4.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-5.rs b/src/test/ui/threads-sendsync/task-comm-5.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-5.rs rename to src/test/ui/threads-sendsync/task-comm-5.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-6.rs b/src/test/ui/threads-sendsync/task-comm-6.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-6.rs rename to src/test/ui/threads-sendsync/task-comm-6.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-7.rs b/src/test/ui/threads-sendsync/task-comm-7.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-7.rs rename to src/test/ui/threads-sendsync/task-comm-7.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-9.rs b/src/test/ui/threads-sendsync/task-comm-9.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-9.rs rename to src/test/ui/threads-sendsync/task-comm-9.rs diff --git a/src/test/run-pass/threads-sendsync/task-comm-chan-nil.rs b/src/test/ui/threads-sendsync/task-comm-chan-nil.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-comm-chan-nil.rs rename to src/test/ui/threads-sendsync/task-comm-chan-nil.rs diff --git a/src/test/run-pass/threads-sendsync/task-life-0.rs b/src/test/ui/threads-sendsync/task-life-0.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-life-0.rs rename to src/test/ui/threads-sendsync/task-life-0.rs diff --git a/src/test/run-pass/threads-sendsync/task-spawn-move-and-copy.rs b/src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-spawn-move-and-copy.rs rename to src/test/ui/threads-sendsync/task-spawn-move-and-copy.rs diff --git a/src/test/run-pass/threads-sendsync/task-stderr.rs b/src/test/ui/threads-sendsync/task-stderr.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/task-stderr.rs rename to src/test/ui/threads-sendsync/task-stderr.rs diff --git a/src/test/run-pass/threads-sendsync/thread-local-extern-static.rs b/src/test/ui/threads-sendsync/thread-local-extern-static.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/thread-local-extern-static.rs rename to src/test/ui/threads-sendsync/thread-local-extern-static.rs diff --git a/src/test/run-pass/threads-sendsync/thread-local-syntax.rs b/src/test/ui/threads-sendsync/thread-local-syntax.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/thread-local-syntax.rs rename to src/test/ui/threads-sendsync/thread-local-syntax.rs diff --git a/src/test/run-pass/threads-sendsync/threads.rs b/src/test/ui/threads-sendsync/threads.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/threads.rs rename to src/test/ui/threads-sendsync/threads.rs diff --git a/src/test/run-pass/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs b/src/test/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs rename to src/test/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs diff --git a/src/test/run-pass/threads-sendsync/tls-init-on-init.rs b/src/test/ui/threads-sendsync/tls-init-on-init.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/tls-init-on-init.rs rename to src/test/ui/threads-sendsync/tls-init-on-init.rs diff --git a/src/test/run-pass/threads-sendsync/tls-try-with.rs b/src/test/ui/threads-sendsync/tls-try-with.rs similarity index 100% rename from src/test/run-pass/threads-sendsync/tls-try-with.rs rename to src/test/ui/threads-sendsync/tls-try-with.rs diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs index ce902b7e7d..8c62b34bd9 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs @@ -5,7 +5,7 @@ type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt:: struct S; // Interpreted as a feature gated custom attribute -#[rustfmt] //~ ERROR attribute `rustfmt` is currently unknown +#[rustfmt] //~ ERROR cannot find attribute macro `rustfmt` in this scope fn check() {} #[rustfmt::skip] // OK diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr index 1df9821f24..33581a1708 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -1,18 +1,15 @@ -error[E0658]: The attribute `rustfmt` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/tool-attributes-misplaced-1.rs:8:3 - | -LL | #[rustfmt] - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable - error: cannot find derive macro `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] | ^^^^^^^ +error: cannot find attribute macro `rustfmt` in this scope + --> $DIR/tool-attributes-misplaced-1.rs:8:3 + | +LL | #[rustfmt] + | ^^^^^^^ + error: cannot find macro `rustfmt!` in this scope --> $DIR/tool-attributes-misplaced-1.rs:14:5 | @@ -45,5 +42,4 @@ LL | rustfmt::skip; error: aborting due to 7 previous errors -Some errors have detailed explanations: E0423, E0658. -For more information about an error, try `rustc --explain E0423`. +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs index 56b908d94c..b5666e4ea7 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs @@ -1,6 +1,6 @@ -#[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute +#[derive(rustfmt::skip)] //~ ERROR expected derive macro, found tool attribute `rustfmt::skip` struct S; fn main() { - rustfmt::skip!(); //~ ERROR expected a macro, found tool attribute + rustfmt::skip!(); //~ ERROR expected macro, found tool attribute `rustfmt::skip` } diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr index c5f5f59c32..6d0f826e62 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr @@ -1,14 +1,14 @@ -error: expected a macro, found tool attribute +error: expected derive macro, found tool attribute `rustfmt::skip` --> $DIR/tool-attributes-misplaced-2.rs:1:10 | LL | #[derive(rustfmt::skip)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a derive macro -error: expected a macro, found tool attribute +error: expected macro, found tool attribute `rustfmt::skip` --> $DIR/tool-attributes-misplaced-2.rs:5:5 | LL | rustfmt::skip!(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a macro error: aborting due to 2 previous errors diff --git a/src/test/run-pass/tool_attributes.rs b/src/test/ui/tool_attributes.rs similarity index 93% rename from src/test/run-pass/tool_attributes.rs rename to src/test/ui/tool_attributes.rs index 506c11011a..be4a10c0ee 100644 --- a/src/test/run-pass/tool_attributes.rs +++ b/src/test/ui/tool_attributes.rs @@ -1,3 +1,4 @@ +// run-pass // Scoped attributes should not trigger an unused attributes lint. #![deny(unused_attributes)] diff --git a/src/test/run-pass/tool_lints.rs b/src/test/ui/tool_lints-rpass.rs similarity index 84% rename from src/test/run-pass/tool_lints.rs rename to src/test/ui/tool_lints-rpass.rs index bf848b8ebe..e467d34376 100644 --- a/src/test/run-pass/tool_lints.rs +++ b/src/test/ui/tool_lints-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![deny(unknown_lints)] #[allow(clippy::almost_swapped)] diff --git a/src/test/run-pass/tool_lints_2018_preview.rs b/src/test/ui/tool_lints_2018_preview.rs similarity index 88% rename from src/test/run-pass/tool_lints_2018_preview.rs rename to src/test/ui/tool_lints_2018_preview.rs index be6d199137..190f0b99dc 100644 --- a/src/test/run-pass/tool_lints_2018_preview.rs +++ b/src/test/ui/tool_lints_2018_preview.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(rust_2018_preview)] #![deny(unknown_lints)] diff --git a/src/test/ui/trace_macros-gate.stderr b/src/test/ui/trace_macros-gate.stderr index e0ffcfe295..7b95427307 100644 --- a/src/test/ui/trace_macros-gate.stderr +++ b/src/test/ui/trace_macros-gate.stderr @@ -1,11 +1,11 @@ -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:4:5 | LL | trace_macros!(); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(trace_macros)] to the crate attributes to enable + = help: add `#![feature(trace_macros)]` to the crate attributes to enable error: trace_macros! accepts only `true` or `false` --> $DIR/trace_macros-gate.rs:4:5 @@ -13,35 +13,35 @@ error: trace_macros! accepts only `true` or `false` LL | trace_macros!(); | ^^^^^^^^^^^^^^^^ -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:6:5 | LL | trace_macros!(true); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(trace_macros)] to the crate attributes to enable + = help: add `#![feature(trace_macros)]` to the crate attributes to enable -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:7:5 | LL | trace_macros!(false); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(trace_macros)] to the crate attributes to enable + = help: add `#![feature(trace_macros)]` to the crate attributes to enable -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:10:26 | LL | ($x: ident) => { trace_macros!($x) } - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ ... LL | expando!(true); | --------------- in this macro invocation | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(trace_macros)] to the crate attributes to enable + = help: add `#![feature(trace_macros)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/ui/trailing-comma.rs similarity index 90% rename from src/test/run-pass/trailing-comma.rs rename to src/test/ui/trailing-comma.rs index 197af295a4..929c35a9e1 100644 --- a/src/test/run-pass/trailing-comma.rs +++ b/src/test/ui/trailing-comma.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(slice_patterns)] @@ -24,7 +25,7 @@ pub fn main() { let (_, _,) = (1, 1,); let [_, _,] = [1, 1,]; let [_, _, .., _,] = [1, 1, 1, 1,]; - let [_, _, _.., _,] = [1, 1, 1, 1,]; + let [_, _, _, ..,] = [1, 1, 1, 1,]; let x: Foo = Foo::(1); diff --git a/src/test/run-pass/traits/anon-trait-static-method.rs b/src/test/ui/traits/anon-trait-static-method.rs similarity index 100% rename from src/test/run-pass/traits/anon-trait-static-method.rs rename to src/test/ui/traits/anon-trait-static-method.rs diff --git a/src/test/run-pass/traits/anon_trait_static_method_exe.rs b/src/test/ui/traits/anon_trait_static_method_exe.rs similarity index 100% rename from src/test/run-pass/traits/anon_trait_static_method_exe.rs rename to src/test/ui/traits/anon_trait_static_method_exe.rs diff --git a/src/test/run-pass/traits/assignability-trait.rs b/src/test/ui/traits/assignability-trait.rs similarity index 100% rename from src/test/run-pass/traits/assignability-trait.rs rename to src/test/ui/traits/assignability-trait.rs diff --git a/src/test/run-pass/traits/astconv-cycle-between-trait-and-type.rs b/src/test/ui/traits/astconv-cycle-between-trait-and-type.rs similarity index 100% rename from src/test/run-pass/traits/astconv-cycle-between-trait-and-type.rs rename to src/test/ui/traits/astconv-cycle-between-trait-and-type.rs diff --git a/src/test/run-pass/traits/augmented-assignments-trait.rs b/src/test/ui/traits/augmented-assignments-trait.rs similarity index 100% rename from src/test/run-pass/traits/augmented-assignments-trait.rs rename to src/test/ui/traits/augmented-assignments-trait.rs diff --git a/src/test/run-pass/traits/auto-traits.rs b/src/test/ui/traits/auto-traits.rs similarity index 100% rename from src/test/run-pass/traits/auto-traits.rs rename to src/test/ui/traits/auto-traits.rs diff --git a/src/test/run-pass/traits/auxiliary/anon_trait_static_method_lib.rs b/src/test/ui/traits/auxiliary/anon_trait_static_method_lib.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/anon_trait_static_method_lib.rs rename to src/test/ui/traits/auxiliary/anon_trait_static_method_lib.rs diff --git a/src/test/run-pass/traits/auxiliary/go_trait.rs b/src/test/ui/traits/auxiliary/go_trait.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/go_trait.rs rename to src/test/ui/traits/auxiliary/go_trait.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_alias.rs b/src/test/ui/traits/auxiliary/trait_alias.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_alias.rs rename to src/test/ui/traits/auxiliary/trait_alias.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux.rs b/src/test/ui/traits/auxiliary/trait_default_method_xc_aux.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux.rs rename to src/test/ui/traits/auxiliary/trait_default_method_xc_aux.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux_2.rs b/src/test/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_default_method_xc_aux_2.rs rename to src/test/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs b/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs rename to src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_aux.rs b/src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_inheritance_auto_xc_aux.rs rename to src/test/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_inheritance_overloading_xc.rs rename to src/test/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs diff --git a/src/test/run-pass/traits/auxiliary/trait_xc_call_aux.rs b/src/test/ui/traits/auxiliary/trait_xc_call_aux.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/trait_xc_call_aux.rs rename to src/test/ui/traits/auxiliary/trait_xc_call_aux.rs diff --git a/src/test/run-pass/traits/auxiliary/traitimpl.rs b/src/test/ui/traits/auxiliary/traitimpl.rs similarity index 100% rename from src/test/run-pass/traits/auxiliary/traitimpl.rs rename to src/test/ui/traits/auxiliary/traitimpl.rs diff --git a/src/test/ui/traits/conservative_impl_trait.rs b/src/test/ui/traits/conservative_impl_trait.rs index 964e21779d..4f25e57be5 100644 --- a/src/test/ui/traits/conservative_impl_trait.rs +++ b/src/test/ui/traits/conservative_impl_trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // #39665 fn batches(n: &u32) -> impl Iterator { diff --git a/src/test/run-pass/traits/cycle-trait-type-trait.rs b/src/test/ui/traits/cycle-trait-type-trait.rs similarity index 100% rename from src/test/run-pass/traits/cycle-trait-type-trait.rs rename to src/test/ui/traits/cycle-trait-type-trait.rs diff --git a/src/test/run-pass/traits/default-method-supertrait-vtable.rs b/src/test/ui/traits/default-method-supertrait-vtable.rs similarity index 100% rename from src/test/run-pass/traits/default-method-supertrait-vtable.rs rename to src/test/ui/traits/default-method-supertrait-vtable.rs diff --git a/src/test/run-pass/traits/dyn-trait.rs b/src/test/ui/traits/dyn-trait.rs similarity index 100% rename from src/test/run-pass/traits/dyn-trait.rs rename to src/test/ui/traits/dyn-trait.rs diff --git a/src/test/run-pass/traits/fmt-pointer-trait.rs b/src/test/ui/traits/fmt-pointer-trait.rs similarity index 100% rename from src/test/run-pass/traits/fmt-pointer-trait.rs rename to src/test/ui/traits/fmt-pointer-trait.rs diff --git a/src/test/run-pass/traits/impl-implicit-trait.rs b/src/test/ui/traits/impl-implicit-trait.rs similarity index 100% rename from src/test/run-pass/traits/impl-implicit-trait.rs rename to src/test/ui/traits/impl-implicit-trait.rs diff --git a/src/test/run-pass/traits/impl-inherent-prefer-over-trait.rs b/src/test/ui/traits/impl-inherent-prefer-over-trait.rs similarity index 100% rename from src/test/run-pass/traits/impl-inherent-prefer-over-trait.rs rename to src/test/ui/traits/impl-inherent-prefer-over-trait.rs diff --git a/src/test/run-pass/traits/infer-from-object-trait-issue-26952.rs b/src/test/ui/traits/infer-from-object-trait-issue-26952.rs similarity index 100% rename from src/test/run-pass/traits/infer-from-object-trait-issue-26952.rs rename to src/test/ui/traits/infer-from-object-trait-issue-26952.rs diff --git a/src/test/run-pass/traits/inherent-trait-method-order.rs b/src/test/ui/traits/inherent-trait-method-order.rs similarity index 100% rename from src/test/run-pass/traits/inherent-trait-method-order.rs rename to src/test/ui/traits/inherent-trait-method-order.rs diff --git a/src/test/run-pass/traits/kindck-owned-trait-contains-1.rs b/src/test/ui/traits/kindck-owned-trait-contains-1.rs similarity index 100% rename from src/test/run-pass/traits/kindck-owned-trait-contains-1.rs rename to src/test/ui/traits/kindck-owned-trait-contains-1.rs diff --git a/src/test/run-pass/traits/multiple-trait-bounds.rs b/src/test/ui/traits/multiple-trait-bounds.rs similarity index 100% rename from src/test/run-pass/traits/multiple-trait-bounds.rs rename to src/test/ui/traits/multiple-trait-bounds.rs diff --git a/src/test/run-pass/traits/object-one-type-two-traits.rs b/src/test/ui/traits/object-one-type-two-traits.rs similarity index 100% rename from src/test/run-pass/traits/object-one-type-two-traits.rs rename to src/test/ui/traits/object-one-type-two-traits.rs diff --git a/src/test/run-pass/traits/overlap-permitted-for-marker-traits-neg.rs b/src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs similarity index 100% rename from src/test/run-pass/traits/overlap-permitted-for-marker-traits-neg.rs rename to src/test/ui/traits/overlap-permitted-for-marker-traits-neg.rs diff --git a/src/test/run-pass/traits/overlap-permitted-for-marker-traits.rs b/src/test/ui/traits/overlap-permitted-for-marker-traits.rs similarity index 100% rename from src/test/run-pass/traits/overlap-permitted-for-marker-traits.rs rename to src/test/ui/traits/overlap-permitted-for-marker-traits.rs diff --git a/src/test/run-pass/traits/parameterized-trait-with-bounds.rs b/src/test/ui/traits/parameterized-trait-with-bounds.rs similarity index 100% rename from src/test/run-pass/traits/parameterized-trait-with-bounds.rs rename to src/test/ui/traits/parameterized-trait-with-bounds.rs diff --git a/src/test/run-pass/traits/principal-less-trait-objects.rs b/src/test/ui/traits/principal-less-trait-objects.rs similarity index 99% rename from src/test/run-pass/traits/principal-less-trait-objects.rs rename to src/test/ui/traits/principal-less-trait-objects.rs index 0984362993..82624650a5 100644 --- a/src/test/run-pass/traits/principal-less-trait-objects.rs +++ b/src/test/ui/traits/principal-less-trait-objects.rs @@ -1,3 +1,4 @@ +// run-pass // Check that trait-objects without a principal codegen properly. use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/src/test/run-pass/traits/supertrait-default-generics.rs b/src/test/ui/traits/supertrait-default-generics.rs similarity index 100% rename from src/test/run-pass/traits/supertrait-default-generics.rs rename to src/test/ui/traits/supertrait-default-generics.rs diff --git a/src/test/run-pass/traits/syntax-trait-polarity.rs b/src/test/ui/traits/syntax-trait-polarity.rs similarity index 100% rename from src/test/run-pass/traits/syntax-trait-polarity.rs rename to src/test/ui/traits/syntax-trait-polarity.rs diff --git a/src/test/ui/traits/trait-alias-ambiguous.stderr b/src/test/ui/traits/trait-alias-ambiguous.stderr index b7443269b8..cde7dd0824 100644 --- a/src/test/ui/traits/trait-alias-ambiguous.stderr +++ b/src/test/ui/traits/trait-alias-ambiguous.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `inner::A` for the type `u | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `inner::A::foo(t)` instead note: candidate #2 is defined in an impl of the trait `inner::B` for the type `u8` --> $DIR/trait-alias-ambiguous.rs:11:9 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `inner::B::foo(t)` instead error: aborting due to previous error diff --git a/src/test/run-pass/traits/trait-alias-import-cross-crate.rs b/src/test/ui/traits/trait-alias-import-cross-crate.rs similarity index 100% rename from src/test/run-pass/traits/trait-alias-import-cross-crate.rs rename to src/test/ui/traits/trait-alias-import-cross-crate.rs diff --git a/src/test/run-pass/traits/trait-alias-import.rs b/src/test/ui/traits/trait-alias-import.rs similarity index 97% rename from src/test/run-pass/traits/trait-alias-import.rs rename to src/test/ui/traits/trait-alias-import.rs index 7d63320b9a..802a8f1569 100644 --- a/src/test/run-pass/traits/trait-alias-import.rs +++ b/src/test/ui/traits/trait-alias-import.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(trait_alias)] mod inner { diff --git a/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs b/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs index 3dfcf03ce7..284baa4814 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs +++ b/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that `dyn ... + ?Sized + ...` resulting from the expansion of trait aliases is okay. diff --git a/src/test/run-pass/traits/trait-bounds-basic.rs b/src/test/ui/traits/trait-bounds-basic.rs similarity index 100% rename from src/test/run-pass/traits/trait-bounds-basic.rs rename to src/test/ui/traits/trait-bounds-basic.rs diff --git a/src/test/run-pass/traits/trait-bounds-impl-comparison-duplicates.rs b/src/test/ui/traits/trait-bounds-impl-comparison-duplicates.rs similarity index 100% rename from src/test/run-pass/traits/trait-bounds-impl-comparison-duplicates.rs rename to src/test/ui/traits/trait-bounds-impl-comparison-duplicates.rs diff --git a/src/test/run-pass/traits/trait-bounds-in-arc.rs b/src/test/ui/traits/trait-bounds-in-arc.rs similarity index 97% rename from src/test/run-pass/traits/trait-bounds-in-arc.rs rename to src/test/ui/traits/trait-bounds-in-arc.rs index a45d834297..941f66c056 100644 --- a/src/test/run-pass/traits/trait-bounds-in-arc.rs +++ b/src/test/ui/traits/trait-bounds-in-arc.rs @@ -1,6 +1,6 @@ // run-pass #![allow(unused_must_use)] -// Tests that a heterogeneous list of existential types can be put inside an Arc +// Tests that a heterogeneous list of existential `dyn` types can be put inside an Arc // and shared between threads as long as all types fulfill Send. // ignore-emscripten no threads support diff --git a/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr b/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr index 250ea4b1c3..f64e637425 100644 --- a/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr +++ b/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr @@ -4,7 +4,7 @@ warning: trait objects without an explicit `dyn` are deprecated LL | fn foo(_x: Foo + Send) { | ^^^^^^^^^^ help: use `dyn`: `dyn Foo + Send` | - = note: #[warn(bare_trait_objects)] on by default + = note: `#[warn(bare_trait_objects)]` on by default error[E0277]: the size for values of type `(dyn Foo + std::marker::Send + 'static)` cannot be known at compilation time --> $DIR/trait-bounds-not-on-bare-trait.rs:7:8 diff --git a/src/test/run-pass/traits/trait-bounds-on-structs-and-enums.rs b/src/test/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs similarity index 100% rename from src/test/run-pass/traits/trait-bounds-on-structs-and-enums.rs rename to src/test/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs diff --git a/src/test/run-pass/traits/trait-bounds-recursion.rs b/src/test/ui/traits/trait-bounds-recursion.rs similarity index 100% rename from src/test/run-pass/traits/trait-bounds-recursion.rs rename to src/test/ui/traits/trait-bounds-recursion.rs diff --git a/src/test/run-pass/traits/trait-bounds.rs b/src/test/ui/traits/trait-bounds.rs similarity index 100% rename from src/test/run-pass/traits/trait-bounds.rs rename to src/test/ui/traits/trait-bounds.rs diff --git a/src/test/run-pass/traits/trait-cache-issue-18209.rs b/src/test/ui/traits/trait-cache-issue-18209.rs similarity index 100% rename from src/test/run-pass/traits/trait-cache-issue-18209.rs rename to src/test/ui/traits/trait-cache-issue-18209.rs diff --git a/src/test/run-pass/traits/trait-coercion-generic.rs b/src/test/ui/traits/trait-coercion-generic.rs similarity index 100% rename from src/test/run-pass/traits/trait-coercion-generic.rs rename to src/test/ui/traits/trait-coercion-generic.rs diff --git a/src/test/run-pass/traits/trait-coercion.rs b/src/test/ui/traits/trait-coercion.rs similarity index 100% rename from src/test/run-pass/traits/trait-coercion.rs rename to src/test/ui/traits/trait-coercion.rs diff --git a/src/test/run-pass/traits/trait-composition-trivial.rs b/src/test/ui/traits/trait-composition-trivial.rs similarity index 100% rename from src/test/run-pass/traits/trait-composition-trivial.rs rename to src/test/ui/traits/trait-composition-trivial.rs diff --git a/src/test/run-pass/traits/trait-copy-guessing.rs b/src/test/ui/traits/trait-copy-guessing.rs similarity index 100% rename from src/test/run-pass/traits/trait-copy-guessing.rs rename to src/test/ui/traits/trait-copy-guessing.rs diff --git a/src/test/run-pass/traits/trait-default-method-bound-subst.rs b/src/test/ui/traits/trait-default-method-bound-subst.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-bound-subst.rs rename to src/test/ui/traits/trait-default-method-bound-subst.rs diff --git a/src/test/run-pass/traits/trait-default-method-bound-subst2.rs b/src/test/ui/traits/trait-default-method-bound-subst2.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-bound-subst2.rs rename to src/test/ui/traits/trait-default-method-bound-subst2.rs diff --git a/src/test/run-pass/traits/trait-default-method-bound-subst3.rs b/src/test/ui/traits/trait-default-method-bound-subst3.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-bound-subst3.rs rename to src/test/ui/traits/trait-default-method-bound-subst3.rs diff --git a/src/test/run-pass/traits/trait-default-method-bound-subst4.rs b/src/test/ui/traits/trait-default-method-bound-subst4.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-bound-subst4.rs rename to src/test/ui/traits/trait-default-method-bound-subst4.rs diff --git a/src/test/run-pass/traits/trait-default-method-bound.rs b/src/test/ui/traits/trait-default-method-bound.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-bound.rs rename to src/test/ui/traits/trait-default-method-bound.rs diff --git a/src/test/run-pass/traits/trait-default-method-xc-2.rs b/src/test/ui/traits/trait-default-method-xc-2.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-xc-2.rs rename to src/test/ui/traits/trait-default-method-xc-2.rs diff --git a/src/test/run-pass/traits/trait-default-method-xc.rs b/src/test/ui/traits/trait-default-method-xc.rs similarity index 100% rename from src/test/run-pass/traits/trait-default-method-xc.rs rename to src/test/ui/traits/trait-default-method-xc.rs diff --git a/src/test/run-pass/traits/trait-false-ambiguity-where-clause-builtin-bound.rs b/src/test/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs similarity index 100% rename from src/test/run-pass/traits/trait-false-ambiguity-where-clause-builtin-bound.rs rename to src/test/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs diff --git a/src/test/run-pass/traits/trait-generic.rs b/src/test/ui/traits/trait-generic.rs similarity index 100% rename from src/test/run-pass/traits/trait-generic.rs rename to src/test/ui/traits/trait-generic.rs diff --git a/src/test/run-pass/traits/trait-impl-2.rs b/src/test/ui/traits/trait-impl-2.rs similarity index 100% rename from src/test/run-pass/traits/trait-impl-2.rs rename to src/test/ui/traits/trait-impl-2.rs diff --git a/src/test/run-pass/traits/trait-impl.rs b/src/test/ui/traits/trait-impl.rs similarity index 100% rename from src/test/run-pass/traits/trait-impl.rs rename to src/test/ui/traits/trait-impl.rs diff --git a/src/test/run-pass/traits/trait-inheritance-auto-xc-2.rs b/src/test/ui/traits/trait-inheritance-auto-xc-2.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-auto-xc-2.rs rename to src/test/ui/traits/trait-inheritance-auto-xc-2.rs diff --git a/src/test/run-pass/traits/trait-inheritance-auto-xc.rs b/src/test/ui/traits/trait-inheritance-auto-xc.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-auto-xc.rs rename to src/test/ui/traits/trait-inheritance-auto-xc.rs diff --git a/src/test/run-pass/traits/trait-inheritance-auto.rs b/src/test/ui/traits/trait-inheritance-auto.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-auto.rs rename to src/test/ui/traits/trait-inheritance-auto.rs diff --git a/src/test/run-pass/traits/trait-inheritance-call-bound-inherited.rs b/src/test/ui/traits/trait-inheritance-call-bound-inherited.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-call-bound-inherited.rs rename to src/test/ui/traits/trait-inheritance-call-bound-inherited.rs diff --git a/src/test/run-pass/traits/trait-inheritance-call-bound-inherited2.rs b/src/test/ui/traits/trait-inheritance-call-bound-inherited2.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-call-bound-inherited2.rs rename to src/test/ui/traits/trait-inheritance-call-bound-inherited2.rs diff --git a/src/test/run-pass/traits/trait-inheritance-cast-without-call-to-supertrait.rs b/src/test/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-cast-without-call-to-supertrait.rs rename to src/test/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs diff --git a/src/test/run-pass/traits/trait-inheritance-cast.rs b/src/test/ui/traits/trait-inheritance-cast.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-cast.rs rename to src/test/ui/traits/trait-inheritance-cast.rs diff --git a/src/test/run-pass/traits/trait-inheritance-cross-trait-call-xc.rs b/src/test/ui/traits/trait-inheritance-cross-trait-call-xc.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-cross-trait-call-xc.rs rename to src/test/ui/traits/trait-inheritance-cross-trait-call-xc.rs diff --git a/src/test/run-pass/traits/trait-inheritance-cross-trait-call.rs b/src/test/ui/traits/trait-inheritance-cross-trait-call.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-cross-trait-call.rs rename to src/test/ui/traits/trait-inheritance-cross-trait-call.rs diff --git a/src/test/run-pass/traits/trait-inheritance-diamond.rs b/src/test/ui/traits/trait-inheritance-diamond.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-diamond.rs rename to src/test/ui/traits/trait-inheritance-diamond.rs diff --git a/src/test/run-pass/traits/trait-inheritance-multiple-inheritors.rs b/src/test/ui/traits/trait-inheritance-multiple-inheritors.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-multiple-inheritors.rs rename to src/test/ui/traits/trait-inheritance-multiple-inheritors.rs diff --git a/src/test/run-pass/traits/trait-inheritance-multiple-params.rs b/src/test/ui/traits/trait-inheritance-multiple-params.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-multiple-params.rs rename to src/test/ui/traits/trait-inheritance-multiple-params.rs diff --git a/src/test/run-pass/traits/trait-inheritance-num.rs b/src/test/ui/traits/trait-inheritance-num.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-num.rs rename to src/test/ui/traits/trait-inheritance-num.rs diff --git a/src/test/run-pass/traits/trait-inheritance-num0.rs b/src/test/ui/traits/trait-inheritance-num0.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-num0.rs rename to src/test/ui/traits/trait-inheritance-num0.rs diff --git a/src/test/run-pass/traits/trait-inheritance-num1.rs b/src/test/ui/traits/trait-inheritance-num1.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-num1.rs rename to src/test/ui/traits/trait-inheritance-num1.rs diff --git a/src/test/run-pass/traits/trait-inheritance-num2.rs b/src/test/ui/traits/trait-inheritance-num2.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-num2.rs rename to src/test/ui/traits/trait-inheritance-num2.rs diff --git a/src/test/run-pass/traits/trait-inheritance-num3.rs b/src/test/ui/traits/trait-inheritance-num3.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-num3.rs rename to src/test/ui/traits/trait-inheritance-num3.rs diff --git a/src/test/run-pass/traits/trait-inheritance-num5.rs b/src/test/ui/traits/trait-inheritance-num5.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-num5.rs rename to src/test/ui/traits/trait-inheritance-num5.rs diff --git a/src/test/run-pass/traits/trait-inheritance-overloading-simple.rs b/src/test/ui/traits/trait-inheritance-overloading-simple.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-overloading-simple.rs rename to src/test/ui/traits/trait-inheritance-overloading-simple.rs diff --git a/src/test/run-pass/traits/trait-inheritance-overloading-xc-exe.rs b/src/test/ui/traits/trait-inheritance-overloading-xc-exe.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-overloading-xc-exe.rs rename to src/test/ui/traits/trait-inheritance-overloading-xc-exe.rs diff --git a/src/test/run-pass/traits/trait-inheritance-overloading.rs b/src/test/ui/traits/trait-inheritance-overloading.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-overloading.rs rename to src/test/ui/traits/trait-inheritance-overloading.rs diff --git a/src/test/run-pass/traits/trait-inheritance-self-in-supertype.rs b/src/test/ui/traits/trait-inheritance-self-in-supertype.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-self-in-supertype.rs rename to src/test/ui/traits/trait-inheritance-self-in-supertype.rs diff --git a/src/test/run-pass/traits/trait-inheritance-self.rs b/src/test/ui/traits/trait-inheritance-self.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-self.rs rename to src/test/ui/traits/trait-inheritance-self.rs diff --git a/src/test/run-pass/traits/trait-inheritance-simple.rs b/src/test/ui/traits/trait-inheritance-simple.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-simple.rs rename to src/test/ui/traits/trait-inheritance-simple.rs diff --git a/src/test/run-pass/traits/trait-inheritance-static.rs b/src/test/ui/traits/trait-inheritance-static.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-static.rs rename to src/test/ui/traits/trait-inheritance-static.rs diff --git a/src/test/run-pass/traits/trait-inheritance-static2.rs b/src/test/ui/traits/trait-inheritance-static2.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-static2.rs rename to src/test/ui/traits/trait-inheritance-static2.rs diff --git a/src/test/run-pass/traits/trait-inheritance-subst.rs b/src/test/ui/traits/trait-inheritance-subst.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-subst.rs rename to src/test/ui/traits/trait-inheritance-subst.rs diff --git a/src/test/run-pass/traits/trait-inheritance-subst2.rs b/src/test/ui/traits/trait-inheritance-subst2.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-subst2.rs rename to src/test/ui/traits/trait-inheritance-subst2.rs diff --git a/src/test/run-pass/traits/trait-inheritance-visibility.rs b/src/test/ui/traits/trait-inheritance-visibility.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance-visibility.rs rename to src/test/ui/traits/trait-inheritance-visibility.rs diff --git a/src/test/run-pass/traits/trait-inheritance2.rs b/src/test/ui/traits/trait-inheritance2.rs similarity index 100% rename from src/test/run-pass/traits/trait-inheritance2.rs rename to src/test/ui/traits/trait-inheritance2.rs diff --git a/src/test/run-pass/traits/trait-item-inside-macro.rs b/src/test/ui/traits/trait-item-inside-macro.rs similarity index 100% rename from src/test/run-pass/traits/trait-item-inside-macro.rs rename to src/test/ui/traits/trait-item-inside-macro.rs diff --git a/src/test/run-pass/traits/trait-object-auto-dedup.rs b/src/test/ui/traits/trait-object-auto-dedup.rs similarity index 100% rename from src/test/run-pass/traits/trait-object-auto-dedup.rs rename to src/test/ui/traits/trait-object-auto-dedup.rs diff --git a/src/test/run-pass/traits/trait-object-exclusion.rs b/src/test/ui/traits/trait-object-exclusion.rs similarity index 100% rename from src/test/run-pass/traits/trait-object-exclusion.rs rename to src/test/ui/traits/trait-object-exclusion.rs diff --git a/src/test/run-pass/traits/trait-object-generics.rs b/src/test/ui/traits/trait-object-generics.rs similarity index 100% rename from src/test/run-pass/traits/trait-object-generics.rs rename to src/test/ui/traits/trait-object-generics.rs diff --git a/src/test/run-pass/traits/trait-object-lifetime-first.rs b/src/test/ui/traits/trait-object-lifetime-first.rs similarity index 100% rename from src/test/run-pass/traits/trait-object-lifetime-first.rs rename to src/test/ui/traits/trait-object-lifetime-first.rs diff --git a/src/test/run-pass/traits/trait-object-with-lifetime-bound.rs b/src/test/ui/traits/trait-object-with-lifetime-bound.rs similarity index 100% rename from src/test/run-pass/traits/trait-object-with-lifetime-bound.rs rename to src/test/ui/traits/trait-object-with-lifetime-bound.rs diff --git a/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs b/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs index 793d556d08..d1b7bf6c2d 100644 --- a/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs +++ b/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test related to #56288. Check that a supertrait projection (of // `Output`) that references `Self` can be ok if it is referencing a projection (of diff --git a/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs b/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs index 3e9f612a2a..83dfe6664a 100644 --- a/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs +++ b/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // FIXME(eddyb) shorten the name so windows doesn't choke on it. #![crate_name = "trait_test"] diff --git a/src/test/ui/traits/trait-privacy.rs b/src/test/ui/traits/trait-privacy.rs index 6254157e25..17a2e05e99 100644 --- a/src/test/ui/traits/trait-privacy.rs +++ b/src/test/ui/traits/trait-privacy.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] mod foo { pub use self::bar::T; diff --git a/src/test/run-pass/traits/trait-region-pointer-simple.rs b/src/test/ui/traits/trait-region-pointer-simple.rs similarity index 100% rename from src/test/run-pass/traits/trait-region-pointer-simple.rs rename to src/test/ui/traits/trait-region-pointer-simple.rs diff --git a/src/test/run-pass/traits/trait-safety-ok-cc.rs b/src/test/ui/traits/trait-safety-ok-cc.rs similarity index 100% rename from src/test/run-pass/traits/trait-safety-ok-cc.rs rename to src/test/ui/traits/trait-safety-ok-cc.rs diff --git a/src/test/run-pass/traits/trait-safety-ok.rs b/src/test/ui/traits/trait-safety-ok.rs similarity index 100% rename from src/test/run-pass/traits/trait-safety-ok.rs rename to src/test/ui/traits/trait-safety-ok.rs diff --git a/src/test/run-pass/traits/trait-static-method-overwriting.rs b/src/test/ui/traits/trait-static-method-overwriting.rs similarity index 100% rename from src/test/run-pass/traits/trait-static-method-overwriting.rs rename to src/test/ui/traits/trait-static-method-overwriting.rs diff --git a/src/test/run-pass/traits/trait-to-str.rs b/src/test/ui/traits/trait-to-str.rs similarity index 100% rename from src/test/run-pass/traits/trait-to-str.rs rename to src/test/ui/traits/trait-to-str.rs diff --git a/src/test/run-pass/traits/trait-where-clause-vs-impl.rs b/src/test/ui/traits/trait-where-clause-vs-impl.rs similarity index 100% rename from src/test/run-pass/traits/trait-where-clause-vs-impl.rs rename to src/test/ui/traits/trait-where-clause-vs-impl.rs diff --git a/src/test/run-pass/traits/trait-with-bounds-default.rs b/src/test/ui/traits/trait-with-bounds-default.rs similarity index 100% rename from src/test/run-pass/traits/trait-with-bounds-default.rs rename to src/test/ui/traits/trait-with-bounds-default.rs diff --git a/src/test/ui/traits/trait-with-dst.rs b/src/test/ui/traits/trait-with-dst.rs index 86d6585bc6..a3e3b31df9 100644 --- a/src/test/ui/traits/trait-with-dst.rs +++ b/src/test/ui/traits/trait-with-dst.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // #55266 struct VTable { diff --git a/src/test/run-pass/traits/traits-assoc-type-in-supertrait.rs b/src/test/ui/traits/traits-assoc-type-in-supertrait.rs similarity index 100% rename from src/test/run-pass/traits/traits-assoc-type-in-supertrait.rs rename to src/test/ui/traits/traits-assoc-type-in-supertrait.rs diff --git a/src/test/run-pass/traits/traits-conditional-dispatch.rs b/src/test/ui/traits/traits-conditional-dispatch.rs similarity index 100% rename from src/test/run-pass/traits/traits-conditional-dispatch.rs rename to src/test/ui/traits/traits-conditional-dispatch.rs diff --git a/src/test/run-pass/traits/traits-conditional-model-fn.rs b/src/test/ui/traits/traits-conditional-model-fn.rs similarity index 100% rename from src/test/run-pass/traits/traits-conditional-model-fn.rs rename to src/test/ui/traits/traits-conditional-model-fn.rs diff --git a/src/test/run-pass/traits/traits-default-method-macro.rs b/src/test/ui/traits/traits-default-method-macro.rs similarity index 100% rename from src/test/run-pass/traits/traits-default-method-macro.rs rename to src/test/ui/traits/traits-default-method-macro.rs diff --git a/src/test/run-pass/traits/traits-default-method-mut.rs b/src/test/ui/traits/traits-default-method-mut.rs similarity index 100% rename from src/test/run-pass/traits/traits-default-method-mut.rs rename to src/test/ui/traits/traits-default-method-mut.rs diff --git a/src/test/run-pass/traits/traits-default-method-self.rs b/src/test/ui/traits/traits-default-method-self.rs similarity index 100% rename from src/test/run-pass/traits/traits-default-method-self.rs rename to src/test/ui/traits/traits-default-method-self.rs diff --git a/src/test/run-pass/traits/traits-default-method-trivial.rs b/src/test/ui/traits/traits-default-method-trivial.rs similarity index 100% rename from src/test/run-pass/traits/traits-default-method-trivial.rs rename to src/test/ui/traits/traits-default-method-trivial.rs diff --git a/src/test/run-pass/traits/traits-elaborate-type-region.rs b/src/test/ui/traits/traits-elaborate-type-region.rs similarity index 100% rename from src/test/run-pass/traits/traits-elaborate-type-region.rs rename to src/test/ui/traits/traits-elaborate-type-region.rs diff --git a/src/test/run-pass/traits/traits-impl-object-overlap-issue-23853.rs b/src/test/ui/traits/traits-impl-object-overlap-issue-23853.rs similarity index 100% rename from src/test/run-pass/traits/traits-impl-object-overlap-issue-23853.rs rename to src/test/ui/traits/traits-impl-object-overlap-issue-23853.rs diff --git a/src/test/run-pass/traits/traits-issue-22019.rs b/src/test/ui/traits/traits-issue-22019.rs similarity index 100% rename from src/test/run-pass/traits/traits-issue-22019.rs rename to src/test/ui/traits/traits-issue-22019.rs diff --git a/src/test/run-pass/traits/traits-issue-22110.rs b/src/test/ui/traits/traits-issue-22110.rs similarity index 100% rename from src/test/run-pass/traits/traits-issue-22110.rs rename to src/test/ui/traits/traits-issue-22110.rs diff --git a/src/test/run-pass/traits/traits-issue-22655.rs b/src/test/ui/traits/traits-issue-22655.rs similarity index 100% rename from src/test/run-pass/traits/traits-issue-22655.rs rename to src/test/ui/traits/traits-issue-22655.rs diff --git a/src/test/ui/traits/traits-issue-23003-overflow.rs b/src/test/ui/traits/traits-issue-23003-overflow.rs index 06aa698dde..5538e0303e 100644 --- a/src/test/ui/traits/traits-issue-23003-overflow.rs +++ b/src/test/ui/traits/traits-issue-23003-overflow.rs @@ -2,7 +2,7 @@ // types are required. This test now just compiles fine, since the // relevant rules that triggered the overflow were removed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::marker::PhantomData; diff --git a/src/test/run-pass/traits/traits-issue-23003.rs b/src/test/ui/traits/traits-issue-23003.rs similarity index 100% rename from src/test/run-pass/traits/traits-issue-23003.rs rename to src/test/ui/traits/traits-issue-23003.rs diff --git a/src/test/run-pass/traits/traits-issue-26339.rs b/src/test/ui/traits/traits-issue-26339.rs similarity index 100% rename from src/test/run-pass/traits/traits-issue-26339.rs rename to src/test/ui/traits/traits-issue-26339.rs diff --git a/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs b/src/test/ui/traits/traits-multidispatch-infer-convert-target.rs similarity index 100% rename from src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs rename to src/test/ui/traits/traits-multidispatch-infer-convert-target.rs diff --git a/src/test/run-pass/traits/traits-negative-impls.rs b/src/test/ui/traits/traits-negative-impls-rpass.rs similarity index 100% rename from src/test/run-pass/traits/traits-negative-impls.rs rename to src/test/ui/traits/traits-negative-impls-rpass.rs diff --git a/src/test/run-pass/traits/traits-repeated-supertrait.rs b/src/test/ui/traits/traits-repeated-supertrait.rs similarity index 100% rename from src/test/run-pass/traits/traits-repeated-supertrait.rs rename to src/test/ui/traits/traits-repeated-supertrait.rs diff --git a/src/test/run-pass/traits/ufcs-trait-object.rs b/src/test/ui/traits/ufcs-trait-object.rs similarity index 100% rename from src/test/run-pass/traits/ufcs-trait-object.rs rename to src/test/ui/traits/ufcs-trait-object.rs diff --git a/src/test/run-pass/traits/use-trait-before-def.rs b/src/test/ui/traits/use-trait-before-def.rs similarity index 100% rename from src/test/run-pass/traits/use-trait-before-def.rs rename to src/test/ui/traits/use-trait-before-def.rs diff --git a/src/test/run-pass/transmute-non-immediate-to-immediate.rs b/src/test/ui/transmute-non-immediate-to-immediate.rs similarity index 94% rename from src/test/run-pass/transmute-non-immediate-to-immediate.rs rename to src/test/ui/transmute-non-immediate-to-immediate.rs index 2119c8336f..cf77c113f4 100644 --- a/src/test/run-pass/transmute-non-immediate-to-immediate.rs +++ b/src/test/ui/transmute-non-immediate-to-immediate.rs @@ -1,3 +1,4 @@ +// run-pass // Issue #7988 // Transmuting non-immediate type to immediate type diff --git a/src/test/run-pass/transmute-specialization.rs b/src/test/ui/transmute-specialization.rs similarity index 94% rename from src/test/run-pass/transmute-specialization.rs rename to src/test/ui/transmute-specialization.rs index e2b110db63..002fba9ce8 100644 --- a/src/test/run-pass/transmute-specialization.rs +++ b/src/test/ui/transmute-specialization.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(specialization)] trait Specializable { type Output; } diff --git a/src/test/ui/transmute/transmute-imut-to-mut.stderr b/src/test/ui/transmute/transmute-imut-to-mut.stderr index d2445f0c7f..d323c1a73b 100644 --- a/src/test/ui/transmute/transmute-imut-to-mut.stderr +++ b/src/test/ui/transmute/transmute-imut-to-mut.stderr @@ -4,7 +4,7 @@ error: mutating transmuted &mut T from &T may cause undefined behavior, consider LL | let _a: &mut u8 = unsafe { transmute(&1u8) }; | ^^^^^^^^^ | - = note: #[deny(mutable_transmutes)] on by default + = note: `#[deny(mutable_transmutes)]` on by default error: aborting due to previous error diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr index 12d61fc42a..af0bad8069 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr @@ -4,7 +4,7 @@ warning: Trait bound std::string::String: std::marker::Copy does not depend on a LL | fn copy_string(t: String) -> String where String: Copy { | ^^^^ | - = note: #[warn(trivial_bounds)] on by default + = note: `#[warn(trivial_bounds)]` on by default warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent-copy.rs:13:56 diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr index 561614dc52..f2aa482f6d 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr @@ -4,7 +4,7 @@ warning: Trait bound B: A does not depend on any type or lifetime parameters LL | B: A | ^ | - = note: #[warn(trivial_bounds)] on by default + = note: `#[warn(trivial_bounds)]` on by default warning: Trait bound B: A does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent-projection.rs:28:8 diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr index fda1d6d70a..a80ebc173f 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr @@ -4,7 +4,7 @@ warning: Trait bound str: std::marker::Sized does not depend on any type or life LL | struct S(str, str) where str: Sized; | ^^^^^ | - = note: #[warn(trivial_bounds)] on by default + = note: `#[warn(trivial_bounds)]` on by default warning: Trait bound for<'a> T<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent-sized.rs:16:49 diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr index a72e3f75cf..fdc3ff1d3b 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr @@ -4,7 +4,7 @@ warning: Trait bound std::vec::Vec: std::fmt::Debug does not depend on any LL | pub fn foo() where Vec: Debug, str: Copy { | ^^^^^ | - = note: #[warn(trivial_bounds)] on by default + = note: `#[warn(trivial_bounds)]` on by default warning: Trait bound str: std::marker::Copy does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent-well-formed.rs:7:42 diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr index a0d638f171..0eb0769c57 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr @@ -4,7 +4,7 @@ warning: Trait bound i32: Foo does not depend on any type or lifetime parameters LL | enum E where i32: Foo { V } | ^^^ | - = note: #[warn(trivial_bounds)] on by default + = note: `#[warn(trivial_bounds)]` on by default warning: Trait bound i32: Foo does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent.rs:16:21 @@ -30,7 +30,7 @@ warning: where clauses are not enforced in type aliases LL | type Y where i32: Foo = (); | ^^^^^^^^ | - = note: #[warn(type_alias_bounds)] on by default + = note: `#[warn(type_alias_bounds)]` on by default = help: the clause will not be checked when the type alias is used, and should be removed warning: Trait bound i32: Foo does not depend on any type or lifetime parameters diff --git a/src/test/run-pass/trivial-message.rs b/src/test/ui/trivial-message.rs similarity index 95% rename from src/test/run-pass/trivial-message.rs rename to src/test/ui/trivial-message.rs index dae0706827..5831e867be 100644 --- a/src/test/run-pass/trivial-message.rs +++ b/src/test/ui/trivial-message.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] /* This is about the simplest program that can successfully send a diff --git a/src/test/run-pass/trivial_casts.rs b/src/test/ui/trivial_casts-rpass.rs similarity index 99% rename from src/test/run-pass/trivial_casts.rs rename to src/test/ui/trivial_casts-rpass.rs index f06b070829..8e49468bf0 100644 --- a/src/test/run-pass/trivial_casts.rs +++ b/src/test/ui/trivial_casts-rpass.rs @@ -1,3 +1,4 @@ +// run-pass // Test that all coercions can actually be done using casts (modulo the lints). #![allow(trivial_casts, trivial_numeric_casts)] diff --git a/src/test/run-pass/try-block.rs b/src/test/ui/try-block.rs similarity index 99% rename from src/test/run-pass/try-block.rs rename to src/test/ui/try-block.rs index dff186cfd0..c29ccc7042 100644 --- a/src/test/run-pass/try-block.rs +++ b/src/test/ui/try-block.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] // compile-flags: --edition 2018 diff --git a/src/test/run-pass/try-from-int-error-partial-eq.rs b/src/test/ui/try-from-int-error-partial-eq.rs similarity index 93% rename from src/test/run-pass/try-from-int-error-partial-eq.rs rename to src/test/ui/try-from-int-error-partial-eq.rs index e9b53f2d1c..6ee4a4cf31 100644 --- a/src/test/run-pass/try-from-int-error-partial-eq.rs +++ b/src/test/ui/try-from-int-error-partial-eq.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] use std::convert::TryFrom; diff --git a/src/test/run-pass/try-is-identifier-edition2015.rs b/src/test/ui/try-is-identifier-edition2015.rs similarity index 93% rename from src/test/run-pass/try-is-identifier-edition2015.rs rename to src/test/ui/try-is-identifier-edition2015.rs index b9807a7072..dfb05599be 100644 --- a/src/test/run-pass/try-is-identifier-edition2015.rs +++ b/src/test/ui/try-is-identifier-edition2015.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] // compile-flags: --edition 2015 diff --git a/src/test/run-pass/try-operator-custom.rs b/src/test/ui/try-operator-custom.rs similarity index 98% rename from src/test/run-pass/try-operator-custom.rs rename to src/test/ui/try-operator-custom.rs index 008cab00ea..9993061ea6 100644 --- a/src/test/run-pass/try-operator-custom.rs +++ b/src/test/ui/try-operator-custom.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(try_trait)] use std::ops::Try; diff --git a/src/test/run-pass/try-operator-hygiene.rs b/src/test/ui/try-operator-hygiene.rs similarity index 97% rename from src/test/run-pass/try-operator-hygiene.rs rename to src/test/ui/try-operator-hygiene.rs index 5f0f9a932c..0b24b4305a 100644 --- a/src/test/run-pass/try-operator-hygiene.rs +++ b/src/test/ui/try-operator-hygiene.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_upper_case_globals)] #![allow(dead_code)] // `expr?` expands to: diff --git a/src/test/run-pass/try-operator.rs b/src/test/ui/try-operator.rs similarity index 99% rename from src/test/run-pass/try-operator.rs rename to src/test/ui/try-operator.rs index 8e7a7b5dfc..9118e8e713 100644 --- a/src/test/run-pass/try-operator.rs +++ b/src/test/ui/try-operator.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // ignore-cloudabi no std::fs diff --git a/src/test/ui/try-poll.rs b/src/test/ui/try-poll.rs index f63950ad5e..d42e51c740 100644 --- a/src/test/ui/try-poll.rs +++ b/src/test/ui/try-poll.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, unused)] diff --git a/src/test/run-pass/try-wait.rs b/src/test/ui/try-wait.rs similarity index 99% rename from src/test/run-pass/try-wait.rs rename to src/test/ui/try-wait.rs index 97caddde41..d8a07c55cf 100644 --- a/src/test/run-pass/try-wait.rs +++ b/src/test/ui/try-wait.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] // ignore-cloudabi no processes // ignore-emscripten no processes diff --git a/src/test/run-pass/try_from.rs b/src/test/ui/try_from.rs similarity index 98% rename from src/test/run-pass/try_from.rs rename to src/test/ui/try_from.rs index 98344491ae..50451576f9 100644 --- a/src/test/run-pass/try_from.rs +++ b/src/test/ui/try_from.rs @@ -1,3 +1,4 @@ +// run-pass // This test relies on `TryFrom` being blanket impl for all `T: Into` // and `TryInto` being blanket impl for all `U: TryFrom` diff --git a/src/test/run-pass/tup.rs b/src/test/ui/tup.rs similarity index 96% rename from src/test/run-pass/tup.rs rename to src/test/ui/tup.rs index 47ea0e1c0d..160477b0b0 100644 --- a/src/test/run-pass/tup.rs +++ b/src/test/ui/tup.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] type point = (isize, isize); diff --git a/src/test/run-pass/tuple-index-fat-types.rs b/src/test/ui/tuple-index-fat-types.rs similarity index 93% rename from src/test/run-pass/tuple-index-fat-types.rs rename to src/test/ui/tuple-index-fat-types.rs index ee224cc84b..5dda1ed975 100644 --- a/src/test/run-pass/tuple-index-fat-types.rs +++ b/src/test/ui/tuple-index-fat-types.rs @@ -1,3 +1,5 @@ +// run-pass + struct Foo<'a>(&'a [isize]); fn main() { diff --git a/src/test/run-pass/tuple-index.rs b/src/test/ui/tuple-index.rs similarity index 97% rename from src/test/run-pass/tuple-index.rs rename to src/test/ui/tuple-index.rs index e68fa1caa5..3e1d92b42a 100644 --- a/src/test/run-pass/tuple-index.rs +++ b/src/test/ui/tuple-index.rs @@ -1,3 +1,5 @@ +// run-pass + struct Point(isize, isize); fn main() { diff --git a/src/test/ui/tydesc-name.rs b/src/test/ui/tydesc-name.rs new file mode 100644 index 0000000000..c432e5b548 --- /dev/null +++ b/src/test/ui/tydesc-name.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(dead_code)] + +use std::any::type_name; + +struct Foo { + x: T +} + +pub fn main() { + assert_eq!(type_name::(), "isize"); + assert_eq!(type_name::>(), "tydesc_name::Foo"); +} diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr index f0dd689934..db8767273b 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -2,9 +2,9 @@ error: ambiguous associated item --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15 | LL | fn f() -> Self::V { 0 } - | ^^^^^^^ help: use fully-qualified syntax: `::V` + | ^^^^^^^ help: use fully-qualified syntax: `::V` | - = note: #[deny(ambiguous_associated_items)] on by default + = note: `#[deny(ambiguous_associated_items)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57644 note: `V` could refer to variant defined here diff --git a/src/test/ui/type-alias-enum-variants/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs index fa351ed51d..058b58e174 100644 --- a/src/test/ui/type-alias-enum-variants/issue-57866.rs +++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Outer { A(T) diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs index dfc618b164..bff04daed0 100644 --- a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs +++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs @@ -1,7 +1,7 @@ // In this regression test we check that a path pattern referring to a unit variant // through a type alias is successful in inferring the generic argument. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Opt { N, diff --git a/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs b/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs new file mode 100644 index 0000000000..66fb8dd0de --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs @@ -0,0 +1,26 @@ +// check-pass + +// Regression test for the issue #63151: +// Spurious unused field warning when matching variants under a `Self` scope +// +// This test checks that the `dead_code` lint properly inspects fields +// in struct patterns that use a type relative path. + +#![deny(dead_code)] + +enum Enum { + Variant { field: usize } +} + +impl Enum { + fn read_field(self) -> usize { + match self { + Self::Variant { field } => field + } + } +} + +fn main() { + let e = Enum::Variant { field: 42 }; + println!("{}", e.read_field()); +} diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs new file mode 100644 index 0000000000..63b21faa62 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs @@ -0,0 +1,8 @@ +#[repr(u8)] +enum Alpha { + V1 = 41, + V2 = Self::V1 as u8 + 1, // OK; See #50072. + V3 = Self::V1 {} as u8 + 2, //~ ERROR cycle detected when const-evaluating +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr new file mode 100644 index 0000000000..dc4050e44a --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -0,0 +1,28 @@ +error[E0391]: cycle detected when const-evaluating + checking `Alpha::V3::{{constant}}#0` + --> $DIR/self-in-enum-definition.rs:5:10 + | +LL | V3 = Self::V1 {} as u8 + 2, + | ^^^^^^^^ + | +note: ...which requires const-evaluating `Alpha::V3::{{constant}}#0`... + --> $DIR/self-in-enum-definition.rs:5:10 + | +LL | V3 = Self::V1 {} as u8 + 2, + | ^^^^^^^^ + = note: ...which requires computing layout of `Alpha`... + = note: ...which again requires const-evaluating + checking `Alpha::V3::{{constant}}#0`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/self-in-enum-definition.rs:1:1 + | +LL | / #[repr(u8)] +LL | | enum Alpha { +LL | | V1 = 41, +LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072. +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/existential_types/existential-associated-type.rs b/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs similarity index 72% rename from src/test/ui/existential_types/existential-associated-type.rs rename to src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs index 299ae91b84..42f07d49ff 100644 --- a/src/test/ui/existential_types/existential-associated-type.rs +++ b/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs @@ -1,5 +1,5 @@ -#![feature(existential_type)] -// compile-pass +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy; @@ -11,7 +11,7 @@ trait Foo { fn bar() -> Self::Assoc; } -existential type Helper: Bar; +type Helper = impl Bar; impl Foo for i32 { type Assoc = Helper; diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs new file mode 100644 index 0000000000..f61807cbdb --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs @@ -0,0 +1,11 @@ +// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. + +#![crate_type="rlib"] + +#![feature(type_alias_impl_trait)] + +pub type Foo = impl std::fmt::Debug; + +pub fn foo() -> Foo { + 5 +} diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs similarity index 58% rename from src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs rename to src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs index 39ec5394fe..0082345626 100644 --- a/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs +++ b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs @@ -1,8 +1,8 @@ -// Crate that exports an existential type. Used for testing cross-crate. +// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. #![crate_type="rlib"] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] pub trait View { type Tmp: Iterator; @@ -13,7 +13,7 @@ pub trait View { pub struct X; impl View for X { - existential type Tmp: Iterator; + type Tmp = impl Iterator; fn test(&self) -> Self::Tmp { vec![1,2,3].into_iter() diff --git a/src/test/ui/existential_types/bound_reduction.rs b/src/test/ui/type-alias-impl-trait/bound_reduction.rs similarity index 63% rename from src/test/ui/existential_types/bound_reduction.rs rename to src/test/ui/type-alias-impl-trait/bound_reduction.rs index c1c0c60d59..18c840d8ed 100644 --- a/src/test/ui/existential_types/bound_reduction.rs +++ b/src/test/ui/type-alias-impl-trait/bound_reduction.rs @@ -1,13 +1,13 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() { } -existential type Foo: std::fmt::Debug; +type Foo = impl std::fmt::Debug; trait Trait {} diff --git a/src/test/ui/existential_types/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs similarity index 79% rename from src/test/ui/existential_types/bound_reduction2.rs rename to src/test/ui/type-alias-impl-trait/bound_reduction2.rs index 542e076d88..919446877a 100644 --- a/src/test/ui/existential_types/bound_reduction2.rs +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs @@ -1,4 +1,4 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() { } @@ -7,7 +7,7 @@ trait TraitWithAssoc { type Assoc; } -existential type Foo: Trait; +type Foo = impl Trait; //~^ ERROR could not find defining uses trait Trait {} diff --git a/src/test/ui/existential_types/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr similarity index 62% rename from src/test/ui/existential_types/bound_reduction2.stderr rename to src/test/ui/type-alias-impl-trait/bound_reduction2.stderr index b8bad7db6b..886d17aca3 100644 --- a/src/test/ui/existential_types/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,4 +1,4 @@ -error: defining existential type use does not fully define existential type +error: defining opaque type use does not fully define opaque type --> $DIR/bound_reduction2.rs:17:1 | LL | / fn foo_desugared(_: T) -> Foo { @@ -9,8 +9,8 @@ LL | | } error: could not find defining uses --> $DIR/bound_reduction2.rs:10:1 | -LL | existential type Foo: Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Foo = impl Trait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/existential_types/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs similarity index 81% rename from src/test/ui/existential_types/cross_crate_ice.rs rename to src/test/ui/type-alias-impl-trait/cross_crate_ice.rs index c5d5ca916a..c30608176a 100644 --- a/src/test/ui/existential_types/cross_crate_ice.rs +++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs @@ -1,5 +1,5 @@ // aux-build:cross_crate_ice.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate cross_crate_ice; diff --git a/src/test/ui/existential_types/cross_crate_ice2.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs similarity index 75% rename from src/test/ui/existential_types/cross_crate_ice2.rs rename to src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs index a0f3933ce3..3a7e490260 100644 --- a/src/test/ui/existential_types/cross_crate_ice2.rs +++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs @@ -1,5 +1,5 @@ // aux-build:cross_crate_ice2.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate cross_crate_ice2; diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs new file mode 100644 index 0000000000..c4bf56a919 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs @@ -0,0 +1,6 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// declared but never defined +type Bar = impl std::fmt::Debug; //~ ERROR could not find defining uses diff --git a/src/test/ui/existential_types/declared_but_never_defined.stderr b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr similarity index 58% rename from src/test/ui/existential_types/declared_but_never_defined.stderr rename to src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr index 7294a074db..ae0fee4333 100644 --- a/src/test/ui/existential_types/declared_but_never_defined.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr @@ -1,8 +1,8 @@ error: could not find defining uses --> $DIR/declared_but_never_defined.rs:6:1 | -LL | existential type Bar: std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Bar = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs new file mode 100644 index 0000000000..09873a8c8c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +mod boo { + // declared in module but not defined inside of it + pub type Boo = impl ::std::fmt::Debug; //~ ERROR could not find defining uses +} + +fn bomp() -> boo::Boo { + "" +} diff --git a/src/test/ui/existential_types/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr similarity index 55% rename from src/test/ui/existential_types/declared_but_not_defined_in_scope.stderr rename to src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr index a72709f719..0642407aba 100644 --- a/src/test/ui/existential_types/declared_but_not_defined_in_scope.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -1,8 +1,8 @@ error: could not find defining uses --> $DIR/declared_but_not_defined_in_scope.rs:7:5 | -LL | pub existential type Boo: ::std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub type Boo = impl ::std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/existential_types/different_defining_uses.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses.rs similarity index 69% rename from src/test/ui/existential_types/different_defining_uses.rs rename to src/test/ui/type-alias-impl-trait/different_defining_uses.rs index a8670cc07f..2d7780a126 100644 --- a/src/test/ui/existential_types/different_defining_uses.rs +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses.rs @@ -1,9 +1,9 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} // two definitions with different types -existential type Foo: std::fmt::Debug; +type Foo = impl std::fmt::Debug; fn foo() -> Foo { "" diff --git a/src/test/ui/existential_types/different_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr similarity index 81% rename from src/test/ui/existential_types/different_defining_uses.stderr rename to src/test/ui/type-alias-impl-trait/different_defining_uses.stderr index fddba58479..87ed997ec5 100644 --- a/src/test/ui/existential_types/different_defining_uses.stderr +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses.rs:12:1 | LL | / fn bar() -> Foo { diff --git a/src/test/ui/existential_types/different_defining_uses_never_type.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs similarity index 77% rename from src/test/ui/existential_types/different_defining_uses_never_type.rs rename to src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs index 13ada63e4b..289b97b00a 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type.rs +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs @@ -1,9 +1,9 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} // two definitions with different types -existential type Foo: std::fmt::Debug; +type Foo = impl std::fmt::Debug; fn foo() -> Foo { "" diff --git a/src/test/ui/existential_types/different_defining_uses_never_type.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr similarity index 81% rename from src/test/ui/existential_types/different_defining_uses_never_type.stderr rename to src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr index 14b7a810be..5be656e8f4 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type.stderr +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses_never_type.rs:12:1 | LL | / fn bar() -> Foo { @@ -14,7 +14,7 @@ LL | | "" LL | | } | |_^ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses_never_type.rs:16:1 | LL | / fn boo() -> Foo { diff --git a/src/test/ui/existential_types/different_defining_uses_never_type2.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs similarity index 79% rename from src/test/ui/existential_types/different_defining_uses_never_type2.rs rename to src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs index 2953f1745e..8549687ea7 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type2.rs +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs @@ -1,11 +1,11 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} // two definitions with different types -existential type Foo: std::fmt::Debug; +type Foo = impl std::fmt::Debug; fn foo() -> Foo { "" diff --git a/src/test/ui/existential_types/generic_different_defining_uses.rs b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs similarity index 70% rename from src/test/ui/existential_types/generic_different_defining_uses.rs rename to src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs index ce3ab88a1c..ac87c2d446 100644 --- a/src/test/ui/existential_types/generic_different_defining_uses.rs +++ b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs @@ -1,8 +1,8 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} -existential type MyIter: Iterator; +type MyIter = impl Iterator; fn my_iter(t: T) -> MyIter { std::iter::once(t) diff --git a/src/test/ui/existential_types/generic_different_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr similarity index 85% rename from src/test/ui/existential_types/generic_different_defining_uses.stderr rename to src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr index e5b1539ccb..4bcd2e1cb1 100644 --- a/src/test/ui/existential_types/generic_different_defining_uses.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/generic_different_defining_uses.rs:11:1 | LL | / fn my_iter2(t: T) -> MyIter { diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs new file mode 100644 index 0000000000..c18a711675 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -0,0 +1,9 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Two<'a, 'b> = impl std::fmt::Debug; + +fn one<'a>(t: &'a ()) -> Two<'a, 'a> { //~ ERROR non-defining opaque type use + t +} diff --git a/src/test/ui/existential_types/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr similarity index 52% rename from src/test/ui/existential_types/generic_duplicate_lifetime_param.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index 29bd252bab..a4d9a67215 100644 --- a/src/test/ui/existential_types/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,4 +1,4 @@ -error: non-defining existential type use in defining scope +error: non-defining opaque type use in defining scope --> $DIR/generic_duplicate_lifetime_param.rs:7:1 | LL | / fn one<'a>(t: &'a ()) -> Two<'a, 'a> { @@ -7,10 +7,10 @@ LL | | } | |_^ | note: lifetime used multiple times - --> $DIR/generic_duplicate_lifetime_param.rs:5:22 + --> $DIR/generic_duplicate_lifetime_param.rs:5:10 | -LL | existential type Two<'a, 'b>: std::fmt::Debug; - | ^^ ^^ +LL | type Two<'a, 'b> = impl std::fmt::Debug; + | ^^ ^^ error: aborting due to previous error diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs similarity index 55% rename from src/test/ui/existential_types/generic_duplicate_param_use.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index 3f8753333a..165e320be5 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -1,14 +1,14 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} // test that unused generic parameters are ok -existential type Two: Debug; +type Two = impl Debug; //~^ could not find defining uses fn one(t: T) -> Two { -//~^ ERROR defining existential type use restricts existential type +//~^ ERROR defining opaque type use restricts opaque type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr similarity index 58% rename from src/test/ui/existential_types/generic_duplicate_param_use.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index a3827943b6..e1794034e2 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,4 +1,4 @@ -error: defining existential type use restricts existential type by using the generic parameter `T` twice +error: defining opaque type use restricts opaque type by using the generic parameter `T` twice --> $DIR/generic_duplicate_param_use.rs:11:1 | LL | / fn one(t: T) -> Two { @@ -10,8 +10,8 @@ LL | | } error: could not find defining uses --> $DIR/generic_duplicate_param_use.rs:8:1 | -LL | existential type Two: Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs new file mode 100644 index 0000000000..898dab1b0b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two = impl Debug; + +fn two(t: T, _: U) -> Two { + (t, 4u32) +} diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs similarity index 59% rename from src/test/ui/existential_types/generic_duplicate_param_use2.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs index 3842292dec..0adce817c5 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use2.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -1,14 +1,14 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} // test that unused generic parameters are ok -existential type Two: Debug; +type Two = impl Debug; fn one(t: T) -> Two { -//~^ defining existential type use restricts existential type +//~^ defining opaque type use restricts opaque type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr similarity index 62% rename from src/test/ui/existential_types/generic_duplicate_param_use2.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr index 74f2802449..a9a51fa0b4 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr @@ -1,4 +1,4 @@ -error: defining existential type use restricts existential type by using the generic parameter `T` twice +error: defining opaque type use restricts opaque type by using the generic parameter `T` twice --> $DIR/generic_duplicate_param_use2.rs:10:1 | LL | / fn one(t: T) -> Two { diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs similarity index 71% rename from src/test/ui/existential_types/generic_duplicate_param_use3.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index 05c77c8947..8d3e7f9f42 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use3.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -1,14 +1,14 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} // test that unused generic parameters are ok -existential type Two: Debug; +type Two = impl Debug; fn one(t: T) -> Two { -//~^ defining existential type use restricts existential type +//~^ defining opaque type use restricts opaque type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr similarity index 85% rename from src/test/ui/existential_types/generic_duplicate_param_use3.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr index 22d5467c36..04dcdc295f 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -1,4 +1,4 @@ -error: defining existential type use restricts existential type by using the generic parameter `T` twice +error: defining opaque type use restricts opaque type by using the generic parameter `T` twice --> $DIR/generic_duplicate_param_use3.rs:10:1 | LL | / fn one(t: T) -> Two { diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs similarity index 58% rename from src/test/ui/existential_types/generic_duplicate_param_use4.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs index 609dbe06cd..65f7d7f485 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use4.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs @@ -1,14 +1,14 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} // test that unused generic parameters are ok -existential type Two: Debug; +type Two = impl Debug; fn one(t: T) -> Two { -//~^ ERROR defining existential type use restricts existential type +//~^ ERROR defining opaque type use restricts opaque type t } diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr similarity index 62% rename from src/test/ui/existential_types/generic_duplicate_param_use4.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr index d7e695578d..082177b821 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr @@ -1,4 +1,4 @@ -error: defining existential type use restricts existential type by using the generic parameter `T` twice +error: defining opaque type use restricts opaque type by using the generic parameter `T` twice --> $DIR/generic_duplicate_param_use4.rs:10:1 | LL | / fn one(t: T) -> Two { diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs similarity index 80% rename from src/test/ui/existential_types/generic_duplicate_param_use5.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs index 3f4a23b8b4..ac87731041 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use5.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs @@ -1,11 +1,11 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} // test that unused generic parameters are ok -existential type Two: Debug; +type Two = impl Debug; fn two(t: T, u: U) -> Two { (t, u) diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr similarity index 84% rename from src/test/ui/existential_types/generic_duplicate_param_use5.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr index cf4535d6c2..589ea74931 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/generic_duplicate_param_use5.rs:14:1 | LL | / fn three(t: T, u: U) -> Two { diff --git a/src/test/ui/existential_types/generic_duplicate_param_use6.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs similarity index 80% rename from src/test/ui/existential_types/generic_duplicate_param_use6.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs index 3b8c56352b..59e7de413a 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use6.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs @@ -1,11 +1,11 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} // test that unused generic parameters are ok -existential type Two: Debug; +type Two = impl Debug; fn two(t: T, u: U) -> Two { (t, t) diff --git a/src/test/ui/existential_types/generic_duplicate_param_use6.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr similarity index 84% rename from src/test/ui/existential_types/generic_duplicate_param_use6.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr index 1f767dacea..66649413d3 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use6.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/generic_duplicate_param_use6.rs:14:1 | LL | / fn three(t: T, u: U) -> Two { diff --git a/src/test/ui/existential_types/generic_duplicate_param_use7.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs similarity index 73% rename from src/test/ui/existential_types/generic_duplicate_param_use7.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs index 5d8d05c308..712a6539f0 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use7.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs @@ -1,11 +1,11 @@ -// compile-pass -#![feature(existential_type)] +// build-pass (FIXME(62277): could be check-pass?) +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} -existential type Two: Debug; +type Two = impl Debug; fn two(t: T, u: U) -> Two { (t, t) diff --git a/src/test/ui/existential_types/generic_duplicate_param_use8.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs similarity index 77% rename from src/test/ui/existential_types/generic_duplicate_param_use8.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs index 83501ad8c4..777ded5260 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use8.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs @@ -1,10 +1,10 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} -existential type Two: Debug; +type Two = impl Debug; fn two(t: T, _: U) -> Two { (t, 4u32) diff --git a/src/test/ui/existential_types/generic_duplicate_param_use8.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr similarity index 85% rename from src/test/ui/existential_types/generic_duplicate_param_use8.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr index 58f4f97b24..8f4cf4c608 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use8.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/generic_duplicate_param_use8.rs:13:1 | LL | / fn three(_: T, u: U) -> Two { diff --git a/src/test/ui/existential_types/generic_duplicate_param_use9.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs similarity index 82% rename from src/test/ui/existential_types/generic_duplicate_param_use9.rs rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs index 4c6897298c..491e6647f4 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use9.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs @@ -1,10 +1,10 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} -existential type Two: Debug; +type Two = impl Debug; trait Foo { type Bar: Debug; diff --git a/src/test/ui/existential_types/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr similarity index 85% rename from src/test/ui/existential_types/generic_duplicate_param_use9.stderr rename to src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr index fe4ae6cfdd..4d0b03ba5e 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use9.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr @@ -1,4 +1,4 @@ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/generic_duplicate_param_use9.rs:18:1 | LL | / fn three(t: T, u: U) -> Two { diff --git a/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs new file mode 100644 index 0000000000..e109c38c98 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Region<'a> = impl std::fmt::Debug; + +fn region<'b>(a: &'b ()) -> Region<'b> { + a +} diff --git a/src/test/ui/existential_types/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs similarity index 56% rename from src/test/ui/existential_types/generic_nondefining_use.rs rename to src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs index ffc965aca4..60106eba17 100644 --- a/src/test/ui/existential_types/generic_nondefining_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -1,13 +1,13 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} -existential type Cmp: 'static; +type Cmp = impl 'static; //~^ ERROR could not find defining uses //~^^ ERROR: at least one trait must be specified // not a defining use, because it doesn't define *all* possible generics -fn cmp() -> Cmp { //~ ERROR defining existential type use does not fully define +fn cmp() -> Cmp { //~ ERROR defining opaque type use does not fully define 5u32 } diff --git a/src/test/ui/existential_types/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr similarity index 51% rename from src/test/ui/existential_types/generic_nondefining_use.stderr rename to src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index d205d44c68..d98d349be3 100644 --- a/src/test/ui/existential_types/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -1,10 +1,10 @@ error: at least one trait must be specified - --> $DIR/generic_nondefining_use.rs:5:26 + --> $DIR/generic_nondefining_use.rs:5:20 | -LL | existential type Cmp: 'static; - | ^^^^^^^ +LL | type Cmp = impl 'static; + | ^^^^^^^ -error: defining existential type use does not fully define existential type +error: defining opaque type use does not fully define opaque type --> $DIR/generic_nondefining_use.rs:11:1 | LL | / fn cmp() -> Cmp { @@ -15,8 +15,8 @@ LL | | } error: could not find defining uses --> $DIR/generic_nondefining_use.rs:5:1 | -LL | existential type Cmp: 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Cmp = impl 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/existential_types/generic_not_used.rs b/src/test/ui/type-alias-impl-trait/generic_not_used.rs similarity index 73% rename from src/test/ui/existential_types/generic_not_used.rs rename to src/test/ui/type-alias-impl-trait/generic_not_used.rs index 054e6f5f2a..ace52dc83a 100644 --- a/src/test/ui/existential_types/generic_not_used.rs +++ b/src/test/ui/type-alias-impl-trait/generic_not_used.rs @@ -1,8 +1,8 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} -existential type WrongGeneric: 'static; +type WrongGeneric = impl 'static; //~^ ERROR: at least one trait must be specified fn wrong_generic(_: U, v: V) -> WrongGeneric { diff --git a/src/test/ui/existential_types/generic_not_used.stderr b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr similarity index 67% rename from src/test/ui/existential_types/generic_not_used.stderr rename to src/test/ui/type-alias-impl-trait/generic_not_used.stderr index d243233992..fe353f6e3d 100644 --- a/src/test/ui/existential_types/generic_not_used.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr @@ -1,10 +1,10 @@ error: at least one trait must be specified - --> $DIR/generic_not_used.rs:5:44 + --> $DIR/generic_not_used.rs:5:38 | -LL | existential type WrongGeneric: 'static; - | ^^^^^^^ +LL | type WrongGeneric = impl 'static; + | ^^^^^^^ -error: type parameter `V` is part of concrete type but not used in parameter list for existential type +error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias --> $DIR/generic_not_used.rs:8:73 | LL | fn wrong_generic(_: U, v: V) -> WrongGeneric { diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr similarity index 73% rename from src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr rename to src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr index f316644156..3f25d5fbd9 100644 --- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr @@ -1,8 +1,8 @@ error: at least one trait must be specified - --> $DIR/generic_type_does_not_live_long_enough.rs:9:35 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:29 | -LL | existential type WrongGeneric: 'static; - | ^^^^^^^ +LL | type WrongGeneric = impl 'static; + | ^^^^^^^ error[E0308]: mismatched types --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs similarity index 79% rename from src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs rename to src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index d9eedd6dca..c0f939a504 100644 --- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -1,4 +1,4 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() { let y = 42; @@ -6,7 +6,7 @@ fn main() { let z: i32 = x; //~ ERROR mismatched types } -existential type WrongGeneric: 'static; +type WrongGeneric = impl 'static; //~^ ERROR the parameter type `T` may not live long enough //~^^ ERROR: at least one trait must be specified diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr similarity index 71% rename from src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr rename to src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index 2f76eea446..12569211df 100644 --- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -1,8 +1,8 @@ error: at least one trait must be specified - --> $DIR/generic_type_does_not_live_long_enough.rs:9:35 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:29 | -LL | existential type WrongGeneric: 'static; - | ^^^^^^^ +LL | type WrongGeneric = impl 'static; + | ^^^^^^^ error[E0308]: mismatched types --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 @@ -16,8 +16,8 @@ LL | let z: i32 = x; error[E0310]: the parameter type `T` may not live long enough --> $DIR/generic_type_does_not_live_long_enough.rs:9:1 | -LL | existential type WrongGeneric: 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type WrongGeneric = impl 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound `T: 'static`... @@ -25,8 +25,8 @@ LL | fn wrong_generic(t: T) -> WrongGeneric { note: ...so that the type `T` will meet its required lifetime bounds --> $DIR/generic_type_does_not_live_long_enough.rs:9:1 | -LL | existential type WrongGeneric: 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type WrongGeneric = impl 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/existential_types/generic_underconstrained.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs similarity index 59% rename from src/test/ui/existential_types/generic_underconstrained.rs rename to src/test/ui/type-alias-impl-trait/generic_underconstrained.rs index cc0db893c6..589612d5ed 100644 --- a/src/test/ui/existential_types/generic_underconstrained.rs +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs @@ -1,9 +1,9 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} trait Trait {} -existential type Underconstrained: 'static; //~ ERROR the trait bound `T: Trait` +type Underconstrained = impl 'static; //~ ERROR the trait bound `T: Trait` //~^ ERROR: at least one trait must be specified // no `Trait` bound diff --git a/src/test/ui/existential_types/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr similarity index 55% rename from src/test/ui/existential_types/generic_underconstrained.stderr rename to src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr index 35083a53eb..dd90dd1b06 100644 --- a/src/test/ui/existential_types/generic_underconstrained.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr @@ -1,14 +1,14 @@ error: at least one trait must be specified - --> $DIR/generic_underconstrained.rs:6:46 + --> $DIR/generic_underconstrained.rs:6:40 | -LL | existential type Underconstrained: 'static; - | ^^^^^^^ +LL | type Underconstrained = impl 'static; + | ^^^^^^^ error[E0277]: the trait bound `T: Trait` is not satisfied --> $DIR/generic_underconstrained.rs:6:1 | -LL | existential type Underconstrained: 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` +LL | type Underconstrained = impl 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` | = help: consider adding a `where T: Trait` bound = note: the return type of a function must have a statically known size diff --git a/src/test/ui/existential_types/generic_underconstrained2.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs similarity index 76% rename from src/test/ui/existential_types/generic_underconstrained2.rs rename to src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs index c6263eacd5..87b8aaad95 100644 --- a/src/test/ui/existential_types/generic_underconstrained2.rs +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs @@ -1,8 +1,8 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} -existential type Underconstrained: 'static; +type Underconstrained = impl 'static; //~^ ERROR `U` doesn't implement `std::fmt::Debug` //~^^ ERROR: at least one trait must be specified @@ -11,7 +11,7 @@ fn underconstrained(_: U) -> Underconstrained { 5u32 } -existential type Underconstrained2: 'static; +type Underconstrained2 = impl 'static; //~^ ERROR `V` doesn't implement `std::fmt::Debug` //~^^ ERROR: at least one trait must be specified diff --git a/src/test/ui/existential_types/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr similarity index 50% rename from src/test/ui/existential_types/generic_underconstrained2.stderr rename to src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr index 6ff783f33b..574432bdcf 100644 --- a/src/test/ui/existential_types/generic_underconstrained2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -1,20 +1,20 @@ error: at least one trait must be specified - --> $DIR/generic_underconstrained2.rs:5:56 + --> $DIR/generic_underconstrained2.rs:5:50 | -LL | existential type Underconstrained: 'static; - | ^^^^^^^ +LL | type Underconstrained = impl 'static; + | ^^^^^^^ error: at least one trait must be specified - --> $DIR/generic_underconstrained2.rs:14:57 + --> $DIR/generic_underconstrained2.rs:14:51 | -LL | existential type Underconstrained2: 'static; - | ^^^^^^^ +LL | type Underconstrained2 = impl 'static; + | ^^^^^^^ error[E0277]: `U` doesn't implement `std::fmt::Debug` --> $DIR/generic_underconstrained2.rs:5:1 | -LL | existential type Underconstrained: 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` +LL | type Underconstrained = impl 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `std::fmt::Debug` is not implemented for `U` = help: consider adding a `where U: std::fmt::Debug` bound @@ -23,8 +23,8 @@ LL | existential type Underconstrained: 'static; error[E0277]: `V` doesn't implement `std::fmt::Debug` --> $DIR/generic_underconstrained2.rs:14:1 | -LL | existential type Underconstrained2: 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` +LL | type Underconstrained2 = impl 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = help: the trait `std::fmt::Debug` is not implemented for `V` = help: consider adding a `where V: std::fmt::Debug` bound diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs new file mode 100644 index 0000000000..a102d16078 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs @@ -0,0 +1,13 @@ +// Checks to ensure that we properly detect when a closure constrains an opaque type + +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() { + type Opaque = impl Debug; + fn _unused() -> Opaque { String::new() } + //~^ ERROR: concrete type differs from previous defining opaque type use + let null = || -> Opaque { 0 }; + println!("{:?}", null()); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr new file mode 100644 index 0000000000..c994eb5986 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr @@ -0,0 +1,20 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/issue-52843-closure-constrain.rs:9:5 + | +LL | fn _unused() -> Opaque { String::new() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, got `std::string::String` + | +note: previous use here + --> $DIR/issue-52843-closure-constrain.rs:7:1 + | +LL | / fn main() { +LL | | type Opaque = impl Debug; +LL | | fn _unused() -> Opaque { String::new() } +LL | | +LL | | let null = || -> Opaque { 0 }; +LL | | println!("{:?}", null()); +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-53096.rs b/src/test/ui/type-alias-impl-trait/issue-53096.rs new file mode 100644 index 0000000000..564c5c3d33 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53096.rs @@ -0,0 +1,9 @@ +// check-pass +#![feature(const_fn)] +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> usize; +const fn bar() -> Foo { || 0usize } +const BAZR: Foo = bar(); + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.rs b/src/test/ui/type-alias-impl-trait/issue-53598.rs new file mode 100644 index 0000000000..61dff79d07 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53598.rs @@ -0,0 +1,28 @@ +// ignore-tidy-linelength +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +pub trait Foo { + type Item: Debug; + + fn foo(_: T) -> Self::Item; +} + +#[derive(Debug)] +pub struct S(std::marker::PhantomData); + +pub struct S2; + +impl Foo for S2 { + type Item = impl Debug; + + fn foo(_: T) -> Self::Item { + //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + S::(Default::default()) + } +} + +fn main() { + S2::foo(123); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.stderr new file mode 100644 index 0000000000..4c8144a235 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53598.stderr @@ -0,0 +1,12 @@ +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-53598.rs:20:42 + | +LL | fn foo(_: T) -> Self::Item { + | __________________________________________^ +LL | | +LL | | S::(Default::default()) +LL | | } + | |_____^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs new file mode 100644 index 0000000000..e7f9373243 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(const_fn, generators, generator_trait, type_alias_impl_trait)] + +use std::ops::Generator; + +type GenOnce = impl Generator; + +const fn const_generator(yielding: Y, returning: R) -> GenOnce { + move || { + yield yielding; + + return returning; + } +} + +const FOO: GenOnce = const_generator(10, 100); + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.rs b/src/test/ui/type-alias-impl-trait/issue-57700.rs new file mode 100644 index 0000000000..bfabef5472 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57700.rs @@ -0,0 +1,22 @@ +// ignore-tidy-linelength +#![feature(arbitrary_self_types)] +#![feature(type_alias_impl_trait)] + +use std::ops::Deref; + +trait Foo { + type Bar: Foo; + + fn foo(self: impl Deref) -> Self::Bar; +} + +impl Foo for C { + type Bar = impl Foo; + + fn foo(self: impl Deref) -> Self::Bar { + //~^ Error type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias + self + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.stderr new file mode 100644 index 0000000000..c701e3e74e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57700.stderr @@ -0,0 +1,12 @@ +error: type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-57700.rs:16:58 + | +LL | fn foo(self: impl Deref) -> Self::Bar { + | __________________________________________________________^ +LL | | +LL | | self +LL | | } + | |_____^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-58887.rs b/src/test/ui/type-alias-impl-trait/issue-58887.rs new file mode 100644 index 0000000000..92ba50ae6c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58887.rs @@ -0,0 +1,23 @@ +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +impl UnwrapItemsExt for I +where + I: Iterator>, + E: std::fmt::Debug, +{ + type Iter = impl Iterator; + //~^ ERROR: could not find defining uses + + fn unwrap_items(self) -> Self::Iter { + //~^ ERROR: type parameter `T` is part of concrete type + //~| ERROR: type parameter `E` is part of concrete type + self.map(|x| x.unwrap()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-58887.stderr b/src/test/ui/type-alias-impl-trait/issue-58887.stderr new file mode 100644 index 0000000000..7e2895711d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58887.stderr @@ -0,0 +1,30 @@ +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-58887.rs:16:41 + | +LL | fn unwrap_items(self) -> Self::Iter { + | _________________________________________^ +LL | | +LL | | +LL | | self.map(|x| x.unwrap()) +LL | | } + | |_____^ + +error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-58887.rs:16:41 + | +LL | fn unwrap_items(self) -> Self::Iter { + | _________________________________________^ +LL | | +LL | | +LL | | self.map(|x| x.unwrap()) +LL | | } + | |_____^ + +error: could not find defining uses + --> $DIR/issue-58887.rs:13:5 + | +LL | type Iter = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/issue-58951.rs b/src/test/ui/type-alias-impl-trait/issue-58951.rs new file mode 100644 index 0000000000..3416c6745b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58951.rs @@ -0,0 +1,13 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type A = impl Iterator; + +fn def_a() -> A { 0..1 } + +pub fn use_a() { + def_a().map(|x| x); +} + +fn main() {} diff --git a/src/test/ui/existential-type/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs similarity index 76% rename from src/test/ui/existential-type/issue-60371.rs rename to src/test/ui/type-alias-impl-trait/issue-60371.rs index f9def11d19..50b9d1ac79 100644 --- a/src/test/ui/existential-type/issue-60371.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -5,7 +5,7 @@ trait Bug { } impl Bug for &() { - existential type Item: Bug; //~ ERROR existential types are unstable + type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable //~^ ERROR the trait bound `(): Bug` is not satisfied //~^^ ERROR could not find defining uses diff --git a/src/test/ui/existential-type/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr similarity index 59% rename from src/test/ui/existential-type/issue-60371.stderr rename to src/test/ui/type-alias-impl-trait/issue-60371.stderr index 2560e01047..1e9b12ebc3 100644 --- a/src/test/ui/existential-type/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -1,17 +1,17 @@ -error[E0658]: existential types are unstable +error[E0658]: `impl Trait` in type aliases is unstable --> $DIR/issue-60371.rs:8:5 | -LL | existential type Item: Bug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Item = impl Bug; + | ^^^^^^^^^^^^^^^^^^^^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/34511 - = help: add #![feature(existential_type)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0277]: the trait bound `(): Bug` is not satisfied --> $DIR/issue-60371.rs:8:5 | -LL | existential type Item: Bug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bug` is not implemented for `()` +LL | type Item = impl Bug; + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Bug` is not implemented for `()` | = help: the following implementations were found: <&() as Bug> @@ -20,8 +20,8 @@ LL | existential type Item: Bug; error: could not find defining uses --> $DIR/issue-60371.rs:8:5 | -LL | existential type Item: Bug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Item = impl Bug; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.rs b/src/test/ui/type-alias-impl-trait/issue-60407.rs new file mode 100644 index 0000000000..7d462f057c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60407.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type Debuggable = impl core::fmt::Debug; + +static mut TEST: Option = None; + +fn main() { + unsafe { TEST = Some(foo()) } +} + +fn foo() -> Debuggable { + 0u32 +} diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs new file mode 100644 index 0000000000..91c4576597 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] + +trait IterBits { + type BitsIter: Iterator; + fn iter_bits(self, n: u8) -> Self::BitsIter; +} + +type IterBitsIter = impl std::iter::Iterator; +//~^ ERROR could not find defining uses + +impl IterBits for T +where + T: std::ops::Shr + + std::ops::BitAnd + + std::convert::From + + std::convert::TryInto, + E: std::fmt::Debug, +{ + type BitsIter = IterBitsIter; + fn iter_bits(self, n: u8) -> Self::BitsIter { + //~^ ERROR type parameter `E` is part of concrete type but not used + (0u8..n) + .rev() + .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + } +} diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr new file mode 100644 index 0000000000..ebb13fca1d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -0,0 +1,25 @@ +error[E0601]: `main` function not found in crate `issue_60564` + | + = note: consider adding a `main` function to `$DIR/issue-60564.rs` + +error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-60564.rs:20:49 + | +LL | fn iter_bits(self, n: u8) -> Self::BitsIter { + | _________________________________________________^ +LL | | +LL | | (0u8..n) +LL | | .rev() +LL | | .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) +LL | | } + | |_____^ + +error: could not find defining uses + --> $DIR/issue-60564.rs:8:1 + | +LL | type IterBitsIter = impl std::iter::Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/existential_types/nested_existential_types.rs b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs similarity index 57% rename from src/test/ui/existential_types/nested_existential_types.rs rename to src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 6d2a12da7e..82c9ecd2ac 100644 --- a/src/test/ui/existential_types/nested_existential_types.rs +++ b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -1,10 +1,10 @@ -#![feature(existential_type)] -// compile-pass +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) mod my_mod { use std::fmt::Debug; - pub existential type Foo: Debug; - pub existential type Foot: Debug; + pub type Foo = impl Debug; + pub type Foot = impl Debug; pub fn get_foo() -> Foo { 5i32 diff --git a/src/test/ui/existential_types/never_reveal_concrete_type.rs b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs similarity index 75% rename from src/test/ui/existential_types/never_reveal_concrete_type.rs rename to src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs index 04da394848..8787c023eb 100644 --- a/src/test/ui/existential_types/never_reveal_concrete_type.rs +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs @@ -1,9 +1,9 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} // don't reveal the concrete type -existential type NoReveal: std::fmt::Debug; +type NoReveal = impl std::fmt::Debug; fn define_no_reveal() -> NoReveal { "" diff --git a/src/test/ui/existential_types/never_reveal_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr similarity index 100% rename from src/test/ui/existential_types/never_reveal_concrete_type.stderr rename to src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs new file mode 100644 index 0000000000..c9ca504f78 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -0,0 +1,13 @@ +// Issue 52985: user code provides no use case that allows a type alias `impl Trait` +// We now emit a 'could not find defining uses' error + +#![feature(type_alias_impl_trait)] + +type Foo = impl Copy; //~ could not find defining uses + +// make compiler happy about using 'Foo' +fn bar(x: Foo) -> Foo { x } + +fn main() { + let _: Foo = std::mem::transmute(0u8); +} diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr new file mode 100644 index 0000000000..444e6e8214 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -0,0 +1,8 @@ +error: could not find defining uses + --> $DIR/no_inferrable_concrete_type.rs:6:1 + | +LL | type Foo = impl Copy; + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/no_revealing_outside_defining_module.rs b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs similarity index 78% rename from src/test/ui/existential_types/no_revealing_outside_defining_module.rs rename to src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs index 04793c67b5..61153b1e17 100644 --- a/src/test/ui/existential_types/no_revealing_outside_defining_module.rs +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs @@ -1,9 +1,9 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() {} mod boo { - pub existential type Boo: ::std::fmt::Debug; + pub type Boo = impl ::std::fmt::Debug; fn bomp() -> Boo { "" } diff --git a/src/test/ui/existential_types/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr similarity index 100% rename from src/test/ui/existential_types/no_revealing_outside_defining_module.stderr rename to src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr diff --git a/src/test/ui/existential_types/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs similarity index 81% rename from src/test/ui/existential_types/not_a_defining_use.rs rename to src/test/ui/type-alias-impl-trait/not_a_defining_use.rs index 3f81f5177d..ca00e582d3 100644 --- a/src/test/ui/existential_types/not_a_defining_use.rs +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -1,13 +1,13 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() {} -existential type Two: Debug; +type Two = impl Debug; fn two(t: T) -> Two { - //~^ ERROR defining existential type use does not fully define existential type + //~^ ERROR defining opaque type use does not fully define opaque type (t, 4i8) } diff --git a/src/test/ui/existential_types/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr similarity index 78% rename from src/test/ui/existential_types/not_a_defining_use.stderr rename to src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr index f315811cdb..7bb8939ccf 100644 --- a/src/test/ui/existential_types/not_a_defining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -1,4 +1,4 @@ -error: defining existential type use does not fully define existential type +error: defining opaque type use does not fully define opaque type --> $DIR/not_a_defining_use.rs:9:1 | LL | / fn two(t: T) -> Two { @@ -7,7 +7,7 @@ LL | | (t, 4i8) LL | | } | |_^ -error: concrete type differs from previous defining existential type use +error: concrete type differs from previous defining opaque type use --> $DIR/not_a_defining_use.rs:30:1 | LL | / fn four(t: T) -> Two { diff --git a/src/test/ui/existential_types/not_well_formed.rs b/src/test/ui/type-alias-impl-trait/not_well_formed.rs similarity index 58% rename from src/test/ui/existential_types/not_well_formed.rs rename to src/test/ui/type-alias-impl-trait/not_well_formed.rs index 073fa90cb3..36ec9b34eb 100644 --- a/src/test/ui/existential_types/not_well_formed.rs +++ b/src/test/ui/type-alias-impl-trait/not_well_formed.rs @@ -1,4 +1,4 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() { } @@ -7,7 +7,7 @@ trait TraitWithAssoc { type Assoc; } -existential type Foo: Trait; //~ associated type `Assoc` not found for `V` +type Foo = impl Trait; //~ associated type `Assoc` not found for `V` trait Trait {} diff --git a/src/test/ui/existential_types/not_well_formed.stderr b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr similarity index 51% rename from src/test/ui/existential_types/not_well_formed.stderr rename to src/test/ui/type-alias-impl-trait/not_well_formed.stderr index 05f84d5762..d374d6d33e 100644 --- a/src/test/ui/existential_types/not_well_formed.stderr +++ b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr @@ -1,8 +1,8 @@ error[E0220]: associated type `Assoc` not found for `V` - --> $DIR/not_well_formed.rs:10:32 + --> $DIR/not_well_formed.rs:10:26 | -LL | existential type Foo: Trait; - | ^^^^^^^^ associated type `Assoc` not found +LL | type Foo = impl Trait; + | ^^^^^^^^ associated type `Assoc` not found error: aborting due to previous error diff --git a/src/test/ui/existential_types/private_unused.rs b/src/test/ui/type-alias-impl-trait/private_unused.rs similarity index 72% rename from src/test/ui/existential_types/private_unused.rs rename to src/test/ui/type-alias-impl-trait/private_unused.rs index 736d812bc0..92268f1861 100644 --- a/src/test/ui/existential_types/private_unused.rs +++ b/src/test/ui/type-alias-impl-trait/private_unused.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[deny(warnings)] diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs new file mode 100644 index 0000000000..0fd4d26ef6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +// Currently, the `type_alias_impl_trait` feature implicitly +// depends on `impl_trait_in_bindings` in order to work properly. +// Specifically, this line requires `impl_trait_in_bindings` to be enabled: +// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/src/librustc_typeck/check/mod.rs#L856 +#![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + +// Ensures that `const` items can constrain an opaque `impl Trait`. + +use std::fmt::Debug; + +pub type Foo = impl Debug; + +const _FOO: Foo = 5; + +fn main() { +} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr new file mode 100644 index 0000000000..691de82c9d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr @@ -0,0 +1,8 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/type-alias-impl-trait-const.rs:8:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs new file mode 100644 index 0000000000..a22b12cae6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs @@ -0,0 +1,27 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +// Regression test for issue #61863 + +pub trait MyTrait {} + +#[derive(Debug)] +pub struct MyStruct { + v: u64 +} + +impl MyTrait for MyStruct {} + +pub fn bla() -> TE { + return MyStruct {v:1} +} + +pub fn bla2() -> TE { + bla() +} + + +type TE = impl MyTrait; + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs new file mode 100644 index 0000000000..86c9d48214 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -0,0 +1,33 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +pub trait MyTrait {} + +impl MyTrait for bool {} + +struct Blah { + my_foo: Foo, + my_u8: u8 +} + +impl Blah { + fn new() -> Blah { + Blah { + my_foo: make_foo(), + my_u8: 12 + } + } + fn into_inner(self) -> (Foo, u8) { + (self.my_foo, self.my_u8) + } +} + +fn make_foo() -> Foo { + true +} + +type Foo = impl MyTrait; + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs new file mode 100644 index 0000000000..c009952eab --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> Foo; +//~^ ERROR: could not find defining uses + +fn crash(x: Foo) -> Foo { + x +} + +fn main() { + +} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr new file mode 100644 index 0000000000..02ab3399ea --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr @@ -0,0 +1,8 @@ +error: could not find defining uses + --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:1 + | +LL | type Foo = impl Fn() -> Foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs new file mode 100644 index 0000000000..32ecc36661 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type Item; +} + +type Foo = impl Bar; +//~^ ERROR: could not find defining uses + +fn crash(x: Foo) -> Foo { + x +} + +fn main() { + +} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr new file mode 100644 index 0000000000..e9abb79588 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr @@ -0,0 +1,8 @@ +error: could not find defining uses + --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:1 + | +LL | type Foo = impl Bar; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/existential_types/existential-types-with-no-traits.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs similarity index 75% rename from src/test/ui/existential_types/existential-types-with-no-traits.rs rename to src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs index 46339c73b1..8ca279eec9 100644 --- a/src/test/ui/existential_types/existential-types-with-no-traits.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs @@ -1,6 +1,6 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] -existential type Foo: 'static; +type Foo = impl 'static; //~^ ERROR: at least one trait must be specified fn foo() -> Foo { diff --git a/src/test/ui/existential_types/existential-types-with-no-traits.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr similarity index 53% rename from src/test/ui/existential_types/existential-types-with-no-traits.stderr rename to src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr index 4b2fbc79d3..58028bd086 100644 --- a/src/test/ui/existential_types/existential-types-with-no-traits.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr @@ -1,11 +1,11 @@ error: at least one trait must be specified - --> $DIR/existential-types-with-no-traits.rs:3:23 + --> $DIR/type-alias-impl-trait-with-no-traits.rs:3:17 | -LL | existential type Foo: 'static; - | ^^^^^^^ +LL | type Foo = impl 'static; + | ^^^^^^^ error: at least one trait must be specified - --> $DIR/existential-types-with-no-traits.rs:10:13 + --> $DIR/type-alias-impl-trait-with-no-traits.rs:10:13 | LL | fn bar() -> impl 'static { | ^^^^^^^^^^^^ diff --git a/src/test/run-pass/existential_type.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs similarity index 78% rename from src/test/run-pass/existential_type.rs rename to src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs index b36435cf11..209134acf0 100644 --- a/src/test/run-pass/existential_type.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs @@ -1,7 +1,9 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unused_variables)] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() { assert_eq!(foo().to_string(), "foo"); @@ -14,14 +16,14 @@ fn main() { } // single definition -existential type Foo: std::fmt::Display; +type Foo = impl std::fmt::Display; fn foo() -> Foo { "foo" } // two definitions -existential type Bar: std::fmt::Display; +type Bar = impl std::fmt::Display; fn bar1() -> Bar { "bar1" @@ -32,7 +34,7 @@ fn bar2() -> Bar { } // definition in submodule -existential type Boo: std::fmt::Display; +type Boo = impl std::fmt::Display; mod boo { pub fn boo() -> super::Boo { @@ -40,7 +42,7 @@ mod boo { } } -existential type MyIter: Iterator; +type MyIter = impl Iterator; fn my_iter(t: T) -> MyIter { std::iter::once(t) @@ -61,21 +63,21 @@ fn my_iter4(_: U, v: V) -> MyIter { } // param names should not have an effect! -existential type MyOtherIter: Iterator; +type MyOtherIter = impl Iterator; fn my_other_iter(u: U) -> MyOtherIter { std::iter::once(u) } trait Trait {} -existential type GenericBound<'a, T: Trait>: Sized + 'a; +type GenericBound<'a, T: Trait> = impl Sized + 'a; fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { t } mod pass_through { - pub existential type Passthrough: Sized + 'static; + pub type Passthrough = impl Sized + 'static; fn define_passthrough(t: T) -> Passthrough { t diff --git a/src/test/ui/existential_types/unused_generic_param.rs b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs similarity index 73% rename from src/test/ui/existential_types/unused_generic_param.rs rename to src/test/ui/type-alias-impl-trait/unused_generic_param.rs index 5455b39f4c..a9ab727b19 100644 --- a/src/test/ui/existential_types/unused_generic_param.rs +++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs @@ -1,16 +1,16 @@ -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] fn main() { } -existential type PartiallyDefined: 'static; +type PartiallyDefined = impl 'static; //~^ ERROR: at least one trait must be specified fn partially_defined(_: T) -> PartiallyDefined { 4u32 } -existential type PartiallyDefined2: 'static; +type PartiallyDefined2 = impl 'static; //~^ ERROR: at least one trait must be specified fn partially_defined2(_: T) -> PartiallyDefined2 { diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr b/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr new file mode 100644 index 0000000000..2310502696 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr @@ -0,0 +1,14 @@ +error: at least one trait must be specified + --> $DIR/unused_generic_param.rs:6:33 + | +LL | type PartiallyDefined = impl 'static; + | ^^^^^^^ + +error: at least one trait must be specified + --> $DIR/unused_generic_param.rs:13:34 + | +LL | type PartiallyDefined2 = impl 'static; + | ^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/run-pass/type-ascription.rs b/src/test/ui/type-ascription.rs similarity index 98% rename from src/test/run-pass/type-ascription.rs rename to src/test/ui/type-ascription.rs index 7e5231b7e0..7adb074428 100644 --- a/src/test/run-pass/type-ascription.rs +++ b/src/test/ui/type-ascription.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_variables)] // Type ascription doesn't lead to unsoundness diff --git a/src/test/run-pass/type-id-higher-rank-2.rs b/src/test/ui/type-id-higher-rank-2.rs similarity index 98% rename from src/test/run-pass/type-id-higher-rank-2.rs rename to src/test/ui/type-id-higher-rank-2.rs index 469bc8ed7e..5391c849da 100644 --- a/src/test/run-pass/type-id-higher-rank-2.rs +++ b/src/test/ui/type-id-higher-rank-2.rs @@ -1,3 +1,4 @@ +// run-pass // Test that we can't ignore lifetimes by going through Any. use std::any::Any; diff --git a/src/test/run-pass/type-id-higher-rank.rs b/src/test/ui/type-id-higher-rank.rs similarity index 99% rename from src/test/run-pass/type-id-higher-rank.rs rename to src/test/ui/type-id-higher-rank.rs index b98dff0d72..355d110994 100644 --- a/src/test/run-pass/type-id-higher-rank.rs +++ b/src/test/ui/type-id-higher-rank.rs @@ -1,3 +1,4 @@ +// run-pass // Test that type IDs correctly account for higher-rank lifetimes // Also acts as a regression test for an ICE (issue #19791) diff --git a/src/test/run-pass/type-in-nested-module.rs b/src/test/ui/type-in-nested-module.rs similarity index 94% rename from src/test/run-pass/type-in-nested-module.rs rename to src/test/ui/type-in-nested-module.rs index 077a28436d..8a92f065f1 100644 --- a/src/test/run-pass/type-in-nested-module.rs +++ b/src/test/ui/type-in-nested-module.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/run-pass/type-infer-generalize-ty-var.rs b/src/test/ui/type-infer-generalize-ty-var.rs similarity index 98% rename from src/test/run-pass/type-infer-generalize-ty-var.rs rename to src/test/ui/type-infer-generalize-ty-var.rs index 6298156452..a3d6916cbf 100644 --- a/src/test/run-pass/type-infer-generalize-ty-var.rs +++ b/src/test/ui/type-infer-generalize-ty-var.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_upper_case_globals)] #![allow(dead_code)] #![allow(unused_assignments)] diff --git a/src/test/run-pass/type-namespace.rs b/src/test/ui/type-namespace.rs similarity index 90% rename from src/test/run-pass/type-namespace.rs rename to src/test/ui/type-namespace.rs index 587a302ad5..3cc0bc447a 100644 --- a/src/test/run-pass/type-namespace.rs +++ b/src/test/ui/type-namespace.rs @@ -1,3 +1,5 @@ +// run-pass + struct A { a: isize } fn a(a: A) -> isize { return a.a; } diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/ui/type-param-constraints.rs similarity index 97% rename from src/test/run-pass/type-param-constraints.rs rename to src/test/ui/type-param-constraints.rs index 8194562899..4b42fddaf5 100644 --- a/src/test/run-pass/type-param-constraints.rs +++ b/src/test/ui/type-param-constraints.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/type-param.rs b/src/test/ui/type-param.rs similarity index 91% rename from src/test/run-pass/type-param.rs rename to src/test/ui/type-param.rs index bfce3f3287..f5ac19cf73 100644 --- a/src/test/run-pass/type-param.rs +++ b/src/test/ui/type-param.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/run-pass/type-params-in-for-each.rs b/src/test/ui/type-params-in-for-each.rs similarity index 96% rename from src/test/run-pass/type-params-in-for-each.rs rename to src/test/ui/type-params-in-for-each.rs index 509843c6b9..be4a0185ed 100644 --- a/src/test/run-pass/type-params-in-for-each.rs +++ b/src/test/ui/type-params-in-for-each.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/type-ptr.rs b/src/test/ui/type-ptr.rs similarity index 93% rename from src/test/run-pass/type-ptr.rs rename to src/test/ui/type-ptr.rs index 57c229a217..7c2438d38b 100644 --- a/src/test/run-pass/type-ptr.rs +++ b/src/test/ui/type-ptr.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/type-sizes.rs b/src/test/ui/type-sizes.rs similarity index 99% rename from src/test/run-pass/type-sizes.rs rename to src/test/ui/type-sizes.rs index db9705058d..27433fd770 100644 --- a/src/test/run-pass/type-sizes.rs +++ b/src/test/ui/type-sizes.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] #![feature(never_type)] diff --git a/src/test/run-pass/type-use-i1-versus-i8.rs b/src/test/ui/type-use-i1-versus-i8.rs similarity index 93% rename from src/test/run-pass/type-use-i1-versus-i8.rs rename to src/test/ui/type-use-i1-versus-i8.rs index dc029e4569..7315cd2fee 100644 --- a/src/test/run-pass/type-use-i1-versus-i8.rs +++ b/src/test/ui/type-use-i1-versus-i8.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 use std::ptr; diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs new file mode 100644 index 0000000000..c11a248d3c --- /dev/null +++ b/src/test/ui/type/ascription/issue-34255-1.rs @@ -0,0 +1,15 @@ +struct Reactor { + input_cells: Vec, +} + +impl Reactor { + pub fn new() -> Self { + input_cells: Vec::new() + //~^ ERROR cannot find value `input_cells` in this scope + //~| ERROR parenthesized type parameters may only be used with a `Fn` trait + //~| ERROR wrong number of type arguments: expected 1, found 0 + //~| WARNING this was previously accepted by the compiler but is being phased out + } +} + +// This case isn't currently being handled gracefully, including for completeness. diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr new file mode 100644 index 0000000000..531455b82b --- /dev/null +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -0,0 +1,30 @@ +error[E0425]: cannot find value `input_cells` in this scope + --> $DIR/issue-34255-1.rs:7:9 + | +LL | input_cells: Vec::new() + | ^^^^^^^^^^^ a field by this name exists in `Self` + +error: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-34255-1.rs:7:30 + | +LL | input_cells: Vec::new() + | ^^ + | + = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42238 + +error[E0601]: `main` function not found in crate `issue_34255_1` + | + = note: consider adding a `main` function to `$DIR/issue-34255-1.rs` + +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/issue-34255-1.rs:7:22 + | +LL | input_cells: Vec::new() + | ^^^^^^^^^^ expected 1 type argument + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0107, E0425, E0601. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs new file mode 100644 index 0000000000..ceb1dd89da --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.rs @@ -0,0 +1,5 @@ +fn main() { + let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found +} + +// This case isn't currently being handled gracefully due to the macro invocation. diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr new file mode 100644 index 0000000000..2f052341fa --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -0,0 +1,17 @@ +error: expected type, found reserved keyword `box` + --> $DIR/issue-47666.rs:2:25 + | +LL | let _ = Option:Some(vec![0, 1]); + | - ^^^^^^^^^^ + | | | + | | expected type + | | in this macro invocation + | | this macro call doesn't expand to a type + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 + = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs new file mode 100644 index 0000000000..6d65760e29 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.rs @@ -0,0 +1,6 @@ +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem:size_of::>()); + //~^ ERROR expected token: `,` +} diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr new file mode 100644 index 0000000000..a846f3bc32 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.stderr @@ -0,0 +1,13 @@ +error: expected token: `,` + --> $DIR/issue-54516.rs:4:58 + | +LL | println!("{}", std::mem:size_of::>()); + | - ^ expected `,` + | | + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 + +error: aborting due to previous error + diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs new file mode 100644 index 0000000000..8fb06c887b --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.rs @@ -0,0 +1,4 @@ +fn main() { + let u: usize = std::mem:size_of::(); + //~^ ERROR expected one of +} diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr new file mode 100644 index 0000000000..c2fc7bbcfc --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.stderr @@ -0,0 +1,13 @@ +error: expected one of `!`, `::`, or `;`, found `(` + --> $DIR/issue-60933.rs:2:43 + | +LL | let u: usize = std::mem:size_of::(); + | - ^ expected one of `!`, `::`, or `;` here + | | + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 + +error: aborting due to previous error + diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs index f3cc5becc6..06705a2ebf 100644 --- a/src/test/ui/type/type-alias-bounds.rs +++ b/src/test/ui/type/type-alias-bounds.rs @@ -1,6 +1,6 @@ // Test `ignored_generic_bounds` lint warning about bounds in type aliases. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::rc::Rc; diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr index 177e5f893e..dbb7b92563 100644 --- a/src/test/ui/type/type-alias-bounds.stderr +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -4,7 +4,7 @@ warning: bounds on generic parameters are not enforced in type aliases LL | type SVec = Vec; | ^^^^ ^^^^ | - = note: #[warn(type_alias_bounds)] on by default + = note: `#[warn(type_alias_bounds)]` on by default = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr index a22d25697d..3fe676de59 100644 --- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr +++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr @@ -2,7 +2,7 @@ error: expected type, found `10` --> $DIR/type-ascription-instead-of-initializer.rs:2:31 | LL | let x: Vec::with_capacity(10, 20); - | -- ^^ + | -- ^^ expected type | || | |help: use `=` if you meant to assign | while parsing the type for `x` diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr index 4929922c83..8fbcb3969a 100644 --- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -4,21 +4,21 @@ error: expected type, found `0` LL | println!("test"): | - help: try using a semicolon: `;` LL | 0; - | ^ expecting a type here because of type ascription + | ^ expected type + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: expected type, found `0` --> $DIR/type-ascription-instead-of-statement-end.rs:9:23 | LL | println!("test"): 0; - | ^ expecting a type here because of type ascription - | - = note: #![feature(type_ascription)] lets you annotate an expression with a type: `: ` -note: this expression expects an ascribed type after the colon - --> $DIR/type-ascription-instead-of-statement-end.rs:9:5 + | - ^ expected type + | | + | tried to parse a type due to this type ascription | -LL | println!("test"): 0; - | ^^^^^^^^^^^^^^^^ - = help: this might be indicative of a syntax error elsewhere + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to 2 previous errors diff --git a/src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs b/src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs similarity index 90% rename from src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs rename to src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs index fe15b912d6..2530a1e966 100644 --- a/src/test/run-pass/typeck-closure-to-unsafe-fn-ptr.rs +++ b/src/test/ui/typeck-closure-to-unsafe-fn-ptr.rs @@ -1,3 +1,5 @@ +// run-pass + unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { func() } diff --git a/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs similarity index 94% rename from src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs rename to src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs index 101f9756c8..1e954f5690 100644 --- a/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs +++ b/src/test/ui/typeck-fn-to-unsafe-fn-ptr.rs @@ -1,3 +1,4 @@ +// run-pass // This tests reification from safe function to `unsafe fn` pointer fn do_nothing() -> () {} diff --git a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs index 9eed80ad88..710b7c9bbe 100644 --- a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs +++ b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#55810: types for a binding in a match arm can be // inferred from arms that come later in the match. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 9ae104c946..2b4d9966c3 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -2,7 +2,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:4:14 | LL | fn test() -> _ { 5 } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:7:16 @@ -20,13 +23,19 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:11:15 | LL | static TEST3: _ = "test"; - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:14:15 | LL | static TEST4: _ = 145; - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:17:16 @@ -98,7 +107,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:57:21 | LL | fn fn_test() -> _ { 5 } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:60:23 @@ -116,13 +128,19 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:64:22 | LL | static FN_TEST3: _ = "test"; - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:67:22 | LL | static FN_TEST4: _ = 145; - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:70:23 @@ -158,7 +176,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:33:24 | LL | fn test9(&self) -> _ { () } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:36:27 @@ -170,7 +191,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:41:24 | LL | fn clone(&self) -> _ { Test9 } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:44:37 @@ -182,7 +206,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:86:31 | LL | fn fn_test9(&self) -> _ { () } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:89:34 @@ -194,7 +221,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item.rs:94:28 | LL | fn clone(&self) -> _ { FnTest9 } - | ^ not allowed in type signatures + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `main::FnTest9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:97:41 diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs new file mode 100644 index 0000000000..905fc35350 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs @@ -0,0 +1,29 @@ +// This test checks that it proper item type will be suggested when +// using the `_` type placeholder. + +fn test1() -> _ { Some(42) } +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +const TEST2: _ = 42u32; +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +const TEST3: _ = Some(42); +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +trait Test4 { + const TEST4: _ = 42; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +} + +struct Test5; + +impl Test5 { + const TEST5: _ = 13; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +} + +pub fn main() { + let _: Option = test1(); + let _: f64 = test1(); + let _: Option = test1(); +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr new file mode 100644 index 0000000000..c5b9566290 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -0,0 +1,48 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item_help.rs:4:15 + | +LL | fn test1() -> _ { Some(42) } + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct return type: `std::option::Option` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item_help.rs:7:14 + | +LL | const TEST2: _ = 42u32; + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `u32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item_help.rs:10:14 + | +LL | const TEST3: _ = Some(42); + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `std::option::Option` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item_help.rs:14:18 + | +LL | const TEST4: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `i32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item_help.rs:21:18 + | +LL | const TEST5: _ = 13; + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `i32` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/ui/typeck_type_placeholder_1.rs similarity index 97% rename from src/test/run-pass/typeck_type_placeholder_1.rs rename to src/test/ui/typeck_type_placeholder_1.rs index 6a3657e4ae..ea7aa5285b 100644 --- a/src/test/run-pass/typeck_type_placeholder_1.rs +++ b/src/test/ui/typeck_type_placeholder_1.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // This test checks that the `_` type placeholder works // correctly for enabling type inference. diff --git a/src/test/run-pass/typeclasses-eq-example-static.rs b/src/test/ui/typeclasses-eq-example-static.rs similarity index 99% rename from src/test/run-pass/typeclasses-eq-example-static.rs rename to src/test/ui/typeclasses-eq-example-static.rs index 60c886ba38..282d51a93d 100644 --- a/src/test/run-pass/typeclasses-eq-example-static.rs +++ b/src/test/ui/typeclasses-eq-example-static.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] diff --git a/src/test/run-pass/typeclasses-eq-example.rs b/src/test/ui/typeclasses-eq-example.rs similarity index 99% rename from src/test/run-pass/typeclasses-eq-example.rs rename to src/test/ui/typeclasses-eq-example.rs index 06bec5385e..8d1d22eb82 100644 --- a/src/test/run-pass/typeclasses-eq-example.rs +++ b/src/test/ui/typeclasses-eq-example.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] diff --git a/src/test/run-pass/typeid-intrinsic.rs b/src/test/ui/typeid-intrinsic.rs similarity index 83% rename from src/test/run-pass/typeid-intrinsic.rs rename to src/test/ui/typeid-intrinsic.rs index 0c7abc086f..5bc4e0c217 100644 --- a/src/test/run-pass/typeid-intrinsic.rs +++ b/src/test/ui/typeid-intrinsic.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(deprecated)] // aux-build:typeid-intrinsic-aux1.rs // aux-build:typeid-intrinsic-aux2.rs @@ -76,10 +78,20 @@ pub fn main() { assert_eq!(TypeId::of::(), other1::id_u32_iterator()); assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); - assert!(other1::id_i32_iterator() != other1::id_u32_iterator()); - assert!(TypeId::of::() != TypeId::of::()); + assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); + assert_ne!(TypeId::of::(), TypeId::of::()); // Check fn pointer against collisions - assert!(TypeId::of:: A) -> A>() != - TypeId::of:: A, A) -> A>()); + assert_ne!( + TypeId::of:: A) -> A>(), + TypeId::of:: A, A) -> A>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32) -> &'a i32>(), + TypeId::of:: fn(&'a i32) -> &'static i32>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32, &'b i32) -> &'a i32>(), + TypeId::of:: fn(&'b i32, &'a i32) -> &'a i32>() + ); } diff --git a/src/test/run-pass/typestate-cfg-nesting.rs b/src/test/ui/typestate-cfg-nesting.rs similarity index 96% rename from src/test/run-pass/typestate-cfg-nesting.rs rename to src/test/ui/typestate-cfg-nesting.rs index 994c7d5169..5718e0efd1 100644 --- a/src/test/run-pass/typestate-cfg-nesting.rs +++ b/src/test/ui/typestate-cfg-nesting.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unknown_lints)] diff --git a/src/test/run-pass/typestate-multi-decl.rs b/src/test/ui/typestate-multi-decl.rs similarity index 87% rename from src/test/run-pass/typestate-multi-decl.rs rename to src/test/ui/typestate-multi-decl.rs index bc8d9c10de..9f94162055 100644 --- a/src/test/run-pass/typestate-multi-decl.rs +++ b/src/test/ui/typestate-multi-decl.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let (x, y) = (10, 20); let z = x + y; diff --git a/src/test/run-pass/ufcs-polymorphic-paths.rs b/src/test/ui/ufcs-polymorphic-paths.rs similarity index 99% rename from src/test/run-pass/ufcs-polymorphic-paths.rs rename to src/test/ui/ufcs-polymorphic-paths.rs index e136bb23bc..a14ebd6a41 100644 --- a/src/test/run-pass/ufcs-polymorphic-paths.rs +++ b/src/test/ui/ufcs-polymorphic-paths.rs @@ -1,3 +1,5 @@ +// run-pass + use std::borrow::{Cow, ToOwned}; use std::default::Default; use std::iter::FromIterator; diff --git a/src/test/run-pass/ufcs-type-params.rs b/src/test/ui/ufcs-type-params.rs similarity index 94% rename from src/test/run-pass/ufcs-type-params.rs rename to src/test/ui/ufcs-type-params.rs index 2bb15b9176..eee2b55b2a 100644 --- a/src/test/run-pass/ufcs-type-params.rs +++ b/src/test/ui/ufcs-type-params.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr index 1251d6eee8..6da20e3757 100644 --- a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -5,7 +5,7 @@ LL | fn foo(self: isize, x: isize) -> isize { | ^^^^^ | = note: type must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0307]: invalid method receiver type: Bar --> $DIR/ufcs-explicit-self-bad.rs:19:18 @@ -14,7 +14,7 @@ LL | fn foo(self: Bar, x: isize) -> isize { | ^^^^^^^^^^ | = note: type must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0307]: invalid method receiver type: &Bar --> $DIR/ufcs-explicit-self-bad.rs:23:18 @@ -23,7 +23,7 @@ LL | fn bar(self: &Bar, x: isize) -> isize { | ^^^^^^^^^^^ | = note: type must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0308]: mismatched method receiver --> $DIR/ufcs-explicit-self-bad.rs:37:21 diff --git a/src/test/run-pass/unary-minus-suffix-inference.rs b/src/test/ui/unary-minus-suffix-inference.rs similarity index 96% rename from src/test/run-pass/unary-minus-suffix-inference.rs rename to src/test/ui/unary-minus-suffix-inference.rs index e5579c20a1..a4d0a84948 100644 --- a/src/test/run-pass/unary-minus-suffix-inference.rs +++ b/src/test/ui/unary-minus-suffix-inference.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let a = 1; let a_neg: i8 = -a; diff --git a/src/test/run-pass/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs b/src/test/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs rename to src/test/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs diff --git a/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr b/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr index c23acbcb31..a76954287e 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr @@ -5,7 +5,7 @@ LL | let x: Box; | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr index e1ed85d4f4..c116728190 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr @@ -5,7 +5,7 @@ LL | fn bar1(x: &dyn Fn<(), Output=()>) { | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead --> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:7:28 @@ -14,7 +14,7 @@ LL | fn bar2(x: &T) where T: Fn<()> { | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-all-traits.rs b/src/test/ui/unboxed-closures/unboxed-closures-all-traits.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-all-traits.rs rename to src/test/ui/unboxed-closures/unboxed-closures-all-traits.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn-mut.rs b/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn-mut.rs rename to src/test/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-blanket-fn.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-blanket-fn.rs rename to src/test/ui/unboxed-closures/unboxed-closures-blanket-fn.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-boxed.rs b/src/test/ui/unboxed-closures/unboxed-closures-boxed.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-boxed.rs rename to src/test/ui/unboxed-closures/unboxed-closures-boxed.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-by-ref.rs b/src/test/ui/unboxed-closures/unboxed-closures-by-ref.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-by-ref.rs rename to src/test/ui/unboxed-closures/unboxed-closures-by-ref.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-call-fn-autoderef.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-call-fn-autoderef.rs rename to src/test/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs rename to src/test/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs rename to src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object.rs b/src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-call-sugar-object.rs rename to src/test/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-counter-not-moved.rs b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-counter-not-moved.rs rename to src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-cross-crate.rs b/src/test/ui/unboxed-closures/unboxed-closures-cross-crate.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-cross-crate.rs rename to src/test/ui/unboxed-closures/unboxed-closures-cross-crate.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-direct-sugary-call.rs b/src/test/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-direct-sugary-call.rs rename to src/test/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-drop.rs b/src/test/ui/unboxed-closures/unboxed-closures-drop.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-drop.rs rename to src/test/ui/unboxed-closures/unboxed-closures-drop.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn-hr.rs b/src/test/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn-hr.rs rename to src/test/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-extern-fn.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-extern-fn.rs rename to src/test/ui/unboxed-closures/unboxed-closures-extern-fn.rs diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr new file mode 100644 index 0000000000..4b906f7514 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.polonius.stderr @@ -0,0 +1,60 @@ +error[E0597]: `factorial` does not live long enough + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:15:17 + | +LL | let f = |x: u32| -> u32 { + | --------------- value captured here +LL | let g = factorial.as_ref().unwrap(); + | ^^^^^^^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `factorial` dropped here while still borrowed + | borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option u32>>` + +error[E0506]: cannot assign to `factorial` because it is borrowed + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:20:5 + | +LL | let f = |x: u32| -> u32 { + | --------------- borrow of `factorial` occurs here +LL | let g = factorial.as_ref().unwrap(); + | --------- borrow occurs due to use in closure +... +LL | factorial = Some(Box::new(f)); + | ^^^^^^^^^ + | | + | assignment to borrowed `factorial` occurs here + | borrow later used here + +error[E0597]: `factorial` does not live long enough + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:28:17 + | +LL | let f = |x: u32| -> u32 { + | --------------- value captured here +LL | let g = factorial.as_ref().unwrap(); + | ^^^^^^^^^ borrowed value does not live long enough +... +LL | } + | - + | | + | `factorial` dropped here while still borrowed + | borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option u32>>` + +error[E0506]: cannot assign to `factorial` because it is borrowed + --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:33:5 + | +LL | let f = |x: u32| -> u32 { + | --------------- borrow of `factorial` occurs here +LL | let g = factorial.as_ref().unwrap(); + | --------- borrow occurs due to use in closure +... +LL | factorial = Some(Box::new(f)); + | ^^^^^^^^^ + | | + | assignment to borrowed `factorial` occurs here + | borrow later used here + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0506, E0597. +For more information about an error, try `rustc --explain E0506`. diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs b/src/test/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs rename to src/test/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs rename to src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-generic.rs b/src/test/ui/unboxed-closures/unboxed-closures-generic.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-generic.rs rename to src/test/ui/unboxed-closures/unboxed-closures-generic.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-move.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut-move.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnmut.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce-move.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce-move.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-fnonce.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-kind.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-kind.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-kind.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-kind.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-recursive-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-recursive-fn.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-infer-upvar.rs b/src/test/ui/unboxed-closures/unboxed-closures-infer-upvar.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-infer-upvar.rs rename to src/test/ui/unboxed-closures/unboxed-closures-infer-upvar.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-manual-impl.rs b/src/test/ui/unboxed-closures/unboxed-closures-manual-impl.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-manual-impl.rs rename to src/test/ui/unboxed-closures/unboxed-closures-manual-impl.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-monomorphization.rs b/src/test/ui/unboxed-closures/unboxed-closures-monomorphization.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-monomorphization.rs rename to src/test/ui/unboxed-closures/unboxed-closures-monomorphization.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs rename to src/test/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-move-mutable.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-move-mutable.rs rename to src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs rename to src/test/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-prelude.rs b/src/test/ui/unboxed-closures/unboxed-closures-prelude.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-prelude.rs rename to src/test/ui/unboxed-closures/unboxed-closures-prelude.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-simple.rs b/src/test/ui/unboxed-closures/unboxed-closures-simple.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-simple.rs rename to src/test/ui/unboxed-closures/unboxed-closures-simple.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-single-word-env.rs b/src/test/ui/unboxed-closures/unboxed-closures-single-word-env.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-single-word-env.rs rename to src/test/ui/unboxed-closures/unboxed-closures-single-word-env.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-static-call-fn-once.rs b/src/test/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-static-call-fn-once.rs rename to src/test/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-sugar-object.rs b/src/test/ui/unboxed-closures/unboxed-closures-sugar-object.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-sugar-object.rs rename to src/test/ui/unboxed-closures/unboxed-closures-sugar-object.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-unique-type-id.rs b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-unique-type-id.rs rename to src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs diff --git a/src/test/run-pass/unboxed-closures/unboxed-closures-zero-args.rs b/src/test/ui/unboxed-closures/unboxed-closures-zero-args.rs similarity index 100% rename from src/test/run-pass/unboxed-closures/unboxed-closures-zero-args.rs rename to src/test/ui/unboxed-closures/unboxed-closures-zero-args.rs diff --git a/src/test/run-pass/underscore-lifetimes.rs b/src/test/ui/underscore-lifetimes.rs similarity index 97% rename from src/test/run-pass/underscore-lifetimes.rs rename to src/test/ui/underscore-lifetimes.rs index 3d0660554e..a1593880d8 100644 --- a/src/test/run-pass/underscore-lifetimes.rs +++ b/src/test/ui/underscore-lifetimes.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] struct Foo<'a>(&'a u8); diff --git a/src/test/run-pass/underscore-method-after-integer.rs b/src/test/ui/underscore-method-after-integer.rs similarity index 90% rename from src/test/run-pass/underscore-method-after-integer.rs rename to src/test/ui/underscore-method-after-integer.rs index f9c06d1e4f..7fb8607f97 100644 --- a/src/test/run-pass/underscore-method-after-integer.rs +++ b/src/test/ui/underscore-method-after-integer.rs @@ -1,3 +1,5 @@ +// run-pass + trait Tr : Sized { fn _method_on_numbers(self) {} } diff --git a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs b/src/test/ui/uniform-paths/auxiliary/issue-53691.rs similarity index 100% rename from src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs rename to src/test/ui/uniform-paths/auxiliary/issue-53691.rs diff --git a/src/test/run-pass/uniform-paths/basic-nested.rs b/src/test/ui/uniform-paths/basic-nested.rs similarity index 100% rename from src/test/run-pass/uniform-paths/basic-nested.rs rename to src/test/ui/uniform-paths/basic-nested.rs diff --git a/src/test/run-pass/uniform-paths/basic.rs b/src/test/ui/uniform-paths/basic.rs similarity index 100% rename from src/test/run-pass/uniform-paths/basic.rs rename to src/test/ui/uniform-paths/basic.rs diff --git a/src/test/run-pass/uniform-paths/issue-53691.rs b/src/test/ui/uniform-paths/issue-53691.rs similarity index 90% rename from src/test/run-pass/uniform-paths/issue-53691.rs rename to src/test/ui/uniform-paths/issue-53691.rs index 73e5fbf423..5c5ca5b70b 100644 --- a/src/test/run-pass/uniform-paths/issue-53691.rs +++ b/src/test/ui/uniform-paths/issue-53691.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:issue-53691.rs extern crate issue_53691; diff --git a/src/test/run-pass/uniform-paths/macros-nested.rs b/src/test/ui/uniform-paths/macros-nested.rs similarity index 100% rename from src/test/run-pass/uniform-paths/macros-nested.rs rename to src/test/ui/uniform-paths/macros-nested.rs diff --git a/src/test/run-pass/uniform-paths/macros.rs b/src/test/ui/uniform-paths/macros.rs similarity index 100% rename from src/test/run-pass/uniform-paths/macros.rs rename to src/test/ui/uniform-paths/macros.rs diff --git a/src/test/run-pass/uniform-paths/same-crate.rs b/src/test/ui/uniform-paths/same-crate.rs similarity index 100% rename from src/test/run-pass/uniform-paths/same-crate.rs rename to src/test/ui/uniform-paths/same-crate.rs diff --git a/src/test/run-pass/unify-return-ty.rs b/src/test/ui/unify-return-ty.rs similarity index 96% rename from src/test/run-pass/unify-return-ty.rs rename to src/test/ui/unify-return-ty.rs index 3f743a7da4..da1d82e896 100644 --- a/src/test/run-pass/unify-return-ty.rs +++ b/src/test/ui/unify-return-ty.rs @@ -1,3 +1,4 @@ +// run-pass // Tests that the tail expr in null() has its type // unified with the type *T, and so the type variable // in that type gets resolved. diff --git a/src/test/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs b/src/test/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs new file mode 100644 index 0000000000..b594320783 --- /dev/null +++ b/src/test/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(exhaustive_patterns)] + +enum Void {} +fn main() { + let a: Option = None; + let None = a; +} diff --git a/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs b/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs index 9fe8a5c832..f476704cd8 100644 --- a/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs +++ b/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_variables)] diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs index 38a52d5860..a5360fa13c 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + enum Void {} fn main() { diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index de7a963577..25519ab2d6 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:5:19 + --> $DIR/uninhabited-matches-feature-gated.rs:7:19 | LL | let _ = match x { | ^ pattern `Err(_)` not covered @@ -7,7 +7,7 @@ LL | let _ = match x { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `&Void` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:10:19 + --> $DIR/uninhabited-matches-feature-gated.rs:12:19 | LL | let _ = match x {}; | ^ @@ -15,7 +15,7 @@ LL | let _ = match x {}; = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:13:19 + --> $DIR/uninhabited-matches-feature-gated.rs:15:19 | LL | let _ = match x {}; | ^ @@ -23,7 +23,7 @@ LL | let _ = match x {}; = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty - --> $DIR/uninhabited-matches-feature-gated.rs:16:19 + --> $DIR/uninhabited-matches-feature-gated.rs:18:19 | LL | let _ = match x {}; | ^ @@ -31,7 +31,7 @@ LL | let _ = match x {}; = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_]` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:19:19 + --> $DIR/uninhabited-matches-feature-gated.rs:21:19 | LL | let _ = match x { | ^ pattern `&[_]` not covered @@ -39,7 +39,7 @@ LL | let _ = match x { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:27:19 + --> $DIR/uninhabited-matches-feature-gated.rs:29:19 | LL | let _ = match x { | ^ pattern `Err(_)` not covered @@ -47,7 +47,7 @@ LL | let _ = match x { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/uninhabited-matches-feature-gated.rs:32:9 + --> $DIR/uninhabited-matches-feature-gated.rs:34:9 | LL | let Ok(x) = x; | ^^^^^ pattern `Err(_)` not covered diff --git a/src/test/run-pass/uninit-empty-types.rs b/src/test/ui/uninit-empty-types.rs similarity index 89% rename from src/test/run-pass/uninit-empty-types.rs rename to src/test/ui/uninit-empty-types.rs index b59971b349..0d1235776a 100644 --- a/src/test/run-pass/uninit-empty-types.rs +++ b/src/test/ui/uninit-empty-types.rs @@ -1,3 +1,4 @@ +// run-pass // Test the uninit() construct returning various empty types. // pretty-expanded FIXME #23616 @@ -7,6 +8,7 @@ use std::mem; #[derive(Clone)] struct Foo; +#[allow(deprecated)] pub fn main() { unsafe { let _x: Foo = mem::uninitialized(); diff --git a/src/test/run-pass/union/auxiliary/union.rs b/src/test/ui/union/auxiliary/union.rs similarity index 100% rename from src/test/run-pass/union/auxiliary/union.rs rename to src/test/ui/union/auxiliary/union.rs diff --git a/src/test/run-pass/union/union-align.rs b/src/test/ui/union/union-align.rs similarity index 100% rename from src/test/run-pass/union/union-align.rs rename to src/test/ui/union/union-align.rs diff --git a/src/test/run-pass/union/union-backcomp.rs b/src/test/ui/union/union-backcomp.rs similarity index 100% rename from src/test/run-pass/union/union-backcomp.rs rename to src/test/ui/union/union-backcomp.rs diff --git a/src/test/run-pass/union/union-basic.rs b/src/test/ui/union/union-basic.rs similarity index 100% rename from src/test/run-pass/union/union-basic.rs rename to src/test/ui/union/union-basic.rs diff --git a/src/test/run-pass/union/union-c-interop.rs b/src/test/ui/union/union-c-interop.rs similarity index 100% rename from src/test/run-pass/union/union-c-interop.rs rename to src/test/ui/union/union-c-interop.rs diff --git a/src/test/run-pass/union/union-const-codegen.rs b/src/test/ui/union/union-const-codegen.rs similarity index 100% rename from src/test/run-pass/union/union-const-codegen.rs rename to src/test/ui/union/union-const-codegen.rs diff --git a/src/test/run-pass/union/union-const-eval-field.rs b/src/test/ui/union/union-const-eval-field.rs similarity index 100% rename from src/test/run-pass/union/union-const-eval-field.rs rename to src/test/ui/union/union-const-eval-field.rs diff --git a/src/test/ui/union/union-const-eval.rs b/src/test/ui/union/union-const-eval.rs index 05e849a3bb..90af8de447 100644 --- a/src/test/ui/union/union-const-eval.rs +++ b/src/test/ui/union/union-const-eval.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_fn_union)] union U { diff --git a/src/test/run-pass/union/union-derive.rs b/src/test/ui/union/union-derive-rpass.rs similarity index 100% rename from src/test/run-pass/union/union-derive.rs rename to src/test/ui/union/union-derive-rpass.rs diff --git a/src/test/run-pass/union/union-drop-assign.rs b/src/test/ui/union/union-drop-assign.rs similarity index 100% rename from src/test/run-pass/union/union-drop-assign.rs rename to src/test/ui/union/union-drop-assign.rs diff --git a/src/test/run-pass/union/union-drop.rs b/src/test/ui/union/union-drop.rs similarity index 100% rename from src/test/run-pass/union/union-drop.rs rename to src/test/ui/union/union-drop.rs diff --git a/src/test/run-pass/union/union-generic.rs b/src/test/ui/union/union-generic-rpass.rs similarity index 100% rename from src/test/run-pass/union/union-generic.rs rename to src/test/ui/union/union-generic-rpass.rs diff --git a/src/test/run-pass/union/union-inherent-method.rs b/src/test/ui/union/union-inherent-method.rs similarity index 100% rename from src/test/run-pass/union/union-inherent-method.rs rename to src/test/ui/union/union-inherent-method.rs diff --git a/src/test/run-pass/union/union-macro.rs b/src/test/ui/union/union-macro.rs similarity index 100% rename from src/test/run-pass/union/union-macro.rs rename to src/test/ui/union/union-macro.rs diff --git a/src/test/run-pass/union/union-nodrop.rs b/src/test/ui/union/union-nodrop.rs similarity index 100% rename from src/test/run-pass/union/union-nodrop.rs rename to src/test/ui/union/union-nodrop.rs diff --git a/src/test/run-pass/union/union-nonzero.rs b/src/test/ui/union/union-nonzero.rs similarity index 100% rename from src/test/run-pass/union/union-nonzero.rs rename to src/test/ui/union/union-nonzero.rs diff --git a/src/test/run-pass/union/union-overwrite.rs b/src/test/ui/union/union-overwrite.rs similarity index 100% rename from src/test/run-pass/union/union-overwrite.rs rename to src/test/ui/union/union-overwrite.rs diff --git a/src/test/run-pass/union/union-packed.rs b/src/test/ui/union/union-packed.rs similarity index 100% rename from src/test/run-pass/union/union-packed.rs rename to src/test/ui/union/union-packed.rs diff --git a/src/test/run-pass/union/union-pat-refutability.rs b/src/test/ui/union/union-pat-refutability.rs similarity index 100% rename from src/test/run-pass/union/union-pat-refutability.rs rename to src/test/ui/union/union-pat-refutability.rs diff --git a/src/test/run-pass/union/union-trait-impl.rs b/src/test/ui/union/union-trait-impl.rs similarity index 100% rename from src/test/run-pass/union/union-trait-impl.rs rename to src/test/ui/union/union-trait-impl.rs diff --git a/src/test/run-pass/union/union-transmute.rs b/src/test/ui/union/union-transmute.rs similarity index 100% rename from src/test/run-pass/union/union-transmute.rs rename to src/test/ui/union/union-transmute.rs diff --git a/src/test/run-pass/union/union-with-drop-fields-lint.rs b/src/test/ui/union/union-with-drop-fields-lint-rpass.rs similarity index 100% rename from src/test/run-pass/union/union-with-drop-fields-lint.rs rename to src/test/ui/union/union-with-drop-fields-lint-rpass.rs diff --git a/src/test/run-pass/unique/unique-assign-copy.rs b/src/test/ui/unique/unique-assign-copy.rs similarity index 100% rename from src/test/run-pass/unique/unique-assign-copy.rs rename to src/test/ui/unique/unique-assign-copy.rs diff --git a/src/test/run-pass/unique/unique-assign-drop.rs b/src/test/ui/unique/unique-assign-drop.rs similarity index 100% rename from src/test/run-pass/unique/unique-assign-drop.rs rename to src/test/ui/unique/unique-assign-drop.rs diff --git a/src/test/run-pass/unique/unique-assign-generic.rs b/src/test/ui/unique/unique-assign-generic.rs similarity index 100% rename from src/test/run-pass/unique/unique-assign-generic.rs rename to src/test/ui/unique/unique-assign-generic.rs diff --git a/src/test/run-pass/unique/unique-assign.rs b/src/test/ui/unique/unique-assign.rs similarity index 100% rename from src/test/run-pass/unique/unique-assign.rs rename to src/test/ui/unique/unique-assign.rs diff --git a/src/test/run-pass/unique/unique-autoderef-field.rs b/src/test/ui/unique/unique-autoderef-field.rs similarity index 100% rename from src/test/run-pass/unique/unique-autoderef-field.rs rename to src/test/ui/unique/unique-autoderef-field.rs diff --git a/src/test/run-pass/unique/unique-autoderef-index.rs b/src/test/ui/unique/unique-autoderef-index.rs similarity index 100% rename from src/test/run-pass/unique/unique-autoderef-index.rs rename to src/test/ui/unique/unique-autoderef-index.rs diff --git a/src/test/run-pass/unique/unique-cmp.rs b/src/test/ui/unique/unique-cmp.rs similarity index 100% rename from src/test/run-pass/unique/unique-cmp.rs rename to src/test/ui/unique/unique-cmp.rs diff --git a/src/test/run-pass/unique/unique-containing-tag.rs b/src/test/ui/unique/unique-containing-tag.rs similarity index 100% rename from src/test/run-pass/unique/unique-containing-tag.rs rename to src/test/ui/unique/unique-containing-tag.rs diff --git a/src/test/run-pass/unique/unique-create.rs b/src/test/ui/unique/unique-create.rs similarity index 100% rename from src/test/run-pass/unique/unique-create.rs rename to src/test/ui/unique/unique-create.rs diff --git a/src/test/run-pass/unique/unique-decl-init-copy.rs b/src/test/ui/unique/unique-decl-init-copy.rs similarity index 100% rename from src/test/run-pass/unique/unique-decl-init-copy.rs rename to src/test/ui/unique/unique-decl-init-copy.rs diff --git a/src/test/run-pass/unique/unique-decl-init.rs b/src/test/ui/unique/unique-decl-init.rs similarity index 100% rename from src/test/run-pass/unique/unique-decl-init.rs rename to src/test/ui/unique/unique-decl-init.rs diff --git a/src/test/run-pass/unique/unique-decl-move.rs b/src/test/ui/unique/unique-decl-move.rs similarity index 100% rename from src/test/run-pass/unique/unique-decl-move.rs rename to src/test/ui/unique/unique-decl-move.rs diff --git a/src/test/run-pass/unique/unique-decl.rs b/src/test/ui/unique/unique-decl.rs similarity index 100% rename from src/test/run-pass/unique/unique-decl.rs rename to src/test/ui/unique/unique-decl.rs diff --git a/src/test/run-pass/unique/unique-deref.rs b/src/test/ui/unique/unique-deref.rs similarity index 100% rename from src/test/run-pass/unique/unique-deref.rs rename to src/test/ui/unique/unique-deref.rs diff --git a/src/test/run-pass/unique/unique-destructure.rs b/src/test/ui/unique/unique-destructure.rs similarity index 100% rename from src/test/run-pass/unique/unique-destructure.rs rename to src/test/ui/unique/unique-destructure.rs diff --git a/src/test/run-pass/unique/unique-drop-complex.rs b/src/test/ui/unique/unique-drop-complex.rs similarity index 100% rename from src/test/run-pass/unique/unique-drop-complex.rs rename to src/test/ui/unique/unique-drop-complex.rs diff --git a/src/test/run-pass/unique/unique-ffi-symbols.rs b/src/test/ui/unique/unique-ffi-symbols.rs similarity index 100% rename from src/test/run-pass/unique/unique-ffi-symbols.rs rename to src/test/ui/unique/unique-ffi-symbols.rs diff --git a/src/test/run-pass/unique/unique-fn-arg-move.rs b/src/test/ui/unique/unique-fn-arg-move.rs similarity index 100% rename from src/test/run-pass/unique/unique-fn-arg-move.rs rename to src/test/ui/unique/unique-fn-arg-move.rs diff --git a/src/test/run-pass/unique/unique-fn-arg-mut.rs b/src/test/ui/unique/unique-fn-arg-mut.rs similarity index 100% rename from src/test/run-pass/unique/unique-fn-arg-mut.rs rename to src/test/ui/unique/unique-fn-arg-mut.rs diff --git a/src/test/run-pass/unique/unique-fn-arg.rs b/src/test/ui/unique/unique-fn-arg.rs similarity index 100% rename from src/test/run-pass/unique/unique-fn-arg.rs rename to src/test/ui/unique/unique-fn-arg.rs diff --git a/src/test/run-pass/unique/unique-fn-ret.rs b/src/test/ui/unique/unique-fn-ret.rs similarity index 100% rename from src/test/run-pass/unique/unique-fn-ret.rs rename to src/test/ui/unique/unique-fn-ret.rs diff --git a/src/test/run-pass/unique/unique-generic-assign.rs b/src/test/ui/unique/unique-generic-assign.rs similarity index 100% rename from src/test/run-pass/unique/unique-generic-assign.rs rename to src/test/ui/unique/unique-generic-assign.rs diff --git a/src/test/run-pass/unique/unique-in-tag.rs b/src/test/ui/unique/unique-in-tag.rs similarity index 100% rename from src/test/run-pass/unique/unique-in-tag.rs rename to src/test/ui/unique/unique-in-tag.rs diff --git a/src/test/run-pass/unique/unique-in-vec-copy.rs b/src/test/ui/unique/unique-in-vec-copy.rs similarity index 100% rename from src/test/run-pass/unique/unique-in-vec-copy.rs rename to src/test/ui/unique/unique-in-vec-copy.rs diff --git a/src/test/run-pass/unique/unique-in-vec.rs b/src/test/ui/unique/unique-in-vec.rs similarity index 100% rename from src/test/run-pass/unique/unique-in-vec.rs rename to src/test/ui/unique/unique-in-vec.rs diff --git a/src/test/run-pass/unique/unique-init.rs b/src/test/ui/unique/unique-init.rs similarity index 100% rename from src/test/run-pass/unique/unique-init.rs rename to src/test/ui/unique/unique-init.rs diff --git a/src/test/run-pass/unique/unique-kinds.rs b/src/test/ui/unique/unique-kinds.rs similarity index 100% rename from src/test/run-pass/unique/unique-kinds.rs rename to src/test/ui/unique/unique-kinds.rs diff --git a/src/test/run-pass/unique/unique-log.rs b/src/test/ui/unique/unique-log.rs similarity index 100% rename from src/test/run-pass/unique/unique-log.rs rename to src/test/ui/unique/unique-log.rs diff --git a/src/test/run-pass/unique/unique-match-discrim.rs b/src/test/ui/unique/unique-match-discrim.rs similarity index 100% rename from src/test/run-pass/unique/unique-match-discrim.rs rename to src/test/ui/unique/unique-match-discrim.rs diff --git a/src/test/run-pass/unique/unique-move-drop.rs b/src/test/ui/unique/unique-move-drop.rs similarity index 100% rename from src/test/run-pass/unique/unique-move-drop.rs rename to src/test/ui/unique/unique-move-drop.rs diff --git a/src/test/run-pass/unique/unique-move-temp.rs b/src/test/ui/unique/unique-move-temp.rs similarity index 100% rename from src/test/run-pass/unique/unique-move-temp.rs rename to src/test/ui/unique/unique-move-temp.rs diff --git a/src/test/run-pass/unique/unique-move.rs b/src/test/ui/unique/unique-move.rs similarity index 100% rename from src/test/run-pass/unique/unique-move.rs rename to src/test/ui/unique/unique-move.rs diff --git a/src/test/run-pass/unique/unique-mutable.rs b/src/test/ui/unique/unique-mutable.rs similarity index 100% rename from src/test/run-pass/unique/unique-mutable.rs rename to src/test/ui/unique/unique-mutable.rs diff --git a/src/test/run-pass/unique/unique-object-move.rs b/src/test/ui/unique/unique-object-move.rs similarity index 100% rename from src/test/run-pass/unique/unique-object-move.rs rename to src/test/ui/unique/unique-object-move.rs diff --git a/src/test/run-pass/unique/unique-pat-2.rs b/src/test/ui/unique/unique-pat-2.rs similarity index 100% rename from src/test/run-pass/unique/unique-pat-2.rs rename to src/test/ui/unique/unique-pat-2.rs diff --git a/src/test/run-pass/unique/unique-pat-3.rs b/src/test/ui/unique/unique-pat-3.rs similarity index 100% rename from src/test/run-pass/unique/unique-pat-3.rs rename to src/test/ui/unique/unique-pat-3.rs diff --git a/src/test/run-pass/unique/unique-pat.rs b/src/test/ui/unique/unique-pat.rs similarity index 100% rename from src/test/run-pass/unique/unique-pat.rs rename to src/test/ui/unique/unique-pat.rs diff --git a/src/test/run-pass/unique/unique-rec.rs b/src/test/ui/unique/unique-rec.rs similarity index 100% rename from src/test/run-pass/unique/unique-rec.rs rename to src/test/ui/unique/unique-rec.rs diff --git a/src/test/run-pass/unique/unique-send-2.rs b/src/test/ui/unique/unique-send-2.rs similarity index 100% rename from src/test/run-pass/unique/unique-send-2.rs rename to src/test/ui/unique/unique-send-2.rs diff --git a/src/test/run-pass/unique/unique-send.rs b/src/test/ui/unique/unique-send.rs similarity index 100% rename from src/test/run-pass/unique/unique-send.rs rename to src/test/ui/unique/unique-send.rs diff --git a/src/test/run-pass/unique/unique-swap.rs b/src/test/ui/unique/unique-swap.rs similarity index 100% rename from src/test/run-pass/unique/unique-swap.rs rename to src/test/ui/unique/unique-swap.rs diff --git a/src/test/run-pass/unit.rs b/src/test/ui/unit.rs similarity index 95% rename from src/test/run-pass/unit.rs rename to src/test/ui/unit.rs index e10b2408cb..4f2dd4194a 100644 --- a/src/test/run-pass/unit.rs +++ b/src/test/ui/unit.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_assignments)] #![allow(unknown_lints)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/unnamed_argument_mode.rs b/src/test/ui/unnamed_argument_mode.rs similarity index 94% rename from src/test/run-pass/unnamed_argument_mode.rs rename to src/test/ui/unnamed_argument_mode.rs index fa817be270..5b7b4002f4 100644 --- a/src/test/run-pass/unnamed_argument_mode.rs +++ b/src/test/ui/unnamed_argument_mode.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 fn good(_a: &isize) { diff --git a/src/test/run-pass/unreachable-code-1.rs b/src/test/ui/unreachable-code-1.rs similarity index 95% rename from src/test/run-pass/unreachable-code-1.rs rename to src/test/ui/unreachable-code-1.rs index ac41377e05..ee44f39994 100644 --- a/src/test/run-pass/unreachable-code-1.rs +++ b/src/test/ui/unreachable-code-1.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(unreachable_code)] diff --git a/src/test/run-pass/unreachable-code.rs b/src/test/ui/unreachable-code.rs similarity index 96% rename from src/test/run-pass/unreachable-code.rs rename to src/test/ui/unreachable-code.rs index ea17be7ade..28b938edc6 100644 --- a/src/test/run-pass/unreachable-code.rs +++ b/src/test/ui/unreachable-code.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(dead_code)] diff --git a/src/test/ui/unreachable/unreachable-try-pattern.rs b/src/test/ui/unreachable/unreachable-try-pattern.rs index 6665c58e45..cbc5fcee2f 100644 --- a/src/test/ui/unreachable/unreachable-try-pattern.rs +++ b/src/test/ui/unreachable/unreachable-try-pattern.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(never_type, exhaustive_patterns)] #![warn(unreachable_code)] #![warn(unreachable_patterns)] diff --git a/src/test/ui/unresolved/unresolved-import.rs b/src/test/ui/unresolved/unresolved-import.rs index 4c7d4bb935..b65c3dfb90 100644 --- a/src/test/ui/unresolved/unresolved-import.rs +++ b/src/test/ui/unresolved/unresolved-import.rs @@ -1,5 +1,5 @@ use foo::bar; //~ ERROR unresolved import `foo` [E0432] - //~^ maybe a missing `extern crate foo;`? + //~^ maybe a missing crate `foo`? use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432] //~| no `Baz` in `bar` diff --git a/src/test/ui/unresolved/unresolved-import.stderr b/src/test/ui/unresolved/unresolved-import.stderr index fb5c0760d1..d4bfea5780 100644 --- a/src/test/ui/unresolved/unresolved-import.stderr +++ b/src/test/ui/unresolved/unresolved-import.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `foo` --> $DIR/unresolved-import.rs:1:5 | LL | use foo::bar; - | ^^^ maybe a missing `extern crate foo;`? + | ^^^ maybe a missing crate `foo`? error[E0432]: unresolved import `bar::Baz` --> $DIR/unresolved-import.rs:4:5 diff --git a/src/test/ui/unrestricted-attribute-tokens.rs b/src/test/ui/unrestricted-attribute-tokens.rs index b07ab96bce..e31bc91a00 100644 --- a/src/test/ui/unrestricted-attribute-tokens.rs +++ b/src/test/ui/unrestricted-attribute-tokens.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/run-pass/unsafe-coercion.rs b/src/test/ui/unsafe-coercion.rs similarity index 95% rename from src/test/run-pass/unsafe-coercion.rs rename to src/test/ui/unsafe-coercion.rs index 0c977c1ef3..2478deeab0 100644 --- a/src/test/run-pass/unsafe-coercion.rs +++ b/src/test/ui/unsafe-coercion.rs @@ -1,3 +1,4 @@ +// run-pass // Check that safe fns are not a subtype of unsafe fns. diff --git a/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs b/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs similarity index 93% rename from src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs rename to src/test/ui/unsafe-fn-called-from-unsafe-blk.rs index e49b372981..38271cc3c7 100644 --- a/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs +++ b/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // // See also: compile-fail/unsafe-fn-called-from-safe.rs diff --git a/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs b/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs similarity index 93% rename from src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs rename to src/test/ui/unsafe-fn-called-from-unsafe-fn.rs index f9414bee29..26acc913e8 100644 --- a/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs +++ b/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // // See also: compile-fail/unsafe-fn-called-from-safe.rs diff --git a/src/test/run-pass/unsafe-pointer-assignability.rs b/src/test/ui/unsafe-pointer-assignability.rs similarity index 88% rename from src/test/run-pass/unsafe-pointer-assignability.rs rename to src/test/ui/unsafe-pointer-assignability.rs index 11e22d7a08..db822bb6a0 100644 --- a/src/test/run-pass/unsafe-pointer-assignability.rs +++ b/src/test/ui/unsafe-pointer-assignability.rs @@ -1,3 +1,5 @@ +// run-pass + fn f(x: *const isize) { unsafe { assert_eq!(*x, 3); diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr index 6a47c5b141..e99155ee10 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.stderr +++ b/src/test/ui/unsafe/ranged_ints2_const.stderr @@ -5,7 +5,7 @@ LL | let y = &mut x.0; | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: mutable references in const fn are unstable --> $DIR/ranged_ints2_const.rs:18:9 @@ -14,7 +14,7 @@ LL | let y = unsafe { &mut x.0 }; | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block --> $DIR/ranged_ints2_const.rs:11:13 diff --git a/src/test/run-pass/unsized-locals/autoderef.rs b/src/test/ui/unsized-locals/autoderef.rs similarity index 98% rename from src/test/run-pass/unsized-locals/autoderef.rs rename to src/test/ui/unsized-locals/autoderef.rs index 885cd2b836..7f2d2f9c7e 100644 --- a/src/test/run-pass/unsized-locals/autoderef.rs +++ b/src/test/ui/unsized-locals/autoderef.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(unsized_locals)] pub trait Foo { diff --git a/src/test/run-pass/unsized-locals/box-fnonce.rs b/src/test/ui/unsized-locals/box-fnonce.rs similarity index 92% rename from src/test/run-pass/unsized-locals/box-fnonce.rs rename to src/test/ui/unsized-locals/box-fnonce.rs index 16bdeae4fa..8b2f9b4c9f 100644 --- a/src/test/run-pass/unsized-locals/box-fnonce.rs +++ b/src/test/ui/unsized-locals/box-fnonce.rs @@ -1,3 +1,5 @@ +// run-pass + fn call_it(f: Box T>) -> T { f() } diff --git a/src/test/run-pass/unsized-locals/by-value-trait-object-safety.rs b/src/test/ui/unsized-locals/by-value-trait-object-safety-rpass.rs similarity index 96% rename from src/test/run-pass/unsized-locals/by-value-trait-object-safety.rs rename to src/test/ui/unsized-locals/by-value-trait-object-safety-rpass.rs index f19ff5b8de..b07d1a571b 100644 --- a/src/test/run-pass/unsized-locals/by-value-trait-object-safety.rs +++ b/src/test/ui/unsized-locals/by-value-trait-object-safety-rpass.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(unsized_locals)] pub trait Foo { diff --git a/src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs b/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs similarity index 96% rename from src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs rename to src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs index e6e363f55a..8b39a99da5 100644 --- a/src/test/run-pass/unsized-locals/by-value-trait-object-safety-withdefault.rs +++ b/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(unsized_locals)] pub trait Foo { diff --git a/src/test/run-pass/unsized-locals/reference-unsized-locals.rs b/src/test/ui/unsized-locals/reference-unsized-locals.rs similarity index 100% rename from src/test/run-pass/unsized-locals/reference-unsized-locals.rs rename to src/test/ui/unsized-locals/reference-unsized-locals.rs diff --git a/src/test/run-pass/unsized-locals/simple-unsized-locals.rs b/src/test/ui/unsized-locals/simple-unsized-locals.rs similarity index 100% rename from src/test/run-pass/unsized-locals/simple-unsized-locals.rs rename to src/test/ui/unsized-locals/simple-unsized-locals.rs diff --git a/src/test/run-pass/unsized-locals/unsized-exprs.rs b/src/test/ui/unsized-locals/unsized-exprs-rpass.rs similarity index 100% rename from src/test/run-pass/unsized-locals/unsized-exprs.rs rename to src/test/ui/unsized-locals/unsized-exprs-rpass.rs diff --git a/src/test/ui/unsized-locals/unsized-index.rs b/src/test/ui/unsized-locals/unsized-index.rs index 2e6bd82bda..19ad97a853 100644 --- a/src/test/ui/unsized-locals/unsized-index.rs +++ b/src/test/ui/unsized-locals/unsized-index.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // `std::ops::Index` has an `: ?Sized` bound on the `Idx` type param. This is // an accidental left-over from the times when it `Index` was by-reference. diff --git a/src/test/run-pass/unsized-locals/unsized-parameters.rs b/src/test/ui/unsized-locals/unsized-parameters.rs similarity index 100% rename from src/test/run-pass/unsized-locals/unsized-parameters.rs rename to src/test/ui/unsized-locals/unsized-parameters.rs diff --git a/src/test/run-pass/unsized-tuple-impls.rs b/src/test/ui/unsized-tuple-impls.rs similarity index 97% rename from src/test/run-pass/unsized-tuple-impls.rs rename to src/test/ui/unsized-tuple-impls.rs index 17ab317361..5e385f33be 100644 --- a/src/test/run-pass/unsized-tuple-impls.rs +++ b/src/test/ui/unsized-tuple-impls.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(unsized_tuple_coercion)] use std::collections::HashSet; diff --git a/src/test/run-pass/unsized.rs b/src/test/ui/unsized.rs similarity index 97% rename from src/test/run-pass/unsized.rs rename to src/test/ui/unsized.rs index ad69214db8..54304834d4 100644 --- a/src/test/run-pass/unsized.rs +++ b/src/test/ui/unsized.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(type_alias_bounds)] #![allow(dead_code)] // Test syntax checks for `?Sized` syntax. diff --git a/src/test/run-pass/unsized2.rs b/src/test/ui/unsized2.rs similarity index 99% rename from src/test/run-pass/unsized2.rs rename to src/test/ui/unsized2.rs index c9a8b2e7c6..be4406399f 100644 --- a/src/test/run-pass/unsized2.rs +++ b/src/test/ui/unsized2.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unconditional_recursion)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/run-pass/unsized3.rs b/src/test/ui/unsized3-rpass.rs similarity index 99% rename from src/test/run-pass/unsized3.rs rename to src/test/ui/unsized3-rpass.rs index eaa65cf37f..65efbd6b52 100644 --- a/src/test/run-pass/unsized3.rs +++ b/src/test/ui/unsized3-rpass.rs @@ -1,3 +1,4 @@ +// run-pass // Test structs with always-unsized fields. diff --git a/src/test/run-pass/unused-move-capture.rs b/src/test/ui/unused-move-capture.rs similarity index 92% rename from src/test/run-pass/unused-move-capture.rs rename to src/test/ui/unused-move-capture.rs index baba19c08c..e9d4684736 100644 --- a/src/test/run-pass/unused-move-capture.rs +++ b/src/test/ui/unused-move-capture.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 #![feature(box_syntax)] diff --git a/src/test/run-pass/unused-move.rs b/src/test/ui/unused-move.rs similarity index 95% rename from src/test/run-pass/unused-move.rs rename to src/test/ui/unused-move.rs index 74632dbc79..37aee22f85 100644 --- a/src/test/run-pass/unused-move.rs +++ b/src/test/ui/unused-move.rs @@ -1,3 +1,4 @@ +// run-pass // Issue #3878 // Issue Name: Unused move causes a crash // Abstract: zero-fill to block after drop diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/ui/unwind-resource.rs similarity index 98% rename from src/test/run-pass/unwind-resource.rs rename to src/test/ui/unwind-resource.rs index a55730c55f..a063bef082 100644 --- a/src/test/run-pass/unwind-resource.rs +++ b/src/test/ui/unwind-resource.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] // ignore-emscripten no threads support diff --git a/src/test/run-pass/unwind-unique.rs b/src/test/ui/unwind-unique.rs similarity index 94% rename from src/test/run-pass/unwind-unique.rs rename to src/test/ui/unwind-unique.rs index 07613a6dd6..ea3089e747 100644 --- a/src/test/run-pass/unwind-unique.rs +++ b/src/test/ui/unwind-unique.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten no threads support #![feature(box_syntax)] diff --git a/src/test/run-pass/use-crate-name-alias.rs b/src/test/ui/use-crate-name-alias.rs similarity index 88% rename from src/test/run-pass/use-crate-name-alias.rs rename to src/test/ui/use-crate-name-alias.rs index 520e72676b..0920d96858 100644 --- a/src/test/run-pass/use-crate-name-alias.rs +++ b/src/test/ui/use-crate-name-alias.rs @@ -1,3 +1,4 @@ +// run-pass // Issue #1706 // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/use-import-export.rs b/src/test/ui/use-import-export.rs similarity index 93% rename from src/test/run-pass/use-import-export.rs rename to src/test/ui/use-import-export.rs index bb6a8ee55b..07a6866ba6 100644 --- a/src/test/run-pass/use-import-export.rs +++ b/src/test/ui/use-import-export.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 mod foo { diff --git a/src/test/run-pass/use-keyword-2.rs b/src/test/ui/use-keyword-2.rs similarity index 95% rename from src/test/run-pass/use-keyword-2.rs rename to src/test/ui/use-keyword-2.rs index 840c907e23..ebddb5d1a4 100644 --- a/src/test/run-pass/use-keyword-2.rs +++ b/src/test/ui/use-keyword-2.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_variables)] pub struct A; diff --git a/src/test/run-pass/use-mod.rs b/src/test/ui/use-mod.rs similarity index 97% rename from src/test/run-pass/use-mod.rs rename to src/test/ui/use-mod.rs index 9af56b71de..84da2e7087 100644 --- a/src/test/run-pass/use-mod.rs +++ b/src/test/ui/use-mod.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_imports)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/use-nested-groups.rs b/src/test/ui/use-nested-groups.rs similarity index 97% rename from src/test/run-pass/use-nested-groups.rs rename to src/test/ui/use-nested-groups.rs index 092b4a34e5..5c739709e9 100644 --- a/src/test/run-pass/use-nested-groups.rs +++ b/src/test/ui/use-nested-groups.rs @@ -1,3 +1,5 @@ +// run-pass + mod a { pub enum B {} diff --git a/src/test/run-pass/use.rs b/src/test/ui/use.rs similarity index 96% rename from src/test/run-pass/use.rs rename to src/test/ui/use.rs index df37a60e35..1beee4a514 100644 --- a/src/test/run-pass/use.rs +++ b/src/test/ui/use.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/use/use-mod/use-mod-4.stderr b/src/test/ui/use/use-mod/use-mod-4.stderr index df9898844d..e30e5c3ceb 100644 --- a/src/test/ui/use/use-mod/use-mod-4.stderr +++ b/src/test/ui/use/use-mod/use-mod-4.stderr @@ -14,7 +14,7 @@ error[E0432]: unresolved import `foo` --> $DIR/use-mod-4.rs:1:5 | LL | use foo::self; - | ^^^ maybe a missing `extern crate foo;`? + | ^^^ maybe a missing crate `foo`? error: aborting due to 3 previous errors diff --git a/src/test/run-pass/use_inline_dtor.rs b/src/test/ui/use_inline_dtor.rs similarity index 92% rename from src/test/run-pass/use_inline_dtor.rs rename to src/test/ui/use_inline_dtor.rs index 0873d18557..ac916de464 100644 --- a/src/test/run-pass/use_inline_dtor.rs +++ b/src/test/ui/use_inline_dtor.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:inline_dtor.rs // pretty-expanded FIXME #23616 diff --git a/src/test/ui/user-defined-macro-rules.rs b/src/test/ui/user-defined-macro-rules.rs index 31bfdd025d..09e071ec45 100644 --- a/src/test/ui/user-defined-macro-rules.rs +++ b/src/test/ui/user-defined-macro-rules.rs @@ -1,5 +1,9 @@ -#![allow(unused_macros)] +// check-pass -macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules` +macro_rules! macro_rules { () => { struct S; } } // OK -fn main() {} +macro_rules! {} // OK, calls the macro defined above + +fn main() { + let s = S; +} diff --git a/src/test/ui/user-defined-macro-rules.stderr b/src/test/ui/user-defined-macro-rules.stderr deleted file mode 100644 index 057515228e..0000000000 --- a/src/test/ui/user-defined-macro-rules.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: user-defined macros may not be named `macro_rules` - --> $DIR/user-defined-macro-rules.rs:3:1 - | -LL | macro_rules! macro_rules { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/run-pass/using-target-feature-unstable.rs b/src/test/ui/using-target-feature-unstable.rs similarity index 93% rename from src/test/run-pass/using-target-feature-unstable.rs rename to src/test/ui/using-target-feature-unstable.rs index 05b1d93a69..c5da45c085 100644 --- a/src/test/run-pass/using-target-feature-unstable.rs +++ b/src/test/ui/using-target-feature-unstable.rs @@ -1,3 +1,4 @@ +// run-pass // only-x86_64 // aux-build:using-target-feature-unstable.rs diff --git a/src/test/run-pass/utf8-bom.rs b/src/test/ui/utf8-bom.rs similarity index 88% rename from src/test/run-pass/utf8-bom.rs rename to src/test/ui/utf8-bom.rs index 90874c9b2e..a3cb0e9a52 100644 --- a/src/test/run-pass/utf8-bom.rs +++ b/src/test/ui/utf8-bom.rs @@ -1,3 +1,4 @@ +// run-pass // // This file has utf-8 BOM, it should be compiled normally without error. diff --git a/src/test/run-pass/utf8.rs b/src/test/ui/utf8.rs similarity index 99% rename from src/test/run-pass/utf8.rs rename to src/test/ui/utf8.rs index b908afbd5b..75b6ddf789 100644 --- a/src/test/run-pass/utf8.rs +++ b/src/test/ui/utf8.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let yen: char = '¥'; // 0xa5 let c_cedilla: char = 'ç'; // 0xe7 diff --git a/src/test/run-pass/utf8_chars.rs b/src/test/ui/utf8_chars.rs similarity index 98% rename from src/test/run-pass/utf8_chars.rs rename to src/test/ui/utf8_chars.rs index c29d8557b7..d764509813 100644 --- a/src/test/run-pass/utf8_chars.rs +++ b/src/test/ui/utf8_chars.rs @@ -1,3 +1,5 @@ +// run-pass + use std::str; pub fn main() { diff --git a/src/test/run-pass/utf8_idents.rs b/src/test/ui/utf8_idents-rpass.rs similarity index 98% rename from src/test/run-pass/utf8_idents.rs rename to src/test/ui/utf8_idents-rpass.rs index 7323e144f8..582b67bc29 100644 --- a/src/test/run-pass/utf8_idents.rs +++ b/src/test/ui/utf8_idents-rpass.rs @@ -1,3 +1,4 @@ +// run-pass // #![allow(non_snake_case)] diff --git a/src/test/ui/utf8_idents.stderr b/src/test/ui/utf8_idents.stderr index b65848cc58..56de63da4f 100644 --- a/src/test/ui/utf8_idents.stderr +++ b/src/test/ui/utf8_idents.stderr @@ -5,7 +5,7 @@ LL | 'β, | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/utf8_idents.rs:3:5 @@ -14,7 +14,7 @@ LL | γ | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/utf8_idents.rs:8:5 @@ -23,7 +23,7 @@ LL | δ: usize | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/utf8_idents.rs:12:9 @@ -32,7 +32,7 @@ LL | let α = 0.00001f64; | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable warning: type parameter `γ` should have an upper camel case name --> $DIR/utf8_idents.rs:3:5 @@ -40,7 +40,7 @@ warning: type parameter `γ` should have an upper camel case name LL | γ | ^ help: convert the identifier to upper camel case: `Γ` | - = note: #[warn(non_camel_case_types)] on by default + = note: `#[warn(non_camel_case_types)]` on by default error: aborting due to 4 previous errors diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/ui/variadic-ffi.rs similarity index 99% rename from src/test/run-pass/variadic-ffi.rs rename to src/test/ui/variadic-ffi.rs index d6fbb1773b..3232a11d72 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/ui/variadic-ffi.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare no libc to test ffi with #![feature(c_variadic)] diff --git a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/ui/variance-intersection-of-ref-and-opt-ref.rs similarity index 98% rename from src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs rename to src/test/ui/variance-intersection-of-ref-and-opt-ref.rs index fde151400b..74707a98d3 100644 --- a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs +++ b/src/test/ui/variance-intersection-of-ref-and-opt-ref.rs @@ -1,3 +1,4 @@ +// run-pass // Elaborated version of the opening example from RFC 738. This failed // to compile before variance because invariance of `Option` prevented // us from approximating the lifetimes of `field1` and `field2` to a diff --git a/src/test/run-pass/variance-iterators-in-libcore.rs b/src/test/ui/variance-iterators-in-libcore.rs similarity index 91% rename from src/test/run-pass/variance-iterators-in-libcore.rs rename to src/test/ui/variance-iterators-in-libcore.rs index 32b56bd0b5..2ab3a8ab5c 100644 --- a/src/test/run-pass/variance-iterators-in-libcore.rs +++ b/src/test/ui/variance-iterators-in-libcore.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(warnings)] use std::iter::Zip; diff --git a/src/test/ui/variance/variance-use-contravariant-struct-2.rs b/src/test/ui/variance/variance-use-contravariant-struct-2.rs index 77bd2b79f8..2113eb2add 100644 --- a/src/test/ui/variance/variance-use-contravariant-struct-2.rs +++ b/src/test/ui/variance/variance-use-contravariant-struct-2.rs @@ -2,7 +2,7 @@ // they permit lifetimes to be approximated as expected. #![allow(dead_code)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct SomeStruct(fn(T)); diff --git a/src/test/ui/variance/variance-use-covariant-struct-2.rs b/src/test/ui/variance/variance-use-covariant-struct-2.rs index cb8159d8a6..ecd2204c99 100644 --- a/src/test/ui/variance/variance-use-covariant-struct-2.rs +++ b/src/test/ui/variance/variance-use-covariant-struct-2.rs @@ -2,7 +2,7 @@ // be shortened. #![allow(dead_code)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct SomeStruct(T); diff --git a/src/test/run-pass/volatile-fat-ptr.rs b/src/test/ui/volatile-fat-ptr.rs similarity index 95% rename from src/test/run-pass/volatile-fat-ptr.rs rename to src/test/ui/volatile-fat-ptr.rs index f01263b73a..f73e7e1c39 100644 --- a/src/test/run-pass/volatile-fat-ptr.rs +++ b/src/test/ui/volatile-fat-ptr.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(stable_features)] #![feature(volatile)] use std::ptr::{read_volatile, write_volatile}; diff --git a/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/ui/wait-forked-but-failed-child.rs similarity index 97% rename from src/test/run-pass/wait-forked-but-failed-child.rs rename to src/test/ui/wait-forked-but-failed-child.rs index 1f32bd00a0..08b16c0e9c 100644 --- a/src/test/run-pass/wait-forked-but-failed-child.rs +++ b/src/test/ui/wait-forked-but-failed-child.rs @@ -1,6 +1,8 @@ +// run-pass // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes +// ignore-vxworks no 'ps' #![feature(rustc_private)] diff --git a/src/test/run-pass/warn-ctypes-inhibit.rs b/src/test/ui/warn-ctypes-inhibit.rs similarity index 94% rename from src/test/run-pass/warn-ctypes-inhibit.rs rename to src/test/ui/warn-ctypes-inhibit.rs index 76b36a12c2..ab9634df65 100644 --- a/src/test/run-pass/warn-ctypes-inhibit.rs +++ b/src/test/ui/warn-ctypes-inhibit.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // compile-flags:-D improper-ctypes diff --git a/src/test/ui/wasm-import-module.stderr b/src/test/ui/wasm-import-module.stderr index 20eec4c9f5..47d6cb6899 100644 --- a/src/test/ui/wasm-import-module.stderr +++ b/src/test/ui/wasm-import-module.stderr @@ -1,16 +1,16 @@ -error: must be of the form #[link(wasm_import_module = "...")] +error: must be of the form `#[link(wasm_import_module = "...")]` --> $DIR/wasm-import-module.rs:1:22 | LL | #[link(name = "...", wasm_import_module)] | ^^^^^^^^^^^^^^^^^^ -error: must be of the form #[link(wasm_import_module = "...")] +error: must be of the form `#[link(wasm_import_module = "...")]` --> $DIR/wasm-import-module.rs:4:22 | LL | #[link(name = "...", wasm_import_module(x))] | ^^^^^^^^^^^^^^^^^^^^^ -error: must be of the form #[link(wasm_import_module = "...")] +error: must be of the form `#[link(wasm_import_module = "...")]` --> $DIR/wasm-import-module.rs:7:22 | LL | #[link(name = "...", wasm_import_module())] diff --git a/src/test/run-pass/weak-lang-item.rs b/src/test/ui/weak-lang-item.rs similarity index 95% rename from src/test/run-pass/weak-lang-item.rs rename to src/test/ui/weak-lang-item.rs index 9a36606a46..a429d8fabc 100644 --- a/src/test/run-pass/weak-lang-item.rs +++ b/src/test/ui/weak-lang-item.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:weak-lang-items.rs // ignore-emscripten no threads support diff --git a/src/test/run-pass/weak-new-uninhabited-issue-48493.rs b/src/test/ui/weak-new-uninhabited-issue-48493.rs similarity index 88% rename from src/test/run-pass/weak-new-uninhabited-issue-48493.rs rename to src/test/ui/weak-new-uninhabited-issue-48493.rs index 4f93800b86..644fc8c248 100644 --- a/src/test/run-pass/weak-new-uninhabited-issue-48493.rs +++ b/src/test/ui/weak-new-uninhabited-issue-48493.rs @@ -1,3 +1,5 @@ +// run-pass + fn main() { enum Void {} std::rc::Weak::::new(); diff --git a/src/test/run-pass/weird-exit-code.rs b/src/test/ui/weird-exit-code.rs similarity index 98% rename from src/test/run-pass/weird-exit-code.rs rename to src/test/ui/weird-exit-code.rs index 9456cbbe6f..a067b7b5b1 100644 --- a/src/test/run-pass/weird-exit-code.rs +++ b/src/test/ui/weird-exit-code.rs @@ -1,3 +1,4 @@ +// run-pass // On Windows the GetExitCodeProcess API is used to get the exit code of a // process, but it's easy to mistake a process exiting with the code 259 as // "still running" because this is the value of the STILL_ACTIVE constant. Make diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/ui/weird-exprs.rs similarity index 99% rename from src/test/run-pass/weird-exprs.rs rename to src/test/ui/weird-exprs.rs index 7b2b46c45d..ca68a5af0d 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/ui/weird-exprs.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(generators)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/wf-bound-region-in-object-type.rs b/src/test/ui/wf-bound-region-in-object-type.rs similarity index 97% rename from src/test/run-pass/wf-bound-region-in-object-type.rs rename to src/test/ui/wf-bound-region-in-object-type.rs index 6814e2baab..7c4dd3ec84 100644 --- a/src/test/run-pass/wf-bound-region-in-object-type.rs +++ b/src/test/ui/wf-bound-region-in-object-type.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #![allow(unused_variables)] // Test that the `wf` checker properly handles bound regions in object diff --git a/src/test/run-pass/where-clauses/auxiliary/where_clauses_xc.rs b/src/test/ui/where-clauses/auxiliary/where_clauses_xc.rs similarity index 100% rename from src/test/run-pass/where-clauses/auxiliary/where_clauses_xc.rs rename to src/test/ui/where-clauses/auxiliary/where_clauses_xc.rs diff --git a/src/test/run-pass/where-clauses/where-clause-bounds-inconsistency.rs b/src/test/ui/where-clauses/where-clause-bounds-inconsistency.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clause-bounds-inconsistency.rs rename to src/test/ui/where-clauses/where-clause-bounds-inconsistency.rs diff --git a/src/test/run-pass/where-clauses/where-clause-early-bound-lifetimes.rs b/src/test/ui/where-clauses/where-clause-early-bound-lifetimes.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clause-early-bound-lifetimes.rs rename to src/test/ui/where-clauses/where-clause-early-bound-lifetimes.rs diff --git a/src/test/run-pass/where-clauses/where-clause-method-substituion.rs b/src/test/ui/where-clauses/where-clause-method-substituion-rpass.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clause-method-substituion.rs rename to src/test/ui/where-clauses/where-clause-method-substituion-rpass.rs diff --git a/src/test/run-pass/where-clauses/where-clause-region-outlives.rs b/src/test/ui/where-clauses/where-clause-region-outlives.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clause-region-outlives.rs rename to src/test/ui/where-clauses/where-clause-region-outlives.rs diff --git a/src/test/run-pass/where-clauses/where-clauses-cross-crate.rs b/src/test/ui/where-clauses/where-clauses-cross-crate.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clauses-cross-crate.rs rename to src/test/ui/where-clauses/where-clauses-cross-crate.rs diff --git a/src/test/run-pass/where-clauses/where-clauses-lifetimes.rs b/src/test/ui/where-clauses/where-clauses-lifetimes.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clauses-lifetimes.rs rename to src/test/ui/where-clauses/where-clauses-lifetimes.rs diff --git a/src/test/run-pass/where-clauses/where-clauses-method.rs b/src/test/ui/where-clauses/where-clauses-method.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clauses-method.rs rename to src/test/ui/where-clauses/where-clauses-method.rs diff --git a/src/test/run-pass/where-clauses/where-clauses-unboxed-closures.rs b/src/test/ui/where-clauses/where-clauses-unboxed-closures.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clauses-unboxed-closures.rs rename to src/test/ui/where-clauses/where-clauses-unboxed-closures.rs diff --git a/src/test/run-pass/where-clauses/where-clauses.rs b/src/test/ui/where-clauses/where-clauses.rs similarity index 100% rename from src/test/run-pass/where-clauses/where-clauses.rs rename to src/test/ui/where-clauses/where-clauses.rs diff --git a/src/test/ui/while-let.stderr b/src/test/ui/while-let.stderr index 156d0e6c33..348925aa97 100644 --- a/src/test/ui/while-let.stderr +++ b/src/test/ui/while-let.stderr @@ -9,7 +9,7 @@ LL | | println!("irrefutable pattern"); LL | | }); | |_______- in this macro invocation | - = note: #[warn(irrefutable_let_patterns)] on by default + = note: `#[warn(irrefutable_let_patterns)]` on by default warning: irrefutable while-let pattern --> $DIR/while-let.rs:6:13 diff --git a/src/test/run-pass/wrapping-int-api.rs b/src/test/ui/wrapping-int-api.rs similarity index 99% rename from src/test/run-pass/wrapping-int-api.rs rename to src/test/ui/wrapping-int-api.rs index fc62caf3b8..2a5baad8b7 100644 --- a/src/test/run-pass/wrapping-int-api.rs +++ b/src/test/ui/wrapping-int-api.rs @@ -1,3 +1,4 @@ +// run-pass // Test inherent wrapping_* methods for {i,u}{size,8,16,32,64}. use std::{i8, i16, i32, i64, isize}; diff --git a/src/test/run-pass/write-fmt-errors.rs b/src/test/ui/write-fmt-errors.rs similarity index 99% rename from src/test/run-pass/write-fmt-errors.rs rename to src/test/ui/write-fmt-errors.rs index f95bbfd569..7dd9856442 100644 --- a/src/test/run-pass/write-fmt-errors.rs +++ b/src/test/ui/write-fmt-errors.rs @@ -1,3 +1,5 @@ +// run-pass + use std::fmt; use std::io::{self, Error, Write, sink}; diff --git a/src/test/run-pass/writealias.rs b/src/test/ui/writealias.rs similarity index 96% rename from src/test/run-pass/writealias.rs rename to src/test/ui/writealias.rs index f80118e08c..8ba4b09ae2 100644 --- a/src/test/run-pass/writealias.rs +++ b/src/test/ui/writealias.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] use std::sync::Mutex; diff --git a/src/test/run-pass/wrong-hashset-issue-42918.rs b/src/test/ui/wrong-hashset-issue-42918.rs similarity index 97% rename from src/test/run-pass/wrong-hashset-issue-42918.rs rename to src/test/ui/wrong-hashset-issue-42918.rs index 12b10640c5..ef834d915c 100644 --- a/src/test/run-pass/wrong-hashset-issue-42918.rs +++ b/src/test/ui/wrong-hashset-issue-42918.rs @@ -1,3 +1,4 @@ +// run-pass // #![allow(dead_code)] // compile-flags: -O diff --git a/src/test/run-pass/x86stdcall.rs b/src/test/ui/x86stdcall.rs similarity index 95% rename from src/test/run-pass/x86stdcall.rs rename to src/test/ui/x86stdcall.rs index cd9450a569..32a4df87fb 100644 --- a/src/test/run-pass/x86stdcall.rs +++ b/src/test/ui/x86stdcall.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-wasm32-bare no libc to test ffi with // ignore-sgx no libc // GetLastError doesn't seem to work with stack switching @@ -31,5 +32,6 @@ pub fn main() { target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "vxworks", target_os = "solaris"))] pub fn main() { } diff --git a/src/test/run-pass/x86stdcall2.rs b/src/test/ui/x86stdcall2.rs similarity index 98% rename from src/test/run-pass/x86stdcall2.rs rename to src/test/ui/x86stdcall2.rs index 3d008f26ab..563e3aba63 100644 --- a/src/test/run-pass/x86stdcall2.rs +++ b/src/test/ui/x86stdcall2.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] pub type HANDLE = usize; pub type DWORD = u32; diff --git a/src/test/run-pass/yield.rs b/src/test/ui/yield.rs similarity index 96% rename from src/test/run-pass/yield.rs rename to src/test/ui/yield.rs index a5fd14bd8f..e83ba55607 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/ui/yield.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(unused_mut)] // ignore-emscripten no threads support diff --git a/src/test/run-pass/yield1.rs b/src/test/ui/yield1.rs similarity index 95% rename from src/test/run-pass/yield1.rs rename to src/test/ui/yield1.rs index e7a6190b56..002e590550 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/ui/yield1.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] #![allow(unused_mut)] // ignore-emscripten no threads support diff --git a/src/test/run-pass/yield2.rs b/src/test/ui/yield2.rs similarity index 91% rename from src/test/run-pass/yield2.rs rename to src/test/ui/yield2.rs index c4ccd2d147..376faab0c4 100644 --- a/src/test/run-pass/yield2.rs +++ b/src/test/ui/yield2.rs @@ -1,3 +1,5 @@ +// run-pass + use std::thread; pub fn main() { diff --git a/src/test/run-pass/z-crate-attr.rs b/src/test/ui/z-crate-attr.rs similarity index 96% rename from src/test/run-pass/z-crate-attr.rs rename to src/test/ui/z-crate-attr.rs index f084394130..1021774fc5 100644 --- a/src/test/run-pass/z-crate-attr.rs +++ b/src/test/ui/z-crate-attr.rs @@ -1,3 +1,4 @@ +// run-pass // This test checks if an unstable feature is enabled with the -Zcrate-attr=feature(foo) flag. If // the exact feature used here is causing problems feel free to replace it with another // perma-unstable feature. diff --git a/src/test/run-pass/zero-sized/zero-size-type-destructors.rs b/src/test/ui/zero-sized/zero-size-type-destructors.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-size-type-destructors.rs rename to src/test/ui/zero-sized/zero-size-type-destructors.rs diff --git a/src/test/run-pass/zero-sized/zero-sized-binary-heap-push.rs b/src/test/ui/zero-sized/zero-sized-binary-heap-push.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-sized-binary-heap-push.rs rename to src/test/ui/zero-sized/zero-sized-binary-heap-push.rs diff --git a/src/test/run-pass/zero-sized/zero-sized-btreemap-insert.rs b/src/test/ui/zero-sized/zero-sized-btreemap-insert.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-sized-btreemap-insert.rs rename to src/test/ui/zero-sized/zero-sized-btreemap-insert.rs diff --git a/src/test/run-pass/zero-sized/zero-sized-linkedlist-push.rs b/src/test/ui/zero-sized/zero-sized-linkedlist-push.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-sized-linkedlist-push.rs rename to src/test/ui/zero-sized/zero-sized-linkedlist-push.rs diff --git a/src/test/run-pass/zero-sized/zero-sized-tuple-struct.rs b/src/test/ui/zero-sized/zero-sized-tuple-struct.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-sized-tuple-struct.rs rename to src/test/ui/zero-sized/zero-sized-tuple-struct.rs diff --git a/src/test/run-pass/zero-sized/zero-sized-vec-deque-push.rs b/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-sized-vec-deque-push.rs rename to src/test/ui/zero-sized/zero-sized-vec-deque-push.rs diff --git a/src/test/run-pass/zero-sized/zero-sized-vec-push.rs b/src/test/ui/zero-sized/zero-sized-vec-push.rs similarity index 100% rename from src/test/run-pass/zero-sized/zero-sized-vec-push.rs rename to src/test/ui/zero-sized/zero-sized-vec-push.rs diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index b6e087c384..9ffa9391c8 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use toml; use serde::Serialize; @@ -48,6 +46,7 @@ static TARGETS: &[&str] = &[ "aarch64-unknown-cloudabi", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", + "aarch64-unknown-redox", "arm-linux-androideabi", "arm-unknown-linux-gnueabi", "arm-unknown-linux-gnueabihf", @@ -58,8 +57,10 @@ static TARGETS: &[&str] = &[ "armv7-apple-ios", "armv7-linux-androideabi", "thumbv7neon-linux-androideabi", + "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "thumbv7neon-unknown-linux-gnueabihf", + "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", "armebv7r-none-eabi", "armebv7r-none-eabihf", @@ -92,6 +93,7 @@ static TARGETS: &[&str] = &[ "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", + "riscv32i-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf", "riscv64imac-unknown-none-elf", diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 14035eedbb..f6aaaa5c6e 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use std::env; use std::process::Command; use std::path::{Path, PathBuf}; @@ -52,7 +50,7 @@ const TEST_REPOS: &'static [Test] = &[ Test { name: "servo", repo: "https://github.com/servo/servo", - sha: "987e376ca7a4245dbc3e0c06e963278ee1ac92d1", + sha: "caac107ae8145ef2fd20365e2b8fadaf09c2eb3b", lock: None, // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox. // This takes much less time to build than all of Servo and supports stable Rust. diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index a75d9f0b0b..66e030e979 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -12,8 +12,6 @@ use crate::util::PathBufExt; pub enum Mode { CompileFail, RunFail, - /// This now behaves like a `ui` test that has an implict `// run-pass`. - RunPass, RunPassValgrind, Pretty, DebugInfoCdb, @@ -33,7 +31,7 @@ pub enum Mode { impl Mode { pub fn disambiguator(self) -> &'static str { - // Run-pass and pretty run-pass tests could run concurrently, and if they do, + // Pretty-printing tests could run concurrently, and if they do, // they need to keep their output segregated. Same is true for debuginfo tests that // can be run on cdb, gdb, and lldb. match self { @@ -52,7 +50,6 @@ impl FromStr for Mode { match s { "compile-fail" => Ok(CompileFail), "run-fail" => Ok(RunFail), - "run-pass" => Ok(RunPass), "run-pass-valgrind" => Ok(RunPassValgrind), "pretty" => Ok(Pretty), "debuginfo-cdb" => Ok(DebugInfoCdb), @@ -78,7 +75,6 @@ impl fmt::Display for Mode { let s = match *self { CompileFail => "compile-fail", RunFail => "run-fail", - RunPass => "run-pass", RunPassValgrind => "run-pass-valgrind", Pretty => "pretty", DebugInfoCdb => "debuginfo-cdb", @@ -202,7 +198,7 @@ pub struct Config { /// The name of the stage being built (stage1, etc) pub stage_id: String, - /// The test mode, compile-fail, run-fail, run-pass + /// The test mode, compile-fail, run-fail, ui pub mode: Mode, /// Run ignored tests diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 52f777db2d..076ad87c70 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -8,9 +8,11 @@ use log::*; use crate::common::{self, CompareMode, Config, Mode, PassMode}; use crate::util; - use crate::extract_gdb_version; +#[cfg(test)] +mod tests; + /// Whether to ignore the test. #[derive(Clone, Copy, PartialEq, Debug)] pub enum Ignore { @@ -591,11 +593,8 @@ impl TestProps { } else if config.parse_name_directive(ln, "build-pass") { check_no_run("build-pass"); Some(PassMode::Build) - } else if config.parse_name_directive(ln, "compile-pass") /* compatibility */ { - check_no_run("compile-pass"); - Some(PassMode::Build) } else if config.parse_name_directive(ln, "run-pass") { - if config.mode != Mode::Ui && config.mode != Mode::RunPass /* compatibility */ { + if config.mode != Mode::Ui { panic!("`run-pass` header is only supported in UI tests") } Some(PassMode::Run) @@ -972,29 +971,3 @@ fn parse_normalization_string(line: &mut &str) -> Option { *line = &line[end + 1..]; Some(result) } - -#[test] -fn test_parse_normalization_string() { - let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits)\"."; - let first = parse_normalization_string(&mut s); - assert_eq!(first, Some("something (32 bits)".to_owned())); - assert_eq!(s, " -> \"something ($WORD bits)\"."); - - // Nothing to normalize (No quotes) - let mut s = "normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)."; - let first = parse_normalization_string(&mut s); - assert_eq!(first, None); - assert_eq!(s, r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)."#); - - // Nothing to normalize (Only a single quote) - let mut s = "normalize-stderr-32bit: \"something (32 bits) -> something ($WORD bits)."; - let first = parse_normalization_string(&mut s); - assert_eq!(first, None); - assert_eq!(s, "normalize-stderr-32bit: \"something (32 bits) -> something ($WORD bits)."); - - // Nothing to normalize (Three quotes) - let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits)."; - let first = parse_normalization_string(&mut s); - assert_eq!(first, Some("something (32 bits)".to_owned())); - assert_eq!(s, " -> \"something ($WORD bits)."); -} diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs new file mode 100644 index 0000000000..2a1831d5ee --- /dev/null +++ b/src/tools/compiletest/src/header/tests.rs @@ -0,0 +1,27 @@ +use super::*; + +#[test] +fn test_parse_normalization_string() { + let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits)\"."; + let first = parse_normalization_string(&mut s); + assert_eq!(first, Some("something (32 bits)".to_owned())); + assert_eq!(s, " -> \"something ($WORD bits)\"."); + + // Nothing to normalize (No quotes) + let mut s = "normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)."; + let first = parse_normalization_string(&mut s); + assert_eq!(first, None); + assert_eq!(s, r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)."#); + + // Nothing to normalize (Only a single quote) + let mut s = "normalize-stderr-32bit: \"something (32 bits) -> something ($WORD bits)."; + let first = parse_normalization_string(&mut s); + assert_eq!(first, None); + assert_eq!(s, "normalize-stderr-32bit: \"something (32 bits) -> something ($WORD bits)."); + + // Nothing to normalize (Three quotes) + let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits)."; + let first = parse_normalization_string(&mut s); + assert_eq!(first, Some("something (32 bits)".to_owned())); + assert_eq!(s, " -> \"something ($WORD bits)."); +} diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 597fdf2d95..bde49ff391 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,7 +1,6 @@ #![crate_name = "compiletest"] #![feature(test)] #![feature(vec_remove_item)] -#![deny(warnings, rust_2018_idioms)] extern crate test; @@ -26,6 +25,9 @@ use log::*; use self::header::{EarlyProps, Ignore}; +#[cfg(test)] +mod tests; + pub mod common; pub mod errors; pub mod header; @@ -125,8 +127,7 @@ pub fn parse_config(args: Vec) -> Config { "", "mode", "which sort of compile tests to run", - "(compile-fail|run-fail|run-pass|\ - run-pass-valgrind|pretty|debug-info|incremental|mir-opt)", + "(compile-fail|run-fail|run-pass-valgrind|pretty|debug-info|incremental|mir-opt)", ) .optopt( "", @@ -814,7 +815,7 @@ fn make_test_name( ) -> test::TestName { // Convert a complete path to something like // - // run-pass/foo/bar/baz.rs + // ui/foo/bar/baz.rs let path = PathBuf::from(config.src_base.file_name().unwrap()) .join(&testpaths.relative_dir) .join(&testpaths.file.file_name().unwrap()); @@ -1095,53 +1096,3 @@ fn extract_lldb_version(full_version_line: Option) -> (Option, b fn is_blacklisted_lldb_version(version: &str) -> bool { version == "350" } - -#[test] -fn test_extract_gdb_version() { - macro_rules! test { ($($expectation:tt: $input:tt,)*) => {{$( - assert_eq!(extract_gdb_version($input), Some($expectation)); - )*}}} - - test! { - 7000001: "GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)", - - 7002000: "GNU gdb (GDB) Red Hat Enterprise Linux (7.2-90.el6)", - - 7004000: "GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04", - 7004001: "GNU gdb (GDB) 7.4.1-debian", - - 7006001: "GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7", - - 7007001: "GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1", - 7007001: "GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1", - 7007001: "GNU gdb (GDB) Fedora 7.7.1-21.fc20", - - 7008000: "GNU gdb (GDB; openSUSE 13.2) 7.8", - 7009001: "GNU gdb (GDB) Fedora 7.9.1-20.fc22", - 7010001: "GNU gdb (GDB) Fedora 7.10.1-31.fc23", - - 7011000: "GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11", - 7011001: "GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1", - 7011001: "GNU gdb (Debian 7.11.1-2) 7.11.1", - 7011001: "GNU gdb (GDB) Fedora 7.11.1-86.fc24", - 7011001: "GNU gdb (GDB; openSUSE Leap 42.1) 7.11.1", - 7011001: "GNU gdb (GDB; openSUSE Tumbleweed) 7.11.1", - - 7011090: "7.11.90", - 7011090: "GNU gdb (Ubuntu 7.11.90.20161005-0ubuntu1) 7.11.90.20161005-git", - - 7012000: "7.12", - 7012000: "GNU gdb (GDB) 7.12", - 7012000: "GNU gdb (GDB) 7.12.20161027-git", - 7012050: "GNU gdb (GDB) 7.12.50.20161027-git", - } -} - -#[test] -fn is_test_test() { - assert_eq!(true, is_test(&OsString::from("a_test.rs"))); - assert_eq!(false, is_test(&OsString::from(".a_test.rs"))); - assert_eq!(false, is_test(&OsString::from("a_cat.gif"))); - assert_eq!(false, is_test(&OsString::from("#a_dog_gif"))); - assert_eq!(false, is_test(&OsString::from("~a_temp_file"))); -} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 35caf82dd7..05cfdf1ce5 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -5,7 +5,7 @@ use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI use crate::common::{output_base_dir, output_base_name, output_testname_unique}; use crate::common::{Codegen, CodegenUnits, Rustdoc}; use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb}; -use crate::common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind}; +use crate::common::{CompileFail, Pretty, RunFail, RunPassValgrind}; use crate::common::{Config, TestPaths}; use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly}; use diff; @@ -35,6 +35,9 @@ use log::*; use crate::extract_gdb_version; use crate::is_android_gdb_target; +#[cfg(test)] +mod tests; + #[cfg(windows)] fn disable_error_reporting R, R>(f: F) -> R { use std::sync::Mutex; @@ -260,7 +263,7 @@ pub fn compute_stamp_hash(config: &Config) -> String { env::var_os("PYTHONPATH").hash(&mut hash); } - if let Ui | RunPass | Incremental | Pretty = config.mode { + if let Ui | Incremental | Pretty = config.mode { config.force_pass_mode.hash(&mut hash); } @@ -306,7 +309,7 @@ impl<'test> TestCx<'test> { CodegenUnits => self.run_codegen_units_test(), Incremental => self.run_incremental_test(), RunMake => self.run_rmake_test(), - RunPass | Ui => self.run_ui_test(), + Ui => self.run_ui_test(), MirOpt => self.run_mir_opt_test(), Assembly => self.run_assembly_test(), JsDocTest => self.run_js_doc_test(), @@ -318,8 +321,9 @@ impl<'test> TestCx<'test> { } fn should_run_successfully(&self) -> bool { + let pass_mode = self.pass_mode(); match self.config.mode { - RunPass | Ui => self.pass_mode() == Some(PassMode::Run), + Ui => pass_mode == Some(PassMode::Run), mode => panic!("unimplemented for mode {:?}", mode), } } @@ -327,7 +331,6 @@ impl<'test> TestCx<'test> { fn should_compile_successfully(&self) -> bool { match self.config.mode { CompileFail => false, - RunPass => true, JsDocTest => true, Ui => self.pass_mode().is_some(), Incremental => { @@ -1525,7 +1528,7 @@ impl<'test> TestCx<'test> { fn compile_test(&self) -> ProcRes { // Only use `make_exe_name` when the test ends up being executed. let will_execute = match self.config.mode { - RunPass | Ui => self.should_run_successfully(), + Ui => self.should_run_successfully(), Incremental => self.revision.unwrap().starts_with("r"), RunFail | RunPassValgrind | MirOpt | DebugInfoCdb | DebugInfoGdbLldb | DebugInfoGdb | DebugInfoLldb => true, @@ -1653,6 +1656,18 @@ impl<'test> TestCx<'test> { None, ) } + _ if self.config.target.contains("vxworks") => { + let aux_dir = self.aux_output_dir_name(); + let ProcArgs { prog, args } = self.make_run_args(); + let mut vx_run = Command::new("vx-run"); + vx_run.args(&[&prog]).args(args).envs(env.clone()); + self.compose_and_run( + vx_run, + self.config.run_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + None, + ) + } _ => { let aux_dir = self.aux_output_dir_name(); let ProcArgs { prog, args } = self.make_run_args(); @@ -1944,7 +1959,7 @@ impl<'test> TestCx<'test> { rustc.arg("-Zui-testing"); } } - RunPass | Ui => { + Ui => { if !self .props .compile_flags @@ -2077,7 +2092,7 @@ impl<'test> TestCx<'test> { } let src = self.config.src_base - .parent().unwrap() // chop off `run-pass` + .parent().unwrap() // chop off `ui` .parent().unwrap() // chop off `test` .parent().unwrap(); // chop off `src` args.push(src.join("src/etc/wasm32-shim.js").display().to_string()); @@ -3694,68 +3709,3 @@ fn read2_abbreviated(mut child: Child) -> io::Result { stderr: stderr.into_bytes(), }) } - -#[cfg(test)] -mod tests { - use super::TestCx; - - #[test] - fn normalize_platform_differences() { - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\foo.rs"), - "$DIR/foo.rs" - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$BUILD_DIR\..\parser.rs"), - "$BUILD_DIR/../parser.rs" - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"), - r"$DIR/bar.rs hello\nworld" - ); - assert_eq!( - TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"), - r"either bar/baz.rs or bar/baz/mod.rs", - ); - assert_eq!( - TestCx::normalize_platform_differences(r"`.\some\path.rs`"), - r"`./some/path.rs`", - ); - assert_eq!( - TestCx::normalize_platform_differences(r"`some\path.rs`"), - r"`some/path.rs`", - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\path-with-dashes.rs"), - r"$DIR/path-with-dashes.rs" - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\path_with_underscores.rs"), - r"$DIR/path_with_underscores.rs", - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11", - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"), - "$DIR/path with spaces 'n' quotes", - ); - assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"), - "$DIR/file_with/no_extension", - ); - - assert_eq!(TestCx::normalize_platform_differences(r"\n"), r"\n"); - assert_eq!(TestCx::normalize_platform_differences(r"{ \n"), r"{ \n"); - assert_eq!(TestCx::normalize_platform_differences(r"`\]`"), r"`\]`"); - assert_eq!(TestCx::normalize_platform_differences(r#""\{""#), r#""\{""#); - assert_eq!( - TestCx::normalize_platform_differences(r#"write!(&mut v, "Hello\n")"#), - r#"write!(&mut v, "Hello\n")"# - ); - assert_eq!( - TestCx::normalize_platform_differences(r#"println!("test\ntest")"#), - r#"println!("test\ntest")"#, - ); - } -} diff --git a/src/tools/compiletest/src/runtest/tests.rs b/src/tools/compiletest/src/runtest/tests.rs new file mode 100644 index 0000000000..79128aa9c6 --- /dev/null +++ b/src/tools/compiletest/src/runtest/tests.rs @@ -0,0 +1,61 @@ +use super::*; + +#[test] +fn normalize_platform_differences() { + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\foo.rs"), + "$DIR/foo.rs" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$BUILD_DIR\..\parser.rs"), + "$BUILD_DIR/../parser.rs" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"), + r"$DIR/bar.rs hello\nworld" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"), + r"either bar/baz.rs or bar/baz/mod.rs", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"`.\some\path.rs`"), + r"`./some/path.rs`", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"`some\path.rs`"), + r"`some/path.rs`", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\path-with-dashes.rs"), + r"$DIR/path-with-dashes.rs" + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\path_with_underscores.rs"), + r"$DIR/path_with_underscores.rs", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"), + "$DIR/path with spaces 'n' quotes", + ); + assert_eq!( + TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"), + "$DIR/file_with/no_extension", + ); + + assert_eq!(TestCx::normalize_platform_differences(r"\n"), r"\n"); + assert_eq!(TestCx::normalize_platform_differences(r"{ \n"), r"{ \n"); + assert_eq!(TestCx::normalize_platform_differences(r"`\]`"), r"`\]`"); + assert_eq!(TestCx::normalize_platform_differences(r#""\{""#), r#""\{""#); + assert_eq!( + TestCx::normalize_platform_differences(r#"write!(&mut v, "Hello\n")"#), + r#"write!(&mut v, "Hello\n")"# + ); + assert_eq!( + TestCx::normalize_platform_differences(r#"println!("test\ntest")"#), + r#"println!("test\ntest")"#, + ); +} diff --git a/src/tools/compiletest/src/tests.rs b/src/tools/compiletest/src/tests.rs new file mode 100644 index 0000000000..388ad75757 --- /dev/null +++ b/src/tools/compiletest/src/tests.rs @@ -0,0 +1,51 @@ +use super::*; + +#[test] +fn test_extract_gdb_version() { + macro_rules! test { ($($expectation:tt: $input:tt,)*) => {{$( + assert_eq!(extract_gdb_version($input), Some($expectation)); + )*}}} + + test! { + 7000001: "GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)", + + 7002000: "GNU gdb (GDB) Red Hat Enterprise Linux (7.2-90.el6)", + + 7004000: "GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04", + 7004001: "GNU gdb (GDB) 7.4.1-debian", + + 7006001: "GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7", + + 7007001: "GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1", + 7007001: "GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1", + 7007001: "GNU gdb (GDB) Fedora 7.7.1-21.fc20", + + 7008000: "GNU gdb (GDB; openSUSE 13.2) 7.8", + 7009001: "GNU gdb (GDB) Fedora 7.9.1-20.fc22", + 7010001: "GNU gdb (GDB) Fedora 7.10.1-31.fc23", + + 7011000: "GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11", + 7011001: "GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1", + 7011001: "GNU gdb (Debian 7.11.1-2) 7.11.1", + 7011001: "GNU gdb (GDB) Fedora 7.11.1-86.fc24", + 7011001: "GNU gdb (GDB; openSUSE Leap 42.1) 7.11.1", + 7011001: "GNU gdb (GDB; openSUSE Tumbleweed) 7.11.1", + + 7011090: "7.11.90", + 7011090: "GNU gdb (Ubuntu 7.11.90.20161005-0ubuntu1) 7.11.90.20161005-git", + + 7012000: "7.12", + 7012000: "GNU gdb (GDB) 7.12", + 7012000: "GNU gdb (GDB) 7.12.20161027-git", + 7012050: "GNU gdb (GDB) 7.12.50.20161027-git", + } +} + +#[test] +fn is_test_test() { + assert_eq!(true, is_test(&OsString::from("a_test.rs"))); + assert_eq!(false, is_test(&OsString::from(".a_test.rs"))); + assert_eq!(false, is_test(&OsString::from("a_cat.gif"))); + assert_eq!(false, is_test(&OsString::from("#a_dog_gif"))); + assert_eq!(false, is_test(&OsString::from("~a_temp_file"))); +} diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 8caf5ca00f..56ebea7c20 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -5,6 +5,9 @@ use crate::common::Config; use log::*; +#[cfg(test)] +mod tests; + /// Conversion table from triple OS name to Rust SYSNAME const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("android", "android"), @@ -30,6 +33,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("solaris", "solaris"), ("win32", "windows"), ("windows", "windows"), + ("vxworks", "vxworks"), ]; const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ @@ -156,34 +160,3 @@ impl PathBufExt for PathBuf { } } } - -#[test] -#[should_panic(expected = "Cannot determine Architecture from triple")] -fn test_get_arch_failure() { - get_arch("abc"); -} - -#[test] -fn test_get_arch() { - assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu")); - assert_eq!("x86_64", get_arch("amd64")); - assert_eq!("nvptx64", get_arch("nvptx64-nvidia-cuda")); -} - -#[test] -#[should_panic(expected = "Cannot determine OS from triple")] -fn test_matches_os_failure() { - matches_os("abc", "abc"); -} - -#[test] -fn test_matches_os() { - assert!(matches_os("x86_64-unknown-linux-gnu", "linux")); - assert!(matches_os("wasm32-unknown-unknown", "emscripten")); - assert!(matches_os("wasm32-unknown-unknown", "wasm32-bare")); - assert!(!matches_os("wasm32-unknown-unknown", "windows")); - assert!(matches_os("thumbv6m0-none-eabi", "none")); - assert!(matches_os("riscv32imc-unknown-none-elf", "none")); - assert!(matches_os("nvptx64-nvidia-cuda", "cuda")); - assert!(matches_os("x86_64-fortanix-unknown-sgx", "sgx")); -} diff --git a/src/tools/compiletest/src/util/tests.rs b/src/tools/compiletest/src/util/tests.rs new file mode 100644 index 0000000000..55bf659ba2 --- /dev/null +++ b/src/tools/compiletest/src/util/tests.rs @@ -0,0 +1,32 @@ +use super::*; + +#[test] +#[should_panic(expected = "Cannot determine Architecture from triple")] +fn test_get_arch_failure() { + get_arch("abc"); +} + +#[test] +fn test_get_arch() { + assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu")); + assert_eq!("x86_64", get_arch("amd64")); + assert_eq!("nvptx64", get_arch("nvptx64-nvidia-cuda")); +} + +#[test] +#[should_panic(expected = "Cannot determine OS from triple")] +fn test_matches_os_failure() { + matches_os("abc", "abc"); +} + +#[test] +fn test_matches_os() { + assert!(matches_os("x86_64-unknown-linux-gnu", "linux")); + assert!(matches_os("wasm32-unknown-unknown", "emscripten")); + assert!(matches_os("wasm32-unknown-unknown", "wasm32-bare")); + assert!(!matches_os("wasm32-unknown-unknown", "windows")); + assert!(matches_os("thumbv6m0-none-eabi", "none")); + assert!(matches_os("riscv32imc-unknown-none-elf", "none")); + assert!(matches_os("nvptx64-nvidia-cuda", "cuda")); + assert!(matches_os("x86_64-fortanix-unknown-sgx", "sgx")); +} diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 3e7c7ab637..a9d1d9997f 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -1,7 +1,5 @@ #![feature(rustc_private)] -#![deny(rust_2018_idioms)] - extern crate env_logger; extern crate syntax; extern crate serialize as rustc_serialize; @@ -18,7 +16,7 @@ use std::cell::RefCell; use syntax::edition::DEFAULT_EDITION; use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata}; -use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, PLAYGROUND}; +use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground}; use rustc_serialize::json; enum OutputFormat { @@ -97,9 +95,13 @@ impl Formatter for HTMLFormatter { match info.description { Some(ref desc) => { let mut id_map = self.0.borrow_mut(); + let playground = Playground { + crate_name: None, + url: String::from("https://play.rust-lang.org/"), + }; write!(output, "{}", - Markdown(desc, &[], RefCell::new(&mut id_map), - ErrorCodes::Yes, DEFAULT_EDITION))? + Markdown(desc, &[], &mut id_map, + ErrorCodes::Yes, DEFAULT_EDITION, &Some(playground)).to_string())? }, None => write!(output, "

    No description.

    \n")?, } @@ -262,9 +264,6 @@ fn parse_args() -> (OutputFormat, PathBuf) { fn main() { env_logger::init(); - PLAYGROUND.with(|slot| { - *slot.borrow_mut() = Some((None, String::from("https://play.rust-lang.org/"))); - }); let (format, dst) = parse_args(); let result = syntax::with_default_globals(move || { main_with_result(format, &dst) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index e2bcd4d40a..49c149afe1 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -14,8 +14,6 @@ //! A few whitelisted exceptions are allowed as there's known bugs in rustdoc, //! but this should catch the majority of "broken link" cases. -#![deny(rust_2018_idioms)] - use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::env; diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index d5dff1dcae..b8dcba3afc 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -1,6 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +## This script publishes the new "current" toolstate in the toolstate repo (not to be +## confused with publishing the test results, which happens in +## `src/ci/docker/x86_64-gnu-tools/checktools.sh`). +## It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts +## when a new commit lands on `master` (i.e., after it passed all checks on `auto`). + import sys import re import os @@ -28,6 +34,7 @@ MAINTAINERS = { '@ryankurte @thejpster @therealprof' ), 'edition-guide': '@ehuss @Centril @steveklabnik', + 'rustc-guide': '@mark-i-m @spastorino' } REPOS = { @@ -41,6 +48,7 @@ REPOS = { 'rust-by-example': 'https://github.com/rust-lang/rust-by-example', 'embedded-book': 'https://github.com/rust-embedded/book', 'edition-guide': 'https://github.com/rust-lang-nursery/edition-guide', + 'rustc-guide': 'https://github.com/rust-lang/rustc-guide', } diff --git a/src/tools/rust-installer/.travis.yml b/src/tools/rust-installer/.travis.yml index 0bb81f77c8..8a58eb067c 100644 --- a/src/tools/rust-installer/.travis.yml +++ b/src/tools/rust-installer/.travis.yml @@ -4,5 +4,6 @@ rust: - beta - nightly script: + - export LZMA_API_STATIC=1 - cargo build - ./test.sh diff --git a/src/tools/rust-installer/Cargo.toml b/src/tools/rust-installer/Cargo.toml index 8626211b08..37dcbb5192 100644 --- a/src/tools/rust-installer/Cargo.toml +++ b/src/tools/rust-installer/Cargo.toml @@ -10,12 +10,14 @@ name = "fabricate" path = "src/main.rs" [dependencies] -error-chain = "0.12.0" +failure = "0.1" flate2 = "1.0.1" rayon = "1.0" tar = "0.4.13" walkdir = "2" xz2 = "0.1.4" +num_cpus = "1" +remove_dir_all = "0.5" [dependencies.clap] features = ["yaml"] diff --git a/src/tools/rust-installer/src/combiner.rs b/src/tools/rust-installer/src/combiner.rs index 222e62c869..35f3560dd7 100644 --- a/src/tools/rust-installer/src/combiner.rs +++ b/src/tools/rust-installer/src/combiner.rs @@ -1,57 +1,47 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::io::{Read, Write}; -use std::path::Path; -use flate2::read::GzDecoder; -use tar::Archive; - -use crate::errors::*; use super::Scripter; use super::Tarballer; use crate::util::*; +use crate::Result; +use failure::{bail, ResultExt}; +use flate2::read::GzDecoder; +use std::io::{Read, Write}; +use std::path::Path; +use tar::Archive; -actor!{ +actor! { #[derive(Debug)] pub struct Combiner { - /// The name of the product, for display + /// The name of the product, for display. product_name: String = "Product", - /// The name of the package, tarball + /// The name of the package tarball. package_name: String = "package", - /// The directory under lib/ where the manifest lives + /// The directory under lib/ where the manifest lives. rel_manifest_dir: String = "packagelib", - /// The string to print after successful installation + /// The string to print after successful installation. success_message: String = "Installed.", - /// Places to look for legacy manifests to uninstall + /// Places to look for legacy manifests to uninstall. legacy_manifest_dirs: String = "", - /// Installers to combine + /// Installers to combine. input_tarballs: String = "", - /// Directory containing files that should not be installed + /// Directory containing files that should not be installed. non_installed_overlay: String = "", - /// The directory to do temporary work + /// The directory to do temporary work. work_dir: String = "./workdir", - /// The location to put the final image and tarball + /// The location to put the final image and tarball. output_dir: String = "./dist", } } impl Combiner { - /// Combine the installer tarballs + /// Combines the installer tarballs. pub fn run(self) -> Result<()> { create_dir_all(&self.work_dir)?; @@ -61,73 +51,87 @@ impl Combiner { } create_dir_all(&package_dir)?; - // Merge each installer into the work directory of the new installer + // Merge each installer into the work directory of the new installer. let components = create_new_file(package_dir.join("components"))?; - for input_tarball in self.input_tarballs.split(',').map(str::trim).filter(|s| !s.is_empty()) { + for input_tarball in self + .input_tarballs + .split(',') + .map(str::trim) + .filter(|s| !s.is_empty()) + { // Extract the input tarballs let tar = GzDecoder::new(open_file(&input_tarball)?); - Archive::new(tar).unpack(&self.work_dir) - .chain_err(|| format!("unable to extract '{}' into '{}'", - &input_tarball, self.work_dir))?; + Archive::new(tar).unpack(&self.work_dir).with_context(|_| { + format!( + "unable to extract '{}' into '{}'", + &input_tarball, self.work_dir + ) + })?; let pkg_name = input_tarball.trim_end_matches(".tar.gz"); let pkg_name = Path::new(pkg_name).file_name().unwrap(); let pkg_dir = Path::new(&self.work_dir).join(&pkg_name); - // Verify the version number + // Verify the version number. let mut version = String::new(); open_file(pkg_dir.join("rust-installer-version")) - .and_then(|mut file| file.read_to_string(&mut version).map_err(Error::from)) - .chain_err(|| format!("failed to read version in '{}'", input_tarball))?; + .and_then(|mut file| Ok(file.read_to_string(&mut version)?)) + .with_context(|_| format!("failed to read version in '{}'", input_tarball))?; if version.trim().parse() != Ok(crate::RUST_INSTALLER_VERSION) { bail!("incorrect installer version in {}", input_tarball); } - // Copy components to the new combined installer + // Copy components to the new combined installer. let mut pkg_components = String::new(); open_file(pkg_dir.join("components")) - .and_then(|mut file| file.read_to_string(&mut pkg_components).map_err(Error::from)) - .chain_err(|| format!("failed to read components in '{}'", input_tarball))?; + .and_then(|mut file| Ok(file.read_to_string(&mut pkg_components)?)) + .with_context(|_| format!("failed to read components in '{}'", input_tarball))?; for component in pkg_components.split_whitespace() { - // All we need to do is copy the component directory. We could + // All we need to do is copy the component directory. We could // move it, but rustbuild wants to reuse the unpacked package // dir for OS-specific installers on macOS and Windows. let component_dir = package_dir.join(&component); create_dir(&component_dir)?; copy_recursive(&pkg_dir.join(&component), &component_dir)?; - // Merge the component name + // Merge the component name. writeln!(&components, "{}", component) - .chain_err(|| "failed to write new components")?; + .with_context(|_| "failed to write new components")?; } } drop(components); - // Write the installer version + // Write the installer version. let version = package_dir.join("rust-installer-version"); - writeln!(create_new_file(version)?, "{}", crate::RUST_INSTALLER_VERSION) - .chain_err(|| "failed to write new installer version")?; - - // Copy the overlay + writeln!( + create_new_file(version)?, + "{}", + crate::RUST_INSTALLER_VERSION + ) + .with_context(|_| "failed to write new installer version")?; + + // Copy the overlay. if !self.non_installed_overlay.is_empty() { copy_recursive(self.non_installed_overlay.as_ref(), &package_dir)?; } - // Generate the install script + // Generate the install script. let output_script = package_dir.join("install.sh"); let mut scripter = Scripter::default(); - scripter.product_name(self.product_name) + scripter + .product_name(self.product_name) .rel_manifest_dir(self.rel_manifest_dir) .success_message(self.success_message) .legacy_manifest_dirs(self.legacy_manifest_dirs) .output_script(path_to_str(&output_script)?); scripter.run()?; - // Make the tarballs + // Make the tarballs. create_dir_all(&self.output_dir)?; let output = Path::new(&self.output_dir).join(&self.package_name); let mut tarballer = Tarballer::default(); - tarballer.work_dir(self.work_dir) + tarballer + .work_dir(self.work_dir) .input(self.package_name) .output(path_to_str(&output)?); tarballer.run()?; diff --git a/src/tools/rust-installer/src/generator.rs b/src/tools/rust-installer/src/generator.rs index 90d647e655..3b4b0d4aac 100644 --- a/src/tools/rust-installer/src/generator.rs +++ b/src/tools/rust-installer/src/generator.rs @@ -1,22 +1,12 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::io::Write; -use std::path::Path; - -use crate::errors::*; use super::Scripter; use super::Tarballer; use crate::util::*; +use crate::Result; +use failure::{format_err, bail, ResultExt}; +use std::io::Write; +use std::path::Path; -actor!{ +actor! { #[derive(Debug)] pub struct Generator { /// The name of the product, for display @@ -55,7 +45,7 @@ actor!{ } impl Generator { - /// Generate the actual installer tarball + /// Generates the actual installer tarball pub fn run(self) -> Result<()> { create_dir_all(&self.work_dir)?; @@ -72,12 +62,16 @@ impl Generator { // Write the component name let components = package_dir.join("components"); writeln!(create_new_file(components)?, "{}", self.component_name) - .chain_err(|| "failed to write the component file")?; + .with_context(|_| "failed to write the component file")?; // Write the installer version (only used by combine-installers.sh) let version = package_dir.join("rust-installer-version"); - writeln!(create_new_file(version)?, "{}", crate::RUST_INSTALLER_VERSION) - .chain_err(|| "failed to write new installer version")?; + writeln!( + create_new_file(version)?, + "{}", + crate::RUST_INSTALLER_VERSION + ) + .with_context(|_| "failed to write new installer version")?; // Copy the overlay if !self.non_installed_overlay.is_empty() { @@ -87,7 +81,8 @@ impl Generator { // Generate the install script let output_script = package_dir.join("install.sh"); let mut scripter = Scripter::default(); - scripter.product_name(self.product_name) + scripter + .product_name(self.product_name) .rel_manifest_dir(self.rel_manifest_dir) .success_message(self.success_message) .legacy_manifest_dirs(self.legacy_manifest_dirs) @@ -98,7 +93,8 @@ impl Generator { create_dir_all(&self.output_dir)?; let output = Path::new(&self.output_dir).join(&self.package_name); let mut tarballer = Tarballer::default(); - tarballer.work_dir(self.work_dir) + tarballer + .work_dir(self.work_dir) .input(self.package_name) .output(path_to_str(&output)?); tarballer.run()?; @@ -110,20 +106,32 @@ impl Generator { /// Copies the `src` directory recursively to `dst`, writing `manifest.in` too. fn copy_and_manifest(src: &Path, dst: &Path, bulk_dirs: &str) -> Result<()> { let manifest = create_new_file(dst.join("manifest.in"))?; - let bulk_dirs: Vec<_> = bulk_dirs.split(',') + let bulk_dirs: Vec<_> = bulk_dirs + .split(',') .filter(|s| !s.is_empty()) - .map(Path::new).collect(); + .map(Path::new) + .collect(); copy_with_callback(src, dst, |path, file_type| { // We need paths to be compatible with both Unix and Windows. - if path.components().filter_map(|c| c.as_os_str().to_str()).any(|s| s.contains('\\')) { - bail!("rust-installer doesn't support '\\' in path components: {:?}", path); + if path + .components() + .filter_map(|c| c.as_os_str().to_str()) + .any(|s| s.contains('\\')) + { + bail!( + "rust-installer doesn't support '\\' in path components: {:?}", + path + ); } // Normalize to Unix-style path separators. let normalized_string; let mut string = path.to_str().ok_or_else(|| { - format!("rust-installer doesn't support non-Unicode paths: {:?}", path) + format_err!( + "rust-installer doesn't support non-Unicode paths: {:?}", + path + ) })?; if string.contains('\\') { normalized_string = string.replace('\\', "/"); diff --git a/src/tools/rust-installer/src/lib.rs b/src/tools/rust-installer/src/lib.rs index af302f1205..0310aba41d 100644 --- a/src/tools/rust-installer/src/lib.rs +++ b/src/tools/rust-installer/src/lib.rs @@ -1,44 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[macro_use] -extern crate error_chain; - -#[cfg(windows)] -extern crate winapi; -#[cfg(windows)] -#[macro_use] -extern crate lazy_static; - -mod errors { - error_chain!{ - foreign_links { - Io(::std::io::Error); - StripPrefix(::std::path::StripPrefixError); - WalkDir(::walkdir::Error); - } - } -} +pub type Result = std::result::Result; #[macro_use] mod util; -// deal with OS complications (cribbed from rustup.rs) -mod remove_dir_all; - mod combiner; mod generator; mod scripter; mod tarballer; -pub use crate::errors::{Result, Error, ErrorKind}; pub use crate::combiner::Combiner; pub use crate::generator::Generator; pub use crate::scripter::Scripter; diff --git a/src/tools/rust-installer/src/main.rs b/src/tools/rust-installer/src/main.rs index bc6025c12d..90f1602c5d 100644 --- a/src/tools/rust-installer/src/main.rs +++ b/src/tools/rust-installer/src/main.rs @@ -1,24 +1,9 @@ -#[macro_use] -extern crate clap; -#[macro_use] -extern crate error_chain; -use installer; - -use crate::errors::*; use clap::{App, ArgMatches}; +use failure::ResultExt; +use installer::Result; -mod errors { - error_chain!{ - links { - Installer(::installer::Error, ::installer::ErrorKind); - } - } -} - -quick_main!(run); - -fn run() -> Result<()> { - let yaml = load_yaml!("main.yml"); +fn main() -> Result<()> { + let yaml = clap::load_yaml!("main.yml"); let matches = App::from_yaml(yaml).get_matches(); match matches.subcommand() { @@ -54,7 +39,10 @@ fn combine(matches: &ArgMatches<'_>) -> Result<()> { "output-dir" => output_dir, }); - combiner.run().chain_err(|| "failed to combine installers") + combiner + .run() + .with_context(|_| "failed to combine installers")?; + Ok(()) } fn generate(matches: &ArgMatches<'_>) -> Result<()> { @@ -72,7 +60,10 @@ fn generate(matches: &ArgMatches<'_>) -> Result<()> { "output-dir" => output_dir, }); - generator.run().chain_err(|| "failed to generate installer") + generator + .run() + .with_context(|_| "failed to generate installer")?; + Ok(()) } fn script(matches: &ArgMatches<'_>) -> Result<()> { @@ -84,7 +75,10 @@ fn script(matches: &ArgMatches<'_>) -> Result<()> { "output-script" => output_script, }); - scripter.run().chain_err(|| "failed to generate installation script") + scripter + .run() + .with_context(|_| "failed to generate installation script")?; + Ok(()) } fn tarball(matches: &ArgMatches<'_>) -> Result<()> { @@ -94,5 +88,8 @@ fn tarball(matches: &ArgMatches<'_>) -> Result<()> { "work-dir" => work_dir, }); - tarballer.run().chain_err(|| "failed to generate tarballs") + tarballer + .run() + .with_context(|_| "failed to generate tarballs")?; + Ok(()) } diff --git a/src/tools/rust-installer/src/remove_dir_all.rs b/src/tools/rust-installer/src/remove_dir_all.rs index 202ac36775..1109765286 100644 --- a/src/tools/rust-installer/src/remove_dir_all.rs +++ b/src/tools/rust-installer/src/remove_dir_all.rs @@ -1,17 +1,7 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #![allow(non_snake_case)] -use std::path::Path; use std::io; +use std::path::Path; #[cfg(not(windows))] pub fn remove_dir_all(path: &Path) -> io::Result<()> { @@ -25,35 +15,43 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> { #[cfg(windows)] mod win { - use winapi::ctypes::{c_ushort, c_uint}; + use winapi::ctypes::{c_uint, c_ushort}; use winapi::shared::minwindef::{BOOL, DWORD, FALSE, FILETIME, LPVOID}; - use winapi::shared::winerror::{ERROR_CALL_NOT_IMPLEMENTED, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_MORE_FILES}; + use winapi::shared::winerror::{ + ERROR_CALL_NOT_IMPLEMENTED, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_MORE_FILES, + }; use winapi::um::errhandlingapi::{GetLastError, SetLastError}; + use winapi::um::fileapi::{ + CreateFileW, FindFirstFileW, FindNextFileW, GetFileInformationByHandle, + }; use winapi::um::fileapi::{BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW}; use winapi::um::fileapi::{FILE_BASIC_INFO, FILE_RENAME_INFO, TRUNCATE_EXISTING}; use winapi::um::fileapi::{OPEN_ALWAYS, OPEN_EXISTING}; - use winapi::um::fileapi::{CreateFileW, GetFileInformationByHandle, FindFirstFileW, FindNextFileW}; use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE}; use winapi::um::ioapiset::DeviceIoControl; - use winapi::um::libloaderapi::{GetProcAddress, GetModuleHandleW}; - use winapi::um::minwinbase::{FileBasicInfo, FileRenameInfo, FILE_INFO_BY_HANDLE_CLASS, WIN32_FIND_DATAW}; - use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_DELETE_ON_CLOSE, FILE_FLAG_OPEN_REPARSE_POINT}; + use winapi::um::libloaderapi::{GetModuleHandleW, GetProcAddress}; + use winapi::um::minwinbase::{ + FileBasicInfo, FileRenameInfo, FILE_INFO_BY_HANDLE_CLASS, WIN32_FIND_DATAW, + }; use winapi::um::winbase::SECURITY_SQOS_PRESENT; + use winapi::um::winbase::{ + FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_DELETE_ON_CLOSE, FILE_FLAG_OPEN_REPARSE_POINT, + }; use winapi::um::winioctl::FSCTL_GET_REPARSE_POINT; - use winapi::um::winnt::{FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_READONLY}; + use winapi::um::winnt::{DELETE, FILE_ATTRIBUTE_DIRECTORY, HANDLE, LPCWSTR}; + use winapi::um::winnt::{FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_REPARSE_POINT}; + use winapi::um::winnt::{FILE_GENERIC_WRITE, FILE_WRITE_DATA, GENERIC_READ, GENERIC_WRITE}; + use winapi::um::winnt::{FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES}; use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE}; - use winapi::um::winnt::{FILE_WRITE_ATTRIBUTES, FILE_READ_ATTRIBUTES}; - use winapi::um::winnt::{FILE_WRITE_DATA, FILE_GENERIC_WRITE, GENERIC_READ, GENERIC_WRITE}; - use winapi::um::winnt::{LARGE_INTEGER, IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK}; - use winapi::um::winnt::{LPCWSTR, DELETE, FILE_ATTRIBUTE_DIRECTORY, HANDLE}; + use winapi::um::winnt::{IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK, LARGE_INTEGER}; - use std::ptr; - use std::sync::Arc; - use std::path::{PathBuf, Path}; - use std::mem; - use std::io; use std::ffi::{OsStr, OsString}; + use std::io; + use std::mem; use std::os::windows::ffi::{OsStrExt, OsStringExt}; + use std::path::{Path, PathBuf}; + use std::ptr; + use std::sync::Arc; pub fn remove_dir_all(path: &Path) -> io::Result<()> { // On Windows it is not enough to just recursively remove the contents of a @@ -67,7 +65,7 @@ mod win { // already need write permission in this dir to delete the directory. And it // should be on the same volume. // - // To handle files with names like `CON` and `morse .. .`, and when a + // To handle files with names like `CON` and `morse .. .`, and when a // directory structure is so deep it needs long path names the path is first // converted to a `//?/`-path with `get_path()`. // @@ -101,17 +99,20 @@ mod win { let (path, metadata) = { let mut opts = OpenOptions::new(); opts.access_mode(FILE_READ_ATTRIBUTES); - opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT); - let file = r#try!(File::open(path, &opts)); - (r#try!(get_path(&file)), r#try!(file.file_attr())) + opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT); + let file = File::open(path, &opts)?; + (get_path(&file)?, file.file_attr()?) }; let mut ctx = RmdirContext { base_dir: match path.parent() { Some(dir) => dir, - None => return Err(io::Error::new(io::ErrorKind::PermissionDenied, - "can't delete root directory")) + None => { + return Err(io::Error::new( + io::ErrorKind::PermissionDenied, + "can't delete root directory", + )) + } }, readonly: metadata.perm().readonly(), counter: 0, @@ -123,15 +124,17 @@ mod win { } else if filetype.is_symlink_dir() { remove_item(path.as_ref(), &mut ctx) } else { - Err(io::Error::new(io::ErrorKind::PermissionDenied, "Not a directory")) + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + "Not a directory", + )) } } - fn readdir(p: &Path) -> io::Result { let root = p.to_path_buf(); let star = p.join("*"); - let path = r#try!(to_u16s(&star)); + let path = to_u16s(&star)?; unsafe { let mut wfd = mem::zeroed(); @@ -154,17 +157,16 @@ mod win { counter: u64, } - fn remove_dir_all_recursive(path: &Path, ctx: &mut RmdirContext) - -> io::Result<()> { + fn remove_dir_all_recursive(path: &Path, ctx: &mut RmdirContext) -> io::Result<()> { let dir_readonly = ctx.readonly; - for child in r#try!(readdir(path)) { - let child = r#try!(child); - let child_type = r#try!(child.file_type()); - ctx.readonly = r#try!(child.metadata()).perm().readonly(); + for child in readdir(path)? { + let child = child?; + let child_type = child.file_type()?; + ctx.readonly = child.metadata()?.perm().readonly(); if child_type.is_dir() { - r#try!(remove_dir_all_recursive(&child.path(), ctx)); + remove_dir_all_recursive(&child.path(), ctx)?; } else { - r#try!(remove_item(&child.path().as_ref(), ctx)); + remove_item(&child.path().as_ref(), ctx)?; } } ctx.readonly = dir_readonly; @@ -175,23 +177,27 @@ mod win { if !ctx.readonly { let mut opts = OpenOptions::new(); opts.access_mode(DELETE); - opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | // delete directory + opts.custom_flags( + FILE_FLAG_BACKUP_SEMANTICS | // delete directory FILE_FLAG_OPEN_REPARSE_POINT | // delete symlink - FILE_FLAG_DELETE_ON_CLOSE); - let file = r#try!(File::open(path, &opts)); + FILE_FLAG_DELETE_ON_CLOSE, + ); + let file = File::open(path, &opts)?; move_item(&file, ctx) } else { // remove read-only permision - r#try!(set_perm(&path, FilePermissions::new())); + set_perm(&path, FilePermissions::new())?; // move and delete file, similar to !readonly. // only the access mode is different. let mut opts = OpenOptions::new(); opts.access_mode(DELETE | FILE_WRITE_ATTRIBUTES); - opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT | - FILE_FLAG_DELETE_ON_CLOSE); - let file = r#try!(File::open(path, &opts)); - r#try!(move_item(&file, ctx)); + opts.custom_flags( + FILE_FLAG_BACKUP_SEMANTICS + | FILE_FLAG_OPEN_REPARSE_POINT + | FILE_FLAG_DELETE_ON_CLOSE, + ); + let file = File::open(path, &opts)?; + move_item(&file, ctx)?; // restore read-only flag just in case there are other hard links let mut perm = FilePermissions::new(); perm.set_readonly(true); @@ -281,8 +287,10 @@ mod win { fn inner(s: &OsStr) -> io::Result> { let mut maybe_result: Vec = s.encode_wide().collect(); if maybe_result.iter().any(|&u| u == 0) { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "strings passed to WinAPI cannot contain NULs")); + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "strings passed to WinAPI cannot contain NULs", + )); } maybe_result.push(0); Ok(maybe_result) @@ -294,13 +302,14 @@ mod win { match v.iter().position(|c| *c == 0) { // don't include the 0 Some(i) => &v[..i], - None => v + None => v, } } fn fill_utf16_buf(mut f1: F1, f2: F2) -> io::Result - where F1: FnMut(*mut u16, DWORD) -> DWORD, - F2: FnOnce(&[u16]) -> T + where + F1: FnMut(*mut u16, DWORD) -> DWORD, + F2: FnOnce(&[u16]) -> T, { // Start off with a stack buf but then spill over to the heap if we end up // needing more space. @@ -338,19 +347,27 @@ mod win { } else if k >= n { n = k; } else { - return Ok(f2(&buf[..k])) + return Ok(f2(&buf[..k])); } } } } #[derive(Clone, PartialEq, Eq, Debug, Default)] - struct FilePermissions { readonly: bool } + struct FilePermissions { + readonly: bool, + } impl FilePermissions { - fn new() -> FilePermissions { Default::default() } - fn readonly(&self) -> bool { self.readonly } - fn set_readonly(&mut self, readonly: bool) { self.readonly = readonly } + fn new() -> FilePermissions { + Default::default() + } + fn readonly(&self) -> bool { + self.readonly + } + fn set_readonly(&mut self, readonly: bool) { + self.readonly = readonly + } } #[derive(Clone)] @@ -390,21 +407,26 @@ mod win { security_attributes: 0, } } - fn custom_flags(&mut self, flags: u32) { self.custom_flags = flags; } - fn access_mode(&mut self, access_mode: u32) { self.access_mode = Some(access_mode); } + fn custom_flags(&mut self, flags: u32) { + self.custom_flags = flags; + } + fn access_mode(&mut self, access_mode: u32) { + self.access_mode = Some(access_mode); + } fn get_access_mode(&self) -> io::Result { const ERROR_INVALID_PARAMETER: i32 = 87; match (self.read, self.write, self.append, self.access_mode) { (_, _, _, Some(mode)) => Ok(mode), - (true, false, false, None) => Ok(GENERIC_READ), - (false, true, false, None) => Ok(GENERIC_WRITE), - (true, true, false, None) => Ok(GENERIC_READ | GENERIC_WRITE), - (false, _, true, None) => Ok(FILE_GENERIC_WRITE & !FILE_WRITE_DATA), - (true, _, true, None) => Ok(GENERIC_READ | - (FILE_GENERIC_WRITE & !FILE_WRITE_DATA)), - (false, false, false, None) => Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)), + (true, false, false, None) => Ok(GENERIC_READ), + (false, true, false, None) => Ok(GENERIC_WRITE), + (true, true, false, None) => Ok(GENERIC_READ | GENERIC_WRITE), + (false, _, true, None) => Ok(FILE_GENERIC_WRITE & !FILE_WRITE_DATA), + (true, _, true, None) => Ok(GENERIC_READ | (FILE_GENERIC_WRITE & !FILE_WRITE_DATA)), + (false, false, false, None) => { + Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)) + } } } @@ -413,60 +435,75 @@ mod win { match (self.write, self.append) { (true, false) => {} - (false, false) => + (false, false) => { if self.truncate || self.create || self.create_new { return Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); - }, - (_, true) => + } + } + (_, true) => { if self.truncate && !self.create_new { return Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); - }, + } + } } Ok(match (self.create, self.truncate, self.create_new) { (false, false, false) => OPEN_EXISTING, - (true, false, false) => OPEN_ALWAYS, - (false, true, false) => TRUNCATE_EXISTING, - (true, true, false) => CREATE_ALWAYS, - (_, _, true) => CREATE_NEW, + (true, false, false) => OPEN_ALWAYS, + (false, true, false) => TRUNCATE_EXISTING, + (true, true, false) => CREATE_ALWAYS, + (_, _, true) => CREATE_NEW, }) } fn get_flags_and_attributes(&self) -> DWORD { - self.custom_flags | - self.attributes | - self.security_qos_flags | - if self.security_qos_flags != 0 { SECURITY_SQOS_PRESENT } else { 0 } | - if self.create_new { FILE_FLAG_OPEN_REPARSE_POINT } else { 0 } + self.custom_flags + | self.attributes + | self.security_qos_flags + | if self.security_qos_flags != 0 { + SECURITY_SQOS_PRESENT + } else { + 0 + } + | if self.create_new { + FILE_FLAG_OPEN_REPARSE_POINT + } else { + 0 + } } } - struct File { handle: Handle } + struct File { + handle: Handle, + } impl File { fn open(path: &Path, opts: &OpenOptions) -> io::Result { - let path = r#try!(to_u16s(path)); + let path = to_u16s(path)?; let handle = unsafe { - CreateFileW(path.as_ptr(), - r#try!(opts.get_access_mode()), - opts.share_mode, - opts.security_attributes as *mut _, - r#try!(opts.get_creation_mode()), - opts.get_flags_and_attributes(), - ptr::null_mut()) + CreateFileW( + path.as_ptr(), + opts.get_access_mode()?, + opts.share_mode, + opts.security_attributes as *mut _, + opts.get_creation_mode()?, + opts.get_flags_and_attributes(), + ptr::null_mut(), + ) }; if handle == INVALID_HANDLE_VALUE { Err(io::Error::last_os_error()) } else { - Ok(File { handle: Handle::new(handle) }) + Ok(File { + handle: Handle::new(handle), + }) } } fn file_attr(&self) -> io::Result { unsafe { let mut info: BY_HANDLE_FILE_INFORMATION = mem::zeroed(); - r#try!(cvt(GetFileInformationByHandle(self.handle.raw(), - &mut info))); + cvt(GetFileInformationByHandle(self.handle.raw(), &mut info))?; let mut attr = FileAttr { attributes: info.dwFileAttributes, creation_time: info.ftCreationTime, @@ -486,24 +523,24 @@ mod win { } fn set_attributes(&self, attr: DWORD) -> io::Result<()> { - let zero: LARGE_INTEGER = unsafe { - mem::zeroed() - }; + let zero: LARGE_INTEGER = unsafe { mem::zeroed() }; let mut info = FILE_BASIC_INFO { - CreationTime: zero, // do not change + CreationTime: zero, // do not change LastAccessTime: zero, // do not change - LastWriteTime: zero, // do not change - ChangeTime: zero, // do not change + LastWriteTime: zero, // do not change + ChangeTime: zero, // do not change FileAttributes: attr, }; let size = mem::size_of_val(&info); - r#try!(cvt(unsafe { - SetFileInformationByHandle(self.handle.raw(), - FileBasicInfo, - &mut info as *mut _ as *mut _, - size as DWORD) - })); + cvt(unsafe { + SetFileInformationByHandle( + self.handle.raw(), + FileBasicInfo, + &mut info as *mut _ as *mut _, + size as DWORD, + ) + })?; Ok(()) } @@ -516,7 +553,8 @@ mod win { const STRUCT_SIZE: usize = 20; // FIXME: check for internal NULs in 'new' - let mut data: Vec = iter::repeat(0u16).take(STRUCT_SIZE/2) + let mut data: Vec = iter::repeat(0u16) + .take(STRUCT_SIZE / 2) .chain(new.as_os_str().encode_wide()) .collect(); data.push(0); @@ -531,15 +569,17 @@ mod win { (*info).ReplaceIfExists = if replace { -1 } else { FALSE }; (*info).RootDirectory = ptr::null_mut(); (*info).FileNameLength = (size - STRUCT_SIZE) as DWORD; - r#try!(cvt(SetFileInformationByHandle(self.handle().raw(), - FileRenameInfo, - data.as_mut_ptr() as *mut _ as *mut _, - size as DWORD))); + cvt(SetFileInformationByHandle( + self.handle().raw(), + FileRenameInfo, + data.as_mut_ptr() as *mut _ as *mut _, + size as DWORD, + ))?; Ok(()) } } fn set_perm(&self, perm: FilePermissions) -> io::Result<()> { - let attr = r#try!(self.file_attr()).attributes; + let attr = self.file_attr()?.attributes; if perm.readonly == (attr & FILE_ATTRIBUTE_READONLY != 0) { Ok(()) } else if perm.readonly { @@ -549,39 +589,50 @@ mod win { } } - fn handle(&self) -> &Handle { &self.handle } + fn handle(&self) -> &Handle { + &self.handle + } - fn reparse_point<'a>(&self, - space: &'a mut [u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE]) - -> io::Result<(DWORD, &'a REPARSE_DATA_BUFFER)> { + fn reparse_point<'a>( + &self, + space: &'a mut [u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE], + ) -> io::Result<(DWORD, &'a REPARSE_DATA_BUFFER)> { unsafe { let mut bytes = 0; - r#try!(cvt({ - DeviceIoControl(self.handle.raw(), - FSCTL_GET_REPARSE_POINT, - ptr::null_mut(), - 0, - space.as_mut_ptr() as *mut _, - space.len() as DWORD, - &mut bytes, - ptr::null_mut()) - })); + cvt({ + DeviceIoControl( + self.handle.raw(), + FSCTL_GET_REPARSE_POINT, + ptr::null_mut(), + 0, + space.as_mut_ptr() as *mut _, + space.len() as DWORD, + &mut bytes, + ptr::null_mut(), + ) + })?; Ok((bytes, &*(space.as_ptr() as *const REPARSE_DATA_BUFFER))) } } } - #[derive(Copy, Clone, PartialEq, Eq, Hash)] enum FileType { - Dir, File, SymlinkFile, SymlinkDir, ReparsePoint, MountPoint, + Dir, + File, + SymlinkFile, + SymlinkDir, + ReparsePoint, + MountPoint, } impl FileType { fn new(attrs: DWORD, reparse_tag: DWORD) -> FileType { - match (attrs & FILE_ATTRIBUTE_DIRECTORY != 0, - attrs & FILE_ATTRIBUTE_REPARSE_POINT != 0, - reparse_tag) { + match ( + attrs & FILE_ATTRIBUTE_DIRECTORY != 0, + attrs & FILE_ATTRIBUTE_REPARSE_POINT != 0, + reparse_tag, + ) { (false, false, _) => FileType::File, (true, false, _) => FileType::Dir, (false, true, IO_REPARSE_TAG_SYMLINK) => FileType::SymlinkFile, @@ -594,7 +645,9 @@ mod win { } } - fn is_dir(&self) -> bool { *self == FileType::Dir } + fn is_dir(&self) -> bool { + *self == FileType::Dir + } fn is_symlink_dir(&self) -> bool { *self == FileType::SymlinkDir || *self == FileType::MountPoint } @@ -623,8 +676,10 @@ mod win { } fn file_type(&self) -> io::Result { - Ok(FileType::new(self.data.dwFileAttributes, - /* reparse_tag = */ self.data.dwReserved0)) + Ok(FileType::new( + self.data.dwFileAttributes, + /* reparse_tag = */ self.data.dwReserved0, + )) } fn metadata(&self) -> io::Result { @@ -633,7 +688,8 @@ mod win { creation_time: self.data.ftCreationTime, last_access_time: self.data.ftLastAccessTime, last_write_time: self.data.ftLastWriteTime, - file_size: ((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64), + file_size: ((self.data.nFileSizeHigh as u64) << 32) + | (self.data.nFileSizeLow as u64), reparse_tag: if self.data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0 { // reserved unless this is a reparse point self.data.dwReserved0 @@ -644,8 +700,6 @@ mod win { } } - - struct DirEntry { root: Arc, data: WIN32_FIND_DATAW, @@ -670,20 +724,19 @@ mod win { loop { if FindNextFileW(self.handle.0, &mut wfd) == 0 { if GetLastError() == ERROR_NO_MORE_FILES { - return None + return None; } else { - return Some(Err(io::Error::last_os_error())) + return Some(Err(io::Error::last_os_error())); } } if let Some(e) = DirEntry::new(&self.root, &wfd) { - return Some(Ok(e)) + return Some(Ok(e)); } } } } } - #[derive(Clone)] struct FileAttr { attributes: DWORD, @@ -697,7 +750,7 @@ mod win { impl FileAttr { fn perm(&self) -> FilePermissions { FilePermissions { - readonly: self.attributes & FILE_ATTRIBUTE_READONLY != 0 + readonly: self.attributes & FILE_ATTRIBUTE_READONLY != 0, } } @@ -720,7 +773,6 @@ mod win { const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; - /// An owned container for `HANDLE` object, closing them on Drop. /// /// All methods are inherited through a `Deref` impl to `RawHandle` @@ -747,12 +799,16 @@ mod win { impl Deref for Handle { type Target = RawHandle; - fn deref(&self) -> &RawHandle { &self.0 } + fn deref(&self) -> &RawHandle { + &self.0 + } } impl Drop for Handle { fn drop(&mut self) { - unsafe { let _ = CloseHandle(self.raw()); } + unsafe { + let _ = CloseHandle(self.raw()); + } } } @@ -761,27 +817,31 @@ mod win { RawHandle(handle) } - fn raw(&self) -> HANDLE { self.0 } + fn raw(&self) -> HANDLE { + self.0 + } } struct FindNextFileHandle(HANDLE); fn get_path(f: &File) -> io::Result { - fill_utf16_buf(|buf, sz| unsafe { - GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, - VOLUME_NAME_DOS) - }, |buf| { - PathBuf::from(OsString::from_wide(buf)) - }) + fill_utf16_buf( + |buf, sz| unsafe { + GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, VOLUME_NAME_DOS) + }, + |buf| PathBuf::from(OsString::from_wide(buf)), + ) } fn move_item(file: &File, ctx: &mut RmdirContext) -> io::Result<()> { - let mut tmpname = ctx.base_dir.join(format!{"rm-{}", ctx.counter}); + let mut tmpname = ctx.base_dir.join(format! {"rm-{}", ctx.counter}); ctx.counter += 1; // Try to rename the file. If it already exists, just retry with an other // filename. while let Err(err) = file.rename(tmpname.as_ref(), false) { - if err.kind() != io::ErrorKind::AlreadyExists { return Err(err) }; + if err.kind() != io::ErrorKind::AlreadyExists { + return Err(err); + }; tmpname = ctx.base_dir.join(format!("rm-{}", ctx.counter)); ctx.counter += 1; } @@ -792,7 +852,7 @@ mod win { let mut opts = OpenOptions::new(); opts.access_mode(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES); opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS); - let file = r#try!(File::open(path, &opts)); + let file = File::open(path, &opts)?; file.set_perm(perm) } diff --git a/src/tools/rust-installer/src/scripter.rs b/src/tools/rust-installer/src/scripter.rs index 3b11efae97..436323052f 100644 --- a/src/tools/rust-installer/src/scripter.rs +++ b/src/tools/rust-installer/src/scripter.rs @@ -1,22 +1,11 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::io::Write; - -use crate::errors::*; +use failure::ResultExt; +use crate::Result; use crate::util::*; const TEMPLATE: &'static str = include_str!("../install-template.sh"); - -actor!{ +actor! { #[derive(Debug)] pub struct Scripter { /// The name of the product, for display @@ -37,26 +26,34 @@ actor!{ } impl Scripter { - /// Generate the actual installer script + /// Generates the actual installer script pub fn run(self) -> Result<()> { // Replace dashes in the success message with spaces (our arg handling botches spaces) - // (TODO: still needed? kept for compatibility for now...) + // TODO: still needed? Kept for compatibility for now. let product_name = self.product_name.replace('-', " "); // Replace dashes in the success message with spaces (our arg handling botches spaces) - // (TODO: still needed? kept for compatibility for now...) + // TODO: still needed? Kept for compatibility for now. let success_message = self.success_message.replace('-', " "); let script = TEMPLATE .replace("%%TEMPLATE_PRODUCT_NAME%%", &sh_quote(&product_name)) .replace("%%TEMPLATE_REL_MANIFEST_DIR%%", &self.rel_manifest_dir) .replace("%%TEMPLATE_SUCCESS_MESSAGE%%", &sh_quote(&success_message)) - .replace("%%TEMPLATE_LEGACY_MANIFEST_DIRS%%", &sh_quote(&self.legacy_manifest_dirs)) - .replace("%%TEMPLATE_RUST_INSTALLER_VERSION%%", &sh_quote(&crate::RUST_INSTALLER_VERSION)); + .replace( + "%%TEMPLATE_LEGACY_MANIFEST_DIRS%%", + &sh_quote(&self.legacy_manifest_dirs), + ) + .replace( + "%%TEMPLATE_RUST_INSTALLER_VERSION%%", + &sh_quote(&crate::RUST_INSTALLER_VERSION), + ); create_new_executable(&self.output_script)? .write_all(script.as_ref()) - .chain_err(|| format!("failed to write output script '{}'", self.output_script)) + .with_context(|_| format!("failed to write output script '{}'", self.output_script))?; + + Ok(()) } } diff --git a/src/tools/rust-installer/src/tarballer.rs b/src/tools/rust-installer/src/tarballer.rs index 03c47294e2..fa6ab2c4ce 100644 --- a/src/tools/rust-installer/src/tarballer.rs +++ b/src/tools/rust-installer/src/tarballer.rs @@ -1,48 +1,36 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - +use failure::{bail, ResultExt}; +use flate2::write::GzEncoder; use std::fs::{read_link, symlink_metadata}; -use std::io::{self, empty, Write, BufWriter}; +use std::io::{self, empty, BufWriter, Write}; use std::path::Path; - -use flate2; -use flate2::write::GzEncoder; -use rayon; use tar::{Builder, Header}; use walkdir::WalkDir; use xz2::write::XzEncoder; -use crate::errors::*; use crate::util::*; +use crate::Result; -actor!{ +actor! { #[derive(Debug)] pub struct Tarballer { - /// The input folder to be compressed + /// The input folder to be compressed. input: String = "package", - /// The prefix of the tarballs + /// The prefix of the tarballs. output: String = "./dist", - /// The folder in which the input is to be found + /// The folder in which the input is to be found. work_dir: String = "./workdir", } } impl Tarballer { - /// Generate the actual tarballs + /// Generates the actual tarballs pub fn run(self) -> Result<()> { let tar_gz = self.output.clone() + ".tar.gz"; let tar_xz = self.output.clone() + ".tar.xz"; - // Remove any existing files + // Remove any existing files. for file in &[&tar_gz, &tar_xz] { if Path::new(file).exists() { remove_file(file)?; @@ -53,43 +41,64 @@ impl Tarballer { // different locations (likely identical) and files with the same // extension (likely containing similar data). let (dirs, mut files) = get_recursive_paths(&self.work_dir, &self.input) - .chain_err(|| "failed to collect file paths")?; + .with_context(|_| "failed to collect file paths")?; files.sort_by(|a, b| a.bytes().rev().cmp(b.bytes().rev())); - // Prepare the .tar.gz file + // Prepare the `.tar.gz` file. let gz = GzEncoder::new(create_new_file(tar_gz)?, flate2::Compression::best()); - // Prepare the .tar.xz file - let xz = XzEncoder::new(create_new_file(tar_xz)?, 6); - - // Write the tar into both encoded files. We write all directories - // first, so files may be directly created. (see rustup.rs#1092) + // Prepare the `.tar.xz` file. Note that preset 6 takes about 173MB of memory + // per thread, so we limit the number of threads to not blow out 32-bit hosts. + // (We could be more precise with `MtStreamBuilder::memusage()` if desired.) + let stream = xz2::stream::MtStreamBuilder::new() + .threads(Ord::min(num_cpus::get(), 8) as u32) + .preset(6) + .encoder()?; + let xz = XzEncoder::new_stream(create_new_file(tar_xz)?, stream); + + // Write the tar into both encoded files. We write all directories + // first, so files may be directly created. (See rust-lang/rustup.rs#1092.) let tee = RayonTee(xz, gz); let buf = BufWriter::with_capacity(1024 * 1024, tee); let mut builder = Builder::new(buf); - let pool = rayon::ThreadPoolBuilder::new().num_threads(2).build().unwrap(); + let pool = rayon::ThreadPoolBuilder::new() + .num_threads(2) + .build() + .unwrap(); pool.install(move || { for path in dirs { let src = Path::new(&self.work_dir).join(&path); - builder.append_dir(&path, &src) - .chain_err(|| format!("failed to tar dir '{}'", src.display()))?; + builder + .append_dir(&path, &src) + .with_context(|_| format!("failed to tar dir '{}'", src.display()))?; } for path in files { let src = Path::new(&self.work_dir).join(&path); append_path(&mut builder, &src, &path) - .chain_err(|| format!("failed to tar file '{}'", src.display()))?; + .with_context(|_| format!("failed to tar file '{}'", src.display()))?; } - let RayonTee(xz, gz) = builder.into_inner() - .chain_err(|| "failed to finish writing .tar stream")? - .into_inner().ok().unwrap(); - - // Finish both encoded files + let RayonTee(xz, gz) = builder + .into_inner() + .with_context(|_| "failed to finish writing .tar stream")? + .into_inner() + .ok() + .unwrap(); + + // Finish both encoded files. let (rxz, rgz) = rayon::join( - || xz.finish().chain_err(|| "failed to finish .tar.xz file"), - || gz.finish().chain_err(|| "failed to finish .tar.gz file"), + || { + xz.finish() + .with_context(|_| "failed to finish .tar.xz file") + }, + || { + gz.finish() + .with_context(|_| "failed to finish .tar.gz file") + }, ); - rxz.and(rgz).and(Ok(())) + rxz?; + rgz?; + Ok(()) }) } } @@ -120,15 +129,21 @@ fn append_path(builder: &mut Builder, src: &Path, path: &String) -> Ok(()) } -/// Returns all `(directories, files)` under the source path +/// Returns all `(directories, files)` under the source path. fn get_recursive_paths(root: P, name: Q) -> Result<(Vec, Vec)> - where P: AsRef, Q: AsRef +where + P: AsRef, + Q: AsRef, { let root = root.as_ref(); let name = name.as_ref(); if !name.is_relative() && !name.starts_with(root) { - bail!("input '{}' is not in work dir '{}'", name.display(), root.display()); + bail!( + "input '{}' is not in work dir '{}'", + name.display(), + root.display() + ); } let mut dirs = vec![]; diff --git a/src/tools/rust-installer/src/util.rs b/src/tools/rust-installer/src/util.rs index 167897324d..868a636205 100644 --- a/src/tools/rust-installer/src/util.rs +++ b/src/tools/rust-installer/src/util.rs @@ -1,14 +1,5 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - +use crate::Result; +use failure::{format_err, ResultExt}; use std::fs; use std::path::Path; use walkdir::WalkDir; @@ -16,78 +7,92 @@ use walkdir::WalkDir; // Needed to set the script mode to executable. #[cfg(unix)] use std::os::unix::fs::OpenOptionsExt; -// FIXME: what about Windows? Are default ACLs executable? +// FIXME: what about Windows? Are default ACLs executable? #[cfg(unix)] use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] use std::os::windows::fs::symlink_file; -use crate::errors::*; - -/// Convert a `&Path` to a UTF-8 `&str` +/// Converts a `&Path` to a UTF-8 `&str`. pub fn path_to_str(path: &Path) -> Result<&str> { - path.to_str().ok_or_else(|| { - ErrorKind::Msg(format!("path is not valid UTF-8 '{}'", path.display())).into() - }) + path.to_str() + .ok_or_else(|| format_err!("path is not valid UTF-8 '{}'", path.display())) } -/// Wrap `fs::copy` with a nicer error message +/// Wraps `fs::copy` with a nicer error message. pub fn copy, Q: AsRef>(from: P, to: Q) -> Result { if fs::symlink_metadata(&from)?.file_type().is_symlink() { let link = fs::read_link(&from)?; symlink_file(link, &to)?; Ok(0) } else { - fs::copy(&from, &to) - .chain_err(|| format!("failed to copy '{}' to '{}'", - from.as_ref().display(), to.as_ref().display())) + let amt = fs::copy(&from, &to).with_context(|_| { + format!( + "failed to copy '{}' to '{}'", + from.as_ref().display(), + to.as_ref().display() + ) + })?; + Ok(amt) } } -/// Wrap `fs::create_dir` with a nicer error message +/// Wraps `fs::create_dir` with a nicer error message. pub fn create_dir>(path: P) -> Result<()> { fs::create_dir(&path) - .chain_err(|| format!("failed to create dir '{}'", path.as_ref().display())) + .with_context(|_| format!("failed to create dir '{}'", path.as_ref().display()))?; + Ok(()) } -/// Wrap `fs::create_dir_all` with a nicer error message +/// Wraps `fs::create_dir_all` with a nicer error message. pub fn create_dir_all>(path: P) -> Result<()> { fs::create_dir_all(&path) - .chain_err(|| format!("failed to create dir '{}'", path.as_ref().display())) + .with_context(|_| format!("failed to create dir '{}'", path.as_ref().display()))?; + Ok(()) } -/// Wrap `fs::OpenOptions::create_new().open()` as executable, with a nicer error message +/// Wraps `fs::OpenOptions::create_new().open()` as executable, with a nicer error message. pub fn create_new_executable>(path: P) -> Result { let mut options = fs::OpenOptions::new(); options.write(true).create_new(true); - #[cfg(unix)] options.mode(0o755); - options.open(&path) - .chain_err(|| format!("failed to create file '{}'", path.as_ref().display())) + #[cfg(unix)] + options.mode(0o755); + let file = options + .open(&path) + .with_context(|_| format!("failed to create file '{}'", path.as_ref().display()))?; + Ok(file) } -/// Wrap `fs::OpenOptions::create_new().open()`, with a nicer error message +/// Wraps `fs::OpenOptions::create_new().open()`, with a nicer error message. pub fn create_new_file>(path: P) -> Result { - fs::OpenOptions::new().write(true).create_new(true).open(&path) - .chain_err(|| format!("failed to create file '{}'", path.as_ref().display())) + let file = fs::OpenOptions::new() + .write(true) + .create_new(true) + .open(&path) + .with_context(|_| format!("failed to create file '{}'", path.as_ref().display()))?; + Ok(file) } -/// Wrap `fs::File::open()` with a nicer error message +/// Wraps `fs::File::open()` with a nicer error message. pub fn open_file>(path: P) -> Result { - fs::File::open(&path) - .chain_err(|| format!("failed to open file '{}'", path.as_ref().display())) + let file = fs::File::open(&path) + .with_context(|_| format!("failed to open file '{}'", path.as_ref().display()))?; + Ok(file) } -/// Wrap `remove_dir_all` with a nicer error message +/// Wraps `remove_dir_all` with a nicer error message. pub fn remove_dir_all>(path: P) -> Result<()> { - crate::remove_dir_all::remove_dir_all(path.as_ref()) - .chain_err(|| format!("failed to remove dir '{}'", path.as_ref().display())) + remove_dir_all::remove_dir_all(path.as_ref()) + .with_context(|_| format!("failed to remove dir '{}'", path.as_ref().display()))?; + Ok(()) } /// Wrap `fs::remove_file` with a nicer error message pub fn remove_file>(path: P) -> Result<()> { fs::remove_file(path.as_ref()) - .chain_err(|| format!("failed to remove file '{}'", path.as_ref().display())) + .with_context(|_| format!("failed to remove file '{}'", path.as_ref().display()))?; + Ok(()) } /// Copies the `src` directory recursively to `dst`. Both are assumed to exist @@ -97,9 +102,10 @@ pub fn copy_recursive(src: &Path, dst: &Path) -> Result<()> { } /// Copies the `src` directory recursively to `dst`. Both are assumed to exist -/// when this function is called. Invokes a callback for each path visited. +/// when this function is called. Invokes a callback for each path visited. pub fn copy_with_callback(src: &Path, dst: &Path, mut callback: F) -> Result<()> - where F: FnMut(&Path, fs::FileType) -> Result<()> +where + F: FnMut(&Path, fs::FileType) -> Result<()>, { for entry in WalkDir::new(src).min_depth(1) { let entry = entry?; @@ -117,8 +123,7 @@ pub fn copy_with_callback(src: &Path, dst: &Path, mut callback: F) -> Result< Ok(()) } - -/// Create an "actor" with default values and setters for all fields. +/// Creates an "actor" with default values and setters for all fields. macro_rules! actor { ($( #[ $attr:meta ] )+ pub struct $name:ident { $( $( #[ $field_attr:meta ] )+ $field:ident : $type:ty = $default:expr, )* diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 54549e4c7e..a7188f0d11 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -5,16 +5,15 @@ version = "0.1.0" license = "MIT OR Apache-2.0" edition = "2018" +[features] +linkcheck = ["mdbook-linkcheck"] + [dependencies] clap = "2.25.0" +failure = "0.1" +mdbook-linkcheck = { version = "0.3.0", optional = true } [dependencies.mdbook] version = "0.3.0" default-features = false features = ["search"] - -[dependencies.mdbook_1] -package = "mdbook" -version = "0.1.7" -default-features = false -features = ["search"] diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 04e48dde86..95530b210a 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use clap::{crate_version}; use std::env; @@ -7,19 +5,20 @@ use std::path::{Path, PathBuf}; use clap::{App, ArgMatches, SubCommand, AppSettings}; -use mdbook_1::{MDBook as MDBook1}; -use mdbook_1::errors::{Result as Result1}; - use mdbook::MDBook; -use mdbook::errors::Result; +use mdbook::errors::{Result as Result3}; + +#[cfg(feature = "linkcheck")] +use mdbook::renderer::RenderContext; +#[cfg(feature = "linkcheck")] +use mdbook_linkcheck::{self, errors::BrokenLinks}; +use failure::Error; fn main() { let d_message = "-d, --dest-dir=[dest-dir] 'The output directory for your book{n}(Defaults to ./book when omitted)'"; let dir_message = "[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'"; - let vers_message = "-m, --mdbook-vers=[md-version] -'The version of mdbook to use for your book{n}(Defaults to 1 when omitted)'"; let matches = App::new("rustbook") .about("Build a book with mdBook") @@ -29,64 +28,63 @@ fn main() { .subcommand(SubCommand::with_name("build") .about("Build the book from the markdown files") .arg_from_usage(d_message) - .arg_from_usage(dir_message) - .arg_from_usage(vers_message)) + .arg_from_usage(dir_message)) + .subcommand(SubCommand::with_name("linkcheck") + .about("Run linkcheck with mdBook 3") + .arg_from_usage(dir_message)) .get_matches(); // Check which subcomamnd the user ran... match matches.subcommand() { ("build", Some(sub_matches)) => { - match sub_matches.value_of("mdbook-vers") { - None | Some("1") => { - if let Err(e) = build_1(sub_matches) { - eprintln!("Error: {}", e); - - for cause in e.iter().skip(1) { - eprintln!("\tCaused By: {}", cause); - } + if let Err(e) = build(sub_matches) { + eprintln!("Error: {}", e); - ::std::process::exit(101); - } + for cause in e.iter().skip(1) { + eprintln!("\tCaused By: {}", cause); } - Some("2") | Some("3") => { - if let Err(e) = build(sub_matches) { - eprintln!("Error: {}", e); - for cause in e.iter().skip(1) { + ::std::process::exit(101); + } + }, + ("linkcheck", Some(sub_matches)) => { + if let Err(err) = linkcheck(sub_matches) { + eprintln!("Error: {}", err); + + #[cfg(feature = "linkcheck")] + { + if let Ok(broken_links) = err.downcast::() { + for cause in broken_links.links().iter() { eprintln!("\tCaused By: {}", cause); } - - ::std::process::exit(101); } } - _ => { - panic!("Invalid mdBook version! Select '1' or '2' or '3'"); - } - }; + + ::std::process::exit(101); + } }, (_, _) => unreachable!(), }; } -// Build command implementation -pub fn build_1(args: &ArgMatches<'_>) -> Result1<()> { +#[cfg(feature = "linkcheck")] +pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> { let book_dir = get_book_dir(args); - let mut book = MDBook1::load(&book_dir)?; - - // Set this to allow us to catch bugs in advance. - book.config.build.create_missing = false; - - if let Some(dest_dir) = args.value_of("dest-dir") { - book.config.build.build_dir = PathBuf::from(dest_dir); - } + let book = MDBook::load(&book_dir).unwrap(); + let cfg = book.config; + let render_ctx = RenderContext::new(&book_dir, book.book, cfg, &book_dir); - book.build()?; + mdbook_linkcheck::check_links(&render_ctx) +} +#[cfg(not(feature = "linkcheck"))] +pub fn linkcheck(_args: &ArgMatches<'_>) -> Result<(), Error> { + println!("mdbook-linkcheck is disabled."); Ok(()) } // Build command implementation -pub fn build(args: &ArgMatches<'_>) -> Result<()> { +pub fn build(args: &ArgMatches<'_>) -> Result3<()> { let book_dir = get_book_dir(args); let mut book = MDBook::load(&book_dir)?; diff --git a/src/tools/rustc-std-workspace-alloc/Cargo.toml b/src/tools/rustc-std-workspace-alloc/Cargo.toml index 05df1fddc7..ef7dc812af 100644 --- a/src/tools/rustc-std-workspace-alloc/Cargo.toml +++ b/src/tools/rustc-std-workspace-alloc/Cargo.toml @@ -6,6 +6,7 @@ license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ +edition = "2018" [lib] path = "lib.rs" diff --git a/src/tools/rustc-std-workspace-core/lib.rs b/src/tools/rustc-std-workspace-core/lib.rs index 99d51bc2d5..1432785256 100644 --- a/src/tools/rustc-std-workspace-core/lib.rs +++ b/src/tools/rustc-std-workspace-core/lib.rs @@ -1,5 +1,4 @@ #![feature(no_core)] #![no_core] -#![deny(rust_2018_idioms)] pub use core::*; diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index 26b447d2ef..4ce411223d 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -64,6 +64,7 @@ features = [ [dependencies] curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } +crossbeam-utils = { version = "0.6.5", features = ["nightly"] } parking_lot = { version = "0.7", features = ['nightly'] } rand = { version = "0.6.1", features = ["i128_support"] } serde = { version = "1.0.82", features = ['derive'] } diff --git a/src/tools/rustdoc-themes/main.rs b/src/tools/rustdoc-themes/main.rs index 63432a6585..616b544483 100644 --- a/src/tools/rustdoc-themes/main.rs +++ b/src/tools/rustdoc-themes/main.rs @@ -1,5 +1,3 @@ -#![deny(rust_2018_idioms)] - use std::env::args; use std::fs::read_dir; use std::path::Path; diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs index 8171708e99..99573cadb9 100644 --- a/src/tools/rustdoc/main.rs +++ b/src/tools/rustdoc/main.rs @@ -1,3 +1 @@ -#![deny(rust_2018_idioms)] - fn main() { rustdoc::main() } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 6169ffc429..de54eb8f57 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -14,6 +14,7 @@ const LICENSES: &[&str] = &[ "Apache-2.0/MIT", "Apache-2.0 / MIT", "MIT OR Apache-2.0", + "Apache-2.0 OR MIT", "MIT", "Unlicense/MIT", "Unlicense OR MIT", @@ -47,11 +48,12 @@ const EXCEPTIONS: &[&str] = &[ "bytesize", // Apache-2.0, cargo "im-rc", // MPL-2.0+, cargo "adler32", // BSD-3-Clause AND Zlib, cargo dep that isn't used - "fortanix-sgx-abi", // MPL-2.0+, libstd but only for `sgx` target "constant_time_eq", // CC0-1.0, rustfmt "utf8parse", // Apache-2.0 OR MIT, cargo via strip-ansi-escapes "vte", // Apache-2.0 OR MIT, cargo via strip-ansi-escapes "sized-chunks", // MPL-2.0+, cargo via im-rc + // FIXME: this dependency violates the documentation comment above: + "fortanix-sgx-abi", // MPL-2.0+, libstd but only for `sgx` target ]; /// Which crates to check against the whitelist? @@ -74,6 +76,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("bitflags"), Crate("build_const"), Crate("byteorder"), + Crate("c2-chacha"), Crate("cc"), Crate("cfg-if"), Crate("chalk-engine"), @@ -95,6 +98,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("fuchsia-zircon"), Crate("fuchsia-zircon-sys"), Crate("getopts"), + Crate("getrandom"), Crate("humantime"), Crate("indexmap"), Crate("itertools"), @@ -120,6 +124,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("parking_lot_core"), Crate("pkg-config"), Crate("polonius-engine"), + Crate("ppv-lite86"), Crate("proc-macro2"), Crate("quick-error"), Crate("quote"), diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs new file mode 100644 index 0000000000..4a2e49fd1c --- /dev/null +++ b/src/tools/tidy/src/edition.rs @@ -0,0 +1,45 @@ +//! Tidy check to ensure that crate `edition` is '2018' +//! + +use std::path::Path; + +fn filter_dirs(path: &Path) -> bool { + // FIXME: just use super::filter_dirs after the submodules are updated. + if super::filter_dirs(path) { + return true; + } + let skip = [ + "src/doc/book/second-edition", + "src/doc/book/2018-edition", + "src/doc/book/ci/stable-check", + "src/doc/reference/stable-check", + ]; + skip.iter().any(|p| path.ends_with(p)) +} + +fn is_edition_2018(mut line: &str) -> bool { + line = line.trim(); + line == "edition = \"2018\"" || line == "edition = \'2018\'" +} + +pub fn check(path: &Path, bad: &mut bool) { + super::walk( + path, + &mut |path| filter_dirs(path) || path.ends_with("src/test"), + &mut |entry, contents| { + let file = entry.path(); + let filename = file.file_name().unwrap(); + if filename != "Cargo.toml" { + return; + } + let has_edition = contents.lines().any(is_edition_2018); + if !has_edition { + tidy_error!( + bad, + "{} doesn't have `edition = \"2018\"` on a separate line", + file.display() + ); + } + }, + ); +} diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 1841beb1fd..88a469ef95 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -16,6 +16,9 @@ use std::path::Path; use regex::Regex; +#[cfg(test)] +mod tests; + mod version; use version::Version; @@ -143,7 +146,7 @@ pub fn check(path: &Path, bad: &mut bool, verbose: bool) -> CollectedFeatures { println!("Expected a gate test for the feature '{}'.", name); println!("Hint: create a failing test file named 'feature-gate-{}.rs'\ \n in the 'ui' test suite, with its failures due to\ - \n missing usage of #![feature({})].", name, name); + \n missing usage of `#![feature({})]`.", name, name); println!("Hint: If you already have such a test and don't want to rename it,\ \n you can also add a // gate-test-{} line to the test file.", name); @@ -203,14 +206,6 @@ fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> { .map(|m| m.as_str()) } -#[test] -fn test_find_attr_val() { - let s = r#"#[unstable(feature = "checked_duration_since", issue = "58402")]"#; - assert_eq!(find_attr_val(s, "feature"), Some("checked_duration_since")); - assert_eq!(find_attr_val(s, "issue"), Some("58402")); - assert_eq!(find_attr_val(s, "since"), None); -} - fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool { let prefix = "feature_gate_"; if filen_underscore.starts_with(prefix) { @@ -344,7 +339,7 @@ fn get_and_check_lib_features(base_src_path: &Path, Ok((name, f)) => { let mut check_features = |f: &Feature, list: &Features, display: &str| { if let Some(ref s) = list.get(name) { - if f.tracking_issue != s.tracking_issue { + if f.tracking_issue != s.tracking_issue && f.level != Status::Stable { tidy_error!(bad, "{}:{}: mismatches the `issue` in {}", file.display(), diff --git a/src/tools/tidy/src/features/tests.rs b/src/tools/tidy/src/features/tests.rs new file mode 100644 index 0000000000..fa7a931ec8 --- /dev/null +++ b/src/tools/tidy/src/features/tests.rs @@ -0,0 +1,9 @@ +use super::*; + +#[test] +fn test_find_attr_val() { + let s = r#"#[unstable(feature = "checked_duration_since", issue = "58402")]"#; + assert_eq!(find_attr_val(s, "feature"), Some("checked_duration_since")); + assert_eq!(find_attr_val(s, "issue"), Some("58402")); + assert_eq!(find_attr_val(s, "since"), None); +} diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs index 1ce9fe127d..cc3a651024 100644 --- a/src/tools/tidy/src/features/version.rs +++ b/src/tools/tidy/src/features/version.rs @@ -2,6 +2,9 @@ use std::str::FromStr; use std::num::ParseIntError; use std::fmt; +#[cfg(test)] +mod tests; + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Version { parts: [u32; 3], @@ -46,45 +49,3 @@ impl FromStr for Version { Ok(Self { parts }) } } - -#[cfg(test)] -mod test { - use super::Version; - - #[test] - fn test_try_from_invalid_version() { - assert!("".parse::().is_err()); - assert!("hello".parse::().is_err()); - assert!("1.32.hi".parse::().is_err()); - assert!("1.32..1".parse::().is_err()); - assert!("1.32".parse::().is_err()); - assert!("1.32.0.1".parse::().is_err()); - } - - #[test] - fn test_try_from_single() { - assert_eq!("1.32.0".parse(), Ok(Version { parts: [1, 32, 0] })); - assert_eq!("1.0.0".parse(), Ok(Version { parts: [1, 0, 0] })); - } - - #[test] - fn test_compare() { - let v_1_0_0 = "1.0.0".parse::().unwrap(); - let v_1_32_0 = "1.32.0".parse::().unwrap(); - let v_1_32_1 = "1.32.1".parse::().unwrap(); - assert!(v_1_0_0 < v_1_32_1); - assert!(v_1_0_0 < v_1_32_0); - assert!(v_1_32_0 < v_1_32_1); - } - - #[test] - fn test_to_string() { - let v_1_0_0 = "1.0.0".parse::().unwrap(); - let v_1_32_1 = "1.32.1".parse::().unwrap(); - - assert_eq!(v_1_0_0.to_string(), "1.0.0"); - assert_eq!(v_1_32_1.to_string(), "1.32.1"); - assert_eq!(format!("{:<8}", v_1_32_1), "1.32.1 "); - assert_eq!(format!("{:>8}", v_1_32_1), " 1.32.1"); - } -} diff --git a/src/tools/tidy/src/features/version/tests.rs b/src/tools/tidy/src/features/version/tests.rs new file mode 100644 index 0000000000..31224fdf1e --- /dev/null +++ b/src/tools/tidy/src/features/version/tests.rs @@ -0,0 +1,38 @@ +use super::*; + +#[test] +fn test_try_from_invalid_version() { + assert!("".parse::().is_err()); + assert!("hello".parse::().is_err()); + assert!("1.32.hi".parse::().is_err()); + assert!("1.32..1".parse::().is_err()); + assert!("1.32".parse::().is_err()); + assert!("1.32.0.1".parse::().is_err()); +} + +#[test] +fn test_try_from_single() { + assert_eq!("1.32.0".parse(), Ok(Version { parts: [1, 32, 0] })); + assert_eq!("1.0.0".parse(), Ok(Version { parts: [1, 0, 0] })); +} + +#[test] +fn test_compare() { + let v_1_0_0 = "1.0.0".parse::().unwrap(); + let v_1_32_0 = "1.32.0".parse::().unwrap(); + let v_1_32_1 = "1.32.1".parse::().unwrap(); + assert!(v_1_0_0 < v_1_32_1); + assert!(v_1_0_0 < v_1_32_0); + assert!(v_1_32_0 < v_1_32_1); +} + +#[test] +fn test_to_string() { + let v_1_0_0 = "1.0.0".parse::().unwrap(); + let v_1_32_1 = "1.32.1".parse::().unwrap(); + + assert_eq!(v_1_0_0.to_string(), "1.0.0"); + assert_eq!(v_1_32_1.to_string(), "1.32.1"); + assert_eq!(format!("{:<8}", v_1_32_1), "1.32.1 "); + assert_eq!(format!("{:>8}", v_1_32_1), " 1.32.1"); +} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index a0bf0b0735..e01184e365 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -34,40 +34,29 @@ pub mod style; pub mod errors; pub mod features; pub mod cargo; +pub mod edition; pub mod pal; pub mod deps; pub mod extdeps; pub mod ui_tests; +pub mod unit_tests; pub mod unstable_book; -pub mod libcoretest; fn filter_dirs(path: &Path) -> bool { let skip = [ - "src/llvm", - "src/llvm-project", "src/llvm-emscripten", - "src/libbacktrace", - "src/librustc_data_structures/owning_ref", - "src/vendor", + "src/llvm-project", + "src/stdarch", "src/tools/cargo", - "src/tools/clang", - "src/tools/rls", "src/tools/clippy", + "src/tools/miri", + "src/tools/rls", "src/tools/rust-installer", "src/tools/rustfmt", - "src/tools/miri", - "src/tools/lld", - "src/tools/lldb", - "src/target", - "src/stdsimd", - "src/rust-sgx", - "target", - "vendor", ]; skip.iter().any(|p| path.ends_with(p)) } - fn walk_many( paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str) ) { diff --git a/src/tools/tidy/src/libcoretest.rs b/src/tools/tidy/src/libcoretest.rs deleted file mode 100644 index ea92f989ad..0000000000 --- a/src/tools/tidy/src/libcoretest.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Tidy check to ensure `#[test]` is not used directly inside `libcore`. -//! -//! `#![no_core]` libraries cannot be tested directly due to duplicating lang -//! item. All tests must be written externally in `libcore/tests`. - -use std::path::Path; - -pub fn check(path: &Path, bad: &mut bool) { - let libcore_path = path.join("libcore"); - super::walk( - &libcore_path, - &mut |subpath| t!(subpath.strip_prefix(&libcore_path)).starts_with("tests"), - &mut |entry, contents| { - let subpath = entry.path(); - if let Some("rs") = subpath.extension().and_then(|e| e.to_str()) { - if contents.contains("#[test]") { - tidy_error!( - bad, - "{} contains #[test]; libcore tests must be placed inside \ - `src/libcore/tests/`", - subpath.display() - ); - } - } - }, - ); -} diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 918762ed6e..5deac52f08 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -4,8 +4,6 @@ //! etc. This is run by default on `make check` and as part of the auto //! builders. -#![deny(warnings)] - use tidy::*; use std::process; @@ -24,10 +22,11 @@ fn main() { style::check(&path, &mut bad); errors::check(&path, &mut bad); cargo::check(&path, &mut bad); + edition::check(&path, &mut bad); let collected = features::check(&path, &mut bad, verbose); pal::check(&path, &mut bad); unstable_book::check(&path, collected, &mut bad); - libcoretest::check(&path, &mut bad); + unit_tests::check(&path, &mut bad); if !args.iter().any(|s| *s == "--no-vendor") { deps::check(&path, &mut bad); } diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 4a159d926b..6a0d530e23 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -152,6 +152,8 @@ pub fn check(path: &Path, bad: &mut bool) { let mut skip_file_length = contains_ignore_directive(can_contain, &contents, "filelength"); let mut skip_end_whitespace = contains_ignore_directive(can_contain, &contents, "end-whitespace"); + let mut skip_trailing_newlines = + contains_ignore_directive(can_contain, &contents, "trailing-newlines"); let mut skip_copyright = contains_ignore_directive(can_contain, &contents, "copyright"); let mut leading_new_lines = false; let mut trailing_new_lines = 0; @@ -214,10 +216,17 @@ pub fn check(path: &Path, bad: &mut bool) { if leading_new_lines { tidy_error!(bad, "{}: leading newline", file.display()); } + let mut err = |msg: &str| { + tidy_error!(bad, "{}: {}", file.display(), msg); + }; match trailing_new_lines { - 0 => tidy_error!(bad, "{}: missing trailing newline", file.display()), + 0 => suppressible_tidy_err!(err, skip_trailing_newlines, "missing trailing newline"), 1 => {} - n => tidy_error!(bad, "{}: too many trailing newlines ({})", file.display(), n), + n => suppressible_tidy_err!( + err, + skip_trailing_newlines, + &format!("too many trailing newlines ({})", n) + ), }; if lines > LINES { let mut err = |_| { @@ -247,6 +256,9 @@ pub fn check(path: &Path, bad: &mut bool) { if let Directive::Ignore(false) = skip_end_whitespace { tidy_error!(bad, "{}: ignoring trailing whitespace unnecessarily", file.display()); } + if let Directive::Ignore(false) = skip_trailing_newlines { + tidy_error!(bad, "{}: ignoring trailing newlines unnecessarily", file.display()); + } if let Directive::Ignore(false) = skip_copyright { tidy_error!(bad, "{}: ignoring copyright unnecessarily", file.display()); } diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs new file mode 100644 index 0000000000..6286945ad2 --- /dev/null +++ b/src/tools/tidy/src/unit_tests.rs @@ -0,0 +1,65 @@ +//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside `libcore`. +//! +//! `#![no_core]` libraries cannot be tested directly due to duplicating lang +//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}`. +//! +//! Outside of libcore tests and benchmarks should be outlined into separate files +//! named `tests.rs` or `benches.rs`, or directories named `tests` or `benches` unconfigured +//! during normal build. + +use std::path::Path; + +pub fn check(root_path: &Path, bad: &mut bool) { + let libcore = &root_path.join("libcore"); + let libcore_tests = &root_path.join("libcore/tests"); + let libcore_benches = &root_path.join("libcore/benches"); + let is_core = |path: &Path| { + path.starts_with(libcore) && + !(path.starts_with(libcore_tests) || path.starts_with(libcore_benches)) + }; + + let mut skip = |path: &Path| { + let file_name = path.file_name().unwrap_or_default(); + if path.is_dir() { + super::filter_dirs(path) || + path.ends_with("src/test") || + path.ends_with("src/doc") || + path.ends_with("src/libstd") || // FIXME? + (file_name == "tests" || file_name == "benches") && !is_core(path) + } else { + let extension = path.extension().unwrap_or_default(); + extension != "rs" || + (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path) + } + }; + + super::walk( + root_path, + &mut skip, + &mut |entry, contents| { + let path = entry.path(); + let is_libcore = path.starts_with(libcore); + for (i, line) in contents.lines().enumerate() { + let line = line.trim(); + let is_test = || line.contains("#[test]") && !line.contains("`#[test]"); + let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]"); + if !line.starts_with("//") && (is_test() || is_bench()) { + let explanation = if is_libcore { + "libcore unit tests and benchmarks must be placed into \ + `libcore/tests` or `libcore/benches`" + } else { + "unit tests and benchmarks must be placed into \ + separate files or directories named \ + `tests.rs`, `benches.rs`, `tests` or `benches`" + }; + let name = if is_test() { "test" } else { "bench" }; + tidy_error!( + bad, "`{}:{}` contains `#[{}]`; {}", + path.display(), i + 1, name, explanation, + ); + return; + } + } + }, + ); +} diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index e92d174a4e..036349ea1c 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -1,10 +1,5 @@ //! Auto-generate stub docs for the unstable book -#![deny(rust_2018_idioms)] -#![deny(warnings)] - - - use tidy::features::{Feature, Features, collect_lib_features, collect_lang_features}; use tidy::unstable_book::{collect_unstable_feature_names, collect_unstable_book_section_file_names, PATH_STR, LANG_FEATURES_DIR, LIB_FEATURES_DIR}; diff --git a/vendor/ammonia/.cargo-checksum.json b/vendor/ammonia/.cargo-checksum.json index 9b50f321d4..e171f53665 100644 --- a/vendor/ammonia/.cargo-checksum.json +++ b/vendor/ammonia/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"a07767d25d8ade958aae0948cd6c6f11ee02da4d9a1e1fccf3b52bee7eadb908","CODE_OF_CONDUCT.md":"8eeefcb4a7d164ea102e157a091a9a6aea659518e9a2d5a8fca09a942f02f80c","Cargo.toml":"e374402aea1f1208a475ac091bbc4514b4bbab1dea5313f4652a87402a29229b","LICENSE-APACHE":"2e54cd84a645bea25943c75dd8ae67cb291e66a47a11578333c9b4b3b6b86c85","LICENSE-MIT":"09c503c8cb1956e1e69b5ebfc0accee85f926b33f4940d74c9bc067b2ed50a87","README.md":"5015370dbb6a1cd38a5249291c80cd529f21c0ffe8433e97e3c554ac36db9a13","RELEASE_PROCESS.md":"3d540f3c0a88817e5a6b34f04a4c1df8344da5c43eca0e68ad60375befb6d42c","examples/ammonia-cat.rs":"b1f1ef032dca4a471589826e440e14e945c5e809f844e3f5db9e083e85892551","src/lib.rs":"80b192f53cc0006e6505ca0b895025dc8f24e8f1917a222d0258b7caea025473","tests/version-numbers.rs":"b5cf333cdac8e318f08d5c40937a72b3afafc44abcfc2b53b77fafef896b15ea"},"package":"c799ecf1ad77acb48b643e2f45b12d60ee41576287fc575031aa020de88b8f45"} \ No newline at end of file +{"files":{"CHANGELOG.md":"1ccea8c0ee3ac564388d23dce30050941fb8615abe1d273eecc1588031508c04","CODE_OF_CONDUCT.md":"8eeefcb4a7d164ea102e157a091a9a6aea659518e9a2d5a8fca09a942f02f80c","Cargo.toml":"9e31375eb9301a8574903406367618fbf401114c37b1808ee3787e876be20291","LICENSE-APACHE":"2e54cd84a645bea25943c75dd8ae67cb291e66a47a11578333c9b4b3b6b86c85","LICENSE-MIT":"09c503c8cb1956e1e69b5ebfc0accee85f926b33f4940d74c9bc067b2ed50a87","README.md":"5015370dbb6a1cd38a5249291c80cd529f21c0ffe8433e97e3c554ac36db9a13","RELEASE_PROCESS.md":"3d540f3c0a88817e5a6b34f04a4c1df8344da5c43eca0e68ad60375befb6d42c","examples/ammonia-cat.rs":"f54b56c8e962b7c4f58e13ce3e2de09fa99807d0a14f64a13f3e6aad2454fc13","src/lib.rs":"14225d60031ebee2e01a8a8913602a67697c3ff51c4424f4febaeda64134d6b0","tests/version-numbers.rs":"b5cf333cdac8e318f08d5c40937a72b3afafc44abcfc2b53b77fafef896b15ea"},"package":"384d704f242a0a9faf793fff775a0be6ab9aa27edabffa097331d73779142520"} \ No newline at end of file diff --git a/vendor/ammonia/CHANGELOG.md b/vendor/ammonia/CHANGELOG.md index 35a0a9bd4c..0f6f39dcd8 100644 --- a/vendor/ammonia/CHANGELOG.md +++ b/vendor/ammonia/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +# 2.1.2 + +* Fix a memory leak caused by certain node types. + # 2.1.1 * Update dependencies diff --git a/vendor/ammonia/Cargo.toml b/vendor/ammonia/Cargo.toml index 242a50c087..9c581c1ef0 100644 --- a/vendor/ammonia/Cargo.toml +++ b/vendor/ammonia/Cargo.toml @@ -12,7 +12,7 @@ [package] name = "ammonia" -version = "2.1.1" +version = "2.1.2" authors = ["Michael Howell "] description = "HTML Sanitization" documentation = "https://docs.rs/ammonia/" @@ -38,5 +38,8 @@ version = "0.4" [dependencies.url] version = "1" +[dev-dependencies.env_logger] +version = "0.6.1" + [dev-dependencies.version-sync] version = "0.7" diff --git a/vendor/ammonia/examples/ammonia-cat.rs b/vendor/ammonia/examples/ammonia-cat.rs index 267cfdb2e1..7f27dfd2a1 100644 --- a/vendor/ammonia/examples/ammonia-cat.rs +++ b/vendor/ammonia/examples/ammonia-cat.rs @@ -29,6 +29,7 @@ fn run() -> io::Result<()> { } fn main() { + env_logger::init(); if let Err(ref e) = run() { println!("error: {}", e); process::exit(1); diff --git a/vendor/ammonia/src/lib.rs b/vendor/ammonia/src/lib.rs index abea708969..bcc52ab211 100644 --- a/vendor/ammonia/src/lib.rs +++ b/vendor/ammonia/src/lib.rs @@ -1364,7 +1364,7 @@ impl<'a> Builder<'a> { // Now, imperatively clean up all of the child nodes. // Otherwise, we could wind up with a DoS, either caused by a memory leak, // or caused by a stack overflow. - while let Some(node) = stack.pop() { + while let Some(node) = removed.pop() { removed.extend_from_slice( &replace(&mut *node.children.borrow_mut(), Vec::new())[..] ); diff --git a/vendor/annotate-snippets/.cargo-checksum.json b/vendor/annotate-snippets/.cargo-checksum.json index caa39926e0..13074988fc 100644 --- a/vendor/annotate-snippets/.cargo-checksum.json +++ b/vendor/annotate-snippets/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"925115cdc75915ab34fdb56d61c6b98fd187e10ea7539f5f3cfaafb17c5d6d70","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"bb23326d42384b69634860bd4f5bffd42480834227d3e5e722c3604e887a75e7","examples/expected_type.rs":"e49f9628c7c14c08d9c3c8286e4020494db2c166c5d3b21c30209a98a7888ad2","examples/footer.rs":"031aee0dba4cbc0a9c5ca4e6342976c4a6c9e9945e626dff54ef525f6a37ff4a","examples/format.rs":"634576d4943b41b30a0b815dbb308ea162e7f4be1e7c2d9595f6cf1f6f59a2e2","examples/multislice.rs":"228063f631a9dcad72c37324d9f669c60181fd1177186965563710cf3bddbe82","src/display_list/from_snippet.rs":"354ed2170db40e8324d3e2c28fe938623b45e4993d6124d3d4979a1546664d09","src/display_list/mod.rs":"e1810ba12bf48515d063075b9cdda3ede667d58bb33e75b1de27c392fbe11836","src/display_list/structs.rs":"ac17f7b364829fcf1336466d6937f31a14c7e8c46a8a8962bc1f8a1c2eb2317f","src/formatter/mod.rs":"12304e8d46260e155368987bacac30b717c688f9dae2e0961025b3cd3a49f76b","src/formatter/style.rs":"185d5b481ba2052da55de712735bf1d50d621477ca08b339cfae49b3c794325f","src/lib.rs":"98848cedd3dd581ea1b7a8443607af4a51a7c4fe27828cd3ebff9140a3ff5a76","src/snippet.rs":"904d642357a4ed5d2a0387e7e9253ec4631ef852c7188507f98e474b16fd5adf","src/stylesheets/color.rs":"fbca2562b765bb5710c0934dcc0a56a349622b2936ddc4b2bbd2e92ebc875933","src/stylesheets/mod.rs":"ef8038360631561f53a4472cffe45e1fbde04f4aed8d4738426da88214b94576","src/stylesheets/no_color.rs":"fc61040fd8a2be45468ff7594a8f74674853867fb3afc81ec24f383c165b22ba","tests/diff/mod.rs":"d423c84a84a4f3247703edf9b5d85b1e6d06f279539af676505abbcc5e2484fb","tests/dl_from_snippet.rs":"4074b10037c66fe15d813a9b80e2842ccdb7520afb04b28e83e4425baefb4d9b","tests/fixtures.rs":"4047554b1b9840437d4779d4689704b792b0cf07173f3fda92e17b4301e23aa0","tests/fixtures/no-color/multiline_annotation.txt":"b8d36204f260d91e99672fe11839e1fe416f6a18b6de46c923d43c0430a97ee7","tests/fixtures/no-color/multiline_annotation.yaml":"fab49391fa0c53ffe3b997f70c5615c0b767c21de105b0a3805a692085e641ae","tests/fixtures/no-color/multiline_annotation2.txt":"391da0ef9bec5de45a30a0869ecc3227a1d3272872508af1d7a294fa431c8dd2","tests/fixtures/no-color/multiline_annotation2.yaml":"aa2fb2c8666f1c625c92dd1630dd643ba304617334c077b169e5a27be0c116af","tests/fixtures/no-color/multiple_annotations.txt":"b284ab83d9de3aa9d014d3d04ac199517967885bc064f0462c15d6a4d71554aa","tests/fixtures/no-color/multiple_annotations.yaml":"7892a2eb95a0442e3926c31482202410d867a87ef3d35c6c4599ebd6e5c33d31","tests/fixtures/no-color/simple.txt":"cb9b7fab003c58e03ce87cae4fd04a40983ff3f8ee329b494dcb3abcf576fccd","tests/fixtures/no-color/simple.yaml":"9650f0a4ff157c7daf6cc3fc33179173f1cd4c1ace298501efca3da134aec1e9","tests/formatter.rs":"adbe7cd1361af4bc1a57648833cf279c255aeda05293ed8f7774f9013db5ea6b","tests/snippet/mod.rs":"0dc871f3d7d49564ae0d355eb70319973b4f88f69c2e3759e184dba4d7118c47"},"package":"e8bcdcd5b291ce85a78f2b9d082a8de9676c12b1840d386d67bc5eea6f9d2b4e"} \ No newline at end of file +{"files":{"CHANGELOG.md":"230269942a7482e8a1c77dd30e22db58b4c7e3fa42dd5203e40e93d6bbcea175","Cargo.toml":"984545ef81f26c2d0087367044b65f9eb1f8c75c6a160c717d37caea5058452b","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"8974c4d36d39dff6dabea6fcef6d04c001bd4fe46ac28e6cd18206a7d96ff9b1","examples/expected_type.rs":"cc8e81dcbdbe31cb1e3d2b2b951c8eeb975789c68c8511f1436b9464752396df","examples/footer.rs":"485dd393b03ad1958549db08b521be9f67ee61400e3181793353e927ec2aa414","examples/format.rs":"a6f1e6b51b13b883f0636aca177fa119db8095faaff58c3c5f2712537d9b08bc","examples/multislice.rs":"0afeed0bb0af412c2f1b5709e536a42186f492602d11869f4c058e8ccb30ceda","src/display_list/from_snippet.rs":"354ed2170db40e8324d3e2c28fe938623b45e4993d6124d3d4979a1546664d09","src/display_list/mod.rs":"e1810ba12bf48515d063075b9cdda3ede667d58bb33e75b1de27c392fbe11836","src/display_list/structs.rs":"d6a13ba21ced6032db262eca1aa50c0a6f738b9f0a778deb6b88a072fc54f335","src/formatter/mod.rs":"8b8414e7a0abc24c2d22d043d59b09da4f0f3cfdebed517e769de9e453765eac","src/formatter/style.rs":"6f3049e6d18fb9629a752f1bdc4ef720b1675ff69f07db55c3e7debb3885ad87","src/lib.rs":"fd655cb0518b4d11d5ff3a92eceefc0f45697c430197e95d3b8bed3bbf90325f","src/snippet.rs":"904d642357a4ed5d2a0387e7e9253ec4631ef852c7188507f98e474b16fd5adf","src/stylesheets/color.rs":"081f025ab42091dea42eda719d997e7fdf6a949885ead46e0d614dfa47c6a3a4","src/stylesheets/mod.rs":"ef8038360631561f53a4472cffe45e1fbde04f4aed8d4738426da88214b94576","src/stylesheets/no_color.rs":"0d25c1253658141b24fab1440b2b39a3fffe71952fc3667d2e2804a471766cf9","tests/diff/mod.rs":"44a8f8ef3b90db894227d6451b3bcbaa158c6daad5e8951456b979de6687b8e1","tests/dl_from_snippet.rs":"468eea5c1811b0578e923cdeaa6b7d8c159d4ac517c8802e332554e709df7038","tests/fixtures.rs":"25af2bd1891997b07bae8425e82a1ec89c04de29645188e83d6eb506948fb1b7","tests/fixtures/no-color/multiline_annotation.txt":"b8d36204f260d91e99672fe11839e1fe416f6a18b6de46c923d43c0430a97ee7","tests/fixtures/no-color/multiline_annotation.yaml":"fab49391fa0c53ffe3b997f70c5615c0b767c21de105b0a3805a692085e641ae","tests/fixtures/no-color/multiline_annotation2.txt":"391da0ef9bec5de45a30a0869ecc3227a1d3272872508af1d7a294fa431c8dd2","tests/fixtures/no-color/multiline_annotation2.yaml":"aa2fb2c8666f1c625c92dd1630dd643ba304617334c077b169e5a27be0c116af","tests/fixtures/no-color/multiple_annotations.txt":"b284ab83d9de3aa9d014d3d04ac199517967885bc064f0462c15d6a4d71554aa","tests/fixtures/no-color/multiple_annotations.yaml":"7892a2eb95a0442e3926c31482202410d867a87ef3d35c6c4599ebd6e5c33d31","tests/fixtures/no-color/simple.txt":"cb9b7fab003c58e03ce87cae4fd04a40983ff3f8ee329b494dcb3abcf576fccd","tests/fixtures/no-color/simple.yaml":"9650f0a4ff157c7daf6cc3fc33179173f1cd4c1ace298501efca3da134aec1e9","tests/formatter.rs":"9a6be74db49bb3d5d91d3c42430f7d0585911b6702fb017063ed02063c50507d","tests/snippet/mod.rs":"e2f2b073590ba2632196ea2bdc26832a9ab986e1955721a578db7a723e21a37e"},"package":"c7021ce4924a3f25f802b2cccd1af585e39ea1a363a1aa2e72afe54b67a3a7a7"} \ No newline at end of file diff --git a/vendor/annotate-snippets/CHANGELOG.md b/vendor/annotate-snippets/CHANGELOG.md new file mode 100644 index 0000000000..a125e8fca3 --- /dev/null +++ b/vendor/annotate-snippets/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog + +## Unreleased + + - … + +## annotate-snippets 0.6.1 (July 23, 2019) + + - Fix too many anonymized line numbers (#5) + +## annotate-snippets 0.6.0 (June 26, 2019) + + - Add an option to anonymize line numbers (#3) + - Transition the crate to rust-lang org. + - Update the syntax to Rust 2018 idioms. (#4) diff --git a/vendor/annotate-snippets/Cargo.toml b/vendor/annotate-snippets/Cargo.toml index 915f4d7dc9..1f157d28ca 100644 --- a/vendor/annotate-snippets/Cargo.toml +++ b/vendor/annotate-snippets/Cargo.toml @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -13,30 +13,28 @@ [package] edition = "2018" name = "annotate-snippets" -version = "0.5.0" +version = "0.6.1" authors = ["Zibi Braniecki "] description = "Library for building code annotations" readme = "README.md" keywords = ["code", "analysis", "ascii", "errors", "debug"] license = "Apache-2.0/MIT" -repository = "https://github.com/zbraniecki/annotate-snippets-rs" +repository = "https://github.com/rust-lang/annotate-snippets-rs" [dependencies.ansi_term] version = "0.11.0" optional = true [dev-dependencies.ansi_term] -version = "^0.11" +version = "^0.12" [dev-dependencies.difference] version = "^2.0" [dev-dependencies.glob] -version = "^0.2" +version = "^0.3" [dev-dependencies.serde] version = "^1.0" - -[dev-dependencies.serde_derive] -version = "^1.0" +features = ["derive"] [dev-dependencies.serde_yaml] version = "^0.8" @@ -46,7 +44,7 @@ color = ["ansi_term"] default = [] [badges.coveralls] branch = "master" -repository = "zbraniecki/annotate-snippets-rs" +repository = "rust-lang/annotate-snippets-rs" service = "github" [badges.maintenance] @@ -54,4 +52,4 @@ status = "actively-developed" [badges.travis-ci] branch = "master" -repository = "zbraniecki/annotate-snippets-rs" +repository = "rust-lang/annotate-snippets-rs" diff --git a/vendor/annotate-snippets/README.md b/vendor/annotate-snippets/README.md index 44c8a62d4b..a690007b0f 100644 --- a/vendor/annotate-snippets/README.md +++ b/vendor/annotate-snippets/README.md @@ -3,11 +3,11 @@ `annotate-snippets` is a Rust library for annotation of programming code slices. [![crates.io](http://meritbadge.herokuapp.com/annotate-snippets)](https://crates.io/crates/annotate-snippets) -[![Build Status](https://travis-ci.org/zbraniecki/annotate-snippets-rs.svg?branch=master)](https://travis-ci.org/zbraniecki/annotate-snippets-rs) -[![Coverage Status](https://coveralls.io/repos/github/zbraniecki/annotate-snippets-rs/badge.svg?branch=master)](https://coveralls.io/github/zbraniecki/annotate-snippets-rs?branch=master) +[![Build Status](https://travis-ci.org/rust-lang/annotate-snippets-rs.svg?branch=master)](https://travis-ci.org/rust-lang/annotate-snippets-rs) +[![Coverage Status](https://coveralls.io/repos/github/rust-lang/annotate-snippets-rs/badge.svg?branch=master)](https://coveralls.io/github/rust-lang/annotate-snippets-rs?branch=master) The library helps visualize meta information annotating source code slices. -It takes a data structure called `Snippet` on the input and procudes a `String` +It takes a data structure called `Snippet` on the input and produces a `String` which may look like this: ```text @@ -30,21 +30,10 @@ error[E0308]: mismatched types [Documentation]: https://docs.rs/annotate-snippets/ -Installation ------------- - -```toml -[dependencies] -annotate-snippets-rs = "0.1.0" -``` - - Usage ----- ```rust -extern crate annotate_snippets; - use annotate_snippets::snippet; fn main() { diff --git a/vendor/annotate-snippets/examples/expected_type.rs b/vendor/annotate-snippets/examples/expected_type.rs index 6c6ed0127b..20cda66889 100644 --- a/vendor/annotate-snippets/examples/expected_type.rs +++ b/vendor/annotate-snippets/examples/expected_type.rs @@ -1,5 +1,3 @@ -extern crate annotate_snippets; - use annotate_snippets::display_list::DisplayList; use annotate_snippets::formatter::DisplayListFormatter; use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation}; @@ -37,6 +35,6 @@ fn main() { }; let dl = DisplayList::from(snippet); - let dlf = DisplayListFormatter::new(true); + let dlf = DisplayListFormatter::new(true, false); println!("{}", dlf.format(&dl)); } diff --git a/vendor/annotate-snippets/examples/footer.rs b/vendor/annotate-snippets/examples/footer.rs index 7cbc9496ca..1b03910fe6 100644 --- a/vendor/annotate-snippets/examples/footer.rs +++ b/vendor/annotate-snippets/examples/footer.rs @@ -1,5 +1,3 @@ -extern crate annotate_snippets; - use annotate_snippets::display_list::DisplayList; use annotate_snippets::formatter::DisplayListFormatter; use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation}; @@ -34,6 +32,6 @@ fn main() { }; let dl = DisplayList::from(snippet); - let dlf = DisplayListFormatter::new(true); + let dlf = DisplayListFormatter::new(true, false); println!("{}", dlf.format(&dl)); } diff --git a/vendor/annotate-snippets/examples/format.rs b/vendor/annotate-snippets/examples/format.rs index 30d86b5c34..7e41802eb8 100644 --- a/vendor/annotate-snippets/examples/format.rs +++ b/vendor/annotate-snippets/examples/format.rs @@ -1,5 +1,3 @@ -extern crate annotate_snippets; - use annotate_snippets::display_list::DisplayList; use annotate_snippets::formatter::DisplayListFormatter; use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation}; @@ -55,6 +53,6 @@ fn main() { }; let dl = DisplayList::from(snippet); - let dlf = DisplayListFormatter::new(true); + let dlf = DisplayListFormatter::new(true, false); println!("{}", dlf.format(&dl)); } diff --git a/vendor/annotate-snippets/examples/multislice.rs b/vendor/annotate-snippets/examples/multislice.rs index e1f294645a..af1cb152bc 100644 --- a/vendor/annotate-snippets/examples/multislice.rs +++ b/vendor/annotate-snippets/examples/multislice.rs @@ -1,5 +1,3 @@ -extern crate annotate_snippets; - use annotate_snippets::display_list::DisplayList; use annotate_snippets::formatter::DisplayListFormatter; use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet}; @@ -31,6 +29,6 @@ fn main() { }; let dl = DisplayList::from(snippet); - let dlf = DisplayListFormatter::new(true); + let dlf = DisplayListFormatter::new(true, false); println!("{}", dlf.format(&dl)); } diff --git a/vendor/annotate-snippets/src/display_list/structs.rs b/vendor/annotate-snippets/src/display_list/structs.rs index ecd9eb49d8..0d3e0bc5b6 100644 --- a/vendor/annotate-snippets/src/display_list/structs.rs +++ b/vendor/annotate-snippets/src/display_list/structs.rs @@ -131,7 +131,7 @@ pub enum DisplayMarkType { /// use annotate_snippets::display_list::*; /// use annotate_snippets::formatter::DisplayListFormatter; /// - /// let dlf = DisplayListFormatter::new(false); // Don't use colors + /// let dlf = DisplayListFormatter::new(false, false); // Don't use colors /// /// let dl = DisplayList { /// body: vec![ @@ -161,7 +161,7 @@ pub enum DisplayMarkType { /// use annotate_snippets::display_list::*; /// use annotate_snippets::formatter::DisplayListFormatter; /// - /// let dlf = DisplayListFormatter::new(false); // Don't use colors + /// let dlf = DisplayListFormatter::new(false, false); // Don't use colors /// /// let dl = DisplayList { /// body: vec![ @@ -214,7 +214,7 @@ pub enum DisplayHeaderType { /// use annotate_snippets::display_list::*; /// use annotate_snippets::formatter::DisplayListFormatter; /// - /// let dlf = DisplayListFormatter::new(false); // Don't use colors + /// let dlf = DisplayListFormatter::new(false, false); // Don't use colors /// /// let dl = DisplayList { /// body: vec![ @@ -236,7 +236,7 @@ pub enum DisplayHeaderType { /// use annotate_snippets::display_list::*; /// use annotate_snippets::formatter::DisplayListFormatter; /// - /// let dlf = DisplayListFormatter::new(false); // Don't use colors + /// let dlf = DisplayListFormatter::new(false, false); // Don't use colors /// /// let dl = DisplayList { /// body: vec![ diff --git a/vendor/annotate-snippets/src/formatter/mod.rs b/vendor/annotate-snippets/src/formatter/mod.rs index 45fee74ce0..654b51893b 100644 --- a/vendor/annotate-snippets/src/formatter/mod.rs +++ b/vendor/annotate-snippets/src/formatter/mod.rs @@ -20,9 +20,11 @@ fn repeat_char(c: char, n: usize) -> String { s.repeat(n) } -/// DisplayListFormatter' constructor accepts a single argument which -/// allows the formatter to optionally apply colors and emphasis -/// using `ansi_term` crate. +/// DisplayListFormatter' constructor accepts two arguments: +/// +/// * `color` allows the formatter to optionally apply colors and emphasis +/// using the `ansi_term` crate. +/// * `anonymized_line_numbers` will replace line numbers in the left column with the text `LL`. /// /// Example: /// @@ -30,7 +32,7 @@ fn repeat_char(c: char, n: usize) -> String { /// use annotate_snippets::formatter::DisplayListFormatter; /// use annotate_snippets::display_list::{DisplayList, DisplayLine, DisplaySourceLine}; /// -/// let dlf = DisplayListFormatter::new(false); // Don't use colors +/// let dlf = DisplayListFormatter::new(false, false); // Don't use colors, Don't anonymize line numbers /// /// let dl = DisplayList { /// body: vec![ @@ -47,24 +49,34 @@ fn repeat_char(c: char, n: usize) -> String { /// assert_eq!(dlf.format(&dl), "192 | Example line of text"); /// ``` pub struct DisplayListFormatter { - stylesheet: Box, + stylesheet: Box, + anonymized_line_numbers: bool, } impl DisplayListFormatter { - /// Constructor for the struct. The argument `color` selects - /// the stylesheet depending on the user preferences and `ansi_term` - /// crate availability. - pub fn new(color: bool) -> Self { + const ANONYMIZED_LINE_NUM: &'static str = "LL"; + + /// Constructor for the struct. + /// + /// The argument `color` selects the stylesheet depending on the user preferences and + /// `ansi_term` crate availability. + /// + /// The argument `anonymized_line_numbers` will replace line numbers in the left column with + /// the text `LL`. This can be useful to enable when running UI tests, such as in the Rust + /// test suite. + pub fn new(color: bool, anonymized_line_numbers: bool) -> Self { if color { Self { #[cfg(feature = "ansi_term")] stylesheet: Box::new(AnsiTermStylesheet {}), #[cfg(not(feature = "ansi_term"))] stylesheet: Box::new(NoColorStylesheet {}), + anonymized_line_numbers, } } else { Self { stylesheet: Box::new(NoColorStylesheet {}), + anonymized_line_numbers, } } } @@ -75,7 +87,13 @@ impl DisplayListFormatter { DisplayLine::Source { lineno: Some(lineno), .. - } => cmp::max(lineno.to_string().len(), max), + } => { + if self.anonymized_line_numbers { + Self::ANONYMIZED_LINE_NUM.len() + } else { + cmp::max(lineno.to_string().len(), max) + } + }, _ => max, }); let inline_marks_width = dl.body.iter().fold(0, |max, line| match line { @@ -101,7 +119,7 @@ impl DisplayListFormatter { } } - fn get_annotation_style(&self, annotation_type: &DisplayAnnotationType) -> Box", "", "-->", "?>", "]]>", ">"]; /// Returns an index into HTML_END_TAGS. /// Assumes `text_bytes` is preceded by `<`. -fn get_html_end_tag(text_bytes : &[u8]) -> Option { +fn get_html_end_tag(text_bytes: &[u8]) -> Option { static BEGIN_TAGS: &[&[u8]; 3] = &[b"pre", b"style", b"script"]; static ST_BEGIN_TAGS: &[&[u8]; 3] = &[b"!--", b"?", b"![CDATA["]; @@ -1432,8 +1497,11 @@ fn get_html_end_tag(text_bytes : &[u8]) -> Option { } } - if text_bytes.len() > 1 && text_bytes[0] == b'!' - && text_bytes[1] >= b'A' && text_bytes[1] <= b'Z' { + if text_bytes.len() > 1 + && text_bytes[0] == b'!' + && text_bytes[1] >= b'A' + && text_bytes[1] <= b'Z' + { Some(6) } else { None @@ -1442,10 +1510,10 @@ fn get_html_end_tag(text_bytes : &[u8]) -> Option { #[derive(Copy, Clone, Debug)] struct InlineEl { - start: TreeIndex, // offset of tree node + start: TreeIndex, // offset of tree node count: usize, - c: u8, // b'*' or b'_' - both: bool, // can both open and close + c: u8, // b'*' or b'_' + both: bool, // can both open and close } #[derive(Debug, Clone, Default)] @@ -1468,18 +1536,15 @@ impl InlineStack { const TILDES: usize = 5; const UNDERSCORE_BOTH: usize = 6; - fn pop_all<'a>(&mut self, tree: &mut Tree) { + fn pop_all(&mut self, tree: &mut Tree) { for el in self.stack.drain(..) { for i in 0..el.count { tree[el.start + i].item.body = ItemBody::Text; } } + self.lower_bounds = [0; 7]; } - // both implies *, i think. because _ can never be - // both opener and closer. - // FIXME: it appears _ can be both?? does it matter from a correctness pov? - // yes, probably fn get_lowerbound(&self, c: u8, count: usize, both: bool) -> usize { if c == b'_' { if both { @@ -1492,7 +1557,10 @@ impl InlineStack { if both { mod3_lower } else { - min(mod3_lower, self.lower_bounds[InlineStack::ASTERISK_NOT_BOTH]) + min( + mod3_lower, + self.lower_bounds[InlineStack::ASTERISK_NOT_BOTH], + ) } } else { self.lower_bounds[InlineStack::TILDES] @@ -1516,10 +1584,14 @@ impl InlineStack { } } - fn find_match<'a>(&mut self, tree: &mut Tree, c: u8, count: usize, both: bool) - -> Option - { - let lowerbound = self.get_lowerbound(c, count, both); + fn find_match( + &mut self, + tree: &mut Tree, + c: u8, + count: usize, + both: bool, + ) -> Option { + let lowerbound = min(self.stack.len(), self.get_lowerbound(c, count, both)); let res = self.stack[lowerbound..] .iter() .cloned() @@ -1529,9 +1601,8 @@ impl InlineStack { }); if let Some((matching_ix, matching_el)) = res { - for i in (matching_ix + 1)..self.stack.len() { - let el = self.stack[i]; - self.set_lowerbound(el.c, el.count, el.both, matching_ix.saturating_sub(1)); + let matching_ix = matching_ix + lowerbound; + for el in &self.stack[(matching_ix + 1)..] { for i in 0..el.count { tree[el.start + i].item.body = ItemBody::Text; } @@ -1539,7 +1610,7 @@ impl InlineStack { self.stack.truncate(matching_ix); Some(matching_el) } else { - self.set_lowerbound(c, count, both, self.stack.len().saturating_sub(1)); + self.set_lowerbound(c, count, both, self.stack.len()); None } } @@ -1576,7 +1647,7 @@ fn scan_reference<'a, 'b>(tree: &'a Tree, text: &'b str, cur: TreePointer) }; let start = tree[cur_ix].item.start; let tail = &text.as_bytes()[start..]; - + if tail.starts_with(b"[]") { let closing_node = tree[cur_ix].next.unwrap(); RefScan::Collapsed(tree[closing_node].next) @@ -1656,12 +1727,15 @@ impl CodeDelims { fn insert(&mut self, count: usize, ix: TreeIndex) { if self.seen_first { - self.inner.entry(count).or_insert_with(Default::default).push_back(ix); + self.inner + .entry(count) + .or_insert_with(Default::default) + .push_back(ix); } else { // Skip the first insert, since that delimiter will always // be an opener and not a closer. self.seen_first = true; - } + } } fn is_populated(&self) -> bool { @@ -1770,7 +1844,7 @@ pub struct Parser<'a> { text: &'a str, tree: Tree, allocs: Allocations<'a>, - broken_link_callback: Option<&'a Fn(&str, &str) -> Option<(String, String)>>, + broken_link_callback: Option<&'a dyn Fn(&str, &str) -> Option<(String, String)>>, offset: usize, html_scan_guard: HtmlScanGuard, @@ -1796,7 +1870,7 @@ impl<'a> Parser<'a> { pub fn new_with_broken_link_callback( text: &'a str, options: Options, - broken_link_callback: Option<&'a Fn(&str, &str) -> Option<(String, String)>> + broken_link_callback: Option<&'a dyn Fn(&str, &str) -> Option<(String, String)>>, ) -> Parser<'a> { let first_pass = FirstPass::new(text, options); let (mut tree, allocs) = first_pass.run(); @@ -1805,8 +1879,14 @@ impl<'a> Parser<'a> { let link_stack = Default::default(); let html_scan_guard = Default::default(); Parser { - text, tree, allocs, broken_link_callback, - offset: 0, inline_stack, link_stack, html_scan_guard, + text, + tree, + allocs, + broken_link_callback, + offset: 0, + inline_stack, + link_stack, + html_scan_guard, } } @@ -1865,11 +1945,16 @@ impl<'a> Parser<'a> { continue; } else { let inline_html = if let TreePointer::Valid(next_ix) = next { - self.tree.peek_up() + self.tree + .peek_up() .map(|parent_ix| self.tree[parent_ix].item.end) .and_then(|end_offset| { let bytes = &self.text.as_bytes()[..end_offset]; - scan_inline_html(bytes, self.tree[next_ix].item.start, &mut self.html_scan_guard) + scan_inline_html( + bytes, + self.tree[next_ix].item.start, + &mut self.html_scan_guard, + ) }) } else { None @@ -1913,9 +1998,15 @@ impl<'a> Parser<'a> { } else { // we haven't previously scanned all codeblock delimiters, // so walk the AST - let mut scan = if search_count > 0 { self.tree[cur_ix].next } else { TreePointer::Nil }; + let mut scan = if search_count > 0 { + self.tree[cur_ix].next + } else { + TreePointer::Nil + }; while let TreePointer::Valid(scan_ix) = scan { - if let ItemBody::MaybeCode(delim_count, _) = self.tree[scan_ix].item.body { + if let ItemBody::MaybeCode(delim_count, _) = + self.tree[scan_ix].item.body + { if search_count == delim_count { self.make_code_span(cur_ix, scan_ix, preceded_by_backslash); code_delims.clear(); @@ -1933,11 +2024,17 @@ impl<'a> Parser<'a> { } ItemBody::MaybeLinkOpen => { self.tree[cur_ix].item.body = ItemBody::Text; - self.link_stack.push(LinkStackEl { node: cur_ix, ty: LinkStackTy::Link }); + self.link_stack.push(LinkStackEl { + node: cur_ix, + ty: LinkStackTy::Link, + }); } ItemBody::MaybeImage => { self.tree[cur_ix].item.body = ItemBody::Text; - self.link_stack.push(LinkStackEl { node: cur_ix, ty: LinkStackTy::Image }); + self.link_stack.push(LinkStackEl { + node: cur_ix, + ty: LinkStackTy::Image, + }); } ItemBody::MaybeLinkClose => { if let Some(tos) = self.link_stack.pop() { @@ -1947,11 +2044,13 @@ impl<'a> Parser<'a> { } let next = self.tree[cur_ix].next; - if let Some((next_ix, url, title)) = scan_inline_link(self.text, self.tree[cur_ix].item.end) { + if let Some((next_ix, url, title)) = + scan_inline_link(self.text, self.tree[cur_ix].item.end) + { let next_node = scan_nodes_to_ix(&self.tree, next, next_ix); if let TreePointer::Valid(prev_ix) = prev { self.tree[prev_ix].next = TreePointer::Nil; - } + } cur = TreePointer::Valid(tos.node); cur_ix = tos.node; let link_ix = self.allocs.allocate_link(LinkType::Inline, url, title); @@ -1963,7 +2062,8 @@ impl<'a> Parser<'a> { self.tree[cur_ix].child = self.tree[cur_ix].next; self.tree[cur_ix].next = next_node; if let TreePointer::Valid(next_node_ix) = next_node { - self.tree[next_node_ix].item.start = next_ix; + self.tree[next_node_ix].item.start = + std::cmp::max(self.tree[next_node_ix].item.start, next_ix); } if tos.ty == LinkStackTy::Link { @@ -2000,21 +2100,32 @@ impl<'a> Parser<'a> { if let Some(ReferenceLabel::Footnote(l)) = label { self.tree[tos.node].next = node_after_link; self.tree[tos.node].child = TreePointer::Nil; - self.tree[tos.node].item.body = ItemBody::FootnoteReference(self.allocs.allocate_cow(l)); + self.tree[tos.node].item.body = + ItemBody::FootnoteReference(self.allocs.allocate_cow(l)); prev = TreePointer::Valid(tos.node); cur = node_after_link; self.link_stack.clear(); continue; } else if let Some(ReferenceLabel::Link(link_label)) = label { - let type_url_title = if let Some(matching_def) = self.allocs.refdefs.get(&UniCase::new(link_label.as_ref().into())) { + let type_url_title = if let Some(matching_def) = self + .allocs + .refdefs + .get(&UniCase::new(link_label.as_ref().into())) + { // found a matching definition! - let title = matching_def.title.as_ref().cloned().unwrap_or("".into()); + let title = matching_def + .title + .as_ref() + .cloned() + .unwrap_or_else(|| "".into()); let url = matching_def.dest.clone(); Some((link_type, url, title)) } else if let Some(callback) = self.broken_link_callback { // looked for matching definition, but didn't find it. try to fix // link with callback, if it is defined - if let Some((url, title)) = callback(link_label.as_ref(), link_label.as_ref()) { + if let Some((url, title)) = + callback(link_label.as_ref(), link_label.as_ref()) + { Some((link_type.to_unknown(), url.into(), title.into())) } else { None @@ -2024,8 +2135,10 @@ impl<'a> Parser<'a> { }; if let Some((def_link_type, url, title)) = type_url_title { - let link_ix = self.allocs.allocate_link(def_link_type, url, title); - self.tree[tos.node].item.body = if tos.ty == LinkStackTy::Image { + let link_ix = + self.allocs.allocate_link(def_link_type, url, title); + self.tree[tos.node].item.body = if tos.ty == LinkStackTy::Image + { ItemBody::Image(link_ix) } else { ItemBody::Link(link_ix) @@ -2041,7 +2154,7 @@ impl<'a> Parser<'a> { // finally: disconnect list of children if let TreePointer::Valid(prev_ix) = prev { self.tree[prev_ix].next = TreePointer::Nil; - } + } // set up cur so next node will be node_after_link cur = TreePointer::Valid(tos.node); @@ -2074,15 +2187,19 @@ impl<'a> Parser<'a> { let mut prev_ix: TreeIndex; let mut cur = self.tree.cur(); while let TreePointer::Valid(mut cur_ix) = cur { - if let ItemBody::MaybeEmphasis(mut count, can_open, can_close) = self.tree[cur_ix].item.body { + if let ItemBody::MaybeEmphasis(mut count, can_open, can_close) = + self.tree[cur_ix].item.body + { let c = self.text.as_bytes()[self.tree[cur_ix].item.start]; let both = can_open && can_close; if can_close { - while let Some(el) = self.inline_stack.find_match(&mut self.tree, c, count, both) { + while let Some(el) = + self.inline_stack.find_match(&mut self.tree, c, count, both) + { // have a match! if let TreePointer::Valid(prev_ix) = prev { self.tree[prev_ix].next = TreePointer::Nil; - } + } let match_count = min(count, el.count); // start, end are tree node indices let mut end = cur_ix - 1; @@ -2161,19 +2278,25 @@ impl<'a> Parser<'a> { let first_ix = open + 1; let last_ix = close - 1; let bytes = self.text.as_bytes(); - let mut span_start = self.tree[first_ix].item.start; + let mut span_start = self.tree[open].item.end; let mut span_end = self.tree[close].item.start; let mut buf: Option = None; // detect all-space sequences, since they are kept as-is as of commonmark 0.29 - if ! bytes[span_start..span_end].iter().all(|&b| b == b' ') { - let opening = match bytes[span_start] { b' ' | b'\r' | b'\n' => true, _ => false }; - let closing = match bytes[span_end - 1] { b' ' | b'\r' | b'\n' => true, _ => false }; + if !bytes[span_start..span_end].iter().all(|&b| b == b' ') { + let opening = match bytes[span_start] { + b' ' | b'\r' | b'\n' => true, + _ => false, + }; + let closing = match bytes[span_end - 1] { + b' ' | b'\r' | b'\n' => true, + _ => false, + }; let drop_enclosing_whitespace = opening && closing; if drop_enclosing_whitespace { span_start += 1; - if span_start < span_end { + if span_start < span_end { span_end -= 1; } } @@ -2181,39 +2304,40 @@ impl<'a> Parser<'a> { let mut ix = first_ix; while ix < close { - match self.tree[ix].item.body { - ItemBody::HardBreak | ItemBody::SoftBreak => { - if drop_enclosing_whitespace && - (ix == first_ix && bytes[self.tree[ix].item.start] != b'\\') || - (ix == last_ix && last_ix > first_ix) { - // just ignore it - } else { - let end = bytes[self.tree[ix].item.start..] - .iter() - .position(|&b| b == b'\r' || b == b'\n') - .unwrap() - + self.tree[ix].item.start; - if let Some(ref mut buf) = buf { - buf.push_str(&self.text[self.tree[ix].item.start..end]); - buf.push(' '); - } else { - let mut new_buf = String::with_capacity(span_end - span_start); - new_buf.push_str(&self.text[span_start..end]); - new_buf.push(' '); - buf = Some(new_buf); - } + if let ItemBody::HardBreak | ItemBody::SoftBreak = self.tree[ix].item.body { + if drop_enclosing_whitespace { + // check whether break should be ignored + if ix == first_ix { + ix = ix + 1; + span_start = min(span_end, self.tree[ix].item.start); + continue; + } else if ix == last_ix && last_ix > first_ix { + ix = ix + 1; + continue; } } - _ => { - if let Some(ref mut buf) = buf { - let end = if ix == last_ix { - span_end - } else { - self.tree[ix].item.end - }; - buf.push_str(&self.text[self.tree[ix].item.start..end]); - } + + let end = bytes[self.tree[ix].item.start..] + .iter() + .position(|&b| b == b'\r' || b == b'\n') + .unwrap() + + self.tree[ix].item.start; + if let Some(ref mut buf) = buf { + buf.push_str(&self.text[self.tree[ix].item.start..end]); + buf.push(' '); + } else { + let mut new_buf = String::with_capacity(span_end - span_start); + new_buf.push_str(&self.text[span_start..end]); + new_buf.push(' '); + buf = Some(new_buf); } + } else if let Some(ref mut buf) = buf { + let end = if ix == last_ix { + span_end + } else { + self.tree[ix].item.end + }; + buf.push_str(&self.text[self.tree[ix].item.start..end]); } ix = ix + 1; } @@ -2238,9 +2362,7 @@ impl<'a> Parser<'a> { } pub fn into_offset_iter(self) -> OffsetIter<'a> { - OffsetIter { - inner: self, - } + OffsetIter { inner: self } } } @@ -2248,7 +2370,7 @@ pub(crate) enum LoopInstruction { /// Continue looking for more special bytes, but skip next few bytes. ContinueAndSkip(usize), /// Break looping immediately, returning with the given index and value. - BreakAtWith(usize, T) + BreakAtWith(usize, T), } /// This function walks the byte slices from the given index and @@ -2262,16 +2384,26 @@ pub(crate) enum LoopInstruction { /// If `BreakAtWith(..)` is never returned, this function will return the first /// index that is outside the byteslice bound and a `None` value. fn iterate_special_bytes(bytes: &[u8], ix: usize, callback: F) -> (usize, Option) - where F: FnMut(usize, u8) -> LoopInstruction> +where + F: FnMut(usize, u8) -> LoopInstruction>, { - #[cfg(all(target_arch = "x86_64", feature="simd"))] - { crate::simd::iterate_special_bytes(bytes, ix, callback) } - #[cfg(not(all(target_arch = "x86_64", feature="simd")))] - { scalar_iterate_special_bytes(bytes, ix, callback) } + #[cfg(all(target_arch = "x86_64", feature = "simd"))] + { + crate::simd::iterate_special_bytes(bytes, ix, callback) + } + #[cfg(not(all(target_arch = "x86_64", feature = "simd")))] + { + scalar_iterate_special_bytes(bytes, ix, callback) + } } -pub(crate) fn scalar_iterate_special_bytes(bytes: &[u8], mut ix: usize, mut callback: F) -> (usize, Option) - where F: FnMut(usize, u8) -> LoopInstruction> +pub(crate) fn scalar_iterate_special_bytes( + bytes: &[u8], + mut ix: usize, + mut callback: F, +) -> (usize, Option) +where + F: FnMut(usize, u8) -> LoopInstruction>, { while ix < bytes.len() { match callback(ix, bytes[ix]) { @@ -2300,7 +2432,10 @@ impl<'a> Iterator for OffsetIter<'a> { let ix = self.inner.tree.pop()?; let tag = item_to_tag(&self.inner.tree[ix].item, &self.inner.allocs); self.inner.tree.next_sibling(ix); - Some((Event::End(tag), self.inner.tree[ix].item.start..self.inner.tree[ix].item.end)) + Some(( + Event::End(tag), + self.inner.tree[ix].item.start..self.inner.tree[ix].item.end, + )) } TreePointer::Valid(cur_ix) => { if self.inner.tree[cur_ix].item.body.is_inline() { @@ -2337,8 +2472,7 @@ fn item_to_tag<'a>(item: &Item, allocs: &Allocations<'a>) -> Tag<'a> { } ItemBody::Rule => Tag::Rule, ItemBody::Header(level) => Tag::Header(level), - ItemBody::FencedCodeBlock(cow_ix) => - Tag::CodeBlock(allocs[cow_ix].clone()), + ItemBody::FencedCodeBlock(cow_ix) => Tag::CodeBlock(allocs[cow_ix].clone()), ItemBody::IndentCodeBlock => Tag::CodeBlock("".into()), ItemBody::BlockQuote => Tag::BlockQuote, ItemBody::List(_, c, listitem_start) => { @@ -2353,31 +2487,24 @@ fn item_to_tag<'a>(item: &Item, allocs: &Allocations<'a>) -> Tag<'a> { ItemBody::TableHead => Tag::TableHead, ItemBody::TableCell => Tag::TableCell, ItemBody::TableRow => Tag::TableRow, - ItemBody::Table(alignment_ix) => { - Tag::Table(allocs[alignment_ix].clone()) - } - ItemBody::FootnoteDefinition(cow_ix) => - Tag::FootnoteDefinition(allocs[cow_ix].clone()), - _ => panic!("unexpected item body {:?}", item.body) + ItemBody::Table(alignment_ix) => Tag::Table(allocs[alignment_ix].clone()), + ItemBody::FootnoteDefinition(cow_ix) => Tag::FootnoteDefinition(allocs[cow_ix].clone()), + _ => panic!("unexpected item body {:?}", item.body), } } fn item_to_event<'a>(item: Item, text: &'a str, allocs: &Allocations<'a>) -> Event<'a> { let tag = match item.body { - ItemBody::Text => - return Event::Text(text[item.start..item.end].into()), - ItemBody::Code(cow_ix) => - return Event::Code(allocs[cow_ix].clone()), - ItemBody::SynthesizeText(cow_ix) => - return Event::Text(allocs[cow_ix].clone()), - ItemBody::Html => - return Event::Html(text[item.start..item.end].into()), - ItemBody::InlineHtml => - return Event::InlineHtml(text[item.start..item.end].into()), + ItemBody::Text => return Event::Text(text[item.start..item.end].into()), + ItemBody::Code(cow_ix) => return Event::Code(allocs[cow_ix].clone()), + ItemBody::SynthesizeText(cow_ix) => return Event::Text(allocs[cow_ix].clone()), + ItemBody::Html => return Event::Html(text[item.start..item.end].into()), + ItemBody::InlineHtml => return Event::InlineHtml(text[item.start..item.end].into()), ItemBody::SoftBreak => return Event::SoftBreak, ItemBody::HardBreak => return Event::HardBreak, - ItemBody::FootnoteReference(cow_ix) => - return Event::FootnoteReference(allocs[cow_ix].clone()), + ItemBody::FootnoteReference(cow_ix) => { + return Event::FootnoteReference(allocs[cow_ix].clone()) + } ItemBody::TaskListMarker(checked) => return Event::TaskListMarker(checked), ItemBody::Paragraph => Tag::Paragraph, @@ -2394,8 +2521,7 @@ fn item_to_event<'a>(item: Item, text: &'a str, allocs: &Allocations<'a>) -> Eve } ItemBody::Rule => Tag::Rule, ItemBody::Header(level) => Tag::Header(level), - ItemBody::FencedCodeBlock(cow_ix) => - Tag::CodeBlock(allocs[cow_ix].clone()), + ItemBody::FencedCodeBlock(cow_ix) => Tag::CodeBlock(allocs[cow_ix].clone()), ItemBody::IndentCodeBlock => Tag::CodeBlock("".into()), ItemBody::BlockQuote => Tag::BlockQuote, ItemBody::List(_, c, listitem_start) => { @@ -2410,19 +2536,16 @@ fn item_to_event<'a>(item: Item, text: &'a str, allocs: &Allocations<'a>) -> Eve ItemBody::TableHead => Tag::TableHead, ItemBody::TableCell => Tag::TableCell, ItemBody::TableRow => Tag::TableRow, - ItemBody::Table(alignment_ix) => { - Tag::Table(allocs[alignment_ix].clone()) - } - ItemBody::FootnoteDefinition(cow_ix) => - Tag::FootnoteDefinition(allocs[cow_ix].clone()), - _ => panic!("unexpected item body {:?}", item.body) + ItemBody::Table(alignment_ix) => Tag::Table(allocs[alignment_ix].clone()), + ItemBody::FootnoteDefinition(cow_ix) => Tag::FootnoteDefinition(allocs[cow_ix].clone()), + _ => panic!("unexpected item body {:?}", item.body), }; Event::Start(tag) } // https://english.stackexchange.com/a/285573 -fn surgerize_tight_list<'a>(tree : &mut Tree, list_ix: TreeIndex) { +fn surgerize_tight_list(tree: &mut Tree, list_ix: TreeIndex) { let mut list_item = tree[list_ix].child; while let TreePointer::Valid(listitem_ix) = list_item { // first child is special, controls how we repoint list_item.child @@ -2579,6 +2702,12 @@ mod test { parser_with_extensions("[^\r> `][^\r> `][^\r> `][").count(); } + #[test] + fn issue_311() { + // dont crash + parser_with_extensions("\\\u{0d}-\u{09}\\\u{0d}-\u{09}").count(); + } + #[test] fn issue_283() { let input = std::str::from_utf8(b"\xf0\x9b\xb2\x9f = Parser::new("*hello* world") .into_offset_iter() .map(|(_ev, range)| range) .collect(); - let expected_offsets = vec![ - (0..13), - (0..7), - (1..6), - (0..7), - (7..13), - (0..13) - ]; + let expected_offsets = vec![(0..13), (0..7), (1..6), (0..7), (7..13), (0..13)]; assert_eq!(expected_offsets, event_offsets); } @@ -2654,17 +2793,21 @@ mod test { #[test] fn simple_broken_link_callback() { let test_str = "This is a link w/o def: [hello][world]"; - let parser = Parser::new_with_broken_link_callback(test_str, Options::empty(), Some(&|norm, raw| { - assert_eq!("world", raw); - assert_eq!("world", norm); - Some(("YOLO".to_owned(), "SWAG".to_owned())) - })); + let parser = Parser::new_with_broken_link_callback( + test_str, + Options::empty(), + Some(&|norm, raw| { + assert_eq!("world", raw); + assert_eq!("world", norm); + Some(("YOLO".to_owned(), "SWAG".to_owned())) + }), + ); let mut link_tag_count = 0; for (typ, url, title) in parser.filter_map(|event| match event { Event::Start(tag) | Event::End(tag) => match tag { Tag::Link(typ, url, title) => Some((typ, url, title)), _ => None, - } + }, _ => None, }) { link_tag_count += 1; diff --git a/vendor/pulldown-cmark/src/puncttable.rs b/vendor/pulldown-cmark/src/puncttable.rs index 4f3a02ec55..f46464b64f 100644 --- a/vendor/pulldown-cmark/src/puncttable.rs +++ b/vendor/pulldown-cmark/src/puncttable.rs @@ -23,285 +23,285 @@ // Autogenerated by mk_puncttable.py const PUNCT_MASKS_ASCII: [u16; 8] = [ - 0x0000, // U+0000...U+000F - 0x0000, // U+0010...U+001F - 0xfffe, // U+0020...U+002F - 0xfc00, // U+0030...U+003F - 0x0001, // U+0040...U+004F - 0xf800, // U+0050...U+005F - 0x0001, // U+0060...U+006F - 0x7800, // U+0070...U+007F - ]; + 0x0000, // U+0000...U+000F + 0x0000, // U+0010...U+001F + 0xfffe, // U+0020...U+002F + 0xfc00, // U+0030...U+003F + 0x0001, // U+0040...U+004F + 0xf800, // U+0050...U+005F + 0x0001, // U+0060...U+006F + 0x7800, // U+0070...U+007F +]; const PUNCT_TAB: [u16; 132] = [ - 10, // U+00A0...U+00AF - 11, // U+00B0...U+00BF - 55, // U+0370...U+037F - 56, // U+0380...U+038F - 85, // U+0550...U+055F - 88, // U+0580...U+058F - 91, // U+05B0...U+05BF - 92, // U+05C0...U+05CF - 95, // U+05F0...U+05FF - 96, // U+0600...U+060F - 97, // U+0610...U+061F - 102, // U+0660...U+066F - 109, // U+06D0...U+06DF - 112, // U+0700...U+070F - 127, // U+07F0...U+07FF - 131, // U+0830...U+083F - 133, // U+0850...U+085F - 150, // U+0960...U+096F - 151, // U+0970...U+097F - 175, // U+0AF0...U+0AFF - 223, // U+0DF0...U+0DFF - 228, // U+0E40...U+0E4F - 229, // U+0E50...U+0E5F - 240, // U+0F00...U+0F0F - 241, // U+0F10...U+0F1F - 243, // U+0F30...U+0F3F - 248, // U+0F80...U+0F8F - 253, // U+0FD0...U+0FDF - 260, // U+1040...U+104F - 271, // U+10F0...U+10FF - 310, // U+1360...U+136F - 320, // U+1400...U+140F - 358, // U+1660...U+166F - 361, // U+1690...U+169F - 366, // U+16E0...U+16EF - 371, // U+1730...U+173F - 381, // U+17D0...U+17DF - 384, // U+1800...U+180F - 404, // U+1940...U+194F - 417, // U+1A10...U+1A1F - 426, // U+1AA0...U+1AAF - 437, // U+1B50...U+1B5F - 438, // U+1B60...U+1B6F - 447, // U+1BF0...U+1BFF - 451, // U+1C30...U+1C3F - 455, // U+1C70...U+1C7F - 460, // U+1CC0...U+1CCF - 461, // U+1CD0...U+1CDF - 513, // U+2010...U+201F - 514, // U+2020...U+202F - 515, // U+2030...U+203F - 516, // U+2040...U+204F - 517, // U+2050...U+205F - 519, // U+2070...U+207F - 520, // U+2080...U+208F - 560, // U+2300...U+230F - 562, // U+2320...U+232F - 630, // U+2760...U+276F - 631, // U+2770...U+277F - 636, // U+27C0...U+27CF - 638, // U+27E0...U+27EF - 664, // U+2980...U+298F - 665, // U+2990...U+299F - 669, // U+29D0...U+29DF - 671, // U+29F0...U+29FF - 719, // U+2CF0...U+2CFF - 727, // U+2D70...U+2D7F - 736, // U+2E00...U+2E0F - 737, // U+2E10...U+2E1F - 738, // U+2E20...U+2E2F - 739, // U+2E30...U+2E3F - 740, // U+2E40...U+2E4F - 768, // U+3000...U+300F - 769, // U+3010...U+301F - 771, // U+3030...U+303F - 778, // U+30A0...U+30AF - 783, // U+30F0...U+30FF - 2639, // U+A4F0...U+A4FF - 2656, // U+A600...U+A60F - 2663, // U+A670...U+A67F - 2671, // U+A6F0...U+A6FF - 2695, // U+A870...U+A87F - 2700, // U+A8C0...U+A8CF - 2703, // U+A8F0...U+A8FF - 2706, // U+A920...U+A92F - 2709, // U+A950...U+A95F - 2716, // U+A9C0...U+A9CF - 2717, // U+A9D0...U+A9DF - 2725, // U+AA50...U+AA5F - 2733, // U+AAD0...U+AADF - 2735, // U+AAF0...U+AAFF - 2750, // U+ABE0...U+ABEF - 4051, // U+FD30...U+FD3F - 4065, // U+FE10...U+FE1F - 4067, // U+FE30...U+FE3F - 4068, // U+FE40...U+FE4F - 4069, // U+FE50...U+FE5F - 4070, // U+FE60...U+FE6F - 4080, // U+FF00...U+FF0F - 4081, // U+FF10...U+FF1F - 4082, // U+FF20...U+FF2F - 4083, // U+FF30...U+FF3F - 4085, // U+FF50...U+FF5F - 4086, // U+FF60...U+FF6F - 4112, // U+10100...U+1010F - 4153, // U+10390...U+1039F - 4157, // U+103D0...U+103DF - 4182, // U+10560...U+1056F - 4229, // U+10850...U+1085F - 4241, // U+10910...U+1091F - 4243, // U+10930...U+1093F - 4261, // U+10A50...U+10A5F - 4263, // U+10A70...U+10A7F - 4271, // U+10AF0...U+10AFF - 4275, // U+10B30...U+10B3F - 4281, // U+10B90...U+10B9F - 4356, // U+11040...U+1104F - 4363, // U+110B0...U+110BF - 4364, // U+110C0...U+110CF - 4372, // U+11140...U+1114F - 4375, // U+11170...U+1117F - 4380, // U+111C0...U+111CF - 4387, // U+11230...U+1123F - 4428, // U+114C0...U+114CF - 4444, // U+115C0...U+115CF - 4452, // U+11640...U+1164F - 4679, // U+12470...U+1247F - 5798, // U+16A60...U+16A6F - 5807, // U+16AF0...U+16AFF - 5811, // U+16B30...U+16B3F - 5812, // U+16B40...U+16B4F - 7113, // U+1BC90...U+1BC9F - ]; + 10, // U+00A0...U+00AF + 11, // U+00B0...U+00BF + 55, // U+0370...U+037F + 56, // U+0380...U+038F + 85, // U+0550...U+055F + 88, // U+0580...U+058F + 91, // U+05B0...U+05BF + 92, // U+05C0...U+05CF + 95, // U+05F0...U+05FF + 96, // U+0600...U+060F + 97, // U+0610...U+061F + 102, // U+0660...U+066F + 109, // U+06D0...U+06DF + 112, // U+0700...U+070F + 127, // U+07F0...U+07FF + 131, // U+0830...U+083F + 133, // U+0850...U+085F + 150, // U+0960...U+096F + 151, // U+0970...U+097F + 175, // U+0AF0...U+0AFF + 223, // U+0DF0...U+0DFF + 228, // U+0E40...U+0E4F + 229, // U+0E50...U+0E5F + 240, // U+0F00...U+0F0F + 241, // U+0F10...U+0F1F + 243, // U+0F30...U+0F3F + 248, // U+0F80...U+0F8F + 253, // U+0FD0...U+0FDF + 260, // U+1040...U+104F + 271, // U+10F0...U+10FF + 310, // U+1360...U+136F + 320, // U+1400...U+140F + 358, // U+1660...U+166F + 361, // U+1690...U+169F + 366, // U+16E0...U+16EF + 371, // U+1730...U+173F + 381, // U+17D0...U+17DF + 384, // U+1800...U+180F + 404, // U+1940...U+194F + 417, // U+1A10...U+1A1F + 426, // U+1AA0...U+1AAF + 437, // U+1B50...U+1B5F + 438, // U+1B60...U+1B6F + 447, // U+1BF0...U+1BFF + 451, // U+1C30...U+1C3F + 455, // U+1C70...U+1C7F + 460, // U+1CC0...U+1CCF + 461, // U+1CD0...U+1CDF + 513, // U+2010...U+201F + 514, // U+2020...U+202F + 515, // U+2030...U+203F + 516, // U+2040...U+204F + 517, // U+2050...U+205F + 519, // U+2070...U+207F + 520, // U+2080...U+208F + 560, // U+2300...U+230F + 562, // U+2320...U+232F + 630, // U+2760...U+276F + 631, // U+2770...U+277F + 636, // U+27C0...U+27CF + 638, // U+27E0...U+27EF + 664, // U+2980...U+298F + 665, // U+2990...U+299F + 669, // U+29D0...U+29DF + 671, // U+29F0...U+29FF + 719, // U+2CF0...U+2CFF + 727, // U+2D70...U+2D7F + 736, // U+2E00...U+2E0F + 737, // U+2E10...U+2E1F + 738, // U+2E20...U+2E2F + 739, // U+2E30...U+2E3F + 740, // U+2E40...U+2E4F + 768, // U+3000...U+300F + 769, // U+3010...U+301F + 771, // U+3030...U+303F + 778, // U+30A0...U+30AF + 783, // U+30F0...U+30FF + 2639, // U+A4F0...U+A4FF + 2656, // U+A600...U+A60F + 2663, // U+A670...U+A67F + 2671, // U+A6F0...U+A6FF + 2695, // U+A870...U+A87F + 2700, // U+A8C0...U+A8CF + 2703, // U+A8F0...U+A8FF + 2706, // U+A920...U+A92F + 2709, // U+A950...U+A95F + 2716, // U+A9C0...U+A9CF + 2717, // U+A9D0...U+A9DF + 2725, // U+AA50...U+AA5F + 2733, // U+AAD0...U+AADF + 2735, // U+AAF0...U+AAFF + 2750, // U+ABE0...U+ABEF + 4051, // U+FD30...U+FD3F + 4065, // U+FE10...U+FE1F + 4067, // U+FE30...U+FE3F + 4068, // U+FE40...U+FE4F + 4069, // U+FE50...U+FE5F + 4070, // U+FE60...U+FE6F + 4080, // U+FF00...U+FF0F + 4081, // U+FF10...U+FF1F + 4082, // U+FF20...U+FF2F + 4083, // U+FF30...U+FF3F + 4085, // U+FF50...U+FF5F + 4086, // U+FF60...U+FF6F + 4112, // U+10100...U+1010F + 4153, // U+10390...U+1039F + 4157, // U+103D0...U+103DF + 4182, // U+10560...U+1056F + 4229, // U+10850...U+1085F + 4241, // U+10910...U+1091F + 4243, // U+10930...U+1093F + 4261, // U+10A50...U+10A5F + 4263, // U+10A70...U+10A7F + 4271, // U+10AF0...U+10AFF + 4275, // U+10B30...U+10B3F + 4281, // U+10B90...U+10B9F + 4356, // U+11040...U+1104F + 4363, // U+110B0...U+110BF + 4364, // U+110C0...U+110CF + 4372, // U+11140...U+1114F + 4375, // U+11170...U+1117F + 4380, // U+111C0...U+111CF + 4387, // U+11230...U+1123F + 4428, // U+114C0...U+114CF + 4444, // U+115C0...U+115CF + 4452, // U+11640...U+1164F + 4679, // U+12470...U+1247F + 5798, // U+16A60...U+16A6F + 5807, // U+16AF0...U+16AFF + 5811, // U+16B30...U+16B3F + 5812, // U+16B40...U+16B4F + 7113, // U+1BC90...U+1BC9F +]; const PUNCT_MASKS: [u16; 132] = [ - 0x0882, // U+00A0...U+00AF - 0x88c0, // U+00B0...U+00BF - 0x4000, // U+0370...U+037F - 0x0080, // U+0380...U+038F - 0xfc00, // U+0550...U+055F - 0x0600, // U+0580...U+058F - 0x4000, // U+05B0...U+05BF - 0x0049, // U+05C0...U+05CF - 0x0018, // U+05F0...U+05FF - 0x3600, // U+0600...U+060F - 0xc800, // U+0610...U+061F - 0x3c00, // U+0660...U+066F - 0x0010, // U+06D0...U+06DF - 0x3fff, // U+0700...U+070F - 0x0380, // U+07F0...U+07FF - 0x7fff, // U+0830...U+083F - 0x4000, // U+0850...U+085F - 0x0030, // U+0960...U+096F - 0x0001, // U+0970...U+097F - 0x0001, // U+0AF0...U+0AFF - 0x0010, // U+0DF0...U+0DFF - 0x8000, // U+0E40...U+0E4F - 0x0c00, // U+0E50...U+0E5F - 0xfff0, // U+0F00...U+0F0F - 0x0017, // U+0F10...U+0F1F - 0x3c00, // U+0F30...U+0F3F - 0x0020, // U+0F80...U+0F8F - 0x061f, // U+0FD0...U+0FDF - 0xfc00, // U+1040...U+104F - 0x0800, // U+10F0...U+10FF - 0x01ff, // U+1360...U+136F - 0x0001, // U+1400...U+140F - 0x6000, // U+1660...U+166F - 0x1800, // U+1690...U+169F - 0x3800, // U+16E0...U+16EF - 0x0060, // U+1730...U+173F - 0x0770, // U+17D0...U+17DF - 0x07ff, // U+1800...U+180F - 0x0030, // U+1940...U+194F - 0xc000, // U+1A10...U+1A1F - 0x3f7f, // U+1AA0...U+1AAF - 0xfc00, // U+1B50...U+1B5F - 0x0001, // U+1B60...U+1B6F - 0xf000, // U+1BF0...U+1BFF - 0xf800, // U+1C30...U+1C3F - 0xc000, // U+1C70...U+1C7F - 0x00ff, // U+1CC0...U+1CCF - 0x0008, // U+1CD0...U+1CDF - 0xffff, // U+2010...U+201F - 0x00ff, // U+2020...U+202F - 0xffff, // U+2030...U+203F - 0xffef, // U+2040...U+204F - 0x7ffb, // U+2050...U+205F - 0x6000, // U+2070...U+207F - 0x6000, // U+2080...U+208F - 0x0f00, // U+2300...U+230F - 0x0600, // U+2320...U+232F - 0xff00, // U+2760...U+276F - 0x003f, // U+2770...U+277F - 0x0060, // U+27C0...U+27CF - 0xffc0, // U+27E0...U+27EF - 0xfff8, // U+2980...U+298F - 0x01ff, // U+2990...U+299F - 0x0f00, // U+29D0...U+29DF - 0x3000, // U+29F0...U+29FF - 0xde00, // U+2CF0...U+2CFF - 0x0001, // U+2D70...U+2D7F - 0xffff, // U+2E00...U+2E0F - 0xffff, // U+2E10...U+2E1F - 0x7fff, // U+2E20...U+2E2F - 0xffff, // U+2E30...U+2E3F - 0x0007, // U+2E40...U+2E4F - 0xff0e, // U+3000...U+300F - 0xfff3, // U+3010...U+301F - 0x2001, // U+3030...U+303F - 0x0001, // U+30A0...U+30AF - 0x0800, // U+30F0...U+30FF - 0xc000, // U+A4F0...U+A4FF - 0xe000, // U+A600...U+A60F - 0x4008, // U+A670...U+A67F - 0x00fc, // U+A6F0...U+A6FF - 0x00f0, // U+A870...U+A87F - 0xc000, // U+A8C0...U+A8CF - 0x0700, // U+A8F0...U+A8FF - 0xc000, // U+A920...U+A92F - 0x8000, // U+A950...U+A95F - 0x3ffe, // U+A9C0...U+A9CF - 0xc000, // U+A9D0...U+A9DF - 0xf000, // U+AA50...U+AA5F - 0xc000, // U+AAD0...U+AADF - 0x0003, // U+AAF0...U+AAFF - 0x0800, // U+ABE0...U+ABEF - 0xc000, // U+FD30...U+FD3F - 0x03ff, // U+FE10...U+FE1F - 0xffff, // U+FE30...U+FE3F - 0xffff, // U+FE40...U+FE4F - 0xfff7, // U+FE50...U+FE5F - 0x0d0b, // U+FE60...U+FE6F - 0xf7ee, // U+FF00...U+FF0F - 0x8c00, // U+FF10...U+FF1F - 0x0001, // U+FF20...U+FF2F - 0xb800, // U+FF30...U+FF3F - 0xa800, // U+FF50...U+FF5F - 0x003f, // U+FF60...U+FF6F - 0x0007, // U+10100...U+1010F - 0x8000, // U+10390...U+1039F - 0x0001, // U+103D0...U+103DF - 0x8000, // U+10560...U+1056F - 0x0080, // U+10850...U+1085F - 0x8000, // U+10910...U+1091F - 0x8000, // U+10930...U+1093F - 0x01ff, // U+10A50...U+10A5F - 0x8000, // U+10A70...U+10A7F - 0x007f, // U+10AF0...U+10AFF - 0xfe00, // U+10B30...U+10B3F - 0x1e00, // U+10B90...U+10B9F - 0x3f80, // U+11040...U+1104F - 0xd800, // U+110B0...U+110BF - 0x0003, // U+110C0...U+110CF - 0x000f, // U+11140...U+1114F - 0x0030, // U+11170...U+1117F - 0x21e0, // U+111C0...U+111CF - 0x3f00, // U+11230...U+1123F - 0x0040, // U+114C0...U+114CF - 0x03fe, // U+115C0...U+115CF - 0x000e, // U+11640...U+1164F - 0x001f, // U+12470...U+1247F - 0xc000, // U+16A60...U+16A6F - 0x0020, // U+16AF0...U+16AFF - 0x0f80, // U+16B30...U+16B3F - 0x0010, // U+16B40...U+16B4F - 0x8000, // U+1BC90...U+1BC9F - ]; + 0x0882, // U+00A0...U+00AF + 0x88c0, // U+00B0...U+00BF + 0x4000, // U+0370...U+037F + 0x0080, // U+0380...U+038F + 0xfc00, // U+0550...U+055F + 0x0600, // U+0580...U+058F + 0x4000, // U+05B0...U+05BF + 0x0049, // U+05C0...U+05CF + 0x0018, // U+05F0...U+05FF + 0x3600, // U+0600...U+060F + 0xc800, // U+0610...U+061F + 0x3c00, // U+0660...U+066F + 0x0010, // U+06D0...U+06DF + 0x3fff, // U+0700...U+070F + 0x0380, // U+07F0...U+07FF + 0x7fff, // U+0830...U+083F + 0x4000, // U+0850...U+085F + 0x0030, // U+0960...U+096F + 0x0001, // U+0970...U+097F + 0x0001, // U+0AF0...U+0AFF + 0x0010, // U+0DF0...U+0DFF + 0x8000, // U+0E40...U+0E4F + 0x0c00, // U+0E50...U+0E5F + 0xfff0, // U+0F00...U+0F0F + 0x0017, // U+0F10...U+0F1F + 0x3c00, // U+0F30...U+0F3F + 0x0020, // U+0F80...U+0F8F + 0x061f, // U+0FD0...U+0FDF + 0xfc00, // U+1040...U+104F + 0x0800, // U+10F0...U+10FF + 0x01ff, // U+1360...U+136F + 0x0001, // U+1400...U+140F + 0x6000, // U+1660...U+166F + 0x1800, // U+1690...U+169F + 0x3800, // U+16E0...U+16EF + 0x0060, // U+1730...U+173F + 0x0770, // U+17D0...U+17DF + 0x07ff, // U+1800...U+180F + 0x0030, // U+1940...U+194F + 0xc000, // U+1A10...U+1A1F + 0x3f7f, // U+1AA0...U+1AAF + 0xfc00, // U+1B50...U+1B5F + 0x0001, // U+1B60...U+1B6F + 0xf000, // U+1BF0...U+1BFF + 0xf800, // U+1C30...U+1C3F + 0xc000, // U+1C70...U+1C7F + 0x00ff, // U+1CC0...U+1CCF + 0x0008, // U+1CD0...U+1CDF + 0xffff, // U+2010...U+201F + 0x00ff, // U+2020...U+202F + 0xffff, // U+2030...U+203F + 0xffef, // U+2040...U+204F + 0x7ffb, // U+2050...U+205F + 0x6000, // U+2070...U+207F + 0x6000, // U+2080...U+208F + 0x0f00, // U+2300...U+230F + 0x0600, // U+2320...U+232F + 0xff00, // U+2760...U+276F + 0x003f, // U+2770...U+277F + 0x0060, // U+27C0...U+27CF + 0xffc0, // U+27E0...U+27EF + 0xfff8, // U+2980...U+298F + 0x01ff, // U+2990...U+299F + 0x0f00, // U+29D0...U+29DF + 0x3000, // U+29F0...U+29FF + 0xde00, // U+2CF0...U+2CFF + 0x0001, // U+2D70...U+2D7F + 0xffff, // U+2E00...U+2E0F + 0xffff, // U+2E10...U+2E1F + 0x7fff, // U+2E20...U+2E2F + 0xffff, // U+2E30...U+2E3F + 0x0007, // U+2E40...U+2E4F + 0xff0e, // U+3000...U+300F + 0xfff3, // U+3010...U+301F + 0x2001, // U+3030...U+303F + 0x0001, // U+30A0...U+30AF + 0x0800, // U+30F0...U+30FF + 0xc000, // U+A4F0...U+A4FF + 0xe000, // U+A600...U+A60F + 0x4008, // U+A670...U+A67F + 0x00fc, // U+A6F0...U+A6FF + 0x00f0, // U+A870...U+A87F + 0xc000, // U+A8C0...U+A8CF + 0x0700, // U+A8F0...U+A8FF + 0xc000, // U+A920...U+A92F + 0x8000, // U+A950...U+A95F + 0x3ffe, // U+A9C0...U+A9CF + 0xc000, // U+A9D0...U+A9DF + 0xf000, // U+AA50...U+AA5F + 0xc000, // U+AAD0...U+AADF + 0x0003, // U+AAF0...U+AAFF + 0x0800, // U+ABE0...U+ABEF + 0xc000, // U+FD30...U+FD3F + 0x03ff, // U+FE10...U+FE1F + 0xffff, // U+FE30...U+FE3F + 0xffff, // U+FE40...U+FE4F + 0xfff7, // U+FE50...U+FE5F + 0x0d0b, // U+FE60...U+FE6F + 0xf7ee, // U+FF00...U+FF0F + 0x8c00, // U+FF10...U+FF1F + 0x0001, // U+FF20...U+FF2F + 0xb800, // U+FF30...U+FF3F + 0xa800, // U+FF50...U+FF5F + 0x003f, // U+FF60...U+FF6F + 0x0007, // U+10100...U+1010F + 0x8000, // U+10390...U+1039F + 0x0001, // U+103D0...U+103DF + 0x8000, // U+10560...U+1056F + 0x0080, // U+10850...U+1085F + 0x8000, // U+10910...U+1091F + 0x8000, // U+10930...U+1093F + 0x01ff, // U+10A50...U+10A5F + 0x8000, // U+10A70...U+10A7F + 0x007f, // U+10AF0...U+10AFF + 0xfe00, // U+10B30...U+10B3F + 0x1e00, // U+10B90...U+10B9F + 0x3f80, // U+11040...U+1104F + 0xd800, // U+110B0...U+110BF + 0x0003, // U+110C0...U+110CF + 0x000f, // U+11140...U+1114F + 0x0030, // U+11170...U+1117F + 0x21e0, // U+111C0...U+111CF + 0x3f00, // U+11230...U+1123F + 0x0040, // U+114C0...U+114CF + 0x03fe, // U+115C0...U+115CF + 0x000e, // U+11640...U+1164F + 0x001f, // U+12470...U+1247F + 0xc000, // U+16A60...U+16A6F + 0x0020, // U+16AF0...U+16AFF + 0x0f80, // U+16B30...U+16B3F + 0x0010, // U+16B40...U+16B4F + 0x8000, // U+1BC90...U+1BC9F +]; pub fn is_ascii_punctuation(c: u8) -> bool { c < 128 && (PUNCT_MASKS_ASCII[(c / 16) as usize] & (1 << (c & 15))) != 0 @@ -309,12 +309,16 @@ pub fn is_ascii_punctuation(c: u8) -> bool { pub fn is_punctuation(c: char) -> bool { let cp = c as u32; - if cp < 128 {return is_ascii_punctuation(cp as u8); } - if cp > 0x1BC9F { return false; } + if cp < 128 { + return is_ascii_punctuation(cp as u8); + } + if cp > 0x1BC9F { + return false; + } let high = (cp / 16) as u16; match PUNCT_TAB.binary_search(&high) { Ok(index) => (PUNCT_MASKS[index] & (1 << (cp & 15))) != 0, - _ => false + _ => false, } } @@ -345,4 +349,3 @@ mod tests { assert!(!is_punctuation('\u{1BCA0}')); } } - diff --git a/vendor/pulldown-cmark/src/scanners.rs b/vendor/pulldown-cmark/src/scanners.rs index ebcd02bd62..ea7b5d4b98 100644 --- a/vendor/pulldown-cmark/src/scanners.rs +++ b/vendor/pulldown-cmark/src/scanners.rs @@ -24,9 +24,9 @@ use std::char; use std::convert::TryInto; use crate::entities; -use crate::parse::{Alignment, LinkType, HtmlScanGuard}; -use crate::strings::CowStr; +use crate::parse::{Alignment, HtmlScanGuard, LinkType}; pub use crate::puncttable::{is_ascii_punctuation, is_punctuation}; +use crate::strings::CowStr; use memchr::memchr; @@ -38,15 +38,70 @@ use memchr::memchr; const LINK_MAX_NESTED_PARENS: usize = 5; // sorted for binary search -const HTML_TAGS: [&str; 62] = ["address", "article", "aside", "base", - "basefont", "blockquote", "body", "caption", "center", "col", "colgroup", - "dd", "details", "dialog", "dir", "div", "dl", "dt", "fieldset", - "figcaption", "figure", "footer", "form", "frame", "frameset", "h1", - "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html", "iframe", - "legend", "li", "link", "main", "menu", "menuitem", "nav", "noframes", - "ol", "optgroup", "option", "p", "param", "section", "source", "summary", - "table", "tbody", "td", "tfoot", "th", "thead", "title", "tr", "track", - "ul"]; +const HTML_TAGS: [&str; 62] = [ + "address", + "article", + "aside", + "base", + "basefont", + "blockquote", + "body", + "caption", + "center", + "col", + "colgroup", + "dd", + "details", + "dialog", + "dir", + "div", + "dl", + "dt", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hr", + "html", + "iframe", + "legend", + "li", + "link", + "main", + "menu", + "menuitem", + "nav", + "noframes", + "ol", + "optgroup", + "option", + "p", + "param", + "section", + "source", + "summary", + "table", + "tbody", + "td", + "tfoot", + "th", + "thead", + "title", + "tr", + "track", + "ul", +]; /// Analysis of the beginning of a line, including indentation and container /// markers. @@ -190,9 +245,15 @@ impl<'a> LineStart<'a> { let val_usize = val as usize; // This will cause some failures on 32 bit arch. // TODO (breaking API change): should be u64, not usize. - if val_usize as u64 != val { return None; } + if val_usize as u64 != val { + return None; + } if self.scan_space(1) || self.is_at_eol() { - return self.finish_list_marker(c, val_usize, indent + self.ix - start_ix); + return self.finish_list_marker( + c, + val_usize, + indent + self.ix - start_ix, + ); } else { break; } @@ -206,9 +267,12 @@ impl<'a> LineStart<'a> { None } - fn finish_list_marker(&mut self, c: u8, start: usize, mut indent: usize) - -> Option<(u8, usize, usize)> - { + fn finish_list_marker( + &mut self, + c: u8, + start: usize, + mut indent: usize, + ) -> Option<(u8, usize, usize)> { let save = self.clone(); // skip the rest of the line if it's blank @@ -253,7 +317,12 @@ impl<'a> LineStart<'a> { *self = save; return None; } - if !self.bytes.get(self.ix).map(|&b| is_ascii_whitespace_no_nl(b)).unwrap_or(false) { + if !self + .bytes + .get(self.ix) + .map(|&b| is_ascii_whitespace_no_nl(b)) + .unwrap_or(false) + { *self = save; return None; } @@ -279,15 +348,15 @@ pub(crate) fn is_ascii_whitespace_no_nl(c: u8) -> bool { fn is_ascii_alpha(c: u8) -> bool { match c { - b'a' ... b'z' | b'A' ... b'Z' => true, - _ => false + b'a'..=b'z' | b'A'..=b'Z' => true, + _ => false, } } fn is_ascii_alphanumeric(c: u8) -> bool { match c { - b'0' ... b'9' | b'a' ... b'z' | b'A' ... b'Z' => true, - _ => false + b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' => true, + _ => false, } } @@ -302,22 +371,30 @@ fn is_digit(c: u8) -> bool { fn is_valid_unquoted_attr_value_char(c: u8) -> bool { match c { b'\'' | b'"' | b' ' | b'=' | b'>' | b'<' | b'`' | b'\n' | b'\r' => false, - _ => true + _ => true, } } // scan a single character pub(crate) fn scan_ch(data: &[u8], c: u8) -> usize { - if !data.is_empty() && data[0] == c { 1 } else { 0 } + if !data.is_empty() && data[0] == c { + 1 + } else { + 0 + } } pub(crate) fn scan_while(data: &[u8], mut f: F) -> usize - where F: FnMut(u8) -> bool { +where + F: FnMut(u8) -> bool, +{ data.iter().take_while(|&&c| f(c)).count() } pub(crate) fn scan_rev_while(data: &[u8], mut f: F) -> usize - where F: FnMut(u8) -> bool { +where + F: FnMut(u8) -> bool, +{ data.iter().rev().take_while(|&&c| f(c)).count() } @@ -336,11 +413,13 @@ fn scan_attr_value_chars(data: &[u8]) -> usize { } pub(crate) fn scan_eol(bytes: &[u8]) -> Option { - if bytes.is_empty() { return Some(0); } + if bytes.is_empty() { + return Some(0); + } match bytes[0] { b'\n' => Some(1), b'\r' => Some(if bytes.get(1) == Some(&b'\n') { 2 } else { 1 }), - _ => None + _ => None, } } @@ -355,11 +434,19 @@ pub(crate) fn scan_nextline(bytes: &[u8]) -> usize { // return: end byte for closing code fence, or None // if the line is not a closing code fence -pub(crate) fn scan_closing_code_fence(bytes: &[u8], fence_char: u8, n_fence_char: usize) -> Option { - if bytes.is_empty() { return Some(0); } +pub(crate) fn scan_closing_code_fence( + bytes: &[u8], + fence_char: u8, + n_fence_char: usize, +) -> Option { + if bytes.is_empty() { + return Some(0); + } let mut i = 0; let num_fence_chars_found = scan_ch_repeat(&bytes[i..], fence_char); - if num_fence_chars_found < n_fence_char { return None; } + if num_fence_chars_found < n_fence_char { + return None; + } i += num_fence_chars_found; let num_trailing_spaces = scan_ch_repeat(&bytes[i..], b' '); i += num_trailing_spaces; @@ -385,7 +472,7 @@ fn calc_indent(text: &[u8], max: usize) -> (usize, usize) { break; } spaces = new_spaces; - }, + } _ => break, } offset = i; @@ -396,15 +483,19 @@ fn calc_indent(text: &[u8], max: usize) -> (usize, usize) { /// Scan hrule opening sequence. /// -/// Returns Ok(x) when it finds an hrule, where x is the +/// Returns Ok(x) when it finds an hrule, where x is the /// size of line containing the hrule, including the trailing newline. -/// +/// /// Returns Err(x) when it does not find an hrule and x is /// the offset in data before no hrule can appear. pub(crate) fn scan_hrule(bytes: &[u8]) -> Result { - if bytes.len() < 3 { return Err(0); } + if bytes.len() < 3 { + return Err(0); + } let c = bytes[0]; - if !(c == b'*' || c == b'-' || c == b'_') { return Err(0); } + if !(c == b'*' || c == b'-' || c == b'_') { + return Err(0); + } let mut n = 0; let mut i = 0; @@ -418,11 +509,15 @@ pub(crate) fn scan_hrule(bytes: &[u8]) -> Result { n += 1; } b' ' | b'\t' => (), - _ => return Err(i) + _ => return Err(i), } i += 1; } - if n >= 3 { Ok(i) } else { Err(i) } + if n >= 3 { + Ok(i) + } else { + Err(i) + } } /// Scan an ATX heading opening sequence. @@ -442,7 +537,9 @@ pub(crate) fn scan_atx_heading(data: &[u8]) -> Option<(usize, i32)> { /// Returns number of bytes in line (including trailing newline) and level. pub(crate) fn scan_setext_heading(data: &[u8]) -> Option<(usize, i32)> { let c = *data.get(0)?; - if !(c == b'-' || c == b'=') { return None; } + if !(c == b'-' || c == b'=') { + return None; + } let mut i = 1 + scan_ch_repeat(&data[1..], c); i += scan_blank_line(&data[i..])?; let level = if c == b'=' { 1 } else { 2 }; @@ -470,28 +567,27 @@ pub(crate) fn scan_table_head(data: &[u8]) -> (usize, Vec) { match *c { b' ' => (), b':' => { - active_col = - match (start_col, active_col) { - (true, Alignment::None) => Alignment::Left, - (false, Alignment::Left) => Alignment::Center, - (false, Alignment::None) => Alignment::Right, - _ => active_col, - }; + active_col = match (start_col, active_col) { + (true, Alignment::None) => Alignment::Left, + (false, Alignment::Left) => Alignment::Center, + (false, Alignment::None) => Alignment::Right, + _ => active_col, + }; start_col = false; } b'-' => { start_col = false; - }, + } b'|' => { start_col = true; cols.push(active_col); active_col = Alignment::None; - }, + } _ => { cols = vec![]; start_col = true; break; - }, + } } i += 1; } @@ -508,7 +604,9 @@ pub(crate) fn scan_table_head(data: &[u8]) -> (usize, Vec) { /// Returns number of bytes scanned and the char that is repeated to make the code fence. pub(crate) fn scan_code_fence(data: &[u8]) -> Option<(usize, u8)> { let c = *data.get(0)?; - if !(c == b'`' || c == b'~') { return None; } + if !(c == b'`' || c == b'~') { + return None; + } let i = 1 + scan_ch_repeat(&data[1..], c); if i >= 3 { if c == b'`' { @@ -551,20 +649,22 @@ pub(crate) fn scan_listitem(bytes: &[u8]) -> Option<(usize, u8, usize, usize)> { let mut c = *bytes.get(0)?; let (w, start) = match c { b'-' | b'+' | b'*' => (1, 0), - b'0' ... b'9' => { + b'0'..=b'9' => { let (length, start) = parse_decimal(bytes); c = *bytes.get(length)?; - if !(c == b'.' || c == b')') { return None; } + if !(c == b'.' || c == b')') { + return None; + } (length + 1, start) } - _ => { return None; } + _ => { + return None; + } }; // TODO: replace calc_indent with scan_leading_whitespace, for tab correctness - let (mut postn, mut postindent) = calc_indent(&bytes[w.. ], 5); + let (mut postn, mut postindent) = calc_indent(&bytes[w..], 5); if postindent == 0 { - if scan_eol(&bytes[w..]).is_none() { - return None; - } + scan_eol(&bytes[w..])?; postindent += 1; } else if postindent > 4 { postn = 1; @@ -579,44 +679,49 @@ pub(crate) fn scan_listitem(bytes: &[u8]) -> Option<(usize, u8, usize, usize)> { // returns (number of bytes, parsed decimal) fn parse_decimal(bytes: &[u8]) -> (usize, usize) { - match bytes.iter() + match bytes + .iter() .take_while(|&&b| is_digit(b)) .try_fold((0, 0usize), |(count, acc), c| { - match acc.checked_mul(10) { - Some(ten_acc) => Ok((count + 1, ten_acc + usize::from(c - b'0'))), + let digit = usize::from(c - b'0'); + match acc + .checked_mul(10) + .and_then(|ten_acc| ten_acc.checked_add(digit)) + { + Some(number) => Ok((count + 1, number)), // stop early on overflow None => Err((count, acc)), } - }) - { - Ok(p) | Err(p) => p, + }) { + Ok(p) | Err(p) => p, } } // returns (number of bytes, parsed hex) fn parse_hex(bytes: &[u8]) -> (usize, usize) { - match bytes.iter() - .try_fold((0, 0usize), |(count, acc), c| { - let mut c = *c; - let digit = if c >= b'0' && c <= b'9' { - usize::from(c - b'0') + match bytes.iter().try_fold((0, 0usize), |(count, acc), c| { + let mut c = *c; + let digit = if c >= b'0' && c <= b'9' { + usize::from(c - b'0') + } else { + // make lower case + c |= 0x20; + if c >= b'a' && c <= b'f' { + usize::from(c - b'a' + 10) } else { - // make lower case - c |= 0x20; - if c >= b'a' && c <= b'f' { - usize::from(c - b'a' + 10) - } else { - return Err((count, acc)); - } - }; - match acc.checked_mul(16) { - Some(sixteen_acc) => Ok((count + 1, sixteen_acc + digit)), - // stop early on overflow - None => Err((count, acc)), + return Err((count, acc)); } - }) - { - Ok(p) | Err(p) => p, + }; + match acc + .checked_mul(16) + .and_then(|sixteen_acc| sixteen_acc.checked_add(digit)) + { + Some(number) => Ok((count + 1, number)), + // stop early on overflow + None => Err((count, acc)), + } + }) { + Ok(p) | Err(p) => p, } } @@ -680,7 +785,7 @@ fn scan_link_title(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { title.push_str(&text[mark..i]); (i - start_ix + 1, title.into()) }; - + return Some(cow); } if c == open { @@ -697,12 +802,10 @@ fn scan_link_title(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { continue; } } - if c == b'\\' { - if i + 1 < bytes.len() && is_ascii_punctuation(bytes[i + 1]) { - title.push_str(&text[mark..i]); - i += 1; - mark = i; - } + if c == b'\\' && i + 1 < bytes.len() && is_ascii_punctuation(bytes[i + 1]) { + title.push_str(&text[mark..i]); + i += 1; + mark = i; } i += 1; @@ -755,7 +858,11 @@ pub(crate) fn scan_refdef_title(text: &str) -> Option<(usize, &str)> { // note: dest returned is raw, still needs to be unescaped // TODO: check that nested parens are really not allowed for refdefs // TODO(performance): this func should probably its own unescaping -pub(crate) fn scan_link_dest(data: &str, start_ix: usize, max_next: usize) -> Option<(usize, &str)> { +pub(crate) fn scan_link_dest( + data: &str, + start_ix: usize, + max_next: usize, +) -> Option<(usize, &str)> { let bytes = &data.as_bytes()[start_ix..]; let mut i = scan_ch(bytes, b'<'); @@ -778,7 +885,7 @@ pub(crate) fn scan_link_dest(data: &str, start_ix: usize, max_next: usize) -> Op let mut nest = 0; while i < bytes.len() { match bytes[i] { - 0x0 ... 0x20 => { + 0x0..=0x20 => { break; } b'(' => { @@ -804,9 +911,11 @@ pub(crate) fn scan_link_dest(data: &str, start_ix: usize, max_next: usize) -> Op } } - /// Returns next byte index, url and title. -pub(crate) fn scan_inline_link(underlying: &str, start_ix: usize) -> Option<(usize, CowStr<'_>, CowStr<'_>)> { +pub(crate) fn scan_inline_link( + underlying: &str, + start_ix: usize, +) -> Option<(usize, CowStr<'_>, CowStr<'_>)> { let mut ix = start_ix; if scan_ch(&underlying.as_bytes()[ix..], b'(') == 0 { return None; @@ -839,43 +948,27 @@ pub(crate) fn scan_inline_link(underlying: &str, start_ix: usize) -> Option<(usi fn scan_attribute_name(data: &[u8]) -> Option { let (&c, tail) = data.split_first()?; if is_ascii_alpha(c) || c == b'_' || c == b':' { - Some(1 + scan_while(tail, |c| is_ascii_alphanumeric(c) - || c == b'_' || c == b'.' || c == b':' || c == b'-')) + Some( + 1 + scan_while(tail, |c| { + is_ascii_alphanumeric(c) || c == b'_' || c == b'.' || c == b':' || c == b'-' + }), + ) } else { None - } -} - -/// Returns byte scanned -fn scan_inline_attribute_value(data: &[u8]) -> Option { - let c = *data.first()?; - let mut ix = 1; - - if is_ascii_whitespace(c) || c == b'=' || c == b'<' || c == b'>' || c == b'`' { - None - } else if c == b'\'' || c == b'"' { - // FIXME: this is very likely a quadratic scaling bug - ix += scan_while(&data[ix..], |b| b != c); - if scan_ch(&data[ix..], c) == 1 { - Some(ix + 1) - } else { - None - } - } else { - ix += scan_attr_value_chars(&data[ix..]); - Some(ix) } } /// Returns byte scanned (TODO: should it return new offset?) -fn scan_inline_attribute(data: &[u8]) -> Option { +fn scan_attribute(data: &[u8], allow_newline: bool) -> Option { + let whitespace_scanner = + |c| is_ascii_whitespace(c) && (allow_newline || c != b'\n' && c != b'\r'); let mut ix = scan_attribute_name(data)?; - let n_whitespace = scan_while(&data[ix..], is_ascii_whitespace); + let n_whitespace = scan_while(&data[ix..], whitespace_scanner); ix += n_whitespace; if scan_ch(&data[ix..], b'=') == 1 { ix += 1; - ix += scan_while(&data[ix..], is_ascii_whitespace); - ix += scan_inline_attribute_value(&data[ix..])?; + ix += scan_while(&data[ix..], whitespace_scanner); + ix += scan_attribute_value(&data[ix..], allow_newline)?; } else if n_whitespace > 0 { // Leave whitespace for next attribute. ix -= 1; @@ -883,20 +976,24 @@ fn scan_inline_attribute(data: &[u8]) -> Option { Some(ix) } -fn scan_attribute_value(data: &[u8]) -> Option { +fn scan_attribute_value(data: &[u8], allow_newline: bool) -> Option { let mut i = 0; match *data.get(0)? { - // FIXME: quadratic scaling bug? b @ b'"' | b @ b'\'' => { i += 1; - i += scan_while(&data[i..], |c| c != b && c != b'\n' && c != b'\r'); + i += scan_while(&data[i..], |c| { + c != b && (allow_newline || c != b'\n' && c != b'\r') + }); if scan_ch(&data[i..], b) == 0 { return None; } i += 1; - }, - b' ' | b'=' | b'>' | b'<' | b'`' | b'\n' | b'\r' => { return None; }, - _ => { // unquoted attribute value + } + b' ' | b'=' | b'>' | b'<' | b'`' | b'\n' | b'\r' => { + return None; + } + _ => { + // unquoted attribute value i += scan_attr_value_chars(&data[i..]); } } @@ -916,23 +1013,21 @@ pub(crate) fn unescape(input: &str) -> CowStr<'_> { mark = i + 1; i += 2; } - b'&' => { - match scan_entity(&bytes[i..]) { - (n, Some(value)) => { - result.push_str(&input[mark..i]); - result.push_str(&value); - i += n; - mark = i; - } - _ => i += 1 + b'&' => match scan_entity(&bytes[i..]) { + (n, Some(value)) => { + result.push_str(&input[mark..i]); + result.push_str(&value); + i += n; + mark = i; } - } + _ => i += 1, + }, b'\r' => { result.push_str(&input[mark..i]); i += 1; mark = i; } - _ => i += 1 + _ => i += 1, } } if mark == 0 { @@ -948,32 +1043,41 @@ pub(crate) fn scan_html_block_tag(data: &[u8]) -> (usize, &[u8]) { let i = scan_ch(data, b'/'); let n = scan_while(&data[i..], is_ascii_alphanumeric); // TODO: scan attributes and > - (i + n, &data[i .. i + n]) + (i + n, &data[i..i + n]) } pub(crate) fn is_html_tag(tag: &[u8]) -> bool { - HTML_TAGS.binary_search_by(|probe| { - let probe_bytes_iter = probe.as_bytes().iter(); - let tag_bytes_iter = tag.iter(); - - probe_bytes_iter.zip(tag_bytes_iter) - .find_map(|(&a, &b)| { - // We can compare case insensitively because the probes are - // all lower case alpha strings. - match a.cmp(&(b | 0x20)) { - std::cmp::Ordering::Equal => None, - inequality => Some(inequality), - } - }) - .unwrap_or_else(|| probe.len().cmp(&tag.len())) - }).is_ok() + HTML_TAGS + .binary_search_by(|probe| { + let probe_bytes_iter = probe.as_bytes().iter(); + let tag_bytes_iter = tag.iter(); + + probe_bytes_iter + .zip(tag_bytes_iter) + .find_map(|(&a, &b)| { + // We can compare case insensitively because the probes are + // all lower case alpha strings. + match a.cmp(&(b | 0x20)) { + std::cmp::Ordering::Equal => None, + inequality => Some(inequality), + } + }) + .unwrap_or_else(|| probe.len().cmp(&tag.len())) + }) + .is_ok() } /// Assumes that `data` is preceded by `<`. pub(crate) fn scan_html_type_7(data: &[u8]) -> Option { + let i = scan_html_block_inner(data, false)?; + scan_blank_line(&data[i..])?; + Some(i) +} + +fn scan_html_block_inner(data: &[u8], allow_newline: bool) -> Option { let close_tag_bytes = scan_ch(&data, b'/'); let l = scan_while(&data[close_tag_bytes..], is_ascii_alpha); - if l == 0 { + if l == 0 { return None; } let mut i = close_tag_bytes + l; @@ -981,13 +1085,17 @@ pub(crate) fn scan_html_type_7(data: &[u8]) -> Option { if close_tag_bytes == 0 { loop { - let whitespace = scan_whitespace_no_nl(&data[i..]); + let whitespace_scanner = + |c| is_ascii_whitespace(c) && (allow_newline || c != b'\n' && c != b'\r'); + let whitespace = scan_while(&data[i..], whitespace_scanner); i += whitespace; if let Some(b'/') | Some(b'>') = data.get(i) { break; } - if whitespace == 0 { return None; } - i += scan_attribute(&data[i..])?; + if whitespace == 0 { + return None; + } + i += scan_attribute(&data[i..], allow_newline)?; } } @@ -999,32 +1107,16 @@ pub(crate) fn scan_html_type_7(data: &[u8]) -> Option { let c = scan_ch(&data[i..], b'>'); if c == 0 { - return None; + None + } else { + Some(i + c) } - i += c; - - scan_blank_line(&data[i..]).map(|_| i) -} - -fn scan_attribute(data: &[u8]) -> Option { - let mut i = scan_whitespace_no_nl(data); - i += scan_attribute_name(&data[i..])?; - scan_attribute_value_spec(&data[i..]).map(|attr_valspec_bytes| attr_valspec_bytes + i) -} - -fn scan_attribute_value_spec(data: &[u8]) -> Option { - let mut i = scan_whitespace_no_nl(data); - let eq = scan_ch(&data[i..], b'='); - if eq == 0 { return None; } - i += eq; - i += scan_whitespace_no_nl(&data[i..]); - i += scan_attribute_value(&data[i..])?; - Some(i) } /// Returns (next_byte_offset, uri, type) pub(crate) fn scan_autolink(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>, LinkType)> { - scan_uri(text, start_ix).map(|(bytes, uri)| (bytes, uri, LinkType::Autolink)) + scan_uri(text, start_ix) + .map(|(bytes, uri)| (bytes, uri, LinkType::Autolink)) .or_else(|| scan_email(text, start_ix).map(|(bytes, uri)| (bytes, uri, LinkType::Email))) } @@ -1052,14 +1144,14 @@ fn scan_uri(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { // scheme length must be between 2 and 32 characters long. scheme // must be followed by colon - if i < 3 || i > 33 { + if i < 3 || i > 33 { return None; } let mut ended = false; while i < bytes.len() { match bytes[i] { - b'\0' ... b' ' => { + b'\0'..=b' ' => { ended = true; } b'>' | b'<' => break, @@ -1067,7 +1159,7 @@ fn scan_uri(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { _ => (), } i += 1; - }; + } Some((start_ix + i + 1, text[start_ix..(start_ix + i)].into())) } @@ -1083,8 +1175,8 @@ fn scan_email(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { i += 1; match c { c if is_ascii_alphanumeric(c) => (), - b'.' | b'!' | b'#' | b'$' | b'%' | b'&' | b'\'' | b'*' | b'+' | b'/' | - b'=' | b'?' | b'^' | b'_' | b'`' | b'{' | b'|' | b'}' | b'~' | b'-' => (), + b'.' | b'!' | b'#' | b'$' | b'%' | b'&' | b'\'' | b'*' | b'+' | b'/' | b'=' | b'?' + | b'^' | b'_' | b'`' | b'{' | b'|' | b'}' | b'~' | b'-' => (), b'@' => break, _ => return None, } @@ -1106,7 +1198,7 @@ fn scan_email(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { fresh_label = false; i += 1; } - + if i == label_start_ix || i - label_start_ix > 63 || bytes[i - 1] == b'-' { return None; } @@ -1126,13 +1218,19 @@ fn scan_email(text: &str, start_ix: usize) -> Option<(usize, CowStr<'_>)> { /// Scan comment, declaration, or CDATA section, with initial " Option { +fn scan_inline_html_comment( + bytes: &[u8], + mut ix: usize, + scan_guard: &mut HtmlScanGuard, +) -> Option { let c = *bytes.get(ix)?; ix += 1; match c { b'-' => { let dashes = scan_ch_repeat(&bytes[ix..], b'-'); - if dashes < 1 { return None; } + if dashes < 1 { + return None; + } // Saw "", /// ]); -/// # } /// ``` #[macro_export(local_inner_macros)] macro_rules! json { diff --git a/vendor/serde_json/src/map.rs b/vendor/serde_json/src/map.rs index dd28c757d7..6424630321 100644 --- a/vendor/serde_json/src/map.rs +++ b/vendor/serde_json/src/map.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! A map of String to serde_json::Value. //! //! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order` @@ -244,7 +236,7 @@ impl PartialEq for Map { /// Access an element of this map. Panics if the given key is not present in the /// map. /// -/// ```rust +/// ```edition2018 /// # use serde_json::Value; /// # /// # let val = &Value::String("".to_owned()); @@ -272,16 +264,13 @@ where /// Mutably access an element of this map. Panics if the given key is not /// present in the map. /// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_json; +/// ```edition2018 +/// # use serde_json::json; /// # -/// # fn main() { -/// # let mut map = serde_json::Map::new(); -/// # map.insert("key".to_owned(), serde_json::Value::Null); +/// # let mut map = serde_json::Map::new(); +/// # map.insert("key".to_owned(), serde_json::Value::Null); /// # /// map["key"] = json!("value"); -/// # } /// ``` impl<'a, Q: ?Sized> ops::IndexMut<&'a Q> for Map where @@ -451,7 +440,7 @@ impl<'a> Entry<'a> { /// /// # Examples /// - /// ```rust + /// ```edition2018 /// let mut map = serde_json::Map::new(); /// assert_eq!(map.entry("serde").key(), &"serde"); /// ``` @@ -467,16 +456,13 @@ impl<'a> Entry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut map = serde_json::Map::new(); /// map.entry("serde").or_insert(json!(12)); /// /// assert_eq!(map["serde"], 12); - /// # } /// ``` pub fn or_insert(self, default: Value) -> &'a mut Value { match self { @@ -491,16 +477,13 @@ impl<'a> Entry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut map = serde_json::Map::new(); /// map.entry("serde").or_insert_with(|| json!("hoho")); /// /// assert_eq!(map["serde"], "hoho".to_owned()); - /// # } /// ``` pub fn or_insert_with(self, default: F) -> &'a mut Value where @@ -519,7 +502,7 @@ impl<'a> VacantEntry<'a> { /// /// # Examples /// - /// ```rust + /// ```edition2018 /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -541,11 +524,9 @@ impl<'a> VacantEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -556,7 +537,6 @@ impl<'a> VacantEntry<'a> { /// } /// Entry::Occupied(_) => unimplemented!(), /// } - /// # } /// ``` #[inline] pub fn insert(self, value: Value) -> &'a mut Value { @@ -569,11 +549,9 @@ impl<'a> OccupiedEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -585,7 +563,6 @@ impl<'a> OccupiedEntry<'a> { /// } /// Entry::Vacant(_) => unimplemented!(), /// } - /// # } /// ``` #[inline] pub fn key(&self) -> &String { @@ -596,11 +573,9 @@ impl<'a> OccupiedEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -612,7 +587,6 @@ impl<'a> OccupiedEntry<'a> { /// } /// Entry::Vacant(_) => unimplemented!(), /// } - /// # } /// ``` #[inline] pub fn get(&self) -> &Value { @@ -623,11 +597,9 @@ impl<'a> OccupiedEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -641,7 +613,6 @@ impl<'a> OccupiedEntry<'a> { /// } /// /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); - /// # } /// ``` #[inline] pub fn get_mut(&mut self) -> &mut Value { @@ -652,11 +623,9 @@ impl<'a> OccupiedEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -670,7 +639,6 @@ impl<'a> OccupiedEntry<'a> { /// } /// /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); - /// # } /// ``` #[inline] pub fn into_mut(self) -> &'a mut Value { @@ -682,11 +650,9 @@ impl<'a> OccupiedEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -699,7 +665,6 @@ impl<'a> OccupiedEntry<'a> { /// } /// Entry::Vacant(_) => unimplemented!(), /// } - /// # } /// ``` #[inline] pub fn insert(&mut self, value: Value) -> Value { @@ -710,11 +675,9 @@ impl<'a> OccupiedEntry<'a> { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// use serde_json::map::Entry; /// /// let mut map = serde_json::Map::new(); @@ -726,7 +689,6 @@ impl<'a> OccupiedEntry<'a> { /// } /// Entry::Vacant(_) => unimplemented!(), /// } - /// # } /// ``` #[inline] pub fn remove(self) -> Value { diff --git a/vendor/serde_json/src/number.rs b/vendor/serde_json/src/number.rs index 58beca11f8..fd2707aa26 100644 --- a/vendor/serde_json/src/number.rs +++ b/vendor/serde_json/src/number.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use error::Error; use serde::de::{self, Unexpected, Visitor}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -54,11 +46,9 @@ impl Number { /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to /// return the integer value. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let big = i64::max_value() as u64 + 10; /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); /// @@ -69,7 +59,6 @@ impl Number { /// /// // Numbers with a decimal point are not considered integers. /// assert!(!v["c"].is_i64()); - /// # } /// ``` #[inline] pub fn is_i64(&self) -> bool { @@ -88,11 +77,9 @@ impl Number { /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to /// return the integer value. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); /// /// assert!(v["a"].is_u64()); @@ -102,7 +89,6 @@ impl Number { /// /// // Numbers with a decimal point are not considered integers. /// assert!(!v["c"].is_u64()); - /// # } /// ``` #[inline] pub fn is_u64(&self) -> bool { @@ -123,11 +109,9 @@ impl Number { /// Currently this function returns true if and only if both `is_i64` and /// `is_u64` return false but this is not a guarantee in the future. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); /// /// assert!(v["a"].is_f64()); @@ -135,7 +119,6 @@ impl Number { /// // Integers. /// assert!(!v["b"].is_f64()); /// assert!(!v["c"].is_f64()); - /// # } /// ``` #[inline] pub fn is_f64(&self) -> bool { @@ -158,18 +141,15 @@ impl Number { /// If the `Number` is an integer, represent it as i64 if possible. Returns /// None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let big = i64::max_value() as u64 + 10; /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); /// /// assert_eq!(v["a"].as_i64(), Some(64)); /// assert_eq!(v["b"].as_i64(), None); /// assert_eq!(v["c"].as_i64(), None); - /// # } /// ``` #[inline] pub fn as_i64(&self) -> Option { @@ -192,17 +172,14 @@ impl Number { /// If the `Number` is an integer, represent it as u64 if possible. Returns /// None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); /// /// assert_eq!(v["a"].as_u64(), Some(64)); /// assert_eq!(v["b"].as_u64(), None); /// assert_eq!(v["c"].as_u64(), None); - /// # } /// ``` #[inline] pub fn as_u64(&self) -> Option { @@ -217,17 +194,14 @@ impl Number { /// Represents the number as f64 if possible. Returns None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); /// /// assert_eq!(v["a"].as_f64(), Some(256.0)); /// assert_eq!(v["b"].as_f64(), Some(64.0)); /// assert_eq!(v["c"].as_f64(), Some(-64.0)); - /// # } /// ``` #[inline] pub fn as_f64(&self) -> Option { @@ -244,7 +218,7 @@ impl Number { /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON /// numbers. /// - /// ```rust + /// ```edition2018 /// # use std::f64; /// # /// # use serde_json::Number; @@ -263,7 +237,7 @@ impl Number { } #[cfg(feature = "arbitrary_precision")] { - ryu::Buffer::new().format(f).to_owned() + ryu::Buffer::new().format_finite(f).to_owned() } }; Some(Number { n: n }) @@ -499,7 +473,7 @@ macro_rules! deserialize_any { } else if let Some(i) = self.as_i64() { return visitor.visit_i64(i); } else if let Some(f) = self.as_f64() { - if f.to_string() == self.n { + if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n { return visitor.visit_f64(f); } } @@ -740,6 +714,21 @@ macro_rules! impl_from_signed { impl_from_unsigned!(u8, u16, u32, u64, usize); impl_from_signed!(i8, i16, i32, i64, isize); +#[cfg(feature = "arbitrary_precision")] +serde_if_integer128! { + impl From for Number { + fn from(i: i128) -> Self { + Number { n: i.to_string() } + } + } + + impl From for Number { + fn from(u: u128) -> Self { + Number { n: u.to_string() } + } + } +} + impl Number { #[cfg(not(feature = "arbitrary_precision"))] // Not public API. Should be pub(crate). diff --git a/vendor/serde_json/src/raw.rs b/vendor/serde_json/src/raw.rs index a6b64108e2..90ef59bd7d 100644 --- a/vendor/serde_json/src/raw.rs +++ b/vendor/serde_json/src/raw.rs @@ -20,13 +20,20 @@ use error::Error; /// When serializing, a value of this type will retain its original formatting /// and will not be minified or pretty-printed. /// -/// # Example +/// # Note /// +/// `RawValue` is only available if serde\_json is built with the `"raw_value"` +/// feature. +/// +/// ```toml +/// [dependencies] +/// serde_json = { version = "1.0", features = ["raw_value"] } /// ``` -/// #[macro_use] -/// extern crate serde_derive; -/// extern crate serde_json; /// +/// # Example +/// +/// ```edition2018 +/// use serde::{Deserialize, Serialize}; /// use serde_json::{Result, value::RawValue}; /// /// #[derive(Deserialize)] @@ -71,11 +78,8 @@ use error::Error; /// /// The typical usage of `RawValue` will be in the borrowed form: /// -/// ``` -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde_json; -/// # +/// ```edition2018 +/// # use serde::Deserialize; /// # use serde_json::value::RawValue; /// # /// #[derive(Deserialize)] @@ -83,8 +87,6 @@ use error::Error; /// #[serde(borrow)] /// raw_value: &'a RawValue, /// } -/// # -/// # fn main() {} /// ``` /// /// The borrowed form is suitable when deserializing through @@ -99,29 +101,14 @@ use error::Error; /// [`serde_json::from_slice`]: ../fn.from_slice.html /// [`serde_json::from_reader`]: ../fn.from_reader.html /// -/// ``` -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde_json; -/// # +/// ```edition2018 +/// # use serde::Deserialize; /// # use serde_json::value::RawValue; /// # /// #[derive(Deserialize)] /// struct SomeStruct { /// raw_value: Box, /// } -/// # -/// # fn main() {} -/// ``` -/// -/// # Note -/// -/// `RawValue` is only available if serde\_json is built with the `"raw_value"` -/// feature. -/// -/// ```toml -/// [dependencies] -/// serde_json = { version = "1.0", features = ["raw_value"] } /// ``` #[repr(C)] pub struct RawValue { @@ -196,11 +183,8 @@ impl RawValue { /// /// # Example /// - /// ``` - /// #[macro_use] - /// extern crate serde_derive; - /// extern crate serde_json; - /// + /// ```edition2018 + /// use serde::Deserialize; /// use serde_json::{Result, value::RawValue}; /// /// #[derive(Deserialize)] diff --git a/vendor/serde_json/src/read.rs b/vendor/serde_json/src/read.rs index 23b279dfbe..71b0504138 100644 --- a/vendor/serde_json/src/read.rs +++ b/vendor/serde_json/src/read.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::ops::Deref; use std::{char, cmp, io, str}; @@ -679,33 +671,33 @@ impl<'a> Read<'a> for StrRead<'a> { ////////////////////////////////////////////////////////////////////////////// -const CT: bool = true; // control character \x00...\x1F -const QU: bool = true; // quote \x22 -const BS: bool = true; // backslash \x5C -const O: bool = false; // allow unescaped - // Lookup table of bytes that must be escaped. A value of true at index i means // that byte i requires an escape sequence in the input. -#[cfg_attr(rustfmt, rustfmt_skip)] -static ESCAPE: [bool; 256] = [ - // 1 2 3 4 5 6 7 8 9 A B C D E F - CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 - CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 - O, O, QU, O, O, O, O, O, O, O, O, O, O, O, O, O, // 2 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 3 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 4 - O, O, O, O, O, O, O, O, O, O, O, O, BS, O, O, O, // 5 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 6 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 7 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 8 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 9 - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // A - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // B - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // C - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // D - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // E - O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // F -]; +static ESCAPE: [bool; 256] = { + const CT: bool = true; // control character \x00...\x1F + const QU: bool = true; // quote \x22 + const BS: bool = true; // backslash \x5C + const __: bool = false; // allow unescaped + [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 + CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 + __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F + ] +}; fn next_or_eof<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result { match try!(read.next()) { @@ -834,26 +826,28 @@ fn ignore_escape<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result<()> { Ok(()) } -#[cfg_attr(rustfmt, rustfmt_skip)] -static HEX: [u8; 256] = [ - // 1 2 3 4 5 6 7 8 9 A B C D E F - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3 - 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5 - 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9 - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // F -]; +static HEX: [u8; 256] = { + const __: u8 = 255; // not a hex digit + [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 1 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, __, __, __, __, __, __, // 3 + __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 5 + __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F + ] +}; fn decode_hex_val(val: u8) -> Option { let n = HEX[val as usize] as u16; diff --git a/vendor/serde_json/src/ser.rs b/vendor/serde_json/src/ser.rs index d391bf03ba..cfae3815fa 100644 --- a/vendor/serde_json/src/ser.rs +++ b/vendor/serde_json/src/ser.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! Serialize a Rust data structure into JSON data. use std::fmt; @@ -995,10 +987,22 @@ where serde_if_integer128! { fn serialize_i128(self, value: i128) -> Result<()> { - self.ser + try!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + try!(self + .ser .formatter .write_number_str(&mut self.ser.writer, &value.to_string()) - .map_err(Error::io) + .map_err(Error::io)); + try!(self + .ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io)); + Ok(()) } } @@ -1080,10 +1084,22 @@ where serde_if_integer128! { fn serialize_u128(self, value: u128) -> Result<()> { - self.ser + try!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + try!(self + .ser .formatter .write_number_str(&mut self.ser.writer, &value.to_string()) - .map_err(Error::io) + .map_err(Error::io)); + try!(self + .ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io)); + Ok(()) } } @@ -1584,7 +1600,7 @@ impl CharEscape { self::RR => CharEscape::CarriageReturn, self::QU => CharEscape::Quote, self::BS => CharEscape::ReverseSolidus, - self::U => CharEscape::AsciiControl(byte), + self::UU => CharEscape::AsciiControl(byte), _ => unreachable!(), } } @@ -1695,7 +1711,7 @@ pub trait Formatter { W: io::Write, { let mut buffer = ryu::Buffer::new(); - let s = buffer.format(value); + let s = buffer.format_finite(value); writer.write_all(s.as_bytes()) } @@ -1706,7 +1722,7 @@ pub trait Formatter { W: io::Write, { let mut buffer = ryu::Buffer::new(); - let s = buffer.format(value); + let s = buffer.format_finite(value); writer.write_all(s.as_bytes()) } @@ -2104,29 +2120,29 @@ const FF: u8 = b'f'; // \x0C const RR: u8 = b'r'; // \x0D const QU: u8 = b'"'; // \x22 const BS: u8 = b'\\'; // \x5C -const U: u8 = b'u'; // \x00...\x1F except the ones above +const UU: u8 = b'u'; // \x00...\x1F except the ones above +const __: u8 = 0; // Lookup table of escape sequences. A value of b'x' at index i means that byte // i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped. -#[cfg_attr(rustfmt, rustfmt_skip)] static ESCAPE: [u8; 256] = [ - // 1 2 3 4 5 6 7 8 9 A B C D E F - U, U, U, U, U, U, U, U, BB, TT, NN, U, FF, RR, U, U, // 0 - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, // 1 - 0, 0, QU, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, BS, 0, 0, 0, // 5 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F + // 1 2 3 4 5 6 7 8 9 A B C D E F + UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0 + UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1 + __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F ]; /// Serialize the given data structure as JSON into the IO stream. diff --git a/vendor/serde_json/src/value/de.rs b/vendor/serde_json/src/value/de.rs index f70589b0cd..a1f40cf92e 100644 --- a/vendor/serde_json/src/value/de.rs +++ b/vendor/serde_json/src/value/de.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::borrow::Cow; use std::fmt; use std::slice; diff --git a/vendor/serde_json/src/value/from.rs b/vendor/serde_json/src/value/from.rs index d7f8332db7..d647deae8d 100644 --- a/vendor/serde_json/src/value/from.rs +++ b/vendor/serde_json/src/value/from.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::borrow::Cow; use super::Value; @@ -29,20 +21,23 @@ from_integer! { u8 u16 u32 u64 usize } +#[cfg(feature = "arbitrary_precision")] +serde_if_integer128! { + from_integer! { + i128 u128 + } +} + impl From for Value { /// Convert 32-bit floating point number to `Value` /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let f: f32 = 13.37; /// let x: Value = f.into(); - /// # } /// ``` fn from(f: f32) -> Self { From::from(f as f64) @@ -54,15 +49,11 @@ impl From for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let f: f64 = 13.37; /// let x: Value = f.into(); - /// # } /// ``` fn from(f: f64) -> Self { Number::from_f64(f).map_or(Value::Null, Value::Number) @@ -74,15 +65,11 @@ impl From for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let b = false; /// let x: Value = b.into(); - /// # } /// ``` fn from(f: bool) -> Self { Value::Bool(f) @@ -94,15 +81,11 @@ impl From for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let s: String = "lorem".to_string(); /// let x: Value = s.into(); - /// # } /// ``` fn from(f: String) -> Self { Value::String(f) @@ -114,15 +97,11 @@ impl<'a> From<&'a str> for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let s: &str = "lorem"; /// let x: Value = s.into(); - /// # } /// ``` fn from(f: &str) -> Self { Value::String(f.to_string()) @@ -134,28 +113,20 @@ impl<'a> From> for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// use std::borrow::Cow; /// /// let s: Cow = Cow::Borrowed("lorem"); /// let x: Value = s.into(); - /// # } /// ``` /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// use std::borrow::Cow; /// /// let s: Cow = Cow::Owned("lorem".to_string()); /// let x: Value = s.into(); - /// # } /// ``` fn from(f: Cow<'a, str>) -> Self { Value::String(f.into_owned()) @@ -167,16 +138,12 @@ impl From> for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::{Map, Value}; /// /// let mut m = Map::new(); /// m.insert("Lorem".to_string(), "ipsum".into()); /// let x: Value = m.into(); - /// # } /// ``` fn from(f: Map) -> Self { Value::Object(f) @@ -188,15 +155,11 @@ impl> From> for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let v = vec!["lorem", "ipsum", "dolor"]; /// let x: Value = v.into(); - /// # } /// ``` fn from(f: Vec) -> Self { Value::Array(f.into_iter().map(Into::into).collect()) @@ -208,15 +171,11 @@ impl<'a, T: Clone + Into> From<&'a [T]> for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; /// let x: Value = v.into(); - /// # } /// ``` fn from(f: &'a [T]) -> Self { Value::Array(f.iter().cloned().map(Into::into).collect()) @@ -228,37 +187,25 @@ impl> ::std::iter::FromIterator for Value { /// /// # Examples /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let v = std::iter::repeat(42).take(5); /// let x: Value = v.collect(); - /// # } /// ``` /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use serde_json::Value; /// /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; /// let x: Value = v.into_iter().collect(); - /// # } /// ``` /// - /// ```rust - /// # extern crate serde_json; - /// # - /// # fn main() { + /// ```edition2018 /// use std::iter::FromIterator; /// use serde_json::Value; /// /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); - /// # } /// ``` fn from_iter>(iter: I) -> Self { Value::Array(iter.into_iter().map(Into::into).collect()) diff --git a/vendor/serde_json/src/value/index.rs b/vendor/serde_json/src/value/index.rs index 87c61eb10c..47990a5473 100644 --- a/vendor/serde_json/src/value/index.rs +++ b/vendor/serde_json/src/value/index.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use std::fmt; use std::ops; @@ -28,11 +20,9 @@ use map::Map; /// /// # Examples /// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_json; +/// ```edition2018 +/// # use serde_json::json; /// # -/// # fn main() { /// let data = json!({ "inner": [1, 2, 3] }); /// /// // Data is a JSON map so it can be indexed with a string. @@ -42,7 +32,6 @@ use map::Map; /// let first = &inner[0]; /// /// assert_eq!(first, 1); -/// # } /// ``` pub trait Index: private::Sealed { /// Return None if the key is not already in the array or object. @@ -204,11 +193,9 @@ where /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let data = json!({ /// "x": { /// "y": ["z", "zz"] @@ -220,7 +207,6 @@ where /// /// assert_eq!(data["a"], json!(null)); // returns null for undefined values /// assert_eq!(data["a"]["b"], json!(null)); // does not panic - /// # } /// ``` fn index(&self, index: I) -> &Value { static NULL: Value = Value::Null; @@ -246,11 +232,9 @@ where /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut data = json!({ "x": 0 }); /// /// // replace an existing key @@ -266,7 +250,6 @@ where /// data["a"]["b"]["c"]["d"] = json!(true); /// /// println!("{}", data); - /// # } /// ``` fn index_mut(&mut self, index: I) -> &mut Value { index.index_or_insert(self) diff --git a/vendor/serde_json/src/value/mod.rs b/vendor/serde_json/src/value/mod.rs index c976af501d..dc2557e35d 100644 --- a/vendor/serde_json/src/value/mod.rs +++ b/vendor/serde_json/src/value/mod.rs @@ -1,32 +1,22 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! The Value enum, a loosely typed way of representing any valid JSON value. //! //! # Constructing JSON //! //! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` -//! objects with very natural JSON syntax. In order to use this macro, -//! `serde_json` needs to be imported with the `#[macro_use]` attribute. +//! objects with very natural JSON syntax. //! -//! ```rust -//! #[macro_use] -//! extern crate serde_json; +//! ```edition2018 +//! use serde_json::json; //! //! fn main() { //! // The type of `john` is `serde_json::Value` //! let john = json!({ -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] //! }); //! //! println!("first phone number: {}", john["phones"][0]); @@ -44,26 +34,22 @@ //! will check at compile time that the value you are interpolating is able to //! be represented as JSON. //! -//! ```rust -//! # #[macro_use] -//! # extern crate serde_json; +//! ```edition2018 +//! # use serde_json::json; //! # //! # fn random_phone() -> u16 { 0 } //! # -//! # fn main() { //! let full_name = "John Doe"; //! let age_last_year = 42; //! //! // The type of `john` is `serde_json::Value` //! let john = json!({ -//! "name": full_name, -//! "age": age_last_year + 1, -//! "phones": [ -//! format!("+44 {}", random_phone()) -//! ] +//! "name": full_name, +//! "age": age_last_year + 1, +//! "phones": [ +//! format!("+44 {}", random_phone()) +//! ] //! }); -//! # let _ = john; -//! # } //! ``` //! //! A string of JSON data can be parsed into a `serde_json::Value` by the @@ -72,21 +58,20 @@ //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or //! a TCP stream. //! -//! ```rust -//! extern crate serde_json; -//! -//! use serde_json::{Value, Error}; +//! ```edition2018 +//! use serde_json::{json, Value, Error}; //! //! fn untyped_example() -> Result<(), Error> { //! // Some JSON input data as a &str. Maybe this comes from the user. -//! let data = r#"{ -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! }"#; +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; //! //! // Parse the string of data into serde_json::Value. //! let v: Value = serde_json::from_str(data)?; @@ -133,61 +118,46 @@ use self::ser::Serializer; pub enum Value { /// Represents a JSON null value. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!(null); - /// # } /// ``` Null, /// Represents a JSON boolean. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!(true); - /// # } /// ``` Bool(bool), /// Represents a JSON number, whether integer or floating point. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!(12.5); - /// # } /// ``` Number(Number), /// Represents a JSON string. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!("a string"); - /// # } /// ``` String(String), /// Represents a JSON array. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!(["an", "array"]); - /// # } /// ``` Array(Vec), @@ -199,13 +169,10 @@ pub enum Value { /// allows JSON data to be deserialized into a Value and serialized to a /// string while retaining the order of map keys in the input. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "an": "object" }); - /// # } /// ``` Object(Map), } @@ -247,11 +214,9 @@ impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { impl fmt::Display for Value { /// Display a JSON value as a string. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let json = json!({ "city": "London", "street": "10 Downing Street" }); /// /// // Compact format: @@ -270,7 +235,6 @@ impl fmt::Display for Value { /// let pretty = format!("{:#}", json); /// assert_eq!(pretty, /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); - /// # } /// ``` fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let alternate = f.alternate(); @@ -302,11 +266,9 @@ impl Value { /// number. Also returns `None` if the given key does not exist in the map /// or the given index is not within the bounds of the array. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let object = json!({ "A": 65, "B": 66, "C": 67 }); /// assert_eq!(*object.get("A").unwrap(), json!(65)); /// @@ -314,18 +276,15 @@ impl Value { /// assert_eq!(*array.get(2).unwrap(), json!("C")); /// /// assert_eq!(array.get("A"), None); - /// # } /// ``` /// /// Square brackets can also be used to index into a value in a more concise /// way. This returns `Value::Null` in cases where `get` would have returned /// `None`. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let object = json!({ /// "A": ["a", "á", "à"], /// "B": ["b", "b́"], @@ -335,7 +294,6 @@ impl Value { /// /// assert_eq!(object["D"], json!(null)); /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); - /// # } /// ``` pub fn get(&self, index: I) -> Option<&Value> { index.index_into(self) @@ -350,17 +308,14 @@ impl Value { /// number. Also returns `None` if the given key does not exist in the map /// or the given index is not within the bounds of the array. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); /// *object.get_mut("A").unwrap() = json!(69); /// /// let mut array = json!([ "A", "B", "C" ]); /// *array.get_mut(2).unwrap() = json!("D"); - /// # } /// ``` pub fn get_mut(&mut self, index: I) -> Option<&mut Value> { index.index_into_mut(self) @@ -372,11 +327,9 @@ impl Value { /// `as_object_mut` are guaranteed to return the map representation of the /// object. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); /// /// assert!(obj.is_object()); @@ -384,7 +337,6 @@ impl Value { /// /// // array, not an object /// assert!(!obj["b"].is_object()); - /// # } /// ``` pub fn is_object(&self) -> bool { self.as_object().is_some() @@ -393,11 +345,9 @@ impl Value { /// If the `Value` is an Object, returns the associated Map. Returns None /// otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); /// /// // The length of `{"nested": true}` is 1 entry. @@ -405,7 +355,6 @@ impl Value { /// /// // The array `["an", "array"]` is not an object. /// assert_eq!(v["b"].as_object(), None); - /// # } /// ``` pub fn as_object(&self) -> Option<&Map> { match *self { @@ -417,17 +366,13 @@ impl Value { /// If the `Value` is an Object, returns the associated mutable Map. /// Returns None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut v = json!({ "a": { "nested": true } }); /// /// v["a"].as_object_mut().unwrap().clear(); /// assert_eq!(v, json!({ "a": {} })); - /// # } - /// /// ``` pub fn as_object_mut(&mut self) -> Option<&mut Map> { match *self { @@ -442,18 +387,15 @@ impl Value { /// `as_array_mut` are guaranteed to return the vector representing the /// array. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); /// /// assert!(obj["a"].is_array()); /// /// // an object, not an array /// assert!(!obj["b"].is_array()); - /// # } /// ``` pub fn is_array(&self) -> bool { self.as_array().is_some() @@ -462,11 +404,9 @@ impl Value { /// If the `Value` is an Array, returns the associated vector. Returns None /// otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); /// /// // The length of `["an", "array"]` is 2 elements. @@ -474,7 +414,6 @@ impl Value { /// /// // The object `{"an": "object"}` is not an array. /// assert_eq!(v["b"].as_array(), None); - /// # } /// ``` pub fn as_array(&self) -> Option<&Vec> { match *self { @@ -486,16 +425,13 @@ impl Value { /// If the `Value` is an Array, returns the associated mutable vector. /// Returns None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut v = json!({ "a": ["an", "array"] }); /// /// v["a"].as_array_mut().unwrap().clear(); /// assert_eq!(v, json!({ "a": [] })); - /// # } /// ``` pub fn as_array_mut(&mut self) -> Option<&mut Vec> { match *self { @@ -509,18 +445,15 @@ impl Value { /// For any Value on which `is_string` returns true, `as_str` is guaranteed /// to return the string slice. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": "some string", "b": false }); /// /// assert!(v["a"].is_string()); /// /// // The boolean `false` is not a string. /// assert!(!v["b"].is_string()); - /// # } /// ``` pub fn is_string(&self) -> bool { self.as_str().is_some() @@ -529,11 +462,9 @@ impl Value { /// If the `Value` is a String, returns the associated str. Returns None /// otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": "some string", "b": false }); /// /// assert_eq!(v["a"].as_str(), Some("some string")); @@ -550,7 +481,6 @@ impl Value { /// // /// // The value is: some string /// println!("The value is: {}", v["a"].as_str().unwrap()); - /// # } /// ``` pub fn as_str(&self) -> Option<&str> { match *self { @@ -561,18 +491,15 @@ impl Value { /// Returns true if the `Value` is a Number. Returns false otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 1, "b": "2" }); /// /// assert!(v["a"].is_number()); /// /// // The string `"2"` is a string, not a number. /// assert!(!v["b"].is_number()); - /// # } /// ``` pub fn is_number(&self) -> bool { match *self { @@ -587,11 +514,9 @@ impl Value { /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to /// return the integer value. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let big = i64::max_value() as u64 + 10; /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); /// @@ -602,7 +527,6 @@ impl Value { /// /// // Numbers with a decimal point are not considered integers. /// assert!(!v["c"].is_i64()); - /// # } /// ``` pub fn is_i64(&self) -> bool { match *self { @@ -616,11 +540,9 @@ impl Value { /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to /// return the integer value. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); /// /// assert!(v["a"].is_u64()); @@ -630,7 +552,6 @@ impl Value { /// /// // Numbers with a decimal point are not considered integers. /// assert!(!v["c"].is_u64()); - /// # } /// ``` pub fn is_u64(&self) -> bool { match *self { @@ -647,11 +568,9 @@ impl Value { /// Currently this function returns true if and only if both `is_i64` and /// `is_u64` return false but this is not a guarantee in the future. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); /// /// assert!(v["a"].is_f64()); @@ -659,7 +578,6 @@ impl Value { /// // Integers. /// assert!(!v["b"].is_f64()); /// assert!(!v["c"].is_f64()); - /// # } /// ``` pub fn is_f64(&self) -> bool { match *self { @@ -671,18 +589,15 @@ impl Value { /// If the `Value` is an integer, represent it as i64 if possible. Returns /// None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let big = i64::max_value() as u64 + 10; /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); /// /// assert_eq!(v["a"].as_i64(), Some(64)); /// assert_eq!(v["b"].as_i64(), None); /// assert_eq!(v["c"].as_i64(), None); - /// # } /// ``` pub fn as_i64(&self) -> Option { match *self { @@ -694,17 +609,14 @@ impl Value { /// If the `Value` is an integer, represent it as u64 if possible. Returns /// None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); /// /// assert_eq!(v["a"].as_u64(), Some(64)); /// assert_eq!(v["b"].as_u64(), None); /// assert_eq!(v["c"].as_u64(), None); - /// # } /// ``` pub fn as_u64(&self) -> Option { match *self { @@ -716,17 +628,14 @@ impl Value { /// If the `Value` is a number, represent it as f64 if possible. Returns /// None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); /// /// assert_eq!(v["a"].as_f64(), Some(256.0)); /// assert_eq!(v["b"].as_f64(), Some(64.0)); /// assert_eq!(v["c"].as_f64(), Some(-64.0)); - /// # } /// ``` pub fn as_f64(&self) -> Option { match *self { @@ -740,18 +649,15 @@ impl Value { /// For any Value on which `is_boolean` returns true, `as_bool` is /// guaranteed to return the boolean value. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": false, "b": "false" }); /// /// assert!(v["a"].is_boolean()); /// /// // The string `"false"` is a string, not a boolean. /// assert!(!v["b"].is_boolean()); - /// # } /// ``` pub fn is_boolean(&self) -> bool { self.as_bool().is_some() @@ -760,18 +666,15 @@ impl Value { /// If the `Value` is a Boolean, returns the associated bool. Returns None /// otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": false, "b": "false" }); /// /// assert_eq!(v["a"].as_bool(), Some(false)); /// /// // The string `"false"` is a string, not a boolean. /// assert_eq!(v["b"].as_bool(), None); - /// # } /// ``` pub fn as_bool(&self) -> Option { match *self { @@ -785,18 +688,15 @@ impl Value { /// For any Value on which `is_null` returns true, `as_null` is guaranteed /// to return `Some(())`. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": null, "b": false }); /// /// assert!(v["a"].is_null()); /// /// // The boolean `false` is not null. /// assert!(!v["b"].is_null()); - /// # } /// ``` pub fn is_null(&self) -> bool { self.as_null().is_some() @@ -804,18 +704,15 @@ impl Value { /// If the `Value` is a Null, returns (). Returns None otherwise. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let v = json!({ "a": null, "b": false }); /// /// assert_eq!(v["a"].as_null(), Some(())); /// /// // The boolean `false` is not null. /// assert_eq!(v["b"].as_null(), None); - /// # } /// ``` pub fn as_null(&self) -> Option<()> { match *self { @@ -838,11 +735,9 @@ impl Value { /// /// # Examples /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let data = json!({ /// "x": { /// "y": ["z", "zz"] @@ -851,7 +746,6 @@ impl Value { /// /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz")); /// assert_eq!(data.pointer("/a/b/c"), None); - /// # } /// ``` pub fn pointer<'a>(&'a self, pointer: &str) -> Option<&'a Value> { if pointer == "" { @@ -896,9 +790,7 @@ impl Value { /// /// # Example of Use /// - /// ```rust - /// extern crate serde_json; - /// + /// ```edition2018 /// use serde_json::Value; /// /// fn main() { @@ -953,15 +845,12 @@ impl Value { /// Takes the value out of the `Value`, leaving a `Null` in its place. /// - /// ```rust - /// # #[macro_use] - /// # extern crate serde_json; + /// ```edition2018 + /// # use serde_json::json; /// # - /// # fn main() { /// let mut v = json!({ "x": "y" }); /// assert_eq!(v["x"].take(), json!("y")); /// assert_eq!(v, json!({ "x": null })); - /// # } /// ``` pub fn take(&mut self) -> Value { mem::replace(self, Value::Null) @@ -974,12 +863,8 @@ impl Value { /// /// # Examples /// -/// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # -/// # extern crate serde_json; -/// # +/// ```edition2018 +/// # use serde::Deserialize; /// use serde_json::Value; /// /// #[derive(Deserialize)] @@ -1018,14 +903,11 @@ mod ser; /// Convert a `T` into `serde_json::Value` which is an enum that can represent /// any valid JSON data. /// -/// ```rust -/// extern crate serde; +/// # Example /// -/// #[macro_use] -/// extern crate serde_derive; -/// -/// #[macro_use] -/// extern crate serde_json; +/// ```edition2018 +/// use serde::Serialize; +/// use serde_json::json; /// /// use std::error::Error; /// @@ -1043,9 +925,9 @@ mod ser; /// /// // The type of `expected` is `serde_json::Value` /// let expected = json!({ -/// "fingerprint": "0xF9BA143B95FF6D82", -/// "location": "Menlo Park, CA", -/// }); +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA", +/// }); /// /// let v = serde_json::to_value(u).unwrap(); /// assert_eq!(v, expected); @@ -1063,9 +945,7 @@ mod ser; /// This conversion can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. /// -/// ```rust -/// extern crate serde_json; -/// +/// ```edition2018 /// use std::collections::BTreeMap; /// /// fn main() { @@ -1087,22 +967,11 @@ where /// Interpret a `serde_json::Value` as an instance of type `T`. /// -/// This conversion can fail if the structure of the Value does not match the -/// structure expected by `T`, for example if `T` is a struct type but the Value -/// contains something other than a JSON map. It can also fail if the structure -/// is correct but `T`'s implementation of `Deserialize` decides that something -/// is wrong with the data, for example required struct fields are missing from -/// the JSON map or some number is too big to fit in the expected primitive -/// type. -/// -/// ```rust -/// #[macro_use] -/// extern crate serde_json; -/// -/// #[macro_use] -/// extern crate serde_derive; +/// # Example /// -/// extern crate serde; +/// ```edition2018 +/// use serde::Deserialize; +/// use serde_json::json; /// /// #[derive(Deserialize, Debug)] /// struct User { @@ -1113,14 +982,24 @@ where /// fn main() { /// // The type of `j` is `serde_json::Value` /// let j = json!({ -/// "fingerprint": "0xF9BA143B95FF6D82", -/// "location": "Menlo Park, CA" -/// }); +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA" +/// }); /// /// let u: User = serde_json::from_value(j).unwrap(); /// println!("{:#?}", u); /// } /// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the Value does not match the +/// structure expected by `T`, for example if `T` is a struct type but the Value +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. pub fn from_value(value: Value) -> Result where T: DeserializeOwned, diff --git a/vendor/serde_json/src/value/partial_eq.rs b/vendor/serde_json/src/value/partial_eq.rs index ef67f5cb65..cfcf957063 100644 --- a/vendor/serde_json/src/value/partial_eq.rs +++ b/vendor/serde_json/src/value/partial_eq.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use super::Value; fn eq_i64(value: &Value, other: i64) -> bool { diff --git a/vendor/serde_json/src/value/ser.rs b/vendor/serde_json/src/value/ser.rs index 172784ccee..b0e09beb54 100644 --- a/vendor/serde_json/src/value/ser.rs +++ b/vendor/serde_json/src/value/ser.rs @@ -1,11 +1,3 @@ -// Copyright 2017 Serde Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use serde::ser::Impossible; use serde::{self, Serialize}; @@ -77,6 +69,13 @@ impl serde::Serializer for Serializer { Ok(Value::Number(value.into())) } + #[cfg(feature = "arbitrary_precision")] + serde_if_integer128! { + fn serialize_i128(self, value: i128) -> Result { + Ok(Value::Number(value.into())) + } + } + #[inline] fn serialize_u8(self, value: u8) -> Result { self.serialize_u64(value as u64) @@ -97,6 +96,13 @@ impl serde::Serializer for Serializer { Ok(Value::Number(value.into())) } + #[cfg(feature = "arbitrary_precision")] + serde_if_integer128! { + fn serialize_u128(self, value: u128) -> Result { + Ok(Value::Number(value.into())) + } + } + #[inline] fn serialize_f32(self, value: f32) -> Result { self.serialize_f64(value as f64) diff --git a/vendor/url/.cargo-checksum.json b/vendor/url-1.7.2/.cargo-checksum.json similarity index 100% rename from vendor/url/.cargo-checksum.json rename to vendor/url-1.7.2/.cargo-checksum.json diff --git a/vendor/url/Cargo.toml b/vendor/url-1.7.2/Cargo.toml similarity index 100% rename from vendor/url/Cargo.toml rename to vendor/url-1.7.2/Cargo.toml diff --git a/vendor/url-1.7.2/LICENSE-APACHE b/vendor/url-1.7.2/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/vendor/url-1.7.2/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/url/LICENSE-MIT b/vendor/url-1.7.2/LICENSE-MIT similarity index 100% rename from vendor/url/LICENSE-MIT rename to vendor/url-1.7.2/LICENSE-MIT diff --git a/vendor/url/README.md b/vendor/url-1.7.2/README.md similarity index 100% rename from vendor/url/README.md rename to vendor/url-1.7.2/README.md diff --git a/vendor/url/UPGRADING.md b/vendor/url-1.7.2/UPGRADING.md similarity index 100% rename from vendor/url/UPGRADING.md rename to vendor/url-1.7.2/UPGRADING.md diff --git a/vendor/url/appveyor.yml b/vendor/url-1.7.2/appveyor.yml similarity index 100% rename from vendor/url/appveyor.yml rename to vendor/url-1.7.2/appveyor.yml diff --git a/vendor/url/benches/parse_url.rs b/vendor/url-1.7.2/benches/parse_url.rs similarity index 100% rename from vendor/url/benches/parse_url.rs rename to vendor/url-1.7.2/benches/parse_url.rs diff --git a/vendor/url/docs/404.html b/vendor/url-1.7.2/docs/404.html similarity index 100% rename from vendor/url/docs/404.html rename to vendor/url-1.7.2/docs/404.html diff --git a/vendor/url/docs/index.html b/vendor/url-1.7.2/docs/index.html similarity index 100% rename from vendor/url/docs/index.html rename to vendor/url-1.7.2/docs/index.html diff --git a/vendor/url/src/encoding.rs b/vendor/url-1.7.2/src/encoding.rs similarity index 100% rename from vendor/url/src/encoding.rs rename to vendor/url-1.7.2/src/encoding.rs diff --git a/vendor/url/src/form_urlencoded.rs b/vendor/url-1.7.2/src/form_urlencoded.rs similarity index 100% rename from vendor/url/src/form_urlencoded.rs rename to vendor/url-1.7.2/src/form_urlencoded.rs diff --git a/vendor/url/src/host.rs b/vendor/url-1.7.2/src/host.rs similarity index 100% rename from vendor/url/src/host.rs rename to vendor/url-1.7.2/src/host.rs diff --git a/vendor/url/src/lib.rs b/vendor/url-1.7.2/src/lib.rs similarity index 100% rename from vendor/url/src/lib.rs rename to vendor/url-1.7.2/src/lib.rs diff --git a/vendor/url/src/origin.rs b/vendor/url-1.7.2/src/origin.rs similarity index 100% rename from vendor/url/src/origin.rs rename to vendor/url-1.7.2/src/origin.rs diff --git a/vendor/url/src/parser.rs b/vendor/url-1.7.2/src/parser.rs similarity index 100% rename from vendor/url/src/parser.rs rename to vendor/url-1.7.2/src/parser.rs diff --git a/vendor/url/src/path_segments.rs b/vendor/url-1.7.2/src/path_segments.rs similarity index 100% rename from vendor/url/src/path_segments.rs rename to vendor/url-1.7.2/src/path_segments.rs diff --git a/vendor/url/src/quirks.rs b/vendor/url-1.7.2/src/quirks.rs similarity index 100% rename from vendor/url/src/quirks.rs rename to vendor/url-1.7.2/src/quirks.rs diff --git a/vendor/url/src/slicing.rs b/vendor/url-1.7.2/src/slicing.rs similarity index 100% rename from vendor/url/src/slicing.rs rename to vendor/url-1.7.2/src/slicing.rs diff --git a/vendor/url/tests/data.rs b/vendor/url-1.7.2/tests/data.rs similarity index 100% rename from vendor/url/tests/data.rs rename to vendor/url-1.7.2/tests/data.rs diff --git a/vendor/url/tests/setters_tests.json b/vendor/url-1.7.2/tests/setters_tests.json similarity index 100% rename from vendor/url/tests/setters_tests.json rename to vendor/url-1.7.2/tests/setters_tests.json diff --git a/vendor/url/tests/unit.rs b/vendor/url-1.7.2/tests/unit.rs similarity index 100% rename from vendor/url/tests/unit.rs rename to vendor/url-1.7.2/tests/unit.rs diff --git a/vendor/url/tests/urltestdata.json b/vendor/url-1.7.2/tests/urltestdata.json similarity index 100% rename from vendor/url/tests/urltestdata.json rename to vendor/url-1.7.2/tests/urltestdata.json diff --git a/version b/version index 9eae164ea3..914d30eb03 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.37.0 (eae3437df 2019-08-13) \ No newline at end of file +1.38.0 (625451e37 2019-09-23) \ No newline at end of file -- 2.39.2

    ` (where P is one of the previous types except `Self`) error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-asm.rs b/src/test/ui/feature-gates/feature-gate-asm.rs index 572d9f26ca..1fce279c9e 100644 --- a/src/test/ui/feature-gates/feature-gate-asm.rs +++ b/src/test/ui/feature-gates/feature-gate-asm.rs @@ -1,3 +1,5 @@ +// ignore-emscripten + fn main() { unsafe { asm!(""); //~ ERROR inline assembly is not stable enough diff --git a/src/test/ui/feature-gates/feature-gate-asm.stderr b/src/test/ui/feature-gates/feature-gate-asm.stderr index ccaf34f016..bfa4c87bed 100644 --- a/src/test/ui/feature-gates/feature-gate-asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm.stderr @@ -1,11 +1,11 @@ -error[E0658]: inline assembly is not stable enough for use and is subject to change - --> $DIR/feature-gate-asm.rs:3:9 +error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change + --> $DIR/feature-gate-asm.rs:5:9 | LL | asm!(""); - | ^^^^^^^^^ + | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29722 - = help: add #![feature(asm)] to the crate attributes to enable + = help: add `#![feature(asm)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-asm2.rs b/src/test/ui/feature-gates/feature-gate-asm2.rs index 259b0a14e5..4f56aa7234 100644 --- a/src/test/ui/feature-gates/feature-gate-asm2.rs +++ b/src/test/ui/feature-gates/feature-gate-asm2.rs @@ -1,4 +1,4 @@ -// gate-test-asm +// ignore-emscripten fn main() { unsafe { diff --git a/src/test/ui/feature-gates/feature-gate-asm2.stderr b/src/test/ui/feature-gates/feature-gate-asm2.stderr index cafe2be9d0..7519cad9a9 100644 --- a/src/test/ui/feature-gates/feature-gate-asm2.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm2.stderr @@ -1,11 +1,11 @@ -error[E0658]: inline assembly is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change --> $DIR/feature-gate-asm2.rs:5:26 | LL | println!("{:?}", asm!("")); - | ^^^^^^^^ + | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29722 - = help: add #![feature(asm)] to the crate attributes to enable + = help: add `#![feature(asm)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-assoc-type-defaults.stderr b/src/test/ui/feature-gates/feature-gate-assoc-type-defaults.stderr index 16b37cf29c..6d3f40c807 100644 --- a/src/test/ui/feature-gates/feature-gate-assoc-type-defaults.stderr +++ b/src/test/ui/feature-gates/feature-gate-assoc-type-defaults.stderr @@ -5,7 +5,7 @@ LL | type Bar = u8; | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29661 - = help: add #![feature(associated_type_defaults)] to the crate attributes to enable + = help: add `#![feature(associated_type_defaults)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 702f61262d..84af2a0163 100644 --- a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -5,7 +5,7 @@ LL | type A: Iterator; | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:15:22 @@ -14,7 +14,7 @@ LL | type B: Iterator; | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:19:20 @@ -23,7 +23,7 @@ LL | struct _St1> { | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:26:18 @@ -32,7 +32,7 @@ LL | enum _En1> { | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:33:19 @@ -41,7 +41,7 @@ LL | union _Un1> { | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:40:37 @@ -50,7 +50,7 @@ LL | type _TaWhere1 where T: Iterator = T; | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:43:22 @@ -59,7 +59,7 @@ LL | fn _apit(_: impl Tr1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:45:26 @@ -68,7 +68,7 @@ LL | fn _apit_dyn(_: &dyn Tr1) {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:48:24 @@ -77,7 +77,7 @@ LL | fn _rpit() -> impl Tr1 { S1 } | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:51:31 @@ -86,7 +86,7 @@ LL | fn _rpit_dyn() -> Box> { Box::new(S1) } | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:54:23 @@ -95,7 +95,7 @@ LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:60:24 @@ -104,7 +104,7 @@ LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:67:21 @@ -113,7 +113,7 @@ LL | let _: impl Tr1 = S1; | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/52662 - = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types --> $DIR/feature-gate-associated_type_bounds.rs:54:14 @@ -121,7 +121,7 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types --> $DIR/feature-gate-associated_type_bounds.rs:60:15 @@ -129,7 +129,7 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types --> $DIR/feature-gate-associated_type_bounds.rs:67:12 @@ -137,7 +137,7 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r LL | let _: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error: aborting due to 16 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr index b419f1232d..0157ed5534 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr +++ b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr @@ -23,7 +23,7 @@ LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(async_await)] to the crate attributes to enable + = help: add `#![feature(async_await)]` to the crate attributes to enable error: aborting due to 4 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs index 9cfefef412..78391c0e10 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await.rs +++ b/src/test/ui/feature-gates/feature-gate-async-await.rs @@ -15,5 +15,4 @@ async fn foo() {} //~ ERROR async fn is unstable fn main() { let _ = async {}; //~ ERROR async blocks are unstable - let _ = async || {}; //~ ERROR async closures are unstable } diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr index 43e41b4545..9f4a90157a 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await.stderr +++ b/src/test/ui/feature-gates/feature-gate-async-await.stderr @@ -11,7 +11,7 @@ LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(async_await)] to the crate attributes to enable + = help: add `#![feature(async_await)]` to the crate attributes to enable error[E0658]: async fn is unstable --> $DIR/feature-gate-async-await.rs:10:5 @@ -20,7 +20,7 @@ LL | async fn foo(); | ^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(async_await)] to the crate attributes to enable + = help: add `#![feature(async_await)]` to the crate attributes to enable error[E0658]: async fn is unstable --> $DIR/feature-gate-async-await.rs:14:1 @@ -29,7 +29,7 @@ LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(async_await)] to the crate attributes to enable + = help: add `#![feature(async_await)]` to the crate attributes to enable error[E0658]: async blocks are unstable --> $DIR/feature-gate-async-await.rs:17:13 @@ -38,17 +38,8 @@ LL | let _ = async {}; | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(async_await)] to the crate attributes to enable + = help: add `#![feature(async_await)]` to the crate attributes to enable -error[E0658]: async closures are unstable - --> $DIR/feature-gate-async-await.rs:18:13 - | -LL | let _ = async || {}; - | ^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add #![feature(async_await)] to the crate attributes to enable - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-box-expr.stderr b/src/test/ui/feature-gates/feature-gate-box-expr.stderr index 9666793313..1f243b2367 100644 --- a/src/test/ui/feature-gates/feature-gate-box-expr.stderr +++ b/src/test/ui/feature-gates/feature-gate-box-expr.stderr @@ -5,7 +5,7 @@ LL | let x = box 'c'; | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49733 - = help: add #![feature(box_syntax)] to the crate attributes to enable + = help: add `#![feature(box_syntax)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-box_patterns.stderr b/src/test/ui/feature-gates/feature-gate-box_patterns.stderr index 765b929de8..d2dafe93a8 100644 --- a/src/test/ui/feature-gates/feature-gate-box_patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-box_patterns.stderr @@ -5,7 +5,7 @@ LL | let box x = Box::new('c'); | ^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29641 - = help: add #![feature(box_patterns)] to the crate attributes to enable + = help: add `#![feature(box_patterns)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-box_syntax.stderr b/src/test/ui/feature-gates/feature-gate-box_syntax.stderr index a9cac7686e..61b0534d2d 100644 --- a/src/test/ui/feature-gates/feature-gate-box_syntax.stderr +++ b/src/test/ui/feature-gates/feature-gate-box_syntax.stderr @@ -5,7 +5,7 @@ LL | let x = box 3; | ^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49733 - = help: add #![feature(box_syntax)] to the crate attributes to enable + = help: add `#![feature(box_syntax)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs b/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs index 827ac3af8f..506b21dc7d 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs +++ b/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs @@ -1,4 +1,4 @@ -#![feature(intrinsics, lang_items, no_core)] +#![feature(intrinsics, lang_items, no_core, rustc_attrs)] #![crate_type="rlib"] #![no_core] @@ -88,3 +88,7 @@ fn main() { cfg!(target_has_atomic = "ptr"); //~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change } + +#[macro_export] +#[rustc_builtin_macro] +macro_rules! cfg { () => () } diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.stderr b/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.stderr index 995528efdd..1765bc7809 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.stderr +++ b/src/test/ui/feature-gates/feature-gate-cfg-target-has-atomic.stderr @@ -5,7 +5,7 @@ LL | #[cfg(target_has_atomic = "8")] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:21:7 @@ -14,7 +14,7 @@ LL | #[cfg(target_has_atomic = "8")] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:26:7 @@ -23,7 +23,7 @@ LL | #[cfg(target_has_atomic = "16")] | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:31:7 @@ -32,7 +32,7 @@ LL | #[cfg(target_has_atomic = "16")] | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:36:7 @@ -41,7 +41,7 @@ LL | #[cfg(target_has_atomic = "32")] | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:41:7 @@ -50,7 +50,7 @@ LL | #[cfg(target_has_atomic = "32")] | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:46:7 @@ -59,7 +59,7 @@ LL | #[cfg(target_has_atomic = "64")] | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:51:7 @@ -68,7 +68,7 @@ LL | #[cfg(target_has_atomic = "64")] | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:56:7 @@ -77,7 +77,7 @@ LL | #[cfg(target_has_atomic = "128")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:61:7 @@ -86,7 +86,7 @@ LL | #[cfg(target_has_atomic = "128")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:66:7 @@ -95,7 +95,7 @@ LL | #[cfg(target_has_atomic = "ptr")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:71:7 @@ -104,7 +104,7 @@ LL | #[cfg(target_has_atomic = "ptr")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:78:10 @@ -113,7 +113,7 @@ LL | cfg!(target_has_atomic = "8"); | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:80:10 @@ -122,7 +122,7 @@ LL | cfg!(target_has_atomic = "16"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:82:10 @@ -131,7 +131,7 @@ LL | cfg!(target_has_atomic = "32"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:84:10 @@ -140,7 +140,7 @@ LL | cfg!(target_has_atomic = "64"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:86:10 @@ -149,7 +149,7 @@ LL | cfg!(target_has_atomic = "128"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change --> $DIR/feature-gate-cfg-target-has-atomic.rs:88:10 @@ -158,7 +158,7 @@ LL | cfg!(target_has_atomic = "ptr"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32976 - = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable + = help: add `#![feature(cfg_target_has_atomic)]` to the crate attributes to enable error: aborting due to 18 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr b/src/test/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr index 3d24b21825..5765449310 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr +++ b/src/test/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr @@ -5,7 +5,7 @@ LL | #[cfg_attr(target_thread_local, thread_local)] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29594 - = help: add #![feature(cfg_target_thread_local)] to the crate attributes to enable + = help: add `#![feature(cfg_target_thread_local)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-compiler-builtins.stderr b/src/test/ui/feature-gates/feature-gate-compiler-builtins.stderr index 278a184bae..9d04aef862 100644 --- a/src/test/ui/feature-gates/feature-gate-compiler-builtins.stderr +++ b/src/test/ui/feature-gates/feature-gate-compiler-builtins.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[compiler_builtins]` attribute is used to identify the `comp LL | #![compiler_builtins] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(compiler_builtins)] to the crate attributes to enable + = help: add `#![feature(compiler_builtins)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents.stderr index be8c727e2b..8639f622cd 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents.stderr @@ -1,20 +1,20 @@ -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents.rs:5:13 | LL | let a = concat_idents!(X, Y_1); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29599 - = help: add #![feature(concat_idents)] to the crate attributes to enable + = help: add `#![feature(concat_idents)]` to the crate attributes to enable -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents.rs:6:13 | LL | let b = concat_idents!(X, Y_2); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29599 - = help: add #![feature(concat_idents)] to the crate attributes to enable + = help: add `#![feature(concat_idents)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.rs b/src/test/ui/feature-gates/feature-gate-concat_idents2.rs index 0cc6c577e8..9660ffeafa 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents2.rs +++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.rs @@ -1,5 +1,3 @@ -// gate-test-concat_idents - fn main() { concat_idents!(a, b); //~ ERROR `concat_idents` is not stable enough //~| ERROR cannot find value `ab` in this scope diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr index 864ee63b20..14519622c0 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr @@ -1,14 +1,14 @@ -error[E0658]: `concat_idents` is not stable enough for use and is subject to change - --> $DIR/feature-gate-concat_idents2.rs:4:5 +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change + --> $DIR/feature-gate-concat_idents2.rs:2:5 | LL | concat_idents!(a, b); - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29599 - = help: add #![feature(concat_idents)] to the crate attributes to enable + = help: add `#![feature(concat_idents)]` to the crate attributes to enable error[E0425]: cannot find value `ab` in this scope - --> $DIR/feature-gate-concat_idents2.rs:4:5 + --> $DIR/feature-gate-concat_idents2.rs:2:5 | LL | concat_idents!(a, b); | ^^^^^^^^^^^^^^^^^^^^^ not found in this scope diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents3.rs b/src/test/ui/feature-gates/feature-gate-concat_idents3.rs index 2882e7a800..81710fd9fb 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents3.rs +++ b/src/test/ui/feature-gates/feature-gate-concat_idents3.rs @@ -1,5 +1,3 @@ -// gate-test-concat_idents - const XY_1: i32 = 10; fn main() { diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr index cb8725ab56..afe6acb253 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr @@ -1,20 +1,20 @@ -error[E0658]: `concat_idents` is not stable enough for use and is subject to change - --> $DIR/feature-gate-concat_idents3.rs:7:20 +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change + --> $DIR/feature-gate-concat_idents3.rs:5:20 | LL | assert_eq!(10, concat_idents!(X, Y_1)); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29599 - = help: add #![feature(concat_idents)] to the crate attributes to enable + = help: add `#![feature(concat_idents)]` to the crate attributes to enable -error[E0658]: `concat_idents` is not stable enough for use and is subject to change - --> $DIR/feature-gate-concat_idents3.rs:8:20 +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change + --> $DIR/feature-gate-concat_idents3.rs:6:20 | LL | assert_eq!(20, concat_idents!(X, Y_2)); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29599 - = help: add #![feature(concat_idents)] to the crate attributes to enable + = help: add `#![feature(concat_idents)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-const-indexing.rs b/src/test/ui/feature-gates/feature-gate-const-indexing.rs index 4df1c7d6ed..2b1067b348 100644 --- a/src/test/ui/feature-gates/feature-gate-const-indexing.rs +++ b/src/test/ui/feature-gates/feature-gate-const-indexing.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47]; diff --git a/src/test/ui/feature-gates/feature-gate-const_fn.stderr b/src/test/ui/feature-gates/feature-gate-const_fn.stderr index b4d64c2422..c5c39cc200 100644 --- a/src/test/ui/feature-gates/feature-gate-const_fn.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_fn.stderr @@ -23,7 +23,7 @@ LL | const fn foo() -> u32; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0658]: const fn is unstable --> $DIR/feature-gate-const_fn.rs:8:5 @@ -32,7 +32,7 @@ LL | const fn bar() -> u32 { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-const_generics.stderr b/src/test/ui/feature-gates/feature-gate-const_generics.stderr index 9ea04a1e20..468e9c31d3 100644 --- a/src/test/ui/feature-gates/feature-gate-const_generics.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_generics.stderr @@ -5,7 +5,7 @@ LL | fn foo() {} | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44580 - = help: add #![feature(const_generics)] to the crate attributes to enable + = help: add `#![feature(const_generics)]` to the crate attributes to enable error[E0658]: const generics are unstable --> $DIR/feature-gate-const_generics.rs:3:18 @@ -14,7 +14,7 @@ LL | struct Foo([(); X]); | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44580 - = help: add #![feature(const_generics)] to the crate attributes to enable + = help: add `#![feature(const_generics)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs b/src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs new file mode 100644 index 0000000000..be195271c1 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs @@ -0,0 +1,11 @@ +// ignore-tidy-linelength +#![allow(warnings)] + +struct Bar; + +fn foo() { + let arr: [Option; 2] = [None::; 2]; + //~^ ERROR the trait bound `std::option::Option: std::marker::Copy` is not satisfied [E0277] +} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.stderr b/src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.stderr new file mode 100644 index 0000000000..eed69a0c28 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `std::option::Option: std::marker::Copy` is not satisfied + --> $DIR/feature-gate-const_in_array_repeat_expressions.rs:7:36 + | +LL | let arr: [Option; 2] = [None::; 2]; + | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::option::Option` + | + = help: the following implementations were found: + as std::marker::Copy> + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/feature-gates/feature-gate-const_transmute.stderr b/src/test/ui/feature-gates/feature-gate-const_transmute.stderr index c3cd313134..41b653d98d 100644 --- a/src/test/ui/feature-gates/feature-gate-const_transmute.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_transmute.stderr @@ -5,7 +5,7 @@ LL | const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) }; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53605 - = help: add #![feature(const_transmute)] to the crate attributes to enable + = help: add `#![feature(const_transmute)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-crate_visibility_modifier.stderr b/src/test/ui/feature-gates/feature-gate-crate_visibility_modifier.stderr index 4e70870ae7..1e061eced3 100644 --- a/src/test/ui/feature-gates/feature-gate-crate_visibility_modifier.stderr +++ b/src/test/ui/feature-gates/feature-gate-crate_visibility_modifier.stderr @@ -5,7 +5,7 @@ LL | crate struct Bender { | ^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53120 - = help: add #![feature(crate_visibility_modifier)] to the crate attributes to enable + = help: add `#![feature(crate_visibility_modifier)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute.rs index f31c9d5afc..d34936b42a 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute.rs @@ -1,23 +1,18 @@ // Check that literals in attributes parse just fine. +#[fake_attr] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(100)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr("hello")] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(name = "hello")] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute macro `fake_attr` in th +#[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute macro `fake_attr` in this scop +#[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute macro `fake_attr` in +#[fake_attr(true)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_attr(b"hi")] //~ ERROR cannot find attribute macro `fake_attr` in this scope +#[fake_doc(r"doc")] //~ ERROR cannot find attribute macro `fake_doc` in this scope +struct Q {} -#![allow(dead_code)] -#![allow(unused_variables)] - -#[fake_attr] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(100)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(1, 2, 3)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr("hello")] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(name = "hello")] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(key = "hello", val = 10)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(key("hello"), val(10))] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(enabled = true, disabled = false)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(true)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(pi = 3.14159)] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_attr(b"hi")] //~ ERROR attribute `fake_attr` is currently unknown -#[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown -struct Q { } - - -fn main() { } +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr index 9b81c38f86..efdc2d1cd3 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr @@ -1,120 +1,80 @@ -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:7:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:3:3 | LL | #[fake_attr] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:8:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:4:3 | LL | #[fake_attr(100)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:9:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:5:3 | LL | #[fake_attr(1, 2, 3)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:10:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:6:3 | LL | #[fake_attr("hello")] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:11:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:7:3 | LL | #[fake_attr(name = "hello")] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:12:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:8:3 | LL | #[fake_attr(1, "hi", key = 12, true, false)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:13:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:9:3 | LL | #[fake_attr(key = "hello", val = 10)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:14:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:10:3 | LL | #[fake_attr(key("hello"), val(10))] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:15:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:11:3 | LL | #[fake_attr(enabled = true, disabled = false)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:16:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:12:3 | LL | #[fake_attr(true)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:17:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:13:3 | LL | #[fake_attr(pi = 3.14159)] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:18:3 +error: cannot find attribute macro `fake_attr` in this scope + --> $DIR/feature-gate-custom_attribute.rs:14:3 | LL | #[fake_attr(b"hi")] | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `fake_doc` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute.rs:19:3 +error: cannot find attribute macro `fake_doc` in this scope + --> $DIR/feature-gate-custom_attribute.rs:15:3 | LL | #[fake_doc(r"doc")] | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to 13 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs index 2137a2a003..8fe11cb02a 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs @@ -4,54 +4,54 @@ // gate-test-custom_attribute struct StLt<#[lt_struct] 'a>(&'a u32); -//~^ ERROR The attribute `lt_struct` is currently unknown to the compiler +//~^ ERROR the attribute `lt_struct` is currently unknown to the compiler struct StTy<#[ty_struct] I>(I); -//~^ ERROR The attribute `ty_struct` is currently unknown to the compiler +//~^ ERROR the attribute `ty_struct` is currently unknown to the compiler enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } -//~^ ERROR The attribute `lt_enum` is currently unknown to the compiler +//~^ ERROR the attribute `lt_enum` is currently unknown to the compiler enum EnTy<#[ty_enum] J> { A(J), B } -//~^ ERROR The attribute `ty_enum` is currently unknown to the compiler +//~^ ERROR the attribute `ty_enum` is currently unknown to the compiler trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -//~^ ERROR The attribute `lt_trait` is currently unknown to the compiler +//~^ ERROR the attribute `lt_trait` is currently unknown to the compiler trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } -//~^ ERROR The attribute `ty_trait` is currently unknown to the compiler +//~^ ERROR the attribute `ty_trait` is currently unknown to the compiler type TyLt<#[lt_type] 'd> = &'d u32; -//~^ ERROR The attribute `lt_type` is currently unknown to the compiler +//~^ ERROR the attribute `lt_type` is currently unknown to the compiler type TyTy<#[ty_type] L> = (L, ); -//~^ ERROR The attribute `ty_type` is currently unknown to the compiler +//~^ ERROR the attribute `ty_type` is currently unknown to the compiler impl<#[lt_inherent] 'e> StLt<'e> { } -//~^ ERROR The attribute `lt_inherent` is currently unknown to the compiler +//~^ ERROR the attribute `lt_inherent` is currently unknown to the compiler impl<#[ty_inherent] M> StTy { } -//~^ ERROR The attribute `ty_inherent` is currently unknown to the compiler +//~^ ERROR the attribute `ty_inherent` is currently unknown to the compiler impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - //~^ ERROR The attribute `lt_impl_for` is currently unknown to the compiler + //~^ ERROR the attribute `lt_impl_for` is currently unknown to the compiler fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } } impl<#[ty_impl_for] N> TrTy for StTy { - //~^ ERROR The attribute `ty_impl_for` is currently unknown to the compiler + //~^ ERROR the attribute `ty_impl_for` is currently unknown to the compiler fn foo(&self, _: N) { } } fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -//~^ ERROR The attribute `lt_fn` is currently unknown to the compiler +//~^ ERROR the attribute `lt_fn` is currently unknown to the compiler fn f_ty<#[ty_fn] O>(_: O) { } -//~^ ERROR The attribute `ty_fn` is currently unknown to the compiler +//~^ ERROR the attribute `ty_fn` is currently unknown to the compiler impl StTy { fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - //~^ ERROR The attribute `lt_meth` is currently unknown to the compiler + //~^ ERROR the attribute `lt_meth` is currently unknown to the compiler fn m_ty<#[ty_meth] P>(_: P) { } - //~^ ERROR The attribute `ty_meth` is currently unknown to the compiler + //~^ ERROR the attribute `ty_meth` is currently unknown to the compiler } fn hof_lt(_: Q) where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - //~^ ERROR The attribute `lt_hof` is currently unknown to the compiler + //~^ ERROR the attribute `lt_hof` is currently unknown to the compiler { } diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr index 8c8ac1233a..15e0c41b90 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr @@ -1,155 +1,155 @@ -error[E0658]: The attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:6:13 | LL | struct StLt<#[lt_struct] 'a>(&'a u32); | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:8:13 | LL | struct StTy<#[ty_struct] I>(I); | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:11:11 | LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:13:11 | LL | enum EnTy<#[ty_enum] J> { A(J), B } | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:16:12 | LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:18:12 | LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:21:11 | LL | type TyLt<#[lt_type] 'd> = &'d u32; | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:23:11 | LL | type TyTy<#[ty_type] L> = (L, ); | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:26:6 | LL | impl<#[lt_inherent] 'e> StLt<'e> { } | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:28:6 | LL | impl<#[ty_inherent] M> StTy { } | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:31:6 | LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:35:6 | LL | impl<#[ty_impl_for] N> TrTy for StTy { | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:40:9 | LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:42:9 | LL | fn f_ty<#[ty_fn] O>(_: O) { } | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:46:13 | LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:48:13 | LL | fn m_ty<#[ty_meth] P>(_: P) { } | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: The attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: the attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/feature-gate-custom_attribute2.rs:53:19 | LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable + = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error: aborting due to 17 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs index 0a20049793..83bb153ba0 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs @@ -1,3 +1,6 @@ #![test_runner(main)] //~ ERROR custom test frameworks are an unstable feature +#[test_case] //~ ERROR custom test frameworks are an unstable feature +fn f() {} + fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr index e288af54cb..38304e7f3f 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr @@ -1,3 +1,12 @@ +error[E0658]: use of unstable library feature 'custom_test_frameworks': custom test frameworks are an unstable feature + --> $DIR/feature-gate-custom_test_frameworks.rs:3:3 + | +LL | #[test_case] + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/50297 + = help: add `#![feature(custom_test_frameworks)]` to the crate attributes to enable + error[E0658]: custom test frameworks are an unstable feature --> $DIR/feature-gate-custom_test_frameworks.rs:1:1 | @@ -5,8 +14,8 @@ LL | #![test_runner(main)] | ^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50297 - = help: add #![feature(custom_test_frameworks)] to the crate attributes to enable + = help: add `#![feature(custom_test_frameworks)]` to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-decl_macro.stderr b/src/test/ui/feature-gates/feature-gate-decl_macro.stderr index 808363a004..905a1b1531 100644 --- a/src/test/ui/feature-gates/feature-gate-decl_macro.stderr +++ b/src/test/ui/feature-gates/feature-gate-decl_macro.stderr @@ -5,7 +5,7 @@ LL | macro m() {} | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/39412 - = help: add #![feature(decl_macro)] to the crate attributes to enable + = help: add `#![feature(decl_macro)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr b/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr index ac8cd10176..f13803b80f 100644 --- a/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr +++ b/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr @@ -4,7 +4,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type` LL | fn avg(_: T) {} | ^ | - = note: #[deny(invalid_type_param_default)] on by default + = note: `#[deny(invalid_type_param_default)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #36887 diff --git a/src/test/ui/feature-gates/feature-gate-doc_alias.rs b/src/test/ui/feature-gates/feature-gate-doc_alias.rs index d7980f882d..adb6fc217a 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_alias.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_alias.rs @@ -1,4 +1,4 @@ -#[doc(alias = "foo")] //~ ERROR: #[doc(alias = "...")] is experimental +#[doc(alias = "foo")] //~ ERROR: `#[doc(alias = "...")]` is experimental pub struct Foo; fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_alias.stderr b/src/test/ui/feature-gates/feature-gate-doc_alias.stderr index be85ae4b13..dddaa45de8 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_alias.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_alias.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[doc(alias = "...")] is experimental +error[E0658]: `#[doc(alias = "...")]` is experimental --> $DIR/feature-gate-doc_alias.rs:1:1 | LL | #[doc(alias = "foo")] | ^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/50146 - = help: add #![feature(doc_alias)] to the crate attributes to enable + = help: add `#![feature(doc_alias)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr index 0f84a1b11f..9bf97a4a47 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr @@ -5,7 +5,7 @@ LL | #[cfg(rustdoc)] | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/43781 - = help: add #![feature(doc_cfg)] to the crate attributes to enable + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg.rs b/src/test/ui/feature-gates/feature-gate-doc_cfg.rs index f13129888b..bb3846e7f6 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg.rs @@ -1,2 +1,2 @@ -#[doc(cfg(unix))] //~ ERROR: #[doc(cfg(...))] is experimental +#[doc(cfg(unix))] //~ ERROR: `#[doc(cfg(...))]` is experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr b/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr index 9e4aa6c7a0..7b0a231df4 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[doc(cfg(...))] is experimental +error[E0658]: `#[doc(cfg(...))]` is experimental --> $DIR/feature-gate-doc_cfg.rs:1:1 | LL | #[doc(cfg(unix))] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/43781 - = help: add #![feature(doc_cfg)] to the crate attributes to enable + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-doc_keyword.rs b/src/test/ui/feature-gates/feature-gate-doc_keyword.rs index b08940e28f..6cdcfa67c3 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_keyword.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_keyword.rs @@ -1,4 +1,4 @@ -#[doc(keyword = "match")] //~ ERROR: #[doc(keyword = "...")] is experimental +#[doc(keyword = "match")] //~ ERROR: `#[doc(keyword = "...")]` is experimental /// wonderful mod foo{} diff --git a/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr b/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr index 6e46478172..abde0bea9b 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[doc(keyword = "...")] is experimental +error[E0658]: `#[doc(keyword = "...")]` is experimental --> $DIR/feature-gate-doc_keyword.rs:1:1 | LL | #[doc(keyword = "match")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51315 - = help: add #![feature(doc_keyword)] to the crate attributes to enable + = help: add `#![feature(doc_keyword)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-doc_masked.rs b/src/test/ui/feature-gates/feature-gate-doc_masked.rs index 034c5cf52e..bde3af6b59 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_masked.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_masked.rs @@ -1,4 +1,4 @@ -#[doc(masked)] //~ ERROR: #[doc(masked)] is experimental +#[doc(masked)] //~ ERROR: `#[doc(masked)]` is experimental extern crate std as realstd; fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_masked.stderr b/src/test/ui/feature-gates/feature-gate-doc_masked.stderr index d778d4d994..0d334fab41 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_masked.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_masked.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[doc(masked)] is experimental +error[E0658]: `#[doc(masked)]` is experimental --> $DIR/feature-gate-doc_masked.rs:1:1 | LL | #[doc(masked)] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44027 - = help: add #![feature(doc_masked)] to the crate attributes to enable + = help: add `#![feature(doc_masked)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs b/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs index 28b689b4d9..452b45b344 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs @@ -1,4 +1,4 @@ -#[doc(spotlight)] //~ ERROR: #[doc(spotlight)] is experimental +#[doc(spotlight)] //~ ERROR: `#[doc(spotlight)]` is experimental trait SomeTrait {} fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr b/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr index 2bf201f490..16532e4433 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[doc(spotlight)] is experimental +error[E0658]: `#[doc(spotlight)]` is experimental --> $DIR/feature-gate-doc_spotlight.rs:1:1 | LL | #[doc(spotlight)] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/45040 - = help: add #![feature(doc_spotlight)] to the crate attributes to enable + = help: add `#![feature(doc_spotlight)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs b/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs deleted file mode 100644 index 33252019e7..0000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![deny(deprecated)] -#![feature(dropck_parametricity)] - -struct Foo; - -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] - //~^ ERROR use of deprecated attribute `dropck_parametricity` - fn drop(&mut self) {} -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr b/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr deleted file mode 100644 index b6a474575c..0000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh-2.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: use of deprecated attribute `dropck_parametricity`: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future. See https://github.com/rust-lang/rust/issues/34761 - --> $DIR/feature-gate-dropck-ugeh-2.rs:7:5 - | -LL | #[unsafe_destructor_blind_to_params] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this attribute with `#[may_dangle]` - | -note: lint level defined here - --> $DIR/feature-gate-dropck-ugeh-2.rs:1:9 - | -LL | #![deny(deprecated)] - | ^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs b/src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs deleted file mode 100644 index a2377cda9b..0000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.rs +++ /dev/null @@ -1,29 +0,0 @@ -// gate-test-dropck_parametricity - -// Ensure that attempts to use the unsafe attribute are feature-gated. -// Example adapted from RFC 1238 text (just left out the feature gate). - -// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md -// #example-of-the-unguarded-escape-hatch - -use std::cell::Cell; - -struct Concrete<'a>(u32, Cell>>); - -struct Foo { data: Vec } - -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] // This is the UGEH attribute - //~^ ERROR unsafe_destructor_blind_to_params has been replaced - //~| WARN use of deprecated attribute `dropck_parametricity` - fn drop(&mut self) { } -} - -fn main() { - let mut foo = Foo { data: Vec::new() }; - foo.data.push(Concrete(0, Cell::new(None))); - foo.data.push(Concrete(0, Cell::new(None))); - - foo.data[0].1.set(Some(&foo.data[1])); - foo.data[1].1.set(Some(&foo.data[0])); -} diff --git a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr b/src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr deleted file mode 100644 index 9c7f7b2178..0000000000 --- a/src/test/ui/feature-gates/feature-gate-dropck-ugeh.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0658]: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future - --> $DIR/feature-gate-dropck-ugeh.rs:16:5 - | -LL | #[unsafe_destructor_blind_to_params] // This is the UGEH attribute - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/28498 - = help: add #![feature(dropck_parametricity)] to the crate attributes to enable - -warning: use of deprecated attribute `dropck_parametricity`: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future. See https://github.com/rust-lang/rust/issues/34761 - --> $DIR/feature-gate-dropck-ugeh.rs:16:5 - | -LL | #[unsafe_destructor_blind_to_params] // This is the UGEH attribute - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this attribute with `#[may_dangle]` - | - = note: #[warn(deprecated)] on by default - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr b/src/test/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr index 0eb6da3b12..ee20408d17 100644 --- a/src/test/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr +++ b/src/test/ui/feature-gates/feature-gate-exclusive-range-pattern.stderr @@ -5,7 +5,7 @@ LL | 0 .. 3 => {} | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37854 - = help: add #![feature(exclusive_range_pattern)] to the crate attributes to enable + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-existential-type.rs b/src/test/ui/feature-gates/feature-gate-existential-type.rs deleted file mode 100644 index 6dfd2d1087..0000000000 --- a/src/test/ui/feature-gates/feature-gate-existential-type.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Check that existential types must be ungated to use the `existential` keyword - -existential type Foo: std::fmt::Debug; //~ ERROR existential types are unstable - -trait Bar { - type Baa: std::fmt::Debug; - fn define() -> Self::Baa; -} - -impl Bar for () { - existential type Baa: std::fmt::Debug; //~ ERROR existential types are unstable - fn define() -> Self::Baa { 0 } -} - -fn define() -> Foo { 0 } - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-existential-type.stderr b/src/test/ui/feature-gates/feature-gate-existential-type.stderr deleted file mode 100644 index efaf29c00d..0000000000 --- a/src/test/ui/feature-gates/feature-gate-existential-type.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: existential types are unstable - --> $DIR/feature-gate-existential-type.rs:3:1 - | -LL | existential type Foo: std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/34511 - = help: add #![feature(existential_type)] to the crate attributes to enable - -error[E0658]: existential types are unstable - --> $DIR/feature-gate-existential-type.rs:11:5 - | -LL | existential type Baa: std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/34511 - = help: add #![feature(existential_type)] to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr b/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr index 59b28704dd..2f4c220ee9 100644 --- a/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr +++ b/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr @@ -2,13 +2,13 @@ error[E0432]: unresolved import `core` --> $DIR/feature-gate-extern_absolute_paths.rs:1:5 | LL | use core::default; - | ^^^^ maybe a missing `extern crate core;`? + | ^^^^ maybe a missing crate `core`? -error[E0433]: failed to resolve: maybe a missing `extern crate core;`? +error[E0433]: failed to resolve: maybe a missing crate `core`? --> $DIR/feature-gate-extern_absolute_paths.rs:4:19 | LL | let _: u8 = ::core::default::Default(); - | ^^^^ maybe a missing `extern crate core;`? + | ^^^^ maybe a missing crate `core`? error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-extern_types.stderr b/src/test/ui/feature-gates/feature-gate-extern_types.stderr index 18c0bae2c4..f82c64f9ca 100644 --- a/src/test/ui/feature-gates/feature-gate-extern_types.stderr +++ b/src/test/ui/feature-gates/feature-gate-extern_types.stderr @@ -5,7 +5,7 @@ LL | type T; | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/43467 - = help: add #![feature(extern_types)] to the crate attributes to enable + = help: add `#![feature(extern_types)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.rs b/src/test/ui/feature-gates/feature-gate-external_doc.rs index e3ffb88819..dec3fa1857 100644 --- a/src/test/ui/feature-gates/feature-gate-external_doc.rs +++ b/src/test/ui/feature-gates/feature-gate-external_doc.rs @@ -1,2 +1,2 @@ -#[doc(include="asdf.md")] //~ ERROR: #[doc(include = "...")] is experimental +#[doc(include="asdf.md")] //~ ERROR: `#[doc(include = "...")]` is experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.stderr b/src/test/ui/feature-gates/feature-gate-external_doc.stderr index 79e4f8e9b6..a5a874374d 100644 --- a/src/test/ui/feature-gates/feature-gate-external_doc.stderr +++ b/src/test/ui/feature-gates/feature-gate-external_doc.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[doc(include = "...")] is experimental +error[E0658]: `#[doc(include = "...")]` is experimental --> $DIR/feature-gate-external_doc.rs:1:1 | LL | #[doc(include="asdf.md")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44732 - = help: add #![feature(external_doc)] to the crate attributes to enable + = help: add `#![feature(external_doc)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-ffi_returns_twice.stderr b/src/test/ui/feature-gates/feature-gate-ffi_returns_twice.stderr index 72e414eab9..b452db86bb 100644 --- a/src/test/ui/feature-gates/feature-gate-ffi_returns_twice.stderr +++ b/src/test/ui/feature-gates/feature-gate-ffi_returns_twice.stderr @@ -5,7 +5,7 @@ LL | #[ffi_returns_twice] | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/58314 - = help: add #![feature(ffi_returns_twice)] to the crate attributes to enable + = help: add `#![feature(ffi_returns_twice)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr b/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr index 58d2c790ff..b211e2f8ed 100644 --- a/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr +++ b/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr @@ -1,10 +1,10 @@ -error[E0658]: `format_args_nl` is only for internal language use and is subject to change +error[E0658]: use of unstable library feature 'format_args_nl': `format_args_nl` is only for internal language use and is subject to change --> $DIR/feature-gate-format_args_nl.rs:2:5 | LL | format_args_nl!(""); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ | - = help: add #![feature(format_args_nl)] to the crate attributes to enable + = help: add `#![feature(format_args_nl)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-fundamental.stderr b/src/test/ui/feature-gates/feature-gate-fundamental.stderr index 265b576bc7..409148484c 100644 --- a/src/test/ui/feature-gates/feature-gate-fundamental.stderr +++ b/src/test/ui/feature-gates/feature-gate-fundamental.stderr @@ -5,7 +5,7 @@ LL | #[fundamental] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29635 - = help: add #![feature(fundamental)] to the crate attributes to enable + = help: add `#![feature(fundamental)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-generators.stderr b/src/test/ui/feature-gates/feature-gate-generators.stderr index d85dc18d03..cdb0560125 100644 --- a/src/test/ui/feature-gates/feature-gate-generators.stderr +++ b/src/test/ui/feature-gates/feature-gate-generators.stderr @@ -5,7 +5,7 @@ LL | yield true; | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/43122 - = help: add #![feature(generators)] to the crate attributes to enable + = help: add `#![feature(generators)]` to the crate attributes to enable error[E0627]: yield statement outside of generator literal --> $DIR/feature-gate-generators.rs:2:5 diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr index d37dd93983..04473f4106 100644 --- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr +++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr @@ -5,7 +5,7 @@ LL | type Pointer: Deref; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: generic associated types are unstable --> $DIR/feature-gate-generic_associated_types.rs:6:5 @@ -14,7 +14,7 @@ LL | type Pointer2: Deref where T: Clone, U: Clone; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: where clauses on associated types are unstable --> $DIR/feature-gate-generic_associated_types.rs:6:5 @@ -23,7 +23,7 @@ LL | type Pointer2: Deref where T: Clone, U: Clone; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: generic associated types are unstable --> $DIR/feature-gate-generic_associated_types.rs:14:5 @@ -32,7 +32,7 @@ LL | type Pointer = Box; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: generic associated types are unstable --> $DIR/feature-gate-generic_associated_types.rs:16:5 @@ -41,7 +41,7 @@ LL | type Pointer2 = Box; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: where clauses on associated types are unstable --> $DIR/feature-gate-generic_associated_types.rs:21:5 @@ -50,7 +50,7 @@ LL | type Assoc where Self: Sized; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: where clauses on associated types are unstable --> $DIR/feature-gate-generic_associated_types.rs:26:5 @@ -59,7 +59,7 @@ LL | type Assoc where Self: Sized = Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add #![feature(generic_associated_types)] to the crate attributes to enable + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error: aborting due to 7 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-global_asm.stderr b/src/test/ui/feature-gates/feature-gate-global_asm.stderr index 7d8abac399..733b8d08f7 100644 --- a/src/test/ui/feature-gates/feature-gate-global_asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-global_asm.stderr @@ -1,11 +1,11 @@ -error[E0658]: `global_asm!` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'global_asm': `global_asm!` is not stable enough for use and is subject to change --> $DIR/feature-gate-global_asm.rs:1:1 | LL | global_asm!(""); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35119 - = help: add #![feature(global_asm)] to the crate attributes to enable + = help: add `#![feature(global_asm)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr index a54e7e1b3b..bd648b4059 100644 --- a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr +++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr @@ -10,7 +10,7 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r LL | const FOO: impl Copy = 42; | ^^^^^^^^^ | - = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types --> $DIR/feature-gate-impl_trait_in_bindings.rs:4:13 @@ -18,7 +18,7 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r LL | static BAR: impl Copy = 42; | ^^^^^^^^^ | - = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr index 372af6ad92..09843f05af 100644 --- a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr +++ b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr @@ -6,7 +6,7 @@ LL | | fn bar(); LL | | } | |_^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:5:1 @@ -14,7 +14,7 @@ error[E0658]: intrinsics are subject to change LL | extern "rust-intrinsic" fn baz() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(intrinsics)] to the crate attributes to enable + = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0093]: unrecognized intrinsic function: `bar` --> $DIR/feature-gate-intrinsics.rs:2:5 diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr index 1d5998641b..11b2b3e740 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr @@ -5,7 +5,7 @@ LL | assert!([1, 2, 2, 9].iter().is_sorted()); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53485 - = help: add #![feature(is_sorted)] to the crate attributes to enable + = help: add `#![feature(is_sorted)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API --> $DIR/feature-gate-is_sorted.rs:5:39 @@ -14,7 +14,7 @@ LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53485 - = help: add #![feature(is_sorted)] to the crate attributes to enable + = help: add `#![feature(is_sorted)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API --> $DIR/feature-gate-is_sorted.rs:9:26 @@ -23,7 +23,7 @@ LL | assert!([1, 2, 2, 9].is_sorted()); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53485 - = help: add #![feature(is_sorted)] to the crate attributes to enable + = help: add `#![feature(is_sorted)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API --> $DIR/feature-gate-is_sorted.rs:11:32 @@ -32,7 +32,7 @@ LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53485 - = help: add #![feature(is_sorted)] to the crate attributes to enable + = help: add `#![feature(is_sorted)]` to the crate attributes to enable error: aborting due to 4 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-label_break_value.stderr b/src/test/ui/feature-gates/feature-gate-label_break_value.stderr index 40efc4dec4..a417e0eec2 100644 --- a/src/test/ui/feature-gates/feature-gate-label_break_value.stderr +++ b/src/test/ui/feature-gates/feature-gate-label_break_value.stderr @@ -5,7 +5,7 @@ LL | 'a: { | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/48594 - = help: add #![feature(label_break_value)] to the crate attributes to enable + = help: add `#![feature(label_break_value)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-lang-items.stderr b/src/test/ui/feature-gates/feature-gate-lang-items.stderr index 8fc1197ddf..c2496863fe 100644 --- a/src/test/ui/feature-gates/feature-gate-lang-items.stderr +++ b/src/test/ui/feature-gates/feature-gate-lang-items.stderr @@ -4,7 +4,7 @@ error[E0658]: language items are subject to change LL | #[lang = "foo"] | ^^^^^^^^^^^^^^^ | - = help: add #![feature(lang_items)] to the crate attributes to enable + = help: add `#![feature(lang_items)]` to the crate attributes to enable error[E0522]: definition of an unknown language item: `foo` --> $DIR/feature-gate-lang-items.rs:1:1 diff --git a/src/test/ui/feature-gates/feature-gate-link_args.stderr b/src/test/ui/feature-gates/feature-gate-link_args.stderr index 5267b56253..bd690b3f89 100644 --- a/src/test/ui/feature-gates/feature-gate-link_args.stderr +++ b/src/test/ui/feature-gates/feature-gate-link_args.stderr @@ -5,7 +5,7 @@ LL | #[link_args = "-l expected_use_case"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29596 - = help: add #![feature(link_args)] to the crate attributes to enable + = help: add `#![feature(link_args)]` to the crate attributes to enable error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead --> $DIR/feature-gate-link_args.rs:16:1 @@ -14,7 +14,7 @@ LL | #[link_args = "-l unexected_use_on_non_extern_item"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29596 - = help: add #![feature(link_args)] to the crate attributes to enable + = help: add `#![feature(link_args)]` to the crate attributes to enable error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead --> $DIR/feature-gate-link_args.rs:9:1 @@ -23,7 +23,7 @@ LL | #![link_args = "-l unexpected_use_as_inner_attr_on_mod"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29596 - = help: add #![feature(link_args)] to the crate attributes to enable + = help: add `#![feature(link_args)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr index 1648245d0b..58aa4ed749 100644 --- a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr +++ b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr @@ -5,7 +5,7 @@ LL | #[link(name = "foo", cfg(foo))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37406 - = help: add #![feature(link_cfg)] to the crate attributes to enable + = help: add `#![feature(link_cfg)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr b/src/test/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr index 903696dc7c..6c8e76d269 100644 --- a/src/test/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr +++ b/src/test/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr @@ -5,7 +5,7 @@ LL | fn sqrt(x: f32) -> f32; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29602 - = help: add #![feature(link_llvm_intrinsics)] to the crate attributes to enable + = help: add `#![feature(link_llvm_intrinsics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-linkage.stderr b/src/test/ui/feature-gates/feature-gate-linkage.stderr index 872c695120..d3f2aa6ba8 100644 --- a/src/test/ui/feature-gates/feature-gate-linkage.stderr +++ b/src/test/ui/feature-gates/feature-gate-linkage.stderr @@ -5,7 +5,7 @@ LL | #[linkage = "extern_weak"] static foo: isize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29603 - = help: add #![feature(linkage)] to the crate attributes to enable + = help: add `#![feature(linkage)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr index 9e814a20d6..390a1bf580 100644 --- a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr +++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr @@ -5,7 +5,7 @@ LL | #![warn(nonstandard_style, reason = "the standard should be respected")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54503 - = help: add #![feature(lint_reasons)] to the crate attributes to enable + = help: add `#![feature(lint_reasons)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax.stderr index 67bd48d3be..fa57c20ecd 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax.stderr +++ b/src/test/ui/feature-gates/feature-gate-log_syntax.stderr @@ -1,11 +1,11 @@ -error[E0658]: `log_syntax!` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change --> $DIR/feature-gate-log_syntax.rs:2:5 | LL | log_syntax!() - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(log_syntax)] to the crate attributes to enable + = help: add `#![feature(log_syntax)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax2.rs b/src/test/ui/feature-gates/feature-gate-log_syntax2.rs index a3906dcc16..db1a96f1f2 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax2.rs +++ b/src/test/ui/feature-gates/feature-gate-log_syntax2.rs @@ -1,5 +1,3 @@ -// gate-test-log_syntax - fn main() { println!("{:?}", log_syntax!()); //~ ERROR `log_syntax!` is not stable } diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr index ff0fa343c8..81daee0b49 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr +++ b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr @@ -1,11 +1,11 @@ -error[E0658]: `log_syntax!` is not stable enough for use and is subject to change - --> $DIR/feature-gate-log_syntax2.rs:4:22 +error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change + --> $DIR/feature-gate-log_syntax2.rs:2:22 | LL | println!("{:?}", log_syntax!()); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(log_syntax)] to the crate attributes to enable + = help: add `#![feature(log_syntax)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-macros_in_extern.stderr b/src/test/ui/feature-gates/feature-gate-macros_in_extern.stderr index 891ed81107..e8b3ab5dda 100644 --- a/src/test/ui/feature-gates/feature-gate-macros_in_extern.stderr +++ b/src/test/ui/feature-gates/feature-gate-macros_in_extern.stderr @@ -5,7 +5,7 @@ LL | returns_isize!(rust_get_test_int); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental --> $DIR/feature-gate-macros_in_extern.rs:21:5 @@ -14,7 +14,7 @@ LL | takes_u32_returns_u32!(rust_dbg_extern_identity_u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental --> $DIR/feature-gate-macros_in_extern.rs:23:5 @@ -23,7 +23,7 @@ LL | emits_nothing!(); | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 - = help: add #![feature(macros_in_extern)] to the crate attributes to enable + = help: add `#![feature(macros_in_extern)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-main.rs b/src/test/ui/feature-gates/feature-gate-main.rs index 681bdca392..9c304a1792 100644 --- a/src/test/ui/feature-gates/feature-gate-main.rs +++ b/src/test/ui/feature-gates/feature-gate-main.rs @@ -1,2 +1,2 @@ #[main] -fn foo() {} //~ ERROR: declaration of a nonstandard #[main] function may change over time +fn foo() {} //~ ERROR: declaration of a non-standard `#[main]` function may change over time diff --git a/src/test/ui/feature-gates/feature-gate-main.stderr b/src/test/ui/feature-gates/feature-gate-main.stderr index 4d2d01b49f..513758e030 100644 --- a/src/test/ui/feature-gates/feature-gate-main.stderr +++ b/src/test/ui/feature-gates/feature-gate-main.stderr @@ -1,11 +1,11 @@ -error[E0658]: declaration of a nonstandard #[main] function may change over time, for now a top-level `fn main()` is required +error[E0658]: declaration of a non-standard `#[main]` function may change over time, for now a top-level `fn main()` is required --> $DIR/feature-gate-main.rs:2:1 | LL | fn foo() {} | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29634 - = help: add #![feature(main)] to the crate attributes to enable + = help: add `#![feature(main)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr index 3ed43b52e5..94dfaf9206 100644 --- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr +++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr @@ -5,7 +5,7 @@ LL | #[marker] trait ExplicitMarker {} | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29864 - = help: add #![feature(marker_trait_attr)] to the crate attributes to enable + = help: add `#![feature(marker_trait_attr)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-may-dangle.rs b/src/test/ui/feature-gates/feature-gate-may-dangle.rs index 20896e426f..23db92c15d 100644 --- a/src/test/ui/feature-gates/feature-gate-may-dangle.rs +++ b/src/test/ui/feature-gates/feature-gate-may-dangle.rs @@ -4,7 +4,7 @@ struct Pt(A); unsafe impl<#[may_dangle] A> Drop for Pt { - //~^ ERROR may_dangle has unstable semantics and may be removed in the future + //~^ ERROR `may_dangle` has unstable semantics and may be removed in the future fn drop(&mut self) { } } diff --git a/src/test/ui/feature-gates/feature-gate-may-dangle.stderr b/src/test/ui/feature-gates/feature-gate-may-dangle.stderr index f93be3ed4e..b344d73757 100644 --- a/src/test/ui/feature-gates/feature-gate-may-dangle.stderr +++ b/src/test/ui/feature-gates/feature-gate-may-dangle.stderr @@ -1,11 +1,11 @@ -error[E0658]: may_dangle has unstable semantics and may be removed in the future +error[E0658]: `may_dangle` has unstable semantics and may be removed in the future --> $DIR/feature-gate-may-dangle.rs:6:13 | LL | unsafe impl<#[may_dangle] A> Drop for Pt { | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/34761 - = help: add #![feature(dropck_eyepatch)] to the crate attributes to enable + = help: add `#![feature(dropck_eyepatch)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr b/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr index f5155b424b..98c9e2b0c9 100644 --- a/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr +++ b/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr @@ -23,7 +23,7 @@ LL | const fn foo() -> u32; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0658]: const fn is unstable --> $DIR/feature-gate-min_const_fn.rs:8:5 @@ -32,7 +32,7 @@ LL | const fn bar() -> u32 { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-naked_functions.stderr b/src/test/ui/feature-gates/feature-gate-naked_functions.stderr index 0ba4d551a6..d4041f4ecd 100644 --- a/src/test/ui/feature-gates/feature-gate-naked_functions.stderr +++ b/src/test/ui/feature-gates/feature-gate-naked_functions.stderr @@ -5,7 +5,7 @@ LL | #[naked] | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32408 - = help: add #![feature(naked_functions)] to the crate attributes to enable + = help: add `#![feature(naked_functions)]` to the crate attributes to enable error[E0658]: the `#[naked]` attribute is an experimental feature --> $DIR/feature-gate-naked_functions.rs:5:1 @@ -14,7 +14,7 @@ LL | #[naked] | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32408 - = help: add #![feature(naked_functions)] to the crate attributes to enable + = help: add `#![feature(naked_functions)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-needs-allocator.stderr b/src/test/ui/feature-gates/feature-gate-needs-allocator.stderr index 012664e9b6..2b213acebb 100644 --- a/src/test/ui/feature-gates/feature-gate-needs-allocator.stderr +++ b/src/test/ui/feature-gates/feature-gate-needs-allocator.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[needs_allocator]` attribute is an experimental feature LL | #![needs_allocator] | ^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(allocator_internals)] to the crate attributes to enable + = help: add `#![feature(allocator_internals)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-never_type.stderr b/src/test/ui/feature-gates/feature-gate-never_type.stderr index 45a6e6de18..d86ab99b82 100644 --- a/src/test/ui/feature-gates/feature-gate-never_type.stderr +++ b/src/test/ui/feature-gates/feature-gate-never_type.stderr @@ -5,7 +5,7 @@ LL | type Ma = (u32, !, i32); | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35121 - = help: add #![feature(never_type)] to the crate attributes to enable + = help: add `#![feature(never_type)]` to the crate attributes to enable error[E0658]: The `!` type is experimental --> $DIR/feature-gate-never_type.rs:8:20 @@ -14,7 +14,7 @@ LL | type Meeshka = Vec; | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35121 - = help: add #![feature(never_type)] to the crate attributes to enable + = help: add `#![feature(never_type)]` to the crate attributes to enable error[E0658]: The `!` type is experimental --> $DIR/feature-gate-never_type.rs:9:24 @@ -23,7 +23,7 @@ LL | type Mow = &'static fn(!) -> !; | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35121 - = help: add #![feature(never_type)] to the crate attributes to enable + = help: add `#![feature(never_type)]` to the crate attributes to enable error[E0658]: The `!` type is experimental --> $DIR/feature-gate-never_type.rs:10:27 @@ -32,7 +32,7 @@ LL | type Skwoz = &'static mut !; | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35121 - = help: add #![feature(never_type)] to the crate attributes to enable + = help: add `#![feature(never_type)]` to the crate attributes to enable error[E0658]: The `!` type is experimental --> $DIR/feature-gate-never_type.rs:13:16 @@ -41,7 +41,7 @@ LL | type Wub = !; | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35121 - = help: add #![feature(never_type)] to the crate attributes to enable + = help: add `#![feature(never_type)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-nll.rs b/src/test/ui/feature-gates/feature-gate-nll.rs index ec5eacd162..8ec752409a 100644 --- a/src/test/ui/feature-gates/feature-gate-nll.rs +++ b/src/test/ui/feature-gates/feature-gate-nll.rs @@ -3,6 +3,7 @@ // Don't use compare-mode=nll, since that turns on NLL. // ignore-compare-mode-nll +// ignore-compare-mode-polonius #![feature(rustc_attrs)] diff --git a/src/test/ui/feature-gates/feature-gate-nll.stderr b/src/test/ui/feature-gates/feature-gate-nll.stderr index 37542d52dc..e5b28bbfa2 100644 --- a/src/test/ui/feature-gates/feature-gate-nll.stderr +++ b/src/test/ui/feature-gates/feature-gate-nll.stderr @@ -1,5 +1,5 @@ warning[E0502]: cannot borrow `*x.1` as immutable because it is also borrowed as mutable - --> $DIR/feature-gate-nll.rs:14:13 + --> $DIR/feature-gate-nll.rs:15:13 | LL | let m = &mut x; | ------ mutable borrow occurs here @@ -14,7 +14,7 @@ LL | m; = note: for more information, try `rustc --explain E0729` error: compilation successful - --> $DIR/feature-gate-nll.rs:10:1 + --> $DIR/feature-gate-nll.rs:11:1 | LL | / fn main() { LL | | let mut x = (33, &0); diff --git a/src/test/ui/feature-gates/feature-gate-no-debug.stderr b/src/test/ui/feature-gates/feature-gate-no-debug.stderr index a58a75b70c..7d5af0802c 100644 --- a/src/test/ui/feature-gates/feature-gate-no-debug.stderr +++ b/src/test/ui/feature-gates/feature-gate-no-debug.stderr @@ -5,7 +5,7 @@ LL | #[no_debug] | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29721 - = help: add #![feature(no_debug)] to the crate attributes to enable + = help: add `#![feature(no_debug)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-no_core.stderr b/src/test/ui/feature-gates/feature-gate-no_core.stderr index e2f0fd68a7..4d4ca96544 100644 --- a/src/test/ui/feature-gates/feature-gate-no_core.stderr +++ b/src/test/ui/feature-gates/feature-gate-no_core.stderr @@ -5,7 +5,7 @@ LL | #![no_core] | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29639 - = help: add #![feature(no_core)] to the crate attributes to enable + = help: add `#![feature(no_core)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-non_ascii_idents.stderr b/src/test/ui/feature-gates/feature-gate-non_ascii_idents.stderr index 1d78b87a3e..02d21c90fe 100644 --- a/src/test/ui/feature-gates/feature-gate-non_ascii_idents.stderr +++ b/src/test/ui/feature-gates/feature-gate-non_ascii_idents.stderr @@ -5,7 +5,7 @@ LL | extern crate core as bäz; | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:3:5 @@ -14,7 +14,7 @@ LL | use föö::bar; | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:5:5 @@ -23,7 +23,7 @@ LL | mod föö { | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:9:4 @@ -32,7 +32,7 @@ LL | fn bär( | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:10:5 @@ -41,7 +41,7 @@ LL | bäz: isize | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:12:9 @@ -50,7 +50,7 @@ LL | let _ö: isize; | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:15:10 @@ -59,7 +59,7 @@ LL | (_ä, _) => {} | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:19:8 @@ -68,7 +68,7 @@ LL | struct Föö { | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:20:5 @@ -77,7 +77,7 @@ LL | föö: isize | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:23:6 @@ -86,7 +86,7 @@ LL | enum Bär { | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:24:5 @@ -95,7 +95,7 @@ LL | Bäz { | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:25:9 @@ -104,7 +104,7 @@ LL | qüx: isize | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/feature-gate-non_ascii_idents.rs:30:8 @@ -113,7 +113,7 @@ LL | fn qüx(); | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error: aborting due to 13 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr index fdb1ffb0a9..8a01aa9eb6 100644 --- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr +++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr @@ -5,7 +5,7 @@ LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/44109 - = help: add #![feature(non_exhaustive)] to the crate attributes to enable + = help: add `#![feature(non_exhaustive)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr b/src/test/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr index 683424899a..a5ec3599f6 100644 --- a/src/test/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr +++ b/src/test/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[omit_gdb_pretty_printer_section]` attribute is just used fo LL | #[omit_gdb_pretty_printer_section] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(omit_gdb_pretty_printer_section)] to the crate attributes to enable + = help: add `#![feature(omit_gdb_pretty_printer_section)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr b/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr index 044a9a398d..6c230f8cad 100644 --- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr +++ b/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr @@ -5,7 +5,7 @@ LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29628 - = help: add #![feature(on_unimplemented)] to the crate attributes to enable + = help: add `#![feature(on_unimplemented)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr index baad1627d9..0c3dd451b2 100644 --- a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr +++ b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr @@ -5,7 +5,7 @@ LL | auto trait AutoDummyTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/13231 - = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable + = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now --> $DIR/feature-gate-optin-builtin-traits.rs:9:1 @@ -14,7 +14,7 @@ LL | impl !AutoDummyTrait for DummyStruct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/13231 - = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable + = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-plugin.stderr b/src/test/ui/feature-gates/feature-gate-plugin.stderr index 5ac4120188..0da9653c9a 100644 --- a/src/test/ui/feature-gates/feature-gate-plugin.stderr +++ b/src/test/ui/feature-gates/feature-gate-plugin.stderr @@ -5,7 +5,7 @@ LL | #![plugin(foo)] | ^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29597 - = help: add #![feature(plugin)] to the crate attributes to enable + = help: add `#![feature(plugin)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-plugin_registrar.stderr b/src/test/ui/feature-gates/feature-gate-plugin_registrar.stderr index 941a6c49d1..93473bfd27 100644 --- a/src/test/ui/feature-gates/feature-gate-plugin_registrar.stderr +++ b/src/test/ui/feature-gates/feature-gate-plugin_registrar.stderr @@ -5,7 +5,7 @@ LL | pub fn registrar() {} | ^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29597 - = help: add #![feature(plugin_registrar)] to the crate attributes to enable + = help: add `#![feature(plugin_registrar)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-prelude_import.stderr b/src/test/ui/feature-gates/feature-gate-prelude_import.stderr index 7501954f90..8686aed8f8 100644 --- a/src/test/ui/feature-gates/feature-gate-prelude_import.stderr +++ b/src/test/ui/feature-gates/feature-gate-prelude_import.stderr @@ -4,7 +4,7 @@ error[E0658]: `#[prelude_import]` is for use by rustc only LL | #[prelude_import] | ^^^^^^^^^^^^^^^^^ | - = help: add #![feature(prelude_import)] to the crate attributes to enable + = help: add `#![feature(prelude_import)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-profiler-runtime.stderr b/src/test/ui/feature-gates/feature-gate-profiler-runtime.stderr index 1f335401f9..18e6503c55 100644 --- a/src/test/ui/feature-gates/feature-gate-profiler-runtime.stderr +++ b/src/test/ui/feature-gates/feature-gate-profiler-runtime.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[profiler_runtime]` attribute is used to identify the `profi LL | #![profiler_runtime] | ^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(profiler_runtime)] to the crate attributes to enable + = help: add `#![feature(profiler_runtime)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-repr-simd.stderr b/src/test/ui/feature-gates/feature-gate-repr-simd.stderr index fd3176e573..dfaa85bc5f 100644 --- a/src/test/ui/feature-gates/feature-gate-repr-simd.stderr +++ b/src/test/ui/feature-gates/feature-gate-repr-simd.stderr @@ -5,7 +5,7 @@ LL | #[repr(simd)] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(repr_simd)] to the crate attributes to enable + = help: add `#![feature(repr_simd)]` to the crate attributes to enable error[E0658]: SIMD types are experimental and possibly buggy --> $DIR/feature-gate-repr-simd.rs:5:1 @@ -14,7 +14,7 @@ LL | #[repr(simd)] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(repr_simd)] to the crate attributes to enable + = help: add `#![feature(repr_simd)]` to the crate attributes to enable warning[E0566]: conflicting representation hints --> $DIR/feature-gate-repr-simd.rs:4:8 diff --git a/src/test/ui/feature-gates/feature-gate-repr128.stderr b/src/test/ui/feature-gates/feature-gate-repr128.stderr index 30433447a2..2139a5da60 100644 --- a/src/test/ui/feature-gates/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gates/feature-gate-repr128.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: for more information, see https://github.com/rust-lang/rust/issues/35118 - = help: add #![feature(repr128)] to the crate attributes to enable + = help: add `#![feature(repr128)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr index ed98484e13..e9dd0867fc 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr @@ -5,7 +5,7 @@ LL | #[rustc_variance] | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable --> $DIR/feature-gate-rustc-attrs-1.rs:6:1 @@ -14,7 +14,7 @@ LL | #[rustc_error] | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable --> $DIR/feature-gate-rustc-attrs-1.rs:7:1 @@ -23,7 +23,7 @@ LL | #[rustc_nonnull_optimization_guaranteed] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs index 5ec413cc71..13983726c7 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -1,6 +1,23 @@ // Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate. -#[rustc_foo] -//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +#![feature(decl_macro)] +mod rustc { pub macro unknown() {} } +mod unknown { pub macro rustc() {} } + +#[rustc::unknown] +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR expected attribute, found macro `rustc::unknown` +fn f() {} + +#[unknown::rustc] +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR expected attribute, found macro `unknown::rustc` +fn g() {} + +#[rustc_dummy] +//~^ ERROR used by the test suite +#[rustc_unknown] +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR cannot find attribute macro `rustc_unknown` in this scope fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index 3c823c8d4e..23cf936ee8 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -1,12 +1,57 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/feature-gate-rustc-attrs.rs:3:3 +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/feature-gate-rustc-attrs.rs:8:3 | -LL | #[rustc_foo] - | ^^^^^^^^^ +LL | #[rustc::unknown] + | ^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(rustc_attrs)] to the crate attributes to enable + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error: aborting due to previous error +error: expected attribute, found macro `rustc::unknown` + --> $DIR/feature-gate-rustc-attrs.rs:8:3 + | +LL | #[rustc::unknown] + | ^^^^^^^^^^^^^^ not an attribute + +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/feature-gate-rustc-attrs.rs:13:12 + | +LL | #[unknown::rustc] + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + +error: expected attribute, found macro `unknown::rustc` + --> $DIR/feature-gate-rustc-attrs.rs:13:3 + | +LL | #[unknown::rustc] + | ^^^^^^^^^^^^^^ not an attribute + +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/feature-gate-rustc-attrs.rs:20:3 + | +LL | #[rustc_unknown] + | ^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + +error: cannot find attribute macro `rustc_unknown` in this scope + --> $DIR/feature-gate-rustc-attrs.rs:20:3 + | +LL | #[rustc_unknown] + | ^^^^^^^^^^^^^ + +error[E0658]: used by the test suite + --> $DIR/feature-gate-rustc-attrs.rs:18:1 + | +LL | #[rustc_dummy] + | ^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.stderr b/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.stderr index 8f584c333a..d7b7cf72a2 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc_const_unstable.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[rustc_const_unstable]` attribute is an internal feature LL | #[rustc_const_unstable(feature="fzzzzzt")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(rustc_const_unstable)] to the crate attributes to enable + = help: add `#![feature(rustc_const_unstable)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr b/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr index 71d9890cb2..b13ec215f8 100644 --- a/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr +++ b/src/test/ui/feature-gates/feature-gate-sanitizer-runtime.stderr @@ -4,7 +4,7 @@ error[E0658]: the `#[sanitizer_runtime]` attribute is used to identify crates th LL | #![sanitizer_runtime] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(sanitizer_runtime)] to the crate attributes to enable + = help: add `#![feature(sanitizer_runtime)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr b/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr index 11e095fef3..8166b6baa2 100644 --- a/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr +++ b/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr @@ -4,7 +4,7 @@ error: use of SIMD type `LocalSimd` in FFI is highly experimental and may result LL | fn baz() -> LocalSimd; | ^^^^^^^^^ | - = help: add #![feature(simd_ffi)] to the crate attributes to enable + = help: add `#![feature(simd_ffi)]` to the crate attributes to enable error: use of SIMD type `LocalSimd` in FFI is highly experimental and may result in invalid code --> $DIR/feature-gate-simd-ffi.rs:10:15 @@ -12,7 +12,7 @@ error: use of SIMD type `LocalSimd` in FFI is highly experimental and may result LL | fn qux(x: LocalSimd); | ^^^^^^^^^ | - = help: add #![feature(simd_ffi)] to the crate attributes to enable + = help: add `#![feature(simd_ffi)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-simd.stderr b/src/test/ui/feature-gates/feature-gate-simd.stderr index 1686a8530f..b72ac1e493 100644 --- a/src/test/ui/feature-gates/feature-gate-simd.stderr +++ b/src/test/ui/feature-gates/feature-gate-simd.stderr @@ -5,7 +5,7 @@ LL | #[repr(simd)] | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27731 - = help: add #![feature(repr_simd)] to the crate attributes to enable + = help: add `#![feature(repr_simd)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs index 0165321deb..f2a1b135b6 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs @@ -3,15 +3,15 @@ fn main() { let x = [1, 2, 3, 4, 5]; match x { - [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [1, 2, ..] => {} //~ ERROR subslice patterns are unstable + [1, .., 5] => {} //~ ERROR subslice patterns are unstable + [.., 4, 5] => {} //~ ERROR subslice patterns are unstable } let x = [ 1, 2, 3, 4, 5 ]; match x { - [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ xs @ .., 4, 5 ] => {} //~ ERROR subslice patterns are unstable + [ 1, xs @ .., 5 ] => {} //~ ERROR subslice patterns are unstable + [ 1, 2, xs @ .. ] => {} //~ ERROR subslice patterns are unstable } } diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr index fe3c1e0afd..d4946a42b8 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr @@ -1,56 +1,56 @@ -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:6:16 | LL | [1, 2, ..] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:7:13 | LL | [1, .., 5] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:8:10 | LL | [.., 4, 5] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:13:11 | -LL | [ xs.., 4, 5 ] => {} - | ^^ +LL | [ xs @ .., 4, 5 ] => {} + | ^^^^^^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:14:14 | -LL | [ 1, xs.., 5 ] => {} - | ^^ +LL | [ 1, xs @ .., 5 ] => {} + | ^^^^^^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:15:17 | -LL | [ 1, 2, xs.. ] => {} - | ^^ +LL | [ 1, 2, xs @ .. ] => {} + | ^^^^^^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable error: aborting due to 6 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-start.rs b/src/test/ui/feature-gates/feature-gate-start.rs index 46a1279a3f..0bd4c7c85b 100644 --- a/src/test/ui/feature-gates/feature-gate-start.rs +++ b/src/test/ui/feature-gates/feature-gate-start.rs @@ -1,3 +1,3 @@ #[start] fn foo(_: isize, _: *const *const u8) -> isize { 0 } -//~^ ERROR a #[start] function is an experimental feature +//~^ ERROR a `#[start]` function is an experimental feature diff --git a/src/test/ui/feature-gates/feature-gate-start.stderr b/src/test/ui/feature-gates/feature-gate-start.stderr index fbe64ea130..c769ef8ee9 100644 --- a/src/test/ui/feature-gates/feature-gate-start.stderr +++ b/src/test/ui/feature-gates/feature-gate-start.stderr @@ -1,11 +1,11 @@ -error[E0658]: a #[start] function is an experimental feature whose signature may change over time +error[E0658]: a `#[start]` function is an experimental feature whose signature may change over time --> $DIR/feature-gate-start.rs:2:1 | LL | fn foo(_: isize, _: *const *const u8) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29633 - = help: add #![feature(start)] to the crate attributes to enable + = help: add `#![feature(start)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr b/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr index 7d5ed74abd..f2e29cf067 100644 --- a/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr +++ b/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr @@ -5,7 +5,7 @@ LL | #[link(name="foo", kind="static-nobundle")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37403 - = help: add #![feature(static_nobundle)] to the crate attributes to enable + = help: add `#![feature(static_nobundle)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-stmt_expr_attributes.stderr b/src/test/ui/feature-gates/feature-gate-stmt_expr_attributes.stderr index bbf0f66ca5..70c70638ea 100644 --- a/src/test/ui/feature-gates/feature-gate-stmt_expr_attributes.stderr +++ b/src/test/ui/feature-gates/feature-gate-stmt_expr_attributes.stderr @@ -5,7 +5,7 @@ LL | const X: i32 = #[allow(dead_code)] 8; | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/15701 - = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-thread_local.stderr b/src/test/ui/feature-gates/feature-gate-thread_local.stderr index 95334d23d5..9f154d9bc5 100644 --- a/src/test/ui/feature-gates/feature-gate-thread_local.stderr +++ b/src/test/ui/feature-gates/feature-gate-thread_local.stderr @@ -5,7 +5,7 @@ LL | #[thread_local] | ^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29594 - = help: add #![feature(thread_local)] to the crate attributes to enable + = help: add `#![feature(thread_local)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-trace_macros.stderr b/src/test/ui/feature-gates/feature-gate-trace_macros.stderr index bcce31d873..cca0818752 100644 --- a/src/test/ui/feature-gates/feature-gate-trace_macros.stderr +++ b/src/test/ui/feature-gates/feature-gate-trace_macros.stderr @@ -1,11 +1,11 @@ -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/feature-gate-trace_macros.rs:2:5 | LL | trace_macros!(true); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29598 - = help: add #![feature(trace_macros)] to the crate attributes to enable + = help: add `#![feature(trace_macros)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-trait-alias.stderr b/src/test/ui/feature-gates/feature-gate-trait-alias.stderr index 1a9718a6ce..9250e27d15 100644 --- a/src/test/ui/feature-gates/feature-gate-trait-alias.stderr +++ b/src/test/ui/feature-gates/feature-gate-trait-alias.stderr @@ -5,7 +5,7 @@ LL | trait Foo = Default; | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/41517 - = help: add #![feature(trait_alias)] to the crate attributes to enable + = help: add `#![feature(trait_alias)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr index 8ba079b89f..8e727c33f2 100644 --- a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr +++ b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr @@ -5,7 +5,7 @@ LL | enum OkButUnstableEnum { | ^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60405 - = help: add #![feature(transparent_enums)] to the crate attributes to enable + = help: add `#![feature(transparent_enums)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr b/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr index 341324c3d6..356950d064 100644 --- a/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr +++ b/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr @@ -5,7 +5,7 @@ LL | union OkButUnstableUnion { | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/60405 - = help: add #![feature(transparent_unions)] to the crate attributes to enable + = help: add `#![feature(transparent_unions)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr index 1d346fd42f..b4d4c992c9 100644 --- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -5,7 +5,7 @@ LL | enum E where i32: Foo { V } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/feature-gate-trivial_bounds.rs:12:1 @@ -14,7 +14,7 @@ LL | struct S where i32: Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/feature-gate-trivial_bounds.rs:14:1 @@ -23,7 +23,7 @@ LL | trait T where i32: Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/feature-gate-trivial_bounds.rs:16:1 @@ -32,7 +32,7 @@ LL | union U where i32: Foo { f: i32 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/feature-gate-trivial_bounds.rs:20:1 @@ -47,7 +47,7 @@ LL | | } | |_^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/feature-gate-trivial_bounds.rs:28:1 @@ -62,7 +62,7 @@ LL | | } | |_^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `std::string::String: std::ops::Neg` is not satisfied --> $DIR/feature-gate-trivial_bounds.rs:36:1 @@ -73,7 +73,7 @@ LL | | } | |_^ the trait `std::ops::Neg` is not implemented for `std::string::String` | = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: `i32` is not an iterator --> $DIR/feature-gate-trivial_bounds.rs:40:1 @@ -86,7 +86,7 @@ LL | | } = help: the trait `std::iter::Iterator` is not implemented for `i32` = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/feature-gate-trivial_bounds.rs:52:1 @@ -97,7 +97,7 @@ LL | struct TwoStrs(str, str) where str: Sized; = help: the trait `std::marker::Sized` is not implemented for `str` = note: to learn more, visit = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time --> $DIR/feature-gate-trivial_bounds.rs:55:1 @@ -111,7 +111,7 @@ LL | | } = note: to learn more, visit = note: required because it appears within the type `Dst<(dyn A + 'static)>` = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/feature-gate-trivial_bounds.rs:59:1 @@ -124,7 +124,7 @@ LL | | } = help: the trait `std::marker::Sized` is not implemented for `str` = note: to learn more, visit = help: see issue #48214 - = help: add #![feature(trivial_bounds)] to the crate attributes to enable + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error: aborting due to 11 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-try_blocks.stderr b/src/test/ui/feature-gates/feature-gate-try_blocks.stderr index cb72b06733..565f3610a2 100644 --- a/src/test/ui/feature-gates/feature-gate-try_blocks.stderr +++ b/src/test/ui/feature-gates/feature-gate-try_blocks.stderr @@ -9,7 +9,7 @@ LL | | }; | |_____^ | = note: for more information, see https://github.com/rust-lang/rust/issues/31436 - = help: add #![feature(try_blocks)] to the crate attributes to enable + = help: add `#![feature(try_blocks)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-try_reserve.stderr b/src/test/ui/feature-gates/feature-gate-try_reserve.stderr index f1d82d94a5..5bd9dffa7f 100644 --- a/src/test/ui/feature-gates/feature-gate-try_reserve.stderr +++ b/src/test/ui/feature-gates/feature-gate-try_reserve.stderr @@ -5,7 +5,7 @@ LL | v.try_reserve(10); | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/48043 - = help: add #![feature(try_reserve)] to the crate attributes to enable + = help: add `#![feature(try_reserve)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs new file mode 100644 index 0000000000..4a0c8c52c4 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -0,0 +1,15 @@ +type Foo = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable + +trait Bar { + type Baa: std::fmt::Debug; + fn define() -> Self::Baa; +} + +impl Bar for () { + type Baa = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable + fn define() -> Self::Baa { 0 } +} + +fn define() -> Foo { 0 } + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr new file mode 100644 index 0000000000..2d0710ea37 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -0,0 +1,21 @@ +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:1:1 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:9:5 + | +LL | type Baa = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-type_ascription.stderr b/src/test/ui/feature-gates/feature-gate-type_ascription.stderr index 0e4e25882c..83f95529f0 100644 --- a/src/test/ui/feature-gates/feature-gate-type_ascription.stderr +++ b/src/test/ui/feature-gates/feature-gate-type_ascription.stderr @@ -5,7 +5,7 @@ LL | let a = 10: u8; | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/23416 - = help: add #![feature(type_ascription)] to the crate attributes to enable + = help: add `#![feature(type_ascription)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 6b09daff0f..fc4317b316 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -5,7 +5,7 @@ LL | extern "rust-call" fn call(self, args: ()) -> () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:5 @@ -14,7 +14,7 @@ LL | extern "rust-call" fn call_once(self, args: ()) -> () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:5 @@ -23,7 +23,7 @@ LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:5 @@ -32,7 +32,7 @@ LL | extern "rust-call" fn call_once(&self, args: ()) -> () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:9:6 @@ -41,7 +41,7 @@ LL | impl Fn<()> for Foo { | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0229]: associated type bindings are not allowed here --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:15:12 @@ -56,7 +56,7 @@ LL | impl FnMut<()> for Bar { | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:27:6 @@ -65,7 +65,7 @@ LL | impl FnOnce<()> for Baz { | ^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error: aborting due to 8 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-method-calls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-method-calls.stderr index 164368cd8e..ee3ba665ce 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-method-calls.stderr +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-method-calls.stderr @@ -5,7 +5,7 @@ LL | f.call(()); | ^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(fn_traits)] to the crate attributes to enable + = help: add `#![feature(fn_traits)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'fn_traits' --> $DIR/feature-gate-unboxed-closures-method-calls.rs:5:7 @@ -14,7 +14,7 @@ LL | f.call_mut(()); | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(fn_traits)] to the crate attributes to enable + = help: add `#![feature(fn_traits)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'fn_traits' --> $DIR/feature-gate-unboxed-closures-method-calls.rs:6:7 @@ -23,7 +23,7 @@ LL | f.call_once(()); | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(fn_traits)] to the crate attributes to enable + = help: add `#![feature(fn_traits)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.stderr index ff2629fe42..f7cb1ab641 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.stderr +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.stderr @@ -5,7 +5,7 @@ LL | Fn::call(&f, ()); | ^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(fn_traits)] to the crate attributes to enable + = help: add `#![feature(fn_traits)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'fn_traits' --> $DIR/feature-gate-unboxed-closures-ufcs-calls.rs:5:5 @@ -14,7 +14,7 @@ LL | FnMut::call_mut(&mut f, ()); | ^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(fn_traits)] to the crate attributes to enable + = help: add `#![feature(fn_traits)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'fn_traits' --> $DIR/feature-gate-unboxed-closures-ufcs-calls.rs:6:5 @@ -23,7 +23,7 @@ LL | FnOnce::call_once(f, ()); | ^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(fn_traits)] to the crate attributes to enable + = help: add `#![feature(fn_traits)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr index 872a593f3e..723c661988 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr @@ -7,7 +7,7 @@ LL | | } | |_____^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead --> $DIR/feature-gate-unboxed-closures.rs:5:6 @@ -16,7 +16,7 @@ LL | impl FnOnce<(u32, u32)> for Test { | ^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr b/src/test/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr index 5b93c889db..d4c62399e9 100644 --- a/src/test/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr +++ b/src/test/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr @@ -5,7 +5,7 @@ LL | let _ : &(dyn Send,) = &((),); | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/42877 - = help: add #![feature(unsized_tuple_coercion)] to the crate attributes to enable + = help: add `#![feature(unsized_tuple_coercion)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr index 5df3a1d699..f59a34e2c8 100644 --- a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32836 - = help: add #![feature(untagged_unions)] to the crate attributes to enable + = help: add `#![feature(untagged_unions)]` to the crate attributes to enable error[E0658]: unions with non-`Copy` fields are unstable --> $DIR/feature-gate-untagged_unions.rs:13:1 @@ -18,7 +18,7 @@ LL | | } | |_^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32836 - = help: add #![feature(untagged_unions)] to the crate attributes to enable + = help: add `#![feature(untagged_unions)]` to the crate attributes to enable error[E0658]: unions with `Drop` implementations are unstable --> $DIR/feature-gate-untagged_unions.rs:17:1 @@ -29,7 +29,7 @@ LL | | } | |_^ | = note: for more information, see https://github.com/rust-lang/rust/issues/32836 - = help: add #![feature(untagged_unions)] to the crate attributes to enable + = help: add `#![feature(untagged_unions)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs index e0cb9c8821..08e8ec9a56 100644 --- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs +++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs @@ -8,7 +8,7 @@ extern { fn extern_fn(); // CHECK-NOT: Function Attrs: nounwind // CHECK: declare void @unwinding_extern_fn - #[unwind(allowed)] //~ ERROR #[unwind] is experimental + #[unwind(allowed)] //~ ERROR `#[unwind]` is experimental fn unwinding_extern_fn(); } diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr index bb55013d63..639b87e016 100644 --- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr +++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr @@ -1,11 +1,11 @@ -error[E0658]: #[unwind] is experimental +error[E0658]: `#[unwind]` is experimental --> $DIR/feature-gate-unwind-attributes.rs:11:5 | LL | #[unwind(allowed)] | ^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/58760 - = help: add #![feature(unwind_attributes)] to the crate attributes to enable + = help: add `#![feature(unwind_attributes)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/filter-block-view-items.rs b/src/test/ui/filter-block-view-items.rs similarity index 94% rename from src/test/run-pass/filter-block-view-items.rs rename to src/test/ui/filter-block-view-items.rs index d2b9866504..e63aa91577 100644 --- a/src/test/run-pass/filter-block-view-items.rs +++ b/src/test/ui/filter-block-view-items.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 pub fn main() { diff --git a/src/test/run-pass/fixup-deref-mut.rs b/src/test/ui/fixup-deref-mut.rs similarity index 98% rename from src/test/run-pass/fixup-deref-mut.rs rename to src/test/ui/fixup-deref-mut.rs index a35412fea3..6b2fd72b89 100644 --- a/src/test/run-pass/fixup-deref-mut.rs +++ b/src/test/ui/fixup-deref-mut.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs index 8519cf741a..e411854661 100644 --- a/src/test/ui/fn_must_use.rs +++ b/src/test/ui/fn_must_use.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/run-pass/for-loop-while/auto-loop.rs b/src/test/ui/for-loop-while/auto-loop.rs similarity index 100% rename from src/test/run-pass/for-loop-while/auto-loop.rs rename to src/test/ui/for-loop-while/auto-loop.rs diff --git a/src/test/run-pass/for-loop-while/break-value.rs b/src/test/ui/for-loop-while/break-value.rs similarity index 100% rename from src/test/run-pass/for-loop-while/break-value.rs rename to src/test/ui/for-loop-while/break-value.rs diff --git a/src/test/run-pass/for-loop-while/break.rs b/src/test/ui/for-loop-while/break.rs similarity index 100% rename from src/test/run-pass/for-loop-while/break.rs rename to src/test/ui/for-loop-while/break.rs diff --git a/src/test/run-pass/for-loop-while/for-destruct.rs b/src/test/ui/for-loop-while/for-destruct.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-destruct.rs rename to src/test/ui/for-loop-while/for-destruct.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-goofiness.rs b/src/test/ui/for-loop-while/for-loop-goofiness.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-goofiness.rs rename to src/test/ui/for-loop-while/for-loop-goofiness.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs b/src/test/ui/for-loop-while/for-loop-has-unit-body.rs similarity index 90% rename from src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs rename to src/test/ui/for-loop-while/for-loop-has-unit-body.rs index 009c59f2fa..38c34d2dc2 100644 --- a/src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs +++ b/src/test/ui/for-loop-while/for-loop-has-unit-body.rs @@ -2,6 +2,7 @@ fn main() { // Check that the tail statement in the body unifies with something for _ in 0..3 { + #[allow(deprecated)] unsafe { std::mem::uninitialized() } } diff --git a/src/test/run-pass/for-loop-while/for-loop-into-iterator.rs b/src/test/ui/for-loop-while/for-loop-into-iterator.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-into-iterator.rs rename to src/test/ui/for-loop-while/for-loop-into-iterator.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-lifetime-of-unbound-values.rs b/src/test/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-lifetime-of-unbound-values.rs rename to src/test/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-macro.rs b/src/test/ui/for-loop-while/for-loop-macro.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-macro.rs rename to src/test/ui/for-loop-while/for-loop-macro.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-mut-ref-element.rs b/src/test/ui/for-loop-while/for-loop-mut-ref-element.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-mut-ref-element.rs rename to src/test/ui/for-loop-while/for-loop-mut-ref-element.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-no-std.rs b/src/test/ui/for-loop-while/for-loop-no-std.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-no-std.rs rename to src/test/ui/for-loop-while/for-loop-no-std.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-panic.rs b/src/test/ui/for-loop-while/for-loop-panic.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-panic.rs rename to src/test/ui/for-loop-while/for-loop-panic.rs diff --git a/src/test/run-pass/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs b/src/test/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs similarity index 100% rename from src/test/run-pass/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs rename to src/test/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs diff --git a/src/test/run-pass/for-loop-while/foreach-external-iterators-break.rs b/src/test/ui/for-loop-while/foreach-external-iterators-break.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-external-iterators-break.rs rename to src/test/ui/for-loop-while/foreach-external-iterators-break.rs diff --git a/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs b/src/test/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs rename to src/test/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs diff --git a/src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap.rs b/src/test/ui/for-loop-while/foreach-external-iterators-hashmap.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-external-iterators-hashmap.rs rename to src/test/ui/for-loop-while/foreach-external-iterators-hashmap.rs diff --git a/src/test/run-pass/for-loop-while/foreach-external-iterators-loop.rs b/src/test/ui/for-loop-while/foreach-external-iterators-loop.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-external-iterators-loop.rs rename to src/test/ui/for-loop-while/foreach-external-iterators-loop.rs diff --git a/src/test/run-pass/for-loop-while/foreach-external-iterators-nested.rs b/src/test/ui/for-loop-while/foreach-external-iterators-nested.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-external-iterators-nested.rs rename to src/test/ui/for-loop-while/foreach-external-iterators-nested.rs diff --git a/src/test/run-pass/for-loop-while/foreach-external-iterators.rs b/src/test/ui/for-loop-while/foreach-external-iterators.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-external-iterators.rs rename to src/test/ui/for-loop-while/foreach-external-iterators.rs diff --git a/src/test/run-pass/for-loop-while/foreach-nested.rs b/src/test/ui/for-loop-while/foreach-nested.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-nested.rs rename to src/test/ui/for-loop-while/foreach-nested.rs diff --git a/src/test/run-pass/for-loop-while/foreach-put-structured.rs b/src/test/ui/for-loop-while/foreach-put-structured.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-put-structured.rs rename to src/test/ui/for-loop-while/foreach-put-structured.rs diff --git a/src/test/run-pass/for-loop-while/foreach-simple-outer-slot.rs b/src/test/ui/for-loop-while/foreach-simple-outer-slot.rs similarity index 100% rename from src/test/run-pass/for-loop-while/foreach-simple-outer-slot.rs rename to src/test/ui/for-loop-while/foreach-simple-outer-slot.rs diff --git a/src/test/run-pass/for-loop-while/label_break_value.rs b/src/test/ui/for-loop-while/label_break_value.rs similarity index 100% rename from src/test/run-pass/for-loop-while/label_break_value.rs rename to src/test/ui/for-loop-while/label_break_value.rs diff --git a/src/test/run-pass/for-loop-while/labeled-break.rs b/src/test/ui/for-loop-while/labeled-break.rs similarity index 100% rename from src/test/run-pass/for-loop-while/labeled-break.rs rename to src/test/ui/for-loop-while/labeled-break.rs diff --git a/src/test/run-pass/for-loop-while/linear-for-loop.rs b/src/test/ui/for-loop-while/linear-for-loop.rs similarity index 100% rename from src/test/run-pass/for-loop-while/linear-for-loop.rs rename to src/test/ui/for-loop-while/linear-for-loop.rs diff --git a/src/test/run-pass/for-loop-while/liveness-assign-imm-local-after-loop.rs b/src/test/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs similarity index 100% rename from src/test/run-pass/for-loop-while/liveness-assign-imm-local-after-loop.rs rename to src/test/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs diff --git a/src/test/run-pass/for-loop-while/liveness-loop-break.rs b/src/test/ui/for-loop-while/liveness-loop-break.rs similarity index 100% rename from src/test/run-pass/for-loop-while/liveness-loop-break.rs rename to src/test/ui/for-loop-while/liveness-loop-break.rs diff --git a/src/test/run-pass/for-loop-while/liveness-move-in-loop.rs b/src/test/ui/for-loop-while/liveness-move-in-loop.rs similarity index 100% rename from src/test/run-pass/for-loop-while/liveness-move-in-loop.rs rename to src/test/ui/for-loop-while/liveness-move-in-loop.rs diff --git a/src/test/run-pass/for-loop-while/loop-break-cont-1.rs b/src/test/ui/for-loop-while/loop-break-cont-1.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-break-cont-1.rs rename to src/test/ui/for-loop-while/loop-break-cont-1.rs diff --git a/src/test/run-pass/for-loop-while/loop-break-cont.rs b/src/test/ui/for-loop-while/loop-break-cont.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-break-cont.rs rename to src/test/ui/for-loop-while/loop-break-cont.rs diff --git a/src/test/run-pass/for-loop-while/loop-break-value.rs b/src/test/ui/for-loop-while/loop-break-value.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-break-value.rs rename to src/test/ui/for-loop-while/loop-break-value.rs diff --git a/src/test/run-pass/for-loop-while/loop-diverges.rs b/src/test/ui/for-loop-while/loop-diverges.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-diverges.rs rename to src/test/ui/for-loop-while/loop-diverges.rs diff --git a/src/test/run-pass/for-loop-while/loop-label-shadowing.rs b/src/test/ui/for-loop-while/loop-label-shadowing.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-label-shadowing.rs rename to src/test/ui/for-loop-while/loop-label-shadowing.rs diff --git a/src/test/run-pass/for-loop-while/loop-labeled-break-value.rs b/src/test/ui/for-loop-while/loop-labeled-break-value.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-labeled-break-value.rs rename to src/test/ui/for-loop-while/loop-labeled-break-value.rs diff --git a/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs b/src/test/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs rename to src/test/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs diff --git a/src/test/run-pass/for-loop-while/loop-scope.rs b/src/test/ui/for-loop-while/loop-scope.rs similarity index 100% rename from src/test/run-pass/for-loop-while/loop-scope.rs rename to src/test/ui/for-loop-while/loop-scope.rs diff --git a/src/test/run-pass/for-loop-while/while-cont.rs b/src/test/ui/for-loop-while/while-cont.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-cont.rs rename to src/test/ui/for-loop-while/while-cont.rs diff --git a/src/test/run-pass/for-loop-while/while-flow-graph.rs b/src/test/ui/for-loop-while/while-flow-graph.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-flow-graph.rs rename to src/test/ui/for-loop-while/while-flow-graph.rs diff --git a/src/test/run-pass/for-loop-while/while-label.rs b/src/test/ui/for-loop-while/while-label.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-label.rs rename to src/test/ui/for-loop-while/while-label.rs diff --git a/src/test/run-pass/for-loop-while/while-let.rs b/src/test/ui/for-loop-while/while-let.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-let.rs rename to src/test/ui/for-loop-while/while-let.rs diff --git a/src/test/run-pass/for-loop-while/while-loop-constraints-2.rs b/src/test/ui/for-loop-while/while-loop-constraints-2.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-loop-constraints-2.rs rename to src/test/ui/for-loop-while/while-loop-constraints-2.rs diff --git a/src/test/run-pass/for-loop-while/while-prelude-drop.rs b/src/test/ui/for-loop-while/while-prelude-drop.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-prelude-drop.rs rename to src/test/ui/for-loop-while/while-prelude-drop.rs diff --git a/src/test/run-pass/for-loop-while/while-with-break.rs b/src/test/ui/for-loop-while/while-with-break.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while-with-break.rs rename to src/test/ui/for-loop-while/while-with-break.rs diff --git a/src/test/run-pass/for-loop-while/while.rs b/src/test/ui/for-loop-while/while.rs similarity index 100% rename from src/test/run-pass/for-loop-while/while.rs rename to src/test/ui/for-loop-while/while.rs diff --git a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr index da2b0dc234..0d77fd4efd 100644 --- a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr +++ b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr @@ -1,8 +1,8 @@ -error[E0005]: refutable pattern in `for` loop binding: `&-2147483648i32..=0i32` not covered +error[E0005]: refutable pattern in `for` loop binding: `&std::i32::MIN..=0i32` not covered --> $DIR/for-loop-refutable-pattern-error-message.rs:2:9 | LL | for &1 in [1].iter() {} - | ^^ pattern `&-2147483648i32..=0i32` not covered + | ^^ pattern `&std::i32::MIN..=0i32` not covered error: aborting due to previous error diff --git a/src/test/run-pass/foreign/auxiliary/fn-abi.rs b/src/test/ui/foreign/auxiliary/fn-abi.rs similarity index 100% rename from src/test/run-pass/foreign/auxiliary/fn-abi.rs rename to src/test/ui/foreign/auxiliary/fn-abi.rs diff --git a/src/test/run-pass/foreign/auxiliary/foreign_lib.rs b/src/test/ui/foreign/auxiliary/foreign_lib.rs similarity index 100% rename from src/test/run-pass/foreign/auxiliary/foreign_lib.rs rename to src/test/ui/foreign/auxiliary/foreign_lib.rs diff --git a/src/test/run-pass/foreign/foreign-call-no-runtime.rs b/src/test/ui/foreign/foreign-call-no-runtime.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-call-no-runtime.rs rename to src/test/ui/foreign/foreign-call-no-runtime.rs diff --git a/src/test/run-pass/foreign/foreign-dupe.rs b/src/test/ui/foreign/foreign-dupe.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-dupe.rs rename to src/test/ui/foreign/foreign-dupe.rs diff --git a/src/test/run-pass/foreign/foreign-fn-linkname.rs b/src/test/ui/foreign/foreign-fn-linkname.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-fn-linkname.rs rename to src/test/ui/foreign/foreign-fn-linkname.rs diff --git a/src/test/run-pass/foreign/foreign-fn-with-byval.rs b/src/test/ui/foreign/foreign-fn-with-byval.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-fn-with-byval.rs rename to src/test/ui/foreign/foreign-fn-with-byval.rs diff --git a/src/test/run-pass/foreign/foreign-int-types.rs b/src/test/ui/foreign/foreign-int-types.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-int-types.rs rename to src/test/ui/foreign/foreign-int-types.rs diff --git a/src/test/run-pass/foreign/foreign-mod-src/compiletest-ignore-dir b/src/test/ui/foreign/foreign-mod-src/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/foreign/foreign-mod-src/compiletest-ignore-dir rename to src/test/ui/foreign/foreign-mod-src/compiletest-ignore-dir diff --git a/src/test/run-pass/foreign/foreign-mod-src/inner.rs b/src/test/ui/foreign/foreign-mod-src/inner.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-mod-src/inner.rs rename to src/test/ui/foreign/foreign-mod-src/inner.rs diff --git a/src/test/run-pass/foreign/foreign-mod-unused-const.rs b/src/test/ui/foreign/foreign-mod-unused-const.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-mod-unused-const.rs rename to src/test/ui/foreign/foreign-mod-unused-const.rs diff --git a/src/test/run-pass/foreign/foreign-no-abi.rs b/src/test/ui/foreign/foreign-no-abi.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-no-abi.rs rename to src/test/ui/foreign/foreign-no-abi.rs diff --git a/src/test/run-pass/foreign/foreign-src/compiletest-ignore-dir b/src/test/ui/foreign/foreign-src/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/foreign/foreign-src/compiletest-ignore-dir rename to src/test/ui/foreign/foreign-src/compiletest-ignore-dir diff --git a/src/test/run-pass/foreign/foreign-src/foreign.rs b/src/test/ui/foreign/foreign-src/foreign.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-src/foreign.rs rename to src/test/ui/foreign/foreign-src/foreign.rs diff --git a/src/test/run-pass/foreign/foreign-truncated-arguments.rs b/src/test/ui/foreign/foreign-truncated-arguments.rs similarity index 100% rename from src/test/run-pass/foreign/foreign-truncated-arguments.rs rename to src/test/ui/foreign/foreign-truncated-arguments.rs diff --git a/src/test/run-pass/foreign/foreign2.rs b/src/test/ui/foreign/foreign2.rs similarity index 100% rename from src/test/run-pass/foreign/foreign2.rs rename to src/test/ui/foreign/foreign2.rs diff --git a/src/test/run-pass/format-nan.rs b/src/test/ui/format-nan.rs similarity index 93% rename from src/test/run-pass/format-nan.rs rename to src/test/ui/format-nan.rs index dbe2c61c49..e4a134fa2f 100644 --- a/src/test/run-pass/format-nan.rs +++ b/src/test/ui/format-nan.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { use std::f64; let x = "NaN".to_string(); diff --git a/src/test/run-pass/format-no-std.rs b/src/test/ui/format-no-std.rs similarity index 97% rename from src/test/run-pass/format-no-std.rs rename to src/test/ui/format-no-std.rs index 32f7a4a07c..c9b7651bfd 100644 --- a/src/test/run-pass/format-no-std.rs +++ b/src/test/ui/format-no-std.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten no no_std executables #![feature(lang_items, start)] diff --git a/src/test/run-pass/format-ref-cell.rs b/src/test/ui/format-ref-cell.rs similarity index 94% rename from src/test/run-pass/format-ref-cell.rs rename to src/test/ui/format-ref-cell.rs index 0e7925af78..afb2f8488b 100644 --- a/src/test/run-pass/format-ref-cell.rs +++ b/src/test/ui/format-ref-cell.rs @@ -1,3 +1,5 @@ +// run-pass + use std::cell::RefCell; pub fn main() { diff --git a/src/test/run-pass/fsu-moves-and-copies.rs b/src/test/ui/fsu-moves-and-copies.rs similarity index 99% rename from src/test/run-pass/fsu-moves-and-copies.rs rename to src/test/ui/fsu-moves-and-copies.rs index f9544ec39a..c41bcc73fa 100644 --- a/src/test/run-pass/fsu-moves-and-copies.rs +++ b/src/test/ui/fsu-moves-and-copies.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(stable_features)] // Issue 4691: Ensure that functional-struct-updates operates diff --git a/src/test/run-pass/fun-call-variants.rs b/src/test/ui/fun-call-variants.rs similarity index 95% rename from src/test/run-pass/fun-call-variants.rs rename to src/test/ui/fun-call-variants.rs index e08878accc..5b83e2620d 100644 --- a/src/test/run-pass/fun-call-variants.rs +++ b/src/test/ui/fun-call-variants.rs @@ -1,3 +1,5 @@ +// run-pass + fn ho(f: F) -> isize where F: FnOnce(isize) -> isize { let n: isize = f(3); return n; } fn direct(x: isize) -> isize { return x + 1; } diff --git a/src/test/run-pass/fun-indirect-call.rs b/src/test/ui/fun-indirect-call.rs similarity index 90% rename from src/test/run-pass/fun-indirect-call.rs rename to src/test/ui/fun-indirect-call.rs index 81af4402c1..49da3d83f4 100644 --- a/src/test/run-pass/fun-indirect-call.rs +++ b/src/test/ui/fun-indirect-call.rs @@ -1,3 +1,5 @@ +// run-pass + fn f() -> isize { return 42; } pub fn main() { diff --git a/src/test/run-pass/functions-closures/auxiliary/fn-abi.rs b/src/test/ui/functions-closures/auxiliary/fn-abi.rs similarity index 100% rename from src/test/run-pass/functions-closures/auxiliary/fn-abi.rs rename to src/test/ui/functions-closures/auxiliary/fn-abi.rs diff --git a/src/test/run-pass/functions-closures/call-closure-from-overloaded-op.rs b/src/test/ui/functions-closures/call-closure-from-overloaded-op.rs similarity index 100% rename from src/test/run-pass/functions-closures/call-closure-from-overloaded-op.rs rename to src/test/ui/functions-closures/call-closure-from-overloaded-op.rs diff --git a/src/test/run-pass/functions-closures/capture-clauses-boxed-closures.rs b/src/test/ui/functions-closures/capture-clauses-boxed-closures.rs similarity index 100% rename from src/test/run-pass/functions-closures/capture-clauses-boxed-closures.rs rename to src/test/ui/functions-closures/capture-clauses-boxed-closures.rs diff --git a/src/test/run-pass/functions-closures/capture-clauses-unboxed-closures.rs b/src/test/ui/functions-closures/capture-clauses-unboxed-closures.rs similarity index 100% rename from src/test/run-pass/functions-closures/capture-clauses-unboxed-closures.rs rename to src/test/ui/functions-closures/capture-clauses-unboxed-closures.rs diff --git a/src/test/run-pass/functions-closures/clone-closure.rs b/src/test/ui/functions-closures/clone-closure.rs similarity index 100% rename from src/test/run-pass/functions-closures/clone-closure.rs rename to src/test/ui/functions-closures/clone-closure.rs diff --git a/src/test/run-pass/functions-closures/closure-bounds-can-capture-chan.rs b/src/test/ui/functions-closures/closure-bounds-can-capture-chan.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-bounds-can-capture-chan.rs rename to src/test/ui/functions-closures/closure-bounds-can-capture-chan.rs diff --git a/src/test/run-pass/functions-closures/closure-expected-type/README.md b/src/test/ui/functions-closures/closure-expected-type/README.md similarity index 100% rename from src/test/run-pass/functions-closures/closure-expected-type/README.md rename to src/test/ui/functions-closures/closure-expected-type/README.md diff --git a/src/test/run-pass/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs b/src/test/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs rename to src/test/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs diff --git a/src/test/run-pass/functions-closures/closure-expected-type/issue-38714.rs b/src/test/ui/functions-closures/closure-expected-type/issue-38714.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-expected-type/issue-38714.rs rename to src/test/ui/functions-closures/closure-expected-type/issue-38714.rs diff --git a/src/test/run-pass/functions-closures/closure-expected-type/supply-just-return-type.rs b/src/test/ui/functions-closures/closure-expected-type/supply-just-return-type.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-expected-type/supply-just-return-type.rs rename to src/test/ui/functions-closures/closure-expected-type/supply-just-return-type.rs diff --git a/src/test/run-pass/functions-closures/closure-expected-type/supply-nothing.rs b/src/test/ui/functions-closures/closure-expected-type/supply-nothing.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-expected-type/supply-nothing.rs rename to src/test/ui/functions-closures/closure-expected-type/supply-nothing.rs diff --git a/src/test/run-pass/functions-closures/closure-immediate.rs b/src/test/ui/functions-closures/closure-immediate.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-immediate.rs rename to src/test/ui/functions-closures/closure-immediate.rs diff --git a/src/test/run-pass/functions-closures/closure-inference.rs b/src/test/ui/functions-closures/closure-inference.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-inference.rs rename to src/test/ui/functions-closures/closure-inference.rs diff --git a/src/test/run-pass/functions-closures/closure-inference2.rs b/src/test/ui/functions-closures/closure-inference2.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-inference2.rs rename to src/test/ui/functions-closures/closure-inference2.rs diff --git a/src/test/run-pass/functions-closures/closure-reform.rs b/src/test/ui/functions-closures/closure-reform.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-reform.rs rename to src/test/ui/functions-closures/closure-reform.rs diff --git a/src/test/run-pass/functions-closures/closure-returning-closure.rs b/src/test/ui/functions-closures/closure-returning-closure.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-returning-closure.rs rename to src/test/ui/functions-closures/closure-returning-closure.rs diff --git a/src/test/run-pass/functions-closures/closure-to-fn-coercion.rs b/src/test/ui/functions-closures/closure-to-fn-coercion.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure-to-fn-coercion.rs rename to src/test/ui/functions-closures/closure-to-fn-coercion.rs diff --git a/src/test/run-pass/functions-closures/closure_to_fn_coercion-expected-types.rs b/src/test/ui/functions-closures/closure_to_fn_coercion-expected-types.rs similarity index 100% rename from src/test/run-pass/functions-closures/closure_to_fn_coercion-expected-types.rs rename to src/test/ui/functions-closures/closure_to_fn_coercion-expected-types.rs diff --git a/src/test/run-pass/functions-closures/copy-closure.rs b/src/test/ui/functions-closures/copy-closure.rs similarity index 100% rename from src/test/run-pass/functions-closures/copy-closure.rs rename to src/test/ui/functions-closures/copy-closure.rs diff --git a/src/test/run-pass/functions-closures/fn-abi.rs b/src/test/ui/functions-closures/fn-abi.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-abi.rs rename to src/test/ui/functions-closures/fn-abi.rs diff --git a/src/test/run-pass/functions-closures/fn-bare-assign.rs b/src/test/ui/functions-closures/fn-bare-assign.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-bare-assign.rs rename to src/test/ui/functions-closures/fn-bare-assign.rs diff --git a/src/test/run-pass/functions-closures/fn-bare-coerce-to-block.rs b/src/test/ui/functions-closures/fn-bare-coerce-to-block.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-bare-coerce-to-block.rs rename to src/test/ui/functions-closures/fn-bare-coerce-to-block.rs diff --git a/src/test/run-pass/functions-closures/fn-bare-item.rs b/src/test/ui/functions-closures/fn-bare-item.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-bare-item.rs rename to src/test/ui/functions-closures/fn-bare-item.rs diff --git a/src/test/run-pass/functions-closures/fn-bare-size.rs b/src/test/ui/functions-closures/fn-bare-size.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-bare-size.rs rename to src/test/ui/functions-closures/fn-bare-size.rs diff --git a/src/test/run-pass/functions-closures/fn-bare-spawn.rs b/src/test/ui/functions-closures/fn-bare-spawn.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-bare-spawn.rs rename to src/test/ui/functions-closures/fn-bare-spawn.rs diff --git a/src/test/run-pass/functions-closures/fn-coerce-field.rs b/src/test/ui/functions-closures/fn-coerce-field.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-coerce-field.rs rename to src/test/ui/functions-closures/fn-coerce-field.rs diff --git a/src/test/run-pass/functions-closures/fn-item-type-cast.rs b/src/test/ui/functions-closures/fn-item-type-cast.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-item-type-cast.rs rename to src/test/ui/functions-closures/fn-item-type-cast.rs diff --git a/src/test/run-pass/functions-closures/fn-item-type-coerce.rs b/src/test/ui/functions-closures/fn-item-type-coerce.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-item-type-coerce.rs rename to src/test/ui/functions-closures/fn-item-type-coerce.rs diff --git a/src/test/run-pass/functions-closures/fn-item-type-zero-sized.rs b/src/test/ui/functions-closures/fn-item-type-zero-sized.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-item-type-zero-sized.rs rename to src/test/ui/functions-closures/fn-item-type-zero-sized.rs diff --git a/src/test/run-pass/functions-closures/fn-lval.rs b/src/test/ui/functions-closures/fn-lval.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-lval.rs rename to src/test/ui/functions-closures/fn-lval.rs diff --git a/src/test/run-pass/functions-closures/fn-type-infer.rs b/src/test/ui/functions-closures/fn-type-infer.rs similarity index 100% rename from src/test/run-pass/functions-closures/fn-type-infer.rs rename to src/test/ui/functions-closures/fn-type-infer.rs diff --git a/src/test/run-pass/functions-closures/implied-bounds-closure-arg-outlives.rs b/src/test/ui/functions-closures/implied-bounds-closure-arg-outlives.rs similarity index 100% rename from src/test/run-pass/functions-closures/implied-bounds-closure-arg-outlives.rs rename to src/test/ui/functions-closures/implied-bounds-closure-arg-outlives.rs diff --git a/src/test/run-pass/functions-closures/nullable-pointer-opt-closures.rs b/src/test/ui/functions-closures/nullable-pointer-opt-closures.rs similarity index 100% rename from src/test/run-pass/functions-closures/nullable-pointer-opt-closures.rs rename to src/test/ui/functions-closures/nullable-pointer-opt-closures.rs diff --git a/src/test/run-pass/functions-closures/parallel-codegen-closures.rs b/src/test/ui/functions-closures/parallel-codegen-closures.rs similarity index 100% rename from src/test/run-pass/functions-closures/parallel-codegen-closures.rs rename to src/test/ui/functions-closures/parallel-codegen-closures.rs diff --git a/src/test/run-pass/functions-closures/return-from-closure.rs b/src/test/ui/functions-closures/return-from-closure.rs similarity index 100% rename from src/test/run-pass/functions-closures/return-from-closure.rs rename to src/test/ui/functions-closures/return-from-closure.rs diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 65c37e01ea..24e3a077ae 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(future_incompatible)] | ^^^^^^^^^^^^^^^^^^^ - = note: #[deny(anonymous_parameters)] implied by #[deny(future_incompatible)] + = note: `#[deny(anonymous_parameters)]` implied by `#[deny(future_incompatible)]` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 diff --git a/src/test/run-pass/generator/addassign-yield.rs b/src/test/ui/generator/addassign-yield.rs similarity index 98% rename from src/test/run-pass/generator/addassign-yield.rs rename to src/test/ui/generator/addassign-yield.rs index 6a41793638..66f22bf31f 100644 --- a/src/test/run-pass/generator/addassign-yield.rs +++ b/src/test/ui/generator/addassign-yield.rs @@ -1,3 +1,4 @@ +// run-pass // Regression test for broken MIR error (#61442) // Due to the two possible evaluation orders for // a '+=' expression (depending on whether or not the 'AddAssign' trait diff --git a/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs b/src/test/ui/generator/auxiliary/xcrate-reachable.rs similarity index 100% rename from src/test/run-pass/generator/auxiliary/xcrate-reachable.rs rename to src/test/ui/generator/auxiliary/xcrate-reachable.rs diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/ui/generator/auxiliary/xcrate.rs similarity index 100% rename from src/test/run-pass/generator/auxiliary/xcrate.rs rename to src/test/ui/generator/auxiliary/xcrate.rs diff --git a/src/test/run-pass/generator/borrow-in-tail-expr.rs b/src/test/ui/generator/borrow-in-tail-expr.rs similarity index 100% rename from src/test/run-pass/generator/borrow-in-tail-expr.rs rename to src/test/ui/generator/borrow-in-tail-expr.rs diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/ui/generator/conditional-drop.rs similarity index 100% rename from src/test/run-pass/generator/conditional-drop.rs rename to src/test/ui/generator/conditional-drop.rs diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/ui/generator/control-flow.rs similarity index 100% rename from src/test/run-pass/generator/control-flow.rs rename to src/test/ui/generator/control-flow.rs diff --git a/src/test/run-pass/generator/drop-and-replace.rs b/src/test/ui/generator/drop-and-replace.rs similarity index 98% rename from src/test/run-pass/generator/drop-and-replace.rs rename to src/test/ui/generator/drop-and-replace.rs index 042e1276db..bb33502815 100644 --- a/src/test/run-pass/generator/drop-and-replace.rs +++ b/src/test/ui/generator/drop-and-replace.rs @@ -1,3 +1,4 @@ +// run-pass // Regression test for incorrect DropAndReplace behavior introduced in #60840 // and fixed in #61373. When combined with the optimization implemented in // #60187, this produced incorrect code for generators when a saved local was diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/ui/generator/drop-env.rs similarity index 100% rename from src/test/run-pass/generator/drop-env.rs rename to src/test/ui/generator/drop-env.rs diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/ui/generator/issue-44197.rs similarity index 100% rename from src/test/run-pass/generator/issue-44197.rs rename to src/test/ui/generator/issue-44197.rs diff --git a/src/test/run-pass/generator/issue-52398.rs b/src/test/ui/generator/issue-52398.rs similarity index 100% rename from src/test/run-pass/generator/issue-52398.rs rename to src/test/ui/generator/issue-52398.rs diff --git a/src/test/ui/generator/issue-53548-1.rs b/src/test/ui/generator/issue-53548-1.rs index df11800731..395456ce7c 100644 --- a/src/test/ui/generator/issue-53548-1.rs +++ b/src/test/ui/generator/issue-53548-1.rs @@ -2,7 +2,7 @@ // but which encountered the same ICE/error. See `issue-53548.rs` // for details. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::RefCell; use std::rc::Rc; diff --git a/src/test/ui/generator/issue-53548.rs b/src/test/ui/generator/issue-53548.rs index 73a2bcdd55..8136c65923 100644 --- a/src/test/ui/generator/issue-53548.rs +++ b/src/test/ui/generator/issue-53548.rs @@ -15,7 +15,7 @@ // also analogous to what we would do for higher-ranked regions // appearing within the trait in other positions). // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(generators)] diff --git a/src/test/run-pass/generator/issue-57084.rs b/src/test/ui/generator/issue-57084.rs similarity index 100% rename from src/test/run-pass/generator/issue-57084.rs rename to src/test/ui/generator/issue-57084.rs diff --git a/src/test/run-pass/generator/issue-58888.rs b/src/test/ui/generator/issue-58888.rs similarity index 100% rename from src/test/run-pass/generator/issue-58888.rs rename to src/test/ui/generator/issue-58888.rs diff --git a/src/test/ui/generator/issue-62506-two_awaits.rs b/src/test/ui/generator/issue-62506-two_awaits.rs new file mode 100644 index 0000000000..774019b6a5 --- /dev/null +++ b/src/test/ui/generator/issue-62506-two_awaits.rs @@ -0,0 +1,18 @@ +// Output = String caused an ICE whereas Output = &'static str compiled successfully. +// Broken MIR: generator contains type std::string::String in MIR, +// but typeck only knows about {::Future, ()} +// check-pass +// edition:2018 + +#![feature(async_await)] +use std::future::Future; + +pub trait T { + type Future: Future; + fn bar() -> Self::Future; +} +pub async fn foo() where S: T { + S::bar().await; + S::bar().await; +} +pub fn main() {} diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/ui/generator/iterator-count.rs similarity index 100% rename from src/test/run-pass/generator/iterator-count.rs rename to src/test/ui/generator/iterator-count.rs diff --git a/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/ui/generator/live-upvar-across-yield.rs similarity index 100% rename from src/test/run-pass/generator/live-upvar-across-yield.rs rename to src/test/ui/generator/live-upvar-across-yield.rs diff --git a/src/test/run-pass/generator/match-bindings.rs b/src/test/ui/generator/match-bindings.rs similarity index 100% rename from src/test/run-pass/generator/match-bindings.rs rename to src/test/ui/generator/match-bindings.rs diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/ui/generator/nested_generators.rs similarity index 100% rename from src/test/run-pass/generator/nested_generators.rs rename to src/test/ui/generator/nested_generators.rs diff --git a/src/test/run-pass/generator/non-static-is-unpin.rs b/src/test/ui/generator/non-static-is-unpin.rs similarity index 100% rename from src/test/run-pass/generator/non-static-is-unpin.rs rename to src/test/ui/generator/non-static-is-unpin.rs diff --git a/src/test/run-pass/generator/overlap-locals.rs b/src/test/ui/generator/overlap-locals.rs similarity index 97% rename from src/test/run-pass/generator/overlap-locals.rs rename to src/test/ui/generator/overlap-locals.rs index 704484a480..101c8714fa 100644 --- a/src/test/run-pass/generator/overlap-locals.rs +++ b/src/test/ui/generator/overlap-locals.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(generators)] fn main() { diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/ui/generator/panic-drops.rs similarity index 100% rename from src/test/run-pass/generator/panic-drops.rs rename to src/test/ui/generator/panic-drops.rs diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/ui/generator/panic-safe.rs similarity index 100% rename from src/test/run-pass/generator/panic-safe.rs rename to src/test/ui/generator/panic-safe.rs diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs new file mode 100644 index 0000000000..1e4593002c --- /dev/null +++ b/src/test/ui/generator/partial-initialization-across-yield.rs @@ -0,0 +1,46 @@ +// Test that we don't allow yielding from a generator while a local is partially +// initialized. + +#![feature(generators)] + +struct S { x: i32, y: i32 } +struct T(i32, i32); + +fn test_tuple() { + let _ = || { + let mut t: (i32, i32); + t.0 = 42; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + yield; + t.1 = 88; + let _ = t; + }; +} + +fn test_tuple_struct() { + let _ = || { + let mut t: T; + t.0 = 42; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + yield; + t.1 = 88; + let _ = t; + }; +} + +fn test_struct() { + let _ = || { + let mut t: S; + t.x = 42; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + yield; + t.y = 88; + let _ = t; + }; +} + +fn main() { + test_tuple(); + test_tuple_struct(); + test_struct(); +} diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr new file mode 100644 index 0000000000..8bf0037e07 --- /dev/null +++ b/src/test/ui/generator/partial-initialization-across-yield.stderr @@ -0,0 +1,21 @@ +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/partial-initialization-across-yield.rs:12:9 + | +LL | t.0 = 42; + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/partial-initialization-across-yield.rs:23:9 + | +LL | t.0 = 42; + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/partial-initialization-across-yield.rs:34:9 + | +LL | t.x = 42; + | ^^^^^^^^ use of possibly uninitialized `t` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/run-pass/generator/pin-box-generator.rs b/src/test/ui/generator/pin-box-generator.rs similarity index 100% rename from src/test/run-pass/generator/pin-box-generator.rs rename to src/test/ui/generator/pin-box-generator.rs diff --git a/src/test/run-pass/generator/reborrow-mut-upvar.rs b/src/test/ui/generator/reborrow-mut-upvar.rs similarity index 100% rename from src/test/run-pass/generator/reborrow-mut-upvar.rs rename to src/test/ui/generator/reborrow-mut-upvar.rs diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr new file mode 100644 index 0000000000..530bf368f6 --- /dev/null +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.polonius.stderr @@ -0,0 +1,20 @@ +error[E0597]: `b` does not live long enough + --> $DIR/ref-escapes-but-not-over-yield.rs:11:13 + | +LL | let mut b = move || { + | _________________- +LL | | yield(); +LL | | let b = 5; +LL | | a = &b; + | | ^^ borrowed value does not live long enough +LL | | +LL | | }; + | | - + | | | + | | `b` dropped here while still borrowed + | |_____... and the borrow might be used here, when that temporary is dropped and runs the destructor for generator + | a temporary with access to the borrow is created here ... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/ui/generator/resume-after-return.rs similarity index 100% rename from src/test/run-pass/generator/resume-after-return.rs rename to src/test/ui/generator/resume-after-return.rs diff --git a/src/test/run-pass/generator/size-moved-locals.rs b/src/test/ui/generator/size-moved-locals.rs similarity index 83% rename from src/test/run-pass/generator/size-moved-locals.rs rename to src/test/ui/generator/size-moved-locals.rs index 37e2e0cfdc..01db971434 100644 --- a/src/test/run-pass/generator/size-moved-locals.rs +++ b/src/test/ui/generator/size-moved-locals.rs @@ -1,3 +1,4 @@ +// run-pass // Test that we don't duplicate storage for a variable that is moved to another // binding. This used to happen in the presence of unwind and drop edges (see // `complex` below.) @@ -9,6 +10,7 @@ // See issue #59123 for a full explanation. // edition:2018 +// ignore-wasm32 issue #62807 #![feature(generators, generator_trait)] @@ -55,8 +57,20 @@ fn overlap_move_points() -> impl Generator { } } +fn overlap_x_and_y() -> impl Generator{ + static || { + let x = Foo([0; FOO_SIZE]); + yield; + drop(x); + let y = Foo([0; FOO_SIZE]); + yield; + drop(y); + } +} + fn main() { assert_eq!(1028, std::mem::size_of_val(&move_before_yield())); assert_eq!(1032, std::mem::size_of_val(&move_before_yield_with_noop())); assert_eq!(2056, std::mem::size_of_val(&overlap_move_points())); + assert_eq!(1032, std::mem::size_of_val(&overlap_x_and_y())); } diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/ui/generator/smoke.rs similarity index 100% rename from src/test/run-pass/generator/smoke.rs rename to src/test/ui/generator/smoke.rs diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/ui/generator/static-generators.rs similarity index 100% rename from src/test/run-pass/generator/static-generators.rs rename to src/test/ui/generator/static-generators.rs diff --git a/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs b/src/test/ui/generator/too-live-local-in-immovable-gen.rs similarity index 100% rename from src/test/run-pass/generator/too-live-local-in-immovable-gen.rs rename to src/test/ui/generator/too-live-local-in-immovable-gen.rs diff --git a/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/ui/generator/xcrate-reachable.rs similarity index 100% rename from src/test/run-pass/generator/xcrate-reachable.rs rename to src/test/ui/generator/xcrate-reachable.rs diff --git a/src/test/run-pass/generator/xcrate.rs b/src/test/ui/generator/xcrate.rs similarity index 100% rename from src/test/run-pass/generator/xcrate.rs rename to src/test/ui/generator/xcrate.rs diff --git a/src/test/run-pass/generator/yield-in-args-rev.rs b/src/test/ui/generator/yield-in-args-rev.rs similarity index 100% rename from src/test/run-pass/generator/yield-in-args-rev.rs rename to src/test/ui/generator/yield-in-args-rev.rs diff --git a/src/test/run-pass/generator/yield-in-box.rs b/src/test/ui/generator/yield-in-box.rs similarity index 100% rename from src/test/run-pass/generator/yield-in-box.rs rename to src/test/ui/generator/yield-in-box.rs diff --git a/src/test/run-pass/generator/yield-in-initializer.rs b/src/test/ui/generator/yield-in-initializer.rs similarity index 100% rename from src/test/run-pass/generator/yield-in-initializer.rs rename to src/test/ui/generator/yield-in-initializer.rs diff --git a/src/test/run-pass/generator/yield-subtype.rs b/src/test/ui/generator/yield-subtype.rs similarity index 100% rename from src/test/run-pass/generator/yield-subtype.rs rename to src/test/ui/generator/yield-subtype.rs diff --git a/src/test/ui/generic/generic-param-attrs.rs b/src/test/ui/generic/generic-param-attrs.rs index 601d2a9e0a..3c5cc84c6a 100644 --- a/src/test/ui/generic/generic-param-attrs.rs +++ b/src/test/ui/generic/generic-param-attrs.rs @@ -1,44 +1,38 @@ // This test previously ensured that attributes on formals in generic parameter // lists are rejected without a feature gate. -// -// (We are prefixing all tested features with `rustc_`, to ensure that -// the attributes themselves won't be rejected by the compiler when -// using `rustc_attrs` feature. There is a separate compile-fail/ test -// ensuring that the attribute feature-gating works in this context.) -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] -#![allow(dead_code)] - -struct StLt<#[rustc_lt_struct] 'a>(&'a u32); -struct StTy<#[rustc_ty_struct] I>(I); -enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B } -enum EnTy<#[rustc_ty_enum] J> { A(J), B } -trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); } -type TyLt<#[rustc_lt_type] 'd> = &'d u32; -type TyTy<#[rustc_ty_type] L> = (L, ); - -impl<#[rustc_lt_inherent] 'e> StLt<'e> { } -impl<#[rustc_ty_inherent] M> StTy { } -impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> { + +struct StLt<#[rustc_dummy] 'a>(&'a u32); +struct StTy<#[rustc_dummy] I>(I); +enum EnLt<#[rustc_dummy] 'b> { A(&'b u32), B } +enum EnTy<#[rustc_dummy] J> { A(J), B } +trait TrLt<#[rustc_dummy] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } +trait TrTy<#[rustc_dummy] K> { fn foo(&self, _: K); } +type TyLt<#[rustc_dummy] 'd> = &'d u32; +type TyTy<#[rustc_dummy] L> = (L, ); + +impl<#[rustc_dummy] 'e> StLt<'e> { } +impl<#[rustc_dummy] M> StTy { } +impl<#[rustc_dummy] 'f> TrLt<'f> for StLt<'f> { fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } } -impl<#[rustc_ty_impl_for] N> TrTy for StTy { +impl<#[rustc_dummy] N> TrTy for StTy { fn foo(&self, _: N) { } } -fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -fn f_ty<#[rustc_ty_fn] O>(_: O) { } +fn f_lt<#[rustc_dummy] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } +fn f_ty<#[rustc_dummy] O>(_: O) { } impl StTy { - fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - fn m_ty<#[rustc_ty_meth] P>(_: P) { } + fn m_lt<#[rustc_dummy] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } + fn m_ty<#[rustc_dummy] P>(_: P) { } } fn hof_lt(_: Q) - where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 + where Q: for <#[rustc_dummy] 'i> Fn(&'i [u32]) -> &'i u32 {} fn main() {} diff --git a/src/test/run-pass/generics/auxiliary/default_type_params_xc.rs b/src/test/ui/generics/auxiliary/default_type_params_xc.rs similarity index 100% rename from src/test/run-pass/generics/auxiliary/default_type_params_xc.rs rename to src/test/ui/generics/auxiliary/default_type_params_xc.rs diff --git a/src/test/run-pass/generics/generic-alias-unique.rs b/src/test/ui/generics/generic-alias-unique.rs similarity index 100% rename from src/test/run-pass/generics/generic-alias-unique.rs rename to src/test/ui/generics/generic-alias-unique.rs diff --git a/src/test/run-pass/generics/generic-default-type-params-cross-crate.rs b/src/test/ui/generics/generic-default-type-params-cross-crate.rs similarity index 100% rename from src/test/run-pass/generics/generic-default-type-params-cross-crate.rs rename to src/test/ui/generics/generic-default-type-params-cross-crate.rs diff --git a/src/test/run-pass/generics/generic-default-type-params.rs b/src/test/ui/generics/generic-default-type-params.rs similarity index 100% rename from src/test/run-pass/generics/generic-default-type-params.rs rename to src/test/ui/generics/generic-default-type-params.rs diff --git a/src/test/run-pass/generics/generic-derived-type.rs b/src/test/ui/generics/generic-derived-type.rs similarity index 100% rename from src/test/run-pass/generics/generic-derived-type.rs rename to src/test/ui/generics/generic-derived-type.rs diff --git a/src/test/run-pass/generics/generic-exterior-unique.rs b/src/test/ui/generics/generic-exterior-unique.rs similarity index 100% rename from src/test/run-pass/generics/generic-exterior-unique.rs rename to src/test/ui/generics/generic-exterior-unique.rs diff --git a/src/test/run-pass/generics/generic-extern-mangle.rs b/src/test/ui/generics/generic-extern-mangle.rs similarity index 100% rename from src/test/run-pass/generics/generic-extern-mangle.rs rename to src/test/ui/generics/generic-extern-mangle.rs diff --git a/src/test/run-pass/generics/generic-fn-infer.rs b/src/test/ui/generics/generic-fn-infer.rs similarity index 100% rename from src/test/run-pass/generics/generic-fn-infer.rs rename to src/test/ui/generics/generic-fn-infer.rs diff --git a/src/test/run-pass/generics/generic-fn-twice.rs b/src/test/ui/generics/generic-fn-twice.rs similarity index 100% rename from src/test/run-pass/generics/generic-fn-twice.rs rename to src/test/ui/generics/generic-fn-twice.rs diff --git a/src/test/run-pass/generics/generic-fn-unique.rs b/src/test/ui/generics/generic-fn-unique.rs similarity index 100% rename from src/test/run-pass/generics/generic-fn-unique.rs rename to src/test/ui/generics/generic-fn-unique.rs diff --git a/src/test/run-pass/generics/generic-fn.rs b/src/test/ui/generics/generic-fn.rs similarity index 100% rename from src/test/run-pass/generics/generic-fn.rs rename to src/test/ui/generics/generic-fn.rs diff --git a/src/test/run-pass/generics/generic-ivec-leak.rs b/src/test/ui/generics/generic-ivec-leak.rs similarity index 100% rename from src/test/run-pass/generics/generic-ivec-leak.rs rename to src/test/ui/generics/generic-ivec-leak.rs diff --git a/src/test/run-pass/generics/generic-newtype-struct.rs b/src/test/ui/generics/generic-newtype-struct.rs similarity index 100% rename from src/test/run-pass/generics/generic-newtype-struct.rs rename to src/test/ui/generics/generic-newtype-struct.rs diff --git a/src/test/run-pass/generics/generic-object.rs b/src/test/ui/generics/generic-object.rs similarity index 100% rename from src/test/run-pass/generics/generic-object.rs rename to src/test/ui/generics/generic-object.rs diff --git a/src/test/run-pass/generics/generic-recursive-tag.rs b/src/test/ui/generics/generic-recursive-tag.rs similarity index 100% rename from src/test/run-pass/generics/generic-recursive-tag.rs rename to src/test/ui/generics/generic-recursive-tag.rs diff --git a/src/test/run-pass/generics/generic-static-methods.rs b/src/test/ui/generics/generic-static-methods.rs similarity index 100% rename from src/test/run-pass/generics/generic-static-methods.rs rename to src/test/ui/generics/generic-static-methods.rs diff --git a/src/test/run-pass/generics/generic-tag-corruption.rs b/src/test/ui/generics/generic-tag-corruption.rs similarity index 100% rename from src/test/run-pass/generics/generic-tag-corruption.rs rename to src/test/ui/generics/generic-tag-corruption.rs diff --git a/src/test/run-pass/generics/generic-tag-local.rs b/src/test/ui/generics/generic-tag-local.rs similarity index 100% rename from src/test/run-pass/generics/generic-tag-local.rs rename to src/test/ui/generics/generic-tag-local.rs diff --git a/src/test/run-pass/generics/generic-tag-match.rs b/src/test/ui/generics/generic-tag-match.rs similarity index 100% rename from src/test/run-pass/generics/generic-tag-match.rs rename to src/test/ui/generics/generic-tag-match.rs diff --git a/src/test/run-pass/generics/generic-tag-values.rs b/src/test/ui/generics/generic-tag-values.rs similarity index 100% rename from src/test/run-pass/generics/generic-tag-values.rs rename to src/test/ui/generics/generic-tag-values.rs diff --git a/src/test/run-pass/generics/generic-tag.rs b/src/test/ui/generics/generic-tag.rs similarity index 100% rename from src/test/run-pass/generics/generic-tag.rs rename to src/test/ui/generics/generic-tag.rs diff --git a/src/test/run-pass/generics/generic-temporary.rs b/src/test/ui/generics/generic-temporary.rs similarity index 100% rename from src/test/run-pass/generics/generic-temporary.rs rename to src/test/ui/generics/generic-temporary.rs diff --git a/src/test/run-pass/generics/generic-tup.rs b/src/test/ui/generics/generic-tup.rs similarity index 100% rename from src/test/run-pass/generics/generic-tup.rs rename to src/test/ui/generics/generic-tup.rs diff --git a/src/test/run-pass/generics/generic-type-synonym.rs b/src/test/ui/generics/generic-type-synonym.rs similarity index 100% rename from src/test/run-pass/generics/generic-type-synonym.rs rename to src/test/ui/generics/generic-type-synonym.rs diff --git a/src/test/run-pass/generics/generic-type.rs b/src/test/ui/generics/generic-type.rs similarity index 100% rename from src/test/run-pass/generics/generic-type.rs rename to src/test/ui/generics/generic-type.rs diff --git a/src/test/run-pass/generics/generic-unique.rs b/src/test/ui/generics/generic-unique.rs similarity index 100% rename from src/test/run-pass/generics/generic-unique.rs rename to src/test/ui/generics/generic-unique.rs diff --git a/src/test/run-pass/global-scope.rs b/src/test/ui/global-scope.rs similarity index 94% rename from src/test/run-pass/global-scope.rs rename to src/test/ui/global-scope.rs index 22fb0f93db..944eee5afc 100644 --- a/src/test/run-pass/global-scope.rs +++ b/src/test/ui/global-scope.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn f() -> isize { return 1; } pub mod foo { diff --git a/src/test/run-pass/guards-not-exhaustive.rs b/src/test/ui/guards-not-exhaustive.rs similarity index 94% rename from src/test/run-pass/guards-not-exhaustive.rs rename to src/test/ui/guards-not-exhaustive.rs index 752e4f6be4..b74f162c0c 100644 --- a/src/test/run-pass/guards-not-exhaustive.rs +++ b/src/test/ui/guards-not-exhaustive.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_snake_case)] #[derive(Copy, Clone)] diff --git a/src/test/run-pass/guards.rs b/src/test/ui/guards.rs similarity index 97% rename from src/test/run-pass/guards.rs rename to src/test/ui/guards.rs index 94095eac16..10a4bb6738 100644 --- a/src/test/run-pass/guards.rs +++ b/src/test/ui/guards.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_shorthand_field_patterns)] #[derive(Copy, Clone)] diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/ui/hashmap-memory.rs similarity index 99% rename from src/test/run-pass/hashmap-memory.rs rename to src/test/ui/hashmap-memory.rs index 987a3e414f..3129eb0da8 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/ui/hashmap-memory.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/src/test/run-pass/hello.rs b/src/test/ui/hello.rs similarity index 78% rename from src/test/run-pass/hello.rs rename to src/test/ui/hello.rs index bc8bb23877..c207c25545 100644 --- a/src/test/run-pass/hello.rs +++ b/src/test/ui/hello.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { println!("hello, world"); } diff --git a/src/test/ui/hello_world/main.rs b/src/test/ui/hello_world/main.rs index f790af64b4..22ce47414b 100644 --- a/src/test/ui/hello_world/main.rs +++ b/src/test/ui/hello_world/main.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that compiling hello world succeeds with no output of any kind. diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-fn-like-trait.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-opt-in-copy.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-opt-in-copy.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-parse.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-parse.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-parse.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-type-outlives.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-type-outlives.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs diff --git a/src/test/run-pass/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs similarity index 100% rename from src/test/run-pass/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs rename to src/test/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr index 0522fc45d6..6d1ef24b2d 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr @@ -11,7 +11,7 @@ LL | | no_hrtb(&mut t); LL | | } | |_^ cannot return without recursing | - = note: #[warn(unconditional_recursion)] on by default + = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr new file mode 100644 index 0000000000..e7deca7644 --- /dev/null +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -0,0 +1,11 @@ +error: implementation of `Stream` is not general enough + --> $DIR/issue-30786.rs:108:22 + | +LL | let map = source.map(|x: &_| x); + | ^^^ + | + = note: `Stream` would have to be implemented for the type `&'0 mut Map`, for any lifetime `'0` + = note: but `Stream` is actually implemented for the type `&'1 mut Map`, for some specific lifetime `'1` + +error: aborting due to previous error + diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr new file mode 100644 index 0000000000..8614d86d93 --- /dev/null +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -0,0 +1,14 @@ +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:112:18 + | +LL | let filter = map.filter(|x: &_| true); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-30786.rs:114:17 + | +LL | let count = filter.count(); // Assert that we still have a valid stream. + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs new file mode 100644 index 0000000000..b9920a1950 --- /dev/null +++ b/src/test/ui/hrtb/issue-30786.rs @@ -0,0 +1,116 @@ +// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream Option; +} + +// Example stream +pub struct Repeat(u64); + +impl<'a> Stream for &'a mut Repeat { + type Item = &'a u64; + fn next(self) -> Option { + Some(&self.0) + } +} + +pub struct Map { + stream: S, + func: F, +} + +impl<'a, A, F, T> Stream for &'a mut Map +where &'a mut A: Stream, + F: FnMut(<&'a mut A as Stream>::Item) -> T, +{ + type Item = T; + fn next(self) -> Option { + match self.stream.next() { + Some(item) => Some((self.func)(item)), + None => None, + } + } +} + +pub struct Filter { + stream: S, + func: F, +} + +impl<'a, A, F, T> Stream for &'a mut Filter +where for<'b> &'b mut A: Stream, // <---- BAD + F: FnMut(&T) -> bool, +{ + type Item = <&'a mut A as Stream>::Item; + fn next(self) -> Option { + while let Some(item) = self.stream.next() { + if (self.func)(&item) { + return Some(item); + } + } + None + } +} + +pub trait StreamExt where for<'b> &'b mut Self: Stream { + fn map(self, func: F) -> Map + where Self: Sized, + for<'a> &'a mut Map: Stream, + { + Map { + func: func, + stream: self, + } + } + + fn filter(self, func: F) -> Filter + where Self: Sized, + for<'a> &'a mut Filter: Stream, + { + Filter { + func: func, + stream: self, + } + } + + fn count(mut self) -> usize + where Self: Sized, + { + let mut count = 0; + while let Some(_) = self.next() { + count += 1; + } + count + } +} + +impl StreamExt for T where for<'a> &'a mut T: Stream { } + +fn main() { + let source = Repeat(10); + let map = source.map(|x: &_| x); + //[migrate]~^ ERROR implementation of `Stream` is not general enough + //[migrate]~| NOTE `Stream` would have to be implemented for the type `&'0 mut Map + //[migrate]~| NOTE but `Stream` is actually implemented for the type `&'1 + let filter = map.filter(|x: &_| true); + //[nll]~^ ERROR higher-ranked subtype error + let count = filter.count(); // Assert that we still have a valid stream. + //[nll]~^ ERROR higher-ranked subtype error +} diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.rs b/src/test/ui/hrtb/issue-62203-hrtb-ice.rs new file mode 100644 index 0000000000..454d7e5e9c --- /dev/null +++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.rs @@ -0,0 +1,50 @@ +trait T0<'a, A> { + type O; +} + +struct L { + f: T, +} + +// explicitly named variants of what one would normally denote by the +// unit type `()`. Why do this? So that we can differentiate them in +// the diagnostic output. +struct Unit1; +struct Unit2; +struct Unit3; +struct Unit4; + +impl<'a, A, T> T0<'a, A> for L +where + T: FnMut(A) -> Unit3, +{ + type O = T::Output; +} + +trait T1: for<'r> Ty<'r> { + fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 + where + F: for<'r> T0<'r, (>::V,), O = >::V>, + { + unimplemented!(); + } +} + +trait Ty<'a> { + type V; +} + +fn main() { + let v = Unit2.m( + //~^ ERROR type mismatch + //~| ERROR type mismatch + L { + f : |x| { drop(x); Unit4 } + }); +} + +impl<'a> Ty<'a> for Unit2 { + type V = &'a u8; +} + +impl T1 for Unit2 {} diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr new file mode 100644 index 0000000000..c2d0e0c2a2 --- /dev/null +++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr @@ -0,0 +1,22 @@ +error[E0271]: type mismatch resolving `for<'r> as T0<'r, (>::V,)>>::O == <_ as Ty<'r>>::V` + --> $DIR/issue-62203-hrtb-ice.rs:38:19 + | +LL | let v = Unit2.m( + | ^ expected struct `Unit4`, found associated type + | + = note: expected type `Unit4` + found type `<_ as Ty<'_>>::V` + +error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3` + --> $DIR/issue-62203-hrtb-ice.rs:38:19 + | +LL | let v = Unit2.m( + | ^ expected struct `Unit4`, found struct `Unit3` + | + = note: expected type `Unit4` + found type `Unit3` + = note: required because of the requirements on the impl of `for<'r> T0<'r, (>::V,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/run-pass/html-literals.rs b/src/test/ui/html-literals.rs similarity index 99% rename from src/test/run-pass/html-literals.rs rename to src/test/ui/html-literals.rs index 237c6e1a10..ae45e97c8b 100644 --- a/src/test/run-pass/html-literals.rs +++ b/src/test/ui/html-literals.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] // A test of the macro system. Can we do HTML literals? diff --git a/src/test/ui/huge-array-simple-32.rs b/src/test/ui/huge-array-simple-32.rs new file mode 100644 index 0000000000..9f98f4d753 --- /dev/null +++ b/src/test/ui/huge-array-simple-32.rs @@ -0,0 +1,11 @@ +// ignore-64bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(exceeding_bitshifts)] + +fn main() { + let _fat: [u8; (1<<31)+(1<<15)] = //~ ERROR too big for the current architecture + [0; (1u32<<31) as usize +(1u32<<15) as usize]; +} diff --git a/src/test/ui/huge-array-simple-32.stderr b/src/test/ui/huge-array-simple-32.stderr new file mode 100644 index 0000000000..16372b0275 --- /dev/null +++ b/src/test/ui/huge-array-simple-32.stderr @@ -0,0 +1,8 @@ +error: the type `[u8; 2147516416]` is too big for the current architecture + --> $DIR/huge-array-simple-32.rs:9:9 + | +LL | let _fat: [u8; (1<<31)+(1<<15)] = + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/huge-array-simple-64.rs b/src/test/ui/huge-array-simple-64.rs new file mode 100644 index 0000000000..f72d69ee74 --- /dev/null +++ b/src/test/ui/huge-array-simple-64.rs @@ -0,0 +1,11 @@ +// ignore-32bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(exceeding_bitshifts)] + +fn main() { + let _fat: [u8; (1<<61)+(1<<31)] = //~ ERROR too big for the current architecture + [0; (1u64<<61) as usize +(1u64<<31) as usize]; +} diff --git a/src/test/ui/huge-array-simple-64.stderr b/src/test/ui/huge-array-simple-64.stderr new file mode 100644 index 0000000000..6ed89269f0 --- /dev/null +++ b/src/test/ui/huge-array-simple-64.stderr @@ -0,0 +1,8 @@ +error: the type `[u8; 2305843011361177600]` is too big for the current architecture + --> $DIR/huge-array-simple-64.rs:9:9 + | +LL | let _fat: [u8; (1<<61)+(1<<31)] = + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/huge-array-simple.rs b/src/test/ui/huge-array-simple.rs deleted file mode 100644 index 0ff27168a7..0000000000 --- a/src/test/ui/huge-array-simple.rs +++ /dev/null @@ -1,20 +0,0 @@ -// error-pattern: too big for the current architecture - -// normalize-stderr-test "; \d+]" -> "; N]" - -// FIXME https://github.com/rust-lang/rust/issues/59774 -// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" -// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" -#![allow(exceeding_bitshifts)] - -#[cfg(target_pointer_width = "64")] -fn main() { - let _fat : [u8; (1<<61)+(1<<31)] = - [0; (1u64<<61) as usize +(1u64<<31) as usize]; -} - -#[cfg(target_pointer_width = "32")] -fn main() { - let _fat : [u8; (1<<31)+(1<<15)] = - [0; (1u32<<31) as usize +(1u32<<15) as usize]; -} diff --git a/src/test/ui/huge-array-simple.stderr b/src/test/ui/huge-array-simple.stderr deleted file mode 100644 index 3e9c86296c..0000000000 --- a/src/test/ui/huge-array-simple.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: the type `[u8; N]` is too big for the current architecture - -error: aborting due to previous error - diff --git a/src/test/ui/huge-array.rs b/src/test/ui/huge-array.rs index f58dcd5806..1ecf012e04 100644 --- a/src/test/ui/huge-array.rs +++ b/src/test/ui/huge-array.rs @@ -1,11 +1,10 @@ -// error-pattern:; 1518600000 - // FIXME https://github.com/rust-lang/rust/issues/59774 // normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" fn generic(t: T) { let s: [T; 1518600000] = [t; 1518600000]; + //~^ ERROR the type `[[u8; 1518599999]; 1518600000]` is too big for the current architecture } fn main() { diff --git a/src/test/ui/huge-array.stderr b/src/test/ui/huge-array.stderr index 38d9effcfb..823d974f42 100644 --- a/src/test/ui/huge-array.stderr +++ b/src/test/ui/huge-array.stderr @@ -1,4 +1,8 @@ error: the type `[[u8; 1518599999]; 1518600000]` is too big for the current architecture + --> $DIR/huge-array.rs:6:9 + | +LL | let s: [T; 1518600000] = [t; 1518600000]; + | ^ error: aborting due to previous error diff --git a/src/test/ui/huge-enum.rs b/src/test/ui/huge-enum.rs index 2492afbdc8..98d0ba6e15 100644 --- a/src/test/ui/huge-enum.rs +++ b/src/test/ui/huge-enum.rs @@ -6,11 +6,12 @@ // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" #[cfg(target_pointer_width = "32")] -fn main() { - let big: Option<[u32; (1<<29)-1]> = None; -} +type BIG = Option<[u32; (1<<29)-1]>; #[cfg(target_pointer_width = "64")] +type BIG = Option<[u32; (1<<45)-1]>; + fn main() { - let big: Option<[u32; (1<<45)-1]> = None; + let big: BIG = None; + //~^ ERROR is too big for the current architecture } diff --git a/src/test/ui/huge-enum.stderr b/src/test/ui/huge-enum.stderr index 67cae3d52e..1f16c81a8f 100644 --- a/src/test/ui/huge-enum.stderr +++ b/src/test/ui/huge-enum.stderr @@ -1,4 +1,8 @@ error: the type `TYPE` is too big for the current architecture + --> $DIR/huge-enum.rs:15:9 + | +LL | let big: BIG = None; + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/huge-struct.rs b/src/test/ui/huge-struct.rs index dc7d75a6f0..e120cae7fd 100644 --- a/src/test/ui/huge-struct.rs +++ b/src/test/ui/huge-struct.rs @@ -47,4 +47,6 @@ struct S1M { val: S1k> } fn main() { let fat: Option>>> = None; + //~^ ERROR the type `S32>>` is too big for the current architecture + } diff --git a/src/test/ui/huge-struct.stderr b/src/test/ui/huge-struct.stderr index 06b084bdc3..5c2140df48 100644 --- a/src/test/ui/huge-struct.stderr +++ b/src/test/ui/huge-struct.stderr @@ -1,4 +1,8 @@ error: the type `SXX>>` is too big for the current architecture + --> $DIR/huge-struct.rs:49:9 + | +LL | let fat: Option>>> = None; + | ^^^ error: aborting due to previous error diff --git a/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs b/src/test/ui/hygiene/auxiliary/legacy_interaction.rs similarity index 92% rename from src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs rename to src/test/ui/hygiene/auxiliary/legacy_interaction.rs index 0774fbecac..90d5243b74 100644 --- a/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs +++ b/src/test/ui/hygiene/auxiliary/legacy_interaction.rs @@ -1,4 +1,3 @@ -// run-pass // ignore-pretty pretty-printing is unhygienic #[macro_export] diff --git a/src/test/run-pass/hygiene/auxiliary/my_crate.rs b/src/test/ui/hygiene/auxiliary/my_crate.rs similarity index 53% rename from src/test/run-pass/hygiene/auxiliary/my_crate.rs rename to src/test/ui/hygiene/auxiliary/my_crate.rs index 5a7412e4bf..cdc6c27d80 100644 --- a/src/test/run-pass/hygiene/auxiliary/my_crate.rs +++ b/src/test/ui/hygiene/auxiliary/my_crate.rs @@ -1,2 +1 @@ -// run-pass pub fn f() {} diff --git a/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs b/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs new file mode 100644 index 0000000000..81b0b7faa5 --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs @@ -0,0 +1,3 @@ +#![feature(decl_macro)] + +pub macro stdlib_macro() {} diff --git a/src/test/ui/hygiene/auxiliary/transparent-basic.rs b/src/test/ui/hygiene/auxiliary/transparent-basic.rs index 0d045d09d2..37de27ee80 100644 --- a/src/test/ui/hygiene/auxiliary/transparent-basic.rs +++ b/src/test/ui/hygiene/auxiliary/transparent-basic.rs @@ -1,6 +1,6 @@ #![feature(decl_macro, rustc_attrs)] -#[rustc_transparent_macro] +#[rustc_macro_transparency = "transparent"] pub macro dollar_crate() { let s = $crate::S; } diff --git a/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs b/src/test/ui/hygiene/auxiliary/unhygienic_example.rs similarity index 98% rename from src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs rename to src/test/ui/hygiene/auxiliary/unhygienic_example.rs index 3f66748bf3..8e6e8f9b32 100644 --- a/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs +++ b/src/test/ui/hygiene/auxiliary/unhygienic_example.rs @@ -1,4 +1,3 @@ -// run-pass #![crate_type = "lib"] extern crate my_crate; diff --git a/src/test/run-pass/hygiene/auxiliary/xcrate.rs b/src/test/ui/hygiene/auxiliary/xcrate.rs similarity index 96% rename from src/test/run-pass/hygiene/auxiliary/xcrate.rs rename to src/test/ui/hygiene/auxiliary/xcrate.rs index 3862914d58..f5a911f57d 100644 --- a/src/test/run-pass/hygiene/auxiliary/xcrate.rs +++ b/src/test/ui/hygiene/auxiliary/xcrate.rs @@ -1,4 +1,3 @@ -// run-pass #![feature(decl_macro)] #![allow(unused)] diff --git a/src/test/ui/hygiene/dollar-crate-modern.rs b/src/test/ui/hygiene/dollar-crate-modern.rs index 380ad20486..a432fb6eee 100644 --- a/src/test/ui/hygiene/dollar-crate-modern.rs +++ b/src/test/ui/hygiene/dollar-crate-modern.rs @@ -1,6 +1,6 @@ // Make sure `$crate` and `crate` work in for basic cases of nested macros. -// compile-pass +// check-pass // aux-build:intercrate.rs #![feature(decl_macro, crate_in_paths)] diff --git a/src/test/ui/hygiene/dollar-crate-modern.stderr b/src/test/ui/hygiene/dollar-crate-modern.stderr index 69bbc52ee0..cd40df16ba 100644 --- a/src/test/ui/hygiene/dollar-crate-modern.stderr +++ b/src/test/ui/hygiene/dollar-crate-modern.stderr @@ -4,5 +4,5 @@ warning: the feature `crate_in_paths` has been stable since 1.30.0 and no longer LL | #![feature(decl_macro, crate_in_paths)] | ^^^^^^^^^^^^^^ | - = note: #[warn(stable_features)] on by default + = note: `#[warn(stable_features)]` on by default diff --git a/src/test/ui/hygiene/duplicate_lifetimes.rs b/src/test/ui/hygiene/duplicate_lifetimes.rs new file mode 100644 index 0000000000..e7312b51db --- /dev/null +++ b/src/test/ui/hygiene/duplicate_lifetimes.rs @@ -0,0 +1,19 @@ +// Ensure that lifetime parameter names are modernized before we check for +// duplicates. + +#![feature(decl_macro, rustc_attrs)] + +#[rustc_macro_transparency = "semitransparent"] +macro m($a:lifetime) { + fn g<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice +} + +#[rustc_macro_transparency = "transparent"] +macro n($a:lifetime) { + fn h<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice +} + +m!('a); +n!('a); + +fn main() {} diff --git a/src/test/ui/hygiene/duplicate_lifetimes.stderr b/src/test/ui/hygiene/duplicate_lifetimes.stderr new file mode 100644 index 0000000000..7aaea6ff24 --- /dev/null +++ b/src/test/ui/hygiene/duplicate_lifetimes.stderr @@ -0,0 +1,27 @@ +error[E0263]: lifetime name `'a` declared twice in the same scope + --> $DIR/duplicate_lifetimes.rs:8:14 + | +LL | fn g<$a, 'a>() {} + | ^^ declared twice +... +LL | m!('a); + | ------- + | | | + | | previous declaration here + | in this macro invocation + +error[E0263]: lifetime name `'a` declared twice in the same scope + --> $DIR/duplicate_lifetimes.rs:13:14 + | +LL | fn h<$a, 'a>() {} + | ^^ declared twice +... +LL | n!('a); + | ------- + | | | + | | previous declaration here + | in this macro invocation + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0263`. diff --git a/src/test/ui/hygiene/eager-from-opaque-2.rs b/src/test/ui/hygiene/eager-from-opaque-2.rs new file mode 100644 index 0000000000..220e552674 --- /dev/null +++ b/src/test/ui/hygiene/eager-from-opaque-2.rs @@ -0,0 +1,22 @@ +// Regression test for the issue #63460. + +// check-pass + +#[macro_export] +macro_rules! separator { + () => { "/" }; +} + +#[macro_export] +macro_rules! concat_separator { + ( $e:literal, $($other:literal),+ ) => { + concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+)) + }; + ( $e:literal ) => { + $e + } +} + +fn main() { + println!("{}", concat_separator!(2, 3, 4)) +} diff --git a/src/test/ui/hygiene/eager-from-opaque.rs b/src/test/ui/hygiene/eager-from-opaque.rs new file mode 100644 index 0000000000..6f3215dd69 --- /dev/null +++ b/src/test/ui/hygiene/eager-from-opaque.rs @@ -0,0 +1,20 @@ +// Opaque macro can eagerly expand its input without breaking its resolution. +// Regression test for issue #63685. + +// check-pass + +macro_rules! foo { + () => { + "foo" + }; +} + +macro_rules! bar { + () => { + foo!() + }; +} + +fn main() { + format_args!(bar!()); +} diff --git a/src/test/ui/hygiene/expansion-info-reset.rs b/src/test/ui/hygiene/expansion-info-reset.rs index 5c384c4ada..fa5f712121 100644 --- a/src/test/ui/hygiene/expansion-info-reset.rs +++ b/src/test/ui/hygiene/expansion-info-reset.rs @@ -1,6 +1,3 @@ -// FIXME: Investigate why expansion info for a single expansion id is reset from -// `MacroBang(format_args)` to `MacroAttribute(derive(Clone))` (issue #52363). - fn main() { format_args!({ #[derive(Clone)] struct S; }); //~^ ERROR format argument must be a string literal diff --git a/src/test/ui/hygiene/expansion-info-reset.stderr b/src/test/ui/hygiene/expansion-info-reset.stderr index 9dd954b16c..d8b602ce1c 100644 --- a/src/test/ui/hygiene/expansion-info-reset.stderr +++ b/src/test/ui/hygiene/expansion-info-reset.stderr @@ -1,5 +1,5 @@ error: format argument must be a string literal - --> $DIR/expansion-info-reset.rs:5:18 + --> $DIR/expansion-info-reset.rs:2:18 | LL | format_args!({ #[derive(Clone)] struct S; }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs new file mode 100644 index 0000000000..06d62656e9 --- /dev/null +++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs @@ -0,0 +1,28 @@ +#![feature(decl_macro)] + +macro a() { + extern crate core as my_core; + mod v { + // Early resolution. + use my_core; //~ ERROR unresolved import `my_core` + } + mod u { + // Late resolution. + fn f() { my_core::mem::drop(0); } + //~^ ERROR failed to resolve: use of undeclared type or module `my_core` + } +} + +a!(); + +mod v { + // Early resolution. + use my_core; //~ ERROR unresolved import `my_core` +} +mod u { + // Late resolution. + fn f() { my_core::mem::drop(0); } + //~^ ERROR failed to resolve: use of undeclared type or module `my_core` +} + +fn main() {} diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr new file mode 100644 index 0000000000..65133eb1e1 --- /dev/null +++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr @@ -0,0 +1,37 @@ +error[E0432]: unresolved import `my_core` + --> $DIR/extern-prelude-from-opaque-fail.rs:20:9 + | +LL | use my_core; + | ^^^^^^^ + | | + | no `my_core` in the root + | help: a similar name exists in the module: `my_core` + +error[E0432]: unresolved import `my_core` + --> $DIR/extern-prelude-from-opaque-fail.rs:7:13 + | +LL | use my_core; + | ^^^^^^^ no `my_core` in the root +... +LL | a!(); + | ----- in this macro invocation + +error[E0433]: failed to resolve: use of undeclared type or module `my_core` + --> $DIR/extern-prelude-from-opaque-fail.rs:11:18 + | +LL | fn f() { my_core::mem::drop(0); } + | ^^^^^^^ use of undeclared type or module `my_core` +... +LL | a!(); + | ----- in this macro invocation + +error[E0433]: failed to resolve: use of undeclared type or module `my_core` + --> $DIR/extern-prelude-from-opaque-fail.rs:24:14 + | +LL | fn f() { my_core::mem::drop(0); } + | ^^^^^^^ use of undeclared type or module `my_core` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0432, E0433. +For more information about an error, try `rustc --explain E0432`. diff --git a/src/test/ui/hygiene/format-args.rs b/src/test/ui/hygiene/format-args.rs new file mode 100644 index 0000000000..d74889b95c --- /dev/null +++ b/src/test/ui/hygiene/format-args.rs @@ -0,0 +1,12 @@ +// check-pass + +#![allow(non_upper_case_globals)] +#![feature(format_args_nl)] + +static arg0: () = (); + +fn main() { + static arg1: () = (); + format_args!("{} {:?}", 0, 1); + format_args_nl!("{} {:?}", 0, 1); +} diff --git a/src/test/ui/hygiene/generate-mod.rs b/src/test/ui/hygiene/generate-mod.rs index 089d74f123..8826293542 100644 --- a/src/test/ui/hygiene/generate-mod.rs +++ b/src/test/ui/hygiene/generate-mod.rs @@ -11,7 +11,7 @@ macro genmod($FromOutside: ident, $Outer: ident) { } } -#[rustc_transparent_macro] +#[rustc_macro_transparency = "transparent"] macro genmod_transparent() { type A = FromOutside; struct Outer; diff --git a/src/test/ui/hygiene/generic_params.rs b/src/test/ui/hygiene/generic_params.rs new file mode 100644 index 0000000000..9dc5adfce4 --- /dev/null +++ b/src/test/ui/hygiene/generic_params.rs @@ -0,0 +1,104 @@ +// Ensure that generic parameters always have modern hygiene. + +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro, rustc_attrs, const_generics)] + +mod type_params { + macro m($T:ident) { + fn f<$T: Clone, T: PartialEq>(t1: $T, t2: T) -> ($T, bool) { + (t1.clone(), t2 == t2) + } + } + + #[rustc_macro_transparency = "semitransparent"] + macro n($T:ident) { + fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + fn h(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + } + + #[rustc_macro_transparency = "transparent"] + macro p($T:ident) { + fn j<$T: Clone>(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + fn k(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + } + + m!(T); + n!(T); + p!(T); +} + +mod lifetime_params { + macro m($a:lifetime) { + fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "semitransparent"] + macro n($a:lifetime) { + fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + fn h<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "transparent"] + macro p($a:lifetime) { + fn j<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + fn k<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + } + + m!('a); + n!('a); + p!('a); +} + +mod const_params { + macro m($C:ident) { + fn f(t1: [(); $C], t2: [(); C]) -> ([(); $C], [(); C]) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "semitransparent"] + macro n($C:ident) { + fn g(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + fn h(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "transparent"] + macro p($C:ident) { + fn j(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + fn k(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + } + + m!(C); + n!(C); + p!(C); +} + +fn main() {} diff --git a/src/test/ui/hygiene/generic_params.stderr b/src/test/ui/hygiene/generic_params.stderr new file mode 100644 index 0000000000..b3e4fef08c --- /dev/null +++ b/src/test/ui/hygiene/generic_params.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/generic_params.rs:6:37 + | +LL | #![feature(decl_macro, rustc_attrs, const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + diff --git a/src/test/run-pass/hygiene/hygiene-dodging-1.rs b/src/test/ui/hygiene/hygiene-dodging-1.rs similarity index 100% rename from src/test/run-pass/hygiene/hygiene-dodging-1.rs rename to src/test/ui/hygiene/hygiene-dodging-1.rs diff --git a/src/test/run-pass/hygiene/hygiene.rs b/src/test/ui/hygiene/hygiene.rs similarity index 100% rename from src/test/run-pass/hygiene/hygiene.rs rename to src/test/ui/hygiene/hygiene.rs diff --git a/src/test/run-pass/hygiene/hygienic-labels-in-let.rs b/src/test/ui/hygiene/hygienic-labels-in-let.rs similarity index 100% rename from src/test/run-pass/hygiene/hygienic-labels-in-let.rs rename to src/test/ui/hygiene/hygienic-labels-in-let.rs diff --git a/src/test/run-pass/hygiene/hygienic-labels-in-let.stderr b/src/test/ui/hygiene/hygienic-labels-in-let.stderr similarity index 100% rename from src/test/run-pass/hygiene/hygienic-labels-in-let.stderr rename to src/test/ui/hygiene/hygienic-labels-in-let.stderr diff --git a/src/test/run-pass/hygiene/hygienic-labels.rs b/src/test/ui/hygiene/hygienic-labels.rs similarity index 100% rename from src/test/run-pass/hygiene/hygienic-labels.rs rename to src/test/ui/hygiene/hygienic-labels.rs diff --git a/src/test/run-pass/hygiene/hygienic-labels.stderr b/src/test/ui/hygiene/hygienic-labels.stderr similarity index 100% rename from src/test/run-pass/hygiene/hygienic-labels.stderr rename to src/test/ui/hygiene/hygienic-labels.stderr diff --git a/src/test/run-pass/hygiene/issue-44128.rs b/src/test/ui/hygiene/issue-44128.rs similarity index 94% rename from src/test/run-pass/hygiene/issue-44128.rs rename to src/test/ui/hygiene/issue-44128.rs index 23ced9ae53..5e03bdb8c5 100644 --- a/src/test/run-pass/hygiene/issue-44128.rs +++ b/src/test/ui/hygiene/issue-44128.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass #![allow(unused_must_use)] #![feature(decl_macro)] diff --git a/src/test/run-pass/hygiene/issue-47311.rs b/src/test/ui/hygiene/issue-47311.rs similarity index 93% rename from src/test/run-pass/hygiene/issue-47311.rs rename to src/test/ui/hygiene/issue-47311.rs index 856184fbc8..5c2379a8ab 100644 --- a/src/test/run-pass/hygiene/issue-47311.rs +++ b/src/test/ui/hygiene/issue-47311.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass // ignore-pretty pretty-printing is unhygienic #![feature(decl_macro)] diff --git a/src/test/run-pass/hygiene/issue-47312.rs b/src/test/ui/hygiene/issue-47312.rs similarity index 95% rename from src/test/run-pass/hygiene/issue-47312.rs rename to src/test/ui/hygiene/issue-47312.rs index 88e7a028f9..bbcb3a7f39 100644 --- a/src/test/run-pass/hygiene/issue-47312.rs +++ b/src/test/ui/hygiene/issue-47312.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass // ignore-pretty pretty-printing is unhygienic #![feature(decl_macro)] diff --git a/src/test/ui/hygiene/issue-61574-const-parameters.rs b/src/test/ui/hygiene/issue-61574-const-parameters.rs new file mode 100644 index 0000000000..dcfb42287d --- /dev/null +++ b/src/test/ui/hygiene/issue-61574-const-parameters.rs @@ -0,0 +1,32 @@ +// A more comprehensive test that const parameters have correctly implemented +// hygiene + +// check-pass + +#![feature(const_generics)] + +use std::ops::Add; + +struct VectorLike([T; {SIZE}]); + +macro_rules! impl_operator_overload { + ($trait_ident:ident, $method_ident:ident) => { + + impl $trait_ident for VectorLike + where + T: $trait_ident, + { + type Output = VectorLike; + + fn $method_ident(self, _: VectorLike) -> VectorLike { + let _ = SIZE; + unimplemented!() + } + } + + } +} + +impl_operator_overload!(Add, add); + +fn main() {} diff --git a/src/test/ui/hygiene/issue-61574-const-parameters.stderr b/src/test/ui/hygiene/issue-61574-const-parameters.stderr new file mode 100644 index 0000000000..c9aac6609a --- /dev/null +++ b/src/test/ui/hygiene/issue-61574-const-parameters.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-61574-const-parameters.rs:6:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + diff --git a/src/test/run-pass/hygiene/items.rs b/src/test/ui/hygiene/items.rs similarity index 97% rename from src/test/run-pass/hygiene/items.rs rename to src/test/ui/hygiene/items.rs index cdc271386b..1c625a9728 100644 --- a/src/test/run-pass/hygiene/items.rs +++ b/src/test/ui/hygiene/items.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass // ignore-pretty pretty-printing is unhygienic #![feature(decl_macro)] diff --git a/src/test/run-pass/hygiene/legacy_interaction.rs b/src/test/ui/hygiene/legacy_interaction.rs similarity index 95% rename from src/test/run-pass/hygiene/legacy_interaction.rs rename to src/test/ui/hygiene/legacy_interaction.rs index a5460a89f1..52008eed51 100644 --- a/src/test/run-pass/hygiene/legacy_interaction.rs +++ b/src/test/ui/hygiene/legacy_interaction.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass #![allow(dead_code)] // ignore-pretty pretty-printing is unhygienic @@ -12,7 +12,7 @@ extern crate legacy_interaction; // ```rust // macro_rules! m { // () => { -// fn f() // (1) +// fn f() {} // (1) // g() // (2) // } // } diff --git a/src/test/run-pass/hygiene/lexical.rs b/src/test/ui/hygiene/lexical.rs similarity index 96% rename from src/test/run-pass/hygiene/lexical.rs rename to src/test/ui/hygiene/lexical.rs index 20bda5508c..3d25c72098 100644 --- a/src/test/run-pass/hygiene/lexical.rs +++ b/src/test/ui/hygiene/lexical.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass // ignore-pretty pretty-printing is unhygienic #![feature(decl_macro)] diff --git a/src/test/ui/hygiene/local_inner_macros.rs b/src/test/ui/hygiene/local_inner_macros.rs index f4c1a931f6..71ffcac40d 100644 --- a/src/test/ui/hygiene/local_inner_macros.rs +++ b/src/test/ui/hygiene/local_inner_macros.rs @@ -1,4 +1,4 @@ -// compile-pass +// check-pass // aux-build:local_inner_macros.rs extern crate local_inner_macros; diff --git a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr index e7ae7afa02..0fdb18d967 100644 --- a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr @@ -3,8 +3,6 @@ error: cannot find macro `print!` in this scope | LL | print!(); | ^^^^^ - | - = help: have you added the `#[macro_use]` on the module/import? error: aborting due to previous error diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index 737b375ed8..a89176fe69 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -13,7 +13,6 @@ error: cannot find macro `panic!` in this scope LL | assert_eq!(0, 0); | ^^^^^^^^^^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0599]: no method named `clone` found for type `()` in the current scope diff --git a/src/test/ui/hygiene/privacy-early.rs b/src/test/ui/hygiene/privacy-early.rs new file mode 100644 index 0000000000..58fc74d65a --- /dev/null +++ b/src/test/ui/hygiene/privacy-early.rs @@ -0,0 +1,17 @@ +// edition:2018 + +#![feature(decl_macro)] + +mod foo { + fn f() {} + macro f() {} + + pub macro m() { + use f as g; //~ ERROR `f` is private, and cannot be re-exported + f!(); + } +} + +fn main() { + foo::m!(); +} diff --git a/src/test/ui/hygiene/privacy-early.stderr b/src/test/ui/hygiene/privacy-early.stderr new file mode 100644 index 0000000000..60e50e05fc --- /dev/null +++ b/src/test/ui/hygiene/privacy-early.stderr @@ -0,0 +1,21 @@ +error[E0364]: `f` is private, and cannot be re-exported + --> $DIR/privacy-early.rs:10:13 + | +LL | use f as g; + | ^^^^^^ +... +LL | foo::m!(); + | ---------- in this macro invocation + | +note: consider marking `f` as `pub` in the imported module + --> $DIR/privacy-early.rs:10:13 + | +LL | use f as g; + | ^^^^^^ +... +LL | foo::m!(); + | ---------- in this macro invocation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0364`. diff --git a/src/test/ui/hygiene/rustc-macro-transparency.rs b/src/test/ui/hygiene/rustc-macro-transparency.rs new file mode 100644 index 0000000000..5f36993af2 --- /dev/null +++ b/src/test/ui/hygiene/rustc-macro-transparency.rs @@ -0,0 +1,31 @@ +#![feature(decl_macro, rustc_attrs)] + +#[rustc_macro_transparency = "transparent"] +macro transparent() { + struct Transparent; + let transparent = 0; +} +#[rustc_macro_transparency = "semitransparent"] +macro semitransparent() { + struct SemiTransparent; + let semitransparent = 0; +} +#[rustc_macro_transparency = "opaque"] +macro opaque() { + struct Opaque; + let opaque = 0; +} + +fn main() { + transparent!(); + semitransparent!(); + opaque!(); + + Transparent; // OK + SemiTransparent; // OK + Opaque; //~ ERROR cannot find value `Opaque` in this scope + + transparent; // OK + semitransparent; //~ ERROR expected value, found macro `semitransparent` + opaque; //~ ERROR expected value, found macro `opaque` +} diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr new file mode 100644 index 0000000000..5eacfdf8de --- /dev/null +++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr @@ -0,0 +1,22 @@ +error[E0425]: cannot find value `Opaque` in this scope + --> $DIR/rustc-macro-transparency.rs:26:5 + | +LL | Opaque; + | ^^^^^^ help: a local variable with a similar name exists: `opaque` + +error[E0423]: expected value, found macro `semitransparent` + --> $DIR/rustc-macro-transparency.rs:29:5 + | +LL | semitransparent; + | ^^^^^^^^^^^^^^^ help: use `!` to invoke the macro: `semitransparent!` + +error[E0423]: expected value, found macro `opaque` + --> $DIR/rustc-macro-transparency.rs:30:5 + | +LL | opaque; + | ^^^^^^ help: use `!` to invoke the macro: `opaque!` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0423, E0425. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/run-pass/hygiene/specialization.rs b/src/test/ui/hygiene/specialization.rs similarity index 100% rename from src/test/run-pass/hygiene/specialization.rs rename to src/test/ui/hygiene/specialization.rs diff --git a/src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs b/src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs new file mode 100644 index 0000000000..c8c5c72bf9 --- /dev/null +++ b/src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs @@ -0,0 +1,21 @@ +// check-pass +// aux-build:stdlib-prelude.rs + +#![feature(decl_macro)] +#![feature(prelude_import)] + +extern crate stdlib_prelude; + +#[prelude_import] +use stdlib_prelude::*; + +macro mac() { + mod m { + use std::mem; // OK (extern prelude) + stdlib_macro!(); // OK (stdlib prelude) + } +} + +mac!(); + +fn main() {} diff --git a/src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs new file mode 100644 index 0000000000..cf65de2bc2 --- /dev/null +++ b/src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(decl_macro)] + +macro mac() { + mod m { + fn f() { + std::mem::drop(0); // OK (extern prelude) + drop(0); // OK (stdlib prelude) + } + } +} + +mac!(); + +fn main() {} diff --git a/src/test/run-pass/hygiene/trait_items.rs b/src/test/ui/hygiene/trait_items-2.rs similarity index 95% rename from src/test/run-pass/hygiene/trait_items.rs rename to src/test/ui/hygiene/trait_items-2.rs index 680f228c98..39edfc37d6 100644 --- a/src/test/run-pass/hygiene/trait_items.rs +++ b/src/test/ui/hygiene/trait_items-2.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass // ignore-pretty pretty-printing is unhygienic #![feature(decl_macro)] diff --git a/src/test/ui/hygiene/transparent-basic.rs b/src/test/ui/hygiene/transparent-basic.rs index 0a86234fdb..bfa1713e4e 100644 --- a/src/test/ui/hygiene/transparent-basic.rs +++ b/src/test/ui/hygiene/transparent-basic.rs @@ -1,16 +1,16 @@ -// compile-pass +// check-pass // aux-build:transparent-basic.rs #![feature(decl_macro, rustc_attrs)] extern crate transparent_basic; -#[rustc_transparent_macro] +#[rustc_macro_transparency = "transparent"] macro binding() { let x = 10; } -#[rustc_transparent_macro] +#[rustc_macro_transparency = "transparent"] macro label() { break 'label } diff --git a/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs b/src/test/ui/hygiene/unpretty-debug.rs similarity index 50% rename from src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs rename to src/test/ui/hygiene/unpretty-debug.rs index ed3b48dbdc..6e936bb3d8 100644 --- a/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs +++ b/src/test/ui/hygiene/unpretty-debug.rs @@ -1,3 +1,9 @@ +// check-pass +// compile-flags: -Zunpretty=expanded,hygiene + +// Don't break whenever Symbol numbering changes +// normalize-stdout-test "\d+#" -> "0#" + // minimal junk #![feature(no_core)] #![no_core] diff --git a/src/test/ui/hygiene/unpretty-debug.stdout b/src/test/ui/hygiene/unpretty-debug.stdout new file mode 100644 index 0000000000..beac4c17ab --- /dev/null +++ b/src/test/ui/hygiene/unpretty-debug.stdout @@ -0,0 +1,15 @@ +// check-pass +// compile-flags: -Zunpretty=expanded,hygiene + +// Don't break whenever Symbol numbering changes +// normalize-stdout-test "\d+#" -> "0#" + +// minimal junk +#![feature /* 0#0 */(no_core)] +#![no_core /* 0#0 */] + +macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } } + +fn bar /* 0#0 */() { let x /* 0#0 */ = 1; y /* 0#1 */ + x /* 0#0 */ } + +fn y /* 0#0 */() { } diff --git a/src/test/run-pass/hygiene/wrap_unhygienic_example.rs b/src/test/ui/hygiene/wrap_unhygienic_example.rs similarity index 98% rename from src/test/run-pass/hygiene/wrap_unhygienic_example.rs rename to src/test/ui/hygiene/wrap_unhygienic_example.rs index e0277e2bb7..50c6b35ab1 100644 --- a/src/test/run-pass/hygiene/wrap_unhygienic_example.rs +++ b/src/test/ui/hygiene/wrap_unhygienic_example.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass // ignore-pretty pretty-printing is unhygienic // aux-build:my_crate.rs diff --git a/src/test/run-pass/hygiene/xcrate.rs b/src/test/ui/hygiene/xcrate.rs similarity index 100% rename from src/test/run-pass/hygiene/xcrate.rs rename to src/test/ui/hygiene/xcrate.rs diff --git a/src/test/run-pass/if-bot.rs b/src/test/ui/if-bot.rs similarity index 87% rename from src/test/run-pass/if-bot.rs rename to src/test/ui/if-bot.rs index 6d87288dd0..0f09db530d 100644 --- a/src/test/run-pass/if-bot.rs +++ b/src/test/ui/if-bot.rs @@ -1,3 +1,5 @@ +// run-pass + pub fn main() { let i: isize = if false { panic!() } else { 5 }; println!("{}", i); diff --git a/src/test/run-pass/if-check.rs b/src/test/ui/if-check.rs similarity index 95% rename from src/test/run-pass/if-check.rs rename to src/test/ui/if-check.rs index 43904f6823..6593225e7d 100644 --- a/src/test/run-pass/if-check.rs +++ b/src/test/ui/if-check.rs @@ -1,3 +1,5 @@ +// run-pass + fn even(x: usize) -> bool { if x < 2 { return false; diff --git a/src/test/run-pass/if-ret.rs b/src/test/ui/if-ret.rs similarity index 89% rename from src/test/run-pass/if-ret.rs rename to src/test/ui/if-ret.rs index 3c2377466a..e1e795d83b 100644 --- a/src/test/run-pass/if-ret.rs +++ b/src/test/ui/if-ret.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_parens)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/if/if-let.rs b/src/test/ui/if/if-let.rs index 741685fe9b..3447f358d8 100644 --- a/src/test/ui/if/if-let.rs +++ b/src/test/ui/if/if-let.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn macros() { macro_rules! foo{ diff --git a/src/test/ui/if/if-let.stderr b/src/test/ui/if/if-let.stderr index 04bca1b76a..f105098b74 100644 --- a/src/test/ui/if/if-let.stderr +++ b/src/test/ui/if/if-let.stderr @@ -9,7 +9,7 @@ LL | | println!("irrefutable pattern"); LL | | }); | |_______- in this macro invocation | - = note: #[warn(irrefutable_let_patterns)] on by default + = note: `#[warn(irrefutable_let_patterns)]` on by default warning: irrefutable if-let pattern --> $DIR/if-let.rs:6:13 diff --git a/src/test/ui/if/if-no-match-bindings.rs b/src/test/ui/if/if-no-match-bindings.rs index 581ce18c1d..ca3df0fdde 100644 --- a/src/test/ui/if/if-no-match-bindings.rs +++ b/src/test/ui/if/if-no-match-bindings.rs @@ -19,4 +19,10 @@ fn main() { if b_mut_ref() {} //~ ERROR mismatched types [E0308] if &true {} //~ ERROR mismatched types [E0308] if &mut true {} //~ ERROR mismatched types [E0308] + + // This is also NOT: + while b_ref() {} //~ ERROR mismatched types [E0308] + while b_mut_ref() {} //~ ERROR mismatched types [E0308] + while &true {} //~ ERROR mismatched types [E0308] + while &mut true {} //~ ERROR mismatched types [E0308] } diff --git a/src/test/ui/if/if-no-match-bindings.stderr b/src/test/ui/if/if-no-match-bindings.stderr index 7b0b472121..cbf52476ae 100644 --- a/src/test/ui/if/if-no-match-bindings.stderr +++ b/src/test/ui/if/if-no-match-bindings.stderr @@ -34,6 +34,42 @@ LL | if &mut true {} = note: expected type `bool` found type `&mut bool` -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:24:11 + | +LL | while b_ref() {} + | ^^^^^^^ expected bool, found &bool + | + = note: expected type `bool` + found type `&bool` + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:25:11 + | +LL | while b_mut_ref() {} + | ^^^^^^^^^^^ expected bool, found &mut bool + | + = note: expected type `bool` + found type `&mut bool` + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:26:11 + | +LL | while &true {} + | ^^^^^ expected bool, found &bool + | + = note: expected type `bool` + found type `&bool` + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:27:11 + | +LL | while &mut true {} + | ^^^^^^^^^ expected bool, found &mut bool + | + = note: expected type `bool` + found type `&mut bool` + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/if/ifmt-bad-arg.rs b/src/test/ui/if/ifmt-bad-arg.rs index a57221af91..ba897f171a 100644 --- a/src/test/ui/if/ifmt-bad-arg.rs +++ b/src/test/ui/if/ifmt-bad-arg.rs @@ -38,7 +38,7 @@ fn main() { format!("{} {}", 1, 2, foo=1, bar=2); //~ ERROR: multiple unused formatting arguments format!("{foo}", foo=1, foo=2); //~ ERROR: duplicate argument - format!("", foo=1, 2); //~ ERROR: positional arguments cannot follow + format!("{foo} {} {}", foo=1, 2); //~ ERROR: positional arguments cannot follow // bad named arguments, #35082 @@ -75,4 +75,15 @@ ninth number: { tenth number: {}", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); //~^^ ERROR: invalid format string + println!("{} {:.*} {}", 1, 3.2, 4); + //~^ ERROR 4 positional arguments in format string, but there are 3 arguments + //~| ERROR mismatched types + println!("{} {:07$.*} {}", 1, 3.2, 4); + //~^ ERROR 4 positional arguments in format string, but there are 3 arguments + //~| ERROR mismatched types + println!("{} {:07$} {}", 1, 3.2, 4); + //~^ ERROR invalid reference to positional argument 7 (there are 3 arguments) + println!("{:foo}", 1); //~ ERROR unknown format trait `foo` + println!("{5} {:4$} {6:7$}", 1); + //~^ ERROR invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument) } diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr index 65be86eaf2..336ea2254b 100644 --- a/src/test/ui/if/ifmt-bad-arg.stderr +++ b/src/test/ui/if/ifmt-bad-arg.stderr @@ -146,11 +146,13 @@ note: previously here LL | format!("{foo}", foo=1, foo=2); | ^ -error: expected ident, positional arguments cannot follow named arguments - --> $DIR/ifmt-bad-arg.rs:41:24 +error: positional arguments cannot follow named arguments + --> $DIR/ifmt-bad-arg.rs:41:35 | -LL | format!("", foo=1, 2); - | ^ +LL | format!("{foo} {} {}", foo=1, 2); + | - ^ positional arguments must be before named arguments + | | + | named argument error: there is no argument named `valueb` --> $DIR/ifmt-bad-arg.rs:45:23 @@ -218,5 +220,87 @@ LL | tenth number: {}", | = note: if you intended to print `{`, you can escape it using `{{` -error: aborting due to 28 previous errors +error: 4 positional arguments in format string, but there are 3 arguments + --> $DIR/ifmt-bad-arg.rs:78:15 + | +LL | println!("{} {:.*} {}", 1, 3.2, 4); + | ^^ ^^--^ ^^ --- this parameter corresponds to the precision flag + | | + | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: 4 positional arguments in format string, but there are 3 arguments + --> $DIR/ifmt-bad-arg.rs:81:15 + | +LL | println!("{} {:07$.*} {}", 1, 3.2, 4); + | ^^ ^^^----^ ^^ --- this parameter corresponds to the precision flag + | | | + | | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected + | this width flag expects an `usize` argument at position 7, but there are 3 arguments + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: invalid reference to positional argument 7 (there are 3 arguments) + --> $DIR/ifmt-bad-arg.rs:84:18 + | +LL | println!("{} {:07$} {}", 1, 3.2, 4); + | ^^^--^ + | | + | this width flag expects an `usize` argument at position 7, but there are 3 arguments + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error: unknown format trait `foo` + --> $DIR/ifmt-bad-arg.rs:86:24 + | +LL | println!("{:foo}", 1); + | ^ + | + = note: the only appropriate formatting traits are: + - ``, which uses the `Display` trait + - `?`, which uses the `Debug` trait + - `e`, which uses the `LowerExp` trait + - `E`, which uses the `UpperExp` trait + - `o`, which uses the `Octal` trait + - `p`, which uses the `Pointer` trait + - `b`, which uses the `Binary` trait + - `x`, which uses the `LowerHex` trait + - `X`, which uses the `UpperHex` trait + +error: invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument) + --> $DIR/ifmt-bad-arg.rs:87:15 + | +LL | println!("{5} {:4$} {6:7$}", 1); + | ^^^ ^^--^ ^^^--^ + | | | + | | this width flag expects an `usize` argument at position 7, but there is 1 argument + | this width flag expects an `usize` argument at position 4, but there is 1 argument + | + = note: positional arguments are zero-based + = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html + +error[E0308]: mismatched types + --> $DIR/ifmt-bad-arg.rs:78:32 + | +LL | println!("{} {:.*} {}", 1, 3.2, 4); + | ^^^ expected usize, found floating-point number + | + = note: expected type `&usize` + found type `&{float}` + +error[E0308]: mismatched types + --> $DIR/ifmt-bad-arg.rs:81:35 + | +LL | println!("{} {:07$.*} {}", 1, 3.2, 4); + | ^^^ expected usize, found floating-point number + | + = note: expected type `&usize` + found type `&{float}` + +error: aborting due to 35 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/if/ifmt-unknown-trait.stderr b/src/test/ui/if/ifmt-unknown-trait.stderr index 9ea367c81e..7853b5ca0c 100644 --- a/src/test/ui/if/ifmt-unknown-trait.stderr +++ b/src/test/ui/if/ifmt-unknown-trait.stderr @@ -3,6 +3,17 @@ error: unknown format trait `notimplemented` | LL | format!("{:notimplemented}", "3"); | ^^^ + | + = note: the only appropriate formatting traits are: + - ``, which uses the `Display` trait + - `?`, which uses the `Debug` trait + - `e`, which uses the `LowerExp` trait + - `E`, which uses the `UpperExp` trait + - `o`, which uses the `Octal` trait + - `p`, which uses the `Pointer` trait + - `b`, which uses the `Binary` trait + - `x`, which uses the `LowerHex` trait + - `X`, which uses the `UpperHex` trait error: aborting due to previous error diff --git a/src/test/run-pass/ifmt.rs b/src/test/ui/ifmt.rs similarity index 99% rename from src/test/run-pass/ifmt.rs rename to src/test/ui/ifmt.rs index 6660f393f7..841be20ef8 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/ui/ifmt.rs @@ -1,3 +1,5 @@ +// run-pass + #![deny(warnings)] #![allow(unused_must_use)] #![allow(unused_features)] diff --git a/src/test/run-pass/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs similarity index 98% rename from src/test/run-pass/ignore-all-the-things.rs rename to src/test/ui/ignore-all-the-things.rs index 6916a199a1..8c046a289f 100644 --- a/src/test/run-pass/ignore-all-the-things.rs +++ b/src/test/ui/ignore-all-the-things.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_shorthand_field_patterns)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/run-pass/impl-for-never.rs b/src/test/ui/impl-for-never.rs similarity index 97% rename from src/test/run-pass/impl-for-never.rs rename to src/test/ui/impl-for-never.rs index a528712300..c5f12981ec 100644 --- a/src/test/run-pass/impl-for-never.rs +++ b/src/test/ui/impl-for-never.rs @@ -1,3 +1,4 @@ +// run-pass // Test that we can call static methods on ! both directly and when it appears in a generic #![feature(never_type)] diff --git a/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs b/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs index 20d778d20a..9d7b2f2d08 100644 --- a/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs +++ b/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Foo<'a>(&'a u8); diff --git a/src/test/run-pass/impl-inherent-non-conflict.rs b/src/test/ui/impl-inherent-non-conflict.rs similarity index 97% rename from src/test/run-pass/impl-inherent-non-conflict.rs rename to src/test/ui/impl-inherent-non-conflict.rs index ed87ffb019..be524f87c9 100644 --- a/src/test/run-pass/impl-inherent-non-conflict.rs +++ b/src/test/ui/impl-inherent-non-conflict.rs @@ -1,3 +1,4 @@ +// run-pass // Ensure that a user-defined type admits multiple inherent methods // with the same name, which can be called on values that have a // precise enough type to allow distinguishing between the methods. diff --git a/src/test/run-pass/impl-not-adjacent-to-type.rs b/src/test/ui/impl-not-adjacent-to-type.rs similarity index 93% rename from src/test/run-pass/impl-not-adjacent-to-type.rs rename to src/test/ui/impl-not-adjacent-to-type.rs index c0cdff30cb..97caf90838 100644 --- a/src/test/run-pass/impl-not-adjacent-to-type.rs +++ b/src/test/ui/impl-not-adjacent-to-type.rs @@ -1,3 +1,5 @@ +// run-pass + mod foo { pub struct Point { pub x: i32, diff --git a/src/test/run-pass/impl-privacy-xc-1.rs b/src/test/ui/impl-privacy-xc-1.rs similarity index 93% rename from src/test/run-pass/impl-privacy-xc-1.rs rename to src/test/ui/impl-privacy-xc-1.rs index 42e149eacb..c9f7f09c7b 100644 --- a/src/test/run-pass/impl-privacy-xc-1.rs +++ b/src/test/ui/impl-privacy-xc-1.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:impl_privacy_xc_1.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/impl-privacy-xc-2.rs b/src/test/ui/impl-privacy-xc-2.rs similarity index 95% rename from src/test/run-pass/impl-privacy-xc-2.rs rename to src/test/ui/impl-privacy-xc-2.rs index 7cdd7146c3..390764588f 100644 --- a/src/test/run-pass/impl-privacy-xc-2.rs +++ b/src/test/ui/impl-privacy-xc-2.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:impl_privacy_xc_2.rs extern crate impl_privacy_xc_2; diff --git a/src/test/run-pass/impl-trait-in-bindings.rs b/src/test/ui/impl-trait-in-bindings.rs similarity index 98% rename from src/test/run-pass/impl-trait-in-bindings.rs rename to src/test/ui/impl-trait-in-bindings.rs index 1e3a641b7c..2e9b6cd5c7 100644 --- a/src/test/run-pass/impl-trait-in-bindings.rs +++ b/src/test/ui/impl-trait-in-bindings.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(impl_trait_in_bindings)] //~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash diff --git a/src/test/run-pass/impl-trait-in-bindings.stderr b/src/test/ui/impl-trait-in-bindings.stderr similarity index 63% rename from src/test/run-pass/impl-trait-in-bindings.stderr rename to src/test/ui/impl-trait-in-bindings.stderr index 4896deb9d5..629089d8c5 100644 --- a/src/test/run-pass/impl-trait-in-bindings.stderr +++ b/src/test/ui/impl-trait-in-bindings.stderr @@ -1,6 +1,8 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/impl-trait-in-bindings.rs:1:12 + --> $DIR/impl-trait-in-bindings.rs:3:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default diff --git a/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs b/src/test/ui/impl-trait/associated-impl-trait-type-generic-trait.rs similarity index 72% rename from src/test/ui/impl-trait/associated-existential-type-generic-trait.rs rename to src/test/ui/impl-trait/associated-impl-trait-type-generic-trait.rs index 26bd435cba..6c7c46b0e3 100644 --- a/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs +++ b/src/test/ui/impl-trait/associated-impl-trait-type-generic-trait.rs @@ -1,5 +1,5 @@ -#![feature(existential_type)] -// compile-pass +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy(U); @@ -11,7 +11,7 @@ trait Foo { } impl Foo for i32 { - existential type Assoc: Bar; + type Assoc = impl Bar; fn foo(w: W) -> Self::Assoc { Dummy(w) } @@ -21,7 +21,7 @@ struct NonGeneric; impl Bar for NonGeneric {} impl Foo for u32 { - existential type Assoc: Bar; + type Assoc = impl Bar; fn foo(_: W) -> Self::Assoc { NonGeneric } diff --git a/src/test/ui/impl-trait/associated-existential-type-trivial.rs b/src/test/ui/impl-trait/associated-impl-trait-type-trivial.rs similarity index 64% rename from src/test/ui/impl-trait/associated-existential-type-trivial.rs rename to src/test/ui/impl-trait/associated-impl-trait-type-trivial.rs index cc974ffea7..cdda341cad 100644 --- a/src/test/ui/impl-trait/associated-existential-type-trivial.rs +++ b/src/test/ui/impl-trait/associated-impl-trait-type-trivial.rs @@ -1,5 +1,5 @@ -#![feature(existential_type)] -// compile-pass +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy; @@ -11,7 +11,7 @@ trait Foo { } impl Foo for i32 { - existential type Assoc: Bar; + type Assoc = impl Bar; fn foo() -> Self::Assoc { Dummy } diff --git a/src/test/ui/impl-trait/associated-existential-type.rs b/src/test/ui/impl-trait/associated-impl-trait-type.rs similarity index 71% rename from src/test/ui/impl-trait/associated-existential-type.rs rename to src/test/ui/impl-trait/associated-impl-trait-type.rs index 38511bd062..d0661d66f4 100644 --- a/src/test/ui/impl-trait/associated-existential-type.rs +++ b/src/test/ui/impl-trait/associated-impl-trait-type.rs @@ -1,5 +1,5 @@ -#![feature(existential_type)] -// compile-pass +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy; @@ -12,7 +12,7 @@ trait Foo { } impl Foo for i32 { - existential type Assoc: Bar; + type Assoc = impl Bar; fn foo() -> Self::Assoc { Dummy } diff --git a/src/test/run-pass/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak-rpass.rs similarity index 100% rename from src/test/run-pass/impl-trait/auto-trait-leak.rs rename to src/test/ui/impl-trait/auto-trait-leak-rpass.rs diff --git a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/ui/impl-trait/auxiliary/xcrate.rs similarity index 100% rename from src/test/run-pass/impl-trait/auxiliary/xcrate.rs rename to src/test/ui/impl-trait/auxiliary/xcrate.rs diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr index d0a6a4ee57..ad108173a7 100644 --- a/src/test/ui/impl-trait/bindings-opaque.stderr +++ b/src/test/ui/impl-trait/bindings-opaque.stderr @@ -3,6 +3,8 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the co | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope --> $DIR/bindings-opaque.rs:11:17 diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index c66836ab8e..e938595519 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -1,9 +1,3 @@ -warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/bindings.rs:1:12 - | -LL | #![feature(impl_trait_in_bindings)] - | ^^^^^^^^^^^^^^^^^^^^^^ - error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:5:29 | @@ -28,6 +22,14 @@ error[E0435]: attempt to use a non-constant value in a constant LL | const foo: impl Clone = x; | ^ non-constant value +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bindings.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs new file mode 100644 index 0000000000..c33261bfd0 --- /dev/null +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -0,0 +1,52 @@ +// compile-fail +// edition:2018 + +#![feature(async_await)] +#![feature(impl_trait_in_bindings)] +//~^ WARNING the feature `impl_trait_in_bindings` is incomplete + +// See issue 60414 + +///////////////////////////////////////////// +// Reduction to `impl Trait` + +struct Foo(T); + +trait FooLike { type Output; } + +impl FooLike for Foo { + type Output = T; +} + +mod impl_trait { + use super::*; + + trait Trait { + type Assoc; + } + + /// `T::Assoc` can't be normalized any further here. + fn foo_fail() -> impl FooLike { + //~^ ERROR: type mismatch + Foo(()) + } +} + +///////////////////////////////////////////// +// Same with lifetimes in the trait + +mod lifetimes { + use super::*; + + trait Trait<'a> { + type Assoc; + } + + /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. + fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { + //~^ ERROR: type mismatch + Foo(()) + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr new file mode 100644 index 0000000000..aa306a7e08 --- /dev/null +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -0,0 +1,31 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bound-normalization-fail.rs:5:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` + --> $DIR/bound-normalization-fail.rs:29:32 + | +LL | fn foo_fail() -> impl FooLike { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type + | + = note: expected type `()` + found type `::Assoc` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` + --> $DIR/bound-normalization-fail.rs:46:41 + | +LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type + | + = note: expected type `()` + found type `>::Assoc` + = note: the return type of a function must have a statically known size + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/impl-trait/bound-normalization-pass.rs b/src/test/ui/impl-trait/bound-normalization-pass.rs new file mode 100644 index 0000000000..5b634e3106 --- /dev/null +++ b/src/test/ui/impl-trait/bound-normalization-pass.rs @@ -0,0 +1,109 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] +#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] +//~^ WARNING the feature `impl_trait_in_bindings` is incomplete + +// See issue 60414 + +///////////////////////////////////////////// +// Reduction to `impl Trait` + +struct Foo(T); + +trait FooLike { type Output; } + +impl FooLike for Foo { + type Output = T; +} + +mod impl_trait { + use super::*; + + trait Trait { + type Assoc; + } + + /// `T::Assoc` should be normalized to `()` here. + fn foo_pass>() -> impl FooLike { + Foo(()) + } +} + +///////////////////////////////////////////// +// Same with lifetimes in the trait + +mod lifetimes { + use super::*; + + trait Trait<'a> { + type Assoc; + } + + /// Like above. + /// + /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here + fn foo2_pass<'a, T: Trait<'a, Assoc=()> + 'a>( + ) -> impl FooLike>::Assoc> + 'a { + Foo(()) + } + + /// Normalization to type containing bound region. + /// + /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here + fn foo2_pass2<'a, T: Trait<'a, Assoc=&'a ()> + 'a>( + ) -> impl FooLike>::Assoc> + 'a { + Foo(&()) + } +} + +///////////////////////////////////////////// +// Reduction using `impl Trait` in bindings + +mod impl_trait_in_bindings { + struct Foo; + + trait FooLike { type Output; } + + impl FooLike for Foo { + type Output = u32; + } + + trait Trait { + type Assoc; + } + + fn foo>() { + let _: impl FooLike = Foo; + } +} + +///////////////////////////////////////////// +// The same applied to `type Foo = impl Bar`s + +mod opaque_types { + trait Implemented { + type Assoc; + } + impl Implemented for T { + type Assoc = u8; + } + + trait Trait { + type Out; + } + + impl Trait for () { + type Out = u8; + } + + type Ex = impl Trait::Assoc>; + + fn define() -> Ex { + () + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/bound-normalization-pass.stderr b/src/test/ui/impl-trait/bound-normalization-pass.stderr new file mode 100644 index 0000000000..229acdb2b1 --- /dev/null +++ b/src/test/ui/impl-trait/bound-normalization-pass.stderr @@ -0,0 +1,8 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bound-normalization-pass.rs:6:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + diff --git a/src/test/run-pass/impl-trait/bounds_regression.rs b/src/test/ui/impl-trait/bounds_regression.rs similarity index 100% rename from src/test/run-pass/impl-trait/bounds_regression.rs rename to src/test/ui/impl-trait/bounds_regression.rs diff --git a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs index 90a7519074..7ae1ac4f57 100644 --- a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs +++ b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs @@ -10,7 +10,7 @@ // concrete type against the bound, which forces the return type to be // `&'static i32` here. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn make_identity() -> impl Sized { |x: &'static i32| x diff --git a/src/test/ui/impl-trait/deprecated_annotation.rs b/src/test/ui/impl-trait/deprecated_annotation.rs index dd9f5fd464..f76724c8ab 100644 --- a/src/test/ui/impl-trait/deprecated_annotation.rs +++ b/src/test/ui/impl-trait/deprecated_annotation.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(warnings)] diff --git a/src/test/run-pass/impl-trait/equality.rs b/src/test/ui/impl-trait/equality-rpass.rs similarity index 100% rename from src/test/run-pass/impl-trait/equality.rs rename to src/test/ui/impl-trait/equality-rpass.rs diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/ui/impl-trait/example-calendar.rs similarity index 100% rename from src/test/run-pass/impl-trait/example-calendar.rs rename to src/test/ui/impl-trait/example-calendar.rs diff --git a/src/test/run-pass/impl-trait/example-st.rs b/src/test/ui/impl-trait/example-st.rs similarity index 100% rename from src/test/run-pass/impl-trait/example-st.rs rename to src/test/ui/impl-trait/example-st.rs diff --git a/src/test/ui/impl-trait/existential_type_in_fn_body.rs b/src/test/ui/impl-trait/existential_type_in_fn_body.rs deleted file mode 100644 index b29ae064b7..0000000000 --- a/src/test/ui/impl-trait/existential_type_in_fn_body.rs +++ /dev/null @@ -1,12 +0,0 @@ -// compile-pass - -#![feature(existential_type)] - -use std::fmt::Debug; - -fn main() { - existential type Existential: Debug; - - fn f() -> Existential {} - println!("{:?}", f()); -} diff --git a/src/test/ui/impl-trait/issue-55872-1.rs b/src/test/ui/impl-trait/issue-55872-1.rs new file mode 100644 index 0000000000..f99096b4d5 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-1.rs @@ -0,0 +1,22 @@ +// ignore-tidy-linelength +#![feature(type_alias_impl_trait)] + +pub trait Bar +{ + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + type E = impl Copy; + //~^ ERROR the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` [E0277] + //~^^ ERROR the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` [E0277] + + fn foo() -> Self::E { + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + (S::default(), T::default()) + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr new file mode 100644 index 0000000000..d5756c0155 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` + --> $DIR/issue-55872-1.rs:12:5 + | +LL | type E = impl Copy; + | ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S` + | + = help: consider adding a `where S: std::marker::Copy` bound + = note: required because it appears within the type `(S, T)` + = note: the return type of a function must have a statically known size + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` + --> $DIR/issue-55872-1.rs:12:5 + | +LL | type E = impl Copy; + | ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T` + | + = help: consider adding a `where T: std::marker::Copy` bound + = note: required because it appears within the type `(S, T)` + = note: the return type of a function must have a statically known size + +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872-1.rs:16:37 + | +LL | fn foo() -> Self::E { + | _____________________________________^ +LL | | +LL | | (S::default(), T::default()) +LL | | } + | |_____^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs new file mode 100644 index 0000000000..dfee20ca64 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -0,0 +1,20 @@ +// edition:2018 +// ignore-tidy-linelength +#![feature(async_await, type_alias_impl_trait)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + type E = impl Copy; + //~^ ERROR the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied [E0277] + fn foo() -> Self::E { + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + async {} + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr new file mode 100644 index 0000000000..676c3fe3d4 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied + --> $DIR/issue-55872-2.rs:12:5 + | +LL | type E = impl Copy; + | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` + | + = note: the return type of a function must have a statically known size + +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872-2.rs:14:28 + | +LL | fn foo() -> Self::E { + | ____________________________^ +LL | | +LL | | async {} +LL | | } + | |_____^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872.rs b/src/test/ui/impl-trait/issue-55872.rs new file mode 100644 index 0000000000..bc91aae70c --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872.rs @@ -0,0 +1,19 @@ +// ignore-tidy-linelength +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + type E = impl Copy; + + fn foo() -> Self::E { + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + || () + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872.stderr b/src/test/ui/impl-trait/issue-55872.stderr new file mode 100644 index 0000000000..60654ec346 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872.stderr @@ -0,0 +1,12 @@ +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872.rs:13:28 + | +LL | fn foo() -> Self::E { + | ____________________________^ +LL | | +LL | | || () +LL | | } + | |_____^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr index fb48ecd12b..d10001e8a8 100644 --- a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr +++ b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr @@ -2,7 +2,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/infinite-impl-trait-issue-38064.rs:8:13 | LL | fn foo() -> impl Quux { - | ^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^ expands to a recursive type | = note: expanded type is `foo::Foo>` @@ -10,7 +10,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/infinite-impl-trait-issue-38064.rs:14:13 | LL | fn bar() -> impl Quux { - | ^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^ expands to a recursive type | = note: expanded type is `bar::Bar>` diff --git a/src/test/ui/impl-trait/issues/issue-42479.rs b/src/test/ui/impl-trait/issues/issue-42479.rs index 2da15ac5b6..7d69cd0a30 100644 --- a/src/test/ui/impl-trait/issues/issue-42479.rs +++ b/src/test/ui/impl-trait/issues/issue-42479.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::iter::once; diff --git a/src/test/ui/impl-trait/issues/issue-49376.rs b/src/test/ui/impl-trait/issues/issue-49376.rs index 13671b8dbf..12e69b16ad 100644 --- a/src/test/ui/impl-trait/issues/issue-49376.rs +++ b/src/test/ui/impl-trait/issues/issue-49376.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests for nested self-reference which caused a stack overflow. diff --git a/src/test/ui/impl-trait/issues/issue-52128.rs b/src/test/ui/impl-trait/issues/issue-52128.rs index eb4456a0d5..ac26c10e55 100644 --- a/src/test/ui/impl-trait/issues/issue-52128.rs +++ b/src/test/ui/impl-trait/issues/issue-52128.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(warnings)] diff --git a/src/test/ui/impl-trait/issues/issue-53457.rs b/src/test/ui/impl-trait/issues/issue-53457.rs index 3f6a4fb278..de8c579743 100644 --- a/src/test/ui/impl-trait/issues/issue-53457.rs +++ b/src/test/ui/impl-trait/issues/issue-53457.rs @@ -1,8 +1,8 @@ // run-pass -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] -existential type X: Clone; +type X = impl Clone; fn bar(f: F) -> F { f diff --git a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs index 50646edd61..0c07101bb7 100644 --- a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs +++ b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs @@ -1,7 +1,7 @@ // This used to ICE because it creates an `impl Trait` that captures a // hidden empty region. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn server() -> impl FilterBase2 { segment2(|| { loop { } }).map2(|| "") diff --git a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs index 11f1a39223..ed066ce192 100644 --- a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs +++ b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs @@ -5,7 +5,7 @@ // opaque type. As all regions are now required to outlive the bound in an // opaque type we avoid the issue here. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct A(F); diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/ui/impl-trait/lifetimes.rs similarity index 100% rename from src/test/run-pass/impl-trait/lifetimes.rs rename to src/test/ui/impl-trait/lifetimes.rs diff --git a/src/test/ui/impl-trait/multiple-lifetimes.rs b/src/test/ui/impl-trait/multiple-lifetimes.rs index 8346542135..92e5ea2f49 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes.rs @@ -1,5 +1,5 @@ // Test that multiple liftimes are allowed in impl trait types. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait X<'x>: Sized {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs index 61e858ee02..b226cf058a 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs @@ -1,14 +1,14 @@ // compile-flags:-Zborrowck=mir #![feature(member_constraints)] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] #[derive(Clone)] struct CopyIfEq(T, U); impl Copy for CopyIfEq {} -existential type E<'a, 'b>: Sized; +type E<'a, 'b> = impl Sized; fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { //~^ ERROR lifetime may not live long enough diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr index b59dfbe9f2..f27e6ff44a 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr @@ -5,7 +5,7 @@ LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- lifetime `'a` defined here ^^^^^^^^^ opaque type requires that `'a` must outlive `'static` help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint | -LL | existential type E<'a, 'b>: Sized; + 'a +LL | type E<'a, 'b> = impl Sized; + 'a | error: aborting due to previous error diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs index 5f48477340..553dea7aa6 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs @@ -1,5 +1,5 @@ // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs similarity index 88% rename from src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs rename to src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs index c17ae6f051..877940c740 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs @@ -1,10 +1,10 @@ // edition:2018 -// compile-pass +// check-pass // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir #![feature(member_constraints)] -#![feature(existential_type)] +#![feature(type_alias_impl_trait)] trait Trait<'a, 'b> { } impl Trait<'_, '_> for T { } @@ -12,7 +12,7 @@ impl Trait<'_, '_> for T { } // Here we wind up selecting `'a` and `'b` in the hidden type because // those are the types that appear in the original values. -existential type Foo<'a, 'b>: Trait<'a, 'b>; +type Foo<'a, 'b> = impl Trait<'a, 'b>; fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> { // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs index 31891ef15c..c0930ec594 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs @@ -1,5 +1,5 @@ // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs index 29c997085d..ed36bda7db 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs @@ -1,5 +1,5 @@ // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir diff --git a/src/test/run-pass/impl-trait/nesting.rs b/src/test/ui/impl-trait/nesting.rs similarity index 100% rename from src/test/run-pass/impl-trait/nesting.rs rename to src/test/ui/impl-trait/nesting.rs diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type.stderr index fce234eb87..324607117d 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type.stderr +++ b/src/test/ui/impl-trait/recursive-impl-trait-type.stderr @@ -2,7 +2,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:6:22 | LL | fn option(i: i32) -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `std::option::Option<(impl Sized, i32)>` @@ -10,7 +10,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:14:15 | LL | fn tuple() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `(impl Sized,)` @@ -18,7 +18,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:18:15 | LL | fn array() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[impl Sized; 1]` @@ -26,7 +26,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:22:13 | LL | fn ptr() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `*const impl Sized` @@ -34,7 +34,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:26:16 | LL | fn fn_ptr() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `fn() -> impl Sized` @@ -42,7 +42,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:30:25 | LL | fn closure_capture() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[closure@$DIR/recursive-impl-trait-type.rs:32:5: 32:19 x:impl Sized]` @@ -50,7 +50,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:35:29 | LL | fn closure_ref_capture() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[closure@$DIR/recursive-impl-trait-type.rs:37:5: 37:20 x:impl Sized]` @@ -58,7 +58,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:40:21 | LL | fn closure_sig() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[closure@$DIR/recursive-impl-trait-type.rs:41:5: 41:21]` @@ -66,7 +66,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:44:23 | LL | fn generator_sig() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[closure@$DIR/recursive-impl-trait-type.rs:45:5: 45:23]` @@ -74,7 +74,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:48:27 | LL | fn generator_capture() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[generator@$DIR/recursive-impl-trait-type.rs:50:5: 50:26 x:impl Sized {()}]` @@ -82,7 +82,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:53:26 | LL | fn substs_change() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `(impl Sized,)` @@ -90,7 +90,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:57:24 | LL | fn generator_hold() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: expanded type is `[generator@$DIR/recursive-impl-trait-type.rs:58:5: 62:6 {impl Sized, ()}]` @@ -98,7 +98,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:69:26 | LL | fn mutual_recursion() -> impl Sync { - | ^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^ expands to a recursive type | = note: type resolves to itself @@ -106,7 +106,7 @@ error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type.rs:73:28 | LL | fn mutual_recursion_b() -> impl Sized { - | ^^^^^^^^^^ expands to self-referential type + | ^^^^^^^^^^ expands to a recursive type | = note: type resolves to itself diff --git a/src/test/ui/impl-trait/existential-minimal.rs b/src/test/ui/impl-trait/return-position-impl-trait-minimal.rs similarity index 53% rename from src/test/ui/impl-trait/existential-minimal.rs rename to src/test/ui/impl-trait/return-position-impl-trait-minimal.rs index c93c6a499b..6d3c069297 100644 --- a/src/test/ui/impl-trait/existential-minimal.rs +++ b/src/test/ui/impl-trait/return-position-impl-trait-minimal.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs b/src/test/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs new file mode 100644 index 0000000000..91be4efd56 --- /dev/null +++ b/src/test/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() { + type Existential = impl Debug; + + fn f() -> Existential {} + println!("{:?}", f()); +} diff --git a/src/test/run-pass/impl-trait/universal_hrtb_anon.rs b/src/test/ui/impl-trait/universal_hrtb_anon.rs similarity index 100% rename from src/test/run-pass/impl-trait/universal_hrtb_anon.rs rename to src/test/ui/impl-trait/universal_hrtb_anon.rs diff --git a/src/test/run-pass/impl-trait/universal_hrtb_named.rs b/src/test/ui/impl-trait/universal_hrtb_named.rs similarity index 100% rename from src/test/run-pass/impl-trait/universal_hrtb_named.rs rename to src/test/ui/impl-trait/universal_hrtb_named.rs diff --git a/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs b/src/test/ui/impl-trait/universal_in_adt_in_parameters.rs similarity index 100% rename from src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs rename to src/test/ui/impl-trait/universal_in_adt_in_parameters.rs diff --git a/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs b/src/test/ui/impl-trait/universal_in_impl_trait_in_parameters.rs similarity index 100% rename from src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs rename to src/test/ui/impl-trait/universal_in_impl_trait_in_parameters.rs diff --git a/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs b/src/test/ui/impl-trait/universal_in_trait_defn_parameters.rs similarity index 100% rename from src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs rename to src/test/ui/impl-trait/universal_in_trait_defn_parameters.rs diff --git a/src/test/run-pass/impl-trait/universal_multiple_bounds.rs b/src/test/ui/impl-trait/universal_multiple_bounds.rs similarity index 100% rename from src/test/run-pass/impl-trait/universal_multiple_bounds.rs rename to src/test/ui/impl-trait/universal_multiple_bounds.rs diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.rs b/src/test/ui/impl-trait/universal_wrong_bounds.rs index 56a13ea257..2182506c7b 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.rs +++ b/src/test/ui/impl-trait/universal_wrong_bounds.rs @@ -6,9 +6,8 @@ fn foo(f: impl Display + Clone) -> String { wants_clone(f); } -fn wants_debug(g: impl Debug) { } //~ ERROR cannot find -fn wants_display(g: impl Debug) { } //~ ERROR cannot find +fn wants_debug(g: impl Debug) { } //~ ERROR expected trait, found derive macro `Debug` +fn wants_display(g: impl Debug) { } //~ ERROR expected trait, found derive macro `Debug` fn wants_clone(g: impl Clone) { } -fn main() { -} +fn main() {} diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index 1fd3ebff62..f530792955 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -1,23 +1,23 @@ -error[E0405]: cannot find trait `Debug` in this scope +error[E0404]: expected trait, found derive macro `Debug` --> $DIR/universal_wrong_bounds.rs:9:24 | LL | fn wants_debug(g: impl Debug) { } - | ^^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope + | ^^^^^ not a trait +help: possible better candidate is found in another module, you can import it into scope | LL | use std::fmt::Debug; | -error[E0405]: cannot find trait `Debug` in this scope +error[E0404]: expected trait, found derive macro `Debug` --> $DIR/universal_wrong_bounds.rs:10:26 | LL | fn wants_display(g: impl Debug) { } - | ^^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope + | ^^^^^ not a trait +help: possible better candidate is found in another module, you can import it into scope | LL | use std::fmt::Debug; | error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0405`. +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs index 31bc9f449a..9eac6b714d 100644 --- a/src/test/ui/impl-trait/where-allowed.rs +++ b/src/test/ui/impl-trait/where-allowed.rs @@ -120,7 +120,8 @@ trait DummyTrait { } impl DummyTrait for () { type Out = impl Debug; - //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types + //~^ ERROR `impl Trait` in type aliases is unstable + //~^^ ERROR could not find defining uses fn in_trait_impl_parameter(_: impl Debug) { } // Allowed @@ -155,7 +156,8 @@ extern "C" fn in_extern_fn_return() -> impl Debug { } type InTypeAlias = impl Debug; -//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types +//~^ ERROR `impl Trait` in type aliases is unstable +//~^^ ERROR could not find defining uses type InReturnInTypeAlias = fn() -> impl Debug; //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index e7a8430fae..1332fff84f 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -16,6 +16,24 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | | nested `impl Trait` here | outer `impl Trait` +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/where-allowed.rs:122:5 + | +LL | type Out = impl Debug; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/where-allowed.rs:158:1 + | +LL | type InTypeAlias = impl Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/63063 + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + error[E0562]: `impl Trait` not allowed outside of function and inherent method return types --> $DIR/where-allowed.rs:18:40 | @@ -137,109 +155,110 @@ LL | fn in_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:122:16 - | -LL | type Out = impl Debug; - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:128:34 + --> $DIR/where-allowed.rs:129:34 | LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:141:33 + --> $DIR/where-allowed.rs:142:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:144:31 + --> $DIR/where-allowed.rs:145:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:157:23 - | -LL | type InTypeAlias = impl Debug; - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:160:39 + --> $DIR/where-allowed.rs:162:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:164:16 + --> $DIR/where-allowed.rs:166:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:169:24 + --> $DIR/where-allowed.rs:171:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:174:6 + --> $DIR/where-allowed.rs:176:6 | LL | impl impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:180:24 + --> $DIR/where-allowed.rs:182:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:186:11 + --> $DIR/where-allowed.rs:188:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:193:15 + --> $DIR/where-allowed.rs:195:15 | LL | where Vec: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:200:24 + --> $DIR/where-allowed.rs:202:24 | LL | where T: PartialEq | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:207:17 + --> $DIR/where-allowed.rs:209:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:214:22 + --> $DIR/where-allowed.rs:216:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:220:29 + --> $DIR/where-allowed.rs:222:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ | - = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:222:46 + --> $DIR/where-allowed.rs:224:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ -error: aborting due to 39 previous errors +error: could not find defining uses + --> $DIR/where-allowed.rs:158:1 + | +LL | type InTypeAlias = impl Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: could not find defining uses + --> $DIR/where-allowed.rs:122:5 + | +LL | type Out = impl Debug; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 41 previous errors -For more information about this error, try `rustc --explain E0562`. +Some errors have detailed explanations: E0562, E0658. +For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/run-pass/impl-trait/xcrate.rs b/src/test/ui/impl-trait/xcrate.rs similarity index 100% rename from src/test/run-pass/impl-trait/xcrate.rs rename to src/test/ui/impl-trait/xcrate.rs diff --git a/src/test/run-pass/impl-trait/xcrate_simple.rs b/src/test/ui/impl-trait/xcrate_simple.rs similarity index 100% rename from src/test/run-pass/impl-trait/xcrate_simple.rs rename to src/test/ui/impl-trait/xcrate_simple.rs diff --git a/src/test/ui/import3.stderr b/src/test/ui/import3.stderr index 73b9b27b57..7bb413be59 100644 --- a/src/test/ui/import3.stderr +++ b/src/test/ui/import3.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `main` --> $DIR/import3.rs:2:5 | LL | use main::bar; - | ^^^^ maybe a missing `extern crate main;`? + | ^^^^ maybe a missing crate `main`? error: aborting due to previous error diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs index 9c9397999f..244293be72 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that `extern crate self;` is accepted // syntactically as an item for use in a macro. diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs index 6f6343a614..9cebb622ee 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate self as foo; diff --git a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs index cf91a9714a..30d87f90b3 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 macro_rules! define_iso { () => { diff --git a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs index 6117e5f6f3..cfae08fcca 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--cfg my_feature #![no_std] diff --git a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs index bb4cf6ca99..c87d58f63e 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:two_macros.rs extern crate two_macros; diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr index 24b1b582d1..e8dfd43b67 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr @@ -14,7 +14,7 @@ LL | Vec::panic!(); | ^^^ ambiguous name | = note: `Vec` could refer to a struct from prelude -note: `Vec` could also refer to the extern crate imported here +note: `Vec` could also refer to the crate imported here --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:5:9 | LL | extern crate std as Vec; diff --git a/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs index c5adeaf17f..9e69a27d7c 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:two_macros.rs extern crate two_macros as core; diff --git a/src/test/ui/imports/gensymed.rs b/src/test/ui/imports/gensymed.rs index 317441079f..613ccc0b24 100644 --- a/src/test/ui/imports/gensymed.rs +++ b/src/test/ui/imports/gensymed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // aux-build:gensymed.rs diff --git a/src/test/ui/imports/glob-conflict-cross-crate.rs b/src/test/ui/imports/glob-conflict-cross-crate.rs index c8b18525d8..d84c243f21 100644 --- a/src/test/ui/imports/glob-conflict-cross-crate.rs +++ b/src/test/ui/imports/glob-conflict-cross-crate.rs @@ -3,6 +3,6 @@ extern crate glob_conflict; fn main() { - glob_conflict::f(); //~ ERROR cannot find function `f` in module `glob_conflict` + glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` } diff --git a/src/test/ui/imports/glob-conflict-cross-crate.stderr b/src/test/ui/imports/glob-conflict-cross-crate.stderr index ad70b7d5b9..0e3b4222fe 100644 --- a/src/test/ui/imports/glob-conflict-cross-crate.stderr +++ b/src/test/ui/imports/glob-conflict-cross-crate.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` in module `glob_conflict` +error[E0425]: cannot find function `f` in crate `glob_conflict` --> $DIR/glob-conflict-cross-crate.rs:6:20 | LL | glob_conflict::f(); diff --git a/src/test/ui/imports/glob-shadowing.stderr b/src/test/ui/imports/glob-shadowing.stderr index 7962fcb9ae..4ef446f93c 100644 --- a/src/test/ui/imports/glob-shadowing.stderr +++ b/src/test/ui/imports/glob-shadowing.stderr @@ -4,7 +4,7 @@ error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope LL | let x = env!("PATH"); | ^^^ ambiguous name | - = note: `env` could refer to a built-in macro + = note: `env` could refer to a macro from prelude note: `env` could also refer to the macro imported here --> $DIR/glob-shadowing.rs:9:9 | @@ -19,7 +19,7 @@ error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope LL | let x = env!("PATH"); | ^^^ ambiguous name | - = note: `env` could refer to a built-in macro + = note: `env` could refer to a macro from prelude note: `env` could also refer to the macro imported here --> $DIR/glob-shadowing.rs:17:13 | diff --git a/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs b/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs similarity index 100% rename from src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs rename to src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs diff --git a/src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs b/src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs similarity index 100% rename from src/test/run-pass/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs rename to src/test/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs diff --git a/src/test/run-pass/imports/import-crate-with-invalid-spans/main.rs b/src/test/ui/imports/import-crate-with-invalid-spans/main.rs similarity index 100% rename from src/test/run-pass/imports/import-crate-with-invalid-spans/main.rs rename to src/test/ui/imports/import-crate-with-invalid-spans/main.rs diff --git a/src/test/run-pass/imports/import-from.rs b/src/test/ui/imports/import-from.rs similarity index 100% rename from src/test/run-pass/imports/import-from.rs rename to src/test/ui/imports/import-from.rs diff --git a/src/test/run-pass/imports/import-glob-0.rs b/src/test/ui/imports/import-glob-0-rpass.rs similarity index 100% rename from src/test/run-pass/imports/import-glob-0.rs rename to src/test/ui/imports/import-glob-0-rpass.rs diff --git a/src/test/run-pass/imports/import-glob-1.rs b/src/test/ui/imports/import-glob-1.rs similarity index 100% rename from src/test/run-pass/imports/import-glob-1.rs rename to src/test/ui/imports/import-glob-1.rs diff --git a/src/test/run-pass/imports/import-glob-crate.rs b/src/test/ui/imports/import-glob-crate.rs similarity index 100% rename from src/test/run-pass/imports/import-glob-crate.rs rename to src/test/ui/imports/import-glob-crate.rs diff --git a/src/test/run-pass/imports/import-in-block.rs b/src/test/ui/imports/import-in-block.rs similarity index 100% rename from src/test/run-pass/imports/import-in-block.rs rename to src/test/ui/imports/import-in-block.rs diff --git a/src/test/run-pass/imports/import-prefix-macro.rs b/src/test/ui/imports/import-prefix-macro.rs similarity index 100% rename from src/test/run-pass/imports/import-prefix-macro.rs rename to src/test/ui/imports/import-prefix-macro.rs diff --git a/src/test/run-pass/imports/import-rename.rs b/src/test/ui/imports/import-rename.rs similarity index 100% rename from src/test/run-pass/imports/import-rename.rs rename to src/test/ui/imports/import-rename.rs diff --git a/src/test/run-pass/imports/import-trailing-comma.rs b/src/test/ui/imports/import-trailing-comma.rs similarity index 100% rename from src/test/run-pass/imports/import-trailing-comma.rs rename to src/test/ui/imports/import-trailing-comma.rs diff --git a/src/test/run-pass/imports/import.rs b/src/test/ui/imports/import.rs similarity index 100% rename from src/test/run-pass/imports/import.rs rename to src/test/ui/imports/import.rs diff --git a/src/test/run-pass/imports/import2.rs b/src/test/ui/imports/import2.rs similarity index 100% rename from src/test/run-pass/imports/import2.rs rename to src/test/ui/imports/import2.rs diff --git a/src/test/run-pass/imports/import3.rs b/src/test/ui/imports/import3.rs similarity index 100% rename from src/test/run-pass/imports/import3.rs rename to src/test/ui/imports/import3.rs diff --git a/src/test/run-pass/imports/import4.rs b/src/test/ui/imports/import4.rs similarity index 100% rename from src/test/run-pass/imports/import4.rs rename to src/test/ui/imports/import4.rs diff --git a/src/test/run-pass/imports/import5.rs b/src/test/ui/imports/import5.rs similarity index 100% rename from src/test/run-pass/imports/import5.rs rename to src/test/ui/imports/import5.rs diff --git a/src/test/run-pass/imports/import6.rs b/src/test/ui/imports/import6.rs similarity index 100% rename from src/test/run-pass/imports/import6.rs rename to src/test/ui/imports/import6.rs diff --git a/src/test/run-pass/imports/import7.rs b/src/test/ui/imports/import7.rs similarity index 100% rename from src/test/run-pass/imports/import7.rs rename to src/test/ui/imports/import7.rs diff --git a/src/test/run-pass/imports/import8.rs b/src/test/ui/imports/import8.rs similarity index 100% rename from src/test/run-pass/imports/import8.rs rename to src/test/ui/imports/import8.rs diff --git a/src/test/run-pass/imports/imports.rs b/src/test/ui/imports/imports.rs similarity index 100% rename from src/test/run-pass/imports/imports.rs rename to src/test/ui/imports/imports.rs diff --git a/src/test/ui/imports/issue-53140.rs b/src/test/ui/imports/issue-53140.rs index dbfba2c943..1854ddf96b 100644 --- a/src/test/ui/imports/issue-53140.rs +++ b/src/test/ui/imports/issue-53140.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod m { pub struct S(u8); diff --git a/src/test/ui/imports/issue-53269.stderr b/src/test/ui/imports/issue-53269.stderr index 613c59867c..bbec2aae82 100644 --- a/src/test/ui/imports/issue-53269.stderr +++ b/src/test/ui/imports/issue-53269.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `nonexistent_module` --> $DIR/issue-53269.rs:6:9 | LL | use nonexistent_module::mac; - | ^^^^^^^^^^^^^^^^^^ maybe a missing `extern crate nonexistent_module;`? + | ^^^^^^^^^^^^^^^^^^ maybe a missing crate `nonexistent_module`? error[E0659]: `mac` is ambiguous (`macro_rules` vs non-`macro_rules` from other module) --> $DIR/issue-53269.rs:8:5 diff --git a/src/test/ui/imports/issue-53512.rs b/src/test/ui/imports/issue-53512.rs index 615b36a0b2..67470f854c 100644 --- a/src/test/ui/imports/issue-53512.rs +++ b/src/test/ui/imports/issue-53512.rs @@ -1,6 +1,7 @@ // Macro from prelude is shadowed by non-existent import recovered as `Res::Err`. -use std::assert; //~ ERROR unresolved import `std::assert` +mod m {} +use m::assert; //~ ERROR unresolved import `m::assert` fn main() { assert!(true); diff --git a/src/test/ui/imports/issue-53512.stderr b/src/test/ui/imports/issue-53512.stderr index f902fc4888..05fe111b38 100644 --- a/src/test/ui/imports/issue-53512.stderr +++ b/src/test/ui/imports/issue-53512.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `std::assert` - --> $DIR/issue-53512.rs:3:5 +error[E0432]: unresolved import `m::assert` + --> $DIR/issue-53512.rs:4:5 | -LL | use std::assert; - | ^^^^^^^^^^^ no `assert` in the root +LL | use m::assert; + | ^^^^^^^^^ no `assert` in `m` error: aborting due to previous error diff --git a/src/test/ui/imports/issue-55457.stderr b/src/test/ui/imports/issue-55457.stderr index 86a76c1d89..aa103ba01e 100644 --- a/src/test/ui/imports/issue-55457.stderr +++ b/src/test/ui/imports/issue-55457.stderr @@ -11,7 +11,7 @@ error[E0432]: unresolved import `non_existent` --> $DIR/issue-55457.rs:2:5 | LL | use non_existent::non_existent; - | ^^^^^^^^^^^^ maybe a missing `extern crate non_existent;`? + | ^^^^^^^^^^^^ maybe a missing crate `non_existent`? error: cannot determine resolution for the derive macro `NonExistent` --> $DIR/issue-55457.rs:5:10 diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs index 95316777fa..8cb602d868 100644 --- a/src/test/ui/imports/issue-55811.rs +++ b/src/test/ui/imports/issue-55811.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:issue-55811.rs extern crate issue_55811; diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr index 0ecedd50e0..d78cc52303 100644 --- a/src/test/ui/imports/issue-56125.stderr +++ b/src/test/ui/imports/issue-56125.stderr @@ -10,8 +10,8 @@ error[E0659]: `issue_56125` is ambiguous (name vs any other name during import r LL | use issue_56125::last_segment::*; | ^^^^^^^^^^^ ambiguous name | - = note: `issue_56125` could refer to an extern crate passed with `--extern` - = help: use `::issue_56125` to refer to this extern crate unambiguously + = note: `issue_56125` could refer to a crate passed with `--extern` + = help: use `::issue_56125` to refer to this crate unambiguously note: `issue_56125` could also refer to the module imported here --> $DIR/issue-56125.rs:6:9 | @@ -25,8 +25,8 @@ error[E0659]: `issue_56125` is ambiguous (name vs any other name during import r LL | use issue_56125::non_last_segment::non_last_segment::*; | ^^^^^^^^^^^ ambiguous name | - = note: `issue_56125` could refer to an extern crate passed with `--extern` - = help: use `::issue_56125` to refer to this extern crate unambiguously + = note: `issue_56125` could refer to a crate passed with `--extern` + = help: use `::issue_56125` to refer to this crate unambiguously note: `issue_56125` could also refer to the module imported here --> $DIR/issue-56125.rs:11:9 | @@ -40,8 +40,8 @@ error[E0659]: `issue_56125` is ambiguous (name vs any other name during import r LL | use issue_56125::*; | ^^^^^^^^^^^ ambiguous name | - = note: `issue_56125` could refer to an extern crate passed with `--extern` - = help: use `::issue_56125` to refer to this extern crate unambiguously + = note: `issue_56125` could refer to a crate passed with `--extern` + = help: use `::issue_56125` to refer to this crate unambiguously note: `issue_56125` could also refer to the module imported here --> $DIR/issue-56125.rs:18:9 | diff --git a/src/test/ui/imports/issue-56263.rs b/src/test/ui/imports/issue-56263.rs index 4113d4390c..4763ae4be9 100644 --- a/src/test/ui/imports/issue-56263.rs +++ b/src/test/ui/imports/issue-56263.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 use ::std; diff --git a/src/test/ui/imports/issue-57539.stderr b/src/test/ui/imports/issue-57539.stderr index ebf27ca54b..174088e8f6 100644 --- a/src/test/ui/imports/issue-57539.stderr +++ b/src/test/ui/imports/issue-57539.stderr @@ -4,8 +4,8 @@ error[E0659]: `core` is ambiguous (name vs any other name during import resoluti LL | use core; | ^^^^ ambiguous name | - = note: `core` could refer to a built-in extern crate - = help: use `::core` to refer to this extern crate unambiguously + = note: `core` could refer to a built-in crate + = help: use `::core` to refer to this crate unambiguously note: `core` could also refer to the module imported here --> $DIR/issue-57539.rs:5:9 | diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index 13d3227d8b..5afdd8889a 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -27,7 +27,7 @@ error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded LL | include!(); | ^^^^^^^ ambiguous name | - = note: `include` could refer to a built-in macro + = note: `include` could refer to a macro from prelude note: `include` could also refer to the macro defined here --> $DIR/local-modularized-tricky-fail-1.rs:17:5 | diff --git a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr index 70d197994f..92a836cadf 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr @@ -8,7 +8,7 @@ LL | () => ( struct Б; ) | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/local-modularized-tricky-fail-2.rs:36:24 @@ -20,7 +20,7 @@ LL | () => ( struct Г; ) | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error[E0658]: non-ascii idents are not fully supported --> $DIR/local-modularized-tricky-fail-2.rs:46:24 @@ -32,7 +32,7 @@ LL | () => ( struct Д; ) | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/55467 - = help: add #![feature(non_ascii_idents)] to the crate attributes to enable + = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/imports/local-modularized-tricky-fail-3.stderr b/src/test/ui/imports/local-modularized-tricky-fail-3.stderr index 6bece2b17c..5272d2a319 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-3.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-3.stderr @@ -4,7 +4,7 @@ error: macro-expanded `macro_export` macros from the current crate cannot be ref LL | use exported; | ^^^^^^^^ | - = note: #[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)] on by default + = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #52234 note: the macro is defined here diff --git a/src/test/ui/imports/local-modularized-tricky-pass.rs b/src/test/ui/imports/local-modularized-tricky-pass.rs index 59aac952b9..b52ddaf895 100644 --- a/src/test/ui/imports/local-modularized-tricky-pass.rs +++ b/src/test/ui/imports/local-modularized-tricky-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! define_exported { () => { #[macro_export] diff --git a/src/test/ui/imports/local-modularized.rs b/src/test/ui/imports/local-modularized.rs index a073fe26eb..8eeb1cf07b 100644 --- a/src/test/ui/imports/local-modularized.rs +++ b/src/test/ui/imports/local-modularized.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[macro_export(local_inner_macros)] macro_rules! dollar_crate_exported { diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr index f20db881c8..e8c827a617 100644 --- a/src/test/ui/imports/unresolved-imports-used.stderr +++ b/src/test/ui/imports/unresolved-imports-used.stderr @@ -8,7 +8,7 @@ error[E0432]: unresolved import `foo` --> $DIR/unresolved-imports-used.rs:10:5 | LL | use foo::bar; - | ^^^ maybe a missing `extern crate foo;`? + | ^^^ maybe a missing crate `foo`? error[E0603]: function `quz` is private --> $DIR/unresolved-imports-used.rs:8:10 diff --git a/src/test/ui/imports/unused-macro-use.stderr b/src/test/ui/imports/unused-macro-use.stderr index 78683147f7..b7fb532c67 100644 --- a/src/test/ui/imports/unused-macro-use.stderr +++ b/src/test/ui/imports/unused-macro-use.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(unused)] | ^^^^^^ - = note: #[deny(unused_imports)] implied by #[deny(unused)] + = note: `#[deny(unused_imports)]` implied by `#[deny(unused)]` error: unused `#[macro_use]` import --> $DIR/unused-macro-use.rs:7:5 diff --git a/src/test/ui/imports/unused.stderr b/src/test/ui/imports/unused.stderr index 259ed95869..0366b52ef6 100644 --- a/src/test/ui/imports/unused.stderr +++ b/src/test/ui/imports/unused.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(unused)] | ^^^^^^ - = note: #[deny(unused_imports)] implied by #[deny(unused)] + = note: `#[deny(unused_imports)]` implied by `#[deny(unused)]` error: aborting due to previous error diff --git a/src/test/run-pass/in-band-lifetimes.rs b/src/test/ui/in-band-lifetimes.rs similarity index 80% rename from src/test/run-pass/in-band-lifetimes.rs rename to src/test/ui/in-band-lifetimes.rs index c892260536..9b2e1fe83c 100644 --- a/src/test/run-pass/in-band-lifetimes.rs +++ b/src/test/ui/in-band-lifetimes.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(warnings)] #![feature(in_band_lifetimes)] @@ -75,19 +77,19 @@ fn impl_trait_in_band(x: &impl MyTrait<'a>) {} trait FunkyTrait<'a> { } impl<'a, T> FunkyTrait<'a> for T { } -fn existential_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { +fn ret_pos_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { x } -fn existential_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { +fn ret_pos_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { x } -fn existential_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { +fn ret_pos_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { x } -fn existential_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { +fn ret_pos_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { x } -fn existential_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { +fn ret_pos_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { x } diff --git a/src/test/run-pass/inc-range-pat.rs b/src/test/ui/inc-range-pat.rs similarity index 96% rename from src/test/run-pass/inc-range-pat.rs rename to src/test/ui/inc-range-pat.rs index a648ff1749..1eb7dd0aa3 100644 --- a/src/test/run-pass/inc-range-pat.rs +++ b/src/test/ui/inc-range-pat.rs @@ -1,3 +1,4 @@ +// run-pass // Test old and new syntax for inclusive range patterns. #![allow(ellipsis_inclusive_range_patterns)] diff --git a/src/test/run-pass/infer-fn-tail-expr.rs b/src/test/ui/infer-fn-tail-expr.rs similarity index 90% rename from src/test/run-pass/infer-fn-tail-expr.rs rename to src/test/ui/infer-fn-tail-expr.rs index ab0210baa9..413b1877a2 100644 --- a/src/test/run-pass/infer-fn-tail-expr.rs +++ b/src/test/ui/infer-fn-tail-expr.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] // issue #680 diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs index 513b15ed08..a90b268db8 100644 --- a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs +++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // tests that the following code compiles, but produces a future-compatibility warning diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr index 52cf68ae2a..b5b885e233 100644 --- a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr +++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr @@ -4,7 +4,7 @@ warning: type annotations needed LL | if data.is_null() {} | ^^^^^^^ | - = note: #[warn(tyvar_behind_raw_pointer)] on by default + = note: `#[warn(tyvar_behind_raw_pointer)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #46906 diff --git a/src/test/ui/inference/inference_unstable.stderr b/src/test/ui/inference/inference_unstable.stderr index dda203bbc5..1f5cc8b13f 100644 --- a/src/test/ui/inference/inference_unstable.stderr +++ b/src/test/ui/inference/inference_unstable.stderr @@ -4,9 +4,9 @@ warning: a method with this name may be added to the standard library in the fut LL | assert_eq!('x'.ipu_flatten(), 1); | ^^^^^^^^^^^ | - = note: #[warn(unstable_name_collisions)] on by default + = note: `#[warn(unstable_name_collisions)]` on by default = 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 = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method - = help: add #![feature(ipu_flatten)] to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten` + = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten` diff --git a/src/test/ui/inference/inference_unstable_featured.stderr b/src/test/ui/inference/inference_unstable_featured.stderr index 08cdb8cc68..b06a6298a5 100644 --- a/src/test/ui/inference/inference_unstable_featured.stderr +++ b/src/test/ui/inference/inference_unstable_featured.stderr @@ -5,7 +5,9 @@ LL | assert_eq!('x'.ipu_flatten(), 0); | ^^^^^^^^^^^ multiple `ipu_flatten` found | = note: candidate #1 is defined in an impl of the trait `inference_unstable_iterator::IpuIterator` for the type `char` + = help: to disambiguate the method call, write `inference_unstable_iterator::IpuIterator::ipu_flatten('x')` instead = note: candidate #2 is defined in an impl of the trait `inference_unstable_itertools::IpuItertools` for the type `char` + = help: to disambiguate the method call, write `inference_unstable_itertools::IpuItertools::ipu_flatten('x')` instead error: aborting due to previous error diff --git a/src/test/ui/inference/inference_unstable_forced.stderr b/src/test/ui/inference/inference_unstable_forced.stderr index 83e27aaf2f..79a0b60b0a 100644 --- a/src/test/ui/inference/inference_unstable_forced.stderr +++ b/src/test/ui/inference/inference_unstable_forced.stderr @@ -5,7 +5,7 @@ LL | assert_eq!('x'.ipu_flatten(), 0); | ^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/99999 - = help: add #![feature(ipu_flatten)] to the crate attributes to enable + = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/inherit-env.rs b/src/test/ui/inherit-env.rs similarity index 98% rename from src/test/run-pass/inherit-env.rs rename to src/test/ui/inherit-env.rs index 229953f1b1..e29fa04bbd 100644 --- a/src/test/run-pass/inherit-env.rs +++ b/src/test/ui/inherit-env.rs @@ -1,3 +1,4 @@ +// run-pass // ignore-emscripten // ignore-wasm32 // ignore-sgx no processes diff --git a/src/test/run-pass/init-large-type.rs b/src/test/ui/init-large-type.rs similarity index 97% rename from src/test/run-pass/init-large-type.rs rename to src/test/ui/init-large-type.rs index cb64cd0b0f..a304fc9356 100644 --- a/src/test/run-pass/init-large-type.rs +++ b/src/test/ui/init-large-type.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_must_use)] // Makes sure that zero-initializing large types is reasonably fast, // Doing it incorrectly causes massive slowdown in LLVM during diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/ui/init-res-into-things.rs similarity index 98% rename from src/test/run-pass/init-res-into-things.rs rename to src/test/ui/init-res-into-things.rs index 832637962b..ed0c600c1d 100644 --- a/src/test/run-pass/init-res-into-things.rs +++ b/src/test/ui/init-res-into-things.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] #![feature(box_syntax)] diff --git a/src/test/ui/init-unsafe.rs b/src/test/ui/init-unsafe.rs index 92b21c4efa..3d65cfc234 100644 --- a/src/test/ui/init-unsafe.rs +++ b/src/test/ui/init-unsafe.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] #![feature(core_intrinsics)] use std::intrinsics::{init}; diff --git a/src/test/ui/init-unsafe.stderr b/src/test/ui/init-unsafe.stderr index 857142dff6..e1126316af 100644 --- a/src/test/ui/init-unsafe.stderr +++ b/src/test/ui/init-unsafe.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/init-unsafe.rs:7:17 + --> $DIR/init-unsafe.rs:8:17 | LL | let stuff = init::(); | ^^^^^^^^^^^^^^^ call to unsafe function diff --git a/src/test/run-pass/inlined-main.rs b/src/test/ui/inlined-main.rs similarity index 70% rename from src/test/run-pass/inlined-main.rs rename to src/test/ui/inlined-main.rs index 3a55a89426..75ff4c87dc 100644 --- a/src/test/run-pass/inlined-main.rs +++ b/src/test/ui/inlined-main.rs @@ -1,2 +1,4 @@ +// run-pass + #[inline(always)] fn main() {} diff --git a/src/test/run-pass/inner-attrs-on-impl.rs b/src/test/ui/inner-attrs-on-impl.rs similarity index 96% rename from src/test/run-pass/inner-attrs-on-impl.rs rename to src/test/ui/inner-attrs-on-impl.rs index 4cc659562e..636e8c4885 100644 --- a/src/test/run-pass/inner-attrs-on-impl.rs +++ b/src/test/ui/inner-attrs-on-impl.rs @@ -1,3 +1,5 @@ +// run-pass + struct Foo; impl Foo { diff --git a/src/test/run-pass/inner-module.rs b/src/test/ui/inner-module.rs similarity index 93% rename from src/test/run-pass/inner-module.rs rename to src/test/ui/inner-module.rs index d865869187..363f753e24 100644 --- a/src/test/run-pass/inner-module.rs +++ b/src/test/ui/inner-module.rs @@ -1,3 +1,5 @@ +// run-pass + mod inner { pub mod inner2 { pub fn hello() { println!("hello, modular world"); } diff --git a/src/test/run-pass/inner-static.rs b/src/test/ui/inner-static.rs similarity index 96% rename from src/test/run-pass/inner-static.rs rename to src/test/ui/inner-static.rs index 6f7d7c2288..adba299ebe 100644 --- a/src/test/run-pass/inner-static.rs +++ b/src/test/ui/inner-static.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:inner_static.rs diff --git a/src/test/run-pass/instantiable.rs b/src/test/ui/instantiable.rs similarity index 96% rename from src/test/run-pass/instantiable.rs rename to src/test/ui/instantiable.rs index fe8d9f9714..ad0cf3f4ac 100644 --- a/src/test/run-pass/instantiable.rs +++ b/src/test/ui/instantiable.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(non_camel_case_types)] #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/internal/internal-unstable-noallow.stderr b/src/test/ui/internal/internal-unstable-noallow.stderr index 7247f68fa4..5a3a235615 100644 --- a/src/test/ui/internal/internal-unstable-noallow.stderr +++ b/src/test/ui/internal/internal-unstable-noallow.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'function' LL | call_unstable_noallow!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0658]: use of unstable library feature 'struct_field' @@ -13,7 +13,7 @@ error[E0658]: use of unstable library feature 'struct_field' LL | construct_unstable_noallow!(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(struct_field)] to the crate attributes to enable + = help: add `#![feature(struct_field)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0658]: use of unstable library feature 'method' @@ -22,7 +22,7 @@ error[E0658]: use of unstable library feature 'method' LL | |x: internal_unstable::Foo| { call_method_noallow!(x) }; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(method)] to the crate attributes to enable + = help: add `#![feature(method)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0658]: use of unstable library feature 'struct2_field' @@ -31,7 +31,7 @@ error[E0658]: use of unstable library feature 'struct2_field' LL | |x: internal_unstable::Bar| { access_field_noallow!(x) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(struct2_field)] to the crate attributes to enable + = help: add `#![feature(struct2_field)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/internal/internal-unstable-thread-local.stderr b/src/test/ui/internal/internal-unstable-thread-local.stderr index 603bdc39bd..558e3dbb78 100644 --- a/src/test/ui/internal/internal-unstable-thread-local.stderr +++ b/src/test/ui/internal/internal-unstable-thread-local.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'function' LL | thread_local!(static BAR: () = internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/internal/internal-unstable.stderr b/src/test/ui/internal/internal-unstable.stderr index 5c14fed568..2c9d146921 100644 --- a/src/test/ui/internal/internal-unstable.stderr +++ b/src/test/ui/internal/internal-unstable.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'function' LL | pass_through_allow!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' --> $DIR/internal-unstable.rs:35:27 @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature 'function' LL | pass_through_noallow!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' --> $DIR/internal-unstable.rs:39:22 @@ -20,7 +20,7 @@ error[E0658]: use of unstable library feature 'function' LL | println!("{:?}", internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' --> $DIR/internal-unstable.rs:41:10 @@ -28,7 +28,7 @@ error[E0658]: use of unstable library feature 'function' LL | bar!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' --> $DIR/internal-unstable.rs:12:9 @@ -39,7 +39,7 @@ LL | internal_unstable::unstable(); LL | bar!(internal_unstable::unstable()); | ------------------------------------ in this macro invocation | - = help: add #![feature(function)] to the crate attributes to enable + = help: add `#![feature(function)]` to the crate attributes to enable error: aborting due to 5 previous errors diff --git a/src/test/run-pass/intrinsics/auxiliary/cci_intrinsic.rs b/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs similarity index 100% rename from src/test/run-pass/intrinsics/auxiliary/cci_intrinsic.rs rename to src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-alignment.rs rename to src/test/ui/intrinsics/intrinsic-alignment.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-assume.rs b/src/test/ui/intrinsics/intrinsic-assume.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-assume.rs rename to src/test/ui/intrinsics/intrinsic-assume.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-atomics-cc.rs b/src/test/ui/intrinsics/intrinsic-atomics-cc.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-atomics-cc.rs rename to src/test/ui/intrinsics/intrinsic-atomics-cc.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-atomics.rs b/src/test/ui/intrinsics/intrinsic-atomics.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-atomics.rs rename to src/test/ui/intrinsics/intrinsic-atomics.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-move-val-cleanups.rs b/src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-move-val-cleanups.rs rename to src/test/ui/intrinsics/intrinsic-move-val-cleanups.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-move-val.rs b/src/test/ui/intrinsics/intrinsic-move-val.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-move-val.rs rename to src/test/ui/intrinsics/intrinsic-move-val.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-uninit.rs b/src/test/ui/intrinsics/intrinsic-uninit.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-uninit.rs rename to src/test/ui/intrinsics/intrinsic-uninit.rs diff --git a/src/test/run-pass/intrinsics/intrinsic-unreachable.rs b/src/test/ui/intrinsics/intrinsic-unreachable.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsic-unreachable.rs rename to src/test/ui/intrinsics/intrinsic-unreachable.rs diff --git a/src/test/run-pass/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsics-integer.rs rename to src/test/ui/intrinsics/intrinsics-integer.rs diff --git a/src/test/run-pass/intrinsics/intrinsics-math.rs b/src/test/ui/intrinsics/intrinsics-math.rs similarity index 100% rename from src/test/run-pass/intrinsics/intrinsics-math.rs rename to src/test/ui/intrinsics/intrinsics-math.rs diff --git a/src/test/ui/intrinsics/unchecked_math_unstable.stderr b/src/test/ui/intrinsics/unchecked_math_unstable.stderr index 6f5429127c..a43aa16aed 100644 --- a/src/test/ui/intrinsics/unchecked_math_unstable.stderr +++ b/src/test/ui/intrinsics/unchecked_math_unstable.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are LL | let add = std::intrinsics::unchecked_add(x, y); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(core_intrinsics)] to the crate attributes to enable + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library --> $DIR/unchecked_math_unstable.rs:5:19 @@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are LL | let sub = std::intrinsics::unchecked_sub(x, y); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(core_intrinsics)] to the crate attributes to enable + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library --> $DIR/unchecked_math_unstable.rs:6:19 @@ -20,7 +20,7 @@ error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are LL | let mul = std::intrinsics::unchecked_mul(x, y); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(core_intrinsics)] to the crate attributes to enable + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/invalid/invalid-crate-type.stderr b/src/test/ui/invalid/invalid-crate-type.stderr index 030dc96c6d..59d5d7bc9b 100644 --- a/src/test/ui/invalid/invalid-crate-type.stderr +++ b/src/test/ui/invalid/invalid-crate-type.stderr @@ -4,7 +4,7 @@ error: invalid `crate_type` value LL | #![crate_type="foo"] | ^^^^^ | - = note: #[deny(unknown_crate_types)] on by default + = note: `#[deny(unknown_crate_types)]` on by default error: invalid `crate_type` value --> $DIR/invalid-crate-type.rs:6:15 diff --git a/src/test/ui/invalid/invalid-plugin-attr.stderr b/src/test/ui/invalid/invalid-plugin-attr.stderr index c7b2ce4748..36714c39b3 100644 --- a/src/test/ui/invalid/invalid-plugin-attr.stderr +++ b/src/test/ui/invalid/invalid-plugin-attr.stderr @@ -10,7 +10,7 @@ note: lint level defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo] +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` --> $DIR/invalid-plugin-attr.rs:4:1 | LL | #[plugin(bla)] diff --git a/src/test/run-pass/invalid_const_promotion.rs b/src/test/ui/invalid_const_promotion.rs similarity index 98% rename from src/test/run-pass/invalid_const_promotion.rs rename to src/test/ui/invalid_const_promotion.rs index ddf4dc4242..6d59bb385d 100644 --- a/src/test/run-pass/invalid_const_promotion.rs +++ b/src/test/ui/invalid_const_promotion.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(unused_mut)] // ignore-wasm32 // ignore-emscripten diff --git a/src/test/run-pass/invoke-external-foreign.rs b/src/test/ui/invoke-external-foreign.rs similarity index 96% rename from src/test/run-pass/invoke-external-foreign.rs rename to src/test/ui/invoke-external-foreign.rs index d34933cde4..dbd2b4ad86 100644 --- a/src/test/run-pass/invoke-external-foreign.rs +++ b/src/test/ui/invoke-external-foreign.rs @@ -1,3 +1,4 @@ +// run-pass // aux-build:foreign_lib.rs // ignore-wasm32-bare no libc to test ffi with diff --git a/src/test/run-pass/irrefutable-unit.rs b/src/test/ui/irrefutable-unit.rs similarity index 86% rename from src/test/run-pass/irrefutable-unit.rs rename to src/test/ui/irrefutable-unit.rs index f588ae3a55..dd8f03b6db 100644 --- a/src/test/run-pass/irrefutable-unit.rs +++ b/src/test/ui/irrefutable-unit.rs @@ -1,3 +1,4 @@ +// run-pass // pretty-expanded FIXME #23616 pub fn main() { diff --git a/src/test/ui/issue-53912.rs b/src/test/ui/issue-53912.rs index d2347c3077..4718aea042 100644 --- a/src/test/ui/issue-53912.rs +++ b/src/test/ui/issue-53912.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the // reproduction compiles successfully and doesn't segfault, whereas that test just checks that the diff --git a/src/test/run-pass/issue-59020.rs b/src/test/ui/issue-59020.rs similarity index 100% rename from src/test/run-pass/issue-59020.rs rename to src/test/ui/issue-59020.rs diff --git a/src/test/run-pass/issues/auxiliary/cgu_test.rs b/src/test/ui/issues/auxiliary/cgu_test.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/cgu_test.rs rename to src/test/ui/issues/auxiliary/cgu_test.rs diff --git a/src/test/run-pass/issues/auxiliary/cgu_test_a.rs b/src/test/ui/issues/auxiliary/cgu_test_a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/cgu_test_a.rs rename to src/test/ui/issues/auxiliary/cgu_test_a.rs diff --git a/src/test/run-pass/issues/auxiliary/cgu_test_b.rs b/src/test/ui/issues/auxiliary/cgu_test_b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/cgu_test_b.rs rename to src/test/ui/issues/auxiliary/cgu_test_b.rs diff --git a/src/test/run-pass/issues/auxiliary/i8.rs b/src/test/ui/issues/auxiliary/i8.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/i8.rs rename to src/test/ui/issues/auxiliary/i8.rs diff --git a/src/test/run-pass/issues/auxiliary/iss.rs b/src/test/ui/issues/auxiliary/iss.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/iss.rs rename to src/test/ui/issues/auxiliary/iss.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-10028.rs b/src/test/ui/issues/auxiliary/issue-10028.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-10028.rs rename to src/test/ui/issues/auxiliary/issue-10028.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs b/src/test/ui/issues/auxiliary/issue-10031-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-10031-aux.rs rename to src/test/ui/issues/auxiliary/issue-10031-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-11224.rs b/src/test/ui/issues/auxiliary/issue-11224.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-11224.rs rename to src/test/ui/issues/auxiliary/issue-11224.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-11225-1.rs b/src/test/ui/issues/auxiliary/issue-11225-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-11225-1.rs rename to src/test/ui/issues/auxiliary/issue-11225-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-11225-2.rs b/src/test/ui/issues/auxiliary/issue-11225-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-11225-2.rs rename to src/test/ui/issues/auxiliary/issue-11225-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-11225-3.rs b/src/test/ui/issues/auxiliary/issue-11225-3.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-11225-3.rs rename to src/test/ui/issues/auxiliary/issue-11225-3.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-11508.rs b/src/test/ui/issues/auxiliary/issue-11508.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-11508.rs rename to src/test/ui/issues/auxiliary/issue-11508.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-11529.rs b/src/test/ui/issues/auxiliary/issue-11529.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-11529.rs rename to src/test/ui/issues/auxiliary/issue-11529.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-12133-dylib.rs b/src/test/ui/issues/auxiliary/issue-12133-dylib.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-12133-dylib.rs rename to src/test/ui/issues/auxiliary/issue-12133-dylib.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-12133-dylib2.rs b/src/test/ui/issues/auxiliary/issue-12133-dylib2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-12133-dylib2.rs rename to src/test/ui/issues/auxiliary/issue-12133-dylib2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-12133-rlib.rs b/src/test/ui/issues/auxiliary/issue-12133-rlib.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-12133-rlib.rs rename to src/test/ui/issues/auxiliary/issue-12133-rlib.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-12612-1.rs b/src/test/ui/issues/auxiliary/issue-12612-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-12612-1.rs rename to src/test/ui/issues/auxiliary/issue-12612-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-12612-2.rs b/src/test/ui/issues/auxiliary/issue-12612-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-12612-2.rs rename to src/test/ui/issues/auxiliary/issue-12612-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-12660-aux.rs b/src/test/ui/issues/auxiliary/issue-12660-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-12660-aux.rs rename to src/test/ui/issues/auxiliary/issue-12660-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-13507.rs b/src/test/ui/issues/auxiliary/issue-13507.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-13507.rs rename to src/test/ui/issues/auxiliary/issue-13507.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-13620-1.rs b/src/test/ui/issues/auxiliary/issue-13620-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-13620-1.rs rename to src/test/ui/issues/auxiliary/issue-13620-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-13620-2.rs b/src/test/ui/issues/auxiliary/issue-13620-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-13620-2.rs rename to src/test/ui/issues/auxiliary/issue-13620-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-13872-1.rs b/src/test/ui/issues/auxiliary/issue-13872-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-13872-1.rs rename to src/test/ui/issues/auxiliary/issue-13872-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-13872-2.rs b/src/test/ui/issues/auxiliary/issue-13872-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-13872-2.rs rename to src/test/ui/issues/auxiliary/issue-13872-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-13872-3.rs b/src/test/ui/issues/auxiliary/issue-13872-3.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-13872-3.rs rename to src/test/ui/issues/auxiliary/issue-13872-3.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-14344-1.rs b/src/test/ui/issues/auxiliary/issue-14344-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-14344-1.rs rename to src/test/ui/issues/auxiliary/issue-14344-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-14344-2.rs b/src/test/ui/issues/auxiliary/issue-14344-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-14344-2.rs rename to src/test/ui/issues/auxiliary/issue-14344-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-14421.rs b/src/test/ui/issues/auxiliary/issue-14421.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-14421.rs rename to src/test/ui/issues/auxiliary/issue-14421.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-14422.rs b/src/test/ui/issues/auxiliary/issue-14422.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-14422.rs rename to src/test/ui/issues/auxiliary/issue-14422.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-15562.rs b/src/test/ui/issues/auxiliary/issue-15562.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-15562.rs rename to src/test/ui/issues/auxiliary/issue-15562.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-16643.rs b/src/test/ui/issues/auxiliary/issue-16643.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-16643.rs rename to src/test/ui/issues/auxiliary/issue-16643.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-17662.rs b/src/test/ui/issues/auxiliary/issue-17662.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-17662.rs rename to src/test/ui/issues/auxiliary/issue-17662.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-17718-aux.rs b/src/test/ui/issues/auxiliary/issue-17718-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-17718-aux.rs rename to src/test/ui/issues/auxiliary/issue-17718-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-18501.rs b/src/test/ui/issues/auxiliary/issue-18501.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-18501.rs rename to src/test/ui/issues/auxiliary/issue-18501.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-18514.rs b/src/test/ui/issues/auxiliary/issue-18514.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-18514.rs rename to src/test/ui/issues/auxiliary/issue-18514.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-18711.rs b/src/test/ui/issues/auxiliary/issue-18711.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-18711.rs rename to src/test/ui/issues/auxiliary/issue-18711.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-18913-1.rs b/src/test/ui/issues/auxiliary/issue-18913-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-18913-1.rs rename to src/test/ui/issues/auxiliary/issue-18913-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-18913-2.rs b/src/test/ui/issues/auxiliary/issue-18913-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-18913-2.rs rename to src/test/ui/issues/auxiliary/issue-18913-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-19293.rs b/src/test/ui/issues/auxiliary/issue-19293.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-19293.rs rename to src/test/ui/issues/auxiliary/issue-19293.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-19340-1.rs b/src/test/ui/issues/auxiliary/issue-19340-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-19340-1.rs rename to src/test/ui/issues/auxiliary/issue-19340-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-20389.rs b/src/test/ui/issues/auxiliary/issue-20389.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-20389.rs rename to src/test/ui/issues/auxiliary/issue-20389.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs b/src/test/ui/issues/auxiliary/issue-2170-lib.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2170-lib.rs rename to src/test/ui/issues/auxiliary/issue-2170-lib.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2316-a.rs b/src/test/ui/issues/auxiliary/issue-2316-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2316-a.rs rename to src/test/ui/issues/auxiliary/issue-2316-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2316-b.rs b/src/test/ui/issues/auxiliary/issue-2316-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2316-b.rs rename to src/test/ui/issues/auxiliary/issue-2316-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2380.rs b/src/test/ui/issues/auxiliary/issue-2380.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2380.rs rename to src/test/ui/issues/auxiliary/issue-2380.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2414-a.rs b/src/test/ui/issues/auxiliary/issue-2414-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2414-a.rs rename to src/test/ui/issues/auxiliary/issue-2414-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2414-b.rs b/src/test/ui/issues/auxiliary/issue-2414-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2414-b.rs rename to src/test/ui/issues/auxiliary/issue-2414-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2472-b.rs b/src/test/ui/issues/auxiliary/issue-2472-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2472-b.rs rename to src/test/ui/issues/auxiliary/issue-2472-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-25185-1.rs b/src/test/ui/issues/auxiliary/issue-25185-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-25185-1.rs rename to src/test/ui/issues/auxiliary/issue-25185-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-25185-2.rs b/src/test/ui/issues/auxiliary/issue-25185-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-25185-2.rs rename to src/test/ui/issues/auxiliary/issue-25185-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2526.rs b/src/test/ui/issues/auxiliary/issue-2526.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2526.rs rename to src/test/ui/issues/auxiliary/issue-2526.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-25467.rs b/src/test/ui/issues/auxiliary/issue-25467.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-25467.rs rename to src/test/ui/issues/auxiliary/issue-25467.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2631-a.rs b/src/test/ui/issues/auxiliary/issue-2631-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2631-a.rs rename to src/test/ui/issues/auxiliary/issue-2631-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-2723-a.rs b/src/test/ui/issues/auxiliary/issue-2723-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-2723-a.rs rename to src/test/ui/issues/auxiliary/issue-2723-a.rs diff --git a/src/test/ui/issues/auxiliary/issue-29265.rs b/src/test/ui/issues/auxiliary/issue-29265.rs new file mode 100644 index 0000000000..6d26002a2e --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-29265.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] + +pub struct SomeType { + pub some_member: usize, +} + +pub static SOME_VALUE: SomeType = SomeType { + some_member: 1, +}; diff --git a/src/test/run-pass/issues/auxiliary/issue-29485.rs b/src/test/ui/issues/auxiliary/issue-29485.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-29485.rs rename to src/test/ui/issues/auxiliary/issue-29485.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-3012-1.rs b/src/test/ui/issues/auxiliary/issue-3012-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-3012-1.rs rename to src/test/ui/issues/auxiliary/issue-3012-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-3136-a.rc b/src/test/ui/issues/auxiliary/issue-3136-a.rc similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-3136-a.rc rename to src/test/ui/issues/auxiliary/issue-3136-a.rc diff --git a/src/test/run-pass/issues/auxiliary/issue-3136-a.rs b/src/test/ui/issues/auxiliary/issue-3136-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-3136-a.rs rename to src/test/ui/issues/auxiliary/issue-3136-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-31702-1.rs b/src/test/ui/issues/auxiliary/issue-31702-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-31702-1.rs rename to src/test/ui/issues/auxiliary/issue-31702-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-31702-2.rs b/src/test/ui/issues/auxiliary/issue-31702-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-31702-2.rs rename to src/test/ui/issues/auxiliary/issue-31702-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs b/src/test/ui/issues/auxiliary/issue-34796-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-34796-aux.rs rename to src/test/ui/issues/auxiliary/issue-34796-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-36954.rs b/src/test/ui/issues/auxiliary/issue-36954.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-36954.rs rename to src/test/ui/issues/auxiliary/issue-36954.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-38190.rs b/src/test/ui/issues/auxiliary/issue-38190.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-38190.rs rename to src/test/ui/issues/auxiliary/issue-38190.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs b/src/test/ui/issues/auxiliary/issue-38226-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-38226-aux.rs rename to src/test/ui/issues/auxiliary/issue-38226-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs b/src/test/ui/issues/auxiliary/issue-38715-modern.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-38715-modern.rs rename to src/test/ui/issues/auxiliary/issue-38715-modern.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-38715.rs b/src/test/ui/issues/auxiliary/issue-38715.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-38715.rs rename to src/test/ui/issues/auxiliary/issue-38715.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs b/src/test/ui/issues/auxiliary/issue-3979-traits.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-3979-traits.rs rename to src/test/ui/issues/auxiliary/issue-3979-traits.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-39823.rs b/src/test/ui/issues/auxiliary/issue-39823.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-39823.rs rename to src/test/ui/issues/auxiliary/issue-39823.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-40469.rs b/src/test/ui/issues/auxiliary/issue-40469.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-40469.rs rename to src/test/ui/issues/auxiliary/issue-40469.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-41053.rs b/src/test/ui/issues/auxiliary/issue-41053.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-41053.rs rename to src/test/ui/issues/auxiliary/issue-41053.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-41394.rs b/src/test/ui/issues/auxiliary/issue-41394.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-41394.rs rename to src/test/ui/issues/auxiliary/issue-41394.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-42007-s.rs b/src/test/ui/issues/auxiliary/issue-42007-s.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-42007-s.rs rename to src/test/ui/issues/auxiliary/issue-42007-s.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-4208-cc.rs b/src/test/ui/issues/auxiliary/issue-4208-cc.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-4208-cc.rs rename to src/test/ui/issues/auxiliary/issue-4208-cc.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-4545.rs b/src/test/ui/issues/auxiliary/issue-4545.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-4545.rs rename to src/test/ui/issues/auxiliary/issue-4545.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-48984-aux.rs b/src/test/ui/issues/auxiliary/issue-48984-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-48984-aux.rs rename to src/test/ui/issues/auxiliary/issue-48984-aux.rs diff --git a/src/test/ui/issues/auxiliary/issue-49544.rs b/src/test/ui/issues/auxiliary/issue-49544.rs new file mode 100644 index 0000000000..f8b3a3fba1 --- /dev/null +++ b/src/test/ui/issues/auxiliary/issue-49544.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +pub fn foo() -> Vec { + std::env::args() + .skip(1) + .collect() +} diff --git a/src/test/run-pass/issues/auxiliary/issue-5518.rs b/src/test/ui/issues/auxiliary/issue-5518.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-5518.rs rename to src/test/ui/issues/auxiliary/issue-5518.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-5521.rs b/src/test/ui/issues/auxiliary/issue-5521.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-5521.rs rename to src/test/ui/issues/auxiliary/issue-5521.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-7178.rs b/src/test/ui/issues/auxiliary/issue-7178.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-7178.rs rename to src/test/ui/issues/auxiliary/issue-7178.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-7899.rs b/src/test/ui/issues/auxiliary/issue-7899.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-7899.rs rename to src/test/ui/issues/auxiliary/issue-7899.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-8044.rs b/src/test/ui/issues/auxiliary/issue-8044.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-8044.rs rename to src/test/ui/issues/auxiliary/issue-8044.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-8259.rs b/src/test/ui/issues/auxiliary/issue-8259.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-8259.rs rename to src/test/ui/issues/auxiliary/issue-8259.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-8401.rs b/src/test/ui/issues/auxiliary/issue-8401.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-8401.rs rename to src/test/ui/issues/auxiliary/issue-8401.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-9123.rs b/src/test/ui/issues/auxiliary/issue-9123.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-9123.rs rename to src/test/ui/issues/auxiliary/issue-9123.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-9155.rs b/src/test/ui/issues/auxiliary/issue-9155.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-9155.rs rename to src/test/ui/issues/auxiliary/issue-9155.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-9188.rs b/src/test/ui/issues/auxiliary/issue-9188.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-9188.rs rename to src/test/ui/issues/auxiliary/issue-9188.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-9906.rs b/src/test/ui/issues/auxiliary/issue-9906.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-9906.rs rename to src/test/ui/issues/auxiliary/issue-9906.rs diff --git a/src/test/run-pass/issues/auxiliary/issue-9968.rs b/src/test/ui/issues/auxiliary/issue-9968.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue-9968.rs rename to src/test/ui/issues/auxiliary/issue-9968.rs diff --git a/src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs b/src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs new file mode 100644 index 0000000000..88a040529e --- /dev/null +++ b/src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs @@ -0,0 +1,5 @@ +// edition:2018 +#![crate_type="lib"] +#![crate_name="xcrate_issue_61711_b"] +pub struct Struct; +pub use crate as alias; diff --git a/src/test/run-pass/issues/issue-10025.rs b/src/test/ui/issues/issue-10025.rs similarity index 100% rename from src/test/run-pass/issues/issue-10025.rs rename to src/test/ui/issues/issue-10025.rs diff --git a/src/test/run-pass/issues/issue-10028.rs b/src/test/ui/issues/issue-10028.rs similarity index 100% rename from src/test/run-pass/issues/issue-10028.rs rename to src/test/ui/issues/issue-10028.rs diff --git a/src/test/run-pass/issues/issue-10031.rs b/src/test/ui/issues/issue-10031.rs similarity index 100% rename from src/test/run-pass/issues/issue-10031.rs rename to src/test/ui/issues/issue-10031.rs diff --git a/src/test/run-pass/issues/issue-10228.rs b/src/test/ui/issues/issue-10228.rs similarity index 100% rename from src/test/run-pass/issues/issue-10228.rs rename to src/test/ui/issues/issue-10228.rs diff --git a/src/test/run-pass/issues/issue-10392.rs b/src/test/ui/issues/issue-10392.rs similarity index 100% rename from src/test/run-pass/issues/issue-10392.rs rename to src/test/ui/issues/issue-10392.rs diff --git a/src/test/ui/issues/issue-10396.rs b/src/test/ui/issues/issue-10396.rs index d8e9aec818..0781e5e3ed 100644 --- a/src/test/ui/issues/issue-10396.rs +++ b/src/test/ui/issues/issue-10396.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Debug)] enum Foo<'s> { diff --git a/src/test/run-pass/issues/issue-10436.rs b/src/test/ui/issues/issue-10436.rs similarity index 100% rename from src/test/run-pass/issues/issue-10436.rs rename to src/test/ui/issues/issue-10436.rs diff --git a/src/test/ui/issues/issue-10456.rs b/src/test/ui/issues/issue-10456.rs index 4b548362f4..7eac095de5 100644 --- a/src/test/ui/issues/issue-10456.rs +++ b/src/test/ui/issues/issue-10456.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub struct Foo; diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index ceb44ecf7f..111078abb3 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -11,13 +11,9 @@ macro_rules! foo{ pub fn main() { foo!(); - assert!({one! two()}); - //~^ ERROR macros that expand to items - //~| ERROR cannot find macro `one!` in this scope - //~| ERROR mismatched types + assert!({one! two()}); //~ ERROR expected open delimiter // regardless of whether nested macro_rules works, the following should at // least throw a conventional error. - assert!({one! two}); - //~^ ERROR expected `(` or `{`, found `}` + assert!({one! two}); //~ ERROR expected open delimiter } diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index 584cdf43a8..73f948107f 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,38 +1,14 @@ -error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-10536.rs:14:22 +error: expected open delimiter + --> $DIR/issue-10536.rs:14:19 | LL | assert!({one! two()}); - | ^^ -help: change the delimiters to curly braces - | -LL | assert!({one! two {}}); - | ^^ -help: add a semicolon - | -LL | assert!({one! two();}); - | ^ + | ^^^ expected open delimiter -error: expected `(` or `{`, found `}` - --> $DIR/issue-10536.rs:21:22 +error: expected open delimiter + --> $DIR/issue-10536.rs:18:19 | LL | assert!({one! two}); - | ^ expected `(` or `{` - -error: cannot find macro `one!` in this scope - --> $DIR/issue-10536.rs:14:14 - | -LL | assert!({one! two()}); - | ^^^ - -error[E0308]: mismatched types - --> $DIR/issue-10536.rs:14:13 - | -LL | assert!({one! two()}); - | ^^^^^^^^^^^^ expected bool, found () - | - = note: expected type `bool` - found type `()` + | ^^^ expected open delimiter -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/run-pass/issues/issue-10626.rs b/src/test/ui/issues/issue-10626.rs similarity index 100% rename from src/test/run-pass/issues/issue-10626.rs rename to src/test/ui/issues/issue-10626.rs diff --git a/src/test/run-pass/issues/issue-10638.rs b/src/test/ui/issues/issue-10638.rs similarity index 100% rename from src/test/run-pass/issues/issue-10638.rs rename to src/test/ui/issues/issue-10638.rs diff --git a/src/test/run-pass/issues/issue-10682.rs b/src/test/ui/issues/issue-10682.rs similarity index 100% rename from src/test/run-pass/issues/issue-10682.rs rename to src/test/ui/issues/issue-10682.rs diff --git a/src/test/run-pass/issues/issue-10683.rs b/src/test/ui/issues/issue-10683.rs similarity index 100% rename from src/test/run-pass/issues/issue-10683.rs rename to src/test/ui/issues/issue-10683.rs diff --git a/src/test/run-pass/issues/issue-10718.rs b/src/test/ui/issues/issue-10718.rs similarity index 100% rename from src/test/run-pass/issues/issue-10718.rs rename to src/test/ui/issues/issue-10718.rs diff --git a/src/test/run-pass/issues/issue-10734.rs b/src/test/ui/issues/issue-10734.rs similarity index 100% rename from src/test/run-pass/issues/issue-10734.rs rename to src/test/ui/issues/issue-10734.rs diff --git a/src/test/ui/issues/issue-10763.rs b/src/test/ui/issues/issue-10763.rs index f2d4c5b47d..091a7c5296 100644 --- a/src/test/ui/issues/issue-10763.rs +++ b/src/test/ui/issues/issue-10763.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-10764.rs b/src/test/ui/issues/issue-10764-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-10764.rs rename to src/test/ui/issues/issue-10764-rpass.rs diff --git a/src/test/run-pass/issues/issue-10767.rs b/src/test/ui/issues/issue-10767.rs similarity index 100% rename from src/test/run-pass/issues/issue-10767.rs rename to src/test/ui/issues/issue-10767.rs diff --git a/src/test/run-pass/issues/issue-10802.rs b/src/test/ui/issues/issue-10802.rs similarity index 100% rename from src/test/run-pass/issues/issue-10802.rs rename to src/test/ui/issues/issue-10802.rs diff --git a/src/test/run-pass/issues/issue-10806.rs b/src/test/ui/issues/issue-10806.rs similarity index 100% rename from src/test/run-pass/issues/issue-10806.rs rename to src/test/ui/issues/issue-10806.rs diff --git a/src/test/ui/issues/issue-10853.rs b/src/test/ui/issues/issue-10853.rs index 0b74eaddcd..c9de39feda 100644 --- a/src/test/ui/issues/issue-10853.rs +++ b/src/test/ui/issues/issue-10853.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-10902.rs b/src/test/ui/issues/issue-10902.rs index 5e7f8ed7fd..d53ce9a1db 100644 --- a/src/test/ui/issues/issue-10902.rs +++ b/src/test/ui/issues/issue-10902.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-11047.rs b/src/test/ui/issues/issue-11047.rs similarity index 100% rename from src/test/run-pass/issues/issue-11047.rs rename to src/test/ui/issues/issue-11047.rs diff --git a/src/test/run-pass/issues/issue-11085.rs b/src/test/ui/issues/issue-11085.rs similarity index 100% rename from src/test/run-pass/issues/issue-11085.rs rename to src/test/ui/issues/issue-11085.rs diff --git a/src/test/run-pass/issues/issue-1112.rs b/src/test/ui/issues/issue-1112.rs similarity index 100% rename from src/test/run-pass/issues/issue-1112.rs rename to src/test/ui/issues/issue-1112.rs diff --git a/src/test/run-pass/issues/issue-11205.rs b/src/test/ui/issues/issue-11205.rs similarity index 100% rename from src/test/run-pass/issues/issue-11205.rs rename to src/test/ui/issues/issue-11205.rs diff --git a/src/test/run-pass/issues/issue-11224.rs b/src/test/ui/issues/issue-11224.rs similarity index 100% rename from src/test/run-pass/issues/issue-11224.rs rename to src/test/ui/issues/issue-11224.rs diff --git a/src/test/run-pass/issues/issue-11225-1.rs b/src/test/ui/issues/issue-11225-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-11225-1.rs rename to src/test/ui/issues/issue-11225-1.rs diff --git a/src/test/run-pass/issues/issue-11225-2.rs b/src/test/ui/issues/issue-11225-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-11225-2.rs rename to src/test/ui/issues/issue-11225-2.rs diff --git a/src/test/run-pass/issues/issue-11225-3.rs b/src/test/ui/issues/issue-11225-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-11225-3.rs rename to src/test/ui/issues/issue-11225-3.rs diff --git a/src/test/run-pass/issues/issue-11267.rs b/src/test/ui/issues/issue-11267.rs similarity index 100% rename from src/test/run-pass/issues/issue-11267.rs rename to src/test/ui/issues/issue-11267.rs diff --git a/src/test/run-pass/issues/issue-11382.rs b/src/test/ui/issues/issue-11382.rs similarity index 100% rename from src/test/run-pass/issues/issue-11382.rs rename to src/test/ui/issues/issue-11382.rs diff --git a/src/test/ui/issues/issue-11384.rs b/src/test/ui/issues/issue-11384.rs index 59d85b175c..443c2be08b 100644 --- a/src/test/ui/issues/issue-11384.rs +++ b/src/test/ui/issues/issue-11384.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Common { fn dummy(&self) { } } diff --git a/src/test/run-pass/issues/issue-11508.rs b/src/test/ui/issues/issue-11508.rs similarity index 100% rename from src/test/run-pass/issues/issue-11508.rs rename to src/test/ui/issues/issue-11508.rs diff --git a/src/test/run-pass/issues/issue-11529.rs b/src/test/ui/issues/issue-11529.rs similarity index 100% rename from src/test/run-pass/issues/issue-11529.rs rename to src/test/ui/issues/issue-11529.rs diff --git a/src/test/run-pass/issues/issue-11552.rs b/src/test/ui/issues/issue-11552.rs similarity index 100% rename from src/test/run-pass/issues/issue-11552.rs rename to src/test/ui/issues/issue-11552.rs diff --git a/src/test/run-pass/issues/issue-11577.rs b/src/test/ui/issues/issue-11577.rs similarity index 100% rename from src/test/run-pass/issues/issue-11577.rs rename to src/test/ui/issues/issue-11577.rs diff --git a/src/test/ui/issues/issue-11592.rs b/src/test/ui/issues/issue-11592.rs index e2028bd56f..0298f83baf 100644 --- a/src/test/ui/issues/issue-11592.rs +++ b/src/test/ui/issues/issue-11592.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! Ensure the private trait Bar isn't complained about. #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-11612.rs b/src/test/ui/issues/issue-11612.rs index fd4fb2443c..553648a5eb 100644 --- a/src/test/ui/issues/issue-11612.rs +++ b/src/test/ui/issues/issue-11612.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // #11612 // We weren't updating the auto adjustments with all the resolved diff --git a/src/test/run-pass/issues/issue-11677.rs b/src/test/ui/issues/issue-11677.rs similarity index 100% rename from src/test/run-pass/issues/issue-11677.rs rename to src/test/ui/issues/issue-11677.rs diff --git a/src/test/run-pass/issues/issue-11709.rs b/src/test/ui/issues/issue-11709.rs similarity index 100% rename from src/test/run-pass/issues/issue-11709.rs rename to src/test/ui/issues/issue-11709.rs diff --git a/src/test/run-pass/issues/issue-11820.rs b/src/test/ui/issues/issue-11820.rs similarity index 100% rename from src/test/run-pass/issues/issue-11820.rs rename to src/test/ui/issues/issue-11820.rs diff --git a/src/test/ui/issues/issue-11869.rs b/src/test/ui/issues/issue-11869.rs index e62879f1f2..a44094bfb2 100644 --- a/src/test/ui/issues/issue-11869.rs +++ b/src/test/ui/issues/issue-11869.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-11940.rs b/src/test/ui/issues/issue-11940.rs similarity index 100% rename from src/test/run-pass/issues/issue-11940.rs rename to src/test/ui/issues/issue-11940.rs diff --git a/src/test/run-pass/issues/issue-11958.rs b/src/test/ui/issues/issue-11958.rs similarity index 100% rename from src/test/run-pass/issues/issue-11958.rs rename to src/test/ui/issues/issue-11958.rs diff --git a/src/test/run-pass/issues/issue-12033.rs b/src/test/ui/issues/issue-12033.rs similarity index 100% rename from src/test/run-pass/issues/issue-12033.rs rename to src/test/ui/issues/issue-12033.rs diff --git a/src/test/run-pass/issues/issue-12133-1.rs b/src/test/ui/issues/issue-12133-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-12133-1.rs rename to src/test/ui/issues/issue-12133-1.rs diff --git a/src/test/run-pass/issues/issue-12133-2.rs b/src/test/ui/issues/issue-12133-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-12133-2.rs rename to src/test/ui/issues/issue-12133-2.rs diff --git a/src/test/run-pass/issues/issue-12133-3.rs b/src/test/ui/issues/issue-12133-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-12133-3.rs rename to src/test/ui/issues/issue-12133-3.rs diff --git a/src/test/run-pass/issues/issue-12285.rs b/src/test/ui/issues/issue-12285.rs similarity index 100% rename from src/test/run-pass/issues/issue-12285.rs rename to src/test/ui/issues/issue-12285.rs diff --git a/src/test/ui/issues/issue-12369.rs b/src/test/ui/issues/issue-12369.rs index 8df8efefd0..0866131807 100644 --- a/src/test/ui/issues/issue-12369.rs +++ b/src/test/ui/issues/issue-12369.rs @@ -6,7 +6,7 @@ fn main() { let v: isize = match &*sl { &[] => 0, &[a,b,c] => 3, - &[a, ref rest..] => a, - &[10,a, ref rest..] => 10 //~ ERROR: unreachable pattern + &[a, ref rest @ ..] => a, + &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern }; } diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr index fec9078dc4..f27425e28c 100644 --- a/src/test/ui/issues/issue-12369.stderr +++ b/src/test/ui/issues/issue-12369.stderr @@ -1,8 +1,8 @@ error: unreachable pattern --> $DIR/issue-12369.rs:10:9 | -LL | &[10,a, ref rest..] => 10 - | ^^^^^^^^^^^^^^^^^^^ +LL | &[10,a, ref rest @ ..] => 10 + | ^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here --> $DIR/issue-12369.rs:2:9 diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs index 84a14a8c09..63b5a4dd1b 100644 --- a/src/test/ui/issues/issue-1251.rs +++ b/src/test/ui/issues/issue-1251.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_attributes)] #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-1257.rs b/src/test/ui/issues/issue-1257.rs similarity index 100% rename from src/test/run-pass/issues/issue-1257.rs rename to src/test/ui/issues/issue-1257.rs diff --git a/src/test/run-pass/issues/issue-12582.rs b/src/test/ui/issues/issue-12582.rs similarity index 100% rename from src/test/run-pass/issues/issue-12582.rs rename to src/test/ui/issues/issue-12582.rs diff --git a/src/test/run-pass/issues/issue-12612.rs b/src/test/ui/issues/issue-12612.rs similarity index 100% rename from src/test/run-pass/issues/issue-12612.rs rename to src/test/ui/issues/issue-12612.rs diff --git a/src/test/run-pass/issues/issue-12660.rs b/src/test/ui/issues/issue-12660.rs similarity index 100% rename from src/test/run-pass/issues/issue-12660.rs rename to src/test/ui/issues/issue-12660.rs diff --git a/src/test/run-pass/issues/issue-12677.rs b/src/test/ui/issues/issue-12677.rs similarity index 100% rename from src/test/run-pass/issues/issue-12677.rs rename to src/test/ui/issues/issue-12677.rs diff --git a/src/test/run-pass/issues/issue-12699.rs b/src/test/ui/issues/issue-12699.rs similarity index 100% rename from src/test/run-pass/issues/issue-12699.rs rename to src/test/ui/issues/issue-12699.rs diff --git a/src/test/ui/issues/issue-12729.rs b/src/test/ui/issues/issue-12729.rs index c2572c7828..67c1bdc32e 100644 --- a/src/test/ui/issues/issue-12729.rs +++ b/src/test/ui/issues/issue-12729.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-12744.rs b/src/test/ui/issues/issue-12744.rs similarity index 100% rename from src/test/run-pass/issues/issue-12744.rs rename to src/test/ui/issues/issue-12744.rs diff --git a/src/test/run-pass/issues/issue-12860.rs b/src/test/ui/issues/issue-12860.rs similarity index 100% rename from src/test/run-pass/issues/issue-12860.rs rename to src/test/ui/issues/issue-12860.rs diff --git a/src/test/run-pass/issues/issue-12909.rs b/src/test/ui/issues/issue-12909.rs similarity index 100% rename from src/test/run-pass/issues/issue-12909.rs rename to src/test/ui/issues/issue-12909.rs diff --git a/src/test/ui/issues/issue-12997-1.rs b/src/test/ui/issues/issue-12997-1.rs index d00980e72f..9f808dac36 100644 --- a/src/test/ui/issues/issue-12997-1.rs +++ b/src/test/ui/issues/issue-12997-1.rs @@ -2,6 +2,8 @@ //! Test that makes sure wrongly-typed bench functions aren't ignored +#![feature(test)] + #[bench] fn foo() { } //~ ERROR functions used as benches diff --git a/src/test/ui/issues/issue-12997-1.stderr b/src/test/ui/issues/issue-12997-1.stderr index e036896812..00c605174f 100644 --- a/src/test/ui/issues/issue-12997-1.stderr +++ b/src/test/ui/issues/issue-12997-1.stderr @@ -1,11 +1,11 @@ error: functions used as benches must have signature `fn(&mut Bencher) -> impl Termination` - --> $DIR/issue-12997-1.rs:6:1 + --> $DIR/issue-12997-1.rs:8:1 | LL | fn foo() { } | ^^^^^^^^^^^^ error: functions used as benches must have signature `fn(&mut Bencher) -> impl Termination` - --> $DIR/issue-12997-1.rs:9:1 + --> $DIR/issue-12997-1.rs:11:1 | LL | fn bar(x: isize, y: isize) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-12997-2.rs b/src/test/ui/issues/issue-12997-2.rs index 8bf1a375bb..9df965315a 100644 --- a/src/test/ui/issues/issue-12997-2.rs +++ b/src/test/ui/issues/issue-12997-2.rs @@ -2,6 +2,8 @@ //! Test that makes sure wrongly-typed bench functions are rejected +#![feature(test)] + #[bench] fn bar(x: isize) { } //~^ ERROR mismatched types diff --git a/src/test/ui/issues/issue-12997-2.stderr b/src/test/ui/issues/issue-12997-2.stderr index e608c42a43..df8c936b82 100644 --- a/src/test/ui/issues/issue-12997-2.stderr +++ b/src/test/ui/issues/issue-12997-2.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-12997-2.rs:6:1 + --> $DIR/issue-12997-2.rs:8:1 | LL | fn bar(x: isize) { } | ^^^^^^^^^^^^^^^^^^^^ expected isize, found mutable reference diff --git a/src/test/run-pass/issues/issue-13027.rs b/src/test/ui/issues/issue-13027.rs similarity index 100% rename from src/test/run-pass/issues/issue-13027.rs rename to src/test/ui/issues/issue-13027.rs diff --git a/src/test/ui/issues/issue-13105.rs b/src/test/ui/issues/issue-13105.rs index 0e118043d5..2410e2f136 100644 --- a/src/test/ui/issues/issue-13105.rs +++ b/src/test/ui/issues/issue-13105.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/ui/issues/issue-13167.rs b/src/test/ui/issues/issue-13167.rs index dcc25a446f..e04faabb7e 100644 --- a/src/test/ui/issues/issue-13167.rs +++ b/src/test/ui/issues/issue-13167.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 use std::slice; diff --git a/src/test/run-pass/issues/issue-13204.rs b/src/test/ui/issues/issue-13204.rs similarity index 100% rename from src/test/run-pass/issues/issue-13204.rs rename to src/test/ui/issues/issue-13204.rs diff --git a/src/test/ui/issues/issue-13214.rs b/src/test/ui/issues/issue-13214.rs index af2d95c5e4..0015169b11 100644 --- a/src/test/ui/issues/issue-13214.rs +++ b/src/test/ui/issues/issue-13214.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // defining static with struct that contains enum // with &'static str variant used to cause ICE diff --git a/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs b/src/test/ui/issues/issue-13259-windows-tcb-trash.rs similarity index 100% rename from src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs rename to src/test/ui/issues/issue-13259-windows-tcb-trash.rs diff --git a/src/test/run-pass/issues/issue-13264.rs b/src/test/ui/issues/issue-13264.rs similarity index 100% rename from src/test/run-pass/issues/issue-13264.rs rename to src/test/ui/issues/issue-13264.rs diff --git a/src/test/run-pass/issues/issue-13304.rs b/src/test/ui/issues/issue-13304.rs similarity index 100% rename from src/test/run-pass/issues/issue-13304.rs rename to src/test/ui/issues/issue-13304.rs diff --git a/src/test/run-pass/issues/issue-13323.rs b/src/test/ui/issues/issue-13323.rs similarity index 100% rename from src/test/run-pass/issues/issue-13323.rs rename to src/test/ui/issues/issue-13323.rs diff --git a/src/test/ui/issues/issue-13405.rs b/src/test/ui/issues/issue-13405.rs index 32965cb0c6..fb48abe264 100644 --- a/src/test/ui/issues/issue-13405.rs +++ b/src/test/ui/issues/issue-13405.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-13434.rs b/src/test/ui/issues/issue-13434.rs similarity index 100% rename from src/test/run-pass/issues/issue-13434.rs rename to src/test/ui/issues/issue-13434.rs diff --git a/src/test/run-pass/issues/issue-13507-2.rs b/src/test/ui/issues/issue-13507-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-13507-2.rs rename to src/test/ui/issues/issue-13507-2.rs diff --git a/src/test/run-pass/issues/issue-13620.rs b/src/test/ui/issues/issue-13620.rs similarity index 100% rename from src/test/run-pass/issues/issue-13620.rs rename to src/test/ui/issues/issue-13620.rs diff --git a/src/test/run-pass/issues/issue-13655.rs b/src/test/ui/issues/issue-13655.rs similarity index 100% rename from src/test/run-pass/issues/issue-13655.rs rename to src/test/ui/issues/issue-13655.rs diff --git a/src/test/run-pass/issues/issue-13665.rs b/src/test/ui/issues/issue-13665.rs similarity index 100% rename from src/test/run-pass/issues/issue-13665.rs rename to src/test/ui/issues/issue-13665.rs diff --git a/src/test/ui/issues/issue-13703.rs b/src/test/ui/issues/issue-13703.rs index 212fff7bce..fe5458a7d7 100644 --- a/src/test/ui/issues/issue-13703.rs +++ b/src/test/ui/issues/issue-13703.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize } diff --git a/src/test/run-pass/issues/issue-13763.rs b/src/test/ui/issues/issue-13763.rs similarity index 100% rename from src/test/run-pass/issues/issue-13763.rs rename to src/test/ui/issues/issue-13763.rs diff --git a/src/test/ui/issues/issue-13775.rs b/src/test/ui/issues/issue-13775.rs index 39e42dc2c0..0359bb581d 100644 --- a/src/test/ui/issues/issue-13775.rs +++ b/src/test/ui/issues/issue-13775.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/run-pass/issues/issue-13808.rs b/src/test/ui/issues/issue-13808.rs similarity index 100% rename from src/test/run-pass/issues/issue-13808.rs rename to src/test/ui/issues/issue-13808.rs diff --git a/src/test/ui/issues/issue-13837.rs b/src/test/ui/issues/issue-13837.rs index d475ce1d83..06790fbd32 100644 --- a/src/test/ui/issues/issue-13837.rs +++ b/src/test/ui/issues/issue-13837.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-13867.rs b/src/test/ui/issues/issue-13867.rs similarity index 100% rename from src/test/run-pass/issues/issue-13867.rs rename to src/test/ui/issues/issue-13867.rs diff --git a/src/test/run-pass/issues/issue-13872.rs b/src/test/ui/issues/issue-13872.rs similarity index 100% rename from src/test/run-pass/issues/issue-13872.rs rename to src/test/ui/issues/issue-13872.rs diff --git a/src/test/run-pass/issues/issue-13902.rs b/src/test/ui/issues/issue-13902.rs similarity index 100% rename from src/test/run-pass/issues/issue-13902.rs rename to src/test/ui/issues/issue-13902.rs diff --git a/src/test/ui/issues/issue-14082.rs b/src/test/ui/issues/issue-14082.rs index 4849077c14..e5f1b492f2 100644 --- a/src/test/ui/issues/issue-14082.rs +++ b/src/test/ui/issues/issue-14082.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![allow(unused_imports, dead_code)] diff --git a/src/test/run-pass/issues/issue-14229.rs b/src/test/ui/issues/issue-14229.rs similarity index 100% rename from src/test/run-pass/issues/issue-14229.rs rename to src/test/ui/issues/issue-14229.rs diff --git a/src/test/ui/issues/issue-14254.rs b/src/test/ui/issues/issue-14254.rs index 3ad388dc2d..8b04fa192a 100644 --- a/src/test/ui/issues/issue-14254.rs +++ b/src/test/ui/issues/issue-14254.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Foo: Sized { diff --git a/src/test/run-pass/issues/issue-14308.rs b/src/test/ui/issues/issue-14308.rs similarity index 100% rename from src/test/run-pass/issues/issue-14308.rs rename to src/test/ui/issues/issue-14308.rs diff --git a/src/test/ui/issues/issue-14330.rs b/src/test/ui/issues/issue-14330.rs index d8f225eb07..be31fa5eab 100644 --- a/src/test/ui/issues/issue-14330.rs +++ b/src/test/ui/issues/issue-14330.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_imports)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-14344.rs b/src/test/ui/issues/issue-14344.rs similarity index 100% rename from src/test/run-pass/issues/issue-14344.rs rename to src/test/ui/issues/issue-14344.rs diff --git a/src/test/run-pass/issues/issue-14382.rs b/src/test/ui/issues/issue-14382.rs similarity index 100% rename from src/test/run-pass/issues/issue-14382.rs rename to src/test/ui/issues/issue-14382.rs diff --git a/src/test/run-pass/issues/issue-14393.rs b/src/test/ui/issues/issue-14393.rs similarity index 100% rename from src/test/run-pass/issues/issue-14393.rs rename to src/test/ui/issues/issue-14393.rs diff --git a/src/test/run-pass/issues/issue-14399.rs b/src/test/ui/issues/issue-14399.rs similarity index 100% rename from src/test/run-pass/issues/issue-14399.rs rename to src/test/ui/issues/issue-14399.rs diff --git a/src/test/run-pass/issues/issue-14421.rs b/src/test/ui/issues/issue-14421.rs similarity index 100% rename from src/test/run-pass/issues/issue-14421.rs rename to src/test/ui/issues/issue-14421.rs diff --git a/src/test/run-pass/issues/issue-14422.rs b/src/test/ui/issues/issue-14422.rs similarity index 100% rename from src/test/run-pass/issues/issue-14422.rs rename to src/test/ui/issues/issue-14422.rs diff --git a/src/test/run-pass/issues/issue-14456.rs b/src/test/ui/issues/issue-14456.rs similarity index 100% rename from src/test/run-pass/issues/issue-14456.rs rename to src/test/ui/issues/issue-14456.rs diff --git a/src/test/run-pass/issues/issue-1451.rs b/src/test/ui/issues/issue-1451.rs similarity index 100% rename from src/test/run-pass/issues/issue-1451.rs rename to src/test/ui/issues/issue-1451.rs diff --git a/src/test/run-pass/issues/issue-14589.rs b/src/test/ui/issues/issue-14589.rs similarity index 100% rename from src/test/run-pass/issues/issue-14589.rs rename to src/test/ui/issues/issue-14589.rs diff --git a/src/test/run-pass/issues/issue-1460.rs b/src/test/ui/issues/issue-1460.rs similarity index 100% rename from src/test/run-pass/issues/issue-1460.rs rename to src/test/ui/issues/issue-1460.rs diff --git a/src/test/run-pass/issues/issue-14821.rs b/src/test/ui/issues/issue-14821.rs similarity index 100% rename from src/test/run-pass/issues/issue-14821.rs rename to src/test/ui/issues/issue-14821.rs diff --git a/src/test/ui/issues/issue-14837.rs b/src/test/ui/issues/issue-14837.rs index 54387804af..a276e27f9d 100644 --- a/src/test/ui/issues/issue-14837.rs +++ b/src/test/ui/issues/issue-14837.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #[deny(dead_code)] diff --git a/src/test/run-pass/issues/issue-14865.rs b/src/test/ui/issues/issue-14865.rs similarity index 100% rename from src/test/run-pass/issues/issue-14865.rs rename to src/test/ui/issues/issue-14865.rs diff --git a/src/test/run-pass/issues/issue-14875.rs b/src/test/ui/issues/issue-14875.rs similarity index 100% rename from src/test/run-pass/issues/issue-14875.rs rename to src/test/ui/issues/issue-14875.rs diff --git a/src/test/ui/issues/issue-14901.rs b/src/test/ui/issues/issue-14901.rs index 9b89c1631d..c164658331 100644 --- a/src/test/ui/issues/issue-14901.rs +++ b/src/test/ui/issues/issue-14901.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Reader {} enum Wrapper<'a> { diff --git a/src/test/run-pass/issues/issue-14919.rs b/src/test/ui/issues/issue-14919.rs similarity index 100% rename from src/test/run-pass/issues/issue-14919.rs rename to src/test/ui/issues/issue-14919.rs diff --git a/src/test/ui/issues/issue-14933.rs b/src/test/ui/issues/issue-14933.rs index 9249ba3d64..f229c0f7c2 100644 --- a/src/test/ui/issues/issue-14933.rs +++ b/src/test/ui/issues/issue-14933.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub type BigRat = T; diff --git a/src/test/ui/issues/issue-14936.rs b/src/test/ui/issues/issue-14936.rs index bd3c99ad8d..809a108899 100644 --- a/src/test/ui/issues/issue-14936.rs +++ b/src/test/ui/issues/issue-14936.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_macros)] #![allow(dead_code)] #![feature(asm)] diff --git a/src/test/run-pass/issues/issue-14940.rs b/src/test/ui/issues/issue-14940.rs similarity index 100% rename from src/test/run-pass/issues/issue-14940.rs rename to src/test/ui/issues/issue-14940.rs diff --git a/src/test/run-pass/issues/issue-14958.rs b/src/test/ui/issues/issue-14958.rs similarity index 100% rename from src/test/run-pass/issues/issue-14958.rs rename to src/test/ui/issues/issue-14958.rs diff --git a/src/test/ui/issues/issue-14959.rs b/src/test/ui/issues/issue-14959.rs index 60daaafbcc..bd6c7a2bda 100644 --- a/src/test/ui/issues/issue-14959.rs +++ b/src/test/ui/issues/issue-14959.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(fn_traits, unboxed_closures)] diff --git a/src/test/run-pass/issues/issue-15043.rs b/src/test/ui/issues/issue-15043.rs similarity index 100% rename from src/test/run-pass/issues/issue-15043.rs rename to src/test/ui/issues/issue-15043.rs diff --git a/src/test/run-pass/issues/issue-15063.rs b/src/test/ui/issues/issue-15063.rs similarity index 100% rename from src/test/run-pass/issues/issue-15063.rs rename to src/test/ui/issues/issue-15063.rs diff --git a/src/test/run-pass/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs similarity index 82% rename from src/test/run-pass/issues/issue-15080.rs rename to src/test/ui/issues/issue-15080.rs index 4558118a80..b11b1cda38 100644 --- a/src/test/run-pass/issues/issue-15080.rs +++ b/src/test/ui/issues/issue-15080.rs @@ -7,11 +7,11 @@ fn main() { let mut result = vec![]; loop { x = match *x { - [1, n, 3, ref rest..] => { + [1, n, 3, ref rest @ ..] => { result.push(n); rest } - [n, ref rest..] => { + [n, ref rest @ ..] => { result.push(n); rest } diff --git a/src/test/run-pass/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs similarity index 81% rename from src/test/run-pass/issues/issue-15104.rs rename to src/test/ui/issues/issue-15104.rs index 3a03a52c32..ee97754113 100644 --- a/src/test/run-pass/issues/issue-15104.rs +++ b/src/test/ui/issues/issue-15104.rs @@ -9,6 +9,6 @@ fn count_members(v: &[usize]) -> usize { match *v { [] => 0, [_] => 1, - [_, ref xs..] => 1 + count_members(xs) + [_, ref xs @ ..] => 1 + count_members(xs) } } diff --git a/src/test/ui/issues/issue-15108.rs b/src/test/ui/issues/issue-15108.rs index d2b56c0949..b8231ad4e8 100644 --- a/src/test/ui/issues/issue-15108.rs +++ b/src/test/ui/issues/issue-15108.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 fn main() {} diff --git a/src/test/run-pass/issues/issue-15129.rs b/src/test/ui/issues/issue-15129-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-15129.rs rename to src/test/ui/issues/issue-15129-rpass.rs diff --git a/src/test/run-pass/issues/issue-15155.rs b/src/test/ui/issues/issue-15155.rs similarity index 100% rename from src/test/run-pass/issues/issue-15155.rs rename to src/test/ui/issues/issue-15155.rs diff --git a/src/test/run-pass/issues/issue-15189.rs b/src/test/ui/issues/issue-15189.rs similarity index 100% rename from src/test/run-pass/issues/issue-15189.rs rename to src/test/ui/issues/issue-15189.rs diff --git a/src/test/run-pass/issues/issue-15221.rs b/src/test/ui/issues/issue-15221.rs similarity index 100% rename from src/test/run-pass/issues/issue-15221.rs rename to src/test/ui/issues/issue-15221.rs diff --git a/src/test/ui/issues/issue-15261.rs b/src/test/ui/issues/issue-15261.rs index 4119cb055c..dd859475f9 100644 --- a/src/test/ui/issues/issue-15261.rs +++ b/src/test/ui/issues/issue-15261.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-15381.nll.stderr b/src/test/ui/issues/issue-15381.nll.stderr deleted file mode 100644 index a8495846b3..0000000000 --- a/src/test/ui/issues/issue-15381.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered - --> $DIR/issue-15381.rs:4:9 - | -LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { - | ^^^^^^^^ pattern `&[]` not covered - -error[E0381]: borrow of possibly uninitialized variable: `y` - --> $DIR/issue-15381.rs:6:26 - | -LL | println!("y={}", y); - | ^ use of possibly uninitialized `y` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0005, E0381. -For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/ui/issues/issue-15381.rs b/src/test/ui/issues/issue-15381.rs index 3dbd4e717a..d21c321b09 100644 --- a/src/test/ui/issues/issue-15381.rs +++ b/src/test/ui/issues/issue-15381.rs @@ -4,8 +4,6 @@ fn main() { for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { //~^ ERROR refutable pattern in `for` loop binding: `&[]` not covered println!("y={}", y); - //~^ WARN borrow of possibly uninitialized variable: `y` - //~| WARN this error has been downgraded to a warning for backwards compatibility - //~| WARN this represents potential undefined behavior in your code and this warning will + //~^ ERROR borrow of possibly uninitialized variable: `y` } } diff --git a/src/test/ui/issues/issue-15381.stderr b/src/test/ui/issues/issue-15381.stderr index 7b11d85ead..a8495846b3 100644 --- a/src/test/ui/issues/issue-15381.stderr +++ b/src/test/ui/issues/issue-15381.stderr @@ -4,17 +4,13 @@ error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { | ^^^^^^^^ pattern `&[]` not covered -warning[E0381]: borrow of possibly uninitialized variable: `y` +error[E0381]: borrow of possibly uninitialized variable: `y` --> $DIR/issue-15381.rs:6:26 | LL | println!("y={}", y); | ^ use of possibly uninitialized `y` - | - = warning: this error has been downgraded to a warning for backwards compatibility with previous releases - = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future - = note: for more information, try `rustc --explain E0729` -error: aborting due to previous error +error: aborting due to 2 previous errors Some errors have detailed explanations: E0005, E0381. For more information about an error, try `rustc --explain E0005`. diff --git a/src/test/run-pass/issues/issue-15444.rs b/src/test/ui/issues/issue-15444.rs similarity index 100% rename from src/test/run-pass/issues/issue-15444.rs rename to src/test/ui/issues/issue-15444.rs diff --git a/src/test/run-pass/issues/issue-15487.rs b/src/test/ui/issues/issue-15487.rs similarity index 100% rename from src/test/run-pass/issues/issue-15487.rs rename to src/test/ui/issues/issue-15487.rs diff --git a/src/test/run-pass/issues/issue-15523-big.rs b/src/test/ui/issues/issue-15523-big.rs similarity index 100% rename from src/test/run-pass/issues/issue-15523-big.rs rename to src/test/ui/issues/issue-15523-big.rs diff --git a/src/test/run-pass/issues/issue-15523.rs b/src/test/ui/issues/issue-15523.rs similarity index 100% rename from src/test/run-pass/issues/issue-15523.rs rename to src/test/ui/issues/issue-15523.rs diff --git a/src/test/run-pass/issues/issue-15562.rs b/src/test/ui/issues/issue-15562.rs similarity index 100% rename from src/test/run-pass/issues/issue-15562.rs rename to src/test/ui/issues/issue-15562.rs diff --git a/src/test/run-pass/issues/issue-15571.rs b/src/test/ui/issues/issue-15571.rs similarity index 100% rename from src/test/run-pass/issues/issue-15571.rs rename to src/test/ui/issues/issue-15571.rs diff --git a/src/test/run-pass/issues/issue-15673.rs b/src/test/ui/issues/issue-15673.rs similarity index 100% rename from src/test/run-pass/issues/issue-15673.rs rename to src/test/ui/issues/issue-15673.rs diff --git a/src/test/run-pass/issues/issue-15689-1.rs b/src/test/ui/issues/issue-15689-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-15689-1.rs rename to src/test/ui/issues/issue-15689-1.rs diff --git a/src/test/ui/issues/issue-15689-2.rs b/src/test/ui/issues/issue-15689-2.rs index 4a13261139..1731a356cc 100644 --- a/src/test/ui/issues/issue-15689-2.rs +++ b/src/test/ui/issues/issue-15689-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-15730.rs b/src/test/ui/issues/issue-15730.rs similarity index 100% rename from src/test/run-pass/issues/issue-15730.rs rename to src/test/ui/issues/issue-15730.rs diff --git a/src/test/run-pass/issues/issue-15734.rs b/src/test/ui/issues/issue-15734.rs similarity index 100% rename from src/test/run-pass/issues/issue-15734.rs rename to src/test/ui/issues/issue-15734.rs diff --git a/src/test/ui/issues/issue-15735.rs b/src/test/ui/issues/issue-15735.rs index 20634cc388..0da4d4a620 100644 --- a/src/test/ui/issues/issue-15735.rs +++ b/src/test/ui/issues/issue-15735.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A<'a> { a: &'a i32, diff --git a/src/test/run-pass/issues/issue-15763.rs b/src/test/ui/issues/issue-15763.rs similarity index 100% rename from src/test/run-pass/issues/issue-15763.rs rename to src/test/ui/issues/issue-15763.rs diff --git a/src/test/run-pass/issues/issue-15774.rs b/src/test/ui/issues/issue-15774.rs similarity index 100% rename from src/test/run-pass/issues/issue-15774.rs rename to src/test/ui/issues/issue-15774.rs diff --git a/src/test/run-pass/issues/issue-15793.rs b/src/test/ui/issues/issue-15793.rs similarity index 100% rename from src/test/run-pass/issues/issue-15793.rs rename to src/test/ui/issues/issue-15793.rs diff --git a/src/test/run-pass/issues/issue-15858.rs b/src/test/ui/issues/issue-15858.rs similarity index 100% rename from src/test/run-pass/issues/issue-15858.rs rename to src/test/ui/issues/issue-15858.rs diff --git a/src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.rs b/src/test/ui/issues/issue-15881-model-lexer-dotdotdot.rs similarity index 100% rename from src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.rs rename to src/test/ui/issues/issue-15881-model-lexer-dotdotdot.rs diff --git a/src/test/ui/issues/issue-15919-32.rs b/src/test/ui/issues/issue-15919-32.rs new file mode 100644 index 0000000000..65d33a6134 --- /dev/null +++ b/src/test/ui/issues/issue-15919-32.rs @@ -0,0 +1,12 @@ +// ignore-64bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn main() { + let x = [0usize; 0xffff_ffff]; //~ ERROR too big +} + +// This and the -64 version of this test need to have different literals, as we can't rely on +// conditional compilation for them while retaining the same spans/lines. diff --git a/src/test/ui/issues/issue-15919-32.stderr b/src/test/ui/issues/issue-15919-32.stderr new file mode 100644 index 0000000000..7f5d9262d3 --- /dev/null +++ b/src/test/ui/issues/issue-15919-32.stderr @@ -0,0 +1,8 @@ +error: the type `[usize; 4294967295]` is too big for the current architecture + --> $DIR/issue-15919-32.rs:8:9 + | +LL | let x = [0usize; 0xffff_ffff]; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-15919-64.rs b/src/test/ui/issues/issue-15919-64.rs new file mode 100644 index 0000000000..abd20cc1ce --- /dev/null +++ b/src/test/ui/issues/issue-15919-64.rs @@ -0,0 +1,12 @@ +// ignore-32bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn main() { + let x = [0usize; 0xffff_ffff_ffff_ffff]; //~ ERROR too big +} + +// This and the -32 version of this test need to have different literals, as we can't rely on +// conditional compilation for them while retaining the same spans/lines. diff --git a/src/test/ui/issues/issue-15919-64.stderr b/src/test/ui/issues/issue-15919-64.stderr new file mode 100644 index 0000000000..571b87d996 --- /dev/null +++ b/src/test/ui/issues/issue-15919-64.stderr @@ -0,0 +1,8 @@ +error: the type `[usize; 18446744073709551615]` is too big for the current architecture + --> $DIR/issue-15919-64.rs:8:9 + | +LL | let x = [0usize; 0xffff_ffff_ffff_ffff]; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-15919.rs b/src/test/ui/issues/issue-15919.rs deleted file mode 100644 index a7ac4802a1..0000000000 --- a/src/test/ui/issues/issue-15919.rs +++ /dev/null @@ -1,16 +0,0 @@ -// error-pattern: too big for the current architecture -// normalize-stderr-test "\[usize; \d+\]" -> "[usize; N]" - -// FIXME https://github.com/rust-lang/rust/issues/59774 -// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" -// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" - -#[cfg(target_pointer_width = "32")] -fn main() { - let x = [0usize; 0xffff_ffff]; -} - -#[cfg(target_pointer_width = "64")] -fn main() { - let x = [0usize; 0xffff_ffff_ffff_ffff]; -} diff --git a/src/test/ui/issues/issue-15919.stderr b/src/test/ui/issues/issue-15919.stderr deleted file mode 100644 index e4e88cc47c..0000000000 --- a/src/test/ui/issues/issue-15919.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: the type `[usize; N]` is too big for the current architecture - -error: aborting due to previous error - diff --git a/src/test/run-pass/issues/issue-16151.rs b/src/test/ui/issues/issue-16151.rs similarity index 100% rename from src/test/run-pass/issues/issue-16151.rs rename to src/test/ui/issues/issue-16151.rs diff --git a/src/test/ui/issues/issue-16250.stderr b/src/test/ui/issues/issue-16250.stderr index 142d8e2153..f3686e82b0 100644 --- a/src/test/ui/issues/issue-16250.stderr +++ b/src/test/ui/issues/issue-16250.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(improper_ctypes)] implied by #[deny(warnings)] + = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]` = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct note: type defined here --> $DIR/issue-16250.rs:3:1 diff --git a/src/test/run-pass/issues/issue-16256.rs b/src/test/ui/issues/issue-16256.rs similarity index 100% rename from src/test/run-pass/issues/issue-16256.rs rename to src/test/ui/issues/issue-16256.rs diff --git a/src/test/run-pass/issues/issue-16272.rs b/src/test/ui/issues/issue-16272.rs similarity index 100% rename from src/test/run-pass/issues/issue-16272.rs rename to src/test/ui/issues/issue-16272.rs diff --git a/src/test/run-pass/issues/issue-16278.rs b/src/test/ui/issues/issue-16278.rs similarity index 100% rename from src/test/run-pass/issues/issue-16278.rs rename to src/test/ui/issues/issue-16278.rs diff --git a/src/test/run-pass/issues/issue-16441.rs b/src/test/ui/issues/issue-16441.rs similarity index 100% rename from src/test/run-pass/issues/issue-16441.rs rename to src/test/ui/issues/issue-16441.rs diff --git a/src/test/run-pass/issues/issue-16452.rs b/src/test/ui/issues/issue-16452.rs similarity index 100% rename from src/test/run-pass/issues/issue-16452.rs rename to src/test/ui/issues/issue-16452.rs diff --git a/src/test/run-pass/issues/issue-16492.rs b/src/test/ui/issues/issue-16492.rs similarity index 100% rename from src/test/run-pass/issues/issue-16492.rs rename to src/test/ui/issues/issue-16492.rs diff --git a/src/test/run-pass/issues/issue-16530.rs b/src/test/ui/issues/issue-16530.rs similarity index 100% rename from src/test/run-pass/issues/issue-16530.rs rename to src/test/ui/issues/issue-16530.rs diff --git a/src/test/run-pass/issues/issue-16560.rs b/src/test/ui/issues/issue-16560.rs similarity index 100% rename from src/test/run-pass/issues/issue-16560.rs rename to src/test/ui/issues/issue-16560.rs diff --git a/src/test/ui/issues/issue-16596.rs b/src/test/ui/issues/issue-16596.rs index 3aa6c20ec5..693dea436b 100644 --- a/src/test/ui/issues/issue-16596.rs +++ b/src/test/ui/issues/issue-16596.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait MatrixRow { fn dummy(&self) { }} diff --git a/src/test/run-pass/issues/issue-16597-empty.rs b/src/test/ui/issues/issue-16597-empty.rs similarity index 100% rename from src/test/run-pass/issues/issue-16597-empty.rs rename to src/test/ui/issues/issue-16597-empty.rs diff --git a/src/test/run-pass/issues/issue-16597.rs b/src/test/ui/issues/issue-16597.rs similarity index 100% rename from src/test/run-pass/issues/issue-16597.rs rename to src/test/ui/issues/issue-16597.rs diff --git a/src/test/run-pass/issues/issue-1660.rs b/src/test/ui/issues/issue-1660.rs similarity index 100% rename from src/test/run-pass/issues/issue-1660.rs rename to src/test/ui/issues/issue-1660.rs diff --git a/src/test/run-pass/issues/issue-16602-1.rs b/src/test/ui/issues/issue-16602-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-16602-1.rs rename to src/test/ui/issues/issue-16602-1.rs diff --git a/src/test/run-pass/issues/issue-16602-2.rs b/src/test/ui/issues/issue-16602-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-16602-2.rs rename to src/test/ui/issues/issue-16602-2.rs diff --git a/src/test/run-pass/issues/issue-16602-3.rs b/src/test/ui/issues/issue-16602-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-16602-3.rs rename to src/test/ui/issues/issue-16602-3.rs diff --git a/src/test/run-pass/issues/issue-16643.rs b/src/test/ui/issues/issue-16643.rs similarity index 100% rename from src/test/run-pass/issues/issue-16643.rs rename to src/test/ui/issues/issue-16643.rs diff --git a/src/test/run-pass/issues/issue-16648.rs b/src/test/ui/issues/issue-16648.rs similarity index 100% rename from src/test/run-pass/issues/issue-16648.rs rename to src/test/ui/issues/issue-16648.rs diff --git a/src/test/ui/issues/issue-16668.rs b/src/test/ui/issues/issue-16668.rs index b570a2ced6..a898ab20a4 100644 --- a/src/test/ui/issues/issue-16668.rs +++ b/src/test/ui/issues/issue-16668.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Parser<'a, I, O> { parse: Box Result + 'a> diff --git a/src/test/run-pass/issues/issue-16671.rs b/src/test/ui/issues/issue-16671.rs similarity index 100% rename from src/test/run-pass/issues/issue-16671.rs rename to src/test/ui/issues/issue-16671.rs diff --git a/src/test/run-pass/issues/issue-16739.rs b/src/test/ui/issues/issue-16739.rs similarity index 100% rename from src/test/run-pass/issues/issue-16739.rs rename to src/test/ui/issues/issue-16739.rs diff --git a/src/test/run-pass/issues/issue-16745.rs b/src/test/ui/issues/issue-16745.rs similarity index 100% rename from src/test/run-pass/issues/issue-16745.rs rename to src/test/ui/issues/issue-16745.rs diff --git a/src/test/run-pass/issues/issue-16774.rs b/src/test/ui/issues/issue-16774.rs similarity index 100% rename from src/test/run-pass/issues/issue-16774.rs rename to src/test/ui/issues/issue-16774.rs diff --git a/src/test/run-pass/issues/issue-16783.rs b/src/test/ui/issues/issue-16783.rs similarity index 100% rename from src/test/run-pass/issues/issue-16783.rs rename to src/test/ui/issues/issue-16783.rs diff --git a/src/test/run-pass/issues/issue-16819.rs b/src/test/ui/issues/issue-16819.rs similarity index 100% rename from src/test/run-pass/issues/issue-16819.rs rename to src/test/ui/issues/issue-16819.rs diff --git a/src/test/run-pass/issues/issue-16922.rs b/src/test/ui/issues/issue-16922-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-16922.rs rename to src/test/ui/issues/issue-16922-rpass.rs diff --git a/src/test/run-pass/issues/issue-1696.rs b/src/test/ui/issues/issue-1696.rs similarity index 100% rename from src/test/run-pass/issues/issue-1696.rs rename to src/test/ui/issues/issue-1696.rs diff --git a/src/test/ui/issues/issue-1697.rs b/src/test/ui/issues/issue-1697.rs index 30b2558dce..5cd76d21f9 100644 --- a/src/test/ui/issues/issue-1697.rs +++ b/src/test/ui/issues/issue-1697.rs @@ -1,6 +1,6 @@ // Testing that we don't fail abnormally after hitting the errors use unresolved::*; //~ ERROR unresolved import `unresolved` [E0432] - //~^ maybe a missing `extern crate unresolved;`? + //~^ maybe a missing crate `unresolved`? fn main() {} diff --git a/src/test/ui/issues/issue-1697.stderr b/src/test/ui/issues/issue-1697.stderr index 6ae5bd1fc2..a76fd30991 100644 --- a/src/test/ui/issues/issue-1697.stderr +++ b/src/test/ui/issues/issue-1697.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `unresolved` --> $DIR/issue-1697.rs:3:5 | LL | use unresolved::*; - | ^^^^^^^^^^ maybe a missing `extern crate unresolved;`? + | ^^^^^^^^^^ maybe a missing crate `unresolved`? error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-1701.rs b/src/test/ui/issues/issue-1701.rs similarity index 100% rename from src/test/run-pass/issues/issue-1701.rs rename to src/test/ui/issues/issue-1701.rs diff --git a/src/test/run-pass/issues/issue-17068.rs b/src/test/ui/issues/issue-17068.rs similarity index 100% rename from src/test/run-pass/issues/issue-17068.rs rename to src/test/ui/issues/issue-17068.rs diff --git a/src/test/run-pass/issues/issue-17074.rs b/src/test/ui/issues/issue-17074.rs similarity index 100% rename from src/test/run-pass/issues/issue-17074.rs rename to src/test/ui/issues/issue-17074.rs diff --git a/src/test/ui/issues/issue-17121.rs b/src/test/ui/issues/issue-17121.rs index 706350fc1e..0f1d4f5410 100644 --- a/src/test/ui/issues/issue-17121.rs +++ b/src/test/ui/issues/issue-17121.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 // ignore-cloudabi no std::fs diff --git a/src/test/run-pass/issues/issue-17170.rs b/src/test/ui/issues/issue-17170.rs similarity index 100% rename from src/test/run-pass/issues/issue-17170.rs rename to src/test/ui/issues/issue-17170.rs diff --git a/src/test/run-pass/issues/issue-17216.rs b/src/test/ui/issues/issue-17216.rs similarity index 100% rename from src/test/run-pass/issues/issue-17216.rs rename to src/test/ui/issues/issue-17216.rs diff --git a/src/test/run-pass/issues/issue-17233.rs b/src/test/ui/issues/issue-17233.rs similarity index 100% rename from src/test/run-pass/issues/issue-17233.rs rename to src/test/ui/issues/issue-17233.rs diff --git a/src/test/ui/issues/issue-17263.rs b/src/test/ui/issues/issue-17263.rs index dce30275ff..f24acb7b30 100644 --- a/src/test/ui/issues/issue-17263.rs +++ b/src/test/ui/issues/issue-17263.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_syntax)] diff --git a/src/test/run-pass/issues/issue-17302.rs b/src/test/ui/issues/issue-17302.rs similarity index 100% rename from src/test/run-pass/issues/issue-17302.rs rename to src/test/ui/issues/issue-17302.rs diff --git a/src/test/run-pass/issues/issue-17322.rs b/src/test/ui/issues/issue-17322.rs similarity index 100% rename from src/test/run-pass/issues/issue-17322.rs rename to src/test/ui/issues/issue-17322.rs diff --git a/src/test/ui/issues/issue-17336.rs b/src/test/ui/issues/issue-17336.rs index e2c0e8b91c..830d799fb6 100644 --- a/src/test/ui/issues/issue-17336.rs +++ b/src/test/ui/issues/issue-17336.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] #[allow(dead_code)] fn check(a: &str) { diff --git a/src/test/run-pass/issues/issue-17351.rs b/src/test/ui/issues/issue-17351.rs similarity index 100% rename from src/test/run-pass/issues/issue-17351.rs rename to src/test/ui/issues/issue-17351.rs diff --git a/src/test/run-pass/issues/issue-17361.rs b/src/test/ui/issues/issue-17361.rs similarity index 100% rename from src/test/run-pass/issues/issue-17361.rs rename to src/test/ui/issues/issue-17361.rs diff --git a/src/test/ui/issues/issue-17450.rs b/src/test/ui/issues/issue-17450.rs index 70f33e3e66..595e0a4d25 100644 --- a/src/test/ui/issues/issue-17450.rs +++ b/src/test/ui/issues/issue-17450.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, warnings)] static mut x: isize = 3; diff --git a/src/test/ui/issues/issue-17458.stderr b/src/test/ui/issues/issue-17458.stderr index d51d2f50d6..bb667e7b7d 100644 --- a/src/test/ui/issues/issue-17458.stderr +++ b/src/test/ui/issues/issue-17458.stderr @@ -5,7 +5,7 @@ LL | static X: usize = unsafe { core::ptr::null::() as usize }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51910 - = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-17503.rs b/src/test/ui/issues/issue-17503.rs similarity index 100% rename from src/test/run-pass/issues/issue-17503.rs rename to src/test/ui/issues/issue-17503.rs diff --git a/src/test/run-pass/issues/issue-17662.rs b/src/test/ui/issues/issue-17662.rs similarity index 100% rename from src/test/run-pass/issues/issue-17662.rs rename to src/test/ui/issues/issue-17662.rs diff --git a/src/test/run-pass/issues/issue-17718-borrow-interior.rs b/src/test/ui/issues/issue-17718-borrow-interior.rs similarity index 100% rename from src/test/run-pass/issues/issue-17718-borrow-interior.rs rename to src/test/ui/issues/issue-17718-borrow-interior.rs diff --git a/src/test/ui/issues/issue-17718-const-destructors.rs b/src/test/ui/issues/issue-17718-const-destructors.rs index 133420b688..7ec025ec3a 100644 --- a/src/test/ui/issues/issue-17718-const-destructors.rs +++ b/src/test/ui/issues/issue-17718-const-destructors.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A; impl Drop for A { diff --git a/src/test/ui/issues/issue-17718-const-naming.stderr b/src/test/ui/issues/issue-17718-const-naming.stderr index b92acecb83..1fe1821292 100644 --- a/src/test/ui/issues/issue-17718-const-naming.stderr +++ b/src/test/ui/issues/issue-17718-const-naming.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(dead_code)] implied by #[deny(warnings)] + = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` error: constant `foo` should have an upper case name --> $DIR/issue-17718-const-naming.rs:4:7 @@ -22,7 +22,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(non_upper_case_globals)] implied by #[deny(warnings)] + = note: `#[deny(non_upper_case_globals)]` implied by `#[deny(warnings)]` error: aborting due to 2 previous errors diff --git a/src/test/run-pass/issues/issue-17718-parse-const.rs b/src/test/ui/issues/issue-17718-parse-const.rs similarity index 100% rename from src/test/run-pass/issues/issue-17718-parse-const.rs rename to src/test/ui/issues/issue-17718-parse-const.rs diff --git a/src/test/run-pass/issues/issue-17718-static-unsafe-interior.rs b/src/test/ui/issues/issue-17718-static-unsafe-interior.rs similarity index 100% rename from src/test/run-pass/issues/issue-17718-static-unsafe-interior.rs rename to src/test/ui/issues/issue-17718-static-unsafe-interior.rs diff --git a/src/test/run-pass/issues/issue-17718.rs b/src/test/ui/issues/issue-17718.rs similarity index 100% rename from src/test/run-pass/issues/issue-17718.rs rename to src/test/ui/issues/issue-17718.rs diff --git a/src/test/ui/issues/issue-17732.rs b/src/test/ui/issues/issue-17732.rs index 7993bbb38b..17135c191c 100644 --- a/src/test/ui/issues/issue-17732.rs +++ b/src/test/ui/issues/issue-17732.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-17734.rs b/src/test/ui/issues/issue-17734.rs similarity index 100% rename from src/test/run-pass/issues/issue-17734.rs rename to src/test/ui/issues/issue-17734.rs diff --git a/src/test/ui/issues/issue-17746.rs b/src/test/ui/issues/issue-17746.rs index 45c5b858ec..847b2eb60b 100644 --- a/src/test/ui/issues/issue-17746.rs +++ b/src/test/ui/issues/issue-17746.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #17746 diff --git a/src/test/run-pass/issues/issue-17756.rs b/src/test/ui/issues/issue-17756.rs similarity index 100% rename from src/test/run-pass/issues/issue-17756.rs rename to src/test/ui/issues/issue-17756.rs diff --git a/src/test/run-pass/issues/issue-17771.rs b/src/test/ui/issues/issue-17771.rs similarity index 100% rename from src/test/run-pass/issues/issue-17771.rs rename to src/test/ui/issues/issue-17771.rs diff --git a/src/test/run-pass/issues/issue-17816.rs b/src/test/ui/issues/issue-17816.rs similarity index 100% rename from src/test/run-pass/issues/issue-17816.rs rename to src/test/ui/issues/issue-17816.rs diff --git a/src/test/run-pass/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs similarity index 77% rename from src/test/run-pass/issues/issue-17877.rs rename to src/test/ui/issues/issue-17877.rs index af22b1ad8f..fefa3f2f87 100644 --- a/src/test/run-pass/issues/issue-17877.rs +++ b/src/test/ui/issues/issue-17877.rs @@ -7,8 +7,8 @@ fn main() { }, 42_usize); assert_eq!(match [0u8; 1024] { - [1, _..] => 0_usize, - [0, _..] => 1_usize, + [1, ..] => 0_usize, + [0, ..] => 1_usize, _ => 2_usize }, 1_usize); } diff --git a/src/test/run-pass/issues/issue-17897.rs b/src/test/ui/issues/issue-17897.rs similarity index 100% rename from src/test/run-pass/issues/issue-17897.rs rename to src/test/ui/issues/issue-17897.rs diff --git a/src/test/ui/issues/issue-17904.rs b/src/test/ui/issues/issue-17904.rs index 2fe54957b3..d916abb9c7 100644 --- a/src/test/ui/issues/issue-17904.rs +++ b/src/test/ui/issues/issue-17904.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test that we can parse where clauses on various forms of tuple // structs. diff --git a/src/test/run-pass/issues/issue-18060.rs b/src/test/ui/issues/issue-18060.rs similarity index 100% rename from src/test/run-pass/issues/issue-18060.rs rename to src/test/ui/issues/issue-18060.rs diff --git a/src/test/run-pass/issues/issue-18075.rs b/src/test/ui/issues/issue-18075.rs similarity index 100% rename from src/test/run-pass/issues/issue-18075.rs rename to src/test/ui/issues/issue-18075.rs diff --git a/src/test/ui/issues/issue-18083.rs b/src/test/ui/issues/issue-18083.rs index c2cf2919ff..f159ed4a0c 100644 --- a/src/test/ui/issues/issue-18083.rs +++ b/src/test/ui/issues/issue-18083.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_imports)] // These crossed imports should resolve fine, and not block on diff --git a/src/test/ui/issues/issue-18088.rs b/src/test/ui/issues/issue-18088.rs index 67000d9a6e..06f259958f 100644 --- a/src/test/ui/issues/issue-18088.rs +++ b/src/test/ui/issues/issue-18088.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Indexable: std::ops::Index { fn index2(&self, i: usize) -> &T { diff --git a/src/test/run-pass/issues/issue-18110.rs b/src/test/ui/issues/issue-18110.rs similarity index 100% rename from src/test/run-pass/issues/issue-18110.rs rename to src/test/ui/issues/issue-18110.rs diff --git a/src/test/run-pass/issues/issue-18173.rs b/src/test/ui/issues/issue-18173.rs similarity index 100% rename from src/test/run-pass/issues/issue-18173.rs rename to src/test/ui/issues/issue-18173.rs diff --git a/src/test/ui/issues/issue-18188.rs b/src/test/ui/issues/issue-18188.rs index 4d0c446475..da10a8647b 100644 --- a/src/test/ui/issues/issue-18188.rs +++ b/src/test/ui/issues/issue-18188.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub trait Promisable: Send + Sync {} diff --git a/src/test/ui/issues/issue-1821.rs b/src/test/ui/issues/issue-1821.rs index 0177b70a69..db97a507b6 100644 --- a/src/test/ui/issues/issue-1821.rs +++ b/src/test/ui/issues/issue-1821.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/issues/issue-18232.rs b/src/test/ui/issues/issue-18232.rs similarity index 100% rename from src/test/run-pass/issues/issue-18232.rs rename to src/test/ui/issues/issue-18232.rs diff --git a/src/test/ui/issues/issue-18294.stderr b/src/test/ui/issues/issue-18294.stderr index d10242434b..7d6ef5eee0 100644 --- a/src/test/ui/issues/issue-18294.stderr +++ b/src/test/ui/issues/issue-18294.stderr @@ -5,7 +5,7 @@ LL | const Y: usize = unsafe { &X as *const u32 as usize }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51910 - = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-18352.rs b/src/test/ui/issues/issue-18352.rs similarity index 100% rename from src/test/run-pass/issues/issue-18352.rs rename to src/test/ui/issues/issue-18352.rs diff --git a/src/test/run-pass/issues/issue-18353.rs b/src/test/ui/issues/issue-18353.rs similarity index 100% rename from src/test/run-pass/issues/issue-18353.rs rename to src/test/ui/issues/issue-18353.rs diff --git a/src/test/run-pass/issues/issue-18412.rs b/src/test/ui/issues/issue-18412.rs similarity index 100% rename from src/test/run-pass/issues/issue-18412.rs rename to src/test/ui/issues/issue-18412.rs diff --git a/src/test/run-pass/issues/issue-18425.rs b/src/test/ui/issues/issue-18425.rs similarity index 100% rename from src/test/run-pass/issues/issue-18425.rs rename to src/test/ui/issues/issue-18425.rs diff --git a/src/test/ui/issues/issue-18446-2.rs b/src/test/ui/issues/issue-18446-2.rs index 3e04a914d4..6b984c13da 100644 --- a/src/test/ui/issues/issue-18446-2.rs +++ b/src/test/ui/issues/issue-18446-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test that methods in trait impls should override default methods. diff --git a/src/test/run-pass/issues/issue-18464.rs b/src/test/ui/issues/issue-18464.rs similarity index 100% rename from src/test/run-pass/issues/issue-18464.rs rename to src/test/ui/issues/issue-18464.rs diff --git a/src/test/run-pass/issues/issue-18501.rs b/src/test/ui/issues/issue-18501.rs similarity index 100% rename from src/test/run-pass/issues/issue-18501.rs rename to src/test/ui/issues/issue-18501.rs diff --git a/src/test/run-pass/issues/issue-18514.rs b/src/test/ui/issues/issue-18514.rs similarity index 100% rename from src/test/run-pass/issues/issue-18514.rs rename to src/test/ui/issues/issue-18514.rs diff --git a/src/test/run-pass/issues/issue-18539.rs b/src/test/ui/issues/issue-18539.rs similarity index 100% rename from src/test/run-pass/issues/issue-18539.rs rename to src/test/ui/issues/issue-18539.rs diff --git a/src/test/run-pass/issues/issue-18652.rs b/src/test/ui/issues/issue-18652.rs similarity index 100% rename from src/test/run-pass/issues/issue-18652.rs rename to src/test/ui/issues/issue-18652.rs diff --git a/src/test/run-pass/issues/issue-18655.rs b/src/test/ui/issues/issue-18655.rs similarity index 100% rename from src/test/run-pass/issues/issue-18655.rs rename to src/test/ui/issues/issue-18655.rs diff --git a/src/test/ui/issues/issue-1866.rs b/src/test/ui/issues/issue-1866.rs index 3de547bfe6..0223e2ebea 100644 --- a/src/test/ui/issues/issue-1866.rs +++ b/src/test/ui/issues/issue-1866.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/issues/issue-18661.rs b/src/test/ui/issues/issue-18661.rs similarity index 100% rename from src/test/run-pass/issues/issue-18661.rs rename to src/test/ui/issues/issue-18661.rs diff --git a/src/test/run-pass/issues/issue-18685.rs b/src/test/ui/issues/issue-18685.rs similarity index 100% rename from src/test/run-pass/issues/issue-18685.rs rename to src/test/ui/issues/issue-18685.rs diff --git a/src/test/run-pass/issues/issue-18711.rs b/src/test/ui/issues/issue-18711.rs similarity index 100% rename from src/test/run-pass/issues/issue-18711.rs rename to src/test/ui/issues/issue-18711.rs diff --git a/src/test/ui/issues/issue-18738.rs b/src/test/ui/issues/issue-18738.rs index c3bd022fa4..ec4429234b 100644 --- a/src/test/ui/issues/issue-18738.rs +++ b/src/test/ui/issues/issue-18738.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Eq, PartialEq, PartialOrd, Ord)] enum Test<'a> { diff --git a/src/test/run-pass/issues/issue-18767.rs b/src/test/ui/issues/issue-18767.rs similarity index 100% rename from src/test/run-pass/issues/issue-18767.rs rename to src/test/ui/issues/issue-18767.rs diff --git a/src/test/run-pass/issues/issue-18804/auxiliary/lib.rs b/src/test/ui/issues/issue-18804/auxiliary/lib.rs similarity index 100% rename from src/test/run-pass/issues/issue-18804/auxiliary/lib.rs rename to src/test/ui/issues/issue-18804/auxiliary/lib.rs diff --git a/src/test/run-pass/issues/issue-18804/main.rs b/src/test/ui/issues/issue-18804/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-18804/main.rs rename to src/test/ui/issues/issue-18804/main.rs diff --git a/src/test/ui/issues/issue-18809.rs b/src/test/ui/issues/issue-18809.rs index fb31666b22..9b8275f811 100644 --- a/src/test/ui/issues/issue-18809.rs +++ b/src/test/ui/issues/issue-18809.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Tup { type T0; type T1; diff --git a/src/test/run-pass/issues/issue-18845.rs b/src/test/ui/issues/issue-18845.rs similarity index 100% rename from src/test/run-pass/issues/issue-18845.rs rename to src/test/ui/issues/issue-18845.rs diff --git a/src/test/run-pass/issues/issue-18859.rs b/src/test/ui/issues/issue-18859.rs similarity index 100% rename from src/test/run-pass/issues/issue-18859.rs rename to src/test/ui/issues/issue-18859.rs diff --git a/src/test/ui/issues/issue-18906.rs b/src/test/ui/issues/issue-18906.rs index 0b9625b186..387fd41fb7 100644 --- a/src/test/ui/issues/issue-18906.rs +++ b/src/test/ui/issues/issue-18906.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-18913.rs b/src/test/ui/issues/issue-18913.rs similarity index 100% rename from src/test/run-pass/issues/issue-18913.rs rename to src/test/ui/issues/issue-18913.rs diff --git a/src/test/run-pass/issues/issue-18937-1.rs b/src/test/ui/issues/issue-18937-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-18937-1.rs rename to src/test/ui/issues/issue-18937-1.rs diff --git a/src/test/run-pass/issues/issue-18952.rs b/src/test/ui/issues/issue-18952.rs similarity index 100% rename from src/test/run-pass/issues/issue-18952.rs rename to src/test/ui/issues/issue-18952.rs diff --git a/src/test/ui/issues/issue-18988.rs b/src/test/ui/issues/issue-18988.rs index 7fe662e907..6dbfd3a0a9 100644 --- a/src/test/ui/issues/issue-18988.rs +++ b/src/test/ui/issues/issue-18988.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] pub trait Foo : Send { } diff --git a/src/test/run-pass/issues/issue-19001.rs b/src/test/ui/issues/issue-19001.rs similarity index 100% rename from src/test/run-pass/issues/issue-19001.rs rename to src/test/ui/issues/issue-19001.rs diff --git a/src/test/ui/issues/issue-19037.rs b/src/test/ui/issues/issue-19037.rs index 4efc0719ff..30497d3e94 100644 --- a/src/test/ui/issues/issue-19037.rs +++ b/src/test/ui/issues/issue-19037.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-19081.rs b/src/test/ui/issues/issue-19081.rs index b487cdd5c7..0948cd3271 100644 --- a/src/test/ui/issues/issue-19081.rs +++ b/src/test/ui/issues/issue-19081.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Hasher { type State; diff --git a/src/test/ui/issues/issue-19097.rs b/src/test/ui/issues/issue-19097.rs index 8055e10625..c800e0bd12 100644 --- a/src/test/ui/issues/issue-19097.rs +++ b/src/test/ui/issues/issue-19097.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // regression test for #19097 diff --git a/src/test/ui/issues/issue-19098.rs b/src/test/ui/issues/issue-19098.rs index 690fe94409..37c0d7f052 100644 --- a/src/test/ui/issues/issue-19098.rs +++ b/src/test/ui/issues/issue-19098.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Handler { fn handle(&self, _: &mut String); } diff --git a/src/test/ui/issues/issue-19102.rs b/src/test/ui/issues/issue-19102.rs index 962cd8d3f6..76ed3efc4e 100644 --- a/src/test/ui/issues/issue-19102.rs +++ b/src/test/ui/issues/issue-19102.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_imports)] #![deny(unused_qualifications)] diff --git a/src/test/run-pass/issues/issue-19127.rs b/src/test/ui/issues/issue-19127.rs similarity index 100% rename from src/test/run-pass/issues/issue-19127.rs rename to src/test/ui/issues/issue-19127.rs diff --git a/src/test/ui/issues/issue-19129-1.rs b/src/test/ui/issues/issue-19129-1.rs index 4be2cc6d17..e17ee053f3 100644 --- a/src/test/ui/issues/issue-19129-1.rs +++ b/src/test/ui/issues/issue-19129-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Trait { diff --git a/src/test/ui/issues/issue-19129-2.rs b/src/test/ui/issues/issue-19129-2.rs index d11ef8af70..30c64573a1 100644 --- a/src/test/ui/issues/issue-19129-2.rs +++ b/src/test/ui/issues/issue-19129-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-19135.rs b/src/test/ui/issues/issue-19135.rs similarity index 100% rename from src/test/run-pass/issues/issue-19135.rs rename to src/test/ui/issues/issue-19135.rs diff --git a/src/test/run-pass/issues/issue-19244.rs b/src/test/ui/issues/issue-19244.rs similarity index 100% rename from src/test/run-pass/issues/issue-19244.rs rename to src/test/ui/issues/issue-19244.rs diff --git a/src/test/run-pass/issues/issue-19293.rs b/src/test/ui/issues/issue-19293.rs similarity index 100% rename from src/test/run-pass/issues/issue-19293.rs rename to src/test/ui/issues/issue-19293.rs diff --git a/src/test/run-pass/issues/issue-19340-1.rs b/src/test/ui/issues/issue-19340-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-19340-1.rs rename to src/test/ui/issues/issue-19340-1.rs diff --git a/src/test/run-pass/issues/issue-19340-2.rs b/src/test/ui/issues/issue-19340-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-19340-2.rs rename to src/test/ui/issues/issue-19340-2.rs diff --git a/src/test/run-pass/issues/issue-19358.rs b/src/test/ui/issues/issue-19358.rs similarity index 100% rename from src/test/run-pass/issues/issue-19358.rs rename to src/test/ui/issues/issue-19358.rs diff --git a/src/test/run-pass/issues/issue-19367.rs b/src/test/ui/issues/issue-19367.rs similarity index 100% rename from src/test/run-pass/issues/issue-19367.rs rename to src/test/ui/issues/issue-19367.rs diff --git a/src/test/ui/issues/issue-19398.rs b/src/test/ui/issues/issue-19398.rs index 5daa14b7cb..28d266a1d6 100644 --- a/src/test/ui/issues/issue-19398.rs +++ b/src/test/ui/issues/issue-19398.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait T { diff --git a/src/test/ui/issues/issue-19404.rs b/src/test/ui/issues/issue-19404.rs index 59544393ba..40c9fdac7b 100644 --- a/src/test/ui/issues/issue-19404.rs +++ b/src/test/ui/issues/issue-19404.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] use std::any::TypeId; diff --git a/src/test/ui/issues/issue-19479.rs b/src/test/ui/issues/issue-19479.rs index 8b78952a6e..c134d85c7e 100644 --- a/src/test/ui/issues/issue-19479.rs +++ b/src/test/ui/issues/issue-19479.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Base { diff --git a/src/test/run-pass/issues/issue-19499.rs b/src/test/ui/issues/issue-19499.rs similarity index 100% rename from src/test/run-pass/issues/issue-19499.rs rename to src/test/ui/issues/issue-19499.rs diff --git a/src/test/ui/issues/issue-19631.rs b/src/test/ui/issues/issue-19631.rs index 8c58331e58..015758dd6e 100644 --- a/src/test/ui/issues/issue-19631.rs +++ b/src/test/ui/issues/issue-19631.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-19632.rs b/src/test/ui/issues/issue-19632.rs index b032b67c1e..ddd87a9f6e 100644 --- a/src/test/ui/issues/issue-19632.rs +++ b/src/test/ui/issues/issue-19632.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-1974.rs b/src/test/ui/issues/issue-1974.rs similarity index 100% rename from src/test/run-pass/issues/issue-1974.rs rename to src/test/ui/issues/issue-1974.rs diff --git a/src/test/run-pass/issues/issue-19811-escape-unicode.rs b/src/test/ui/issues/issue-19811-escape-unicode.rs similarity index 100% rename from src/test/run-pass/issues/issue-19811-escape-unicode.rs rename to src/test/ui/issues/issue-19811-escape-unicode.rs diff --git a/src/test/ui/issues/issue-19850.rs b/src/test/ui/issues/issue-19850.rs index fb64ef8940..d51cf0cfcb 100644 --- a/src/test/ui/issues/issue-19850.rs +++ b/src/test/ui/issues/issue-19850.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] // Test that `::Output` and `Self::Output` are accepted as type annotations in let // bindings diff --git a/src/test/ui/issues/issue-19982.rs b/src/test/ui/issues/issue-19982.rs index 6b5a4b2c10..fb88781ee2 100644 --- a/src/test/ui/issues/issue-19982.rs +++ b/src/test/ui/issues/issue-19982.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(fn_traits, unboxed_closures)] diff --git a/src/test/ui/issues/issue-20009.rs b/src/test/ui/issues/issue-20009.rs index 6228d044ad..730f1a9a16 100644 --- a/src/test/ui/issues/issue-20009.rs +++ b/src/test/ui/issues/issue-20009.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that associated types are `Sized` // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-20055-box-trait.rs b/src/test/ui/issues/issue-20055-box-trait.rs similarity index 100% rename from src/test/run-pass/issues/issue-20055-box-trait.rs rename to src/test/ui/issues/issue-20055-box-trait.rs diff --git a/src/test/run-pass/issues/issue-20055-box-unsized-array.rs b/src/test/ui/issues/issue-20055-box-unsized-array.rs similarity index 100% rename from src/test/run-pass/issues/issue-20055-box-unsized-array.rs rename to src/test/ui/issues/issue-20055-box-unsized-array.rs diff --git a/src/test/ui/issues/issue-20091.rs b/src/test/ui/issues/issue-20091.rs index 4ea567d25c..68e0f65ca2 100644 --- a/src/test/ui/issues/issue-20091.rs +++ b/src/test/ui/issues/issue-20091.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(stable_features)] // ignore-cloudabi no processes diff --git a/src/test/run-pass/issues/issue-20174.rs b/src/test/ui/issues/issue-20174.rs similarity index 100% rename from src/test/run-pass/issues/issue-20174.rs rename to src/test/ui/issues/issue-20174.rs diff --git a/src/test/ui/issues/issue-20186.rs b/src/test/ui/issues/issue-20186.rs index 98d856e172..28cbde772c 100644 --- a/src/test/ui/issues/issue-20186.rs +++ b/src/test/ui/issues/issue-20186.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] struct Foo; diff --git a/src/test/run-pass/issues/issue-20313.rs b/src/test/ui/issues/issue-20313-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-20313.rs rename to src/test/ui/issues/issue-20313-rpass.rs diff --git a/src/test/ui/issues/issue-20313.stderr b/src/test/ui/issues/issue-20313.stderr index 405e717c35..a3fa7ebba8 100644 --- a/src/test/ui/issues/issue-20313.stderr +++ b/src/test/ui/issues/issue-20313.stderr @@ -5,7 +5,7 @@ LL | fn sqrt(x: f32) -> f32; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29602 - = help: add #![feature(link_llvm_intrinsics)] to the crate attributes to enable + = help: add `#![feature(link_llvm_intrinsics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-20343.rs b/src/test/ui/issues/issue-20343.rs similarity index 100% rename from src/test/run-pass/issues/issue-20343.rs rename to src/test/ui/issues/issue-20343.rs diff --git a/src/test/run-pass/issues/issue-20389.rs b/src/test/ui/issues/issue-20389.rs similarity index 100% rename from src/test/run-pass/issues/issue-20389.rs rename to src/test/ui/issues/issue-20389.rs diff --git a/src/test/ui/issues/issue-20396.rs b/src/test/ui/issues/issue-20396.rs index 0e69b7f3d1..5e0411b2cd 100644 --- a/src/test/ui/issues/issue-20396.rs +++ b/src/test/ui/issues/issue-20396.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/src/test/ui/issues/issue-20414.rs b/src/test/ui/issues/issue-20414.rs index 1653a9da00..5c6929d45d 100644 --- a/src/test/ui/issues/issue-20414.rs +++ b/src/test/ui/issues/issue-20414.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-20427.rs b/src/test/ui/issues/issue-20427.rs similarity index 100% rename from src/test/run-pass/issues/issue-20427.rs rename to src/test/ui/issues/issue-20427.rs diff --git a/src/test/ui/issues/issue-20454.rs b/src/test/ui/issues/issue-20454.rs index d4920c0c75..13ce1daf30 100644 --- a/src/test/ui/issues/issue-20454.rs +++ b/src/test/ui/issues/issue-20454.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] use std::thread; diff --git a/src/test/run-pass/issues/issue-20544.rs b/src/test/ui/issues/issue-20544.rs similarity index 100% rename from src/test/run-pass/issues/issue-20544.rs rename to src/test/ui/issues/issue-20544.rs diff --git a/src/test/run-pass/issues/issue-20575.rs b/src/test/ui/issues/issue-20575.rs similarity index 100% rename from src/test/run-pass/issues/issue-20575.rs rename to src/test/ui/issues/issue-20575.rs diff --git a/src/test/run-pass/issues/issue-20616.rs b/src/test/ui/issues/issue-20616.rs similarity index 100% rename from src/test/run-pass/issues/issue-20616.rs rename to src/test/ui/issues/issue-20616.rs diff --git a/src/test/ui/issues/issue-2063-resource.rs b/src/test/ui/issues/issue-2063-resource.rs index 6ed3e027ff..ea4cbf2ced 100644 --- a/src/test/ui/issues/issue-2063-resource.rs +++ b/src/test/ui/issues/issue-2063-resource.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // test that autoderef of a type like this does not // cause compiler to loop. Note that no instances diff --git a/src/test/run-pass/issues/issue-2063.rs b/src/test/ui/issues/issue-2063.rs similarity index 100% rename from src/test/run-pass/issues/issue-2063.rs rename to src/test/ui/issues/issue-2063.rs diff --git a/src/test/ui/issues/issue-20644.rs b/src/test/ui/issues/issue-20644.rs index db32344864..bde65229ec 100644 --- a/src/test/ui/issues/issue-20644.rs +++ b/src/test/ui/issues/issue-20644.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_imports)] #![allow(stable_features)] diff --git a/src/test/run-pass/issues/issue-20676.rs b/src/test/ui/issues/issue-20676.rs similarity index 100% rename from src/test/run-pass/issues/issue-20676.rs rename to src/test/ui/issues/issue-20676.rs diff --git a/src/test/run-pass/issues/issue-2074.rs b/src/test/ui/issues/issue-2074.rs similarity index 100% rename from src/test/run-pass/issues/issue-2074.rs rename to src/test/ui/issues/issue-2074.rs diff --git a/src/test/ui/issues/issue-20763-1.rs b/src/test/ui/issues/issue-20763-1.rs index c5b2852094..0f0ac8f646 100644 --- a/src/test/ui/issues/issue-20763-1.rs +++ b/src/test/ui/issues/issue-20763-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-20763-2.rs b/src/test/ui/issues/issue-20763-2.rs index cfa252b095..e3b566d050 100644 --- a/src/test/ui/issues/issue-20763-2.rs +++ b/src/test/ui/issues/issue-20763-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-20797.rs b/src/test/ui/issues/issue-20797.rs index e504b4705d..bda7e8f818 100644 --- a/src/test/ui/issues/issue-20797.rs +++ b/src/test/ui/issues/issue-20797.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-cloudabi no std::fs // Regression test for #20797. diff --git a/src/test/run-pass/issues/issue-20803.rs b/src/test/ui/issues/issue-20803.rs similarity index 100% rename from src/test/run-pass/issues/issue-20803.rs rename to src/test/ui/issues/issue-20803.rs diff --git a/src/test/run-pass/issues/issue-20823.rs b/src/test/ui/issues/issue-20823.rs similarity index 100% rename from src/test/run-pass/issues/issue-20823.rs rename to src/test/ui/issues/issue-20823.rs diff --git a/src/test/ui/issues/issue-20825-2.rs b/src/test/ui/issues/issue-20825-2.rs index cceed54218..7d72ef839e 100644 --- a/src/test/ui/issues/issue-20825-2.rs +++ b/src/test/ui/issues/issue-20825-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Subscriber { type Input; } diff --git a/src/test/run-pass/issues/issue-20847.rs b/src/test/ui/issues/issue-20847.rs similarity index 100% rename from src/test/run-pass/issues/issue-20847.rs rename to src/test/ui/issues/issue-20847.rs diff --git a/src/test/run-pass/issues/issue-20953.rs b/src/test/ui/issues/issue-20953.rs similarity index 100% rename from src/test/run-pass/issues/issue-20953.rs rename to src/test/ui/issues/issue-20953.rs diff --git a/src/test/run-pass/issues/issue-21033.rs b/src/test/ui/issues/issue-21033.rs similarity index 100% rename from src/test/run-pass/issues/issue-21033.rs rename to src/test/ui/issues/issue-21033.rs diff --git a/src/test/run-pass/issues/issue-21058.rs b/src/test/ui/issues/issue-21058.rs similarity index 88% rename from src/test/run-pass/issues/issue-21058.rs rename to src/test/ui/issues/issue-21058.rs index 3efa94ce68..6facf0b2dd 100644 --- a/src/test/run-pass/issues/issue-21058.rs +++ b/src/test/ui/issues/issue-21058.rs @@ -1,6 +1,5 @@ // run-pass #![allow(dead_code)] -#![feature(core_intrinsics)] use std::fmt::Debug; @@ -12,7 +11,7 @@ macro_rules! check { assert_eq!(type_name_of_val($ty_of), $expected); }; ($ty:ty, $expected:expr) => { - assert_eq!(unsafe { std::intrinsics::type_name::<$ty>()}, $expected); + assert_eq!(std::any::type_name::<$ty>(), $expected); }; } @@ -50,7 +49,7 @@ fn bar() { } fn type_name_of_val(_: T) -> &'static str { - unsafe { std::intrinsics::type_name::() } + std::any::type_name::() } #[derive(Debug)] diff --git a/src/test/ui/issues/issue-21140.rs b/src/test/ui/issues/issue-21140.rs index 86d4e63670..92834bbb0e 100644 --- a/src/test/ui/issues/issue-21140.rs +++ b/src/test/ui/issues/issue-21140.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Trait where Self::Out: std::fmt::Display { type Out; } diff --git a/src/test/ui/issues/issue-21174-2.rs b/src/test/ui/issues/issue-21174-2.rs index 145b062baf..351a98d5c8 100644 --- a/src/test/ui/issues/issue-21174-2.rs +++ b/src/test/ui/issues/issue-21174-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] trait Trait<'a> { diff --git a/src/test/ui/issues/issue-21245.rs b/src/test/ui/issues/issue-21245.rs index edf482afc5..d0aa16bfb1 100644 --- a/src/test/ui/issues/issue-21245.rs +++ b/src/test/ui/issues/issue-21245.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for issue #21245. Check that we are able to infer // the types in these examples correctly. It used to be that diff --git a/src/test/run-pass/issues/issue-21291.rs b/src/test/ui/issues/issue-21291.rs similarity index 100% rename from src/test/run-pass/issues/issue-21291.rs rename to src/test/ui/issues/issue-21291.rs diff --git a/src/test/run-pass/issues/issue-21306.rs b/src/test/ui/issues/issue-21306.rs similarity index 100% rename from src/test/run-pass/issues/issue-21306.rs rename to src/test/ui/issues/issue-21306.rs diff --git a/src/test/run-pass/issues/issue-21361.rs b/src/test/ui/issues/issue-21361.rs similarity index 100% rename from src/test/run-pass/issues/issue-21361.rs rename to src/test/ui/issues/issue-21361.rs diff --git a/src/test/ui/issues/issue-21363.rs b/src/test/ui/issues/issue-21363.rs index 12efce9496..d5f1eec061 100644 --- a/src/test/ui/issues/issue-21363.rs +++ b/src/test/ui/issues/issue-21363.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![no_implicit_prelude] diff --git a/src/test/run-pass/issues/issue-21384.rs b/src/test/ui/issues/issue-21384.rs similarity index 100% rename from src/test/run-pass/issues/issue-21384.rs rename to src/test/ui/issues/issue-21384.rs diff --git a/src/test/run-pass/issues/issue-21400.rs b/src/test/ui/issues/issue-21400.rs similarity index 100% rename from src/test/run-pass/issues/issue-21400.rs rename to src/test/ui/issues/issue-21400.rs diff --git a/src/test/ui/issues/issue-21402.rs b/src/test/ui/issues/issue-21402.rs index 518d3cfe5a..21e0d58b5f 100644 --- a/src/test/ui/issues/issue-21402.rs +++ b/src/test/ui/issues/issue-21402.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-21475.rs b/src/test/ui/issues/issue-21475.rs similarity index 100% rename from src/test/run-pass/issues/issue-21475.rs rename to src/test/ui/issues/issue-21475.rs diff --git a/src/test/run-pass/issues/issue-21486.rs b/src/test/ui/issues/issue-21486.rs similarity index 100% rename from src/test/run-pass/issues/issue-21486.rs rename to src/test/ui/issues/issue-21486.rs diff --git a/src/test/ui/issues/issue-21520.rs b/src/test/ui/issues/issue-21520.rs index 450448f1a1..133bcc2360 100644 --- a/src/test/ui/issues/issue-21520.rs +++ b/src/test/ui/issues/issue-21520.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test that the requirement (in `Bar`) that `T::Bar : 'static` does // not wind up propagating to `T`. diff --git a/src/test/ui/issues/issue-21562.rs b/src/test/ui/issues/issue-21562.rs index e31316d070..2f3ee7b749 100644 --- a/src/test/ui/issues/issue-21562.rs +++ b/src/test/ui/issues/issue-21562.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-21596.stderr b/src/test/ui/issues/issue-21596.stderr index 07d29f30e9..8e4e09b13a 100644 --- a/src/test/ui/issues/issue-21596.stderr +++ b/src/test/ui/issues/issue-21596.stderr @@ -5,6 +5,7 @@ LL | println!("{}", z.to_string()); | ^^^^^^^^^ | = note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref + = note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior = note: the method `to_string` exists but the following trait bounds were not satisfied: `*const u8 : std::string::ToString` diff --git a/src/test/ui/issues/issue-21622.rs b/src/test/ui/issues/issue-21622.rs index 2b80f2f36c..4aae089943 100644 --- a/src/test/ui/issues/issue-21622.rs +++ b/src/test/ui/issues/issue-21622.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/issues/issue-21634.rs b/src/test/ui/issues/issue-21634.rs index 8941bb1c24..36b207bb2a 100644 --- a/src/test/ui/issues/issue-21634.rs +++ b/src/test/ui/issues/issue-21634.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(stable_features)] #![feature(cfg_target_feature)] diff --git a/src/test/run-pass/issues/issue-21655.rs b/src/test/ui/issues/issue-21655.rs similarity index 100% rename from src/test/run-pass/issues/issue-21655.rs rename to src/test/ui/issues/issue-21655.rs diff --git a/src/test/run-pass/issues/issue-2170-exe.rs b/src/test/ui/issues/issue-2170-exe.rs similarity index 100% rename from src/test/run-pass/issues/issue-2170-exe.rs rename to src/test/ui/issues/issue-2170-exe.rs diff --git a/src/test/run-pass/issues/issue-21721.rs b/src/test/ui/issues/issue-21721.rs similarity index 100% rename from src/test/run-pass/issues/issue-21721.rs rename to src/test/ui/issues/issue-21721.rs diff --git a/src/test/ui/issues/issue-21726.rs b/src/test/ui/issues/issue-21726.rs index f2065976b3..1c8284c829 100644 --- a/src/test/ui/issues/issue-21726.rs +++ b/src/test/ui/issues/issue-21726.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #21726: an issue arose around the rules for // subtyping of projection types that resulted in an unconstrained diff --git a/src/test/ui/issues/issue-21891.rs b/src/test/ui/issues/issue-21891.rs index 9b1e44c181..de0aa2919c 100644 --- a/src/test/ui/issues/issue-21891.rs +++ b/src/test/ui/issues/issue-21891.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/run-pass/issues/issue-2190-1.rs b/src/test/ui/issues/issue-2190-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-2190-1.rs rename to src/test/ui/issues/issue-2190-1.rs diff --git a/src/test/run-pass/issues/issue-21909.rs b/src/test/ui/issues/issue-21909.rs similarity index 100% rename from src/test/run-pass/issues/issue-21909.rs rename to src/test/ui/issues/issue-21909.rs diff --git a/src/test/run-pass/issues/issue-21922.rs b/src/test/ui/issues/issue-21922.rs similarity index 100% rename from src/test/run-pass/issues/issue-21922.rs rename to src/test/ui/issues/issue-21922.rs diff --git a/src/test/run-pass/issues/issue-22008.rs b/src/test/ui/issues/issue-22008.rs similarity index 100% rename from src/test/run-pass/issues/issue-22008.rs rename to src/test/ui/issues/issue-22008.rs diff --git a/src/test/run-pass/issues/issue-22036.rs b/src/test/ui/issues/issue-22036.rs similarity index 100% rename from src/test/run-pass/issues/issue-22036.rs rename to src/test/ui/issues/issue-22036.rs diff --git a/src/test/ui/issues/issue-22066.rs b/src/test/ui/issues/issue-22066.rs index 8c0b664d78..fbf31aa424 100644 --- a/src/test/ui/issues/issue-22066.rs +++ b/src/test/ui/issues/issue-22066.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait LineFormatter<'a> { type Iter: Iterator + 'a; fn iter(&'a self, line: &'a str) -> Self::Iter; diff --git a/src/test/run-pass/issues/issue-2214.rs b/src/test/ui/issues/issue-2214.rs similarity index 79% rename from src/test/run-pass/issues/issue-2214.rs rename to src/test/ui/issues/issue-2214.rs index 22f33545cb..c4c56cd109 100644 --- a/src/test/run-pass/issues/issue-2214.rs +++ b/src/test/ui/issues/issue-2214.rs @@ -25,12 +25,15 @@ mod m { #[link_name = "m"] extern { - #[cfg(any(unix, target_os = "cloudabi"))] + #[cfg(any(all(unix, not(target_os = "vxworks")), target_os = "cloudabi"))] #[link_name="lgamma_r"] pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; #[cfg(windows)] #[link_name="lgamma"] pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; + #[cfg(target_os = "vxworks")] + #[link_name="lgamma"] + pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; } } diff --git a/src/test/run-pass/issues/issue-2216.rs b/src/test/ui/issues/issue-2216.rs similarity index 100% rename from src/test/run-pass/issues/issue-2216.rs rename to src/test/ui/issues/issue-2216.rs diff --git a/src/test/run-pass/issues/issue-22258.rs b/src/test/ui/issues/issue-22258.rs similarity index 100% rename from src/test/run-pass/issues/issue-22258.rs rename to src/test/ui/issues/issue-22258.rs diff --git a/src/test/run-pass/issues/issue-22346.rs b/src/test/ui/issues/issue-22346.rs similarity index 100% rename from src/test/run-pass/issues/issue-22346.rs rename to src/test/ui/issues/issue-22346.rs diff --git a/src/test/ui/issues/issue-22356.rs b/src/test/ui/issues/issue-22356.rs index 3f3b1d3e5f..ec4695e5e0 100644 --- a/src/test/ui/issues/issue-22356.rs +++ b/src/test/ui/issues/issue-22356.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(type_alias_bounds)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-22375.rs b/src/test/ui/issues/issue-22375.rs index bae7b2bfab..201aea3a05 100644 --- a/src/test/ui/issues/issue-22375.rs +++ b/src/test/ui/issues/issue-22375.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait A> {} fn main() {} diff --git a/src/test/run-pass/issues/issue-22403.rs b/src/test/ui/issues/issue-22403.rs similarity index 100% rename from src/test/run-pass/issues/issue-22403.rs rename to src/test/ui/issues/issue-22403.rs diff --git a/src/test/run-pass/issues/issue-22426.rs b/src/test/ui/issues/issue-22426.rs similarity index 100% rename from src/test/run-pass/issues/issue-22426.rs rename to src/test/ui/issues/issue-22426.rs diff --git a/src/test/run-pass/issues/issue-22463.rs b/src/test/ui/issues/issue-22463.rs similarity index 100% rename from src/test/run-pass/issues/issue-22463.rs rename to src/test/ui/issues/issue-22463.rs diff --git a/src/test/ui/issues/issue-22471.rs b/src/test/ui/issues/issue-22471.rs index a22c7e6173..befccc19bf 100644 --- a/src/test/ui/issues/issue-22471.rs +++ b/src/test/ui/issues/issue-22471.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(type_alias_bounds)] diff --git a/src/test/run-pass/issues/issue-22536-copy-mustnt-zero.rs b/src/test/ui/issues/issue-22536-copy-mustnt-zero.rs similarity index 100% rename from src/test/run-pass/issues/issue-22536-copy-mustnt-zero.rs rename to src/test/ui/issues/issue-22536-copy-mustnt-zero.rs diff --git a/src/test/run-pass/issues/issue-22546.rs b/src/test/ui/issues/issue-22546.rs similarity index 100% rename from src/test/run-pass/issues/issue-22546.rs rename to src/test/ui/issues/issue-22546.rs diff --git a/src/test/run-pass/issues/issue-22577.rs b/src/test/ui/issues/issue-22577.rs similarity index 100% rename from src/test/run-pass/issues/issue-22577.rs rename to src/test/ui/issues/issue-22577.rs diff --git a/src/test/run-pass/issues/issue-22629.rs b/src/test/ui/issues/issue-22629.rs similarity index 100% rename from src/test/run-pass/issues/issue-22629.rs rename to src/test/ui/issues/issue-22629.rs diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index cf36953546..0fe167963c 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -87,15 +87,12 @@ error: expected type, found `4` --> $DIR/issue-22644.rs:34:28 | LL | println!("{}", a: &mut 4); - | ^ expecting a type here because of type ascription + | - ^ expected type + | | + | tried to parse a type due to this type ascription | - = note: #![feature(type_ascription)] lets you annotate an expression with a type: `: ` -note: this expression expects an ascribed type after the colon - --> $DIR/issue-22644.rs:34:20 - | -LL | println!("{}", a: &mut 4); - | ^ - = help: this might be indicative of a syntax error elsewhere + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to 9 previous errors diff --git a/src/test/ui/issues/issue-22777.rs b/src/test/ui/issues/issue-22777.rs index f9b264623d..81efb250df 100644 --- a/src/test/ui/issues/issue-22777.rs +++ b/src/test/ui/issues/issue-22777.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test is reduced from libsyntax. It is just checking that we // can successfully deal with a "deep" structure, which the drop-check // was hitting a recursion limit on at one point. diff --git a/src/test/ui/issues/issue-22781.rs b/src/test/ui/issues/issue-22781.rs index a7b94c106a..37f40aa042 100644 --- a/src/test/ui/issues/issue-22781.rs +++ b/src/test/ui/issues/issue-22781.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] use std::collections::HashMap; use std::collections::hash_map::Entry::Vacant; diff --git a/src/test/ui/issues/issue-22814.rs b/src/test/ui/issues/issue-22814.rs index bcc7a8a5ae..065e7edc67 100644 --- a/src/test/ui/issues/issue-22814.rs +++ b/src/test/ui/issues/issue-22814.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Test {} macro_rules! test { diff --git a/src/test/run-pass/issues/issue-22828.rs b/src/test/ui/issues/issue-22828.rs similarity index 100% rename from src/test/run-pass/issues/issue-22828.rs rename to src/test/ui/issues/issue-22828.rs diff --git a/src/test/run-pass/issues/issue-2284.rs b/src/test/ui/issues/issue-2284.rs similarity index 100% rename from src/test/run-pass/issues/issue-2284.rs rename to src/test/ui/issues/issue-2284.rs diff --git a/src/test/run-pass/issues/issue-22864-1.rs b/src/test/ui/issues/issue-22864-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-22864-1.rs rename to src/test/ui/issues/issue-22864-1.rs diff --git a/src/test/run-pass/issues/issue-22864-2.rs b/src/test/ui/issues/issue-22864-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-22864-2.rs rename to src/test/ui/issues/issue-22864-2.rs diff --git a/src/test/run-pass/issues/issue-2288.rs b/src/test/ui/issues/issue-2288.rs similarity index 100% rename from src/test/run-pass/issues/issue-2288.rs rename to src/test/ui/issues/issue-2288.rs diff --git a/src/test/ui/issues/issue-22894.rs b/src/test/ui/issues/issue-22894.rs index f5b26de54f..7b1513a10c 100644 --- a/src/test/ui/issues/issue-22894.rs +++ b/src/test/ui/issues/issue-22894.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[allow(dead_code)] static X: &'static str = &*""; fn main() {} diff --git a/src/test/run-pass/issues/issue-22992-2.rs b/src/test/ui/issues/issue-22992-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-22992-2.rs rename to src/test/ui/issues/issue-22992-2.rs diff --git a/src/test/run-pass/issues/issue-22992.rs b/src/test/ui/issues/issue-22992.rs similarity index 100% rename from src/test/run-pass/issues/issue-22992.rs rename to src/test/ui/issues/issue-22992.rs diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index e99854539d..43561938ef 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -5,7 +5,7 @@ LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29625 - = help: add #![feature(unboxed_closures)] to the crate attributes to enable + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0107]: wrong number of type arguments: expected 1, found 0 --> $DIR/issue-23024.rs:9:39 diff --git a/src/test/run-pass/issues/issue-23036.rs b/src/test/ui/issues/issue-23036.rs similarity index 100% rename from src/test/run-pass/issues/issue-23036.rs rename to src/test/ui/issues/issue-23036.rs diff --git a/src/test/ui/issues/issue-2311-2.rs b/src/test/ui/issues/issue-2311-2.rs index 40cda23186..f735338fcd 100644 --- a/src/test/ui/issues/issue-2311-2.rs +++ b/src/test/ui/issues/issue-2311-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-2311.rs b/src/test/ui/issues/issue-2311.rs index 07b9951e68..151ad4e266 100644 --- a/src/test/ui/issues/issue-2311.rs +++ b/src/test/ui/issues/issue-2311.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(non_camel_case_types)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-2312.rs b/src/test/ui/issues/issue-2312.rs index 1fc7b5a3f3..b445f9581b 100644 --- a/src/test/ui/issues/issue-2312.rs +++ b/src/test/ui/issues/issue-2312.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/issues/issue-2316-c.rs b/src/test/ui/issues/issue-2316-c.rs similarity index 100% rename from src/test/run-pass/issues/issue-2316-c.rs rename to src/test/ui/issues/issue-2316-c.rs diff --git a/src/test/run-pass/issues/issue-23208.rs b/src/test/ui/issues/issue-23208.rs similarity index 100% rename from src/test/run-pass/issues/issue-23208.rs rename to src/test/ui/issues/issue-23208.rs diff --git a/src/test/run-pass/issues/issue-23261.rs b/src/test/ui/issues/issue-23261.rs similarity index 100% rename from src/test/run-pass/issues/issue-23261.rs rename to src/test/ui/issues/issue-23261.rs diff --git a/src/test/run-pass/issues/issue-23304-1.rs b/src/test/ui/issues/issue-23304-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-23304-1.rs rename to src/test/ui/issues/issue-23304-1.rs diff --git a/src/test/run-pass/issues/issue-23304-2.rs b/src/test/ui/issues/issue-23304-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-23304-2.rs rename to src/test/ui/issues/issue-23304-2.rs diff --git a/src/test/run-pass/issues/issue-23311.rs b/src/test/ui/issues/issue-23311.rs similarity index 100% rename from src/test/run-pass/issues/issue-23311.rs rename to src/test/ui/issues/issue-23311.rs diff --git a/src/test/run-pass/issues/issue-23336.rs b/src/test/ui/issues/issue-23336.rs similarity index 100% rename from src/test/run-pass/issues/issue-23336.rs rename to src/test/ui/issues/issue-23336.rs diff --git a/src/test/run-pass/issues/issue-23338-ensure-param-drop-order.rs b/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs similarity index 100% rename from src/test/run-pass/issues/issue-23338-ensure-param-drop-order.rs rename to src/test/ui/issues/issue-23338-ensure-param-drop-order.rs diff --git a/src/test/run-pass/issues/issue-23338-params-outlive-temps-of-body.rs b/src/test/ui/issues/issue-23338-params-outlive-temps-of-body.rs similarity index 100% rename from src/test/run-pass/issues/issue-23338-params-outlive-temps-of-body.rs rename to src/test/ui/issues/issue-23338-params-outlive-temps-of-body.rs diff --git a/src/test/ui/issues/issue-23406.rs b/src/test/ui/issues/issue-23406.rs index 9d77af0914..2e57b16e3c 100644 --- a/src/test/ui/issues/issue-23406.rs +++ b/src/test/ui/issues/issue-23406.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Inner { type T; diff --git a/src/test/run-pass/issues/issue-23433.rs b/src/test/ui/issues/issue-23433.rs similarity index 100% rename from src/test/run-pass/issues/issue-23433.rs rename to src/test/ui/issues/issue-23433.rs diff --git a/src/test/ui/issues/issue-23442.rs b/src/test/ui/issues/issue-23442.rs index c3b613a06c..659e1e0794 100644 --- a/src/test/ui/issues/issue-23442.rs +++ b/src/test/ui/issues/issue-23442.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::marker::PhantomData; diff --git a/src/test/ui/issues/issue-23477.rs b/src/test/ui/issues/issue-23477.rs index f363e6a0f4..b10b2e4961 100644 --- a/src/test/ui/issues/issue-23477.rs +++ b/src/test/ui/issues/issue-23477.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compiler-flags: -g pub struct Dst { diff --git a/src/test/run-pass/issues/issue-23485.rs b/src/test/ui/issues/issue-23485.rs similarity index 100% rename from src/test/run-pass/issues/issue-23485.rs rename to src/test/ui/issues/issue-23485.rs diff --git a/src/test/run-pass/issues/issue-23491.rs b/src/test/ui/issues/issue-23491.rs similarity index 100% rename from src/test/run-pass/issues/issue-23491.rs rename to src/test/ui/issues/issue-23491.rs diff --git a/src/test/ui/issues/issue-23550.rs b/src/test/ui/issues/issue-23550.rs index 370d5c5aa3..fad0ad7ecc 100644 --- a/src/test/ui/issues/issue-23550.rs +++ b/src/test/ui/issues/issue-23550.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(core_intrinsics)] #![allow(warnings)] diff --git a/src/test/run-pass/issues/issue-23611-enum-swap-in-drop.rs b/src/test/ui/issues/issue-23611-enum-swap-in-drop.rs similarity index 100% rename from src/test/run-pass/issues/issue-23611-enum-swap-in-drop.rs rename to src/test/ui/issues/issue-23611-enum-swap-in-drop.rs diff --git a/src/test/run-pass/issues/issue-23649-1.rs b/src/test/ui/issues/issue-23649-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-23649-1.rs rename to src/test/ui/issues/issue-23649-1.rs diff --git a/src/test/run-pass/issues/issue-23649-2.rs b/src/test/ui/issues/issue-23649-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-23649-2.rs rename to src/test/ui/issues/issue-23649-2.rs diff --git a/src/test/ui/issues/issue-23649-3.rs b/src/test/ui/issues/issue-23649-3.rs index 718fe606b8..febdc4256c 100644 --- a/src/test/ui/issues/issue-23649-3.rs +++ b/src/test/ui/issues/issue-23649-3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(PartialEq)] struct Slice { slice: [u8] } diff --git a/src/test/run-pass/issues/issue-23699.rs b/src/test/ui/issues/issue-23699.rs similarity index 100% rename from src/test/run-pass/issues/issue-23699.rs rename to src/test/ui/issues/issue-23699.rs diff --git a/src/test/run-pass/issues/issue-23781.rs b/src/test/ui/issues/issue-23781.rs similarity index 100% rename from src/test/run-pass/issues/issue-23781.rs rename to src/test/ui/issues/issue-23781.rs diff --git a/src/test/run-pass/issues/issue-2380-b.rs b/src/test/ui/issues/issue-2380-b.rs similarity index 100% rename from src/test/run-pass/issues/issue-2380-b.rs rename to src/test/ui/issues/issue-2380-b.rs diff --git a/src/test/run-pass/issues/issue-23808.rs b/src/test/ui/issues/issue-23808.rs similarity index 100% rename from src/test/run-pass/issues/issue-23808.rs rename to src/test/ui/issues/issue-23808.rs diff --git a/src/test/run-pass/issues/issue-23825.rs b/src/test/ui/issues/issue-23825.rs similarity index 100% rename from src/test/run-pass/issues/issue-23825.rs rename to src/test/ui/issues/issue-23825.rs diff --git a/src/test/run-pass/issues/issue-2383.rs b/src/test/ui/issues/issue-2383.rs similarity index 100% rename from src/test/run-pass/issues/issue-2383.rs rename to src/test/ui/issues/issue-2383.rs diff --git a/src/test/run-pass/issues/issue-23833.rs b/src/test/ui/issues/issue-23833.rs similarity index 100% rename from src/test/run-pass/issues/issue-23833.rs rename to src/test/ui/issues/issue-23833.rs diff --git a/src/test/run-pass/issues/issue-23891.rs b/src/test/ui/issues/issue-23891.rs similarity index 100% rename from src/test/run-pass/issues/issue-23891.rs rename to src/test/ui/issues/issue-23891.rs diff --git a/src/test/run-pass/issues/issue-23898.rs b/src/test/ui/issues/issue-23898.rs similarity index 100% rename from src/test/run-pass/issues/issue-23898.rs rename to src/test/ui/issues/issue-23898.rs diff --git a/src/test/run-pass/issues/issue-23958.rs b/src/test/ui/issues/issue-23958.rs similarity index 100% rename from src/test/run-pass/issues/issue-23958.rs rename to src/test/ui/issues/issue-23958.rs diff --git a/src/test/run-pass/issues/issue-23968-const-not-overflow.rs b/src/test/ui/issues/issue-23968-const-not-overflow.rs similarity index 100% rename from src/test/run-pass/issues/issue-23968-const-not-overflow.rs rename to src/test/ui/issues/issue-23968-const-not-overflow.rs diff --git a/src/test/run-pass/issues/issue-23992.rs b/src/test/ui/issues/issue-23992.rs similarity index 100% rename from src/test/run-pass/issues/issue-23992.rs rename to src/test/ui/issues/issue-23992.rs diff --git a/src/test/run-pass/issues/issue-24010.rs b/src/test/ui/issues/issue-24010.rs similarity index 94% rename from src/test/run-pass/issues/issue-24010.rs rename to src/test/ui/issues/issue-24010.rs index 264e1ee22c..f181853348 100644 --- a/src/test/run-pass/issues/issue-24010.rs +++ b/src/test/ui/issues/issue-24010.rs @@ -1,3 +1,5 @@ +// run-pass + trait Foo: Fn(i32) -> i32 + Send {} impl i32 + Send> Foo for T {} diff --git a/src/test/ui/issues/issue-24085.rs b/src/test/ui/issues/issue-24085.rs index d06647762a..dc2de922ff 100644 --- a/src/test/ui/issues/issue-24085.rs +++ b/src/test/ui/issues/issue-24085.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #24085. Errors were occurring in region // inference due to the requirement that `'a:b'`, which was getting diff --git a/src/test/run-pass/issues/issue-24086.rs b/src/test/ui/issues/issue-24086.rs similarity index 100% rename from src/test/run-pass/issues/issue-24086.rs rename to src/test/ui/issues/issue-24086.rs diff --git a/src/test/run-pass/issues/issue-2414-c.rs b/src/test/ui/issues/issue-2414-c.rs similarity index 100% rename from src/test/run-pass/issues/issue-2414-c.rs rename to src/test/ui/issues/issue-2414-c.rs diff --git a/src/test/ui/issues/issue-24161.rs b/src/test/ui/issues/issue-24161.rs index 99b09ba74d..c5c8651d43 100644 --- a/src/test/ui/issues/issue-24161.rs +++ b/src/test/ui/issues/issue-24161.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Copy,Clone)] struct Functions { diff --git a/src/test/ui/issues/issue-24227.rs b/src/test/ui/issues/issue-24227.rs index 83e12caff6..eaadaf7c44 100644 --- a/src/test/ui/issues/issue-24227.rs +++ b/src/test/ui/issues/issue-24227.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This resulted in an ICE. Test for future-proofing // Issue #24227 diff --git a/src/test/run-pass/issues/issue-2428.rs b/src/test/ui/issues/issue-2428.rs similarity index 100% rename from src/test/run-pass/issues/issue-2428.rs rename to src/test/ui/issues/issue-2428.rs diff --git a/src/test/run-pass/issues/issue-24308.rs b/src/test/ui/issues/issue-24308.rs similarity index 100% rename from src/test/run-pass/issues/issue-24308.rs rename to src/test/ui/issues/issue-24308.rs diff --git a/src/test/run-pass/issues/issue-24313.rs b/src/test/ui/issues/issue-24313.rs similarity index 100% rename from src/test/run-pass/issues/issue-24313.rs rename to src/test/ui/issues/issue-24313.rs diff --git a/src/test/ui/issues/issue-24338.rs b/src/test/ui/issues/issue-24338.rs index fafeff0642..09cc99f950 100644 --- a/src/test/ui/issues/issue-24338.rs +++ b/src/test/ui/issues/issue-24338.rs @@ -1,5 +1,5 @@ // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait DictLike<'a> { type ItemsIterator: Iterator; diff --git a/src/test/run-pass/issues/issue-24353.rs b/src/test/ui/issues/issue-24353.rs similarity index 100% rename from src/test/run-pass/issues/issue-24353.rs rename to src/test/ui/issues/issue-24353.rs diff --git a/src/test/ui/issues/issue-24389.rs b/src/test/ui/issues/issue-24389.rs index da48a76e20..63d1687af5 100644 --- a/src/test/ui/issues/issue-24389.rs +++ b/src/test/ui/issues/issue-24389.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo; diff --git a/src/test/ui/issues/issue-24434.rs b/src/test/ui/issues/issue-24434.rs index 2424a1c92c..b500b9d56d 100644 --- a/src/test/ui/issues/issue-24434.rs +++ b/src/test/ui/issues/issue-24434.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--cfg set1 #![cfg_attr(set1, feature(rustc_attrs))] diff --git a/src/test/run-pass/issues/issue-2445-b.rs b/src/test/ui/issues/issue-2445-b.rs similarity index 100% rename from src/test/run-pass/issues/issue-2445-b.rs rename to src/test/ui/issues/issue-2445-b.rs diff --git a/src/test/run-pass/issues/issue-2445.rs b/src/test/ui/issues/issue-2445.rs similarity index 100% rename from src/test/run-pass/issues/issue-2445.rs rename to src/test/ui/issues/issue-2445.rs diff --git a/src/test/run-pass/issues/issue-24533.rs b/src/test/ui/issues/issue-24533.rs similarity index 100% rename from src/test/run-pass/issues/issue-24533.rs rename to src/test/ui/issues/issue-24533.rs diff --git a/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs similarity index 100% rename from src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs rename to src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs diff --git a/src/test/run-pass/issues/issue-24589.rs b/src/test/ui/issues/issue-24589.rs similarity index 100% rename from src/test/run-pass/issues/issue-24589.rs rename to src/test/ui/issues/issue-24589.rs diff --git a/src/test/run-pass/issues/issue-2463.rs b/src/test/ui/issues/issue-2463.rs similarity index 100% rename from src/test/run-pass/issues/issue-2463.rs rename to src/test/ui/issues/issue-2463.rs diff --git a/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs similarity index 100% rename from src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs rename to src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs diff --git a/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs similarity index 100% rename from src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs rename to src/test/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs diff --git a/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs rename to src/test/ui/issues/issue-24687-embed-debuginfo/main.rs diff --git a/src/test/run-pass/issues/issue-2472.rs b/src/test/ui/issues/issue-2472.rs similarity index 100% rename from src/test/run-pass/issues/issue-2472.rs rename to src/test/ui/issues/issue-2472.rs diff --git a/src/test/run-pass/issues/issue-24779.rs b/src/test/ui/issues/issue-24779.rs similarity index 100% rename from src/test/run-pass/issues/issue-24779.rs rename to src/test/ui/issues/issue-24779.rs diff --git a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs b/src/test/ui/issues/issue-24805-dropck-itemless.rs similarity index 91% rename from src/test/run-pass/issues/issue-24805-dropck-itemless.rs rename to src/test/ui/issues/issue-24805-dropck-itemless.rs index db427ed3d3..555eefeb3a 100644 --- a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs +++ b/src/test/ui/issues/issue-24805-dropck-itemless.rs @@ -1,12 +1,11 @@ // run-pass -#![allow(deprecated)] // Check that item-less traits do not cause dropck to inject extra // region constraints. #![allow(non_camel_case_types)] -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] trait UserDefined { } @@ -20,9 +19,8 @@ impl<'a, T> UserDefined for &'a T { } // ``` macro_rules! impl_drop { ($Bound:ident, $Id:ident) => { - struct $Id(T); - impl Drop for $Id { - #[unsafe_destructor_blind_to_params] + struct $Id(T); + unsafe impl <#[may_dangle] T: $Bound> Drop for $Id { fn drop(&mut self) { } } } diff --git a/src/test/ui/issues/issue-2487-a.rs b/src/test/ui/issues/issue-2487-a.rs index 36e121ddb7..a43933d202 100644 --- a/src/test/ui/issues/issue-2487-a.rs +++ b/src/test/ui/issues/issue-2487-a.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/issues/issue-24945-repeat-dash-opts.rs b/src/test/ui/issues/issue-24945-repeat-dash-opts.rs similarity index 100% rename from src/test/run-pass/issues/issue-24945-repeat-dash-opts.rs rename to src/test/ui/issues/issue-24945-repeat-dash-opts.rs diff --git a/src/test/run-pass/issues/issue-24947.rs b/src/test/ui/issues/issue-24947.rs similarity index 100% rename from src/test/run-pass/issues/issue-24947.rs rename to src/test/ui/issues/issue-24947.rs diff --git a/src/test/run-pass/issues/issue-24954.rs b/src/test/ui/issues/issue-24954.rs similarity index 100% rename from src/test/run-pass/issues/issue-24954.rs rename to src/test/ui/issues/issue-24954.rs diff --git a/src/test/ui/issues/issue-2502.rs b/src/test/ui/issues/issue-2502.rs index 29b68c94c2..9a2bbb8241 100644 --- a/src/test/ui/issues/issue-2502.rs +++ b/src/test/ui/issues/issue-2502.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/issues/issue-25089.rs b/src/test/ui/issues/issue-25089.rs similarity index 100% rename from src/test/run-pass/issues/issue-25089.rs rename to src/test/ui/issues/issue-25089.rs diff --git a/src/test/run-pass/issues/issue-25145.rs b/src/test/ui/issues/issue-25145.rs similarity index 100% rename from src/test/run-pass/issues/issue-25145.rs rename to src/test/ui/issues/issue-25145.rs diff --git a/src/test/ui/issues/issue-25180.rs b/src/test/ui/issues/issue-25180.rs index 297f403c05..12f8f88a17 100644 --- a/src/test/ui/issues/issue-25180.rs +++ b/src/test/ui/issues/issue-25180.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/run-pass/issues/issue-25185.rs b/src/test/ui/issues/issue-25185.rs similarity index 100% rename from src/test/run-pass/issues/issue-25185.rs rename to src/test/ui/issues/issue-25185.rs diff --git a/src/test/run-pass/issues/issue-2526-a.rs b/src/test/ui/issues/issue-2526-a.rs similarity index 100% rename from src/test/run-pass/issues/issue-2526-a.rs rename to src/test/ui/issues/issue-2526-a.rs diff --git a/src/test/run-pass/issues/issue-25279.rs b/src/test/ui/issues/issue-25279.rs similarity index 100% rename from src/test/run-pass/issues/issue-25279.rs rename to src/test/ui/issues/issue-25279.rs diff --git a/src/test/run-pass/issues/issue-25339.rs b/src/test/ui/issues/issue-25339.rs similarity index 100% rename from src/test/run-pass/issues/issue-25339.rs rename to src/test/ui/issues/issue-25339.rs diff --git a/src/test/run-pass/issues/issue-25343.rs b/src/test/ui/issues/issue-25343.rs similarity index 100% rename from src/test/run-pass/issues/issue-25343.rs rename to src/test/ui/issues/issue-25343.rs diff --git a/src/test/ui/issues/issue-25394.rs b/src/test/ui/issues/issue-25394.rs index d1638aa98a..c41b554df1 100644 --- a/src/test/ui/issues/issue-25394.rs +++ b/src/test/ui/issues/issue-25394.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Debug)] struct Row([T]); diff --git a/src/test/run-pass/issues/issue-25467.rs b/src/test/ui/issues/issue-25467.rs similarity index 100% rename from src/test/run-pass/issues/issue-25467.rs rename to src/test/ui/issues/issue-25467.rs diff --git a/src/test/run-pass/issues/issue-25497.rs b/src/test/ui/issues/issue-25497.rs similarity index 100% rename from src/test/run-pass/issues/issue-25497.rs rename to src/test/ui/issues/issue-25497.rs diff --git a/src/test/run-pass/issues/issue-2550.rs b/src/test/ui/issues/issue-2550.rs similarity index 100% rename from src/test/run-pass/issues/issue-2550.rs rename to src/test/ui/issues/issue-2550.rs diff --git a/src/test/run-pass/issues/issue-25515.rs b/src/test/ui/issues/issue-25515.rs similarity index 100% rename from src/test/run-pass/issues/issue-25515.rs rename to src/test/ui/issues/issue-25515.rs diff --git a/src/test/run-pass/issues/issue-25549-multiple-drop.rs b/src/test/ui/issues/issue-25549-multiple-drop.rs similarity index 100% rename from src/test/run-pass/issues/issue-25549-multiple-drop.rs rename to src/test/ui/issues/issue-25549-multiple-drop.rs diff --git a/src/test/ui/issues/issue-25579.rs b/src/test/ui/issues/issue-25579.rs index 31ba102746..32b4b75b08 100644 --- a/src/test/ui/issues/issue-25579.rs +++ b/src/test/ui/issues/issue-25579.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Sexpression { Num(()), diff --git a/src/test/run-pass/issues/issue-25679.rs b/src/test/ui/issues/issue-25679.rs similarity index 100% rename from src/test/run-pass/issues/issue-25679.rs rename to src/test/ui/issues/issue-25679.rs diff --git a/src/test/run-pass/issues/issue-25693.rs b/src/test/ui/issues/issue-25693.rs similarity index 100% rename from src/test/run-pass/issues/issue-25693.rs rename to src/test/ui/issues/issue-25693.rs diff --git a/src/test/run-pass/issues/issue-25700-1.rs b/src/test/ui/issues/issue-25700-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-25700-1.rs rename to src/test/ui/issues/issue-25700-1.rs diff --git a/src/test/run-pass/issues/issue-25700-2.rs b/src/test/ui/issues/issue-25700-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-25700-2.rs rename to src/test/ui/issues/issue-25700-2.rs diff --git a/src/test/run-pass/issues/issue-25746-bool-transmute.rs b/src/test/ui/issues/issue-25746-bool-transmute.rs similarity index 100% rename from src/test/run-pass/issues/issue-25746-bool-transmute.rs rename to src/test/ui/issues/issue-25746-bool-transmute.rs diff --git a/src/test/run-pass/issues/issue-25757.rs b/src/test/ui/issues/issue-25757.rs similarity index 100% rename from src/test/run-pass/issues/issue-25757.rs rename to src/test/ui/issues/issue-25757.rs diff --git a/src/test/run-pass/issues/issue-25810.rs b/src/test/ui/issues/issue-25810.rs similarity index 100% rename from src/test/run-pass/issues/issue-25810.rs rename to src/test/ui/issues/issue-25810.rs diff --git a/src/test/ui/issues/issue-25826.stderr b/src/test/ui/issues/issue-25826.stderr index a800f787e3..84d5aeef63 100644 --- a/src/test/ui/issues/issue-25826.stderr +++ b/src/test/ui/issues/issue-25826.stderr @@ -5,7 +5,7 @@ LL | const A: bool = unsafe { id:: as *const () < id:: as *const () | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/53020 - = help: add #![feature(const_compare_raw_pointers)] to the crate attributes to enable + = help: add `#![feature(const_compare_raw_pointers)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-25916.rs b/src/test/ui/issues/issue-25916.rs similarity index 100% rename from src/test/run-pass/issues/issue-25916.rs rename to src/test/ui/issues/issue-25916.rs diff --git a/src/test/ui/issues/issue-26095.rs b/src/test/ui/issues/issue-26095.rs index 707cf1df51..1e3cc902e5 100644 --- a/src/test/ui/issues/issue-26095.rs +++ b/src/test/ui/issues/issue-26095.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-2611-3.rs b/src/test/ui/issues/issue-2611-3.rs index 5d4b65628d..7335d53f8a 100644 --- a/src/test/ui/issues/issue-2611-3.rs +++ b/src/test/ui/issues/issue-2611-3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Tests that impls are allowed to have looser, more permissive bounds // than the traits require. diff --git a/src/test/run-pass/issues/issue-26127.rs b/src/test/ui/issues/issue-26127.rs similarity index 100% rename from src/test/run-pass/issues/issue-26127.rs rename to src/test/ui/issues/issue-26127.rs diff --git a/src/test/ui/issues/issue-26158.rs b/src/test/ui/issues/issue-26158.rs deleted file mode 100644 index 11f47b6d02..0000000000 --- a/src/test/ui/issues/issue-26158.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(slice_patterns)] - -fn main() { - let x: &[u32] = &[]; - let &[[ref _a, ref _b..]..] = x; //~ ERROR refutable pattern -} diff --git a/src/test/ui/issues/issue-26158.stderr b/src/test/ui/issues/issue-26158.stderr deleted file mode 100644 index 3a4dd79e81..0000000000 --- a/src/test/ui/issues/issue-26158.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0005]: refutable pattern in local binding: `&[]` not covered - --> $DIR/issue-26158.rs:5:9 - | -LL | let &[[ref _a, ref _b..]..] = x; - | ^^^^^^^^^^^^^^^^^^^^^^^ pattern `&[]` not covered - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/issues/issue-26205.rs b/src/test/ui/issues/issue-26205.rs index 01b71652c0..45ca998a83 100644 --- a/src/test/ui/issues/issue-26205.rs +++ b/src/test/ui/issues/issue-26205.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::ops::{Deref, DerefMut}; diff --git a/src/test/run-pass/issues/issue-26251.rs b/src/test/ui/issues/issue-26251.rs similarity index 100% rename from src/test/run-pass/issues/issue-26251.rs rename to src/test/ui/issues/issue-26251.rs diff --git a/src/test/run-pass/issues/issue-2631-b.rs b/src/test/ui/issues/issue-2631-b.rs similarity index 100% rename from src/test/run-pass/issues/issue-2631-b.rs rename to src/test/ui/issues/issue-2631-b.rs diff --git a/src/test/run-pass/issues/issue-26322.rs b/src/test/ui/issues/issue-26322.rs similarity index 100% rename from src/test/run-pass/issues/issue-26322.rs rename to src/test/ui/issues/issue-26322.rs diff --git a/src/test/run-pass/issues/issue-2633-2.rs b/src/test/ui/issues/issue-2633-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-2633-2.rs rename to src/test/ui/issues/issue-2633-2.rs diff --git a/src/test/run-pass/issues/issue-2633.rs b/src/test/ui/issues/issue-2633.rs similarity index 100% rename from src/test/run-pass/issues/issue-2633.rs rename to src/test/ui/issues/issue-2633.rs diff --git a/src/test/run-pass/issues/issue-2642.rs b/src/test/ui/issues/issue-2642.rs similarity index 100% rename from src/test/run-pass/issues/issue-2642.rs rename to src/test/ui/issues/issue-2642.rs diff --git a/src/test/run-pass/issues/issue-26468.rs b/src/test/ui/issues/issue-26468.rs similarity index 100% rename from src/test/run-pass/issues/issue-26468.rs rename to src/test/ui/issues/issue-26468.rs diff --git a/src/test/run-pass/issues/issue-26484.rs b/src/test/ui/issues/issue-26484.rs similarity index 100% rename from src/test/run-pass/issues/issue-26484.rs rename to src/test/ui/issues/issue-26484.rs diff --git a/src/test/run-pass/issues/issue-26641.rs b/src/test/ui/issues/issue-26641.rs similarity index 100% rename from src/test/run-pass/issues/issue-26641.rs rename to src/test/ui/issues/issue-26641.rs diff --git a/src/test/ui/issues/issue-26646.rs b/src/test/ui/issues/issue-26646.rs index 6aa5e03996..d6f51ce9c9 100644 --- a/src/test/ui/issues/issue-26646.rs +++ b/src/test/ui/issues/issue-26646.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_attributes)] #[repr(C)] diff --git a/src/test/run-pass/issues/issue-26655.rs b/src/test/ui/issues/issue-26655.rs similarity index 100% rename from src/test/run-pass/issues/issue-26655.rs rename to src/test/ui/issues/issue-26655.rs diff --git a/src/test/run-pass/issues/issue-26709.rs b/src/test/ui/issues/issue-26709.rs similarity index 100% rename from src/test/run-pass/issues/issue-26709.rs rename to src/test/ui/issues/issue-26709.rs diff --git a/src/test/run-pass/issues/issue-26802.rs b/src/test/ui/issues/issue-26802.rs similarity index 100% rename from src/test/run-pass/issues/issue-26802.rs rename to src/test/ui/issues/issue-26802.rs diff --git a/src/test/run-pass/issues/issue-26805.rs b/src/test/ui/issues/issue-26805.rs similarity index 100% rename from src/test/run-pass/issues/issue-26805.rs rename to src/test/ui/issues/issue-26805.rs diff --git a/src/test/run-pass/issues/issue-26873-multifile.rs b/src/test/ui/issues/issue-26873-multifile.rs similarity index 100% rename from src/test/run-pass/issues/issue-26873-multifile.rs rename to src/test/ui/issues/issue-26873-multifile.rs diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/B.rs b/src/test/ui/issues/issue-26873-multifile/A/B.rs similarity index 100% rename from src/test/run-pass/issues/issue-26873-multifile/A/B.rs rename to src/test/ui/issues/issue-26873-multifile/A/B.rs diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/C.rs b/src/test/ui/issues/issue-26873-multifile/A/C.rs similarity index 100% rename from src/test/run-pass/issues/issue-26873-multifile/A/C.rs rename to src/test/ui/issues/issue-26873-multifile/A/C.rs diff --git a/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs b/src/test/ui/issues/issue-26873-multifile/A/mod.rs similarity index 100% rename from src/test/run-pass/issues/issue-26873-multifile/A/mod.rs rename to src/test/ui/issues/issue-26873-multifile/A/mod.rs diff --git a/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir b/src/test/ui/issues/issue-26873-multifile/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir rename to src/test/ui/issues/issue-26873-multifile/compiletest-ignore-dir diff --git a/src/test/run-pass/issues/issue-26873-multifile/mod.rs b/src/test/ui/issues/issue-26873-multifile/mod.rs similarity index 100% rename from src/test/run-pass/issues/issue-26873-multifile/mod.rs rename to src/test/ui/issues/issue-26873-multifile/mod.rs diff --git a/src/test/run-pass/issues/issue-26873-onefile.rs b/src/test/ui/issues/issue-26873-onefile.rs similarity index 100% rename from src/test/run-pass/issues/issue-26873-onefile.rs rename to src/test/ui/issues/issue-26873-onefile.rs diff --git a/src/test/run-pass/issues/issue-26905.rs b/src/test/ui/issues/issue-26905-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-26905.rs rename to src/test/ui/issues/issue-26905-rpass.rs diff --git a/src/test/run-pass/issues/issue-26996.rs b/src/test/ui/issues/issue-26996.rs similarity index 100% rename from src/test/run-pass/issues/issue-26996.rs rename to src/test/ui/issues/issue-26996.rs diff --git a/src/test/ui/issues/issue-26997.rs b/src/test/ui/issues/issue-26997.rs index dd48440720..a2b32a1367 100644 --- a/src/test/ui/issues/issue-26997.rs +++ b/src/test/ui/issues/issue-26997.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] pub struct Foo { x: isize, diff --git a/src/test/run-pass/issues/issue-27021.rs b/src/test/ui/issues/issue-27021.rs similarity index 100% rename from src/test/run-pass/issues/issue-27021.rs rename to src/test/ui/issues/issue-27021.rs diff --git a/src/test/ui/issues/issue-27042.rs b/src/test/ui/issues/issue-27042.rs index 8c7758597f..517c1f2e6c 100644 --- a/src/test/ui/issues/issue-27042.rs +++ b/src/test/ui/issues/issue-27042.rs @@ -6,6 +6,7 @@ fn main() { loop { break }; //~ ERROR mismatched types let _: i32 = 'b: //~ ERROR mismatched types + //~^ WARN denote infinite loops with while true { break }; // but here we cite the whole loop let _: i32 = 'c: //~ ERROR mismatched types diff --git a/src/test/ui/issues/issue-27042.stderr b/src/test/ui/issues/issue-27042.stderr index cce7d24a5f..7678984a51 100644 --- a/src/test/ui/issues/issue-27042.stderr +++ b/src/test/ui/issues/issue-27042.stderr @@ -1,16 +1,30 @@ +warning: denote infinite loops with `loop { ... }` + --> $DIR/issue-27042.rs:8:9 + | +LL | / 'b: +LL | | +LL | | while true { break }; // but here we cite the whole loop + | |____________________________^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + error[E0308]: mismatched types --> $DIR/issue-27042.rs:6:16 | LL | loop { break }; - | ^^^^^ expected (), found i32 + | ^^^^^ + | | + | expected i32, found () + | help: give it a value of the expected type: `break 42` | - = note: expected type `()` - found type `i32` + = note: expected type `i32` + found type `()` error[E0308]: mismatched types --> $DIR/issue-27042.rs:8:9 | LL | / 'b: +LL | | LL | | while true { break }; // but here we cite the whole loop | |____________________________^ expected i32, found () | @@ -18,7 +32,7 @@ LL | | while true { break }; // but here we cite the whole loop found type `()` error[E0308]: mismatched types - --> $DIR/issue-27042.rs:11:9 + --> $DIR/issue-27042.rs:12:9 | LL | / 'c: LL | | for _ in None { break }; // but here we cite the whole loop @@ -28,7 +42,7 @@ LL | | for _ in None { break }; // but here we cite the whole loop found type `()` error[E0308]: mismatched types - --> $DIR/issue-27042.rs:14:9 + --> $DIR/issue-27042.rs:15:9 | LL | / 'd: LL | | while let Some(_) = None { break }; diff --git a/src/test/run-pass/issues/issue-27054-primitive-binary-ops.rs b/src/test/ui/issues/issue-27054-primitive-binary-ops.rs similarity index 100% rename from src/test/run-pass/issues/issue-27054-primitive-binary-ops.rs rename to src/test/ui/issues/issue-27054-primitive-binary-ops.rs diff --git a/src/test/run-pass/issues/issue-27060.rs b/src/test/ui/issues/issue-27060-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-27060.rs rename to src/test/ui/issues/issue-27060-rpass.rs diff --git a/src/test/run-pass/issues/issue-2708.rs b/src/test/ui/issues/issue-2708.rs similarity index 100% rename from src/test/run-pass/issues/issue-2708.rs rename to src/test/ui/issues/issue-2708.rs diff --git a/src/test/ui/issues/issue-27105.rs b/src/test/ui/issues/issue-27105.rs index 1aafa11768..e7584d941b 100644 --- a/src/test/ui/issues/issue-27105.rs +++ b/src/test/ui/issues/issue-27105.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::RefCell; use std::rc::Rc; diff --git a/src/test/run-pass/issues/issue-2718.rs b/src/test/ui/issues/issue-2718.rs similarity index 100% rename from src/test/run-pass/issues/issue-2718.rs rename to src/test/ui/issues/issue-2718.rs diff --git a/src/test/run-pass/issues/issue-2723-b.rs b/src/test/ui/issues/issue-2723-b.rs similarity index 100% rename from src/test/run-pass/issues/issue-2723-b.rs rename to src/test/ui/issues/issue-2723-b.rs diff --git a/src/test/run-pass/issues/issue-27240.rs b/src/test/ui/issues/issue-27240.rs similarity index 100% rename from src/test/run-pass/issues/issue-27240.rs rename to src/test/ui/issues/issue-27240.rs diff --git a/src/test/run-pass/issues/issue-27268.rs b/src/test/ui/issues/issue-27268.rs similarity index 100% rename from src/test/run-pass/issues/issue-27268.rs rename to src/test/ui/issues/issue-27268.rs diff --git a/src/test/ui/issues/issue-27281.rs b/src/test/ui/issues/issue-27281.rs index 8403d9b450..58b8f07bca 100644 --- a/src/test/ui/issues/issue-27281.rs +++ b/src/test/ui/issues/issue-27281.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Trait<'a> { type T; type U; diff --git a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs index c79b187324..1ffb7f6fd4 100644 --- a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs +++ b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs @@ -5,9 +5,7 @@ // reject it. But I want to make sure that we continue to reject it // (under NLL) even when that conservaive check goes away. - #![feature(bind_by_move_pattern_guards)] -#![feature(nll)] fn main() { let mut b = &mut true; diff --git a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr index 3a10928981..a8eb78b7cc 100644 --- a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr +++ b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard - --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:16:25 + --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:14:25 | LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); | ^^ - mutable borrow occurs due to use of `r` in closure diff --git a/src/test/run-pass/issues/issue-27320.rs b/src/test/ui/issues/issue-27320.rs similarity index 100% rename from src/test/run-pass/issues/issue-27320.rs rename to src/test/ui/issues/issue-27320.rs diff --git a/src/test/run-pass/issues/issue-2734.rs b/src/test/ui/issues/issue-2734.rs similarity index 100% rename from src/test/run-pass/issues/issue-2734.rs rename to src/test/ui/issues/issue-2734.rs diff --git a/src/test/run-pass/issues/issue-2735-2.rs b/src/test/ui/issues/issue-2735-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-2735-2.rs rename to src/test/ui/issues/issue-2735-2.rs diff --git a/src/test/run-pass/issues/issue-2735-3.rs b/src/test/ui/issues/issue-2735-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-2735-3.rs rename to src/test/ui/issues/issue-2735-3.rs diff --git a/src/test/run-pass/issues/issue-2735.rs b/src/test/ui/issues/issue-2735.rs similarity index 100% rename from src/test/run-pass/issues/issue-2735.rs rename to src/test/ui/issues/issue-2735.rs diff --git a/src/test/run-pass/issues/issue-27401-dropflag-reinit.rs b/src/test/ui/issues/issue-27401-dropflag-reinit.rs similarity index 100% rename from src/test/run-pass/issues/issue-27401-dropflag-reinit.rs rename to src/test/ui/issues/issue-27401-dropflag-reinit.rs diff --git a/src/test/ui/issues/issue-2748-a.rs b/src/test/ui/issues/issue-2748-a.rs index 683a931cc3..5f566e186e 100644 --- a/src/test/ui/issues/issue-2748-a.rs +++ b/src/test/ui/issues/issue-2748-a.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_snake_case)] diff --git a/src/test/run-pass/issues/issue-2748-b.rs b/src/test/ui/issues/issue-2748-b.rs similarity index 100% rename from src/test/run-pass/issues/issue-2748-b.rs rename to src/test/ui/issues/issue-2748-b.rs diff --git a/src/test/ui/issues/issue-27583.rs b/src/test/ui/issues/issue-27583.rs index 763e9ebe24..9981f867bd 100644 --- a/src/test/ui/issues/issue-27583.rs +++ b/src/test/ui/issues/issue-27583.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for issue #27583. Unclear how useful this will be // going forward, since the issue in question was EXTREMELY sensitive // to compiler internals (like the precise numbering of nodes), but diff --git a/src/test/run-pass/issues/issue-27639.rs b/src/test/ui/issues/issue-27639.rs similarity index 100% rename from src/test/run-pass/issues/issue-27639.rs rename to src/test/ui/issues/issue-27639.rs diff --git a/src/test/run-pass/issues/issue-27859.rs b/src/test/ui/issues/issue-27859.rs similarity index 100% rename from src/test/run-pass/issues/issue-27859.rs rename to src/test/ui/issues/issue-27859.rs diff --git a/src/test/ui/issues/issue-27889.rs b/src/test/ui/issues/issue-27889.rs index 22de7c7cfa..bb5a186b45 100644 --- a/src/test/ui/issues/issue-27889.rs +++ b/src/test/ui/issues/issue-27889.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_assignments)] #![allow(unused_variables)] // Test that a field can have the same name in different variants diff --git a/src/test/run-pass/issues/issue-27890.rs b/src/test/ui/issues/issue-27890.rs similarity index 100% rename from src/test/run-pass/issues/issue-27890.rs rename to src/test/ui/issues/issue-27890.rs diff --git a/src/test/run-pass/issues/issue-27901.rs b/src/test/ui/issues/issue-27901.rs similarity index 100% rename from src/test/run-pass/issues/issue-27901.rs rename to src/test/ui/issues/issue-27901.rs diff --git a/src/test/run-pass/issues/issue-27949.rs b/src/test/ui/issues/issue-27949.rs similarity index 100% rename from src/test/run-pass/issues/issue-27949.rs rename to src/test/ui/issues/issue-27949.rs diff --git a/src/test/run-pass/issues/issue-27997.rs b/src/test/ui/issues/issue-27997.rs similarity index 100% rename from src/test/run-pass/issues/issue-27997.rs rename to src/test/ui/issues/issue-27997.rs diff --git a/src/test/ui/issues/issue-2804-2.rs b/src/test/ui/issues/issue-2804-2.rs index d515742061..68933fc2e8 100644 --- a/src/test/ui/issues/issue-2804-2.rs +++ b/src/test/ui/issues/issue-2804-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Minimized version of issue-2804.rs. Both check that callee IDs don't // clobber the previous node ID in a macro expr diff --git a/src/test/ui/issues/issue-28075.stderr b/src/test/ui/issues/issue-28075.stderr index 323be5cc2c..7e53bb5445 100644 --- a/src/test/ui/issues/issue-28075.stderr +++ b/src/test/ui/issues/issue-28075.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | use lint_stability::{unstable, deprecated}; | ^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28134.rs b/src/test/ui/issues/issue-28134.rs index 2bd4f93791..fa692db4bf 100644 --- a/src/test/ui/issues/issue-28134.rs +++ b/src/test/ui/issues/issue-28134.rs @@ -1,3 +1,3 @@ // compile-flags: --test -#![test] //~ ERROR only functions may be used as tests +#![test] //~ ERROR cannot determine resolution for the attribute macro `test` diff --git a/src/test/ui/issues/issue-28134.stderr b/src/test/ui/issues/issue-28134.stderr index b918948004..5f8d27dd04 100644 --- a/src/test/ui/issues/issue-28134.stderr +++ b/src/test/ui/issues/issue-28134.stderr @@ -1,8 +1,10 @@ -error: only functions may be used as tests - --> $DIR/issue-28134.rs:3:1 +error: cannot determine resolution for the attribute macro `test` + --> $DIR/issue-28134.rs:3:4 | LL | #![test] - | ^^^^^^^^ + | ^^^^ + | + = note: import resolution is stuck, try simplifying macro imports error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-28181.rs b/src/test/ui/issues/issue-28181.rs similarity index 100% rename from src/test/run-pass/issues/issue-28181.rs rename to src/test/ui/issues/issue-28181.rs diff --git a/src/test/ui/issues/issue-28279.rs b/src/test/ui/issues/issue-28279.rs index fab91160a8..e36a9551ab 100644 --- a/src/test/ui/issues/issue-28279.rs +++ b/src/test/ui/issues/issue-28279.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::rc::Rc; diff --git a/src/test/ui/issues/issue-28388-3.stderr b/src/test/ui/issues/issue-28388-3.stderr index 2eb8249250..d2e46683b9 100644 --- a/src/test/ui/issues/issue-28388-3.stderr +++ b/src/test/ui/issues/issue-28388-3.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'unstable_test_feature' LL | use lint_stability::UnstableEnum::{}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: add #![feature(unstable_test_feature)] to the crate attributes to enable + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-28498-must-work-ex1.rs b/src/test/ui/issues/issue-28498-must-work-ex1.rs similarity index 100% rename from src/test/run-pass/issues/issue-28498-must-work-ex1.rs rename to src/test/ui/issues/issue-28498-must-work-ex1.rs diff --git a/src/test/run-pass/issues/issue-28498-must-work-ex2.rs b/src/test/ui/issues/issue-28498-must-work-ex2.rs similarity index 100% rename from src/test/run-pass/issues/issue-28498-must-work-ex2.rs rename to src/test/ui/issues/issue-28498-must-work-ex2.rs diff --git a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs b/src/test/ui/issues/issue-28498-ugeh-ex1.rs similarity index 73% rename from src/test/run-pass/issues/issue-28498-ugeh-ex1.rs rename to src/test/ui/issues/issue-28498-ugeh-ex1.rs index c4f249c45f..90cf2cddcf 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs +++ b/src/test/ui/issues/issue-28498-ugeh-ex1.rs @@ -1,21 +1,19 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Example taken from RFC 1238 text // https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md // #example-of-the-unguarded-escape-hatch -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] use std::cell::Cell; struct Concrete<'a>(u32, Cell>>); struct Foo { data: Vec } -impl Drop for Foo { - // Below is the UGEH attribute - #[unsafe_destructor_blind_to_params] +// Below is the UGEH attribute +unsafe impl<#[may_dangle] T> Drop for Foo { fn drop(&mut self) { } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs b/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs similarity index 73% rename from src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs rename to src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs index 573ec8f613..aea9fde530 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs +++ b/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs @@ -1,12 +1,11 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Demonstrate the use of the unguarded escape hatch with a lifetime param // to assert that destructor will not access any dead data. // // Compare with compile-fail/issue28498-reject-lifetime-param.rs -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #[derive(Debug)] struct ScribbleOnDrop(String); @@ -19,11 +18,9 @@ impl Drop for ScribbleOnDrop { struct Foo<'a>(u32, &'a ScribbleOnDrop); -impl<'a> Drop for Foo<'a> { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] 'a> Drop for Foo<'a> { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is sound, - // because destructor never accesses `self.1`. + // Use of `may_dangle` is sound, because destructor never accesses `self.1`. println!("Dropping Foo({}, _)", self.0); } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs similarity index 76% rename from src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs rename to src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs index e0863fa994..91ef5a7c98 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs +++ b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs @@ -1,5 +1,4 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Demonstrate the use of the unguarded escape hatch with a type param in negative position // to assert that destructor will not access any dead data. @@ -11,7 +10,7 @@ // // Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] #[derive(Debug)] struct ScribbleOnDrop(String); @@ -24,12 +23,10 @@ impl Drop for ScribbleOnDrop { struct Foo(u32, T, Box fn(&'r T) -> String>); -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T> Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is sound, - // because destructor never passes a `self.1` to the callback - // (in `self.2`) despite having it available. + // Use of `may_dangle` is sound, because destructor never passes a `self.1` + // to the callback (in `self.2`) despite having it available. println!("Dropping Foo({}, _)", self.0); } } diff --git a/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs b/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs similarity index 66% rename from src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs rename to src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs index 01d884584f..808f3b6e81 100644 --- a/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs +++ b/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs @@ -1,12 +1,11 @@ // run-pass -#![allow(deprecated)] // FIXME: switch to `#[may_dangle]` below. // Demonstrate the use of the unguarded escape hatch with a trait bound // to assert that destructor will not access any dead data. // // Compare with compile-fail/issue28498-reject-trait-bound.rs -#![feature(dropck_parametricity)] +#![feature(dropck_eyepatch)] use std::fmt; @@ -19,14 +18,12 @@ impl Drop for ScribbleOnDrop { } } -struct Foo(u32, T); +struct Foo(u32, T); -impl Drop for Foo { - #[unsafe_destructor_blind_to_params] +unsafe impl<#[may_dangle] T: fmt::Debug> Drop for Foo { fn drop(&mut self) { - // Use of `unsafe_destructor_blind_to_params` is sound, - // because destructor never accesses the `Debug::fmt` method - // of `T`, despite having it available. + // Use of `may_dangle` is sound, because destructor never accesses + // the `Debug::fmt` method of `T`, despite having it available. println!("Dropping Foo({}, _)", self.0); } } diff --git a/src/test/run-pass/issues/issue-28550.rs b/src/test/ui/issues/issue-28550.rs similarity index 100% rename from src/test/run-pass/issues/issue-28550.rs rename to src/test/ui/issues/issue-28550.rs diff --git a/src/test/ui/issues/issue-28561.rs b/src/test/ui/issues/issue-28561.rs index 9dcce9991f..cc4e63696e 100644 --- a/src/test/ui/issues/issue-28561.rs +++ b/src/test/ui/issues/issue-28561.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] struct Array { f00: [T; 00], diff --git a/src/test/ui/issues/issue-28600.rs b/src/test/ui/issues/issue-28600.rs index 44a85924e3..05c4050b03 100644 --- a/src/test/ui/issues/issue-28600.rs +++ b/src/test/ui/issues/issue-28600.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // #28600 ICE: pub extern fn with parameter type &str inside struct impl struct Test; diff --git a/src/test/run-pass/issues/issue-28676.rs b/src/test/ui/issues/issue-28676.rs similarity index 100% rename from src/test/run-pass/issues/issue-28676.rs rename to src/test/ui/issues/issue-28676.rs diff --git a/src/test/run-pass/issues/issue-28777.rs b/src/test/ui/issues/issue-28777.rs similarity index 100% rename from src/test/run-pass/issues/issue-28777.rs rename to src/test/ui/issues/issue-28777.rs diff --git a/src/test/ui/issues/issue-28822.rs b/src/test/ui/issues/issue-28822.rs index 7381c348cd..2c0c01aa82 100644 --- a/src/test/ui/issues/issue-28822.rs +++ b/src/test/ui/issues/issue-28822.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] fn main() {} diff --git a/src/test/run-pass/issues/issue-28828.rs b/src/test/ui/issues/issue-28828.rs similarity index 100% rename from src/test/run-pass/issues/issue-28828.rs rename to src/test/ui/issues/issue-28828.rs diff --git a/src/test/run-pass/issues/issue-28839.rs b/src/test/ui/issues/issue-28839.rs similarity index 100% rename from src/test/run-pass/issues/issue-28839.rs rename to src/test/ui/issues/issue-28839.rs diff --git a/src/test/ui/issues/issue-28871.rs b/src/test/ui/issues/issue-28871.rs index b7e02b8587..43564dfcc4 100644 --- a/src/test/ui/issues/issue-28871.rs +++ b/src/test/ui/issues/issue-28871.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for #28871. The problem is that rustc encountered // two ways to project, one from a where clause and one from the where // clauses on the trait definition. (In fact, in this case, the where diff --git a/src/test/ui/issues/issue-28936.rs b/src/test/ui/issues/issue-28936.rs index 5365adf3e8..9267491aaf 100644 --- a/src/test/ui/issues/issue-28936.rs +++ b/src/test/ui/issues/issue-28936.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub type Session = i32; pub struct StreamParser<'a, T> { _tokens: T, diff --git a/src/test/run-pass/issues/issue-2895.rs b/src/test/ui/issues/issue-2895.rs similarity index 100% rename from src/test/run-pass/issues/issue-2895.rs rename to src/test/ui/issues/issue-2895.rs diff --git a/src/test/run-pass/issues/issue-28950.rs b/src/test/ui/issues/issue-28950.rs similarity index 100% rename from src/test/run-pass/issues/issue-28950.rs rename to src/test/ui/issues/issue-28950.rs diff --git a/src/test/run-pass/issues/issue-28983.rs b/src/test/ui/issues/issue-28983.rs similarity index 100% rename from src/test/run-pass/issues/issue-28983.rs rename to src/test/ui/issues/issue-28983.rs diff --git a/src/test/ui/issues/issue-28999.rs b/src/test/ui/issues/issue-28999.rs index 4f6fa412e8..888a8010a2 100644 --- a/src/test/ui/issues/issue-28999.rs +++ b/src/test/ui/issues/issue-28999.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Xyz<'a, V> { pub v: (V, &'a u32), } diff --git a/src/test/ui/issues/issue-29030.rs b/src/test/ui/issues/issue-29030.rs index 9ac7742e4f..f9e8984031 100644 --- a/src/test/ui/issues/issue-29030.rs +++ b/src/test/ui/issues/issue-29030.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Debug)] struct Message<'a, P: 'a = &'a [u8]> { diff --git a/src/test/ui/issues/issue-29037.rs b/src/test/ui/issues/issue-29037.rs index e0eb71f5de..b1ca76be10 100644 --- a/src/test/ui/issues/issue-29037.rs +++ b/src/test/ui/issues/issue-29037.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // This test ensures that each pointer type `P` is covariant in `X`. diff --git a/src/test/ui/issues/issue-2904.rs b/src/test/ui/issues/issue-2904.rs index 42f71a1b09..36bc8002f9 100644 --- a/src/test/ui/issues/issue-2904.rs +++ b/src/test/ui/issues/issue-2904.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/src/test/ui/issues/issue-29048.rs b/src/test/ui/issues/issue-29048.rs index 6c4b6183c3..e3ccb0d657 100644 --- a/src/test/ui/issues/issue-29048.rs +++ b/src/test/ui/issues/issue-29048.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Chan; pub struct ChanSelect<'c, T> { chans: Vec<(&'c Chan, T)>, diff --git a/src/test/run-pass/issues/issue-29053.rs b/src/test/ui/issues/issue-29053.rs similarity index 100% rename from src/test/run-pass/issues/issue-29053.rs rename to src/test/ui/issues/issue-29053.rs diff --git a/src/test/run-pass/issues/issue-29071-2.rs b/src/test/ui/issues/issue-29071-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-29071-2.rs rename to src/test/ui/issues/issue-29071-2.rs diff --git a/src/test/ui/issues/issue-29071.rs b/src/test/ui/issues/issue-29071.rs index 1ea4a54226..7e016a715c 100644 --- a/src/test/ui/issues/issue-29071.rs +++ b/src/test/ui/issues/issue-29071.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/run-pass/issues/issue-29092.rs b/src/test/ui/issues/issue-29092.rs similarity index 100% rename from src/test/run-pass/issues/issue-29092.rs rename to src/test/ui/issues/issue-29092.rs diff --git a/src/test/run-pass/issues/issue-29147.rs b/src/test/ui/issues/issue-29147-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-29147.rs rename to src/test/ui/issues/issue-29147-rpass.rs diff --git a/src/test/run-pass/issues/issue-29166.rs b/src/test/ui/issues/issue-29166.rs similarity index 100% rename from src/test/run-pass/issues/issue-29166.rs rename to src/test/ui/issues/issue-29166.rs diff --git a/src/test/run-pass/issues/issue-29227.rs b/src/test/ui/issues/issue-29227.rs similarity index 100% rename from src/test/run-pass/issues/issue-29227.rs rename to src/test/ui/issues/issue-29227.rs diff --git a/src/test/ui/issues/issue-29265.rs b/src/test/ui/issues/issue-29265.rs new file mode 100644 index 0000000000..f554c4d16c --- /dev/null +++ b/src/test/ui/issues/issue-29265.rs @@ -0,0 +1,10 @@ +// aux-build:issue-29265.rs +// check-pass + +extern crate issue_29265 as lib; + +static _UNUSED: &'static lib::SomeType = &lib::SOME_VALUE; + +fn main() { + vec![0u8; lib::SOME_VALUE.some_member]; +} diff --git a/src/test/ui/issues/issue-29276.rs b/src/test/ui/issues/issue-29276.rs index 2a0358bc52..2532dac977 100644 --- a/src/test/ui/issues/issue-29276.rs +++ b/src/test/ui/issues/issue-29276.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct S([u8; { struct Z; 0 }]); diff --git a/src/test/run-pass/issues/issue-2935.rs b/src/test/ui/issues/issue-2935.rs similarity index 100% rename from src/test/run-pass/issues/issue-2935.rs rename to src/test/ui/issues/issue-2935.rs diff --git a/src/test/run-pass/issues/issue-2936.rs b/src/test/ui/issues/issue-2936.rs similarity index 100% rename from src/test/run-pass/issues/issue-2936.rs rename to src/test/ui/issues/issue-2936.rs diff --git a/src/test/run-pass/issues/issue-29466.rs b/src/test/ui/issues/issue-29466.rs similarity index 100% rename from src/test/run-pass/issues/issue-29466.rs rename to src/test/ui/issues/issue-29466.rs diff --git a/src/test/run-pass/issues/issue-29485.rs b/src/test/ui/issues/issue-29485.rs similarity index 100% rename from src/test/run-pass/issues/issue-29485.rs rename to src/test/ui/issues/issue-29485.rs diff --git a/src/test/run-pass/issues/issue-29488.rs b/src/test/ui/issues/issue-29488.rs similarity index 100% rename from src/test/run-pass/issues/issue-29488.rs rename to src/test/ui/issues/issue-29488.rs diff --git a/src/test/ui/issues/issue-29516.rs b/src/test/ui/issues/issue-29516.rs index 8082694e15..8966730fd8 100644 --- a/src/test/ui/issues/issue-29516.rs +++ b/src/test/ui/issues/issue-29516.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(optin_builtin_traits)] auto trait NotSame {} diff --git a/src/test/run-pass/issues/issue-29522.rs b/src/test/ui/issues/issue-29522.rs similarity index 100% rename from src/test/run-pass/issues/issue-29522.rs rename to src/test/ui/issues/issue-29522.rs diff --git a/src/test/ui/issues/issue-29540.rs b/src/test/ui/issues/issue-29540.rs index b68205eda8..e472f71aa7 100644 --- a/src/test/ui/issues/issue-29540.rs +++ b/src/test/ui/issues/issue-29540.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(Debug)] pub struct Config { pub name: String, diff --git a/src/test/run-pass/issues/issue-29663.rs b/src/test/ui/issues/issue-29663.rs similarity index 100% rename from src/test/run-pass/issues/issue-29663.rs rename to src/test/ui/issues/issue-29663.rs diff --git a/src/test/run-pass/issues/issue-29668.rs b/src/test/ui/issues/issue-29668.rs similarity index 100% rename from src/test/run-pass/issues/issue-29668.rs rename to src/test/ui/issues/issue-29668.rs diff --git a/src/test/ui/issues/issue-29710.rs b/src/test/ui/issues/issue-29710.rs index 58907e78e4..d4de756e56 100644 --- a/src/test/ui/issues/issue-29710.rs +++ b/src/test/ui/issues/issue-29710.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_results)] #![allow(dead_code)] diff --git a/src/test/ui/issues/issue-29740.rs b/src/test/ui/issues/issue-29740.rs index f37d868ab7..50a03d86ac 100644 --- a/src/test/ui/issues/issue-29740.rs +++ b/src/test/ui/issues/issue-29740.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #29740. Inefficient MIR matching algorithms // generated way too much code for this sort of case, leading to OOM. diff --git a/src/test/ui/issues/issue-29743.rs b/src/test/ui/issues/issue-29743.rs index 5bc3b0c537..2598b07490 100644 --- a/src/test/ui/issues/issue-29743.rs +++ b/src/test/ui/issues/issue-29743.rs @@ -1,5 +1,5 @@ // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let mut i = [1, 2, 3]; diff --git a/src/test/run-pass/issues/issue-29746.rs b/src/test/ui/issues/issue-29746.rs similarity index 100% rename from src/test/run-pass/issues/issue-29746.rs rename to src/test/ui/issues/issue-29746.rs diff --git a/src/test/run-pass/issues/issue-29844.rs b/src/test/ui/issues/issue-29844.rs similarity index 100% rename from src/test/run-pass/issues/issue-29844.rs rename to src/test/ui/issues/issue-29844.rs diff --git a/src/test/run-pass/issues/issue-2989.rs b/src/test/ui/issues/issue-2989.rs similarity index 100% rename from src/test/run-pass/issues/issue-2989.rs rename to src/test/ui/issues/issue-2989.rs diff --git a/src/test/run-pass/issues/issue-29914-2.rs b/src/test/ui/issues/issue-29914-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-29914-2.rs rename to src/test/ui/issues/issue-29914-2.rs diff --git a/src/test/run-pass/issues/issue-29914-3.rs b/src/test/ui/issues/issue-29914-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-29914-3.rs rename to src/test/ui/issues/issue-29914-3.rs diff --git a/src/test/run-pass/issues/issue-29914.rs b/src/test/ui/issues/issue-29914.rs similarity index 100% rename from src/test/run-pass/issues/issue-29914.rs rename to src/test/ui/issues/issue-29914.rs diff --git a/src/test/run-pass/issues/issue-29927-1.rs b/src/test/ui/issues/issue-29927-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-29927-1.rs rename to src/test/ui/issues/issue-29927-1.rs diff --git a/src/test/run-pass/issues/issue-29927.rs b/src/test/ui/issues/issue-29927.rs similarity index 100% rename from src/test/run-pass/issues/issue-29927.rs rename to src/test/ui/issues/issue-29927.rs diff --git a/src/test/run-pass/issues/issue-29948.rs b/src/test/ui/issues/issue-29948.rs similarity index 100% rename from src/test/run-pass/issues/issue-29948.rs rename to src/test/ui/issues/issue-29948.rs diff --git a/src/test/run-pass/issues/issue-30018-nopanic.rs b/src/test/ui/issues/issue-30018-nopanic.rs similarity index 100% rename from src/test/run-pass/issues/issue-30018-nopanic.rs rename to src/test/ui/issues/issue-30018-nopanic.rs diff --git a/src/test/run-pass/issues/issue-30018-panic.rs b/src/test/ui/issues/issue-30018-panic.rs similarity index 100% rename from src/test/run-pass/issues/issue-30018-panic.rs rename to src/test/ui/issues/issue-30018-panic.rs diff --git a/src/test/ui/issues/issue-30079.stderr b/src/test/ui/issues/issue-30079.stderr index 57ca572154..6fc8b81074 100644 --- a/src/test/ui/issues/issue-30079.stderr +++ b/src/test/ui/issues/issue-30079.stderr @@ -4,7 +4,7 @@ warning: private type `m1::Priv` in public interface (error E0446) LL | pub fn f(_: Priv) {} | ^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(private_in_public)] on by default + = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 diff --git a/src/test/run-pass/issues/issue-30081.rs b/src/test/ui/issues/issue-30081.rs similarity index 100% rename from src/test/run-pass/issues/issue-30081.rs rename to src/test/ui/issues/issue-30081.rs diff --git a/src/test/run-pass/issues/issue-3012-2.rs b/src/test/ui/issues/issue-3012-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-3012-2.rs rename to src/test/ui/issues/issue-3012-2.rs diff --git a/src/test/run-pass/issues/issue-30240.rs b/src/test/ui/issues/issue-30240-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-30240.rs rename to src/test/ui/issues/issue-30240-rpass.rs diff --git a/src/test/run-pass/issues/issue-3026.rs b/src/test/ui/issues/issue-3026.rs similarity index 100% rename from src/test/run-pass/issues/issue-3026.rs rename to src/test/ui/issues/issue-3026.rs diff --git a/src/test/run-pass/issues/issue-3037.rs b/src/test/ui/issues/issue-3037.rs similarity index 100% rename from src/test/run-pass/issues/issue-3037.rs rename to src/test/ui/issues/issue-3037.rs diff --git a/src/test/run-pass/issues/issue-30371.rs b/src/test/ui/issues/issue-30371.rs similarity index 100% rename from src/test/run-pass/issues/issue-30371.rs rename to src/test/ui/issues/issue-30371.rs diff --git a/src/test/run-pass/issues/issue-30490.rs b/src/test/ui/issues/issue-30490.rs similarity index 100% rename from src/test/run-pass/issues/issue-30490.rs rename to src/test/ui/issues/issue-30490.rs diff --git a/src/test/run-pass/issues/issue-3052.rs b/src/test/ui/issues/issue-3052.rs similarity index 100% rename from src/test/run-pass/issues/issue-3052.rs rename to src/test/ui/issues/issue-3052.rs diff --git a/src/test/run-pass/issues/issue-30530.rs b/src/test/ui/issues/issue-30530.rs similarity index 100% rename from src/test/run-pass/issues/issue-30530.rs rename to src/test/ui/issues/issue-30530.rs diff --git a/src/test/run-pass/issues/issue-30615.rs b/src/test/ui/issues/issue-30615.rs similarity index 100% rename from src/test/run-pass/issues/issue-30615.rs rename to src/test/ui/issues/issue-30615.rs diff --git a/src/test/ui/issues/issue-30730.stderr b/src/test/ui/issues/issue-30730.stderr index 0a901076f4..fcbab77b00 100644 --- a/src/test/ui/issues/issue-30730.stderr +++ b/src/test/ui/issues/issue-30730.stderr @@ -9,7 +9,7 @@ note: lint level defined here | LL | #![deny(warnings)] | ^^^^^^^^ - = note: #[deny(unused_imports)] implied by #[deny(warnings)] + = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]` error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-30756.rs b/src/test/ui/issues/issue-30756.rs similarity index 100% rename from src/test/run-pass/issues/issue-30756.rs rename to src/test/ui/issues/issue-30756.rs diff --git a/src/test/run-pass/issues/issue-30891.rs b/src/test/ui/issues/issue-30891.rs similarity index 100% rename from src/test/run-pass/issues/issue-30891.rs rename to src/test/ui/issues/issue-30891.rs diff --git a/src/test/run-pass/issues/issue-3091.rs b/src/test/ui/issues/issue-3091.rs similarity index 100% rename from src/test/run-pass/issues/issue-3091.rs rename to src/test/ui/issues/issue-3091.rs diff --git a/src/test/run-pass/issues/issue-3109.rs b/src/test/ui/issues/issue-3109.rs similarity index 100% rename from src/test/run-pass/issues/issue-3109.rs rename to src/test/ui/issues/issue-3109.rs diff --git a/src/test/run-pass/issues/issue-3121.rs b/src/test/ui/issues/issue-3121.rs similarity index 100% rename from src/test/run-pass/issues/issue-3121.rs rename to src/test/ui/issues/issue-3121.rs diff --git a/src/test/ui/issues/issue-31260.rs b/src/test/ui/issues/issue-31260.rs index f7e717c59a..608900301e 100644 --- a/src/test/ui/issues/issue-31260.rs +++ b/src/test/ui/issues/issue-31260.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] pub struct Struct { pub field: K, diff --git a/src/test/run-pass/issues/issue-31267-additional.rs b/src/test/ui/issues/issue-31267-additional.rs similarity index 100% rename from src/test/run-pass/issues/issue-31267-additional.rs rename to src/test/ui/issues/issue-31267-additional.rs diff --git a/src/test/run-pass/issues/issue-31267.rs b/src/test/ui/issues/issue-31267.rs similarity index 100% rename from src/test/run-pass/issues/issue-31267.rs rename to src/test/ui/issues/issue-31267.rs diff --git a/src/test/run-pass/issues/issue-31299.rs b/src/test/ui/issues/issue-31299.rs similarity index 100% rename from src/test/run-pass/issues/issue-31299.rs rename to src/test/ui/issues/issue-31299.rs diff --git a/src/test/run-pass/issues/issue-3136-b.rs b/src/test/ui/issues/issue-3136-b.rs similarity index 100% rename from src/test/run-pass/issues/issue-3136-b.rs rename to src/test/ui/issues/issue-3136-b.rs diff --git a/src/test/ui/issues/issue-3149.rs b/src/test/ui/issues/issue-3149.rs index c9a6f53775..da3fe9ad6e 100644 --- a/src/test/ui/issues/issue-3149.rs +++ b/src/test/ui/issues/issue-3149.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_snake_case)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-31597.rs b/src/test/ui/issues/issue-31597.rs index 3962f13fe9..1d28a91ea7 100644 --- a/src/test/ui/issues/issue-31597.rs +++ b/src/test/ui/issues/issue-31597.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Make { type Out; diff --git a/src/test/run-pass/issues/issue-31702.rs b/src/test/ui/issues/issue-31702.rs similarity index 100% rename from src/test/run-pass/issues/issue-31702.rs rename to src/test/ui/issues/issue-31702.rs diff --git a/src/test/run-pass/issues/issue-31776.rs b/src/test/ui/issues/issue-31776.rs similarity index 100% rename from src/test/run-pass/issues/issue-31776.rs rename to src/test/ui/issues/issue-31776.rs diff --git a/src/test/run-pass/issues/issue-32008.rs b/src/test/ui/issues/issue-32008.rs similarity index 100% rename from src/test/run-pass/issues/issue-32008.rs rename to src/test/ui/issues/issue-32008.rs diff --git a/src/test/run-pass/issues/issue-3211.rs b/src/test/ui/issues/issue-3211.rs similarity index 100% rename from src/test/run-pass/issues/issue-3211.rs rename to src/test/ui/issues/issue-3211.rs diff --git a/src/test/run-pass/issues/issue-3220.rs b/src/test/ui/issues/issue-3220.rs similarity index 100% rename from src/test/run-pass/issues/issue-3220.rs rename to src/test/ui/issues/issue-3220.rs diff --git a/src/test/run-pass/issues/issue-32292.rs b/src/test/ui/issues/issue-32292.rs similarity index 100% rename from src/test/run-pass/issues/issue-32292.rs rename to src/test/ui/issues/issue-32292.rs diff --git a/src/test/ui/issues/issue-32323.stderr b/src/test/ui/issues/issue-32323.stderr index 0339fdc55b..6256dc0c55 100644 --- a/src/test/ui/issues/issue-32323.stderr +++ b/src/test/ui/issues/issue-32323.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | pub fn f<'a, T: Tr<'a>>() -> >::Out {} | - ^^^^^^^^^^^^^^^^^^ expected associated type, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `>::Out` found type `()` diff --git a/src/test/ui/issues/issue-32324.rs b/src/test/ui/issues/issue-32324.rs index 9abbe32160..eaad98d678 100644 --- a/src/test/ui/issues/issue-32324.rs +++ b/src/test/ui/issues/issue-32324.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Resources { diff --git a/src/test/run-pass/issues/issue-32389.rs b/src/test/ui/issues/issue-32389.rs similarity index 100% rename from src/test/run-pass/issues/issue-32389.rs rename to src/test/ui/issues/issue-32389.rs diff --git a/src/test/run-pass/issues/issue-32518.rs b/src/test/ui/issues/issue-32518.rs similarity index 100% rename from src/test/run-pass/issues/issue-32518.rs rename to src/test/ui/issues/issue-32518.rs diff --git a/src/test/ui/issues/issue-32655.rs b/src/test/ui/issues/issue-32655.rs index 4634179d4e..fad7bf55cf 100644 --- a/src/test/ui/issues/issue-32655.rs +++ b/src/test/ui/issues/issue-32655.rs @@ -1,9 +1,6 @@ -#![allow(dead_code)] -#![feature(rustc_attrs)] - macro_rules! foo ( () => ( - #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown + #[derive_Clone] //~ ERROR cannot find attribute macro `derive_Clone` in this scope struct T; ); ); @@ -15,7 +12,7 @@ macro_rules! bar ( foo!(); bar!( - #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown + #[derive_Clone] //~ ERROR cannot find attribute macro `derive_Clone` in this scope struct S; ); diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr index 3ab934f6ca..e13bed0fbf 100644 --- a/src/test/ui/issues/issue-32655.stderr +++ b/src/test/ui/issues/issue-32655.stderr @@ -1,24 +1,17 @@ -error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-32655.rs:6:11 +error: cannot find attribute macro `derive_Clone` in this scope + --> $DIR/issue-32655.rs:3:11 | LL | #[derive_Clone] | ^^^^^^^^^^^^ ... LL | foo!(); | ------- in this macro invocation - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/issue-32655.rs:18:7 +error: cannot find attribute macro `derive_Clone` in this scope + --> $DIR/issue-32655.rs:15:7 | LL | #[derive_Clone] | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-32782.stderr b/src/test/ui/issues/issue-32782.stderr index 886f529715..029826f09a 100644 --- a/src/test/ui/issues/issue-32782.stderr +++ b/src/test/ui/issues/issue-32782.stderr @@ -7,7 +7,7 @@ LL | #[allow_internal_unstable] LL | foo!(); | ------- in this macro invocation | - = help: add #![feature(allow_internal_unstable)] to the crate attributes to enable + = help: add `#![feature(allow_internal_unstable)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-32805.rs b/src/test/ui/issues/issue-32805.rs similarity index 100% rename from src/test/run-pass/issues/issue-32805.rs rename to src/test/ui/issues/issue-32805.rs diff --git a/src/test/ui/issues/issue-32829.stderr b/src/test/ui/issues/issue-32829.stderr index 157c8c85af..b620abbf43 100644 --- a/src/test/ui/issues/issue-32829.stderr +++ b/src/test/ui/issues/issue-32829.stderr @@ -5,7 +5,7 @@ LL | static S : u64 = { { panic!("foo"); 0 } }; | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51999 - = help: add #![feature(const_panic)] to the crate attributes to enable + = help: add `#![feature(const_panic)]` to the crate attributes to enable = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-3290.rs b/src/test/ui/issues/issue-3290.rs similarity index 100% rename from src/test/run-pass/issues/issue-3290.rs rename to src/test/ui/issues/issue-3290.rs diff --git a/src/test/run-pass/issues/issue-32947.rs b/src/test/ui/issues/issue-32947.rs similarity index 100% rename from src/test/run-pass/issues/issue-32947.rs rename to src/test/ui/issues/issue-32947.rs diff --git a/src/test/ui/issues/issue-32995-2.stderr b/src/test/ui/issues/issue-32995-2.stderr index 104b76cba2..4a580b09bf 100644 --- a/src/test/ui/issues/issue-32995-2.stderr +++ b/src/test/ui/issues/issue-32995-2.stderr @@ -4,7 +4,7 @@ error: parenthesized type parameters may only be used with a `Fn` trait LL | { fn f() {} } | ^^ | - = note: #[deny(parenthesized_params_in_types_and_modules)] on by default + = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr index f97d86f652..59d93ece06 100644 --- a/src/test/ui/issues/issue-32995.stderr +++ b/src/test/ui/issues/issue-32995.stderr @@ -4,7 +4,7 @@ error: parenthesized type parameters may only be used with a `Fn` trait LL | let x: usize() = 1; | ^^ | - = note: #[deny(parenthesized_params_in_types_and_modules)] on by default + = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42238 diff --git a/src/test/run-pass/issues/issue-33096.rs b/src/test/ui/issues/issue-33096.rs similarity index 100% rename from src/test/run-pass/issues/issue-33096.rs rename to src/test/ui/issues/issue-33096.rs diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.rs b/src/test/ui/issues/issue-33140-traitobject-crate.rs index 078f3f3dd2..03567b20a8 100644 --- a/src/test/ui/issues/issue-33140-traitobject-crate.rs +++ b/src/test/ui/issues/issue-33140-traitobject-crate.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(order_dependent_trait_objects)] diff --git a/src/test/run-pass/issues/issue-33185.rs b/src/test/ui/issues/issue-33185.rs similarity index 100% rename from src/test/run-pass/issues/issue-33185.rs rename to src/test/ui/issues/issue-33185.rs diff --git a/src/test/run-pass/issues/issue-33187.rs b/src/test/ui/issues/issue-33187.rs similarity index 100% rename from src/test/run-pass/issues/issue-33187.rs rename to src/test/ui/issues/issue-33187.rs diff --git a/src/test/run-pass/issues/issue-33202.rs b/src/test/ui/issues/issue-33202.rs similarity index 100% rename from src/test/run-pass/issues/issue-33202.rs rename to src/test/ui/issues/issue-33202.rs diff --git a/src/test/ui/issues/issue-33264.rs b/src/test/ui/issues/issue-33264.rs index 51608b48be..e6370bc84d 100644 --- a/src/test/ui/issues/issue-33264.rs +++ b/src/test/ui/issues/issue-33264.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // only-x86_64 #![allow(dead_code, non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-33287.rs b/src/test/ui/issues/issue-33287.rs index cc47e58fcd..036a1e3768 100644 --- a/src/test/ui/issues/issue-33287.rs +++ b/src/test/ui/issues/issue-33287.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] const A: [u32; 1] = [0]; diff --git a/src/test/run-pass/issues/issue-333.rs b/src/test/ui/issues/issue-333.rs similarity index 100% rename from src/test/run-pass/issues/issue-333.rs rename to src/test/ui/issues/issue-333.rs diff --git a/src/test/run-pass/issues/issue-33387.rs b/src/test/ui/issues/issue-33387.rs similarity index 100% rename from src/test/run-pass/issues/issue-33387.rs rename to src/test/ui/issues/issue-33387.rs diff --git a/src/test/run-pass/issues/issue-33461.rs b/src/test/ui/issues/issue-33461.rs similarity index 100% rename from src/test/run-pass/issues/issue-33461.rs rename to src/test/ui/issues/issue-33461.rs diff --git a/src/test/ui/issues/issue-33464.stderr b/src/test/ui/issues/issue-33464.stderr index bbf8d21cf6..d3bf404c99 100644 --- a/src/test/ui/issues/issue-33464.stderr +++ b/src/test/ui/issues/issue-33464.stderr @@ -2,19 +2,19 @@ error[E0432]: unresolved import `abc` --> $DIR/issue-33464.rs:3:5 | LL | use abc::one_el; - | ^^^ maybe a missing `extern crate abc;`? + | ^^^ maybe a missing crate `abc`? error[E0432]: unresolved import `abc` --> $DIR/issue-33464.rs:5:5 | LL | use abc::{a, bbb, cccccc}; - | ^^^ maybe a missing `extern crate abc;`? + | ^^^ maybe a missing crate `abc`? error[E0432]: unresolved import `a_very_long_name` --> $DIR/issue-33464.rs:7:5 | LL | use a_very_long_name::{el, el2}; - | ^^^^^^^^^^^^^^^^ maybe a missing `extern crate a_very_long_name;`? + | ^^^^^^^^^^^^^^^^ maybe a missing crate `a_very_long_name`? error: aborting due to 3 previous errors diff --git a/src/test/run-pass/issues/issue-33498.rs b/src/test/ui/issues/issue-33498.rs similarity index 100% rename from src/test/run-pass/issues/issue-33498.rs rename to src/test/ui/issues/issue-33498.rs diff --git a/src/test/run-pass/issues/issue-33537.rs b/src/test/ui/issues/issue-33537.rs similarity index 100% rename from src/test/run-pass/issues/issue-33537.rs rename to src/test/ui/issues/issue-33537.rs diff --git a/src/test/run-pass/issues/issue-33687.rs b/src/test/ui/issues/issue-33687.rs similarity index 100% rename from src/test/run-pass/issues/issue-33687.rs rename to src/test/ui/issues/issue-33687.rs diff --git a/src/test/run-pass/issues/issue-33770.rs b/src/test/ui/issues/issue-33770.rs similarity index 100% rename from src/test/run-pass/issues/issue-33770.rs rename to src/test/ui/issues/issue-33770.rs diff --git a/src/test/run-pass/issues/issue-3389.rs b/src/test/ui/issues/issue-3389.rs similarity index 100% rename from src/test/run-pass/issues/issue-3389.rs rename to src/test/ui/issues/issue-3389.rs diff --git a/src/test/ui/issues/issue-33903.rs b/src/test/ui/issues/issue-33903.rs index 4fdc8dda8b..6a8305dabe 100644 --- a/src/test/ui/issues/issue-33903.rs +++ b/src/test/ui/issues/issue-33903.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Issue 33903: // Built-in indexing should be used even when the index is not diff --git a/src/test/run-pass/issues/issue-33992.rs b/src/test/ui/issues/issue-33992.rs similarity index 100% rename from src/test/run-pass/issues/issue-33992.rs rename to src/test/ui/issues/issue-33992.rs diff --git a/src/test/run-pass/issues/issue-34053.rs b/src/test/ui/issues/issue-34053.rs similarity index 100% rename from src/test/run-pass/issues/issue-34053.rs rename to src/test/ui/issues/issue-34053.rs diff --git a/src/test/run-pass/issues/issue-34074.rs b/src/test/ui/issues/issue-34074.rs similarity index 100% rename from src/test/run-pass/issues/issue-34074.rs rename to src/test/ui/issues/issue-34074.rs diff --git a/src/test/ui/issues/issue-34194.rs b/src/test/ui/issues/issue-34194.rs index b65de91d69..ea89e4cbde 100644 --- a/src/test/ui/issues/issue-34194.rs +++ b/src/test/ui/issues/issue-34194.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A { diff --git a/src/test/ui/issues/issue-3424.rs b/src/test/ui/issues/issue-3424.rs index 19f9f13e14..a8ff03e2a2 100644 --- a/src/test/ui/issues/issue-3424.rs +++ b/src/test/ui/issues/issue-3424.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] // rustc --test ignores2.rs && ./ignores2 diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr index 01f3953777..acb093b514 100644 --- a/src/test/ui/issues/issue-34255-1.stderr +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -2,15 +2,12 @@ error: expected type, found `42` --> $DIR/issue-34255-1.rs:8:24 | LL | Test::Drill(field: 42); - | ^^ expecting a type here because of type ascription + | - ^^ expected type + | | + | tried to parse a type due to this type ascription | - = note: #![feature(type_ascription)] lets you annotate an expression with a type: `: ` -note: this expression expects an ascribed type after the colon - --> $DIR/issue-34255-1.rs:8:17 - | -LL | Test::Drill(field: 42); - | ^^^^^ - = help: this might be indicative of a syntax error elsewhere + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-3429.rs b/src/test/ui/issues/issue-3429.rs similarity index 100% rename from src/test/run-pass/issues/issue-3429.rs rename to src/test/ui/issues/issue-3429.rs diff --git a/src/test/ui/issues/issue-34334.rs b/src/test/ui/issues/issue-34334.rs index 928d217441..4457d71cbb 100644 --- a/src/test/ui/issues/issue-34334.rs +++ b/src/test/ui/issues/issue-34334.rs @@ -5,6 +5,7 @@ fn main () { //~| ERROR mismatched types //~| ERROR invalid left-hand side expression //~| ERROR expected expression, found reserved identifier `_` + //~| ERROR expected expression, found reserved identifier `_` let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); //~^ ERROR no method named `iter` found for type `()` in the current scope } diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index e8386fd8de..7f89caf92a 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -4,6 +4,12 @@ error: expected expression, found reserved identifier `_` LL | let sr: Vec<(u32, _, _) = vec![]; | ^ expected expression +error: expected expression, found reserved identifier `_` + --> $DIR/issue-34334.rs:2:26 + | +LL | let sr: Vec<(u32, _, _) = vec![]; + | ^ expected expression + error: expected one of `,` or `>`, found `=` --> $DIR/issue-34334.rs:2:29 | @@ -36,12 +42,12 @@ LL | let sr: Vec<(u32, _, _) = vec![]; | ^^^^^^^^^^^^^^^^^^^^^^^^ left-hand of expression not valid error[E0599]: no method named `iter` found for type `()` in the current scope - --> $DIR/issue-34334.rs:8:36 + --> $DIR/issue-34334.rs:9:36 | LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); | ^^^^ -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0070, E0308, E0423, E0599. For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/run-pass/issues/issue-34427.rs b/src/test/ui/issues/issue-34427.rs similarity index 100% rename from src/test/run-pass/issues/issue-34427.rs rename to src/test/ui/issues/issue-34427.rs diff --git a/src/test/run-pass/issues/issue-3447.rs b/src/test/ui/issues/issue-3447.rs similarity index 100% rename from src/test/run-pass/issues/issue-3447.rs rename to src/test/ui/issues/issue-3447.rs diff --git a/src/test/run-pass/issues/issue-34503.rs b/src/test/ui/issues/issue-34503.rs similarity index 100% rename from src/test/run-pass/issues/issue-34503.rs rename to src/test/ui/issues/issue-34503.rs diff --git a/src/test/run-pass/issues/issue-34569.rs b/src/test/ui/issues/issue-34569.rs similarity index 100% rename from src/test/run-pass/issues/issue-34569.rs rename to src/test/ui/issues/issue-34569.rs diff --git a/src/test/run-pass/issues/issue-34571.rs b/src/test/ui/issues/issue-34571.rs similarity index 100% rename from src/test/run-pass/issues/issue-34571.rs rename to src/test/ui/issues/issue-34571.rs diff --git a/src/test/ui/issues/issue-34751.rs b/src/test/ui/issues/issue-34751.rs index cca06c573e..a921cb5061 100644 --- a/src/test/ui/issues/issue-34751.rs +++ b/src/test/ui/issues/issue-34751.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)' diff --git a/src/test/ui/issues/issue-34780.rs b/src/test/ui/issues/issue-34780.rs index bfe444e5d3..3202ef6402 100644 --- a/src/test/ui/issues/issue-34780.rs +++ b/src/test/ui/issues/issue-34780.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(stable_features)] #![feature(associated_consts)] diff --git a/src/test/run-pass/issues/issue-34784.rs b/src/test/ui/issues/issue-34784.rs similarity index 100% rename from src/test/run-pass/issues/issue-34784.rs rename to src/test/ui/issues/issue-34784.rs diff --git a/src/test/run-pass/issues/issue-34796.rs b/src/test/ui/issues/issue-34796.rs similarity index 100% rename from src/test/run-pass/issues/issue-34796.rs rename to src/test/ui/issues/issue-34796.rs diff --git a/src/test/run-pass/issues/issue-34798.rs b/src/test/ui/issues/issue-34798.rs similarity index 100% rename from src/test/run-pass/issues/issue-34798.rs rename to src/test/ui/issues/issue-34798.rs diff --git a/src/test/run-pass/issues/issue-34932.rs b/src/test/ui/issues/issue-34932.rs similarity index 100% rename from src/test/run-pass/issues/issue-34932.rs rename to src/test/ui/issues/issue-34932.rs diff --git a/src/test/run-pass/issues/issue-3500.rs b/src/test/ui/issues/issue-3500.rs similarity index 100% rename from src/test/run-pass/issues/issue-3500.rs rename to src/test/ui/issues/issue-3500.rs diff --git a/src/test/ui/issues/issue-35241.stderr b/src/test/ui/issues/issue-35241.stderr index 8fda58abad..586146cbaa 100644 --- a/src/test/ui/issues/issue-35241.stderr +++ b/src/test/ui/issues/issue-35241.stderr @@ -1,11 +1,14 @@ error[E0308]: mismatched types --> $DIR/issue-35241.rs:3:20 | +LL | struct Foo(u32); + | ---------------- fn(u32) -> Foo {Foo} defined here +LL | LL | fn test() -> Foo { Foo } | --- ^^^ | | | | | expected struct `Foo`, found fn item - | | did you mean `Foo(/* fields */)`? + | | help: use parentheses to instantiate this tuple struct: `Foo(_)` | expected `Foo` because of return type | = note: expected type `Foo` diff --git a/src/test/ui/issues/issue-35376.rs b/src/test/ui/issues/issue-35376.rs index 2a80c9f05d..b415d65540 100644 --- a/src/test/ui/issues/issue-35376.rs +++ b/src/test/ui/issues/issue-35376.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(specialization)] fn main() {} diff --git a/src/test/run-pass/issues/issue-35423.rs b/src/test/ui/issues/issue-35423.rs similarity index 100% rename from src/test/run-pass/issues/issue-35423.rs rename to src/test/ui/issues/issue-35423.rs diff --git a/src/test/ui/issues/issue-35546.rs b/src/test/ui/issues/issue-35546.rs index 500ba48e0b..e2f0f98d57 100644 --- a/src/test/ui/issues/issue-35546.rs +++ b/src/test/ui/issues/issue-35546.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #35546. Check that we are able to codegen // this. Before we had problems because of the drop glue signature diff --git a/src/test/run-pass/issues/issue-3556.rs b/src/test/ui/issues/issue-3556.rs similarity index 100% rename from src/test/run-pass/issues/issue-3556.rs rename to src/test/ui/issues/issue-3556.rs diff --git a/src/test/run-pass/issues/issue-3559.rs b/src/test/ui/issues/issue-3559.rs similarity index 100% rename from src/test/run-pass/issues/issue-3559.rs rename to src/test/ui/issues/issue-3559.rs diff --git a/src/test/run-pass/issues/issue-35600.rs b/src/test/ui/issues/issue-35600.rs similarity index 100% rename from src/test/run-pass/issues/issue-35600.rs rename to src/test/ui/issues/issue-35600.rs diff --git a/src/test/ui/issues/issue-3563-2.rs b/src/test/ui/issues/issue-3563-2.rs index 48f7c845d5..5ab668eed1 100644 --- a/src/test/ui/issues/issue-3563-2.rs +++ b/src/test/ui/issues/issue-3563-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Canvas { diff --git a/src/test/run-pass/issues/issue-3563-3.rs b/src/test/ui/issues/issue-3563-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-3563-3.rs rename to src/test/ui/issues/issue-3563-3.rs diff --git a/src/test/run-pass/issues/issue-3574.rs b/src/test/ui/issues/issue-3574.rs similarity index 100% rename from src/test/run-pass/issues/issue-3574.rs rename to src/test/ui/issues/issue-3574.rs diff --git a/src/test/run-pass/issues/issue-35815.rs b/src/test/ui/issues/issue-35815.rs similarity index 100% rename from src/test/run-pass/issues/issue-35815.rs rename to src/test/ui/issues/issue-35815.rs diff --git a/src/test/run-pass/issues/issue-36023.rs b/src/test/ui/issues/issue-36023.rs similarity index 100% rename from src/test/run-pass/issues/issue-36023.rs rename to src/test/ui/issues/issue-36023.rs diff --git a/src/test/run-pass/issues/issue-36036-associated-type-layout.rs b/src/test/ui/issues/issue-36036-associated-type-layout.rs similarity index 100% rename from src/test/run-pass/issues/issue-36036-associated-type-layout.rs rename to src/test/ui/issues/issue-36036-associated-type-layout.rs diff --git a/src/test/run-pass/issues/issue-36053.rs b/src/test/ui/issues/issue-36053.rs similarity index 100% rename from src/test/run-pass/issues/issue-36053.rs rename to src/test/ui/issues/issue-36053.rs diff --git a/src/test/ui/issues/issue-36075.rs b/src/test/ui/issues/issue-36075.rs index c9ca2f7134..00c8cf1fb8 100644 --- a/src/test/ui/issues/issue-36075.rs +++ b/src/test/ui/issues/issue-36075.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait DeclarationParser { type Declaration; diff --git a/src/test/ui/issues/issue-3609.rs b/src/test/ui/issues/issue-3609.rs index 9bccb2a21e..e8fc073a15 100644 --- a/src/test/ui/issues/issue-3609.rs +++ b/src/test/ui/issues/issue-3609.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/src/test/run-pass/issues/issue-36139-normalize-closure-sig.rs b/src/test/ui/issues/issue-36139-normalize-closure-sig.rs similarity index 100% rename from src/test/run-pass/issues/issue-36139-normalize-closure-sig.rs rename to src/test/ui/issues/issue-36139-normalize-closure-sig.rs diff --git a/src/test/run-pass/issues/issue-36260.rs b/src/test/ui/issues/issue-36260.rs similarity index 100% rename from src/test/run-pass/issues/issue-36260.rs rename to src/test/ui/issues/issue-36260.rs diff --git a/src/test/run-pass/issues/issue-36278-prefix-nesting.rs b/src/test/ui/issues/issue-36278-prefix-nesting.rs similarity index 100% rename from src/test/run-pass/issues/issue-36278-prefix-nesting.rs rename to src/test/ui/issues/issue-36278-prefix-nesting.rs diff --git a/src/test/run-pass/issues/issue-36381.rs b/src/test/ui/issues/issue-36381.rs similarity index 100% rename from src/test/run-pass/issues/issue-36381.rs rename to src/test/ui/issues/issue-36381.rs diff --git a/src/test/run-pass/issues/issue-36401.rs b/src/test/ui/issues/issue-36401.rs similarity index 100% rename from src/test/run-pass/issues/issue-36401.rs rename to src/test/ui/issues/issue-36401.rs diff --git a/src/test/run-pass/issues/issue-36474.rs b/src/test/ui/issues/issue-36474.rs similarity index 100% rename from src/test/run-pass/issues/issue-36474.rs rename to src/test/ui/issues/issue-36474.rs diff --git a/src/test/run-pass/issues/issue-3656.rs b/src/test/ui/issues/issue-3656.rs similarity index 86% rename from src/test/run-pass/issues/issue-3656.rs rename to src/test/ui/issues/issue-3656.rs index d55a22a72b..17ff6b9f9f 100644 --- a/src/test/run-pass/issues/issue-3656.rs +++ b/src/test/ui/issues/issue-3656.rs @@ -12,13 +12,13 @@ #![feature(rustc_private)] extern crate libc; -use libc::{c_uint, uint32_t, c_void}; +use libc::{c_uint, c_void}; pub struct KEYGEN { hash_algorithm: [c_uint; 2], - count: uint32_t, + count: u32, salt: *const c_void, - salt_size: uint32_t, + salt_size: u32, } extern { diff --git a/src/test/run-pass/issues/issue-36744-bitcast-args-if-needed.rs b/src/test/ui/issues/issue-36744-bitcast-args-if-needed.rs similarity index 100% rename from src/test/run-pass/issues/issue-36744-bitcast-args-if-needed.rs rename to src/test/ui/issues/issue-36744-bitcast-args-if-needed.rs diff --git a/src/test/ui/issues/issue-36744-without-calls.rs b/src/test/ui/issues/issue-36744-without-calls.rs index 57d63e67f3..4d03d9bbca 100644 --- a/src/test/ui/issues/issue-36744-without-calls.rs +++ b/src/test/ui/issues/issue-36744-without-calls.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests for an LLVM abort when storing a lifetime-parametric fn into // context that is expecting one that is not lifetime-parametric // (i.e., has no `for <'_>`). diff --git a/src/test/run-pass/issues/issue-36768.rs b/src/test/ui/issues/issue-36768.rs similarity index 100% rename from src/test/run-pass/issues/issue-36768.rs rename to src/test/ui/issues/issue-36768.rs diff --git a/src/test/run-pass/issues/issue-36786-resolve-call.rs b/src/test/ui/issues/issue-36786-resolve-call.rs similarity index 100% rename from src/test/run-pass/issues/issue-36786-resolve-call.rs rename to src/test/ui/issues/issue-36786-resolve-call.rs diff --git a/src/test/run-pass/issues/issue-36792.rs b/src/test/ui/issues/issue-36792.rs similarity index 100% rename from src/test/run-pass/issues/issue-36792.rs rename to src/test/ui/issues/issue-36792.rs diff --git a/src/test/run-pass/issues/issue-36816.rs b/src/test/ui/issues/issue-36816.rs similarity index 100% rename from src/test/run-pass/issues/issue-36816.rs rename to src/test/ui/issues/issue-36816.rs diff --git a/src/test/run-pass/issues/issue-3683.rs b/src/test/ui/issues/issue-3683.rs similarity index 100% rename from src/test/run-pass/issues/issue-3683.rs rename to src/test/ui/issues/issue-3683.rs diff --git a/src/test/run-pass/issues/issue-36856.rs b/src/test/ui/issues/issue-36856.rs similarity index 100% rename from src/test/run-pass/issues/issue-36856.rs rename to src/test/ui/issues/issue-36856.rs diff --git a/src/test/ui/issues/issue-36881.rs b/src/test/ui/issues/issue-36881.rs index 2b0508d08e..04313872d2 100644 --- a/src/test/ui/issues/issue-36881.rs +++ b/src/test/ui/issues/issue-36881.rs @@ -1,7 +1,6 @@ // aux-build:issue-36881-aux.rs fn main() { - #[allow(unused_extern_crates)] extern crate issue_36881_aux; use issue_36881_aux::Foo; //~ ERROR unresolved import } diff --git a/src/test/ui/issues/issue-36881.stderr b/src/test/ui/issues/issue-36881.stderr index 2ec636fde6..caf9d5d6d6 100644 --- a/src/test/ui/issues/issue-36881.stderr +++ b/src/test/ui/issues/issue-36881.stderr @@ -1,8 +1,8 @@ error[E0432]: unresolved import `issue_36881_aux` - --> $DIR/issue-36881.rs:6:9 + --> $DIR/issue-36881.rs:5:9 | LL | use issue_36881_aux::Foo; - | ^^^^^^^^^^^^^^^ maybe a missing `extern crate issue_36881_aux;`? + | ^^^^^^^^^^^^^^^ maybe a missing crate `issue_36881_aux`? error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-36936.rs b/src/test/ui/issues/issue-36936.rs similarity index 100% rename from src/test/run-pass/issues/issue-36936.rs rename to src/test/ui/issues/issue-36936.rs diff --git a/src/test/run-pass/issues/issue-36954.rs b/src/test/ui/issues/issue-36954.rs similarity index 100% rename from src/test/run-pass/issues/issue-36954.rs rename to src/test/ui/issues/issue-36954.rs diff --git a/src/test/ui/issues/issue-3702-2.stderr b/src/test/ui/issues/issue-3702-2.stderr index 347a19b687..4d0ff750c2 100644 --- a/src/test/ui/issues/issue-3702-2.stderr +++ b/src/test/ui/issues/issue-3702-2.stderr @@ -9,11 +9,13 @@ note: candidate #1 is defined in an impl of the trait `ToPrimitive` for the type | LL | fn to_int(&self) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `ToPrimitive::to_int(&self)` instead note: candidate #2 is defined in an impl of the trait `Add` for the type `isize` --> $DIR/issue-3702-2.rs:14:5 | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to disambiguate the method call, write `Add::to_int(&self)` instead error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-3702.rs b/src/test/ui/issues/issue-3702.rs similarity index 100% rename from src/test/run-pass/issues/issue-3702.rs rename to src/test/ui/issues/issue-3702.rs diff --git a/src/test/run-pass/issues/issue-37109.rs b/src/test/ui/issues/issue-37109.rs similarity index 100% rename from src/test/run-pass/issues/issue-37109.rs rename to src/test/ui/issues/issue-37109.rs diff --git a/src/test/run-pass/issues/issue-37175.rs b/src/test/ui/issues/issue-37175.rs similarity index 100% rename from src/test/run-pass/issues/issue-37175.rs rename to src/test/ui/issues/issue-37175.rs diff --git a/src/test/run-pass/issues/issue-37222.rs b/src/test/ui/issues/issue-37222.rs similarity index 100% rename from src/test/run-pass/issues/issue-37222.rs rename to src/test/ui/issues/issue-37222.rs diff --git a/src/test/run-pass/issues/issue-37291/auxiliary/lib.rs b/src/test/ui/issues/issue-37291/auxiliary/lib.rs similarity index 100% rename from src/test/run-pass/issues/issue-37291/auxiliary/lib.rs rename to src/test/ui/issues/issue-37291/auxiliary/lib.rs diff --git a/src/test/run-pass/issues/issue-37291/main.rs b/src/test/ui/issues/issue-37291/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-37291/main.rs rename to src/test/ui/issues/issue-37291/main.rs diff --git a/src/test/ui/issues/issue-37323.rs b/src/test/ui/issues/issue-37323.rs index a7cf0cd1bd..61c8029adf 100644 --- a/src/test/ui/issues/issue-37323.rs +++ b/src/test/ui/issues/issue-37323.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(warnings)] diff --git a/src/test/run-pass/issues/issue-3743.rs b/src/test/ui/issues/issue-3743.rs similarity index 100% rename from src/test/run-pass/issues/issue-3743.rs rename to src/test/ui/issues/issue-3743.rs diff --git a/src/test/ui/issues/issue-37433.rs b/src/test/ui/issues/issue-37433.rs new file mode 100644 index 0000000000..d3663e24e6 --- /dev/null +++ b/src/test/ui/issues/issue-37433.rs @@ -0,0 +1,10 @@ +// ignore-emscripten no asm! support + +#![feature(asm)] + +fn main() { + unsafe { + asm!("" :: "r"("")); + //~^ ERROR: invalid value for constraint in inline assembly + } +} diff --git a/src/test/ui/issues/issue-37433.stderr b/src/test/ui/issues/issue-37433.stderr new file mode 100644 index 0000000000..eec0446902 --- /dev/null +++ b/src/test/ui/issues/issue-37433.stderr @@ -0,0 +1,8 @@ +error[E0669]: invalid value for constraint in inline assembly + --> $DIR/issue-37433.rs:7:24 + | +LL | asm!("" :: "r"("")); + | ^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-37515.stderr b/src/test/ui/issues/issue-37515.stderr index 1476d17cdc..f084095969 100644 --- a/src/test/ui/issues/issue-37515.stderr +++ b/src/test/ui/issues/issue-37515.stderr @@ -9,5 +9,5 @@ note: lint level defined here | LL | #![warn(unused)] | ^^^^^^ - = note: #[warn(dead_code)] implied by #[warn(unused)] + = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` diff --git a/src/test/run-pass/issues/issue-3753.rs b/src/test/ui/issues/issue-3753.rs similarity index 100% rename from src/test/run-pass/issues/issue-3753.rs rename to src/test/ui/issues/issue-3753.rs diff --git a/src/test/ui/issues/issue-37534.rs b/src/test/ui/issues/issue-37534.rs index 9386b4516a..1e67e9a815 100644 --- a/src/test/ui/issues/issue-37534.rs +++ b/src/test/ui/issues/issue-37534.rs @@ -1,5 +1,5 @@ struct Foo { } -//~^ ERROR cannot find trait `Hash` in this scope +//~^ ERROR expected trait, found derive macro `Hash` //~^^ ERROR parameter `T` is never used //~^^^ WARN default bound relaxed for a type parameter, but this does nothing diff --git a/src/test/ui/issues/issue-37534.stderr b/src/test/ui/issues/issue-37534.stderr index 741e93561b..3a0ab32dcc 100644 --- a/src/test/ui/issues/issue-37534.stderr +++ b/src/test/ui/issues/issue-37534.stderr @@ -1,9 +1,9 @@ -error[E0405]: cannot find trait `Hash` in this scope +error[E0404]: expected trait, found derive macro `Hash` --> $DIR/issue-37534.rs:1:16 | LL | struct Foo { } - | ^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope + | ^^^^ not a trait +help: possible better candidate is found in another module, you can import it into scope | LL | use std::hash::Hash; | @@ -24,5 +24,5 @@ LL | struct Foo { } error: aborting due to 2 previous errors -Some errors have detailed explanations: E0392, E0405. +Some errors have detailed explanations: E0392, E0404. For more information about an error, try `rustc --explain E0392`. diff --git a/src/test/ui/issues/issue-37550.stderr b/src/test/ui/issues/issue-37550.stderr index 609043942b..c1523e911f 100644 --- a/src/test/ui/issues/issue-37550.stderr +++ b/src/test/ui/issues/issue-37550.stderr @@ -5,7 +5,7 @@ LL | let x = || t; | ^ | = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 - = help: add #![feature(const_fn)] to the crate attributes to enable + = help: add `#![feature(const_fn)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs index 209f797b15..31b3aba6bc 100644 --- a/src/test/ui/issues/issue-37598.rs +++ b/src/test/ui/issues/issue-37598.rs @@ -1,11 +1,10 @@ -// compile-pass -#![allow(dead_code)] +// check-pass #![feature(slice_patterns)] fn check(list: &[u8]) { match list { &[] => {}, - &[_u1, _u2, ref _next..] => {}, + &[_u1, _u2, ref _next @ ..] => {}, &[_u1] => {}, } } diff --git a/src/test/ui/issues/issue-37655.rs b/src/test/ui/issues/issue-37655.rs index bfc6406b92..fecff4e024 100644 --- a/src/test/ui/issues/issue-37655.rs +++ b/src/test/ui/issues/issue-37655.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for #37655. The problem was a false edge created by // coercion that wound up requiring that `'a` (in `split()`) outlive // `'b`, which shouldn't be necessary. diff --git a/src/test/run-pass/issues/issue-37686.rs b/src/test/ui/issues/issue-37686.rs similarity index 100% rename from src/test/run-pass/issues/issue-37686.rs rename to src/test/ui/issues/issue-37686.rs diff --git a/src/test/ui/issues/issue-37725.rs b/src/test/ui/issues/issue-37725.rs index a572781f09..eefdc72f0c 100644 --- a/src/test/ui/issues/issue-37725.rs +++ b/src/test/ui/issues/issue-37725.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Foo { fn foo(&self); diff --git a/src/test/ui/issues/issue-37733.rs b/src/test/ui/issues/issue-37733.rs index 2dcb0cd8ce..c1df28331a 100644 --- a/src/test/ui/issues/issue-37733.rs +++ b/src/test/ui/issues/issue-37733.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] type A = for<> fn(); diff --git a/src/test/ui/issues/issue-37887.stderr b/src/test/ui/issues/issue-37887.stderr index 81ec3a5956..6ef5359f98 100644 --- a/src/test/ui/issues/issue-37887.stderr +++ b/src/test/ui/issues/issue-37887.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `libc` --> $DIR/issue-37887.rs:3:9 | LL | use libc::*; - | ^^^^ maybe a missing `extern crate libc;`? + | ^^^^ maybe a missing crate `libc`? error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? --> $DIR/issue-37887.rs:2:5 @@ -11,7 +11,7 @@ LL | extern crate libc; | ^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/27812 - = help: add #![feature(rustc_private)] to the crate attributes to enable + = help: add `#![feature(rustc_private)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/run-pass/issues/issue-3794.rs b/src/test/ui/issues/issue-3794.rs similarity index 100% rename from src/test/run-pass/issues/issue-3794.rs rename to src/test/ui/issues/issue-3794.rs diff --git a/src/test/run-pass/issues/issue-37991.rs b/src/test/ui/issues/issue-37991.rs similarity index 100% rename from src/test/run-pass/issues/issue-37991.rs rename to src/test/ui/issues/issue-37991.rs diff --git a/src/test/run-pass/issues/issue-38002.rs b/src/test/ui/issues/issue-38002.rs similarity index 100% rename from src/test/run-pass/issues/issue-38002.rs rename to src/test/ui/issues/issue-38002.rs diff --git a/src/test/run-pass/issues/issue-38033.rs b/src/test/ui/issues/issue-38033.rs similarity index 100% rename from src/test/run-pass/issues/issue-38033.rs rename to src/test/ui/issues/issue-38033.rs diff --git a/src/test/run-pass/issues/issue-38074.rs b/src/test/ui/issues/issue-38074.rs similarity index 100% rename from src/test/run-pass/issues/issue-38074.rs rename to src/test/ui/issues/issue-38074.rs diff --git a/src/test/run-pass/issues/issue-38091.rs b/src/test/ui/issues/issue-38091.rs similarity index 100% rename from src/test/run-pass/issues/issue-38091.rs rename to src/test/ui/issues/issue-38091.rs diff --git a/src/test/run-pass/issues/issue-38190.rs b/src/test/ui/issues/issue-38190.rs similarity index 100% rename from src/test/run-pass/issues/issue-38190.rs rename to src/test/ui/issues/issue-38190.rs diff --git a/src/test/run-pass/issues/issue-38226.rs b/src/test/ui/issues/issue-38226.rs similarity index 100% rename from src/test/run-pass/issues/issue-38226.rs rename to src/test/ui/issues/issue-38226.rs diff --git a/src/test/run-pass/issues/issue-38437.rs b/src/test/ui/issues/issue-38437.rs similarity index 100% rename from src/test/run-pass/issues/issue-38437.rs rename to src/test/ui/issues/issue-38437.rs diff --git a/src/test/run-pass/issues/issue-3847.rs b/src/test/ui/issues/issue-3847.rs similarity index 100% rename from src/test/run-pass/issues/issue-3847.rs rename to src/test/ui/issues/issue-3847.rs diff --git a/src/test/run-pass/issues/issue-38556.rs b/src/test/ui/issues/issue-38556.rs similarity index 100% rename from src/test/run-pass/issues/issue-38556.rs rename to src/test/ui/issues/issue-38556.rs diff --git a/src/test/run-pass/issues/issue-38715.rs b/src/test/ui/issues/issue-38715-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-38715.rs rename to src/test/ui/issues/issue-38715-rpass.rs diff --git a/src/test/ui/issues/issue-38715.stderr b/src/test/ui/issues/issue-38715.stderr index 34e08bfc93..02b96d2d24 100644 --- a/src/test/ui/issues/issue-38715.stderr +++ b/src/test/ui/issues/issue-38715.stderr @@ -4,7 +4,7 @@ error: a macro named `foo` has already been exported LL | macro_rules! foo { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` already exported | - = note: #[deny(duplicate_macro_exports)] on by default + = note: `#[deny(duplicate_macro_exports)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #35896 note: previous macro export is now shadowed diff --git a/src/test/ui/issues/issue-38727.rs b/src/test/ui/issues/issue-38727.rs index d9f32637a9..3c728e9def 100644 --- a/src/test/ui/issues/issue-38727.rs +++ b/src/test/ui/issues/issue-38727.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[repr(u64)] enum A { diff --git a/src/test/ui/issues/issue-3874.rs b/src/test/ui/issues/issue-3874.rs index 8a7eaf2953..b290da5208 100644 --- a/src/test/ui/issues/issue-3874.rs +++ b/src/test/ui/issues/issue-3874.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-38763.rs b/src/test/ui/issues/issue-38763.rs similarity index 100% rename from src/test/run-pass/issues/issue-38763.rs rename to src/test/ui/issues/issue-38763.rs diff --git a/src/test/run-pass/issues/issue-3878.rs b/src/test/ui/issues/issue-3878.rs similarity index 100% rename from src/test/run-pass/issues/issue-3878.rs rename to src/test/ui/issues/issue-3878.rs diff --git a/src/test/ui/issues/issue-38875/issue-38875.rs b/src/test/ui/issues/issue-38875/issue-38875.rs index df321b8dcb..68981eaf2b 100644 --- a/src/test/ui/issues/issue-38875/issue-38875.rs +++ b/src/test/ui/issues/issue-38875/issue-38875.rs @@ -1,5 +1,5 @@ // aux-build:issue-38875-b.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate issue_38875_b; diff --git a/src/test/ui/issues/issue-3888-2.rs b/src/test/ui/issues/issue-3888-2.rs index 27d05b470b..3d4b184ab6 100644 --- a/src/test/ui/issues/issue-3888-2.rs +++ b/src/test/ui/issues/issue-3888-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-38942.rs b/src/test/ui/issues/issue-38942.rs similarity index 100% rename from src/test/run-pass/issues/issue-38942.rs rename to src/test/ui/issues/issue-38942.rs diff --git a/src/test/run-pass/issues/issue-3895.rs b/src/test/ui/issues/issue-3895.rs similarity index 100% rename from src/test/run-pass/issues/issue-3895.rs rename to src/test/ui/issues/issue-3895.rs diff --git a/src/test/run-pass/issues/issue-38987.rs b/src/test/ui/issues/issue-38987.rs similarity index 100% rename from src/test/run-pass/issues/issue-38987.rs rename to src/test/ui/issues/issue-38987.rs diff --git a/src/test/run-pass/issues/issue-3904.rs b/src/test/ui/issues/issue-3904.rs similarity index 100% rename from src/test/run-pass/issues/issue-3904.rs rename to src/test/ui/issues/issue-3904.rs diff --git a/src/test/ui/issues/issue-39089.rs b/src/test/ui/issues/issue-39089.rs index 77be9d2c76..12ca9e1da0 100644 --- a/src/test/ui/issues/issue-39089.rs +++ b/src/test/ui/issues/issue-39089.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] fn f Sized>() {} diff --git a/src/test/run-pass/issues/issue-39292.rs b/src/test/ui/issues/issue-39292.rs similarity index 100% rename from src/test/run-pass/issues/issue-39292.rs rename to src/test/ui/issues/issue-39292.rs diff --git a/src/test/run-pass/issues/issue-3935.rs b/src/test/ui/issues/issue-3935.rs similarity index 100% rename from src/test/run-pass/issues/issue-3935.rs rename to src/test/ui/issues/issue-3935.rs diff --git a/src/test/run-pass/issues/issue-39367.rs b/src/test/ui/issues/issue-39367.rs similarity index 100% rename from src/test/run-pass/issues/issue-39367.rs rename to src/test/ui/issues/issue-39367.rs diff --git a/src/test/ui/issues/issue-39404.stderr b/src/test/ui/issues/issue-39404.stderr index bffea49362..d2f2a823c2 100644 --- a/src/test/ui/issues/issue-39404.stderr +++ b/src/test/ui/issues/issue-39404.stderr @@ -4,7 +4,7 @@ error: missing fragment specifier LL | macro_rules! m { ($i) => {} } | ^^ | - = note: #[deny(missing_fragment_specifier)] on by default + = note: `#[deny(missing_fragment_specifier)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 diff --git a/src/test/ui/issues/issue-39467.rs b/src/test/ui/issues/issue-39467.rs index 077e5cefd5..86e6756000 100644 --- a/src/test/ui/issues/issue-39467.rs +++ b/src/test/ui/issues/issue-39467.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] macro_rules! expr { () => { () } } diff --git a/src/test/run-pass/issues/issue-39548.rs b/src/test/ui/issues/issue-39548.rs similarity index 100% rename from src/test/run-pass/issues/issue-39548.rs rename to src/test/ui/issues/issue-39548.rs diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr index aded0c2de4..b945b5e665 100644 --- a/src/test/ui/issues/issue-39559.stderr +++ b/src/test/ui/issues/issue-39559.stderr @@ -4,9 +4,11 @@ error[E0599]: no function or associated item named `dim` found for type `D` in t LL | entries: [T; D::dim()], | ^^^ function or associated item not found in `D` | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `dim`, perhaps you need to implement it: - candidate #1: `Dim` + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `dim`, perhaps you need to restrict type parameter `D` with it: + | +LL | pub struct Vector { + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-39616.stderr b/src/test/ui/issues/issue-39616.stderr index e24ffcdb0d..75eb55fa50 100644 --- a/src/test/ui/issues/issue-39616.stderr +++ b/src/test/ui/issues/issue-39616.stderr @@ -2,7 +2,7 @@ error: expected type, found `0` --> $DIR/issue-39616.rs:1:12 | LL | fn foo(a: [0; 1]) {} - | ^ + | ^ expected type error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]` --> $DIR/issue-39616.rs:1:16 diff --git a/src/test/run-pass/issues/issue-39709.rs b/src/test/ui/issues/issue-39709.rs similarity index 100% rename from src/test/run-pass/issues/issue-39709.rs rename to src/test/ui/issues/issue-39709.rs diff --git a/src/test/run-pass/issues/issue-39720.rs b/src/test/ui/issues/issue-39720.rs similarity index 100% rename from src/test/run-pass/issues/issue-39720.rs rename to src/test/ui/issues/issue-39720.rs diff --git a/src/test/run-pass/issues/issue-39720.stderr b/src/test/ui/issues/issue-39720.stderr similarity index 100% rename from src/test/run-pass/issues/issue-39720.stderr rename to src/test/ui/issues/issue-39720.stderr diff --git a/src/test/ui/issues/issue-3979-2.rs b/src/test/ui/issues/issue-3979-2.rs index eec8c85f27..f3fcfd2c8f 100644 --- a/src/test/ui/issues/issue-3979-2.rs +++ b/src/test/ui/issues/issue-3979-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait A { diff --git a/src/test/run-pass/issues/issue-3979-generics.rs b/src/test/ui/issues/issue-3979-generics.rs similarity index 100% rename from src/test/run-pass/issues/issue-3979-generics.rs rename to src/test/ui/issues/issue-3979-generics.rs diff --git a/src/test/run-pass/issues/issue-3979-xcrate.rs b/src/test/ui/issues/issue-3979-xcrate.rs similarity index 100% rename from src/test/run-pass/issues/issue-3979-xcrate.rs rename to src/test/ui/issues/issue-3979-xcrate.rs diff --git a/src/test/run-pass/issues/issue-3979.rs b/src/test/ui/issues/issue-3979.rs similarity index 100% rename from src/test/run-pass/issues/issue-3979.rs rename to src/test/ui/issues/issue-3979.rs diff --git a/src/test/run-pass/issues/issue-39808.rs b/src/test/ui/issues/issue-39808.rs similarity index 100% rename from src/test/run-pass/issues/issue-39808.rs rename to src/test/ui/issues/issue-39808.rs diff --git a/src/test/run-pass/issues/issue-39823.rs b/src/test/ui/issues/issue-39823.rs similarity index 100% rename from src/test/run-pass/issues/issue-39823.rs rename to src/test/ui/issues/issue-39823.rs diff --git a/src/test/run-pass/issues/issue-39827.rs b/src/test/ui/issues/issue-39827.rs similarity index 100% rename from src/test/run-pass/issues/issue-39827.rs rename to src/test/ui/issues/issue-39827.rs diff --git a/src/test/ui/issues/issue-39848.stderr b/src/test/ui/issues/issue-39848.stderr index 6eda03c1a0..fa87967432 100644 --- a/src/test/ui/issues/issue-39848.stderr +++ b/src/test/ui/issues/issue-39848.stderr @@ -2,7 +2,7 @@ error: expected `{`, found `foo` --> $DIR/issue-39848.rs:8:19 | LL | if $tgt.has_$field() {} - | -- - help: try placing this code inside a block: `{ foo(); }` + | -- - help: try placing this code inside a block: `{ ) }` | | | this `if` statement has a condition, but no block ... diff --git a/src/test/ui/issues/issue-3991.rs b/src/test/ui/issues/issue-3991.rs index bc63aae0b9..b8ff671bf3 100644 --- a/src/test/ui/issues/issue-3991.rs +++ b/src/test/ui/issues/issue-3991.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-39984.rs b/src/test/ui/issues/issue-39984.rs index 5018b1c62c..613aad1a34 100644 --- a/src/test/ui/issues/issue-39984.rs +++ b/src/test/ui/issues/issue-39984.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unreachable_code)] // Regression test for issue #39984. diff --git a/src/test/run-pass/issues/issue-40003.rs b/src/test/ui/issues/issue-40003.rs similarity index 100% rename from src/test/run-pass/issues/issue-40003.rs rename to src/test/ui/issues/issue-40003.rs diff --git a/src/test/run-pass/issues/issue-40085.rs b/src/test/ui/issues/issue-40085.rs similarity index 100% rename from src/test/run-pass/issues/issue-40085.rs rename to src/test/ui/issues/issue-40085.rs diff --git a/src/test/ui/issues/issue-40136.rs b/src/test/ui/issues/issue-40136.rs index 0849f54374..412ddafdd9 100644 --- a/src/test/ui/issues/issue-40136.rs +++ b/src/test/ui/issues/issue-40136.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] macro_rules! m { () => { 0 } } diff --git a/src/test/run-pass/issues/issue-40235.rs b/src/test/ui/issues/issue-40235.rs similarity index 100% rename from src/test/run-pass/issues/issue-40235.rs rename to src/test/ui/issues/issue-40235.rs diff --git a/src/test/ui/issues/issue-4025.rs b/src/test/ui/issues/issue-4025.rs index fc036f3edd..6e009ba6eb 100644 --- a/src/test/ui/issues/issue-4025.rs +++ b/src/test/ui/issues/issue-4025.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_mut)] /* diff --git a/src/test/run-pass/issues/issue-40408.rs b/src/test/ui/issues/issue-40408.rs similarity index 100% rename from src/test/run-pass/issues/issue-40408.rs rename to src/test/ui/issues/issue-40408.rs diff --git a/src/test/run-pass/issues/issue-40469.rs b/src/test/ui/issues/issue-40469.rs similarity index 100% rename from src/test/run-pass/issues/issue-40469.rs rename to src/test/ui/issues/issue-40469.rs diff --git a/src/test/ui/issues/issue-40510-2.rs b/src/test/ui/issues/issue-40510-2.rs index 2304badd17..499fa8a04f 100644 --- a/src/test/ui/issues/issue-40510-2.rs +++ b/src/test/ui/issues/issue-40510-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] fn f() { diff --git a/src/test/ui/issues/issue-40510-4.rs b/src/test/ui/issues/issue-40510-4.rs index 45cd4fd94e..5fad7e4a62 100644 --- a/src/test/ui/issues/issue-40510-4.rs +++ b/src/test/ui/issues/issue-40510-4.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] fn f() { diff --git a/src/test/run-pass/issues/issue-40770.rs b/src/test/ui/issues/issue-40770.rs similarity index 100% rename from src/test/run-pass/issues/issue-40770.rs rename to src/test/ui/issues/issue-40770.rs diff --git a/src/test/run-pass/issues/issue-40847.rs b/src/test/ui/issues/issue-40847.rs similarity index 100% rename from src/test/run-pass/issues/issue-40847.rs rename to src/test/ui/issues/issue-40847.rs diff --git a/src/test/run-pass/issues/issue-40883.rs b/src/test/ui/issues/issue-40883.rs similarity index 100% rename from src/test/run-pass/issues/issue-40883.rs rename to src/test/ui/issues/issue-40883.rs diff --git a/src/test/run-pass/issues/issue-40951.rs b/src/test/ui/issues/issue-40951.rs similarity index 100% rename from src/test/run-pass/issues/issue-40951.rs rename to src/test/ui/issues/issue-40951.rs diff --git a/src/test/ui/issues/issue-40962.rs b/src/test/ui/issues/issue-40962.rs index 50d9276e79..c051133cbe 100644 --- a/src/test/ui/issues/issue-40962.rs +++ b/src/test/ui/issues/issue-40962.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! m { ($i:meta) => { #[derive($i)] diff --git a/src/test/run-pass/issues/issue-41053.rs b/src/test/ui/issues/issue-41053.rs similarity index 100% rename from src/test/run-pass/issues/issue-41053.rs rename to src/test/ui/issues/issue-41053.rs diff --git a/src/test/run-pass/issues/issue-4107.rs b/src/test/ui/issues/issue-4107.rs similarity index 100% rename from src/test/run-pass/issues/issue-4107.rs rename to src/test/ui/issues/issue-4107.rs diff --git a/src/test/run-pass/issues/issue-41213.rs b/src/test/ui/issues/issue-41213.rs similarity index 100% rename from src/test/run-pass/issues/issue-41213.rs rename to src/test/ui/issues/issue-41213.rs diff --git a/src/test/ui/issues/issue-41272.rs b/src/test/ui/issues/issue-41272.rs index 4a43e11f47..9cd2003628 100644 --- a/src/test/ui/issues/issue-41272.rs +++ b/src/test/ui/issues/issue-41272.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo; diff --git a/src/test/ui/issues/issue-41298.rs b/src/test/ui/issues/issue-41298.rs index e8eeabaf3a..c719664de0 100644 --- a/src/test/ui/issues/issue-41298.rs +++ b/src/test/ui/issues/issue-41298.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Function { t: T, f: F } diff --git a/src/test/run-pass/issues/issue-41394.rs b/src/test/ui/issues/issue-41394-rpass.rs similarity index 100% rename from src/test/run-pass/issues/issue-41394.rs rename to src/test/ui/issues/issue-41394-rpass.rs diff --git a/src/test/run-pass/issues/issue-41479.rs b/src/test/ui/issues/issue-41479.rs similarity index 100% rename from src/test/run-pass/issues/issue-41479.rs rename to src/test/ui/issues/issue-41479.rs diff --git a/src/test/run-pass/issues/issue-41498.rs b/src/test/ui/issues/issue-41498.rs similarity index 100% rename from src/test/run-pass/issues/issue-41498.rs rename to src/test/ui/issues/issue-41498.rs diff --git a/src/test/run-pass/issues/issue-41604.rs b/src/test/ui/issues/issue-41604.rs similarity index 100% rename from src/test/run-pass/issues/issue-41604.rs rename to src/test/ui/issues/issue-41604.rs diff --git a/src/test/ui/issues/issue-41628.rs b/src/test/ui/issues/issue-41628.rs index b837a1e234..92369fdcd4 100644 --- a/src/test/ui/issues/issue-41628.rs +++ b/src/test/ui/issues/issue-41628.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(dead_code)] #[used] diff --git a/src/test/run-pass/issues/issue-41677.rs b/src/test/ui/issues/issue-41677.rs similarity index 100% rename from src/test/run-pass/issues/issue-41677.rs rename to src/test/ui/issues/issue-41677.rs diff --git a/src/test/run-pass/issues/issue-41696.rs b/src/test/ui/issues/issue-41696.rs similarity index 100% rename from src/test/run-pass/issues/issue-41696.rs rename to src/test/ui/issues/issue-41696.rs diff --git a/src/test/ui/issues/issue-41726.rs b/src/test/ui/issues/issue-41726.rs index ed05629389..39631912c0 100644 --- a/src/test/ui/issues/issue-41726.rs +++ b/src/test/ui/issues/issue-41726.rs @@ -2,6 +2,6 @@ use std::collections::HashMap; fn main() { let things: HashMap> = HashMap::new(); for src in things.keys() { - things[src.as_str()].sort(); //~ ERROR cannot borrow data in a `&` reference as mutable + things[src.as_str()].sort(); //~ ERROR cannot borrow data in an index of } } diff --git a/src/test/ui/issues/issue-41726.stderr b/src/test/ui/issues/issue-41726.stderr index c92753d6e3..aa7f23511d 100644 --- a/src/test/ui/issues/issue-41726.stderr +++ b/src/test/ui/issues/issue-41726.stderr @@ -1,4 +1,4 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable +error[E0596]: cannot borrow data in an index of `std::collections::HashMap>` as mutable --> $DIR/issue-41726.rs:5:9 | LL | things[src.as_str()].sort(); diff --git a/src/test/run-pass/issues/issue-41744.rs b/src/test/ui/issues/issue-41744.rs similarity index 100% rename from src/test/run-pass/issues/issue-41744.rs rename to src/test/ui/issues/issue-41744.rs diff --git a/src/test/run-pass/issues/issue-41803.rs b/src/test/ui/issues/issue-41803.rs similarity index 100% rename from src/test/run-pass/issues/issue-41803.rs rename to src/test/ui/issues/issue-41803.rs diff --git a/src/test/run-pass/issues/issue-41849-variance-req.rs b/src/test/ui/issues/issue-41849-variance-req.rs similarity index 100% rename from src/test/run-pass/issues/issue-41849-variance-req.rs rename to src/test/ui/issues/issue-41849-variance-req.rs diff --git a/src/test/run-pass/issues/issue-41888.rs b/src/test/ui/issues/issue-41888.rs similarity index 100% rename from src/test/run-pass/issues/issue-41888.rs rename to src/test/ui/issues/issue-41888.rs diff --git a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs index 4dddc484d3..6c6cec25a9 100644 --- a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs +++ b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #41936. The coerce-unsized trait check in // coherence was using subtyping, which triggered variance diff --git a/src/test/ui/issues/issue-41998.rs b/src/test/ui/issues/issue-41998.rs index e54bc201c1..2f2842598f 100644 --- a/src/test/ui/issues/issue-41998.rs +++ b/src/test/ui/issues/issue-41998.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { diff --git a/src/test/run-pass/issues/issue-42007.rs b/src/test/ui/issues/issue-42007.rs similarity index 100% rename from src/test/run-pass/issues/issue-42007.rs rename to src/test/ui/issues/issue-42007.rs diff --git a/src/test/run-pass/issues/issue-4208.rs b/src/test/ui/issues/issue-4208.rs similarity index 100% rename from src/test/run-pass/issues/issue-4208.rs rename to src/test/ui/issues/issue-4208.rs diff --git a/src/test/run-pass/issues/issue-42148.rs b/src/test/ui/issues/issue-42148.rs similarity index 100% rename from src/test/run-pass/issues/issue-42148.rs rename to src/test/ui/issues/issue-42148.rs diff --git a/src/test/run-pass/issues/issue-42210.rs b/src/test/ui/issues/issue-42210.rs similarity index 100% rename from src/test/run-pass/issues/issue-42210.rs rename to src/test/ui/issues/issue-42210.rs diff --git a/src/test/run-pass/issues/issue-4228.rs b/src/test/ui/issues/issue-4228.rs similarity index 100% rename from src/test/run-pass/issues/issue-4228.rs rename to src/test/ui/issues/issue-4228.rs diff --git a/src/test/run-pass/issues/issue-42453.rs b/src/test/ui/issues/issue-42453.rs similarity index 100% rename from src/test/run-pass/issues/issue-42453.rs rename to src/test/ui/issues/issue-42453.rs diff --git a/src/test/run-pass/issues/issue-42463.rs b/src/test/ui/issues/issue-42463.rs similarity index 100% rename from src/test/run-pass/issues/issue-42463.rs rename to src/test/ui/issues/issue-42463.rs diff --git a/src/test/ui/issues/issue-42467.rs b/src/test/ui/issues/issue-42467.rs index 9ad515bdf5..f1a55169ff 100644 --- a/src/test/ui/issues/issue-42467.rs +++ b/src/test/ui/issues/issue-42467.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo(T); diff --git a/src/test/run-pass/issues/issue-4252.rs b/src/test/ui/issues/issue-4252.rs similarity index 100% rename from src/test/run-pass/issues/issue-4252.rs rename to src/test/ui/issues/issue-4252.rs diff --git a/src/test/run-pass/issues/issue-42552.rs b/src/test/ui/issues/issue-42552.rs similarity index 100% rename from src/test/run-pass/issues/issue-42552.rs rename to src/test/ui/issues/issue-42552.rs diff --git a/src/test/run-pass/issues/issue-42679.rs b/src/test/ui/issues/issue-42679.rs similarity index 100% rename from src/test/run-pass/issues/issue-42679.rs rename to src/test/ui/issues/issue-42679.rs diff --git a/src/test/run-pass/issues/issue-42747.rs b/src/test/ui/issues/issue-42747.rs similarity index 100% rename from src/test/run-pass/issues/issue-42747.rs rename to src/test/ui/issues/issue-42747.rs diff --git a/src/test/ui/issues/issue-42956.rs b/src/test/ui/issues/issue-42956.rs index 34cb04657e..8cf0ae0030 100644 --- a/src/test/ui/issues/issue-42956.rs +++ b/src/test/ui/issues/issue-42956.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(stable_features)] #![feature(associated_consts)] diff --git a/src/test/ui/issues/issue-43057.rs b/src/test/ui/issues/issue-43057.rs index 3ed64bba90..7e1d5036f3 100644 --- a/src/test/ui/issues/issue-43057.rs +++ b/src/test/ui/issues/issue-43057.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] macro_rules! column { diff --git a/src/test/ui/issues/issue-43105.stderr b/src/test/ui/issues/issue-43105.stderr index 378fbe6d5c..e3609c57dc 100644 --- a/src/test/ui/issues/issue-43105.stderr +++ b/src/test/ui/issues/issue-43105.stderr @@ -12,7 +12,7 @@ LL | const NUM: u8 = xyz(); | | | calling non-const function `xyz` | - = note: #[deny(const_err)] on by default + = note: `#[deny(const_err)]` on by default error: could not evaluate constant pattern --> $DIR/issue-43105.rs:9:9 diff --git a/src/test/run-pass/issues/issue-43132.rs b/src/test/ui/issues/issue-43132.rs similarity index 100% rename from src/test/run-pass/issues/issue-43132.rs rename to src/test/ui/issues/issue-43132.rs diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index cd11959ede..6d3e8b5ba2 100644 --- a/src/test/ui/issues/issue-43162.stderr +++ b/src/test/ui/issues/issue-43162.stderr @@ -16,7 +16,7 @@ error[E0308]: mismatched types LL | fn foo() -> bool { | --- ^^^^ expected bool, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression LL | LL | break true; | - help: consider removing this semicolon diff --git a/src/test/run-pass/issues/issue-43205.rs b/src/test/ui/issues/issue-43205.rs similarity index 100% rename from src/test/run-pass/issues/issue-43205.rs rename to src/test/ui/issues/issue-43205.rs diff --git a/src/test/run-pass/issues/issue-43291.rs b/src/test/ui/issues/issue-43291.rs similarity index 100% rename from src/test/run-pass/issues/issue-43291.rs rename to src/test/ui/issues/issue-43291.rs diff --git a/src/test/run-pass/issues/issue-4333.rs b/src/test/ui/issues/issue-4333.rs similarity index 100% rename from src/test/run-pass/issues/issue-4333.rs rename to src/test/ui/issues/issue-4333.rs diff --git a/src/test/ui/issues/issue-43357.rs b/src/test/ui/issues/issue-43357.rs index 6b8e7de850..3090e229b6 100644 --- a/src/test/ui/issues/issue-43357.rs +++ b/src/test/ui/issues/issue-43357.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Trait { type Output; diff --git a/src/test/ui/issues/issue-43398.rs b/src/test/ui/issues/issue-43398.rs new file mode 100644 index 0000000000..ae52e8f3f6 --- /dev/null +++ b/src/test/ui/issues/issue-43398.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(repr128)] + +#[repr(i128)] +enum Big { A, B } + +fn main() { + unsafe { + println!("{} {:?}", + std::intrinsics::discriminant_value(&Big::A), + std::mem::discriminant(&Big::B)); + } +} diff --git a/src/test/ui/issues/issue-43483.rs b/src/test/ui/issues/issue-43483.rs index a123ae4849..f071d110f3 100644 --- a/src/test/ui/issues/issue-43483.rs +++ b/src/test/ui/issues/issue-43483.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] trait VecN { diff --git a/src/test/ui/issues/issue-43623.rs b/src/test/ui/issues/issue-43623.rs new file mode 100644 index 0000000000..b259e9e269 --- /dev/null +++ b/src/test/ui/issues/issue-43623.rs @@ -0,0 +1,19 @@ +pub trait Trait<'a> { + type Assoc; +} + +pub struct Type; + +impl<'a> Trait<'a> for Type { + type Assoc = (); +} + +pub fn break_me(f: F) +where T: for<'b> Trait<'b>, + F: for<'b> FnMut(>::Assoc) { + break_me::; + //~^ ERROR: type mismatch in function arguments + //~| ERROR: type mismatch resolving +} + +fn main() {} diff --git a/src/test/ui/issues/issue-43623.stderr b/src/test/ui/issues/issue-43623.stderr new file mode 100644 index 0000000000..b5674105f7 --- /dev/null +++ b/src/test/ui/issues/issue-43623.stderr @@ -0,0 +1,42 @@ +error[E0631]: type mismatch in function arguments + --> $DIR/issue-43623.rs:14:5 + | +LL | break_me::; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected signature of `for<'b> fn(>::Assoc) -> _` + | found signature of `fn(_) -> _` + | +note: required by `break_me` + --> $DIR/issue-43623.rs:11:1 + | +LL | / pub fn break_me(f: F) +LL | | where T: for<'b> Trait<'b>, +LL | | F: for<'b> FnMut(>::Assoc) { +LL | | break_me::; +LL | | +LL | | +LL | | } + | |_^ + +error[E0271]: type mismatch resolving `for<'b> >::Assoc,)>>::Output == ()` + --> $DIR/issue-43623.rs:14:5 + | +LL | break_me::; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime + | +note: required by `break_me` + --> $DIR/issue-43623.rs:11:1 + | +LL | / pub fn break_me(f: F) +LL | | where T: for<'b> Trait<'b>, +LL | | F: for<'b> FnMut(>::Assoc) { +LL | | break_me::; +LL | | +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/run-pass/issues/issue-43692.rs b/src/test/ui/issues/issue-43692.rs similarity index 100% rename from src/test/run-pass/issues/issue-43692.rs rename to src/test/ui/issues/issue-43692.rs diff --git a/src/test/run-pass/issues/issue-43853.rs b/src/test/ui/issues/issue-43853.rs similarity index 100% rename from src/test/run-pass/issues/issue-43853.rs rename to src/test/ui/issues/issue-43853.rs diff --git a/src/test/run-pass/issues/issue-4387.rs b/src/test/ui/issues/issue-4387.rs similarity index 100% rename from src/test/run-pass/issues/issue-4387.rs rename to src/test/ui/issues/issue-4387.rs diff --git a/src/test/run-pass/issues/issue-43910.rs b/src/test/ui/issues/issue-43910.rs similarity index 100% rename from src/test/run-pass/issues/issue-43910.rs rename to src/test/ui/issues/issue-43910.rs diff --git a/src/test/run-pass/issues/issue-43923.rs b/src/test/ui/issues/issue-43923.rs similarity index 100% rename from src/test/run-pass/issues/issue-43923.rs rename to src/test/ui/issues/issue-43923.rs diff --git a/src/test/ui/issues/issue-44005.rs b/src/test/ui/issues/issue-44005.rs index f6d1b7073a..f6fe9fcbd8 100644 --- a/src/test/ui/issues/issue-44005.rs +++ b/src/test/ui/issues/issue-44005.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Foo<'a> { type Bar; fn foo(&'a self) -> Self::Bar; diff --git a/src/test/run-pass/issues/issue-4401.rs b/src/test/ui/issues/issue-4401.rs similarity index 100% rename from src/test/run-pass/issues/issue-4401.rs rename to src/test/ui/issues/issue-4401.rs diff --git a/src/test/ui/issues/issue-44023.stderr b/src/test/ui/issues/issue-44023.stderr index 153be363c1..258ffe558e 100644 --- a/src/test/ui/issues/issue-44023.stderr +++ b/src/test/ui/issues/issue-44023.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { | ------------------------ ^^^^^ expected isize, found () | | - | this function's body doesn't return + | implicitly returns `()` as its body has no tail or `return` expression | = note: expected type `isize` found type `()` diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs index 8ed371485c..42f30bf302 100644 --- a/src/test/ui/issues/issue-44056.rs +++ b/src/test/ui/issues/issue-44056.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // only-x86_64 // no-prefer-dynamic // compile-flags: -Ctarget-feature=+avx -Clto diff --git a/src/test/ui/issues/issue-44247.rs b/src/test/ui/issues/issue-44247.rs index b45d541f21..ef244e0385 100644 --- a/src/test/ui/issues/issue-44247.rs +++ b/src/test/ui/issues/issue-44247.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait T { type X; diff --git a/src/test/run-pass/issues/issue-44333.rs b/src/test/ui/issues/issue-44333.rs similarity index 100% rename from src/test/run-pass/issues/issue-44333.rs rename to src/test/ui/issues/issue-44333.rs diff --git a/src/test/ui/issues/issue-44373-2.rs b/src/test/ui/issues/issue-44373-2.rs index 18b2ce8512..7fdc4b1ee5 100644 --- a/src/test/ui/issues/issue-44373-2.rs +++ b/src/test/ui/issues/issue-44373-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo(bool); diff --git a/src/test/ui/issues/issue-44402.rs b/src/test/ui/issues/issue-44402.rs index 7a2eaac1fd..29b7eb5ee4 100644 --- a/src/test/ui/issues/issue-44402.rs +++ b/src/test/ui/issues/issue-44402.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![feature(never_type)] #![feature(exhaustive_patterns)] diff --git a/src/test/ui/issues/issue-44405.rs b/src/test/ui/issues/issue-44405.rs new file mode 100644 index 0000000000..d404b9044d --- /dev/null +++ b/src/test/ui/issues/issue-44405.rs @@ -0,0 +1,22 @@ +use std::ops::Index; + +struct Test; +struct Container(Test); + +impl Test { + fn test(&mut self) {} +} + +impl<'a> Index<&'a bool> for Container { + type Output = Test; + + fn index(&self, _index: &'a bool) -> &Test { + &self.0 + } +} + +fn main() { + let container = Container(Test); + let mut val = true; + container[&mut val].test(); //~ ERROR: cannot borrow data +} diff --git a/src/test/ui/issues/issue-44405.stderr b/src/test/ui/issues/issue-44405.stderr new file mode 100644 index 0000000000..1fd69f6e77 --- /dev/null +++ b/src/test/ui/issues/issue-44405.stderr @@ -0,0 +1,11 @@ +error[E0596]: cannot borrow data in an index of `Container` as mutable + --> $DIR/issue-44405.rs:21:5 + | +LL | container[&mut val].test(); + | ^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable + | + = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Container` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/issues/issue-44406.stderr b/src/test/ui/issues/issue-44406.stderr index 14b3b8cc5c..108542c9b6 100644 --- a/src/test/ui/issues/issue-44406.stderr +++ b/src/test/ui/issues/issue-44406.stderr @@ -15,7 +15,10 @@ LL | bar(baz: $rest) | - help: try using a semicolon: `;` ... LL | foo!(true); - | ^^^^ expecting a type here because of type ascription + | ^^^^ expected type + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `: ` + = note: for more information, see https://github.com/rust-lang/rust/issues/23416 error: aborting due to 2 previous errors diff --git a/src/test/run-pass/issues/issue-4446.rs b/src/test/ui/issues/issue-4446.rs similarity index 100% rename from src/test/run-pass/issues/issue-4446.rs rename to src/test/ui/issues/issue-4446.rs diff --git a/src/test/run-pass/issues/issue-4448.rs b/src/test/ui/issues/issue-4448.rs similarity index 100% rename from src/test/run-pass/issues/issue-4448.rs rename to src/test/ui/issues/issue-4448.rs diff --git a/src/test/ui/issues/issue-4464.rs b/src/test/ui/issues/issue-4464.rs index c20c1cad66..13df611248 100644 --- a/src/test/ui/issues/issue-4464.rs +++ b/src/test/ui/issues/issue-4464.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-44730.rs b/src/test/ui/issues/issue-44730.rs index 7dae6c8123..93f0445d34 100644 --- a/src/test/ui/issues/issue-44730.rs +++ b/src/test/ui/issues/issue-44730.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! dox #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-44851.rs b/src/test/ui/issues/issue-44851.rs index 697b4dcf42..735678047a 100644 --- a/src/test/ui/issues/issue-44851.rs +++ b/src/test/ui/issues/issue-44851.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! a { () => { "a" } } diff --git a/src/test/run-pass/issues/issue-45124.rs b/src/test/ui/issues/issue-45124.rs similarity index 100% rename from src/test/run-pass/issues/issue-45124.rs rename to src/test/ui/issues/issue-45124.rs diff --git a/src/test/run-pass/issues/issue-45152.rs b/src/test/ui/issues/issue-45152.rs similarity index 100% rename from src/test/run-pass/issues/issue-45152.rs rename to src/test/ui/issues/issue-45152.rs diff --git a/src/test/ui/issues/issue-45296.stderr b/src/test/ui/issues/issue-45296.stderr index bc14d20b62..c0d4ce1243 100644 --- a/src/test/ui/issues/issue-45296.stderr +++ b/src/test/ui/issues/issue-45296.stderr @@ -1,8 +1,8 @@ error: an inner attribute is not permitted in this context - --> $DIR/issue-45296.rs:4:7 + --> $DIR/issue-45296.rs:4:5 | LL | #![allow(unused_variables)] - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/run-pass/issues/issue-4541.rs b/src/test/ui/issues/issue-4541.rs similarity index 100% rename from src/test/run-pass/issues/issue-4541.rs rename to src/test/ui/issues/issue-4541.rs diff --git a/src/test/run-pass/issues/issue-4542.rs b/src/test/ui/issues/issue-4542.rs similarity index 100% rename from src/test/run-pass/issues/issue-4542.rs rename to src/test/ui/issues/issue-4542.rs diff --git a/src/test/ui/issues/issue-45425.rs b/src/test/ui/issues/issue-45425.rs index a2ef85a2a0..99e018ba6c 100644 --- a/src/test/ui/issues/issue-45425.rs +++ b/src/test/ui/issues/issue-45425.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::ops::Add; diff --git a/src/test/run-pass/issues/issue-4545.rs b/src/test/ui/issues/issue-4545.rs similarity index 100% rename from src/test/run-pass/issues/issue-4545.rs rename to src/test/ui/issues/issue-4545.rs diff --git a/src/test/run-pass/issues/issue-45510.rs b/src/test/ui/issues/issue-45510.rs similarity index 100% rename from src/test/run-pass/issues/issue-45510.rs rename to src/test/ui/issues/issue-45510.rs diff --git a/src/test/ui/issues/issue-45562.fixed b/src/test/ui/issues/issue-45562.fixed index c23f5909bb..ac700fbd04 100644 --- a/src/test/ui/issues/issue-45562.fixed +++ b/src/test/ui/issues/issue-45562.fixed @@ -1,6 +1,6 @@ // run-rustfix #[no_mangle] pub static RAH: usize = 5; -//~^ ERROR const items should never be #[no_mangle] +//~^ ERROR const items should never be `#[no_mangle]` fn main() {} diff --git a/src/test/ui/issues/issue-45562.rs b/src/test/ui/issues/issue-45562.rs index 8ac4f6794f..eabb5a5cec 100644 --- a/src/test/ui/issues/issue-45562.rs +++ b/src/test/ui/issues/issue-45562.rs @@ -1,6 +1,6 @@ // run-rustfix #[no_mangle] pub const RAH: usize = 5; -//~^ ERROR const items should never be #[no_mangle] +//~^ ERROR const items should never be `#[no_mangle]` fn main() {} diff --git a/src/test/ui/issues/issue-45562.stderr b/src/test/ui/issues/issue-45562.stderr index b97b9cd672..be259d3f8a 100644 --- a/src/test/ui/issues/issue-45562.stderr +++ b/src/test/ui/issues/issue-45562.stderr @@ -1,4 +1,4 @@ -error: const items should never be #[no_mangle] +error: const items should never be `#[no_mangle]` --> $DIR/issue-45562.rs:3:14 | LL | #[no_mangle] pub const RAH: usize = 5; @@ -6,7 +6,7 @@ LL | #[no_mangle] pub const RAH: usize = 5; | | | help: try a static value: `pub static` | - = note: #[deny(no_mangle_const_items)] on by default + = note: `#[deny(no_mangle_const_items)]` on by default error: aborting due to previous error diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr index 479b724ad1..2e99572d01 100644 --- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr +++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr @@ -1,5 +1,5 @@ warning[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:51:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:52:5 | LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -14,7 +14,7 @@ LL | } = note: for more information, try `rustc --explain E0729` warning[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:62:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:63:5 | LL | fn boxed_scribbled<'a>(s: Box>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -29,7 +29,7 @@ LL | } = note: for more information, try `rustc --explain E0729` warning[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:74:5 | LL | fn boxed_boxed_scribbled<'a>(s: Box>>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -44,7 +44,7 @@ LL | } = note: for more information, try `rustc --explain E0729` error: compilation successful - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:80:1 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:81:1 | LL | / fn main() { LL | | let mut x = 1; diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr index 1b9fb04992..45b22511d2 100644 --- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr +++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr @@ -1,5 +1,5 @@ error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:51:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:52:5 | LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -10,7 +10,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:62:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:63:5 | LL | fn boxed_scribbled<'a>(s: Box>) -> &'a mut u32 { | -- lifetime `'a` defined here @@ -21,7 +21,7 @@ LL | } | - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait error[E0713]: borrow may still be in use when destructor runs - --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5 + --> $DIR/issue-45696-scribble-on-boxed-borrow.rs:74:5 | LL | fn boxed_boxed_scribbled<'a>(s: Box>>) -> &'a mut u32 { | -- lifetime `'a` defined here diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs index f568efa487..9f261884f3 100644 --- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs +++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.rs @@ -7,6 +7,7 @@ // revisions: nll migrate // ignore-compare-mode-nll +// ignore-compare-mode-polonius // This test is going to pass in the migrate revision, because the AST-borrowck // accepted this code in the past (see notes below). So we use `#[rustc_error]` diff --git a/src/test/run-pass/issues/issue-45731.rs b/src/test/ui/issues/issue-45731.rs similarity index 100% rename from src/test/run-pass/issues/issue-45731.rs rename to src/test/ui/issues/issue-45731.rs diff --git a/src/test/run-pass/issues/issue-46069.rs b/src/test/ui/issues/issue-46069.rs similarity index 100% rename from src/test/run-pass/issues/issue-46069.rs rename to src/test/ui/issues/issue-46069.rs diff --git a/src/test/run-pass/issues/issue-46095.rs b/src/test/ui/issues/issue-46095.rs similarity index 100% rename from src/test/run-pass/issues/issue-46095.rs rename to src/test/ui/issues/issue-46095.rs diff --git a/src/test/run-pass/issues/issue-46519.rs b/src/test/ui/issues/issue-46519.rs similarity index 100% rename from src/test/run-pass/issues/issue-46519.rs rename to src/test/ui/issues/issue-46519.rs diff --git a/src/test/run-pass/issues/issue-46553.rs b/src/test/ui/issues/issue-46553.rs similarity index 100% rename from src/test/run-pass/issues/issue-46553.rs rename to src/test/ui/issues/issue-46553.rs diff --git a/src/test/run-pass/issues/issue-46845.rs b/src/test/ui/issues/issue-46845.rs similarity index 100% rename from src/test/run-pass/issues/issue-46845.rs rename to src/test/ui/issues/issue-46845.rs diff --git a/src/test/run-pass/issues/issue-46855.rs b/src/test/ui/issues/issue-46855.rs similarity index 100% rename from src/test/run-pass/issues/issue-46855.rs rename to src/test/ui/issues/issue-46855.rs diff --git a/src/test/run-pass/issues/issue-46920-byte-array-patterns.rs b/src/test/ui/issues/issue-46920-byte-array-patterns.rs similarity index 100% rename from src/test/run-pass/issues/issue-46920-byte-array-patterns.rs rename to src/test/ui/issues/issue-46920-byte-array-patterns.rs diff --git a/src/test/ui/issues/issue-46959.rs b/src/test/ui/issues/issue-46959.rs index e1147ac99a..86f1158c19 100644 --- a/src/test/ui/issues/issue-46959.rs +++ b/src/test/ui/issues/issue-46959.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(non_camel_case_types)] #[allow(dead_code)] diff --git a/src/test/ui/issues/issue-46964.rs b/src/test/ui/issues/issue-46964.rs index 4688c9b0a1..9cf53973d8 100644 --- a/src/test/ui/issues/issue-46964.rs +++ b/src/test/ui/issues/issue-46964.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod my_mod { #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct Name<'a> { diff --git a/src/test/ui/issues/issue-47094.rs b/src/test/ui/issues/issue-47094.rs index 6c78a3ba96..f17d4f88d9 100644 --- a/src/test/ui/issues/issue-47094.rs +++ b/src/test/ui/issues/issue-47094.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[repr(C,u8)] enum Foo { diff --git a/src/test/run-pass/issues/issue-47139-1.rs b/src/test/ui/issues/issue-47139-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-47139-1.rs rename to src/test/ui/issues/issue-47139-1.rs diff --git a/src/test/run-pass/issues/issue-47139-2.rs b/src/test/ui/issues/issue-47139-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-47139-2.rs rename to src/test/ui/issues/issue-47139-2.rs diff --git a/src/test/ui/issues/issue-47309.rs b/src/test/ui/issues/issue-47309.rs index a9aeecb61b..03092022d4 100644 --- a/src/test/ui/issues/issue-47309.rs +++ b/src/test/ui/issues/issue-47309.rs @@ -3,7 +3,7 @@ // See https://github.com/rust-lang/rust/issues/47309 // compile-flags:-Clink-dead-code -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type="rlib"] diff --git a/src/test/run-pass/issues/issue-4734.rs b/src/test/ui/issues/issue-4734.rs similarity index 100% rename from src/test/run-pass/issues/issue-4734.rs rename to src/test/ui/issues/issue-4734.rs diff --git a/src/test/run-pass/issues/issue-4735.rs b/src/test/ui/issues/issue-4735.rs similarity index 100% rename from src/test/run-pass/issues/issue-4735.rs rename to src/test/ui/issues/issue-4735.rs diff --git a/src/test/run-pass/issues/issue-47364.rs b/src/test/ui/issues/issue-47364.rs similarity index 100% rename from src/test/run-pass/issues/issue-47364.rs rename to src/test/ui/issues/issue-47364.rs diff --git a/src/test/run-pass/issues/issue-4759-1.rs b/src/test/ui/issues/issue-4759-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-4759-1.rs rename to src/test/ui/issues/issue-4759-1.rs diff --git a/src/test/run-pass/issues/issue-4759.rs b/src/test/ui/issues/issue-4759.rs similarity index 100% rename from src/test/run-pass/issues/issue-4759.rs rename to src/test/ui/issues/issue-4759.rs diff --git a/src/test/run-pass/issues/issue-47638.rs b/src/test/ui/issues/issue-47638.rs similarity index 100% rename from src/test/run-pass/issues/issue-47638.rs rename to src/test/ui/issues/issue-47638.rs diff --git a/src/test/ui/issues/issue-47673.rs b/src/test/ui/issues/issue-47673.rs index 6d7b8f9cc1..0d813e2fad 100644 --- a/src/test/ui/issues/issue-47673.rs +++ b/src/test/ui/issues/issue-47673.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_imports)] use {{}, {}}; diff --git a/src/test/ui/issues/issue-47703-1.rs b/src/test/ui/issues/issue-47703-1.rs index 74323317f1..9573882864 100644 --- a/src/test/ui/issues/issue-47703-1.rs +++ b/src/test/ui/issues/issue-47703-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct AtomicRefMut<'a> { value: &'a mut i32, diff --git a/src/test/ui/issues/issue-47703-tuple.rs b/src/test/ui/issues/issue-47703-tuple.rs index 377eeb67ae..1b285f219d 100644 --- a/src/test/ui/issues/issue-47703-tuple.rs +++ b/src/test/ui/issues/issue-47703-tuple.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct WithDrop; diff --git a/src/test/ui/issues/issue-47703.rs b/src/test/ui/issues/issue-47703.rs index 22f2a1f364..dbf49c7621 100644 --- a/src/test/ui/issues/issue-47703.rs +++ b/src/test/ui/issues/issue-47703.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct MyStruct<'a> { field: &'a mut (), diff --git a/src/test/ui/issues/issue-47722.rs b/src/test/ui/issues/issue-47722.rs index cefc872668..b3c344257b 100644 --- a/src/test/ui/issues/issue-47722.rs +++ b/src/test/ui/issues/issue-47722.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests that automatic coercions from &mut T to *mut T // allow borrows of T to expire immediately - essentially, that diff --git a/src/test/ui/issues/issue-47789.rs b/src/test/ui/issues/issue-47789.rs index 334bd608ad..28671db099 100644 --- a/src/test/ui/issues/issue-47789.rs +++ b/src/test/ui/issues/issue-47789.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(non_upper_case_globals)] static mut x: &'static u32 = &0; diff --git a/src/test/run-pass/issues/issue-48006.rs b/src/test/ui/issues/issue-48006.rs similarity index 96% rename from src/test/run-pass/issues/issue-48006.rs rename to src/test/ui/issues/issue-48006.rs index 8e7105cf10..3a862ace55 100644 --- a/src/test/run-pass/issues/issue-48006.rs +++ b/src/test/ui/issues/issue-48006.rs @@ -1,3 +1,5 @@ +// run-pass + #![feature(step_trait)] use std::iter::Step; diff --git a/src/test/ui/issues/issue-48131.rs b/src/test/ui/issues/issue-48131.rs index b3cc350acf..c854072935 100644 --- a/src/test/ui/issues/issue-48131.rs +++ b/src/test/ui/issues/issue-48131.rs @@ -1,6 +1,7 @@ // This note is annotated because the purpose of the test // is to ensure that certain other notes are not generated. #![deny(unused_unsafe)] //~ NOTE +#![allow(deprecated)] // (test that no note is generated on this unsafe fn) pub unsafe fn a() { diff --git a/src/test/ui/issues/issue-48131.stderr b/src/test/ui/issues/issue-48131.stderr index adc36e266c..6df065b980 100644 --- a/src/test/ui/issues/issue-48131.stderr +++ b/src/test/ui/issues/issue-48131.stderr @@ -1,5 +1,5 @@ error: unnecessary `unsafe` block - --> $DIR/issue-48131.rs:8:9 + --> $DIR/issue-48131.rs:9:9 | LL | unsafe { /* unnecessary */ } | ^^^^^^ unnecessary `unsafe` block @@ -11,7 +11,7 @@ LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/issue-48131.rs:19:13 + --> $DIR/issue-48131.rs:20:13 | LL | unsafe { /* unnecessary */ } | ^^^^^^ unnecessary `unsafe` block diff --git a/src/test/run-pass/issues/issue-48159.rs b/src/test/ui/issues/issue-48159.rs similarity index 100% rename from src/test/run-pass/issues/issue-48159.rs rename to src/test/ui/issues/issue-48159.rs diff --git a/src/test/ui/issues/issue-4830.rs b/src/test/ui/issues/issue-4830.rs index cf94094a79..3724bb6393 100644 --- a/src/test/ui/issues/issue-4830.rs +++ b/src/test/ui/issues/issue-4830.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-48508-aux.rs b/src/test/ui/issues/issue-48508-aux.rs similarity index 100% rename from src/test/run-pass/issues/issue-48508-aux.rs rename to src/test/ui/issues/issue-48508-aux.rs diff --git a/src/test/run-pass/issues/issue-48508.rs b/src/test/ui/issues/issue-48508.rs similarity index 100% rename from src/test/run-pass/issues/issue-48508.rs rename to src/test/ui/issues/issue-48508.rs diff --git a/src/test/ui/issues/issue-48551.rs b/src/test/ui/issues/issue-48551.rs index b5dd673b04..903b2e2992 100644 --- a/src/test/ui/issues/issue-48551.rs +++ b/src/test/ui/issues/issue-48551.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for #48551. Covers a case where duplicate candidates // arose during associated type projection. diff --git a/src/test/run-pass/issues/issue-4865-1.rs b/src/test/ui/issues/issue-4865-1.rs similarity index 100% rename from src/test/run-pass/issues/issue-4865-1.rs rename to src/test/ui/issues/issue-4865-1.rs diff --git a/src/test/run-pass/issues/issue-4865-2.rs b/src/test/ui/issues/issue-4865-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-4865-2.rs rename to src/test/ui/issues/issue-4865-2.rs diff --git a/src/test/run-pass/issues/issue-4865-3.rs b/src/test/ui/issues/issue-4865-3.rs similarity index 100% rename from src/test/run-pass/issues/issue-4865-3.rs rename to src/test/ui/issues/issue-4865-3.rs diff --git a/src/test/run-pass/issues/issue-4875.rs b/src/test/ui/issues/issue-4875.rs similarity index 100% rename from src/test/run-pass/issues/issue-4875.rs rename to src/test/ui/issues/issue-4875.rs diff --git a/src/test/run-pass/issues/issue-48962.rs b/src/test/ui/issues/issue-48962.rs similarity index 100% rename from src/test/run-pass/issues/issue-48962.rs rename to src/test/ui/issues/issue-48962.rs diff --git a/src/test/run-pass/issues/issue-48984.rs b/src/test/ui/issues/issue-48984.rs similarity index 100% rename from src/test/run-pass/issues/issue-48984.rs rename to src/test/ui/issues/issue-48984.rs diff --git a/src/test/ui/issues/issue-49074.rs b/src/test/ui/issues/issue-49074.rs index ad66e421c6..38074d5b05 100644 --- a/src/test/ui/issues/issue-49074.rs +++ b/src/test/ui/issues/issue-49074.rs @@ -1,7 +1,7 @@ // Check that unknown attribute error is shown even if there are unresolved macros. #[marco_use] // typo -//~^ ERROR The attribute `marco_use` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `marco_use` in this scope mod foo { macro_rules! bar { () => (); diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr index 29e10f1bf4..c557255ab5 100644 --- a/src/test/ui/issues/issue-49074.stderr +++ b/src/test/ui/issues/issue-49074.stderr @@ -1,11 +1,8 @@ -error[E0658]: The attribute `marco_use` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `marco_use` in this scope --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add #![feature(custom_attribute)] to the crate attributes to enable error: cannot find macro `bar!` in this scope --> $DIR/issue-49074.rs:12:4 @@ -17,4 +14,3 @@ LL | bar!(); error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/run-pass/issues/issue-49298.rs b/src/test/ui/issues/issue-49298.rs similarity index 100% rename from src/test/run-pass/issues/issue-49298.rs rename to src/test/ui/issues/issue-49298.rs diff --git a/src/test/ui/issues/issue-49544.rs b/src/test/ui/issues/issue-49544.rs new file mode 100644 index 0000000000..ed356275fc --- /dev/null +++ b/src/test/ui/issues/issue-49544.rs @@ -0,0 +1,9 @@ +// aux-build:issue-49544.rs +// check-pass + +extern crate issue_49544; +use issue_49544::foo; + +fn main() { + let _ = foo(); +} diff --git a/src/test/ui/issues/issue-49556.rs b/src/test/ui/issues/issue-49556.rs index 46d9e749aa..d3c6d17f41 100644 --- a/src/test/ui/issues/issue-49556.rs +++ b/src/test/ui/issues/issue-49556.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn iter<'a>(data: &'a [usize]) -> impl Iterator + 'a { data.iter() .map( diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs index dd7b9eeb8d..79cc107d4f 100644 --- a/src/test/ui/issues/issue-49579.rs +++ b/src/test/ui/issues/issue-49579.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-emscripten no i128 support fn fibs(n: u32) -> impl Iterator { diff --git a/src/test/run-pass/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/src/test/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs similarity index 100% rename from src/test/run-pass/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs rename to src/test/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs diff --git a/src/test/run-pass/issues/issue-49632.rs b/src/test/ui/issues/issue-49632.rs similarity index 100% rename from src/test/run-pass/issues/issue-49632.rs rename to src/test/ui/issues/issue-49632.rs diff --git a/src/test/run-pass/issues/issue-49685.rs b/src/test/ui/issues/issue-49685.rs similarity index 100% rename from src/test/run-pass/issues/issue-49685.rs rename to src/test/ui/issues/issue-49685.rs diff --git a/src/test/run-pass/issues/issue-49854.rs b/src/test/ui/issues/issue-49854.rs similarity index 100% rename from src/test/run-pass/issues/issue-49854.rs rename to src/test/ui/issues/issue-49854.rs diff --git a/src/test/ui/issues/issue-49919.rs b/src/test/ui/issues/issue-49919.rs new file mode 100644 index 0000000000..780f338681 --- /dev/null +++ b/src/test/ui/issues/issue-49919.rs @@ -0,0 +1,7 @@ +fn foo<'a, T: 'a>(t: T) -> Box &'a T + 'a> { + let foo: Box Fn() -> &'c T> = Box::new(move || &t); + //~^ ERROR: binding for associated type + unimplemented!() +} + +fn main() {} diff --git a/src/test/ui/issues/issue-49919.stderr b/src/test/ui/issues/issue-49919.stderr new file mode 100644 index 0000000000..8098be5cc4 --- /dev/null +++ b/src/test/ui/issues/issue-49919.stderr @@ -0,0 +1,9 @@ +error[E0582]: binding for associated type `Output` references lifetime `'c`, which does not appear in the trait input types + --> $DIR/issue-49919.rs:2:39 + | +LL | let foo: Box Fn() -> &'c T> = Box::new(move || &t); + | ^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0582`. diff --git a/src/test/ui/issues/issue-49934.rs b/src/test/ui/issues/issue-49934.rs index ad410f30c0..e75381afae 100644 --- a/src/test/ui/issues/issue-49934.rs +++ b/src/test/ui/issues/issue-49934.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(stmt_expr_attributes)] #![warn(unused_attributes)] //~ NOTE lint level defined here diff --git a/src/test/run-pass/issues/issue-49955-2.rs b/src/test/ui/issues/issue-49955-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-49955-2.rs rename to src/test/ui/issues/issue-49955-2.rs diff --git a/src/test/run-pass/issues/issue-49955.rs b/src/test/ui/issues/issue-49955.rs similarity index 100% rename from src/test/run-pass/issues/issue-49955.rs rename to src/test/ui/issues/issue-49955.rs diff --git a/src/test/run-pass/issues/issue-49973.rs b/src/test/ui/issues/issue-49973.rs similarity index 100% rename from src/test/run-pass/issues/issue-49973.rs rename to src/test/ui/issues/issue-49973.rs diff --git a/src/test/run-pass/issues/issue-5008-borrowed-traitobject-method-call.rs b/src/test/ui/issues/issue-5008-borrowed-traitobject-method-call.rs similarity index 100% rename from src/test/run-pass/issues/issue-5008-borrowed-traitobject-method-call.rs rename to src/test/ui/issues/issue-5008-borrowed-traitobject-method-call.rs diff --git a/src/test/ui/issues/issue-50187.rs b/src/test/ui/issues/issue-50187.rs index cda1c4d5fa..f530c3853e 100644 --- a/src/test/ui/issues/issue-50187.rs +++ b/src/test/ui/issues/issue-50187.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(decl_macro)] diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs new file mode 100644 index 0000000000..67feb3ff6a --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Some(42).as_deref(); +//~^ ERROR no method named `as_deref` found for type `std::option::Option<{integer}>` +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr new file mode 100644 index 0000000000..345f91437b --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref` found for type `std::option::Option<{integer}>` in the current scope + --> $DIR/option-as_deref.rs:4:29 + | +LL | let _result = &Some(42).as_deref(); + | ^^^^^^^^ help: there is a method with a similar name: `as_ref` + | + = note: the method `as_deref` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs new file mode 100644 index 0000000000..56aead8d0e --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Some(42).as_deref_mut(); +//~^ ERROR no method named `as_deref_mut` found for type `std::option::Option<{integer}>` +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr new file mode 100644 index 0000000000..2c3a18be67 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut` found for type `std::option::Option<{integer}>` in the current scope + --> $DIR/option-as_deref_mut.rs:4:33 + | +LL | let _result = &mut Some(42).as_deref_mut(); + | ^^^^^^^^^^^^ + | + = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs deleted file mode 100644 index f82eafcaff..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Some(42).deref(); -//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>` -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr deleted file mode 100644 index e916b7d7d3..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref` found for type `std::option::Option<{integer}>` in the current scope - --> $DIR/option-deref.rs:4:29 - | -LL | let _result = &Some(42).deref(); - | ^^^^^ - | - = note: the method `deref` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs new file mode 100644 index 0000000000..1d5eabd617 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Ok(42).as_deref(); +//~^ ERROR no method named `as_deref` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr new file mode 100644 index 0000000000..5e01674877 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref.rs:4:27 + | +LL | let _result = &Ok(42).as_deref(); + | ^^^^^^^^ help: there is a method with a similar name: `as_ref` + | + = note: the method `as_deref` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs new file mode 100644 index 0000000000..104aa3bcad --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Err(41).as_deref_err(); +//~^ ERROR no method named `as_deref_err` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr new file mode 100644 index 0000000000..6dc13da548 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_err` found for type `std::result::Result<_, {integer}>` in the current scope + --> $DIR/result-as_deref_err.rs:4:28 + | +LL | let _result = &Err(41).as_deref_err(); + | ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_ok` + | + = note: the method `as_deref_err` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs new file mode 100644 index 0000000000..c897ab3531 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Ok(42).as_deref_mut(); +//~^ ERROR no method named `as_deref_mut` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr new file mode 100644 index 0000000000..f21e97388b --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref_mut.rs:4:31 + | +LL | let _result = &mut Ok(42).as_deref_mut(); + | ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err` + | + = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs new file mode 100644 index 0000000000..b7849ecb6d --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Err(41).as_deref_mut_err(); +//~^ ERROR no method named `as_deref_mut_err` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr new file mode 100644 index 0000000000..44c0c954ee --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut_err` found for type `std::result::Result<_, {integer}>` in the current scope + --> $DIR/result-as_deref_mut_err.rs:4:32 + | +LL | let _result = &mut Err(41).as_deref_mut_err(); + | ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_ok` + | + = note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs new file mode 100644 index 0000000000..54b695a086 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Ok(42).as_deref_mut_ok(); +//~^ ERROR no method named `as_deref_mut_ok` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr new file mode 100644 index 0000000000..b8369c9b82 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut_ok` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref_mut_ok.rs:4:31 + | +LL | let _result = &mut Ok(42).as_deref_mut_ok(); + | ^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_err` + | + = note: the method `as_deref_mut_ok` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs new file mode 100644 index 0000000000..ebb0500e81 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Ok(42).as_deref_ok(); +//~^ ERROR no method named `as_deref_ok` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr new file mode 100644 index 0000000000..b26705a99e --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref_ok.rs:4:27 + | +LL | let _result = &Ok(42).as_deref_ok(); + | ^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err` + | + = note: the method `as_deref_ok` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs deleted file mode 100644 index 4be2000f05..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Err(41).deref_err(); -//~^ ERROR no method named `deref_err` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr deleted file mode 100644 index 333036127e..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref_err` found for type `std::result::Result<_, {integer}>` in the current scope - --> $DIR/result-deref-err.rs:4:28 - | -LL | let _result = &Err(41).deref_err(); - | ^^^^^^^^^ help: there is a method with a similar name: `deref_ok` - | - = note: the method `deref_err` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs deleted file mode 100644 index a706cde734..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Ok(42).deref_ok(); -//~^ ERROR no method named `deref_ok` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr deleted file mode 100644 index 5937051235..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-deref-ok.rs:4:27 - | -LL | let _result = &Ok(42).deref_ok(); - | ^^^^^^^^ - | - = note: the method `deref_ok` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs deleted file mode 100644 index 43a68e37dd..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Ok(42).deref(); -//~^ ERROR no method named `deref` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr deleted file mode 100644 index 05baa7907f..0000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref` found for type `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-deref.rs:4:27 - | -LL | let _result = &Ok(42).deref(); - | ^^^^^ - | - = note: the method `deref` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50411.rs b/src/test/ui/issues/issue-50411.rs index 1ba47d3b93..a32faa6984 100644 --- a/src/test/ui/issues/issue-50411.rs +++ b/src/test/ui/issues/issue-50411.rs @@ -4,7 +4,7 @@ // second time. Uncool. // compile-flags:-Zmir-opt-level=3 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count(); diff --git a/src/test/run-pass/issues/issue-50415.rs b/src/test/ui/issues/issue-50415.rs similarity index 100% rename from src/test/run-pass/issues/issue-50415.rs rename to src/test/ui/issues/issue-50415.rs diff --git a/src/test/run-pass/issues/issue-50442.rs b/src/test/ui/issues/issue-50442.rs similarity index 100% rename from src/test/run-pass/issues/issue-50442.rs rename to src/test/ui/issues/issue-50442.rs diff --git a/src/test/ui/issues/issue-50471.rs b/src/test/ui/issues/issue-50471.rs index 6868d48196..e728e45e60 100644 --- a/src/test/ui/issues/issue-50471.rs +++ b/src/test/ui/issues/issue-50471.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { assert!({false}); diff --git a/src/test/ui/issues/issue-50518.rs b/src/test/ui/issues/issue-50518.rs index d776d181b6..653b52902d 100644 --- a/src/test/ui/issues/issue-50518.rs +++ b/src/test/ui/issues/issue-50518.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::marker::PhantomData; struct Meta { diff --git a/src/test/run-pass/issues/issue-5060.rs b/src/test/ui/issues/issue-5060.rs similarity index 100% rename from src/test/run-pass/issues/issue-5060.rs rename to src/test/ui/issues/issue-5060.rs diff --git a/src/test/run-pass/issues/issue-50689.rs b/src/test/ui/issues/issue-50689.rs similarity index 100% rename from src/test/run-pass/issues/issue-50689.rs rename to src/test/ui/issues/issue-50689.rs diff --git a/src/test/run-pass/issues/issue-50731.rs b/src/test/ui/issues/issue-50731.rs similarity index 100% rename from src/test/run-pass/issues/issue-50731.rs rename to src/test/ui/issues/issue-50731.rs diff --git a/src/test/ui/issues/issue-50761.rs b/src/test/ui/issues/issue-50761.rs index 70b4bc8b75..59d4f9afda 100644 --- a/src/test/ui/issues/issue-50761.rs +++ b/src/test/ui/issues/issue-50761.rs @@ -1,6 +1,6 @@ // Confirm that we don't accidentally divide or mod by zero in llvm_type -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod a { pub trait A {} diff --git a/src/test/run-pass/issues/issue-50811.rs b/src/test/ui/issues/issue-50811.rs similarity index 100% rename from src/test/run-pass/issues/issue-50811.rs rename to src/test/ui/issues/issue-50811.rs diff --git a/src/test/run-pass/issues/issue-50865-private-impl-trait/auxiliary/lib.rs b/src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs similarity index 100% rename from src/test/run-pass/issues/issue-50865-private-impl-trait/auxiliary/lib.rs rename to src/test/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs diff --git a/src/test/run-pass/issues/issue-50865-private-impl-trait/main.rs b/src/test/ui/issues/issue-50865-private-impl-trait/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-50865-private-impl-trait/main.rs rename to src/test/ui/issues/issue-50865-private-impl-trait/main.rs diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs index 772c45dee1..b170e09d02 100644 --- a/src/test/ui/issues/issue-50993.rs +++ b/src/test/ui/issues/issue-50993.rs @@ -1,5 +1,5 @@ // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` #![feature(no_core)] diff --git a/src/test/run-pass/issues/issue-51185.rs b/src/test/ui/issues/issue-51185.rs similarity index 100% rename from src/test/run-pass/issues/issue-51185.rs rename to src/test/ui/issues/issue-51185.rs diff --git a/src/test/run-pass/issues/issue-51345.rs b/src/test/ui/issues/issue-51345.rs similarity index 100% rename from src/test/run-pass/issues/issue-51345.rs rename to src/test/ui/issues/issue-51345.rs diff --git a/src/test/run-pass/issues/issue-51582.rs b/src/test/ui/issues/issue-51582.rs similarity index 100% rename from src/test/run-pass/issues/issue-51582.rs rename to src/test/ui/issues/issue-51582.rs diff --git a/src/test/ui/issues/issue-51655.rs b/src/test/ui/issues/issue-51655.rs index 989fcc041a..c2ad60fd8c 100644 --- a/src/test/ui/issues/issue-51655.rs +++ b/src/test/ui/issues/issue-51655.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] const PATH_DOT: &[u8] = &[b'.']; diff --git a/src/test/run-pass/issues/issue-51907.rs b/src/test/ui/issues/issue-51907.rs similarity index 100% rename from src/test/run-pass/issues/issue-51907.rs rename to src/test/ui/issues/issue-51907.rs diff --git a/src/test/run-pass/issues/issue-5192.rs b/src/test/ui/issues/issue-5192.rs similarity index 100% rename from src/test/run-pass/issues/issue-5192.rs rename to src/test/ui/issues/issue-5192.rs diff --git a/src/test/ui/issues/issue-51947.rs b/src/test/ui/issues/issue-51947.rs index 7b79807e4d..b5ebf156a2 100644 --- a/src/test/ui/issues/issue-51947.rs +++ b/src/test/ui/issues/issue-51947.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "lib"] #![feature(linkage)] diff --git a/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs b/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs index 63f1128f10..d12b483ba4 100644 --- a/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs +++ b/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs @@ -1,4 +1,4 @@ fn main() { let _ = [0; (&0 as *const i32) as usize]; //~ ERROR casting pointers to integers in constants - //~^ ERROR it is undefined behavior to use this value + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr b/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr index f8c3016e3a..68ee537541 100644 --- a/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr +++ b/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr @@ -5,15 +5,13 @@ LL | let _ = [0; (&0 as *const i32) as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/51910 - = help: add #![feature(const_raw_ptr_to_usize_cast)] to the crate attributes to enable + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable -error[E0080]: it is undefined behavior to use this value +error[E0080]: evaluation of constant value failed --> $DIR/issue-52023-array-size-pointer-cast.rs:2:17 | LL | let _ = [0; (&0 as *const i32) as usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 2 previous errors diff --git a/src/test/run-pass/issues/issue-52140/auxiliary/some_crate.rs b/src/test/ui/issues/issue-52140/auxiliary/some_crate.rs similarity index 100% rename from src/test/run-pass/issues/issue-52140/auxiliary/some_crate.rs rename to src/test/ui/issues/issue-52140/auxiliary/some_crate.rs diff --git a/src/test/run-pass/issues/issue-52140/main.rs b/src/test/ui/issues/issue-52140/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-52140/main.rs rename to src/test/ui/issues/issue-52140/main.rs diff --git a/src/test/run-pass/issues/issue-52141/auxiliary/some_crate.rs b/src/test/ui/issues/issue-52141/auxiliary/some_crate.rs similarity index 100% rename from src/test/run-pass/issues/issue-52141/auxiliary/some_crate.rs rename to src/test/ui/issues/issue-52141/auxiliary/some_crate.rs diff --git a/src/test/run-pass/issues/issue-52141/main.rs b/src/test/ui/issues/issue-52141/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-52141/main.rs rename to src/test/ui/issues/issue-52141/main.rs diff --git a/src/test/run-pass/issues/issue-52169.rs b/src/test/ui/issues/issue-52169.rs similarity index 100% rename from src/test/run-pass/issues/issue-52169.rs rename to src/test/ui/issues/issue-52169.rs diff --git a/src/test/run-pass/issues/issue-5239-2.rs b/src/test/ui/issues/issue-5239-2.rs similarity index 100% rename from src/test/run-pass/issues/issue-5239-2.rs rename to src/test/ui/issues/issue-5239-2.rs diff --git a/src/test/run-pass/issues/issue-5243.rs b/src/test/ui/issues/issue-5243.rs similarity index 100% rename from src/test/run-pass/issues/issue-5243.rs rename to src/test/ui/issues/issue-5243.rs diff --git a/src/test/ui/issues/issue-52489.stderr b/src/test/ui/issues/issue-52489.stderr index 339877f87e..842ebd1969 100644 --- a/src/test/ui/issues/issue-52489.stderr +++ b/src/test/ui/issues/issue-52489.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'issue_52489_unstable' LL | use issue_52489; | ^^^^^^^^^^^ | - = help: add #![feature(issue_52489_unstable)] to the crate attributes to enable + = help: add `#![feature(issue_52489_unstable)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/run-pass/issues/issue-52557.rs b/src/test/ui/issues/issue-52557.rs similarity index 100% rename from src/test/run-pass/issues/issue-52557.rs rename to src/test/ui/issues/issue-52557.rs diff --git a/src/test/run-pass/issues/issue-52705/auxiliary/png2.rs b/src/test/ui/issues/issue-52705/auxiliary/png2.rs similarity index 100% rename from src/test/run-pass/issues/issue-52705/auxiliary/png2.rs rename to src/test/ui/issues/issue-52705/auxiliary/png2.rs diff --git a/src/test/run-pass/issues/issue-52705/main.rs b/src/test/ui/issues/issue-52705/main.rs similarity index 100% rename from src/test/run-pass/issues/issue-52705/main.rs rename to src/test/ui/issues/issue-52705/main.rs diff --git a/src/test/run-pass/issues/issue-5280.rs b/src/test/ui/issues/issue-5280.rs similarity index 100% rename from src/test/run-pass/issues/issue-5280.rs rename to src/test/ui/issues/issue-5280.rs diff --git a/src/test/ui/issues/issue-52992.rs b/src/test/ui/issues/issue-52992.rs index c58656330e..727dd43d57 100644 --- a/src/test/ui/issues/issue-52992.rs +++ b/src/test/ui/issues/issue-52992.rs @@ -2,7 +2,7 @@ // implied bounds was causing outlives relations that were not // properly handled. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/run-pass/issues/issue-5315.rs b/src/test/ui/issues/issue-5315.rs similarity index 100% rename from src/test/run-pass/issues/issue-5315.rs rename to src/test/ui/issues/issue-5315.rs diff --git a/src/test/run-pass/issues/issue-5321-immediates-with-bare-self.rs b/src/test/ui/issues/issue-5321-immediates-with-bare-self.rs similarity index 100% rename from src/test/run-pass/issues/issue-5321-immediates-with-bare-self.rs rename to src/test/ui/issues/issue-5321-immediates-with-bare-self.rs diff --git a/src/test/run-pass/issues/issue-53333.rs b/src/test/ui/issues/issue-53333.rs similarity index 100% rename from src/test/run-pass/issues/issue-53333.rs rename to src/test/ui/issues/issue-53333.rs diff --git a/src/test/ui/issues/issue-53419.rs b/src/test/ui/issues/issue-53419.rs index bf6791734d..64ac0b1c03 100644 --- a/src/test/ui/issues/issue-53419.rs +++ b/src/test/ui/issues/issue-53419.rs @@ -1,4 +1,4 @@ -//compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Foo { bar: dyn for<'r> Fn(usize, &'r dyn FnMut()) diff --git a/src/test/ui/issues/issue-5353.rs b/src/test/ui/issues/issue-5353.rs index 808b73ec72..cca1759505 100644 --- a/src/test/ui/issues/issue-5353.rs +++ b/src/test/ui/issues/issue-5353.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-53568.rs b/src/test/ui/issues/issue-53568.rs index 4d3b3f80a9..7644810c94 100644 --- a/src/test/ui/issues/issue-53568.rs +++ b/src/test/ui/issues/issue-53568.rs @@ -1,7 +1,7 @@ // Regression test for an NLL-related ICE (#53568) -- we failed to // resolve inference variables in "custom type-ops". // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Future { type Item; diff --git a/src/test/ui/issues/issue-53675-a-test-called-panic.rs b/src/test/ui/issues/issue-53675-a-test-called-panic.rs index 8a35b36d46..b8dca96946 100644 --- a/src/test/ui/issues/issue-53675-a-test-called-panic.rs +++ b/src/test/ui/issues/issue-53675-a-test-called-panic.rs @@ -1,7 +1,7 @@ // rust-lang/rust#53675: At one point the compiler errored when a test // named `panic` used the `assert!` macro in expression position. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: --test mod in_expression_position { diff --git a/src/test/run-pass/issues/issue-53728.rs b/src/test/ui/issues/issue-53728.rs similarity index 95% rename from src/test/run-pass/issues/issue-53728.rs rename to src/test/ui/issues/issue-53728.rs index 00666972e2..77b5010f77 100644 --- a/src/test/run-pass/issues/issue-53728.rs +++ b/src/test/ui/issues/issue-53728.rs @@ -1,3 +1,5 @@ +// run-pass + #![allow(dead_code)] #[repr(u16)] enum DeviceKind { diff --git a/src/test/ui/issues/issue-53787-inline-assembler-macro.rs b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs index 937bce1b65..09e8d55c06 100644 --- a/src/test/ui/issues/issue-53787-inline-assembler-macro.rs +++ b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs @@ -1,5 +1,7 @@ // Regression test for Issue #53787: Fix ICE when creating a label in inline assembler with macros. +// ignore-emscripten + #![feature(asm)] macro_rules! fake_jump { diff --git a/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr index 7edf235652..6a4416d78f 100644 --- a/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr +++ b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr @@ -1,5 +1,5 @@ error[E0669]: invalid value for constraint in inline assembly - --> $DIR/issue-53787-inline-assembler-macro.rs:21:16 + --> $DIR/issue-53787-inline-assembler-macro.rs:23:16 | LL | fake_jump!("FirstFunc"); | ^^^^^^^^^^^ diff --git a/src/test/run-pass/issues/issue-53843.rs b/src/test/ui/issues/issue-53843.rs similarity index 95% rename from src/test/run-pass/issues/issue-53843.rs rename to src/test/ui/issues/issue-53843.rs index 53728ec4d9..f305b370ce 100644 --- a/src/test/run-pass/issues/issue-53843.rs +++ b/src/test/ui/issues/issue-53843.rs @@ -1,3 +1,5 @@ +// run-pass + use std::ops::Deref; pub struct Pin