]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #74623 - lcnr:polymorphize-functions, r=eddyb
authorYuki Okushi <huyuumi.dev@gmail.com>
Fri, 24 Jul 2020 09:56:31 +0000 (18:56 +0900)
committerGitHub <noreply@github.com>
Fri, 24 Jul 2020 09:56:31 +0000 (18:56 +0900)
polymorphize GlobalAlloc::Function

this sadly does not change #74614

r? @eddyb

260 files changed:
.github/workflows/ci.yml
.gitmodules
Cargo.lock
Cargo.toml
rustfmt.toml
src/backtrace [deleted submodule]
src/bootstrap/builder.rs
src/bootstrap/dist.rs
src/build_helper/lib.rs
src/ci/azure-pipelines/auto.yml
src/ci/azure-pipelines/master.yml [deleted file]
src/ci/azure-pipelines/pr.yml [deleted file]
src/ci/azure-pipelines/try.yml
src/ci/github-actions/ci.yml
src/doc/book
src/doc/edition-guide
src/doc/reference
src/doc/rustc/src/codegen-options/index.md
src/liballoc/string.rs
src/libcore/convert/mod.rs
src/libcore/hash/sip.rs
src/libcore/intrinsics.rs
src/libcore/iter/traits/iterator.rs
src/libcore/macros/mod.rs
src/libcore/mem/mod.rs
src/libcore/num/f64.rs
src/libcore/pin.rs
src/libcore/ptr/const_ptr.rs
src/libcore/ptr/mut_ptr.rs
src/libcore/ptr/non_null.rs
src/libprofiler_builtins/Cargo.toml
src/libprofiler_builtins/build.rs
src/librustc_ast/build.rs [deleted file]
src/librustc_ast_passes/ast_validation.rs
src/librustc_attr/Cargo.toml
src/librustc_attr/build.rs [deleted file]
src/librustc_attr/builtin.rs
src/librustc_codegen_llvm/build.rs [deleted file]
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/va_arg.rs
src/librustc_codegen_ssa/back/link.rs
src/librustc_codegen_ssa/back/linker.rs
src/librustc_codegen_ssa/build.rs [deleted file]
src/librustc_driver/build.rs [deleted file]
src/librustc_error_codes/error_codes.rs
src/librustc_error_codes/error_codes/E0724.md
src/librustc_feature/accepted.rs
src/librustc_hir/hir.rs
src/librustc_incremental/build.rs [deleted file]
src/librustc_infer/infer/combine.rs
src/librustc_infer/infer/error_reporting/mod.rs
src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
src/librustc_infer/infer/mod.rs
src/librustc_infer/lib.rs
src/librustc_interface/build.rs [deleted file]
src/librustc_interface/tests.rs
src/librustc_llvm/Cargo.toml
src/librustc_llvm/build.rs
src/librustc_metadata/build.rs [deleted file]
src/librustc_middle/build.rs [deleted file]
src/librustc_middle/lib.rs
src/librustc_middle/middle/stability.rs
src/librustc_middle/traits/mod.rs
src/librustc_middle/traits/structural_impls.rs
src/librustc_middle/ty/layout.rs
src/librustc_middle/ty/mod.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir_build/build/mod.rs
src/librustc_passes/stability.rs
src/librustc_resolve/macros.rs
src/librustc_session/config.rs
src/librustc_session/options.rs
src/librustc_session/session.rs
src/librustc_target/build.rs [deleted file]
src/librustc_target/spec/aarch64_apple_darwin.rs [new file with mode: 0644]
src/librustc_target/spec/apple_base.rs
src/librustc_target/spec/freestanding_base.rs
src/librustc_target/spec/illumos_base.rs
src/librustc_target/spec/mod.rs
src/librustc_target/spec/msp430_none_elf.rs
src/librustc_target/spec/riscv32i_unknown_none_elf.rs
src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
src/librustc_target/spec/solaris_base.rs
src/librustc_target/spec/windows_gnu_base.rs
src/librustc_target/spec/x86_64_apple_darwin.rs
src/librustc_trait_selection/traits/codegen/mod.rs
src/librustc_trait_selection/traits/coherence.rs
src/librustc_trait_selection/traits/error_reporting/suggestions.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/types.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/rustdoc.css
src/librustdoc/html/static/themes/ayu.css
src/librustdoc/html/static/themes/dark.css
src/librustdoc/html/static/themes/light.css
src/librustdoc/passes/collect_intra_doc_links.rs
src/libstd/Cargo.toml
src/libstd/backtrace.rs
src/libstd/build.rs
src/libstd/f32.rs
src/libstd/f64.rs
src/libstd/lib.rs
src/libstd/os/linux/fs.rs
src/libstd/os/redox/fs.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/sys/sgx/fd.rs
src/libstd/sys/unix/ext/fs.rs
src/libstd/sys/unix/fd.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/net.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/weak.rs
src/libstd/sys/vxworks/fd.rs
src/libstd/sys/vxworks/time.rs
src/libstd/sys/wasi/fs.rs
src/libstd/sys_common/backtrace.rs
src/libunwind/Cargo.toml
src/test/codegen-units/item-collection/static-init.rs
src/test/codegen-units/item-collection/trait-method-default-impl.rs
src/test/codegen-units/polymorphization/unused_type_parameters.rs
src/test/codegen/abi-efiapi.rs
src/test/codegen/cfguard-checks.rs
src/test/codegen/cfguard-disabled.rs
src/test/codegen/cfguard-nochecks.rs
src/test/codegen/cfguard-non-msvc.rs
src/test/codegen/force-unwind-tables.rs
src/test/codegen/unchecked-float-casts.rs
src/test/codegen/wasm_casts_trapping.rs
src/test/debuginfo/function-call.rs
src/test/debuginfo/pretty-huge-vec.rs
src/test/debuginfo/pretty-std-collections.rs
src/test/debuginfo/pretty-std.rs
src/test/debuginfo/pretty-uninitialized-vec.rs
src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c
src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
src/test/rustdoc-ui/intra-doc-alias-ice.stderr
src/test/rustdoc-ui/intra-link-span-ice-55723.rs
src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
src/test/rustdoc-ui/intra-links-anchors.rs
src/test/rustdoc-ui/intra-links-anchors.stderr
src/test/rustdoc-ui/intra-links-private.private.stderr [new file with mode: 0644]
src/test/rustdoc-ui/intra-links-private.public.stderr
src/test/rustdoc-ui/intra-links-private.rs
src/test/rustdoc-ui/intra-links-warning-crlf.rs
src/test/rustdoc-ui/intra-links-warning-crlf.stderr
src/test/rustdoc-ui/intra-links-warning.rs
src/test/rustdoc-ui/intra-links-warning.stderr
src/test/rustdoc-ui/issue-74134.private.stderr [new file with mode: 0644]
src/test/rustdoc-ui/issue-74134.public.stderr
src/test/rustdoc-ui/issue-74134.rs
src/test/rustdoc-ui/lint-group.rs
src/test/rustdoc-ui/lint-group.stderr
src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
src/test/ui/async-await/issues/issue-62097.rs
src/test/ui/async-await/issues/issue-62097.stderr
src/test/ui/cfguard-run.rs
src/test/ui/const-generics/defaults/wrong-order.rs [new file with mode: 0644]
src/test/ui/const-generics/defaults/wrong-order.stderr [new file with mode: 0644]
src/test/ui/consts/issue-73976-monomorphic.rs [new file with mode: 0644]
src/test/ui/consts/issue-73976-polymorphic.rs [new file with mode: 0644]
src/test/ui/consts/issue-73976-polymorphic.stderr [new file with mode: 0644]
src/test/ui/impl-header-lifetime-elision/dyn-trait.rs
src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
src/test/ui/impl-trait/static-return-lifetime-infered.rs
src/test/ui/impl-trait/static-return-lifetime-infered.stderr
src/test/ui/issues/issue-16922.rs
src/test/ui/issues/issue-16922.stderr
src/test/ui/issues/issue-74614.rs [new file with mode: 0644]
src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
src/test/ui/object-lifetime/object-lifetime-default-from-box-error.rs
src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
src/test/ui/polymorphization/const_parameters/closures.rs
src/test/ui/polymorphization/const_parameters/closures.stderr
src/test/ui/polymorphization/const_parameters/functions.rs
src/test/ui/polymorphization/const_parameters/functions.stderr
src/test/ui/polymorphization/drop_shims/simple.rs
src/test/ui/polymorphization/drop_shims/transitive.rs
src/test/ui/polymorphization/generators.rs
src/test/ui/polymorphization/generators.stderr
src/test/ui/polymorphization/lifetimes.rs
src/test/ui/polymorphization/lifetimes.stderr
src/test/ui/polymorphization/normalized_sig_types.rs
src/test/ui/polymorphization/predicates.rs
src/test/ui/polymorphization/predicates.stderr
src/test/ui/polymorphization/type_parameters/closures.rs
src/test/ui/polymorphization/type_parameters/closures.stderr
src/test/ui/polymorphization/type_parameters/functions.rs
src/test/ui/polymorphization/type_parameters/functions.stderr
src/test/ui/polymorphization/unsized_cast.rs
src/test/ui/polymorphization/unsized_cast.stderr
src/test/ui/print_type_sizes/niche-filling.stdout
src/test/ui/regions/region-object-lifetime-in-coercion.rs
src/test/ui/regions/region-object-lifetime-in-coercion.stderr
src/test/ui/regions/regions-addr-of-self.rs
src/test/ui/regions/regions-addr-of-self.stderr
src/test/ui/regions/regions-close-object-into-object-2.rs
src/test/ui/regions/regions-close-object-into-object-2.stderr
src/test/ui/regions/regions-close-object-into-object-4.rs
src/test/ui/regions/regions-close-object-into-object-4.stderr
src/test/ui/regions/regions-proc-bound-capture.rs
src/test/ui/regions/regions-proc-bound-capture.stderr
src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs [new file with mode: 0644]
src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs [new file with mode: 0644]
src/test/ui/sanitize/new-llvm-pass-manager-thin-lto.rs
src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
src/test/ui/stability-attribute/stability-attribute-sanity.rs
src/test/ui/stability-attribute/stability-attribute-sanity.stderr
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr [new file with mode: 0644]
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs [new file with mode: 0644]
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr [new file with mode: 0644]
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.fixed [new file with mode: 0644]
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr [new file with mode: 0644]
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs [new file with mode: 0644]
src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr [new file with mode: 0644]
src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs
src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
src/test/ui/type-sizes.rs
src/test/ui/typeck/typeck_type_placeholder_item.rs
src/test/ui/typeck/typeck_type_placeholder_item.stderr
src/test/ui/underscore-lifetime/dyn-trait-underscore.rs
src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
src/tools/cargo
src/tools/compiletest/src/common.rs
src/tools/compiletest/src/header.rs
src/tools/compiletest/src/header/tests.rs
src/tools/compiletest/src/main.rs
src/tools/compiletest/src/tests.rs
src/tools/error_index_generator/Cargo.toml
src/tools/tidy/src/deps.rs
src/tools/tidy/src/lib.rs
triagebot.toml

index 6e0808c0d58969089975d8f2f2f2868881a96712..d83971b70bedc45bfecb79c29608d884c0d5ef79 100644 (file)
@@ -20,6 +20,7 @@ name: CI
     branches:
       - auto
       - try
+      - try-perf
       - master
   pull_request:
     branches:
@@ -146,7 +147,7 @@ jobs:
       CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
       ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
       CACHE_DOMAIN: ci-caches.rust-lang.org
-    if: "github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'"
+    if: "github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
     strategy:
       matrix:
         include:
@@ -717,7 +718,7 @@ jobs:
   try-success:
     needs:
       - try
-    if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'"
+    if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
     steps:
       - name: mark the job as a success
         run: exit 0
@@ -727,7 +728,7 @@ jobs:
   try-failure:
     needs:
       - try
-    if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'"
+    if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
     steps:
       - name: mark the job as a failure
         run: exit 1
index b914b7d6fa12961cb20f627f0a2133715e86c481..5c0ab737f63dbd7da7c41695f382a9a2a275f1b6 100644 (file)
@@ -44,6 +44,3 @@
 [submodule "src/tools/rust-analyzer"]
        path = src/tools/rust-analyzer
        url = https://github.com/rust-analyzer/rust-analyzer.git
-[submodule "src/backtrace"]
-       path = src/backtrace
-       url = https://github.com/rust-lang/backtrace-rs.git
index 34a33eca3f40b7c635b79dfbf7b1bc0f416c8497..8f110403eb842311fcc3e72b72cf392be76dda80 100644 (file)
@@ -1,26 +1,10 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
 [[package]]
-name = "addr2line"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
-dependencies = [
- "compiler_builtins",
- "gimli",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
-]
-
-[[package]]
-name = "adler"
-version = "0.2.2"
+name = "adler32"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccc9a9dd069569f212bc4330af9f17c4afb5e8ce185e83dbb14f1349dda18b10"
-dependencies = [
- "compiler_builtins",
- "rustc-std-workspace-core",
-]
+checksum = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
 
 [[package]]
 name = "aho-corasick"
@@ -141,14 +125,28 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
 
 [[package]]
 name = "backtrace"
-version = "0.3.50"
+version = "0.3.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e"
 dependencies = [
- "addr2line",
+ "backtrace-sys",
  "cfg-if",
+ "compiler_builtins",
  "libc",
- "miniz_oxide",
- "object",
  "rustc-demangle",
+ "rustc-std-workspace-core",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18fbebbe1c9d1f383a9cc7e8ccdb471b91c8d024ee9c2ca5b5346121fe8b4399"
+dependencies = [
+ "cc",
+ "compiler_builtins",
+ "libc",
+ "rustc-std-workspace-core",
 ]
 
 [[package]]
@@ -280,7 +278,7 @@ checksum = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010"
 
 [[package]]
 name = "cargo"
-version = "0.47.0"
+version = "0.48.0"
 dependencies = [
  "anyhow",
  "atty",
@@ -412,9 +410,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.57"
+version = "1.0.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe"
+checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
 dependencies = [
  "jobserver",
 ]
@@ -690,9 +688,9 @@ dependencies = [
 
 [[package]]
 name = "crc32fast"
-version = "1.2.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
+checksum = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"
 dependencies = [
  "cfg-if",
 ]
@@ -1025,9 +1023,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
 
 [[package]]
 name = "flate2"
-version = "1.0.16"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e"
+checksum = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3"
 dependencies = [
  "cfg-if",
  "crc32fast",
@@ -1161,17 +1159,6 @@ dependencies = [
  "wasi",
 ]
 
-[[package]]
-name = "gimli"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
-dependencies = [
- "compiler_builtins",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
-]
-
 [[package]]
 name = "git2"
 version = "0.13.5"
@@ -1576,9 +1563,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.71"
+version = "0.2.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
+checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -1832,14 +1819,11 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.4.0"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
+checksum = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625"
 dependencies = [
- "adler",
- "compiler_builtins",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
+ "adler32",
 ]
 
 [[package]]
@@ -1971,17 +1955,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "object"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
-dependencies = [
- "compiler_builtins",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
-]
-
 [[package]]
 name = "once_cell"
 version = "1.1.0"
@@ -4373,8 +4346,8 @@ dependencies = [
 name = "std"
 version = "0.0.0"
 dependencies = [
- "addr2line",
  "alloc",
+ "backtrace",
  "cfg-if",
  "compiler_builtins",
  "core",
@@ -4383,13 +4356,10 @@ dependencies = [
  "hashbrown",
  "hermit-abi",
  "libc",
- "miniz_oxide",
- "object",
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
  "rand 0.7.3",
- "rustc-demangle",
  "unwind",
  "wasi",
 ]
index 9429e063b51106e35e9d19aa6eb89a91e242eba4..efc6f4a0291ca6791b9088ad6f7a02bb4473106b 100644 (file)
@@ -80,11 +80,5 @@ rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' }
 rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' }
 rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' }
 
-# This crate's integration with libstd is a bit wonky, so we use a submodule
-# instead of a crates.io dependency. Make sure everything else in the repo is
-# also using the submodule, however, so we can avoid duplicate copies of the
-# source code for this crate.
-backtrace = { path = "src/backtrace" }
-
 [patch."https://github.com/rust-lang/rust-clippy"]
 clippy_lints = { path = "src/tools/clippy/clippy_lints" }
index b16aecc463c9191c591d0c135ab50e975afc1000..c76a75fa07bb0361eee0acda48734f8c58c797a2 100644 (file)
@@ -30,7 +30,6 @@ ignore = [
     "src/tools/rust-analyzer",
     "src/tools/rust-installer",
     "src/tools/rustfmt",
-    "src/backtrace",
 
     # We do not format this file as it is externally sourced and auto-generated.
     "src/libstd/sys/cloudabi/abi/cloudabi.rs",
diff --git a/src/backtrace b/src/backtrace
deleted file mode 160000 (submodule)
index 5965cf5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 5965cf5fc17affc84c11dc9972ae8f4dc2c32db1
index 737176c48f878ef5cb59a81a173cfb8ca6c5102e..c1e56347ab1e0111ed0ff5d0bd71f1c88aead816 100644 (file)
@@ -1239,7 +1239,7 @@ pub fn cargo(
             && self.config.control_flow_guard
             && compiler.stage >= 1
         {
-            rustflags.arg("-Zcontrol-flow-guard");
+            rustflags.arg("-Ccontrol-flow-guard");
         }
 
         // For `cargo doc` invocations, make rustdoc print the Rust version into the docs
index 14c22605e8188d383056378d4f3c6105a6141539..c64934cd6c9ded20f166b32e7988f80eb94eb68c 100644 (file)
@@ -1005,7 +1005,6 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
         // (essentially libstd and all of its path dependencies)
         let std_src_dirs = [
             "src/build_helper",
-            "src/backtrace/src",
             "src/liballoc",
             "src/libcore",
             "src/libpanic_abort",
index 43c3c5773ce5b2d45cd32ee1157cf2d8ce0dc1b2..e30da8d56e10fca3ebb0fb3e289f07665e4e27e0 100644 (file)
@@ -1,3 +1,5 @@
+use std::ffi::{OsStr, OsString};
+use std::fmt::Display;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::time::{SystemTime, UNIX_EPOCH};
@@ -28,6 +30,14 @@ macro_rules! t {
     };
 }
 
+/// Reads an environment variable and adds it to dependencies.
+/// Supposed to be used for all variables except those set for build scripts by cargo
+/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
+pub fn tracked_env_var_os<K: AsRef<OsStr> + Display>(key: K) -> Option<OsString> {
+    println!("cargo:rerun-if-env-changed={}", key);
+    env::var_os(key)
+}
+
 // Because Cargo adds the compiler's dylib path to our library search path, llvm-config may
 // break: the dylib path for the compiler, as of this writing, contains a copy of the LLVM
 // shared library, which means that when our freshly built llvm-config goes to load it's
@@ -37,10 +47,8 @@ macro_rules! t {
 // perfect -- we might actually want to see something from Cargo's added library paths -- but
 // for now it works.
 pub fn restore_library_path() {
-    println!("cargo:rerun-if-env-changed=REAL_LIBRARY_PATH_VAR");
-    println!("cargo:rerun-if-env-changed=REAL_LIBRARY_PATH");
-    let key = env::var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR");
-    if let Some(env) = env::var_os("REAL_LIBRARY_PATH") {
+    let key = tracked_env_var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR");
+    if let Some(env) = tracked_env_var_os("REAL_LIBRARY_PATH") {
         env::set_var(&key, &env);
     } else {
         env::remove_var(&key);
index 63c3d44020f0cd3032bae382aefef2b8a0f04bf1..06e284c763c1509f7c34b38d3edc5e0198ff158c 100644 (file)
 #####################################
 
 #
-# Azure Pipelines "auto" branch build for Rust on Linux, macOS, and Windows.
+# Azure Pipelines "auto" branch build for Rust on macOS
 #
 
 pr: none
 trigger:
   - auto
 
-variables:
-- group: dummy-credentials
-
 jobs:
-- job: Linux
-  timeoutInMinutes: 600
-  pool:
-    vmImage: ubuntu-16.04
-  steps:
-  - template: steps/run.yml
-  strategy:
-    matrix:
-      x86_64-gnu-llvm-8:
-        RUST_BACKTRACE: 1
-      dist-x86_64-linux: {}
-      dist-x86_64-linux-alt:
-        IMAGE: dist-x86_64-linux
-      arm-android: {}
-      armhf-gnu: {}
-      dist-various-1: {}
-      dist-various-2: {}
-      dist-aarch64-linux: {}
-      dist-android: {}
-      dist-arm-linux: {}
-      dist-armhf-linux: {}
-      dist-armv7-linux: {}
-      dist-i586-gnu-i586-i686-musl: {}
-      dist-i686-freebsd: {}
-      dist-i686-linux: {}
-      dist-mips-linux: {}
-      dist-mips64-linux: {}
-      dist-mips64el-linux: {}
-      dist-mipsel-linux: {}
-      dist-powerpc-linux: {}
-      dist-powerpc64-linux: {}
-      dist-powerpc64le-linux: {}
-      dist-riscv64-linux: {}
-      dist-s390x-linux: {}
-      dist-x86_64-freebsd: {}
-      dist-x86_64-illumos: {}
-      dist-x86_64-musl: {}
-      dist-x86_64-netbsd: {}
-      i686-gnu: {}
-      i686-gnu-nopt: {}
-      test-various: {}
-      wasm32: {}
-      x86_64-gnu: {}
-      x86_64-gnu-full-bootstrap: {}
-      x86_64-gnu-aux: {}
-      x86_64-gnu-tools:
-        DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
-      x86_64-gnu-debug: {}
-      x86_64-gnu-nopt: {}
-      x86_64-gnu-distcheck: {}
-      mingw-check: {}
-
 - job: macOS
   timeoutInMinutes: 600
   pool:
@@ -115,115 +60,3 @@ jobs:
         MACOSX_DEPLOYMENT_TARGET: 10.7
         NO_LLVM_ASSERTIONS: 1
         NO_DEBUG_ASSERTIONS: 1
-
-
-- job: Windows
-  timeoutInMinutes: 600
-  pool:
-    vmImage: 'vs2017-win2016'
-  steps:
-  - template: steps/run.yml
-  strategy:
-    matrix:
-      # 32/64 bit MSVC tests
-      x86_64-msvc-1:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
-        SCRIPT: make ci-subset-1
-        # FIXME(#59637)
-        NO_DEBUG_ASSERTIONS: 1
-        NO_LLVM_ASSERTIONS: 1
-      x86_64-msvc-2:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
-        SCRIPT: make ci-subset-2
-      i686-msvc-1:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
-        SCRIPT: make ci-subset-1
-        # FIXME(#59637)
-        NO_DEBUG_ASSERTIONS: 1
-        NO_LLVM_ASSERTIONS: 1
-      i686-msvc-2:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
-        SCRIPT: make ci-subset-2
-        # FIXME(#59637)
-        NO_DEBUG_ASSERTIONS: 1
-        NO_LLVM_ASSERTIONS: 1
-      x86_64-msvc-cargo:
-        SCRIPT: python x.py test src/tools/cargotest src/tools/cargo
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
-        VCVARS_BAT: vcvars64.bat
-        # FIXME(#59637)
-        NO_DEBUG_ASSERTIONS: 1
-        NO_LLVM_ASSERTIONS: 1
-      # MSVC tools tests
-      x86_64-msvc-tools:
-        SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstate/toolstates.json
-
-      # 32/64-bit MinGW builds.
-      #
-      # We are using MinGW with posix threads since LLVM does not compile with
-      # the win32 threads version due to missing support for C++'s std::thread.
-      #
-      # Instead of relying on the MinGW version installed on appveryor we download
-      # and install one ourselves so we won't be surprised by changes to appveyor's
-      # build image.
-      #
-      # Finally, note that the downloads below are all in the `rust-lang-ci` S3
-      # bucket, but they cleraly didn't originate there! The downloads originally
-      # came from the mingw-w64 SourceForge download site. Unfortunately
-      # SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
-      i686-mingw-1:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-        SCRIPT: make ci-mingw-subset-1
-        CUSTOM_MINGW: 1
-        # FIXME(#59637)
-        NO_DEBUG_ASSERTIONS: 1
-        NO_LLVM_ASSERTIONS: 1
-      i686-mingw-2:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-        SCRIPT: make ci-mingw-subset-2
-        CUSTOM_MINGW: 1
-      x86_64-mingw-1:
-        SCRIPT: make ci-mingw-subset-1
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-        CUSTOM_MINGW: 1
-        # FIXME(#59637)
-        NO_DEBUG_ASSERTIONS: 1
-        NO_LLVM_ASSERTIONS: 1
-      x86_64-mingw-2:
-        SCRIPT: make ci-mingw-subset-2
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-        CUSTOM_MINGW: 1
-
-      # 32/64 bit MSVC and GNU deployment
-      dist-x86_64-msvc:
-        INITIAL_RUST_CONFIGURE_ARGS: >-
-          --build=x86_64-pc-windows-msvc
-          --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
-          --enable-full-tools
-          --enable-profiler
-        SCRIPT: python x.py dist
-        DIST_REQUIRE_ALL_TOOLS: 1
-      dist-i686-msvc:
-        INITIAL_RUST_CONFIGURE_ARGS: >-
-          --build=i686-pc-windows-msvc
-          --target=i586-pc-windows-msvc
-          --enable-full-tools
-          --enable-profiler
-        SCRIPT: python x.py dist
-        DIST_REQUIRE_ALL_TOOLS: 1
-      dist-i686-mingw:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler
-        SCRIPT: python x.py dist
-        CUSTOM_MINGW: 1
-        DIST_REQUIRE_ALL_TOOLS: 1
-      dist-x86_64-mingw:
-        SCRIPT: python x.py dist
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler
-        CUSTOM_MINGW: 1
-        DIST_REQUIRE_ALL_TOOLS: 1
-
-      # "alternate" deployment, see .travis.yml for more info
-      dist-x86_64-msvc-alt:
-        INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
-        SCRIPT: python x.py dist
diff --git a/src/ci/azure-pipelines/master.yml b/src/ci/azure-pipelines/master.yml
deleted file mode 100644 (file)
index 13c5561..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#####################################
-##    READ BEFORE CHANGING THIS    ##
-#####################################
-
-# We're in the process of evaluating GitHub Actions as a possible replacement
-# for Azure Pipelines, and at the moment the configuration is duplicated
-# between the two CI providers. Be sure to also change the configuration in
-# src/ci/github-actions when changing this file.
-
-#####################################
-
-#
-# Azure Pipelines job to publish toolstate. Only triggers on pushes to master.
-#
-
-pr: none
-trigger:
-  - master
-
-variables:
-- group: dummy-credentials
-
-pool:
-  vmImage: ubuntu-16.04
-
-steps:
-- checkout: self
-  fetchDepth: 2
-
-- script: src/ci/publish_toolstate.sh
-  displayName: Publish toolstate
-  env:
-    TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN)
diff --git a/src/ci/azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml
deleted file mode 100644 (file)
index 1fc8d18..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#####################################
-##    READ BEFORE CHANGING THIS    ##
-#####################################
-
-# We're in the process of evaluating GitHub Actions as a possible replacement
-# for Azure Pipelines, and at the moment the configuration is duplicated
-# between the two CI providers. Be sure to also change the configuration in
-# src/ci/github-actions when changing this file.
-
-#####################################
-
-#
-# Azure Pipelines pull request build for Rust
-#
-
-trigger: none
-pr:
-- master
-
-variables:
-- group: public-credentials
-
-jobs:
-- job: Linux
-  timeoutInMinutes: 600
-  pool:
-    vmImage: ubuntu-16.04
-  steps:
-    - template: steps/run.yml
-  strategy:
-    matrix:
-      x86_64-gnu-llvm-8: {}
-      mingw-check: {}
-      x86_64-gnu-tools:
-        CI_ONLY_WHEN_SUBMODULES_CHANGED: 1
index eebc5ccdaf69cfbf4476286513c14af2843c0bc1..62bb6f47334123f79f34d6d77bd552ba99ea2900 100644 (file)
@@ -13,70 +13,10 @@ pr: none
 trigger:
 - try
 
-variables:
-- group: dummy-credentials
-
 jobs:
-- job: Linux
+- job: Dummy
   timeoutInMinutes: 600
   pool:
     vmImage: ubuntu-16.04
   steps:
-  - template: steps/run.yml
-  strategy:
-    matrix:
-      dist-x86_64-linux: {}
-
-# The macOS and Windows builds here are currently disabled due to them not being
-# overly necessary on `try` builds. We also don't actually have anything that
-# consumes the artifacts currently. Perhaps one day we can re-enable, but for now
-# it helps free up capacity on Azure.
-# - job: macOS
-#   timeoutInMinutes: 600
-#   pool:
-#     vmImage: macos-10.15
-#   steps:
-#   - template: steps/run.yml
-#   strategy:
-#     matrix:
-#       dist-x86_64-apple:
-#         SCRIPT: ./x.py dist
-#         INITIAL_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
-#         NO_LLVM_ASSERTIONS: 1
-#         NO_DEBUG_ASSERTIONS: 1
-#         DIST_REQUIRE_ALL_TOOLS: 1
-#
-#       dist-x86_64-apple-alt:
-#         SCRIPT: ./x.py dist
-#         INITIAL_RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc
-#         DEPLOY_ALT: 1
-#         RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-#         MACOSX_DEPLOYMENT_TARGET: 10.7
-#         NO_LLVM_ASSERTIONS: 1
-#         NO_DEBUG_ASSERTIONS: 1
-#
-# - job: Windows
-#   timeoutInMinutes: 600
-#   pool:
-#     vmImage: 'vs2017-win2016'
-#   steps:
-#   - template: steps/run.yml
-#   strategy:
-#     matrix:
-#       dist-x86_64-msvc:
-#         INITIAL_RUST_CONFIGURE_ARGS: >
-#           --build=x86_64-pc-windows-msvc
-#           --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
-#           --enable-full-tools
-#           --enable-profiler
-#         SCRIPT: python x.py dist
-#         DIST_REQUIRE_ALL_TOOLS: 1
-#         DEPLOY: 1
-#
-#       dist-x86_64-msvc-alt:
-#         INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
-#         SCRIPT: python x.py dist
-#         DEPLOY_ALT: 1
+  - bash: echo "We're running this job since bors is still gating on Azure"
index 425e34f1af624b91f89d594c0dbd34205b6d41a3..0aeb6a04e5f773ec8d12ef17351ba9ef77f5d88f 100644 (file)
@@ -247,6 +247,7 @@ on:
     branches:
       - auto
       - try
+      - try-perf
       - master
   pull_request:
     branches:
@@ -285,7 +286,7 @@ jobs:
     name: try
     env:
       <<: [*shared-ci-variables, *prod-variables]
-    if: github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'
+    if: github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'
     strategy:
       matrix:
         include:
@@ -645,11 +646,11 @@ jobs:
   # successful listening to webhooks only.
   try-success:
     needs: [try]
-    if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'"
+    if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
     <<: *base-success-job
   try-failure:
     needs: [try]
-    if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'"
+    if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
     <<: *base-failure-job
   auto-success:
     needs: [auto]
index 84a31397b34f9d405df44f2899ff17a4828dba18..a914f2c7e5cdb771fa465de142381a51c53b580e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 84a31397b34f9d405df44f2899ff17a4828dba18
+Subproject commit a914f2c7e5cdb771fa465de142381a51c53b580e
index 82bec5877c77cfad530ca11095db4456d757f668..bd6e4a9f59c5c1545f572266af77f5c7a5bad6d1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 82bec5877c77cfad530ca11095db4456d757f668
+Subproject commit bd6e4a9f59c5c1545f572266af77f5c7a5bad6d1
index 0ea7bc494f1289234d8800bb9185021e0ad946f0..b329ce37424874ad4db94f829a55807c6e21d2cb 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0ea7bc494f1289234d8800bb9185021e0ad946f0
+Subproject commit b329ce37424874ad4db94f829a55807c6e21d2cb
index 0b4bb05c1db23e66ead131d085b9ced6d7bf9141..35904e15d3feeaa596f58772a70bcd92fb1cd848 100644 (file)
@@ -42,6 +42,18 @@ generated code, but may be slower to compile.
 The default value, if not specified, is 16 for non-incremental builds. For
 incremental builds the default is 256 which allows caching to be more granular.
 
+## control-flow-guard
+
+This flag controls whether LLVM enables the Windows [Control Flow 
+Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) 
+platform security feature. This flag is currently ignored for non-Windows targets. 
+It takes one of the following values:
+
+* `y`, `yes`, `on`, `checks`, or no value: enable Control Flow Guard.
+* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this 
+should only be used for testing purposes as it does not provide security enforcement).
+* `n`, `no`, `off`: do not enable Control Flow Guard (the default).
+
 ## debug-assertions
 
 This flag lets you turn `cfg(debug_assertions)` [conditional
index 15f10df9a45cc097b6fe5c2160d2efa6814ee898..f41c8c5a5591054c6c89d6ecc1e6108c94acd7c1 100644 (file)
@@ -65,7 +65,7 @@
 ///
 /// # Examples
 ///
-/// You can create a `String` from [a literal string][str] with [`String::from`]:
+/// You can create a `String` from [a literal string][`str`] with [`String::from`]:
 ///
 /// [`String::from`]: From::from
 ///
 ///
 /// Here, there's no need to allocate more memory inside the loop.
 ///
-/// [`&str`]: str
+/// [`str`]: type@str
+/// [`&str`]: type@str
 /// [`Deref`]: core::ops::Deref
 /// [`as_str()`]: String::as_str
 #[derive(PartialOrd, Eq, Ord)]
index 94f7ff5c1f7fe7864f6bf1fd0399ae7d8b568eef..03b798d57db9bcf37ba50b1ba515730782f2e7bd 100644 (file)
@@ -677,7 +677,7 @@ fn as_ref(&self) -> &str {
 ///
 ///
 /// However there is one case where `!` syntax can be used
-/// before `!` is stabilized as a full-fleged type: in the position of a function’s return type.
+/// before `!` is stabilized as a full-fledged type: in the position of a function’s return type.
 /// Specifically, it is possible implementations for two different function pointer types:
 ///
 /// ```
index f2bbf646f3272b87d1c5beb7e8b22721f985abce..a9882d54de4f18b3e47d86ce132d760c852e2ab6 100644 (file)
@@ -43,7 +43,7 @@ struct SipHasher24 {
 ///
 /// SipHash is a general-purpose hashing function: it runs at a good
 /// speed (competitive with Spooky and City) and permits strong _keyed_
-/// hashing. This lets you key your hashtables from a strong RNG, such as
+/// hashing. This lets you key your hash tables from a strong RNG, such as
 /// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).
 ///
 /// Although the SipHash algorithm is considered to be generally strong,
index 049f51fb1035a3d2a3ea4496135eff651a85fa51..1af4f1009d1ac86e94d3c2d49e62d3db44a93a25 100644 (file)
@@ -15,7 +15,7 @@
 //!
 //! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
 //! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done
-//! without T-lang consulation, because it bakes a feature into the language that cannot be
+//! without T-lang consultation, because it bakes a feature into the language that cannot be
 //! replicated in user code without compiler support.
 //!
 //! # Volatiles
     /// [`std::mem::align_of`](../../std/mem/fn.align_of.html).
     #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
     pub fn min_align_of<T>() -> usize;
-    /// The prefered alignment of a type.
+    /// The preferred alignment of a type.
     ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_pref_align_of", issue = "none")]
     ///     assert!(mid <= len);
     ///     unsafe {
     ///         let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
-    ///         // first: transmute is not typesafe; all it checks is that T and
+    ///         // first: transmute is not type safe; all it checks is that T and
     ///         // U are of the same size. Second, right here, you have two
     ///         // mutable references pointing to the same memory.
     ///         (&mut slice[0..mid], &mut slice2[mid..len])
     ///     }
     /// }
     ///
-    /// // This gets rid of the typesafety problems; `&mut *` will *only* give
+    /// // This gets rid of the type safety problems; `&mut *` will *only* give
     /// // you an `&mut T` from an `&mut T` or `*mut T`.
     /// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
     ///                          -> (&mut [T], &mut [T]) {
index b8faeb488e72d3cf776f324498c170d1cc6f319d..3ea3eeed6b0434f3f4f5fc7b3b5569051a255249 100644 (file)
@@ -1069,7 +1069,7 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     /// let vec = iter.collect::<Vec<_>>();
     ///
     /// // We have more elements which could fit in u32 (4, 5), but `map_while` returned `None` for `-3`
-    /// // (as the `predicate` returned `None`) and `collect` stops at the first `None` entcountered.
+    /// // (as the `predicate` returned `None`) and `collect` stops at the first `None` encountered.
     /// assert_eq!(vec, vec![0, 1, 2]);
     /// ```
     ///
index 4ac366ab16408eb3de7c8d60359a9cd5fb8dbd05..3b9057b7e8377911feec5d30b98e163a787d0fab 100644 (file)
@@ -1047,7 +1047,7 @@ macro_rules! stringify {
         };
     }
 
-    /// Includes a utf8-encoded file as a string.
+    /// Includes a UTF-8 encoded file as a string.
     ///
     /// The file is located relative to the current file (similarly to how
     /// modules are found). The provided path is interpreted in a platform-specific
index d62de7617a00df5de0e4161462237247644e6a36..6ff7baab70f61eee903dde10278c4e06dcdeabe1 100644 (file)
@@ -348,11 +348,11 @@ pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
 ///
 /// - If `T` is `Sized`, this function is always safe to call.
 /// - If the unsized tail of `T` is:
-///     - a [slice], then the length of the slice tail must be an intialized
+///     - a [slice], then the length of the slice tail must be an initialized
 ///       integer, and the size of the *entire value*
 ///       (dynamic tail length + statically sized prefix) must fit in `isize`.
 ///     - a [trait object], then the vtable part of the pointer must point
-///       to a valid vtable acquired by an unsizing coersion, and the size
+///       to a valid vtable acquired by an unsizing coercion, and the size
 ///       of the *entire value* (dynamic tail length + statically sized prefix)
 ///       must fit in `isize`.
 ///     - an (unstable) [extern type], then this function is always safe to
@@ -483,11 +483,11 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
 ///
 /// - If `T` is `Sized`, this function is always safe to call.
 /// - If the unsized tail of `T` is:
-///     - a [slice], then the length of the slice tail must be an intialized
+///     - a [slice], then the length of the slice tail must be an initialized
 ///       integer, and the size of the *entire value*
 ///       (dynamic tail length + statically sized prefix) must fit in `isize`.
 ///     - a [trait object], then the vtable part of the pointer must point
-///       to a valid vtable acquired by an unsizing coersion, and the size
+///       to a valid vtable acquired by an unsizing coercion, and the size
 ///       of the *entire value* (dynamic tail length + statically sized prefix)
 ///       must fit in `isize`.
 ///     - an (unstable) [extern type], then this function is always safe to
index bcb6cd4084691da478fb7e2ebc4175b6b564d8a9..a5b1eb3f1fd67c61adcc65d041319bc7b88f6f29 100644 (file)
@@ -687,7 +687,7 @@ pub fn to_bits(self) -> u64 {
     /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
     ///
     /// Rather than trying to preserve signaling-ness cross-platform, this
-    /// implementation favours preserving the exact bits. This means that
+    /// implementation favors preserving the exact bits. This means that
     /// any payloads encoded in NaNs will be preserved even if the result of
     /// this method is sent over the network from an x86 machine to a MIPS one.
     ///
@@ -696,7 +696,7 @@ pub fn to_bits(self) -> u64 {
     ///
     /// If the input isn't NaN, then there is no portability concern.
     ///
-    /// If you don't care about signalingness (very likely), then there is no
+    /// If you don't care about signaling-ness (very likely), then there is no
     /// portability concern.
     ///
     /// Note that this function is distinct from `as` casting, which attempts to
index da299f026f8f16c87f0d7dd4f64fe3e62f37491b..9bcacd8ddcf77ee54bb950f8a9dcff1d280fbf6d 100644 (file)
 //!
 //! 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.
+//! from its neighboring elements would become invalid, which would break the data structure.
 //!
 //! Therefore, pinning also comes with a [`drop`]-related guarantee.
 //!
index 896ad740e1e692424a695f23fc0ca04576d326a8..a2acc239bd38f942da26c334b1254e4a6a24db00 100644 (file)
@@ -331,13 +331,13 @@ pub const fn guaranteed_eq(self, other: *const T) -> bool
         intrinsics::ptr_guaranteed_eq(self, other)
     }
 
-    /// Returns whether two pointers are guaranteed to be inequal.
+    /// Returns whether two pointers are guaranteed to be unequal.
     ///
     /// At runtime this function behaves like `self != other`.
     /// However, in some contexts (e.g., compile-time evaluation),
     /// it is not always possible to determine the inequality of two pointers, so this function may
-    /// spuriously return `false` for pointers that later actually turn out to be inequal.
-    /// But when it returns `true`, the pointers are guaranteed to be inequal.
+    /// spuriously return `false` for pointers that later actually turn out to be unequal.
+    /// But when it returns `true`, the pointers are guaranteed to be unequal.
     ///
     /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
     /// comparisons for which both functions return `false`.
index 96856e7512cabdcf5cad84e732ad9de4f30c543c..17fa90ecc08b5c81acc3e672bf9f3a6db429178d 100644 (file)
@@ -47,17 +47,22 @@ pub const fn cast<U>(self) -> *mut U {
     /// operation because the returned value could be pointing to invalid
     /// memory.
     ///
-    /// When calling this method, you have to ensure that if the pointer is
-    /// non-NULL, then it is properly aligned, dereferenceable (for the whole
-    /// size of `T`) and points to an initialized instance of `T`. This applies
-    /// even if the result of this method is unused!
+    /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+    /// all of the following is true:
+    /// - it is properly aligned
+    /// - it must point to an initialized instance of T; in particular, the pointer must be
+    ///   "dereferencable" in the sense defined [here].
+    ///
+    /// This applies even if the result of this method is unused!
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
     ///
     /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
-    /// not necessarily reflect the actual lifetime of the data. It is up to the
-    /// caller to ensure that for the duration of this lifetime, the memory this
-    /// pointer points to does not get written to outside of `UnsafeCell<U>`.
+    /// not necessarily reflect the actual lifetime of the data. *You* must enforce
+    /// Rust's aliasing rules. In particular, for the duration of this lifetime,
+    /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
+    ///
+    /// [here]: crate::ptr#safety
     ///
     /// # Examples
     ///
@@ -312,13 +317,13 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool
         intrinsics::ptr_guaranteed_eq(self as *const _, other as *const _)
     }
 
-    /// Returns whether two pointers are guaranteed to be inequal.
+    /// Returns whether two pointers are guaranteed to be unequal.
     ///
     /// At runtime this function behaves like `self != other`.
     /// However, in some contexts (e.g., compile-time evaluation),
     /// it is not always possible to determine the inequality of two pointers, so this function may
-    /// spuriously return `false` for pointers that later actually turn out to be inequal.
-    /// But when it returns `true`, the pointers are guaranteed to be inequal.
+    /// spuriously return `false` for pointers that later actually turn out to be unequal.
+    /// But when it returns `true`, the pointers are guaranteed to be unequal.
     ///
     /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
     /// comparisons for which both functions return `false`.
index b362a49d604e7ffd2a3ccdecee89c4f33c17f440..9f843a570990d615b795f7233734686b42675ed2 100644 (file)
@@ -172,7 +172,7 @@ impl<T> NonNull<[T]> {
     /// assert_eq!(unsafe { slice.as_ref()[2] }, 7);
     /// ```
     ///
-    /// (Note that this example artifically demonstrates a use of this method,
+    /// (Note that this example artificially demonstrates a use of this method,
     /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.)
     #[unstable(feature = "nonnull_slice_from_raw_parts", issue = "71941")]
     #[rustc_const_unstable(feature = "const_nonnull_slice_from_raw_parts", issue = "71941")]
index 0d36bd0b39d76b69a3f7e835e5e5c579828425f4..899f923b957fe3af07644fe48f79a65d5adc53dc 100644 (file)
@@ -1,6 +1,5 @@
 [package]
 authors = ["The Rust Project Developers"]
-build = "build.rs"
 name = "profiler_builtins"
 version = "0.0.0"
 edition = "2018"
index bb7d59e113c08a29fc9c61e26383c668adb577e7..d2cb873058c282f14f04317fe77e4cc6e46554b1 100644 (file)
@@ -9,6 +9,8 @@ fn main() {
     let target = env::var("TARGET").expect("TARGET was not set");
     let cfg = &mut cc::Build::new();
 
+    // FIXME: `rerun-if-changed` directives are not currently emitted and the build script
+    // will not rerun on changes in these source files or headers included into them.
     let mut profile_sources = vec![
         "GCDAProfiling.c",
         "InstrProfiling.c",
diff --git a/src/librustc_ast/build.rs b/src/librustc_ast/build.rs
deleted file mode 100644 (file)
index 9b861f9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL");
-    println!("cargo:rerun-if-env-changed=CFG_DISABLE_UNSTABLE_FEATURES");
-}
index 975881d9a0ac0c898895c5318320f3dd6f9660a0..daf3e23d6a1234c2196fe76286000f792f60976c 100644 (file)
@@ -1118,13 +1118,26 @@ fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
     fn visit_generics(&mut self, generics: &'a Generics) {
         let mut prev_ty_default = None;
         for param in &generics.params {
-            if let GenericParamKind::Type { ref default, .. } = param.kind {
-                if default.is_some() {
+            match param.kind {
+                GenericParamKind::Lifetime => (),
+                GenericParamKind::Type { default: Some(_), .. } => {
                     prev_ty_default = Some(param.ident.span);
-                } else if let Some(span) = prev_ty_default {
-                    self.err_handler()
-                        .span_err(span, "type parameters with a default must be trailing");
-                    break;
+                }
+                GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
+                    if let Some(span) = prev_ty_default {
+                        let mut err = self.err_handler().struct_span_err(
+                            span,
+                            "type parameters with a default must be trailing",
+                        );
+                        if matches!(param.kind, GenericParamKind::Const { .. }) {
+                            err.note(
+                                "using type defaults and const parameters \
+                                 in the same parameter list is currently not permitted",
+                            );
+                        }
+                        err.emit();
+                        break;
+                    }
                 }
             }
         }
index 677796a8df0b37a89cc427c8754d7b8b190df517..496becb8f1b5948235438afe758fdc9db0282829 100644 (file)
@@ -3,7 +3,6 @@ authors = ["The Rust Project Developers"]
 name = "rustc_attr"
 version = "0.0.0"
 edition = "2018"
-build = "build.rs"
 
 [lib]
 name = "rustc_attr"
diff --git a/src/librustc_attr/build.rs b/src/librustc_attr/build.rs
deleted file mode 100644 (file)
index 863f2b7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_RELEASE");
-    println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL");
-}
index 0606fac2fe748f17aa13ee7e078ab363f146ecb6..1e088b52dcc35b5fffb03d09cde40843b6801e81 100644 (file)
@@ -124,13 +124,11 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
 ///
 /// - `#[stable]`
 /// - `#[unstable]`
-/// - `#[rustc_deprecated]`
 #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[derive(HashStable_Generic)]
 pub struct Stability {
     pub level: StabilityLevel,
     pub feature: Symbol,
-    pub rustc_depr: Option<RustcDeprecation>,
 }
 
 /// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
@@ -163,15 +161,6 @@ pub fn is_stable(&self) -> bool {
     }
 }
 
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
-#[derive(HashStable_Generic)]
-pub struct RustcDeprecation {
-    pub since: Symbol,
-    pub reason: Symbol,
-    /// A text snippet used to completely replace any use of the deprecated item in an expression.
-    pub suggestion: Option<Symbol>,
-}
-
 /// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`.
 /// This will not perform any "sanity checks" on the form of the attributes.
 pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
@@ -205,7 +194,6 @@ fn find_stability_generic<'a, I>(
     use StabilityLevel::*;
 
     let mut stab: Option<Stability> = None;
-    let mut rustc_depr: Option<RustcDeprecation> = None;
     let mut const_stab: Option<ConstStability> = None;
     let mut promotable = false;
     let mut allow_const_fn_ptr = false;
@@ -213,7 +201,6 @@ fn find_stability_generic<'a, I>(
 
     'outer: for attr in attrs_iter {
         if ![
-            sym::rustc_deprecated,
             sym::rustc_const_unstable,
             sym::rustc_const_stable,
             sym::unstable,
@@ -258,76 +245,8 @@ fn find_stability_generic<'a, I>(
                 }
             };
 
-            macro_rules! get_meta {
-                ($($name:ident),+) => {
-                    $(
-                        let mut $name = None;
-                    )+
-                    for meta in metas {
-                        if let Some(mi) = meta.meta_item() {
-                            match mi.name_or_empty() {
-                                $(
-                                    sym::$name => if !get(mi, &mut $name) { continue 'outer },
-                                )+
-                                _ => {
-                                    let expected = &[ $( stringify!($name) ),+ ];
-                                    handle_errors(
-                                        sess,
-                                        mi.span,
-                                        AttrError::UnknownMetaItem(
-                                            pprust::path_to_string(&mi.path),
-                                            expected,
-                                        ),
-                                    );
-                                    continue 'outer
-                                }
-                            }
-                        } else {
-                            handle_errors(
-                                sess,
-                                meta.span(),
-                                AttrError::UnsupportedLiteral(
-                                    "unsupported literal",
-                                    false,
-                                ),
-                            );
-                            continue 'outer
-                        }
-                    }
-                }
-            }
-
             let meta_name = meta.name_or_empty();
             match meta_name {
-                sym::rustc_deprecated => {
-                    if rustc_depr.is_some() {
-                        struct_span_err!(
-                            diagnostic,
-                            item_sp,
-                            E0540,
-                            "multiple rustc_deprecated attributes"
-                        )
-                        .emit();
-                        continue 'outer;
-                    }
-
-                    get_meta!(since, reason, suggestion);
-
-                    match (since, reason) {
-                        (Some(since), Some(reason)) => {
-                            rustc_depr = Some(RustcDeprecation { since, reason, suggestion })
-                        }
-                        (None, _) => {
-                            handle_errors(sess, attr.span, AttrError::MissingSince);
-                            continue;
-                        }
-                        _ => {
-                            struct_span_err!(diagnostic, attr.span, E0543, "missing 'reason'")
-                                .emit();
-                            continue;
-                        }
-                    }
-                }
                 sym::rustc_const_unstable | sym::unstable => {
                     if meta_name == sym::unstable && stab.is_some() {
                         handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
@@ -429,7 +348,7 @@ macro_rules! get_meta {
                         (Some(feature), reason, Some(_)) => {
                             let level = Unstable { reason, issue: issue_num, is_soft };
                             if sym::unstable == meta_name {
-                                stab = Some(Stability { level, feature, rustc_depr: None });
+                                stab = Some(Stability { level, feature });
                             } else {
                                 const_stab = Some(ConstStability {
                                     level,
@@ -501,7 +420,7 @@ macro_rules! get_meta {
                         (Some(feature), Some(since)) => {
                             let level = Stable { since };
                             if sym::stable == meta_name {
-                                stab = Some(Stability { level, feature, rustc_depr: None });
+                                stab = Some(Stability { level, feature });
                             } else {
                                 const_stab = Some(ConstStability {
                                     level,
@@ -526,22 +445,6 @@ macro_rules! get_meta {
         }
     }
 
-    // Merge the deprecation info into the stability info
-    if let Some(rustc_depr) = rustc_depr {
-        if let Some(ref mut stab) = stab {
-            stab.rustc_depr = Some(rustc_depr);
-        } else {
-            struct_span_err!(
-                diagnostic,
-                item_sp,
-                E0549,
-                "rustc_deprecated attribute must be paired with \
-                       either stable or unstable attribute"
-            )
-            .emit();
-        }
-    }
-
     // Merge the const-unstable info into the stability info
     if promotable || allow_const_fn_ptr {
         if let Some(ref mut stab) = const_stab {
@@ -714,7 +617,16 @@ pub fn eval_condition(
 #[derive(RustcEncodable, RustcDecodable, Clone, HashStable_Generic)]
 pub struct Deprecation {
     pub since: Option<Symbol>,
+    /// The note to issue a reason.
     pub note: Option<Symbol>,
+    /// A text snippet used to completely replace any use of the deprecated item in an expression.
+    ///
+    /// This is currently unstable.
+    pub suggestion: Option<Symbol>,
+
+    /// Whether to treat the since attribute as being a Rust version identifier
+    /// (rather than an opaque string).
+    pub is_since_rustc_version: bool,
 }
 
 /// Finds the deprecation attribute. `None` if none exists.
@@ -738,7 +650,7 @@ fn find_deprecation_generic<'a, I>(
     let diagnostic = &sess.span_diagnostic;
 
     'outer: for attr in attrs_iter {
-        if !attr.check_name(sym::deprecated) {
+        if !(attr.check_name(sym::deprecated) || attr.check_name(sym::rustc_deprecated)) {
             continue;
         }
 
@@ -751,11 +663,12 @@ fn find_deprecation_generic<'a, I>(
             Some(meta) => meta,
             None => continue,
         };
-        depr = match &meta.kind {
-            MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
-            MetaItemKind::NameValue(..) => {
-                meta.value_str().map(|note| Deprecation { since: None, note: Some(note) })
-            }
+        let mut since = None;
+        let mut note = None;
+        let mut suggestion = None;
+        match &meta.kind {
+            MetaItemKind::Word => {}
+            MetaItemKind::NameValue(..) => note = meta.value_str(),
             MetaItemKind::List(list) => {
                 let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
                     if item.is_some() {
@@ -789,8 +702,6 @@ fn find_deprecation_generic<'a, I>(
                     }
                 };
 
-                let mut since = None;
-                let mut note = None;
                 for meta in list {
                     match meta {
                         NestedMetaItem::MetaItem(mi) => match mi.name_or_empty() {
@@ -799,18 +710,32 @@ fn find_deprecation_generic<'a, I>(
                                     continue 'outer;
                                 }
                             }
-                            sym::note => {
+                            sym::note if attr.check_name(sym::deprecated) => {
+                                if !get(mi, &mut note) {
+                                    continue 'outer;
+                                }
+                            }
+                            sym::reason if attr.check_name(sym::rustc_deprecated) => {
                                 if !get(mi, &mut note) {
                                     continue 'outer;
                                 }
                             }
+                            sym::suggestion if attr.check_name(sym::rustc_deprecated) => {
+                                if !get(mi, &mut suggestion) {
+                                    continue 'outer;
+                                }
+                            }
                             _ => {
                                 handle_errors(
                                     sess,
                                     meta.span(),
                                     AttrError::UnknownMetaItem(
                                         pprust::path_to_string(&mi.path),
-                                        &["since", "note"],
+                                        if attr.check_name(sym::deprecated) {
+                                            &["since", "note"]
+                                        } else {
+                                            &["since", "reason", "suggestion"]
+                                        },
                                     ),
                                 );
                                 continue 'outer;
@@ -829,10 +754,29 @@ fn find_deprecation_generic<'a, I>(
                         }
                     }
                 }
+            }
+        }
+
+        if suggestion.is_some() && attr.check_name(sym::deprecated) {
+            unreachable!("only allowed on rustc_deprecated")
+        }
 
-                Some(Deprecation { since, note })
+        if attr.check_name(sym::rustc_deprecated) {
+            if since.is_none() {
+                handle_errors(sess, attr.span, AttrError::MissingSince);
+                continue;
             }
-        };
+
+            if note.is_none() {
+                struct_span_err!(diagnostic, attr.span, E0543, "missing 'reason'").emit();
+                continue;
+            }
+        }
+
+        mark_used(&attr);
+
+        let is_since_rustc_version = attr.check_name(sym::rustc_deprecated);
+        depr = Some(Deprecation { since, note, suggestion, is_since_rustc_version });
     }
 
     depr
diff --git a/src/librustc_codegen_llvm/build.rs b/src/librustc_codegen_llvm/build.rs
deleted file mode 100644 (file)
index d1fc624..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_VERSION");
-    println!("cargo:rerun-if-env-changed=CFG_PREFIX");
-    println!("cargo:rerun-if-env-changed=CFG_LLVM_ROOT");
-}
index d58aad340a1dcbc57044edd5f0b473098b84cfbd..8a1bb258d4274480afd58fa175e64fd129fcdd8a 100644 (file)
@@ -1330,7 +1330,12 @@ fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Si
         self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
     }
 
-    fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
+    pub(crate) fn phi(
+        &mut self,
+        ty: &'ll Type,
+        vals: &[&'ll Value],
+        bbs: &[&'ll BasicBlock],
+    ) -> &'ll Value {
         assert_eq!(vals.len(), bbs.len());
         let phi = unsafe { llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED) };
         unsafe {
index 21ba97d15a485776362716ed8b84b6c946cd1f8d..33a3cdbfa9b443ff638b5e51d4f9c6bd3b851450 100644 (file)
@@ -190,7 +190,7 @@ pub unsafe fn create_module(
 
     // Control Flow Guard is currently only supported by the MSVC linker on Windows.
     if sess.target.target.options.is_like_msvc {
-        match sess.opts.debugging_opts.control_flow_guard {
+        match sess.opts.cg.control_flow_guard {
             CFGuard::Disabled => {}
             CFGuard::NoChecks => {
                 // Set `cfguard=1` module flag to emit metadata only.
@@ -510,6 +510,14 @@ macro_rules! vector_types {
         ifn!("llvm.wasm.trunc.saturate.signed.i32.f64", fn(t_f64) -> t_i32);
         ifn!("llvm.wasm.trunc.saturate.signed.i64.f32", fn(t_f32) -> t_i64);
         ifn!("llvm.wasm.trunc.saturate.signed.i64.f64", fn(t_f64) -> t_i64);
+        ifn!("llvm.wasm.trunc.unsigned.i32.f32", fn(t_f32) -> t_i32);
+        ifn!("llvm.wasm.trunc.unsigned.i32.f64", fn(t_f64) -> t_i32);
+        ifn!("llvm.wasm.trunc.unsigned.i64.f32", fn(t_f32) -> t_i64);
+        ifn!("llvm.wasm.trunc.unsigned.i64.f64", fn(t_f64) -> t_i64);
+        ifn!("llvm.wasm.trunc.signed.i32.f32", fn(t_f32) -> t_i32);
+        ifn!("llvm.wasm.trunc.signed.i32.f64", fn(t_f64) -> t_i32);
+        ifn!("llvm.wasm.trunc.signed.i64.f32", fn(t_f32) -> t_i64);
+        ifn!("llvm.wasm.trunc.signed.i64.f64", fn(t_f64) -> t_i64);
 
         ifn!("llvm.trap", fn() -> void);
         ifn!("llvm.debugtrap", fn() -> void);
index 2e5929a433de040cb8b49e0f1e78355a096bf170..11b1c95c58b3e14e10dfb341bb1ccea0752fe4a5 100644 (file)
@@ -629,27 +629,24 @@ fn codegen_intrinsic_call(
             }
 
             sym::float_to_int_unchecked => {
-                if float_type_width(arg_tys[0]).is_none() {
-                    span_invalid_monomorphization_error(
-                        tcx.sess,
-                        span,
-                        &format!(
-                            "invalid monomorphization of `float_to_int_unchecked` \
+                let float_width = match float_type_width(arg_tys[0]) {
+                    Some(width) => width,
+                    None => {
+                        span_invalid_monomorphization_error(
+                            tcx.sess,
+                            span,
+                            &format!(
+                                "invalid monomorphization of `float_to_int_unchecked` \
                                   intrinsic: expected basic float type, \
                                   found `{}`",
-                            arg_tys[0]
-                        ),
-                    );
-                    return;
-                }
-                match int_type_width_signed(ret_ty, self.cx) {
-                    Some((width, signed)) => {
-                        if signed {
-                            self.fptosi(args[0].immediate(), self.cx.type_ix(width))
-                        } else {
-                            self.fptoui(args[0].immediate(), self.cx.type_ix(width))
-                        }
+                                arg_tys[0]
+                            ),
+                        );
+                        return;
                     }
+                };
+                let (width, signed) = match int_type_width_signed(ret_ty, self.cx) {
+                    Some(pair) => pair,
                     None => {
                         span_invalid_monomorphization_error(
                             tcx.sess,
@@ -663,7 +660,49 @@ fn codegen_intrinsic_call(
                         );
                         return;
                     }
+                };
+
+                // The LLVM backend can reorder and speculate `fptosi` and
+                // `fptoui`, so on WebAssembly the codegen for this instruction
+                // is quite heavyweight. To avoid this heavyweight codegen we
+                // instead use the raw wasm intrinsics which will lower to one
+                // instruction in WebAssembly (`iNN.trunc_fMM_{s,u}`). This one
+                // instruction will trap if the operand is out of bounds, but
+                // that's ok since this intrinsic is UB if the operands are out
+                // of bounds, so the behavior can be different on WebAssembly
+                // than other targets.
+                //
+                // Note, however, that when the `nontrapping-fptoint` feature is
+                // enabled in LLVM then LLVM will lower `fptosi` to
+                // `iNN.trunc_sat_fMM_{s,u}`, so if that's the case we don't
+                // bother with intrinsics.
+                let mut result = None;
+                if self.sess().target.target.arch == "wasm32"
+                    && !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
+                {
+                    let name = match (width, float_width, signed) {
+                        (32, 32, true) => Some("llvm.wasm.trunc.signed.i32.f32"),
+                        (32, 64, true) => Some("llvm.wasm.trunc.signed.i32.f64"),
+                        (64, 32, true) => Some("llvm.wasm.trunc.signed.i64.f32"),
+                        (64, 64, true) => Some("llvm.wasm.trunc.signed.i64.f64"),
+                        (32, 32, false) => Some("llvm.wasm.trunc.unsigned.i32.f32"),
+                        (32, 64, false) => Some("llvm.wasm.trunc.unsigned.i32.f64"),
+                        (64, 32, false) => Some("llvm.wasm.trunc.unsigned.i64.f32"),
+                        (64, 64, false) => Some("llvm.wasm.trunc.unsigned.i64.f64"),
+                        _ => None,
+                    };
+                    if let Some(name) = name {
+                        let intrinsic = self.get_intrinsic(name);
+                        result = Some(self.call(intrinsic, &[args[0].immediate()], None));
+                    }
                 }
+                result.unwrap_or_else(|| {
+                    if signed {
+                        self.fptosi(args[0].immediate(), self.cx.type_ix(width))
+                    } else {
+                        self.fptoui(args[0].immediate(), self.cx.type_ix(width))
+                    }
+                })
             }
 
             sym::discriminant_value => {
index 8bc3579800ea81380214b01e823161a28bb8454b..54efa05aee81e315ea619eebb3b2bc827603f15d 100644 (file)
@@ -3,8 +3,9 @@
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 use rustc_codegen_ssa::mir::operand::OperandRef;
-use rustc_codegen_ssa::traits::{
-    BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods,
+use rustc_codegen_ssa::{
+    common::IntPredicate,
+    traits::{BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods},
 };
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::Ty;
@@ -89,6 +90,81 @@ fn emit_ptr_va_arg(
     }
 }
 
+fn emit_aapcs_va_arg(
+    bx: &mut Builder<'a, 'll, 'tcx>,
+    list: OperandRef<'tcx, &'ll Value>,
+    target_ty: Ty<'tcx>,
+) -> &'ll Value {
+    // Implementation of the AAPCS64 calling convention for va_args see
+    // https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst
+    let va_list_addr = list.immediate();
+    let layout = bx.cx.layout_of(target_ty);
+
+    let mut maybe_reg = bx.build_sibling_block("va_arg.maybe_reg");
+    let mut in_reg = bx.build_sibling_block("va_arg.in_reg");
+    let mut on_stack = bx.build_sibling_block("va_arg.on_stack");
+    let mut end = bx.build_sibling_block("va_arg.end");
+    let zero = bx.const_i32(0);
+    let offset_align = Align::from_bytes(4).unwrap();
+    assert!(&*bx.tcx().sess.target.target.target_endian == "little");
+
+    let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
+    let (reg_off, reg_top_index, slot_size) = if gr_type {
+        let gr_offs = bx.struct_gep(va_list_addr, 7);
+        let nreg = (layout.size.bytes() + 7) / 8;
+        (gr_offs, 3, nreg * 8)
+    } else {
+        let vr_off = bx.struct_gep(va_list_addr, 9);
+        let nreg = (layout.size.bytes() + 15) / 16;
+        (vr_off, 5, nreg * 16)
+    };
+
+    // if the offset >= 0 then the value will be on the stack
+    let mut reg_off_v = bx.load(reg_off, offset_align);
+    let use_stack = bx.icmp(IntPredicate::IntSGE, reg_off_v, zero);
+    bx.cond_br(use_stack, &on_stack.llbb(), &maybe_reg.llbb());
+
+    // The value at this point might be in a register, but there is a chance that
+    // it could be on the stack so we have to update the offset and then check
+    // the offset again.
+
+    if gr_type && layout.align.abi.bytes() > 8 {
+        reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(15));
+        reg_off_v = maybe_reg.and(reg_off_v, bx.const_i32(-16));
+    }
+    let new_reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(slot_size as i32));
+
+    maybe_reg.store(new_reg_off_v, reg_off, offset_align);
+
+    // Check to see if we have overflowed the registers as a result of this.
+    // If we have then we need to use the stack for this value
+    let use_stack = maybe_reg.icmp(IntPredicate::IntSGT, new_reg_off_v, zero);
+    maybe_reg.cond_br(use_stack, &on_stack.llbb(), &in_reg.llbb());
+
+    let top = in_reg.struct_gep(va_list_addr, reg_top_index);
+    let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi);
+
+    // reg_value = *(@top + reg_off_v);
+    let top = in_reg.gep(top, &[reg_off_v]);
+    let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx)));
+    let reg_value = in_reg.load(top, layout.align.abi);
+    in_reg.br(&end.llbb());
+
+    // On Stack block
+    let stack_value =
+        emit_ptr_va_arg(&mut on_stack, list, target_ty, false, Align::from_bytes(8).unwrap(), true);
+    on_stack.br(&end.llbb());
+
+    let val = end.phi(
+        layout.immediate_llvm_type(bx),
+        &[reg_value, stack_value],
+        &[&in_reg.llbb(), &on_stack.llbb()],
+    );
+
+    *bx = end;
+    val
+}
+
 pub(super) fn emit_va_arg(
     bx: &mut Builder<'a, 'll, 'tcx>,
     addr: OperandRef<'tcx, &'ll Value>,
@@ -115,6 +191,7 @@ pub(super) fn emit_va_arg(
         ("aarch64", _) if target.target_os == "ios" => {
             emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true)
         }
+        ("aarch64", _) => emit_aapcs_va_arg(bx, addr, target_ty),
         // Windows x86_64
         ("x86_64", true) => {
             let target_ty_size = bx.cx.size_of(target_ty).bytes();
index 2d65282ce7798751268970eb62534bf7349201b6..9191c68d4537aac7f7a43a8596d5adaa3d505680 100644 (file)
@@ -1598,7 +1598,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     }
 
     // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
-    cmd.add_eh_frame_header();
+    if sess.target.target.options.eh_frame_header {
+        cmd.add_eh_frame_header();
+    }
 
     // NO-OPT-OUT, OBJECT-FILES-NO
     if crt_objects_fallback {
@@ -1700,7 +1702,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     }
 
     // OBJECT-FILES-NO, AUDIT-ORDER
-    if sess.opts.debugging_opts.control_flow_guard != CFGuard::Disabled {
+    if sess.opts.cg.control_flow_guard != CFGuard::Disabled {
         cmd.control_flow_guard();
     }
 
index e64aafa599fd8ae39d63af34fbb8808cd810090e..d1ae9e372695fded7ad77293f052f541368ca746 100644 (file)
@@ -619,13 +619,7 @@ fn linker_plugin_lto(&mut self) {
     // Some versions of `gcc` add it implicitly, some (e.g. `musl-gcc`) don't,
     // so we just always add it.
     fn add_eh_frame_header(&mut self) {
-        if !self.sess.target.target.options.is_like_osx
-            && !self.sess.target.target.options.is_like_windows
-            && !self.sess.target.target.options.is_like_solaris
-            && self.sess.target.target.target_os != "uefi"
-        {
-            self.linker_arg("--eh-frame-hdr");
-        }
+        self.linker_arg("--eh-frame-hdr");
     }
 }
 
diff --git a/src/librustc_codegen_ssa/build.rs b/src/librustc_codegen_ssa/build.rs
deleted file mode 100644 (file)
index ea2af6e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL");
-}
diff --git a/src/librustc_driver/build.rs b/src/librustc_driver/build.rs
deleted file mode 100644 (file)
index 414d134..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_RELEASE");
-    println!("cargo:rerun-if-env-changed=CFG_VERSION");
-    println!("cargo:rerun-if-env-changed=CFG_VER_DATE");
-    println!("cargo:rerun-if-env-changed=CFG_VER_HASH");
-}
index 279c65ce03d2dabaf251f463202f368256fd1461..4e5e77f80c28a1208c4f0121777816cd98cbf24f 100644 (file)
     E0521, // borrowed data escapes outside of closure
     E0523,
 //  E0526, // shuffle indices are not constant
-    E0540, // multiple rustc_deprecated attributes
+//  E0540, // multiple rustc_deprecated attributes
     E0542, // missing 'since'
     E0543, // missing 'reason'
     E0544, // multiple stability levels
     E0755, // `#[ffi_pure]` is only allowed on foreign functions
     E0756, // `#[ffi_const]` is only allowed on foreign functions
     E0757, // `#[ffi_const]` functions cannot be `#[ffi_pure]`
+    E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
 }
index 7a7ba15485434836c9754da42db925d1a098a5d8..e8f84d0fc7d508deb202e5b1515149806bc83546 100644 (file)
@@ -1,4 +1,5 @@
-`#[ffi_returns_twice]` was used on non-foreign function.
+`#[ffi_returns_twice]` was used on something other than a foreign function
+declaration.
 
 Erroneous code example:
 
index d93c17b05b498c02baa6225f0173191cc519cca3..d16f023c00a6216109be48ace5e222590dcf5c10 100644 (file)
@@ -262,9 +262,9 @@ macro_rules! declare_features {
     /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`.
     (accepted, slice_patterns, "1.42.0", Some(62254), None),
     /// Allows the use of `if` and `match` in constants.
-    (accepted, const_if_match, "1.45.0", Some(49146), None),
+    (accepted, const_if_match, "1.46.0", Some(49146), None),
     /// Allows the use of `loop` and `while` in constants.
-    (accepted, const_loop, "1.45.0", Some(52000), None),
+    (accepted, const_loop, "1.46.0", Some(52000), None),
     /// Allows `#[track_caller]` to be used which provides
     /// accurate caller location reporting during panic (RFC 2091).
     (accepted, track_caller, "1.46.0", Some(47809), None),
index f56522406b0a707f36cda83862b4bc684f47fb6b..6474dc318d329f73854c2c0526b8f075589c7f0b 100644 (file)
@@ -2198,7 +2198,17 @@ pub enum IsAsync {
     NotAsync,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(
+    Copy,
+    Clone,
+    PartialEq,
+    RustcEncodable,
+    RustcDecodable,
+    Debug,
+    HashStable_Generic,
+    Eq,
+    Hash
+)]
 pub enum Defaultness {
     Default { has_value: bool },
     Final,
diff --git a/src/librustc_incremental/build.rs b/src/librustc_incremental/build.rs
deleted file mode 100644 (file)
index d230ba9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_VERSION");
-}
index 3b564e03d9a94e91ff1fe11b78e4ff7505147402..c63464e5baec9e3b1a71409ad0402cc1a710684e 100644 (file)
 
 use rustc_ast::ast;
 use rustc_hir::def_id::DefId;
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use rustc_middle::ty::{IntType, UintType};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::DUMMY_SP;
 
 #[derive(Clone)]
 pub struct CombineFields<'infcx, 'tcx> {
@@ -367,10 +368,11 @@ fn generalize(
         };
 
         debug!("generalize: for_universe = {:?}", for_universe);
+        debug!("generalize: trace = {:?}", self.trace);
 
         let mut generalize = Generalizer {
             infcx: self.infcx,
-            span: self.trace.cause.span,
+            cause: &self.trace.cause,
             for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid),
             for_universe,
             ambient_variance,
@@ -414,7 +416,7 @@ struct Generalizer<'cx, 'tcx> {
     infcx: &'cx InferCtxt<'cx, 'tcx>,
 
     /// The span, used when creating new type variables and things.
-    span: Span,
+    cause: &'cx ObligationCause<'tcx>,
 
     /// The vid of the type variable that is in the process of being
     /// instantiated; if we find this within the type we are folding,
@@ -639,7 +641,7 @@ fn regions(
 
         // FIXME: This is non-ideal because we don't give a
         // very descriptive origin for this region variable.
-        Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.span), self.for_universe))
+        Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.cause.span), self.for_universe))
     }
 
     fn consts(
index 633589db2704cd7e37ed882b7d3f64b64bfcb997..ff905faa95a9fe627e85e4b433c303218f5ef493 100644 (file)
@@ -2010,7 +2010,7 @@ fn report_inference_failure(
             infer::MiscVariable(_) => String::new(),
             infer::PatternRegion(_) => " for pattern".to_string(),
             infer::AddrOfRegion(_) => " for borrow expression".to_string(),
-            infer::Autoref(_) => " for autoref".to_string(),
+            infer::Autoref(_, _) => " for autoref".to_string(),
             infer::Coercion(_) => " for automatic coercion".to_string(),
             infer::LateBoundRegion(_, br, infer::FnCall) => {
                 format!(" for lifetime parameter {}in function call", br_string(br))
index b6e971feb0e5fdc4043f45411baa2264ea13cc19..4fa6d9d2394242cb56b69ad0ad19f5b3e4b4e745 100644 (file)
 
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
-use rustc_errors::{struct_span_err, Applicability, ErrorReported};
-use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind};
-use rustc_middle::ty::RegionKind;
+use crate::infer::{SubregionOrigin, TypeTrace};
+use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
+use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
+use rustc_hir::{
+    self as hir, GenericBound, ImplItem, Item, ItemKind, Lifetime, LifetimeName, Node, TraitItem,
+    TyKind,
+};
+use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, TypeVisitor};
+use rustc_span::symbol::Ident;
+use rustc_span::{MultiSpan, Span};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
-    /// Print the error message for lifetime errors when the return type is a static impl Trait.
+    /// Print the error message for lifetime errors when the return type is a static `impl Trait`,
+    /// `dyn Trait` or if a method call on a trait object introduces a static requirement.
     pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
         debug!("try_report_static_impl_trait(error={:?})", self.error);
-        if let Some(RegionResolutionError::SubSupConflict(
-            _,
-            var_origin,
-            ref sub_origin,
-            sub_r,
-            ref sup_origin,
-            sup_r,
-        )) = self.error
-        {
-            debug!(
-                "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
-                var_origin, sub_origin, sub_r, sup_origin, sup_r
-            );
-            let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
-            debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
-            let fn_returns = self.tcx().return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
-            if fn_returns.is_empty() {
+        let tcx = self.tcx();
+        let (var_origin, sub_origin, sub_r, sup_origin, sup_r) = match self.error.as_ref()? {
+            RegionResolutionError::SubSupConflict(
+                _,
+                var_origin,
+                sub_origin,
+                sub_r,
+                sup_origin,
+                sup_r,
+            ) if **sub_r == RegionKind::ReStatic => {
+                (var_origin, sub_origin, sub_r, sup_origin, sup_r)
+            }
+            RegionResolutionError::ConcreteFailure(
+                SubregionOrigin::Subtype(box TypeTrace { cause, .. }),
+                sub_r,
+                sup_r,
+            ) if **sub_r == RegionKind::ReStatic => {
+                // This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
+                if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code {
+                    let param = self.find_param_with_region(sup_r, sub_r)?;
+                    let lifetime = if sup_r.has_name() {
+                        format!("lifetime `{}`", sup_r)
+                    } else {
+                        "an anonymous lifetime `'_`".to_string()
+                    };
+                    let mut err = struct_span_err!(
+                        tcx.sess,
+                        cause.span,
+                        E0772,
+                        "{} has {} but calling `{}` introduces an implicit `'static` lifetime \
+                         requirement",
+                        param
+                            .param
+                            .pat
+                            .simple_ident()
+                            .map(|s| format!("`{}`", s))
+                            .unwrap_or_else(|| "`fn` parameter".to_string()),
+                        lifetime,
+                        ctxt.assoc_item.ident,
+                    );
+                    err.span_label(param.param_ty_span, &format!("this data with {}...", lifetime));
+                    err.span_label(
+                        cause.span,
+                        &format!(
+                            "...is captured and required to live as long as `'static` here \
+                             because of an implicit lifetime bound on the {}",
+                            match ctxt.assoc_item.container {
+                                AssocItemContainer::TraitContainer(id) =>
+                                    format!("`impl` of `{}`", tcx.def_path_str(id)),
+                                AssocItemContainer::ImplContainer(_) =>
+                                    "inherent `impl`".to_string(),
+                            },
+                        ),
+                    );
+                    if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
+                        err.emit();
+                        return Some(ErrorReported);
+                    } else {
+                        err.cancel();
+                    }
+                }
                 return None;
             }
-            debug!("try_report_static_impl_trait: fn_return={:?}", fn_returns);
-            if *sub_r == RegionKind::ReStatic {
-                let sp = var_origin.span();
-                let return_sp = sub_origin.span();
-                let param_info = self.find_param_with_region(sup_r, sub_r)?;
-                let (lifetime_name, lifetime) = if sup_r.has_name() {
-                    (sup_r.to_string(), format!("lifetime `{}`", sup_r))
-                } else {
-                    ("'_".to_owned(), "an anonymous lifetime `'_`".to_string())
-                };
-                let mut err = struct_span_err!(
-                    self.tcx().sess,
-                    sp,
-                    E0759,
-                    "cannot infer an appropriate lifetime"
-                );
+            _ => return None,
+        };
+        debug!(
+            "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
+            var_origin, sub_origin, sub_r, sup_origin, sup_r
+        );
+        let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
+        debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
+        let sp = var_origin.span();
+        let return_sp = sub_origin.span();
+        let param = self.find_param_with_region(sup_r, sub_r)?;
+        let (lifetime_name, lifetime) = if sup_r.has_name() {
+            (sup_r.to_string(), format!("lifetime `{}`", sup_r))
+        } else {
+            ("'_".to_owned(), "an anonymous lifetime `'_`".to_string())
+        };
+        let param_name = param
+            .param
+            .pat
+            .simple_ident()
+            .map(|s| format!("`{}`", s))
+            .unwrap_or_else(|| "`fn` parameter".to_string());
+        let mut err = struct_span_err!(
+            tcx.sess,
+            sp,
+            E0759,
+            "{} has {} but it needs to satisfy a `'static` lifetime requirement",
+            param_name,
+            lifetime,
+        );
+        err.span_label(param.param_ty_span, &format!("this data with {}...", lifetime));
+        debug!("try_report_static_impl_trait: param_info={:?}", param);
+
+        // We try to make the output have fewer overlapping spans if possible.
+        if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()))
+            && sup_origin.span() != return_sp
+        {
+            // FIXME: account for `async fn` like in `async-await/issues/issue-62097.rs`
+
+            // Customize the spans and labels depending on their relative order so
+            // that split sentences flow correctly.
+            if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() {
+                // Avoid the following:
+                //
+                // error: cannot infer an appropriate lifetime
+                //   --> $DIR/must_outlive_least_region_or_bound.rs:18:50
+                //    |
+                // LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
+                //    |           ----                      ---------^-
+                //
+                // and instead show:
+                //
+                // error: cannot infer an appropriate lifetime
+                //   --> $DIR/must_outlive_least_region_or_bound.rs:18:50
+                //    |
+                // LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
+                //    |           ----                               ^
                 err.span_label(
-                    param_info.param_ty_span,
-                    &format!("this data with {}...", lifetime),
+                    sup_origin.span(),
+                    "...is captured here, requiring it to live as long as `'static`",
                 );
-                debug!("try_report_static_impl_trait: param_info={:?}", param_info);
+            } else {
+                err.span_label(sup_origin.span(), "...is captured here...");
+                if return_sp < sup_origin.span() {
+                    err.span_note(
+                        return_sp,
+                        "...and is required to live as long as `'static` here",
+                    );
+                } else {
+                    err.span_label(
+                        return_sp,
+                        "...and is required to live as long as `'static` here",
+                    );
+                }
+            }
+        } else {
+            err.span_label(
+                return_sp,
+                "...is captured and required to live as long as `'static` here",
+            );
+        }
+
+        let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
 
-                // We try to make the output have fewer overlapping spans if possible.
-                if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()))
-                    && sup_origin.span() != return_sp
+        let mut override_error_code = None;
+        if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin {
+            if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code {
+                // Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a
+                // `'static` lifetime when called as a method on a binding: `bar.qux()`.
+                if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
+                    override_error_code = Some(ctxt.assoc_item.ident);
+                }
+            }
+        }
+        if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin {
+            if let ObligationCauseCode::ItemObligation(item_def_id) = cause.code {
+                // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
+                // lifetime as above, but called using a fully-qualified path to the method:
+                // `Foo::qux(bar)`.
+                let mut v = TraitObjectVisitor(vec![]);
+                v.visit_ty(param.param_ty);
+                if let Some((ident, self_ty)) =
+                    self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0[..])
                 {
-                    // FIXME: account for `async fn` like in `async-await/issues/issue-62097.rs`
-
-                    // Customize the spans and labels depending on their relative order so
-                    // that split sentences flow correctly.
-                    if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() {
-                        // Avoid the following:
-                        //
-                        // error: cannot infer an appropriate lifetime
-                        //   --> $DIR/must_outlive_least_region_or_bound.rs:18:50
-                        //    |
-                        // LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
-                        //    |           ----                      ---------^-
-                        //
-                        // and instead show:
-                        //
-                        // error: cannot infer an appropriate lifetime
-                        //   --> $DIR/must_outlive_least_region_or_bound.rs:18:50
-                        //    |
-                        // LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
-                        //    |           ----                               ^
-                        err.span_label(
-                            sup_origin.span(),
-                            "...is captured here, requiring it to live as long as `'static`",
+                    if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0[..], ident, self_ty)
+                    {
+                        override_error_code = Some(ident);
+                    }
+                }
+            }
+        }
+        if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) {
+            // Provide a more targetted error code and description.
+            err.code(rustc_errors::error_code!(E0772));
+            err.set_primary_message(&format!(
+                "{} has {} but calling `{}` introduces an implicit `'static` lifetime \
+                requirement",
+                param_name, lifetime, ident,
+            ));
+        }
+
+        debug!("try_report_static_impl_trait: fn_return={:?}", fn_returns);
+        // FIXME: account for the need of parens in `&(dyn Trait + '_)`
+        let consider = "consider changing the";
+        let declare = "to declare that the";
+        let arg = match param.param.pat.simple_ident() {
+            Some(simple_ident) => format!("argument `{}`", simple_ident),
+            None => "the argument".to_string(),
+        };
+        let explicit = format!("you can add an explicit `{}` lifetime bound", lifetime_name);
+        let explicit_static = format!("explicit `'static` bound to the lifetime of {}", arg);
+        let captures = format!("captures data from {}", arg);
+        let add_static_bound = "alternatively, add an explicit `'static` bound to this reference";
+        let plus_lt = format!(" + {}", lifetime_name);
+        for fn_return in fn_returns {
+            if fn_return.span.desugaring_kind().is_some() {
+                // Skip `async` desugaring `impl Future`.
+                continue;
+            }
+            match fn_return.kind {
+                TyKind::OpaqueDef(item_id, _) => {
+                    let item = tcx.hir().item(item_id.id);
+                    let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
+                        opaque
+                    } else {
+                        err.emit();
+                        return Some(ErrorReported);
+                    };
+
+                    if let Some(span) = opaque
+                        .bounds
+                        .iter()
+                        .filter_map(|arg| match arg {
+                            GenericBound::Outlives(Lifetime {
+                                name: LifetimeName::Static,
+                                span,
+                                ..
+                            }) => Some(*span),
+                            _ => None,
+                        })
+                        .next()
+                    {
+                        err.span_suggestion_verbose(
+                            span,
+                            &format!("{} `impl Trait`'s {}", consider, explicit_static),
+                            lifetime_name.clone(),
+                            Applicability::MaybeIncorrect,
+                        );
+                        err.span_suggestion_verbose(
+                            param.param_ty_span,
+                            add_static_bound,
+                            param.param_ty.to_string(),
+                            Applicability::MaybeIncorrect,
                         );
+                    } else if let Some(_) = opaque
+                        .bounds
+                        .iter()
+                        .filter_map(|arg| match arg {
+                            GenericBound::Outlives(Lifetime { name, span, .. })
+                                if name.ident().to_string() == lifetime_name =>
+                            {
+                                Some(*span)
+                            }
+                            _ => None,
+                        })
+                        .next()
+                    {
                     } else {
-                        err.span_label(sup_origin.span(), "...is captured here...");
-                        if return_sp < sup_origin.span() {
-                            err.span_note(
-                                return_sp,
-                                "...and is required to live as long as `'static` here",
-                            );
-                        } else {
-                            err.span_label(
-                                return_sp,
-                                "...and is required to live as long as `'static` here",
-                            );
-                        }
+                        err.span_suggestion_verbose(
+                            fn_return.span.shrink_to_hi(),
+                            &format!(
+                                "{declare} `impl Trait` {captures}, {explicit}",
+                                declare = declare,
+                                captures = captures,
+                                explicit = explicit,
+                            ),
+                            plus_lt.clone(),
+                            Applicability::MaybeIncorrect,
+                        );
                     }
-                } else {
-                    err.span_label(
-                        return_sp,
-                        "...is captured and required to live as long as `'static` here",
-                    );
                 }
+                TyKind::TraitObject(_, lt) => match lt.name {
+                    LifetimeName::ImplicitObjectLifetimeDefault => {
+                        err.span_suggestion_verbose(
+                            fn_return.span.shrink_to_hi(),
+                            &format!(
+                                "{declare} trait object {captures}, {explicit}",
+                                declare = declare,
+                                captures = captures,
+                                explicit = explicit,
+                            ),
+                            plus_lt.clone(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    name if name.ident().to_string() != lifetime_name => {
+                        // With this check we avoid suggesting redundant bounds. This
+                        // would happen if there are nested impl/dyn traits and only
+                        // one of them has the bound we'd suggest already there, like
+                        // in `impl Foo<X = dyn Bar> + '_`.
+                        err.span_suggestion_verbose(
+                            lt.span,
+                            &format!("{} trait object's {}", consider, explicit_static),
+                            lifetime_name.clone(),
+                            Applicability::MaybeIncorrect,
+                        );
+                        err.span_suggestion_verbose(
+                            param.param_ty_span,
+                            add_static_bound,
+                            param.param_ty.to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    _ => {}
+                },
+                _ => {}
+            }
+        }
+        err.emit();
+        Some(ErrorReported)
+    }
 
-                // FIXME: account for the need of parens in `&(dyn Trait + '_)`
-                let consider = "consider changing the";
-                let declare = "to declare that the";
-                let arg = match param_info.param.pat.simple_ident() {
-                    Some(simple_ident) => format!("argument `{}`", simple_ident),
-                    None => "the argument".to_string(),
-                };
-                let explicit =
-                    format!("you can add an explicit `{}` lifetime bound", lifetime_name);
-                let explicit_static =
-                    format!("explicit `'static` bound to the lifetime of {}", arg);
-                let captures = format!("captures data from {}", arg);
-                let add_static_bound =
-                    "alternatively, add an explicit `'static` bound to this reference";
-                let plus_lt = format!(" + {}", lifetime_name);
-                for fn_return in fn_returns {
-                    if fn_return.span.desugaring_kind().is_some() {
-                        // Skip `async` desugaring `impl Future`.
-                        continue;
+    fn get_impl_ident_and_self_ty_from_trait(
+        &self,
+        def_id: DefId,
+        trait_objects: &[DefId],
+    ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
+        let tcx = self.tcx();
+        match tcx.hir().get_if_local(def_id) {
+            Some(Node::ImplItem(ImplItem { ident, hir_id, .. })) => {
+                match tcx.hir().find(tcx.hir().get_parent_item(*hir_id)) {
+                    Some(Node::Item(Item { kind: ItemKind::Impl { self_ty, .. }, .. })) => {
+                        Some((*ident, self_ty))
                     }
-                    match fn_return.kind {
-                        TyKind::OpaqueDef(item_id, _) => {
-                            let item = self.tcx().hir().item(item_id.id);
-                            let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
-                                opaque
-                            } else {
-                                err.emit();
-                                return Some(ErrorReported);
-                            };
-
-                            if let Some(span) = opaque
-                                .bounds
-                                .iter()
-                                .filter_map(|arg| match arg {
-                                    GenericBound::Outlives(Lifetime {
-                                        name: LifetimeName::Static,
-                                        span,
+                    _ => None,
+                }
+            }
+            Some(Node::TraitItem(TraitItem { ident, hir_id, .. })) => {
+                let parent_id = tcx.hir().get_parent_item(*hir_id);
+                match tcx.hir().find(parent_id) {
+                    Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => {
+                        // The method being called is defined in the `trait`, but the `'static`
+                        // obligation comes from the `impl`. Find that `impl` so that we can point
+                        // at it in the suggestion.
+                        let trait_did = tcx.hir().local_def_id(parent_id).to_def_id();
+                        match tcx
+                            .hir()
+                            .trait_impls(trait_did)
+                            .iter()
+                            .filter_map(|impl_node| {
+                                let impl_did = tcx.hir().local_def_id(*impl_node);
+                                match tcx.hir().get_if_local(impl_did.to_def_id()) {
+                                    Some(Node::Item(Item {
+                                        kind: ItemKind::Impl { self_ty, .. },
                                         ..
-                                    }) => Some(*span),
-                                    _ => None,
-                                })
-                                .next()
-                            {
-                                err.span_suggestion_verbose(
-                                    span,
-                                    &format!("{} `impl Trait`'s {}", consider, explicit_static),
-                                    lifetime_name.clone(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                                err.span_suggestion_verbose(
-                                    param_info.param_ty_span,
-                                    add_static_bound,
-                                    param_info.param_ty.to_string(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            } else if let Some(_) = opaque
-                                .bounds
-                                .iter()
-                                .filter_map(|arg| match arg {
-                                    GenericBound::Outlives(Lifetime { name, span, .. })
-                                        if name.ident().to_string() == lifetime_name =>
+                                    })) if trait_objects.iter().all(|did| {
+                                        // FIXME: we should check `self_ty` against the receiver
+                                        // type in the `UnifyReceiver` context, but for now, use
+                                        // this imperfect proxy. This will fail if there are
+                                        // multiple `impl`s for the same trait like
+                                        // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
+                                        // In that case, only the first one will get suggestions.
+                                        let mut hir_v = HirTraitObjectVisitor(vec![], *did);
+                                        hir_v.visit_ty(self_ty);
+                                        !hir_v.0.is_empty()
+                                    }) =>
                                     {
-                                        Some(*span)
+                                        Some(self_ty)
                                     }
                                     _ => None,
-                                })
-                                .next()
-                            {
-                            } else {
-                                err.span_suggestion_verbose(
-                                    fn_return.span.shrink_to_hi(),
-                                    &format!(
-                                        "{declare} `impl Trait` {captures}, {explicit}",
-                                        declare = declare,
-                                        captures = captures,
-                                        explicit = explicit,
-                                    ),
-                                    plus_lt.clone(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            }
+                                }
+                            })
+                            .next()
+                        {
+                            Some(self_ty) => Some((*ident, self_ty)),
+                            _ => None,
                         }
-                        TyKind::TraitObject(_, lt) => match lt.name {
-                            LifetimeName::ImplicitObjectLifetimeDefault => {
-                                err.span_suggestion_verbose(
-                                    fn_return.span.shrink_to_hi(),
-                                    &format!(
-                                        "{declare} trait object {captures}, {explicit}",
-                                        declare = declare,
-                                        captures = captures,
-                                        explicit = explicit,
-                                    ),
-                                    plus_lt.clone(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            }
-                            name if name.ident().to_string() != lifetime_name => {
-                                // With this check we avoid suggesting redundant bounds. This
-                                // would happen if there are nested impl/dyn traits and only
-                                // one of them has the bound we'd suggest already there, like
-                                // in `impl Foo<X = dyn Bar> + '_`.
-                                err.span_suggestion_verbose(
-                                    lt.span,
-                                    &format!("{} trait object's {}", consider, explicit_static),
-                                    lifetime_name.clone(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                                err.span_suggestion_verbose(
-                                    param_info.param_ty_span,
-                                    add_static_bound,
-                                    param_info.param_ty.to_string(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            }
-                            _ => {}
-                        },
-                        _ => {}
+                    }
+                    _ => None,
+                }
+            }
+            _ => None,
+        }
+    }
+
+    /// When we call a method coming from an `impl Foo for dyn Bar`, `dyn Bar` introduces a default
+    /// `'static` obligation. Suggest relaxing that implicit bound.
+    fn find_impl_on_dyn_trait(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        ty: Ty<'_>,
+        ctxt: &UnifyReceiverContext<'tcx>,
+    ) -> bool {
+        let tcx = self.tcx();
+
+        // Find the method being called.
+        let instance = match ty::Instance::resolve(
+            tcx,
+            ctxt.param_env,
+            ctxt.assoc_item.def_id,
+            self.infcx.resolve_vars_if_possible(&ctxt.substs),
+        ) {
+            Ok(Some(instance)) => instance,
+            _ => return false,
+        };
+
+        let mut v = TraitObjectVisitor(vec![]);
+        v.visit_ty(ty);
+
+        // Get the `Ident` of the method being called and the corresponding `impl` (to point at
+        // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
+        let (ident, self_ty) =
+            match self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0[..]) {
+                Some((ident, self_ty)) => (ident, self_ty),
+                None => return false,
+            };
+
+        // Find the trait object types in the argument, so we point at *only* the trait object.
+        self.suggest_constrain_dyn_trait_in_impl(err, &v.0[..], ident, self_ty)
+    }
+
+    fn suggest_constrain_dyn_trait_in_impl(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        found_dids: &[DefId],
+        ident: Ident,
+        self_ty: &hir::Ty<'_>,
+    ) -> bool {
+        let mut suggested = false;
+        for found_did in found_dids {
+            let mut hir_v = HirTraitObjectVisitor(vec![], *found_did);
+            hir_v.visit_ty(&self_ty);
+            for span in &hir_v.0 {
+                let mut multi_span: MultiSpan = vec![*span].into();
+                multi_span.push_span_label(
+                    *span,
+                    "this has an implicit `'static` lifetime requirement".to_string(),
+                );
+                multi_span.push_span_label(
+                    ident.span,
+                    "calling this method introduces the `impl`'s 'static` requirement".to_string(),
+                );
+                err.span_note(multi_span, "the used `impl` has a `'static` requirement");
+                err.span_suggestion_verbose(
+                    span.shrink_to_hi(),
+                    "consider relaxing the implicit `'static` requirement",
+                    " + '_".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+                suggested = true;
+            }
+        }
+        suggested
+    }
+}
+
+/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
+struct TraitObjectVisitor(Vec<DefId>);
+
+impl TypeVisitor<'_> for TraitObjectVisitor {
+    fn visit_ty(&mut self, t: Ty<'_>) -> bool {
+        match t.kind {
+            ty::Dynamic(preds, RegionKind::ReStatic) => {
+                if let Some(def_id) = preds.principal_def_id() {
+                    self.0.push(def_id);
+                }
+                false
+            }
+            _ => t.super_visit_with(self),
+        }
+    }
+}
+
+/// Collect all `hir::Ty<'_>` `Span`s for trait objects with an implicit lifetime.
+struct HirTraitObjectVisitor(Vec<Span>, DefId);
+
+impl<'tcx> Visitor<'tcx> for HirTraitObjectVisitor {
+    type Map = ErasedMap<'tcx>;
+
+    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
+        NestedVisitorMap::None
+    }
+
+    fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
+        match t.kind {
+            TyKind::TraitObject(
+                poly_trait_refs,
+                Lifetime { name: LifetimeName::ImplicitObjectLifetimeDefault, .. },
+            ) => {
+                for ptr in poly_trait_refs {
+                    if Some(self.1) == ptr.trait_ref.trait_def_id() {
+                        self.0.push(ptr.span);
                     }
                 }
-                err.emit();
-                return Some(ErrorReported);
             }
+            _ => {}
         }
-        None
+        walk_ty(self, t);
     }
 }
index fa999abb1a86c46b672c88b81b49d1efc36f5fea..28e9dd90cfd674531eafece5122db6f3410fa2f5 100644 (file)
@@ -7,20 +7,18 @@
 use rustc_middle::ty::{self, DefIdTree, Region, Ty};
 use rustc_span::Span;
 
-// The struct contains the information about the anonymous region
-// we are searching for.
+/// Information about the anonymous region we are searching for.
 #[derive(Debug)]
 pub(super) struct AnonymousParamInfo<'tcx> {
-    // the parameter corresponding to the anonymous region
+    /// The parameter corresponding to the anonymous region.
     pub param: &'tcx hir::Param<'tcx>,
-    // the type corresponding to the anonymopus region parameter
+    /// The type corresponding to the anonymous region parameter.
     pub param_ty: Ty<'tcx>,
-    // the ty::BoundRegion corresponding to the anonymous region
+    /// The ty::BoundRegion corresponding to the anonymous region.
     pub bound_region: ty::BoundRegion,
-    // param_ty_span contains span of parameter type
+    /// The `Span` of the parameter type.
     pub param_ty_span: Span,
-    // corresponds to id the argument is the first parameter
-    // in the declaration
+    /// Signals that the argument is the first parameter in the declaration.
     pub is_first: bool,
 }
 
index 37883fcb07468e7256f7e50b7fe2b671695860e2..3744ad5d0324a59ebd145ae16ca0537210feb11d 100644 (file)
@@ -463,7 +463,7 @@ pub enum RegionVariableOrigin {
     AddrOfRegion(Span),
 
     /// Regions created as part of an autoref of a method receiver
-    Autoref(Span),
+    Autoref(Span, ty::AssocItem),
 
     /// Regions created as part of an automatic coercion
     Coercion(Span),
@@ -1800,15 +1800,15 @@ pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>, default:
 impl RegionVariableOrigin {
     pub fn span(&self) -> Span {
         match *self {
-            MiscVariable(a) => a,
-            PatternRegion(a) => a,
-            AddrOfRegion(a) => a,
-            Autoref(a) => a,
-            Coercion(a) => a,
-            EarlyBoundRegion(a, ..) => a,
-            LateBoundRegion(a, ..) => a,
+            MiscVariable(a)
+            | PatternRegion(a)
+            | AddrOfRegion(a)
+            | Autoref(a, _)
+            | Coercion(a)
+            | EarlyBoundRegion(a, ..)
+            | LateBoundRegion(a, ..)
+            | UpvarRegion(_, a) => a,
             BoundRegionInCoherence(_) => rustc_span::DUMMY_SP,
-            UpvarRegion(_, a) => a,
             NLL(..) => bug!("NLL variable used with `span`"),
         }
     }
index 0cd6585163c4e9ce2a6df197881ded29be98563e..bacb7fa153e43b1a0cca8d8f5272ec5c71d749f5 100644 (file)
@@ -13,6 +13,7 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
+#![feature(bindings_after_at)]
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
diff --git a/src/librustc_interface/build.rs b/src/librustc_interface/build.rs
deleted file mode 100644 (file)
index 79a343e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=RUSTC_INSTALL_BINDIR");
-}
index 3c549b88523684fa812623d87bfb0aa48fdd9614..22197a66530ddddb7d1eaba67444109707e5ba2f 100644 (file)
@@ -420,6 +420,7 @@ macro_rules! tracked {
     // Make sure that changing a [TRACKED] option changes the hash.
     // This list is in alphabetical order.
     tracked!(code_model, Some(CodeModel::Large));
+    tracked!(control_flow_guard, CFGuard::Checks);
     tracked!(debug_assertions, Some(true));
     tracked!(debuginfo, 0xdeadbeef);
     tracked!(embed_bitcode, false);
@@ -537,7 +538,6 @@ macro_rules! tracked {
     tracked!(binary_dep_depinfo, true);
     tracked!(chalk, true);
     tracked!(codegen_backend, Some("abc".to_string()));
-    tracked!(control_flow_guard, CFGuard::Checks);
     tracked!(crate_attr, vec!["abc".to_string()]);
     tracked!(debug_macros, true);
     tracked!(dep_info_omit_d_target, true);
index 4fc02e348f64637a61aeff09833cd5a561fa9fef..9f2711eec10acb26b7d1e004bbb103e034daa6c9 100644 (file)
@@ -2,7 +2,6 @@
 authors = ["The Rust Project Developers"]
 name = "rustc_llvm"
 version = "0.0.0"
-build = "build.rs"
 edition = "2018"
 
 [lib]
@@ -14,8 +13,8 @@ static-libstdcpp = []
 emscripten = []
 
 [dependencies]
-libc = "0.2"
+libc = "0.2.73"
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-cc = "1.0.1"
+cc = "1.0.58"
index 78e27b10ec657e35f83d37d51256f567aa0d5986..21b8080714c1744ca54130adbb6325ece0082bff 100644 (file)
@@ -2,12 +2,12 @@
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-use build_helper::output;
+use build_helper::{output, tracked_env_var_os};
 
 fn detect_llvm_link() -> (&'static str, &'static str) {
     // Force the link mode we want, preferring static by default, but
     // possibly overridden by `configure --enable-llvm-link-shared`.
-    if env::var_os("LLVM_LINK_SHARED").is_some() {
+    if tracked_env_var_os("LLVM_LINK_SHARED").is_some() {
         ("dylib", "--link-shared")
     } else {
         ("static", "--link-static")
@@ -15,8 +15,7 @@ fn detect_llvm_link() -> (&'static str, &'static str) {
 }
 
 fn main() {
-    println!("cargo:rerun-if-env-changed=RUST_CHECK");
-    if env::var_os("RUST_CHECK").is_some() {
+    if tracked_env_var_os("RUST_CHECK").is_some() {
         // If we're just running `check`, there's no need for LLVM to be built.
         return;
     }
@@ -25,8 +24,8 @@ fn main() {
 
     let target = env::var("TARGET").expect("TARGET was not set");
     let llvm_config =
-        env::var_os("LLVM_CONFIG").map(|x| Some(PathBuf::from(x))).unwrap_or_else(|| {
-            if let Some(dir) = env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
+        tracked_env_var_os("LLVM_CONFIG").map(|x| Some(PathBuf::from(x))).unwrap_or_else(|| {
+            if let Some(dir) = tracked_env_var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
                 let to_test = dir
                     .parent()
                     .unwrap()
@@ -46,8 +45,6 @@ fn main() {
     }
     let llvm_config = llvm_config.unwrap_or_else(|| PathBuf::from("llvm-config"));
 
-    println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
-
     // Test whether we're cross-compiling LLVM. This is a pretty rare case
     // currently where we're producing an LLVM for a different platform than
     // what this build script is currently running on.
@@ -163,12 +160,11 @@ fn main() {
         cfg.define(&flag, None);
     }
 
-    println!("cargo:rerun-if-changed-env=LLVM_RUSTLLVM");
-    if env::var_os("LLVM_RUSTLLVM").is_some() {
+    if tracked_env_var_os("LLVM_RUSTLLVM").is_some() {
         cfg.define("LLVM_RUSTLLVM", None);
     }
 
-    if env::var_os("LLVM_NDEBUG").is_some() {
+    if tracked_env_var_os("LLVM_NDEBUG").is_some() {
         cfg.define("NDEBUG", None);
         cfg.debug(false);
     }
@@ -255,7 +251,7 @@ fn main() {
     // librustc_llvm, for example when using static libc++, we may need to
     // manually specify the library search path and -ldl -lpthread as link
     // dependencies.
-    let llvm_linker_flags = env::var_os("LLVM_LINKER_FLAGS");
+    let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS");
     if let Some(s) = llvm_linker_flags {
         for lib in s.into_string().unwrap().split_whitespace() {
             if lib.starts_with("-l") {
@@ -266,8 +262,8 @@ fn main() {
         }
     }
 
-    let llvm_static_stdcpp = env::var_os("LLVM_STATIC_STDCPP");
-    let llvm_use_libcxx = env::var_os("LLVM_USE_LIBCXX");
+    let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP");
+    let llvm_use_libcxx = tracked_env_var_os("LLVM_USE_LIBCXX");
 
     let stdcppname = if target.contains("openbsd") {
         if target.contains("sparc64") { "estdc++" } else { "c++" }
diff --git a/src/librustc_metadata/build.rs b/src/librustc_metadata/build.rs
deleted file mode 100644 (file)
index 7d5c58e..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_VERSION");
-    println!("cargo:rerun-if-env-changed=CFG_VIRTUAL_RUST_SOURCE_BASE_DIR");
-}
diff --git a/src/librustc_middle/build.rs b/src/librustc_middle/build.rs
deleted file mode 100644 (file)
index af7723a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-use std::env;
-
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_LIBDIR_RELATIVE");
-    println!("cargo:rerun-if-env-changed=CFG_COMPILER_HOST_TRIPLE");
-    println!("cargo:rerun-if-env-changed=RUSTC_VERIFY_LLVM_IR");
-
-    if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
-        println!("cargo:rustc-cfg=always_verify_llvm_ir");
-    }
-}
index a68301385b7a5b5a983609f57ce7d4057a438ebf..b7dccb8d8ce6d3ef3aab403891855949f17bae76 100644 (file)
@@ -27,7 +27,6 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(cmp_min_max_by)]
 #![feature(const_fn)]
 #![feature(const_panic)]
 #![feature(const_fn_transmute)]
index 54c05bca3bd2bbfac04dbc72c1b0e5422e55ef80..5f7ff54fd31c3ee5a3e329752aa59e6e19e96ad4 100644 (file)
@@ -5,7 +5,7 @@
 
 use crate::ty::{self, TyCtxt};
 use rustc_ast::ast::CRATE_NODE_ID;
-use rustc_attr::{self as attr, ConstStability, Deprecation, RustcDeprecation, Stability};
+use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_feature::GateIssue;
@@ -130,14 +130,26 @@ pub fn report_unstable(
 
 /// 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 {
+pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool {
+    let since = if let Some(since) = since {
+        if is_since_rustc_version {
+            since
+        } else {
+            // We assume that the deprecation is in effect if it's not a
+            // rustc version.
+            return true;
+        }
+    } else {
+        // If since attribute is not set, then we're definitely in effect.
+        return true;
+    };
     fn parse_version(ver: &str) -> Vec<u32> {
         // We ignore non-integer components of the version (e.g., "nightly").
         ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
     }
 
     if let Some(rustc) = option_env!("CFG_RELEASE") {
-        let since: Vec<u32> = parse_version(since);
+        let since: Vec<u32> = parse_version(&since);
         let rustc: Vec<u32> = parse_version(rustc);
         // We simply treat invalid `since` attributes as relating to a previous
         // Rust version, thus always displaying the warning.
@@ -167,31 +179,27 @@ pub fn deprecation_suggestion(
     }
 }
 
-fn deprecation_message_common(message: String, reason: Option<Symbol>) -> 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), DEPRECATED)
-}
-
-pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) {
-    let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) {
+    let (message, lint) = if deprecation_in_effect(
+        depr.is_since_rustc_version,
+        depr.since.map(Symbol::as_str).as_deref(),
+    ) {
         (format!("use of deprecated item '{}'", path), DEPRECATED)
     } else {
         (
             format!(
                 "use of item '{}' that will be deprecated in future version {}",
-                path, depr.since
+                path,
+                depr.since.unwrap()
             ),
             DEPRECATED_IN_FUTURE,
         )
     };
-    (deprecation_message_common(message, Some(depr.reason)), lint)
+    let message = match depr.note {
+        Some(reason) => format!("{}: {}", message, reason),
+        None => message,
+    };
+    (message, lint)
 }
 
 pub fn early_report_deprecation(
@@ -289,10 +297,23 @@ pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> Eva
                     .lookup_deprecation_entry(parent_def_id.to_def_id())
                     .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
 
-                if !skip {
+                // #[deprecated] doesn't emit a notice if we're not on the
+                // topmost deprecation. For example, if a struct is deprecated,
+                // the use of a field won't be linted.
+                //
+                // #[rustc_deprecated] however wants to emit down the whole
+                // hierarchy.
+                if !skip || depr_entry.attr.is_since_rustc_version {
                     let (message, lint) =
                         deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
-                    late_report_deprecation(self, &message, None, lint, span, id);
+                    late_report_deprecation(
+                        self,
+                        &message,
+                        depr_entry.attr.suggestion,
+                        lint,
+                        span,
+                        id,
+                    );
                 }
             };
         }
@@ -310,16 +331,6 @@ pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> Eva
             def_id, span, stability
         );
 
-        if let Some(id) = id {
-            if let Some(stability) = stability {
-                if let Some(depr) = &stability.rustc_depr {
-                    let (message, lint) =
-                        rustc_deprecation_message(depr, &self.def_path_str(def_id));
-                    late_report_deprecation(self, &message, depr.suggestion, lint, span, id);
-                }
-            }
-        }
-
         // Only the cross-crate scenario matters when checking unstable APIs
         let cross_crate = !def_id.is_local();
         if !cross_crate {
index c15c31a53f0c9fefafb2f06bdf6d086e95c08488..d2747e5fc659b9efcef4b621e1d6fea8eb33f347 100644 (file)
@@ -169,6 +169,13 @@ pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span {
     }
 }
 
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct UnifyReceiverContext<'tcx> {
+    pub assoc_item: ty::AssocItem,
+    pub param_env: ty::ParamEnv<'tcx>,
+    pub substs: SubstsRef<'tcx>,
+}
+
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from the span.
@@ -300,6 +307,8 @@ pub enum ObligationCauseCode<'tcx> {
     /// Method receiver
     MethodReceiver,
 
+    UnifyReceiver(Box<UnifyReceiverContext<'tcx>>),
+
     /// `return` with no expression
     ReturnNoExpression,
 
index 334462790edbcc5a2f03c2de543fcdf9148d0065..18b4371053a89c77b3340161b2eaab7cefaa92c2 100644 (file)
@@ -213,12 +213,26 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
             super::StartFunctionType => Some(super::StartFunctionType),
             super::IntrinsicType => Some(super::IntrinsicType),
             super::MethodReceiver => Some(super::MethodReceiver),
+            super::UnifyReceiver(ref ctxt) => tcx.lift(ctxt).map(|ctxt| super::UnifyReceiver(ctxt)),
             super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
             super::TrivialBound => Some(super::TrivialBound),
         }
     }
 }
 
+impl<'a, 'tcx> Lift<'tcx> for traits::UnifyReceiverContext<'a> {
+    type Lifted = traits::UnifyReceiverContext<'tcx>;
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
+        tcx.lift(&self.param_env).and_then(|param_env| {
+            tcx.lift(&self.substs).map(|substs| traits::UnifyReceiverContext {
+                assoc_item: self.assoc_item,
+                param_env,
+                substs,
+            })
+        })
+    }
+}
+
 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
     type Lifted = traits::DerivedObligationCause<'tcx>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
index dc775b15927fa2edaf2fa09c4194a4f27e79d96e..215f44819b5d144996f2d8e20c289fffca4fb009 100644 (file)
@@ -876,8 +876,6 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
                     .iter_enumerated()
                     .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
 
-                let mut niche_filling_layout = None;
-
                 // Niche-filling enum optimization.
                 if !def.repr.inhibit_enum_layout_opt() && no_explicit_discriminants {
                     let mut dataful_variant = None;
@@ -974,7 +972,7 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
                             let largest_niche =
                                 Niche::from_scalar(dl, offset, niche_scalar.clone());
 
-                            niche_filling_layout = Some(Layout {
+                            return Ok(tcx.intern_layout(Layout {
                                 variants: Variants::Multiple {
                                     tag: niche_scalar,
                                     tag_encoding: TagEncoding::Niche {
@@ -993,7 +991,7 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
                                 largest_niche,
                                 size,
                                 align,
-                            });
+                            }));
                         }
                     }
                 }
@@ -1216,7 +1214,7 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
 
                 let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone());
 
-                let tagged_layout = Layout {
+                tcx.intern_layout(Layout {
                     variants: Variants::Multiple {
                         tag,
                         tag_encoding: TagEncoding::Direct,
@@ -1231,23 +1229,7 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
                     abi,
                     align,
                     size,
-                };
-
-                let best_layout = match (tagged_layout, niche_filling_layout) {
-                    (tagged_layout, Some(niche_filling_layout)) => {
-                        // Pick the smaller layout; otherwise,
-                        // pick the layout with the larger niche; otherwise,
-                        // pick tagged as it has simpler codegen.
-                        cmp::min_by_key(tagged_layout, niche_filling_layout, |layout| {
-                            let niche_size =
-                                layout.largest_niche.as_ref().map_or(0, |n| n.available(dl));
-                            (layout.size, cmp::Reverse(niche_size))
-                        })
-                    }
-                    (tagged_layout, None) => tagged_layout,
-                };
-
-                tcx.intern_layout(best_layout)
+                })
             }
 
             // Types with no meaningful known layout.
index 51a353c0132412cb0cdf5429bf4d0fdb7c71f144..a5ddcdfdb0408b8767ef0c75c4534ab44a55b85a 100644 (file)
@@ -136,7 +136,7 @@ pub struct ResolverOutputs {
     pub extern_prelude: FxHashMap<Symbol, bool>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash)]
 pub enum AssocItemContainer {
     TraitContainer(DefId),
     ImplContainer(DefId),
@@ -184,7 +184,7 @@ pub enum ImplPolarity {
     Reservation,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash)]
 pub struct AssocItem {
     pub def_id: DefId,
     #[stable_hasher(project(name))]
@@ -199,7 +199,7 @@ pub struct AssocItem {
     pub fn_has_self_parameter: bool,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash)]
 pub enum AssocKind {
     Const,
     Fn,
@@ -316,7 +316,7 @@ pub fn find_by_name_and_namespace(
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable, Hash)]
 pub enum Visibility {
     /// Visible everywhere (including in other crates).
     Public,
@@ -1617,12 +1617,33 @@ pub struct WithOptConstParam<T> {
 
 impl<T> WithOptConstParam<T> {
     /// Creates a new `WithOptConstParam` setting `const_param_did` to `None`.
+    #[inline(always)]
     pub fn unknown(did: T) -> WithOptConstParam<T> {
         WithOptConstParam { did, const_param_did: None }
     }
 }
 
 impl WithOptConstParam<LocalDefId> {
+    /// Returns `Some((did, param_did))` if `def_id` is a const argument,
+    /// `None` otherwise.
+    #[inline(always)]
+    pub fn try_lookup(did: LocalDefId, tcx: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> {
+        tcx.opt_const_param_of(did).map(|param_did| (did, param_did))
+    }
+
+    /// In case `self` is unknown but `self.did` is a const argument, this returns
+    /// a `WithOptConstParam` with the correct `const_param_did`.
+    #[inline(always)]
+    pub fn try_upgrade(self, tcx: TyCtxt<'_>) -> Option<WithOptConstParam<LocalDefId>> {
+        if self.const_param_did.is_none() {
+            if let const_param_did @ Some(_) = tcx.opt_const_param_of(self.did) {
+                return Some(WithOptConstParam { did: self.did, const_param_did });
+            }
+        }
+
+        None
+    }
+
     pub fn to_global(self) -> WithOptConstParam<DefId> {
         WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did }
     }
index 1972b7149d569fb42a1066dd06eefe71129099a8..76cc03fa60909ba58b605fa105b6928bac3a6ea0 100644 (file)
 
 pub fn provide(providers: &mut Providers) {
     *providers = Providers {
-        mir_borrowck: |tcx, did| mir_borrowck(tcx, ty::WithOptConstParam::unknown(did)),
+        mir_borrowck: |tcx, did| {
+            if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
+                tcx.mir_borrowck_const_arg(def)
+            } else {
+                mir_borrowck(tcx, ty::WithOptConstParam::unknown(did))
+            }
+        },
         mir_borrowck_const_arg: |tcx, (did, param_did)| {
             mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
         },
@@ -100,12 +106,6 @@ fn mir_borrowck<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx BorrowCheckResult<'tcx> {
-    if def.const_param_did.is_none() {
-        if let Some(param_did) = tcx.opt_const_param_of(def.did) {
-            return tcx.mir_borrowck_const_arg((def.did, param_did));
-        }
-    }
-
     let (input_body, promoted) = tcx.mir_validated(def);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
 
index 5836fc9c95a80af6cb330c332a4446f3094665e6..29549041d258cc285d8db7e636da3e5638a22f31 100644 (file)
@@ -12,7 +12,7 @@
 };
 use rustc_middle::ty;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size};
 
@@ -54,6 +54,9 @@ fn numeric_intrinsic<'tcx, Tag>(
     let name = tcx.item_name(def_id);
     Ok(match name {
         sym::type_name => {
+            if tp_ty.needs_subst() {
+                throw_inval!(TooGeneric);
+            }
             let alloc = type_name::alloc_type_name(tcx, tp_ty);
             ConstValue::Slice { data: alloc, start: 0, end: alloc.len() }
         }
@@ -68,7 +71,12 @@ fn numeric_intrinsic<'tcx, Tag>(
             };
             ConstValue::from_machine_usize(n, &tcx)
         }
-        sym::type_id => ConstValue::from_u64(tcx.type_id_hash(tp_ty)),
+        sym::type_id => {
+            if tp_ty.needs_subst() {
+                throw_inval!(TooGeneric);
+            }
+            ConstValue::from_u64(tcx.type_id_hash(tp_ty))
+        }
         sym::variant_count => {
             if let ty::Adt(ref adt, _) = tp_ty.kind {
                 ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx)
index 0b5f27fc17a72fd12562c1e304874e7edcc437e1..e724180f4d833d588c199cc4bdf46bab1c681410 100644 (file)
@@ -627,8 +627,9 @@ fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location)
                     Ok(val) => collect_const_value(self.tcx, val, self.output),
                     Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
                     Err(ErrorHandled::TooGeneric) => span_bug!(
-                        self.tcx.def_span(def.did),
-                        "collection encountered polymorphic constant",
+                        self.body.source_info(location).span,
+                        "collection encountered polymorphic constant: {}",
+                        substituted_constant
                     ),
                 }
             }
index 81d7ac089262206aa24957a226f5c50ea627701e..9c06e173bcd5713b2b946af7faa85dd4a341614b 100644 (file)
@@ -439,7 +439,11 @@ fn check_target_features(&mut self, func_did: DefId) {
 pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
         unsafety_check_result: |tcx, def_id| {
-            unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id))
+            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
+                tcx.unsafety_check_result_for_const_arg(def)
+            } else {
+                unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id))
+            }
         },
         unsafety_check_result_for_const_arg: |tcx, (did, param_did)| {
             unsafety_check_result(
@@ -499,12 +503,6 @@ fn unsafety_check_result<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx UnsafetyCheckResult {
-    if def.const_param_did.is_none() {
-        if let Some(param_did) = tcx.opt_const_param_of(def.did) {
-            return tcx.unsafety_check_result_for_const_arg((def.did, param_did));
-        }
-    }
-
     debug!("unsafety_violations({:?})", def);
 
     // N.B., this borrow is valid because all the consumers of
index 51a9e76e762ebe50a66548dd4db53e0214da7417..283e4b289f286925979d94c6733fe9c7867cb058 100644 (file)
@@ -48,8 +48,13 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
         mir_keys,
         mir_const,
-        mir_const_qualif: |tcx, did| {
-            mir_const_qualif(tcx, ty::WithOptConstParam::unknown(did.expect_local()))
+        mir_const_qualif: |tcx, def_id| {
+            let def_id = def_id.expect_local();
+            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
+                tcx.mir_const_qualif_const_arg(def)
+            } else {
+                mir_const_qualif(tcx, ty::WithOptConstParam::unknown(def_id))
+            }
         },
         mir_const_qualif_const_arg: |tcx, (did, param_did)| {
             mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
@@ -60,7 +65,12 @@ pub(crate) fn provide(providers: &mut Providers) {
         optimized_mir_of_const_arg,
         is_mir_available,
         promoted_mir: |tcx, def_id| {
-            promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id.expect_local()))
+            let def_id = def_id.expect_local();
+            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
+                tcx.promoted_mir_of_const_arg(def)
+            } else {
+                promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id))
+            }
         },
         promoted_mir_of_const_arg: |tcx, (did, param_did)| {
             promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
@@ -221,12 +231,6 @@ pub fn run_passes(
 }
 
 fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs {
-    if def.const_param_did.is_none() {
-        if let Some(param_did) = tcx.opt_const_param_of(def.did) {
-            return tcx.mir_const_qualif_const_arg((def.did, param_did));
-        }
-    }
-
     let const_kind = tcx.hir().body_const_context(def.did);
 
     // No need to const-check a non-const `fn`.
@@ -266,10 +270,8 @@ fn mir_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx Steal<Body<'tcx>> {
-    if def.const_param_did.is_none() {
-        if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
-            return tcx.mir_const(ty::WithOptConstParam { const_param_did, ..def });
-        }
+    if let Some(def) = def.try_upgrade(tcx) {
+        return tcx.mir_const(def);
     }
 
     // Unsafety check uses the raw mir, so make sure it is run.
@@ -312,10 +314,8 @@ fn mir_validated(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> (&'tcx Steal<Body<'tcx>>, &'tcx Steal<IndexVec<Promoted, Body<'tcx>>>) {
-    if def.const_param_did.is_none() {
-        if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
-            return tcx.mir_validated(ty::WithOptConstParam { const_param_did, ..def });
-        }
+    if let Some(def) = def.try_upgrade(tcx) {
+        return tcx.mir_validated(def);
     }
 
     // Ensure that we compute the `mir_const_qualif` for constants at
@@ -357,13 +357,8 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx Steal<Body<'tcx>> {
-    if def.const_param_did.is_none() {
-        if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
-            return tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam {
-                const_param_did,
-                ..def
-            });
-        }
+    if let Some(def) = def.try_upgrade(tcx) {
+        return tcx.mir_drops_elaborated_and_const_checked(def);
     }
 
     // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
@@ -490,8 +485,8 @@ fn run_optimization_passes<'tcx>(
 
 fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx Body<'tcx> {
     let did = did.expect_local();
-    if let Some(param_did) = tcx.opt_const_param_of(did) {
-        tcx.optimized_mir_of_const_arg((did, param_did))
+    if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
+        tcx.optimized_mir_of_const_arg(def)
     } else {
         tcx.arena.alloc(inner_optimized_mir(tcx, ty::WithOptConstParam::unknown(did)))
     }
@@ -528,12 +523,6 @@ fn promoted_mir<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
-    if def.const_param_did.is_none() {
-        if let Some(param_did) = tcx.opt_const_param_of(def.did) {
-            return tcx.promoted_mir_of_const_arg((def.did, param_did));
-        }
-    }
-
     if tcx.is_constructor(def.did.to_def_id()) {
         return tcx.arena.alloc(IndexVec::new());
     }
index eb47195c06278d189fff0ac7c9c8204af936e97e..1e677f3d2aba82693e775972cefab82ce3a1dc38 100644 (file)
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
 ) -> &'tcx ty::steal::Steal<Body<'tcx>> {
-    if def.const_param_did.is_none() {
-        if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
-            return tcx.mir_built(ty::WithOptConstParam { const_param_did, ..def });
-        }
+    if let Some(def) = def.try_upgrade(tcx) {
+        return tcx.mir_built(def);
     }
 
     tcx.alloc_steal_mir(mir_build(tcx, def))
index 5d972c70d139255f27b137c08895167d1c9f572d..830af8d31e7a6a3b48baa76f6f72ffb05624c9a6 100644 (file)
@@ -59,20 +59,50 @@ fn annotate<F>(
     ) where
         F: FnOnce(&mut Self),
     {
+        debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
+        let mut did_error = false;
         if !self.tcx.features().staged_api {
-            self.forbid_staged_api_attrs(hir_id, attrs, item_sp, kind, visit_children);
-            return;
+            did_error = self.forbid_staged_api_attrs(hir_id, attrs);
         }
 
-        // This crate explicitly wants staged API.
+        let depr = if did_error {
+            None
+        } else {
+            attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp)
+        };
+        let mut is_deprecated = false;
+        if let Some(depr) = &depr {
+            is_deprecated = true;
 
-        debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
-        if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
-            self.tcx.sess.span_err(
-                item_sp,
-                "`#[deprecated]` cannot be used in staged API; \
-                                             use `#[rustc_deprecated]` instead",
+            if kind == AnnotationKind::Prohibited {
+                self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
+            }
+
+            // `Deprecation` is just two pointers, no need to intern it
+            let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
+            self.index.depr_map.insert(hir_id, depr_entry);
+        } else if let Some(parent_depr) = self.parent_depr.clone() {
+            is_deprecated = true;
+            info!("tagging child {:?} as deprecated from parent", hir_id);
+            self.index.depr_map.insert(hir_id, parent_depr);
+        }
+
+        if self.tcx.features().staged_api {
+            if let Some(..) = attrs.iter().find(|a| a.check_name(sym::deprecated)) {
+                self.tcx.sess.span_err(
+                    item_sp,
+                    "`#[deprecated]` cannot be used in staged API; \
+                                                use `#[rustc_deprecated]` instead",
+                );
+            }
+        } else {
+            self.recurse_with_stability_attrs(
+                depr.map(|d| DeprecationEntry::local(d, hir_id)),
+                None,
+                None,
+                visit_children,
             );
+            return;
         }
 
         let (stab, const_stab) = attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp);
@@ -92,33 +122,34 @@ fn annotate<F>(
             }
         }
 
-        let stab = stab.map(|mut stab| {
+        if depr.as_ref().map_or(false, |d| d.is_since_rustc_version) {
+            if stab.is_none() {
+                struct_span_err!(
+                    self.tcx.sess,
+                    item_sp,
+                    E0549,
+                    "rustc_deprecated attribute must be paired with \
+                    either stable or unstable attribute"
+                )
+                .emit();
+            }
+        }
+
+        let stab = stab.map(|stab| {
             // Error if prohibited, or can't inherit anything from a container.
             if kind == AnnotationKind::Prohibited
-                || (kind == AnnotationKind::Container
-                    && stab.level.is_stable()
-                    && stab.rustc_depr.is_none())
+                || (kind == AnnotationKind::Container && stab.level.is_stable() && is_deprecated)
             {
                 self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
             }
 
             debug!("annotate: found {:?}", stab);
-            // If parent is deprecated and we're not, inherit this by merging
-            // deprecated_since and its reason.
-            if let Some(parent_stab) = self.parent_stab {
-                if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() {
-                    stab.rustc_depr = parent_stab.rustc_depr
-                }
-            }
-
             let stab = self.tcx.intern_stability(stab);
 
             // Check if deprecated_since < stable_since. If it is,
             // this is *almost surely* an accident.
-            if let (
-                &Some(attr::RustcDeprecation { since: dep_since, .. }),
-                &attr::Stable { since: stab_since },
-            ) = (&stab.rustc_depr, &stab.level)
+            if let (&Some(dep_since), &attr::Stable { since: stab_since }) =
+                (&depr.as_ref().and_then(|d| d.since), &stab.level)
             {
                 // Explicit version of iter::order::lt to handle parse errors properly
                 for (dep_v, stab_v) in
@@ -163,19 +194,29 @@ fn annotate<F>(
             }
         }
 
-        self.recurse_with_stability_attrs(stab, const_stab, visit_children);
+        self.recurse_with_stability_attrs(
+            depr.map(|d| DeprecationEntry::local(d, hir_id)),
+            stab,
+            const_stab,
+            visit_children,
+        );
     }
 
     fn recurse_with_stability_attrs(
         &mut self,
+        depr: Option<DeprecationEntry>,
         stab: Option<&'tcx Stability>,
         const_stab: Option<&'tcx ConstStability>,
         f: impl FnOnce(&mut Self),
     ) {
         // These will be `Some` if this item changes the corresponding stability attribute.
+        let mut replaced_parent_depr = None;
         let mut replaced_parent_stab = None;
         let mut replaced_parent_const_stab = None;
 
+        if let Some(depr) = depr {
+            replaced_parent_depr = Some(replace(&mut self.parent_depr, Some(depr)));
+        }
         if let Some(stab) = stab {
             replaced_parent_stab = Some(replace(&mut self.parent_stab, Some(stab)));
         }
@@ -186,6 +227,9 @@ fn recurse_with_stability_attrs(
 
         f(self);
 
+        if let Some(orig_parent_depr) = replaced_parent_depr {
+            self.parent_depr = orig_parent_depr;
+        }
         if let Some(orig_parent_stab) = replaced_parent_stab {
             self.parent_stab = orig_parent_stab;
         }
@@ -194,14 +238,8 @@ fn recurse_with_stability_attrs(
         }
     }
 
-    fn forbid_staged_api_attrs(
-        &mut self,
-        hir_id: HirId,
-        attrs: &[Attribute],
-        item_sp: Span,
-        kind: AnnotationKind,
-        visit_children: impl FnOnce(&mut Self),
-    ) {
+    // returns true if an error occurred, used to suppress some spurious errors
+    fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute]) -> bool {
         // Emit errors for non-staged-api crates.
         let unstable_attrs = [
             sym::unstable,
@@ -210,6 +248,7 @@ fn forbid_staged_api_attrs(
             sym::rustc_const_unstable,
             sym::rustc_const_stable,
         ];
+        let mut has_error = false;
         for attr in attrs {
             let name = attr.name_or_empty();
             if unstable_attrs.contains(&name) {
@@ -221,6 +260,7 @@ fn forbid_staged_api_attrs(
                     "stability attributes may not be used outside of the standard library",
                 )
                 .emit();
+                has_error = true;
             }
         }
 
@@ -232,24 +272,7 @@ fn forbid_staged_api_attrs(
             }
         }
 
-        if let Some(depr) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
-            if kind == AnnotationKind::Prohibited {
-                self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
-            }
-
-            // `Deprecation` is just two pointers, no need to intern it
-            let depr_entry = DeprecationEntry::local(depr, hir_id);
-            self.index.depr_map.insert(hir_id, depr_entry.clone());
-
-            let orig_parent_depr = replace(&mut self.parent_depr, Some(depr_entry));
-            visit_children(self);
-            self.parent_depr = orig_parent_depr;
-        } else if let Some(parent_depr) = self.parent_depr.clone() {
-            self.index.depr_map.insert(hir_id, parent_depr);
-            visit_children(self);
-        } else {
-            visit_children(self);
-        }
+        has_error
     }
 }
 
@@ -454,7 +477,6 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
                     is_soft: false,
                 },
                 feature: sym::rustc_private,
-                rustc_depr: None,
             });
             annotator.parent_stab = Some(stability);
         }
index 3976e501c169feb0f46574bf1b19c53f70d5f1df..fee7cb4836e3d6a61e11901540979b02f4e33b23 100644 (file)
@@ -1017,22 +1017,17 @@ fn check_stability_and_deprecation(
                     );
                 }
             }
-            if let Some(depr) = &stability.rustc_depr {
-                let path = pprust::path_to_string(path);
-                let (message, lint) = stability::rustc_deprecation_message(depr, &path);
-                stability::early_report_deprecation(
-                    &mut self.lint_buffer,
-                    &message,
-                    depr.suggestion,
-                    lint,
-                    span,
-                );
-            }
         }
         if let Some(depr) = &ext.deprecation {
             let path = pprust::path_to_string(&path);
             let (message, lint) = stability::deprecation_message(depr, &path);
-            stability::early_report_deprecation(&mut self.lint_buffer, &message, None, lint, span);
+            stability::early_report_deprecation(
+                &mut self.lint_buffer,
+                &message,
+                depr.suggestion,
+                lint,
+                span,
+            );
         }
     }
 
index 839ffa5785adacb372b7068475b3998ebe25e49f..620a04b45b0e4c457823af78a21d1bc9abf2b38b 100644 (file)
@@ -103,7 +103,7 @@ pub enum Strip {
     Symbols,
 }
 
-/// The different settings that the `-Z control-flow-guard` flag can have.
+/// The different settings that the `-C control-flow-guard` flag can have.
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum CFGuard {
     /// Do not emit Control Flow Guard metadata or checks.
index 6b2097240e215f5d4d75af507f42a3478e1dea19..502102fa1787647139a57ffa11dc4b14868bc736 100644 (file)
@@ -692,6 +692,8 @@ fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool {
         "choose the code model to use (`rustc --print code-models` for details)"),
     codegen_units: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
         "divide crate into N units to optimize in parallel"),
+    control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED],
+        "use Windows Control Flow Guard (default: no)"),
     debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "explicitly enable the `cfg(debug_assertions)` directive"),
     debuginfo: usize = (0, parse_uint, [TRACKED],
@@ -809,8 +811,6 @@ fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool {
         "enable the experimental Chalk-based trait solving engine"),
     codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
         "the backend to use"),
-    control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED],
-        "use Windows Control Flow Guard (default: no)"),
     crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
         "inject the given attribute in the crate"),
     debug_macros: bool = (false, parse_bool, [TRACKED],
@@ -949,7 +949,7 @@ fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool {
         (default: PLT is disabled if full relro is enabled)"),
     polonius: bool = (false, parse_bool, [UNTRACKED],
         "enable polonius-based borrow-checker (default: no)"),
-    polymorphize: bool = (true, parse_bool, [TRACKED],
+    polymorphize: bool = (false, parse_bool, [TRACKED],
           "perform polymorphization analysis"),
     pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED],
         "a single extra argument to prepend the linker invocation (can be used several times)"),
index 4ad95e95e9a86a68fe5e30eebf489878e3067909..1b8f6cdd8bebcc7a2d8bd328a4dd14d25a7c27be 100644 (file)
@@ -548,7 +548,7 @@ pub fn asm_comments(&self) -> bool {
         self.opts.debugging_opts.asm_comments
     }
     pub fn verify_llvm_ir(&self) -> bool {
-        self.opts.debugging_opts.verify_llvm_ir || cfg!(always_verify_llvm_ir)
+        self.opts.debugging_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some()
     }
     pub fn borrowck_stats(&self) -> bool {
         self.opts.debugging_opts.borrowck_stats
diff --git a/src/librustc_target/build.rs b/src/librustc_target/build.rs
deleted file mode 100644 (file)
index 368200b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_DEFAULT_LINKER");
-}
diff --git a/src/librustc_target/spec/aarch64_apple_darwin.rs b/src/librustc_target/spec/aarch64_apple_darwin.rs
new file mode 100644 (file)
index 0000000..60daf10
--- /dev/null
@@ -0,0 +1,30 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::apple_base::opts();
+    base.cpu = "apple-a12".to_string();
+    base.max_atomic_width = Some(128);
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
+
+    base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
+
+    // Clang automatically chooses a more specific target based on
+    // MACOSX_DEPLOYMENT_TARGET.  To enable cross-language LTO to work
+    // correctly, we do too.
+    let arch = "aarch64";
+    let llvm_target = super::apple_base::macos_llvm_target(&arch);
+
+    Ok(Target {
+        llvm_target,
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: arch.to_string(),
+        target_os: "macos".to_string(),
+        target_env: String::new(),
+        target_vendor: "apple".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: TargetOptions { target_mcount: "\u{1}mcount".to_string(), ..base },
+    })
+}
index bdd5a893d34e2c19c1a300b986010ceb32fd2736..e7b565ae9cad979a7741b6509713db4ae8157d9f 100644 (file)
@@ -31,6 +31,7 @@ pub fn opts() -> TargetOptions {
         has_elf_tls: version >= (10, 7),
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
+        eh_frame_header: false,
 
         // This environment variable is pretty magical but is intended for
         // producing deterministic builds. This was first discovered to be used
index 5402ea074fae1ee891c64a17560783761408ff6e..c338856228dc66b607304672531fe61243f4b3ce 100644 (file)
@@ -25,6 +25,7 @@ pub fn opts() -> TargetOptions {
         has_rpath: false,
         pre_link_args: args,
         position_independent_executables: false,
+        eh_frame_header: false,
         ..Default::default()
     }
 }
index 35ac346fb3f6f1586d6f32167aa00b04a9c1be41..214142b88fc2c7721f6617ba6e999abdbb6d0c25 100644 (file)
@@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
         is_like_solaris: true,
         limit_rdylib_exports: false, // Linker doesn't support this
         eliminate_frame_pointer: false,
+        eh_frame_header: false,
         late_link_args,
 
         // While we support ELF TLS, rust requires a way to register
index d53033ba3ba2043d79e4330df412e17455f5f782..961a438fd233cc175c5019a5d984ab5a0eb2de58 100644 (file)
@@ -574,6 +574,7 @@ fn $module() {
     ("i686-unknown-haiku", i686_unknown_haiku),
     ("x86_64-unknown-haiku", x86_64_unknown_haiku),
 
+    ("aarch64-apple-darwin", aarch64_apple_darwin),
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
 
@@ -987,6 +988,11 @@ pub struct TargetOptions {
     /// Whether to use legacy .ctors initialization hooks rather than .init_array. Defaults
     /// to false (uses .init_array).
     pub use_ctors_section: bool,
+
+    /// Whether the linker is instructed to add a `GNU_EH_FRAME` ELF header
+    /// used to locate unwinding information is passed
+    /// (only has effect if the linker is `ld`-like).
+    pub eh_frame_header: bool,
 }
 
 impl Default for TargetOptions {
@@ -1078,6 +1084,7 @@ fn default() -> TargetOptions {
             relax_elf_relocations: false,
             llvm_args: vec![],
             use_ctors_section: false,
+            eh_frame_header: true,
         }
     }
 }
@@ -1470,6 +1477,7 @@ macro_rules! key {
         key!(relax_elf_relocations, bool);
         key!(llvm_args, list);
         key!(use_ctors_section, bool);
+        key!(eh_frame_header, bool);
 
         // NB: The old name is deprecated, but support for it is retained for
         // compatibility.
@@ -1707,6 +1715,7 @@ macro_rules! target_option_val {
         target_option_val!(relax_elf_relocations);
         target_option_val!(llvm_args);
         target_option_val!(use_ctors_section);
+        target_option_val!(eh_frame_header);
 
         if default.unsupported_abis != self.options.unsupported_abis {
             d.insert(
index c6d0308f8f82feec5ef3022e3dab8b44a304cb12..f75697996ac7863870e02b78052bc5a09c613945 100644 (file)
@@ -56,6 +56,8 @@ pub fn target() -> TargetResult {
             // See the thumb_base.rs file for an explanation of this value
             emit_debug_gdb_scripts: false,
 
+            eh_frame_header: false,
+
             ..Default::default()
         },
     })
index 977aa896f2520573df84a8c8b7eea9b708f7d078..5b5e342000b55d70d486a0bc508215ef983e3785 100644 (file)
@@ -25,6 +25,7 @@ pub fn target() -> TargetResult {
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
             unsupported_abis: super::riscv_base::unsupported_abis(),
+            eh_frame_header: false,
             ..Default::default()
         },
     })
index 1a85cdff1315ca0f41a4fc2b1b2a89fd3ad606df..4cef5c42d8ddfc8c54d5036280a3fcd38402c563 100644 (file)
@@ -25,6 +25,7 @@ pub fn target() -> TargetResult {
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
             unsupported_abis: super::riscv_base::unsupported_abis(),
+            eh_frame_header: false,
             ..Default::default()
         },
     })
index e3c1c6908a23af24a13cba44b2bf421fe0bf3a0c..8ad563e441de3183345e829804e9c2befbdf814a 100644 (file)
@@ -25,6 +25,7 @@ pub fn target() -> TargetResult {
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
             unsupported_abis: super::riscv_base::unsupported_abis(),
+            eh_frame_header: false,
             ..Default::default()
         },
     })
index 857af4ceb0d9f1635a8e3cfbd9af18b07720372a..3aeb3f3ca72b2beef3b33f89641cc4a398105bcf 100644 (file)
@@ -26,6 +26,7 @@ pub fn target() -> TargetResult {
             code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
             unsupported_abis: super::riscv_base::unsupported_abis(),
+            eh_frame_header: false,
             ..Default::default()
         },
     })
index 36fe7730f95bfcaea3837c556d2a93683ea804e5..d8144964dc913277ea849a163e7dd68a55c51baf 100644 (file)
@@ -26,6 +26,7 @@ pub fn target() -> TargetResult {
             code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
             unsupported_abis: super::riscv_base::unsupported_abis(),
+            eh_frame_header: false,
             ..Default::default()
         },
     })
index 8d3a3563f4164a87fc6de8803e52be11da28a16f..3d7f0034b8b10dd128f5311102e431d93dcc9f2b 100644 (file)
@@ -8,6 +8,7 @@ pub fn opts() -> TargetOptions {
         target_family: Some("unix".to_string()),
         is_like_solaris: true,
         limit_rdylib_exports: false, // Linker doesn't support this
+        eh_frame_header: false,
 
         ..Default::default()
     }
index 680dbbad4b0a02e91f0bc76ef1570f0f82d7b156..69236e98e58d7890befe267b1076a2cfd6268f23 100644 (file)
@@ -91,6 +91,7 @@ pub fn opts() -> TargetOptions {
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
         requires_uwtable: true,
+        eh_frame_header: false,
 
         ..Default::default()
     }
index 31011e847495838d3a1083b6449c88942052b0f9..909aebec70b58766a1f26d55b7f6b2828903049e 100644 (file)
@@ -5,7 +5,10 @@ pub fn target() -> TargetResult {
     base.cpu = "core2".to_string();
     base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
-    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
+    base.pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()],
+    );
     base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
     base.stack_probes = true;
 
index cf575d3eca9c226853e7481af7b0b728f180a0ae..dd7ea55cc1043693be0a1e0e96399a602c21c32e 100644 (file)
@@ -6,6 +6,7 @@
 use crate::infer::{InferCtxt, TyCtxtInferExt};
 use crate::traits::{
     FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine,
+    Unimplemented,
 };
 use rustc_errors::ErrorReported;
 use rustc_middle::ty::fold::TypeFoldable;
@@ -58,6 +59,18 @@ pub fn codegen_fulfill_obligation<'tcx>(
                 );
                 return Err(ErrorReported);
             }
+            Err(Unimplemented) => {
+                // This can trigger when we probe for the source of a `'static` lifetime requirement
+                // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
+                infcx.tcx.sess.delay_span_bug(
+                    rustc_span::DUMMY_SP,
+                    &format!(
+                        "Encountered error `Unimplemented` selecting `{:?}` during codegen",
+                        trait_ref
+                    ),
+                );
+                return Err(ErrorReported);
+            }
             Err(e) => {
                 bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref)
             }
index 3ec7fe2bf25c68f2635fb64f117a8487ee374bde..b06cf4411d053188e80f90188b4ea1c5125a526f 100644 (file)
@@ -289,11 +289,11 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
 ///     - but (knowing that `Vec<T>` is non-fundamental, and assuming it's
 ///       not local), `Vec<LocalType>` is bad, because `Vec<->` is between
 ///       the local type and the type parameter.
-/// 3. Every type parameter before the local key parameter is fully known in C.
-///     - e.g., `impl<T> T: Trait<LocalType>` is bad, because `T` might be
-///       an unknown type.
-///     - but `impl<T> LocalType: Trait<T>` is OK, because `LocalType`
-///       occurs before `T`.
+/// 3. Before this local type, no generic type parameter of the impl must
+///    be reachable through fundamental types.
+///     - e.g. `impl<T> Trait<LocalType> for Vec<T>` is fine, as `Vec` is not fundamental.
+///     - while `impl<T> Trait<LocalType for Box<T>` results in an error, as `T` is
+///       reachable through the fundamental type `Box`.
 /// 4. Every type in the local key parameter not known in C, going
 ///    through the parameter's type tree, must appear only as a subtree of
 ///    a type local to C, with only fundamental types between the type
@@ -387,9 +387,9 @@ fn uncover_fundamental_ty<'tcx>(
         ty: Ty<'tcx>,
         in_crate: InCrate,
     ) -> Vec<Ty<'tcx>> {
-        // FIXME(eddyb) figure out if this is redundant with `ty_is_non_local`,
-        // or maybe if this should be calling `ty_is_non_local_constructor`.
-        if ty_is_non_local(tcx, ty, in_crate).is_some() {
+        // FIXME: this is currently somewhat overly complicated,
+        // but fixing this requires a more complicated refactor.
+        if !contained_non_local_types(tcx, ty, in_crate).is_empty() {
             if let Some(inner_tys) = fundamental_ty_inner_tys(tcx, ty) {
                 return inner_tys
                     .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
@@ -408,8 +408,8 @@ fn uncover_fundamental_ty<'tcx>(
         .enumerate()
     {
         debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
-        let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
-        if non_local_tys.is_none() {
+        let non_local_tys = contained_non_local_types(tcx, input_ty, in_crate);
+        if non_local_tys.is_empty() {
             debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
             return Ok(());
         } else if let ty::Param(_) = input_ty.kind {
@@ -418,16 +418,15 @@ fn uncover_fundamental_ty<'tcx>(
                 .substs
                 .types()
                 .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
-                .find(|ty| ty_is_non_local_constructor(ty, in_crate).is_none());
+                .find(|ty| ty_is_local_constructor(ty, in_crate));
 
             debug!("orphan_check_trait_ref: uncovered ty local_type: `{:?}`", local_type);
 
             return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type));
         }
-        if let Some(non_local_tys) = non_local_tys {
-            for input_ty in non_local_tys {
-                non_local_spans.push((input_ty, i == 0));
-            }
+
+        for input_ty in non_local_tys {
+            non_local_spans.push((input_ty, i == 0));
         }
     }
     // If we exit above loop, never found a local type.
@@ -435,20 +434,29 @@ fn uncover_fundamental_ty<'tcx>(
     Err(OrphanCheckErr::NonLocalInputType(non_local_spans))
 }
 
-fn ty_is_non_local(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, in_crate: InCrate) -> Option<Vec<Ty<'tcx>>> {
-    match ty_is_non_local_constructor(ty, in_crate) {
-        Some(ty) => {
-            if let Some(inner_tys) = fundamental_ty_inner_tys(tcx, ty) {
-                let tys: Vec<_> = inner_tys
-                    .filter_map(|ty| ty_is_non_local(tcx, ty, in_crate))
-                    .flatten()
-                    .collect();
-                if tys.is_empty() { None } else { Some(tys) }
-            } else {
-                Some(vec![ty])
+/// Returns a list of relevant non-local types for `ty`.
+///
+/// This is just `ty` itself unless `ty` is `#[fundamental]`,
+/// in which case we recursively look into this type.
+///
+/// If `ty` is local itself, this method returns an empty `Vec`.
+///
+/// # Examples
+///
+/// - `u32` is not local, so this returns `[u32]`.
+/// - for `Foo<u32>`, where `Foo` is a local type, this returns `[]`.
+/// - `&mut u32` returns `[u32]`, as `&mut` is a fundamental type, similar to `Box`.
+/// - `Box<Foo<u32>>` returns `[]`, as `Box` is a fundamental type and `Foo` is local.
+fn contained_non_local_types(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
+    if ty_is_local_constructor(ty, in_crate) {
+        Vec::new()
+    } else {
+        match fundamental_ty_inner_tys(tcx, ty) {
+            Some(inner_tys) => {
+                inner_tys.flat_map(|ty| contained_non_local_types(tcx, ty, in_crate)).collect()
             }
+            None => vec![ty],
         }
-        None => None,
     }
 }
 
@@ -493,9 +501,8 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
     }
 }
 
-// FIXME(eddyb) this can just return `bool` as it always returns `Some(ty)` or `None`.
-fn ty_is_non_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> Option<Ty<'_>> {
-    debug!("ty_is_non_local_constructor({:?})", ty);
+fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
+    debug!("ty_is_local_constructor({:?})", ty);
 
     match ty.kind {
         ty::Bool
@@ -513,29 +520,17 @@ fn ty_is_non_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> Option<Ty<'_>>
         | ty::Never
         | ty::Tuple(..)
         | ty::Param(..)
-        | ty::Projection(..) => Some(ty),
+        | ty::Projection(..) => false,
 
         ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate {
-            InCrate::Local => Some(ty),
+            InCrate::Local => false,
             // The inference variable might be unified with a local
             // type in that remote crate.
-            InCrate::Remote => None,
+            InCrate::Remote => true,
         },
 
-        ty::Adt(def, _) => {
-            if def_id_is_local(def.did, in_crate) {
-                None
-            } else {
-                Some(ty)
-            }
-        }
-        ty::Foreign(did) => {
-            if def_id_is_local(did, in_crate) {
-                None
-            } else {
-                Some(ty)
-            }
-        }
+        ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
+        ty::Foreign(did) => def_id_is_local(did, in_crate),
         ty::Opaque(..) => {
             // This merits some explanation.
             // Normally, opaque types are not involed when performing
@@ -553,7 +548,7 @@ fn ty_is_non_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> Option<Ty<'_>>
             // the underlying type *within the same crate*. When an
             // opaque type is used from outside the module
             // where it is declared, it should be impossible to observe
-            // anyything about it other than the traits that it implements.
+            // anything about it other than the traits that it implements.
             //
             // The alternative would be to look at the underlying type
             // to determine whether or not the opaque type itself should
@@ -562,18 +557,18 @@ fn ty_is_non_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> Option<Ty<'_>>
             // to a remote type. This would violate the rule that opaque
             // types should be completely opaque apart from the traits
             // that they implement, so we don't use this behavior.
-            Some(ty)
+            false
         }
 
         ty::Dynamic(ref tt, ..) => {
             if let Some(principal) = tt.principal() {
-                if def_id_is_local(principal.def_id(), in_crate) { None } else { Some(ty) }
+                def_id_is_local(principal.def_id(), in_crate)
             } else {
-                Some(ty)
+                false
             }
         }
 
-        ty::Error(_) => None,
+        ty::Error(_) => true,
 
         ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => {
             bug!("ty_is_local invoked on unexpected type: {:?}", ty)
index 0a6fb72ca51eae890af70698ac34d8b50d788cf9..0632ce2319aeef1d462898e2537243cbcd7f0d42 100644 (file)
@@ -1706,6 +1706,7 @@ fn note_obligation_cause_code<T>(
             | ObligationCauseCode::IntrinsicType
             | ObligationCauseCode::MethodReceiver
             | ObligationCauseCode::ReturnNoExpression
+            | ObligationCauseCode::UnifyReceiver(..)
             | ObligationCauseCode::MiscObligation => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
index 96248e18aaf87a44fb6b9be380a14c112dfbd38d..ed84095ae6b0cbc4a5a6d7094edb3eea07cd9509 100644 (file)
@@ -6,6 +6,7 @@
 use crate::hir::GenericArg;
 use rustc_hir as hir;
 use rustc_infer::infer::{self, InferOk};
+use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
 use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::fold::TypeFoldable;
@@ -91,7 +92,11 @@ fn confirm(
         // signature (which is also done during probing).
         let method_sig_rcvr =
             self.normalize_associated_types_in(self.span, &method_sig.inputs()[0]);
-        self.unify_receivers(self_ty, method_sig_rcvr);
+        debug!(
+            "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}",
+            self_ty, method_sig_rcvr, method_sig, method_predicates
+        );
+        self.unify_receivers(self_ty, method_sig_rcvr, &pick, all_substs);
 
         let (method_sig, method_predicates) =
             self.normalize_associated_types_in(self.span, &(method_sig, method_predicates));
@@ -150,7 +155,7 @@ fn adjust_self_ty(
             self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
 
         if let Some(mutbl) = pick.autoref {
-            let region = self.next_region_var(infer::Autoref(self.span));
+            let region = self.next_region_var(infer::Autoref(self.span, pick.item));
             target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl, ty: target });
             let mutbl = match mutbl {
                 hir::Mutability::Not => AutoBorrowMutability::Not,
@@ -334,8 +339,26 @@ fn instantiate_method_substs(
         )
     }
 
-    fn unify_receivers(&mut self, self_ty: Ty<'tcx>, method_self_ty: Ty<'tcx>) {
-        match self.at(&self.misc(self.span), self.param_env).sup(method_self_ty, self_ty) {
+    fn unify_receivers(
+        &mut self,
+        self_ty: Ty<'tcx>,
+        method_self_ty: Ty<'tcx>,
+        pick: &probe::Pick<'tcx>,
+        substs: SubstsRef<'tcx>,
+    ) {
+        debug!(
+            "unify_receivers: self_ty={:?} method_self_ty={:?} span={:?} pick={:?}",
+            self_ty, method_self_ty, self.span, pick
+        );
+        let cause = self.cause(
+            self.span,
+            ObligationCauseCode::UnifyReceiver(Box::new(UnifyReceiverContext {
+                assoc_item: pick.item,
+                param_env: self.param_env,
+                substs,
+            })),
+        );
+        match self.at(&cause, self.param_env).sup(method_self_ty, self_ty) {
             Ok(InferOk { obligations, value: () }) => {
                 self.register_predicates(obligations);
             }
index 04e02704296defd79c3b2a8cbfc98eaee84c2eaf..6e77aba30506a5ba89c946207752d7be27d7745a 100644 (file)
@@ -256,14 +256,6 @@ pub struct Inherited<'a, 'tcx> {
     /// opaque type.
     opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
 
-    /// Each type parameter has an implicit region bound that
-    /// indicates it must outlive at least the function body (the user
-    /// may specify stronger requirements). This field indicates the
-    /// region of the callee. If it is `None`, then the parameter
-    /// environment is for an item or something where the "callee" is
-    /// not clear.
-    implicit_region_bound: Option<ty::Region<'tcx>>,
-
     body_id: Option<hir::BodyId>,
 }
 
@@ -684,7 +676,6 @@ fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
             deferred_generator_interiors: RefCell::new(Vec::new()),
             opaque_types: RefCell::new(Default::default()),
             opaque_types_vars: RefCell::new(Default::default()),
-            implicit_region_bound: None,
             body_id,
         }
     }
index b72152d1911f7dc5851f627149f7d5d1205335aa..221e5f72dc977b135d5a263212ecf5094d187285 100644 (file)
@@ -309,7 +309,7 @@ fn visit_region_obligations(&mut self, hir_id: hir::HirId) {
     fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
         self.infcx.process_registered_region_obligations(
             self.outlives_environment.region_bound_pairs_map(),
-            self.implicit_region_bound,
+            Some(self.tcx.lifetimes.re_root_empty),
             self.param_env,
         );
 
index c3b54f146142649591cad2bffb5e4ad4747f3004..cb9348a9521bcd6e05f4061080d41ac76752cdd7 100644 (file)
@@ -730,7 +730,13 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
             placeholder_type_error(tcx, None, &[], visitor.0, false);
         }
 
-        hir::TraitItemKind::Type(_, None) => {}
+        hir::TraitItemKind::Type(_, None) => {
+            // #74612: Visit and try to find bad placeholders
+            // even if there is no concrete type.
+            let mut visitor = PlaceholderHirTyCollector::default();
+            visitor.visit_trait_item(trait_item);
+            placeholder_type_error(tcx, None, &[], visitor.0, false);
+        }
     };
 
     tcx.ensure().predicates_of(def_id);
index 8a4ee91df405fcb8b033ec6911e8916b71154aaf..94d95115dcdbcaed7bfd447b6cc22331da063d87 100644 (file)
@@ -2353,10 +2353,6 @@ fn clean(&self, _: &DocContext<'_>) -> Stability {
                 attr::Stable { ref since } => since.to_string(),
                 _ => String::new(),
             },
-            deprecation: self.rustc_depr.as_ref().map(|d| Deprecation {
-                note: Some(d.reason.to_string()).filter(|r| !r.is_empty()),
-                since: Some(d.since.to_string()).filter(|d| !d.is_empty()),
-            }),
             unstable_reason: match self.level {
                 attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
                 _ => None,
@@ -2374,6 +2370,7 @@ fn clean(&self, _: &DocContext<'_>) -> Deprecation {
         Deprecation {
             since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()),
             note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()),
+            is_since_rustc_version: self.is_since_rustc_version,
         }
     }
 }
index 6a03722cd0802786f31710bb146e981c3fecf13e..071834c59d65ec749aafa5f8b4a72113638b74d7 100644 (file)
@@ -195,7 +195,8 @@ pub fn stability_class(&self) -> Option<String> {
                 classes.push("unstable");
             }
 
-            if s.deprecation.is_some() {
+            // FIXME: what about non-staged API items that are deprecated?
+            if self.deprecation.is_some() {
                 classes.push("deprecated");
             }
 
@@ -216,14 +217,6 @@ pub fn type_(&self) -> ItemType {
         ItemType::from(self)
     }
 
-    /// Returns the info in the item's `#[deprecated]` or `#[rustc_deprecated]` attributes.
-    ///
-    /// If the item is not deprecated, returns `None`.
-    pub fn deprecation(&self) -> Option<&Deprecation> {
-        self.deprecation
-            .as_ref()
-            .or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref()))
-    }
     pub fn is_default(&self) -> bool {
         match self.inner {
             ItemEnum::MethodItem(ref meth) => {
@@ -1528,7 +1521,6 @@ pub struct Stability {
     pub level: stability::StabilityLevel,
     pub feature: Option<String>,
     pub since: String,
-    pub deprecation: Option<Deprecation>,
     pub unstable_reason: Option<String>,
     pub issue: Option<NonZeroU32>,
 }
@@ -1537,6 +1529,7 @@ pub struct Stability {
 pub struct Deprecation {
     pub since: Option<String>,
     pub note: Option<String>,
+    pub is_since_rustc_version: bool,
 }
 
 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
index f872ed7010c7537ad3aae0cdec855f2e6a771213..f7050cf377722622eee91859903f82a04b0cf5d0 100644 (file)
@@ -2216,16 +2216,10 @@ fn tag_html(class: &str, contents: &str) -> String {
     }
 
     // The trailing space after each tag is to space it properly against the rest of the docs.
-    if item.deprecation().is_some() {
+    if let Some(depr) = &item.deprecation {
         let mut message = "Deprecated";
-        if let Some(ref stab) = item.stability {
-            if let Some(ref depr) = stab.deprecation {
-                if let Some(ref since) = depr.since {
-                    if !stability::deprecation_in_effect(&since) {
-                        message = "Deprecation planned";
-                    }
-                }
-            }
+        if !stability::deprecation_in_effect(depr.is_since_rustc_version, depr.since.as_deref()) {
+            message = "Deprecation planned";
         }
         tags += &tag_html("deprecated", message);
     }
@@ -2254,23 +2248,18 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
     let mut stability = vec![];
     let error_codes = cx.shared.codes;
 
-    if let Some(Deprecation { note, since }) = &item.deprecation() {
+    if let Some(Deprecation { ref note, ref since, is_since_rustc_version }) = item.deprecation {
         // We display deprecation messages for #[deprecated] and #[rustc_deprecated]
         // but only display the future-deprecation messages for #[rustc_deprecated].
         let mut message = if let Some(since) = since {
-            format!("Deprecated since {}", Escape(since))
+            if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
+                format!("Deprecating in {}", Escape(&since))
+            } else {
+                format!("Deprecated since {}", Escape(&since))
+            }
         } else {
             String::from("Deprecated")
         };
-        if let Some(ref stab) = item.stability {
-            if let Some(ref depr) = stab.deprecation {
-                if let Some(ref since) = depr.since {
-                    if !stability::deprecation_in_effect(&since) {
-                        message = format!("Deprecating in {}", Escape(&since));
-                    }
-                }
-            }
-        }
 
         if let Some(note) = note {
             let mut ids = cx.id_map.borrow_mut();
index 850a4b3cbc216f38dce50447e486f0e05b80c3e6..d0312d77a7c5d5867e5c027b76ae27957b910454 100644 (file)
@@ -1291,6 +1291,16 @@ h4 > .important-traits {
 
 /* Media Queries */
 
+@media (min-width: 701px) {
+       /* In case there is no documentation before a code block, we need to add some margin at the top
+       to prevent an overlay between the "collapse toggle" and the information tooltip.
+       However, it's needed needed with smaller screen width because the doc/code block is always put
+       "one line" below. */
+       .information:first-child > .tooltip {
+               margin-top: 16px;
+       }
+}
+
 @media (max-width: 700px) {
        body {
                padding-top: 0px;
index 96ba5c46a3cded556bf73b004fd4425155bd245e..41fe8e0fafb413185b7fa4e0043758435b2539d4 100644 (file)
@@ -62,6 +62,10 @@ pre {
        background-color: #14191f;
 }
 
+.logo-container > img {
+       filter: drop-shadow(0 0 5px #fff);
+}
+
 /* Improve the scrollbar display on firefox */
 * {
        scrollbar-color: #5c6773 transparent;
@@ -322,7 +326,7 @@ a.test-arrow:hover {
 
 :target > code, :target > .in-band {
        background: rgba(255, 236, 164, 0.06);
-       border-right: 3px solid #ffb44c;
+       border-right: 3px solid rgba(255, 180, 76, 0.85);
 }
 
 pre.compile_fail {
index 33c0f885fa95b4afe9f136c299f4db23e9c59b1b..b3b586ba362fa475b9f7c5c392bcf126305527c8 100644 (file)
@@ -34,6 +34,10 @@ pre {
        background-color: #505050;
 }
 
+.logo-container > img {
+       filter: drop-shadow(0 0 5px #fff);
+}
+
 /* Improve the scrollbar display on firefox */
 * {
        scrollbar-color: rgb(64, 65, 67) #717171;
@@ -270,6 +274,7 @@ a.test-arrow:hover{
 
 :target > code, :target > .in-band {
        background-color: #494a3d;
+       border-right: 3px solid #bb7410;
 }
 
 pre.compile_fail {
index 569ce7da2091f07d79c2499d6f7fe4335de6bdd6..b0c5715604baab86ea5d29eab697f5b3b6a0701f 100644 (file)
@@ -45,6 +45,10 @@ pre {
        scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9;
 }
 
+.logo-container > img {
+       filter: drop-shadow(0 0 5px #aaa);
+}
+
 /* Improve the scrollbar display on webkit-based browsers */
 ::-webkit-scrollbar-track {
        background-color: #ecebeb;
@@ -265,6 +269,7 @@ a.test-arrow:hover{
 
 :target > code, :target > .in-band {
        background: #FDFFD3;
+       border-right: 3px solid #ffb44c;
 }
 
 pre.compile_fail {
index e187b9251f71e5194d002060dbca21f94b2211e7..5187839423d6b1d8e00f981b6ee2d54f07e5a310 100644 (file)
@@ -1,5 +1,5 @@
 use rustc_ast::ast;
-use rustc_errors::Applicability;
+use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_expand::base::SyntaxExtensionKind;
 use rustc_feature::UnstableFeatures;
 use rustc_hir as hir;
@@ -45,7 +45,17 @@ pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
 
 enum ErrorKind {
     ResolutionFailure,
-    AnchorFailure(&'static str),
+    AnchorFailure(AnchorFailure),
+}
+
+enum AnchorFailure {
+    MultipleAnchors,
+    Primitive,
+    Variant,
+    AssocConstant,
+    AssocType,
+    Field,
+    Method,
 }
 
 struct LinkCollector<'a, 'tcx> {
@@ -197,9 +207,7 @@ fn resolve(
                     // Not a trait item; just return what we found.
                     Res::PrimTy(..) => {
                         if extra_fragment.is_some() {
-                            return Err(ErrorKind::AnchorFailure(
-                                "primitive types cannot be followed by anchors",
-                            ));
+                            return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
                         }
                         return Ok((res, Some(path_str.to_owned())));
                     }
@@ -209,9 +217,7 @@ fn resolve(
                         if disambiguator == Some("type") {
                             if let Some(prim) = is_primitive(path_str, ns) {
                                 if extra_fragment.is_some() {
-                                    return Err(ErrorKind::AnchorFailure(
-                                        "primitive types cannot be followed by anchors",
-                                    ));
+                                    return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
                                 }
                                 return Ok((prim, Some(path_str.to_owned())));
                             }
@@ -228,9 +234,7 @@ fn resolve(
                 }
             } else if let Some(prim) = is_primitive(path_str, ns) {
                 if extra_fragment.is_some() {
-                    return Err(ErrorKind::AnchorFailure(
-                        "primitive types cannot be followed by anchors",
-                    ));
+                    return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
                 }
                 return Ok((prim, Some(path_str.to_owned())));
             } else {
@@ -338,9 +342,9 @@ fn resolve(
                         };
                         if extra_fragment.is_some() {
                             Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Fn {
-                                "methods cannot be followed by anchors"
+                                AnchorFailure::Method
                             } else {
-                                "associated constants cannot be followed by anchors"
+                                AnchorFailure::AssocConstant
                             }))
                         } else {
                             Ok((ty_res, Some(format!("{}.{}", out, item_name))))
@@ -358,9 +362,9 @@ fn resolve(
                                 } {
                                     if extra_fragment.is_some() {
                                         Err(ErrorKind::AnchorFailure(if def.is_enum() {
-                                            "enum variants cannot be followed by anchors"
+                                            AnchorFailure::Variant
                                         } else {
-                                            "struct fields cannot be followed by anchors"
+                                            AnchorFailure::Field
                                         }))
                                     } else {
                                         Ok((
@@ -404,11 +408,11 @@ fn resolve(
 
                         if extra_fragment.is_some() {
                             Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Const {
-                                "associated constants cannot be followed by anchors"
+                                AnchorFailure::AssocConstant
                             } else if item.kind == ty::AssocKind::Type {
-                                "associated types cannot be followed by anchors"
+                                AnchorFailure::AssocType
                             } else {
-                                "methods cannot be followed by anchors"
+                                AnchorFailure::Method
                             }))
                         } else {
                             Ok((ty_res, Some(format!("{}.{}", kind, item_name))))
@@ -559,16 +563,7 @@ fn fold_item(&mut self, mut item: Item) -> Option<Item> {
             let link = ori_link.replace("`", "");
             let parts = link.split('#').collect::<Vec<_>>();
             let (link, extra_fragment) = if parts.len() > 2 {
-                build_diagnostic(
-                    cx,
-                    &item,
-                    &link,
-                    &dox,
-                    link_range,
-                    "has an issue with the link anchor.",
-                    "only one `#` is allowed in a link",
-                    None,
-                );
+                anchor_failure(cx, &item, &link, &dox, link_range, AnchorFailure::MultipleAnchors);
                 continue;
             } else if parts.len() == 2 {
                 if parts[0].trim().is_empty() {
@@ -795,29 +790,22 @@ fn fold_item(&mut self, mut item: Item) -> Option<Item> {
                 item.attrs.links.push((ori_link, None, fragment));
             } else {
                 debug!("intra-doc link to {} resolved to {:?}", path_str, res);
-                if let Some(local) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
+
+                // item can be non-local e.g. when using #[doc(primitive = "pointer")]
+                if let Some((src_id, dst_id)) = res
+                    .opt_def_id()
+                    .and_then(|def_id| def_id.as_local())
+                    .and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id)))
+                {
                     use rustc_hir::def_id::LOCAL_CRATE;
 
-                    let hir_id = self.cx.tcx.hir().as_local_hir_id(local);
-                    if !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_id)
-                        && (item.visibility == Visibility::Public)
-                        && !self.cx.render_options.document_private
+                    let hir_src = self.cx.tcx.hir().as_local_hir_id(src_id);
+                    let hir_dst = self.cx.tcx.hir().as_local_hir_id(dst_id);
+
+                    if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src)
+                        && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
                     {
-                        let item_name = item.name.as_deref().unwrap_or("<unknown>");
-                        let err_msg = format!(
-                            "public documentation for `{}` links to a private item",
-                            item_name
-                        );
-                        build_diagnostic(
-                            cx,
-                            &item,
-                            path_str,
-                            &dox,
-                            link_range,
-                            &err_msg,
-                            "this item is private",
-                            None,
-                        );
+                        privacy_error(cx, &item, &path_str, &dox, link_range);
                         continue;
                     }
                 }
@@ -851,24 +839,33 @@ fn fold_crate(&mut self, mut c: Crate) -> Crate {
     }
 }
 
-fn build_diagnostic(
+/// Reports a diagnostic for an intra-doc link.
+///
+/// If no link range is provided, or the source span of the link cannot be determined, the span of
+/// the entire documentation block is used for the lint. If a range is provided but the span
+/// calculation fails, a note is added to the diagnostic pointing to the link in the markdown.
+///
+/// The `decorate` callback is invoked in all cases to allow further customization of the
+/// diagnostic before emission. If the span of the link was able to be determined, the second
+/// parameter of the callback will contain it, and the primary span of the diagnostic will be set
+/// to it.
+fn report_diagnostic(
     cx: &DocContext<'_>,
+    msg: &str,
     item: &Item,
-    path_str: &str,
     dox: &str,
     link_range: Option<Range<usize>>,
-    err_msg: &str,
-    short_err_msg: &str,
-    help_msg: Option<&str>,
+    decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
 ) {
     let hir_id = match cx.as_local_hir_id(item.def_id) {
         Some(hir_id) => hir_id,
         None => {
             // If non-local, no need to check anything.
-            info!("ignoring warning from parent crate: {}", err_msg);
+            info!("ignoring warning from parent crate: {}", msg);
             return;
         }
     };
+
     let attrs = &item.attrs;
     let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
 
@@ -877,12 +874,15 @@ fn build_diagnostic(
         hir_id,
         sp,
         |lint| {
-            let mut diag = lint.build(&format!("`[{}]` {}", path_str, err_msg));
+            let mut diag = lint.build(msg);
+
+            let span = link_range
+                .as_ref()
+                .and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs));
+
             if let Some(link_range) = link_range {
-                if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs)
-                {
+                if let Some(sp) = span {
                     diag.set_span(sp);
-                    diag.span_label(sp, short_err_msg);
                 } else {
                     // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
                     //                       ^     ~~~~
@@ -902,20 +902,15 @@ fn build_diagnostic(
                         found = link_range.len(),
                     ));
                 }
-            };
-            if let Some(help_msg) = help_msg {
-                diag.help(help_msg);
             }
+
+            decorate(&mut diag, span);
+
             diag.emit();
         },
     );
 }
 
-/// Reports a resolution failure diagnostic.
-///
-/// If we cannot find the exact source span of the resolution failure, we use the span of the
-/// documentation attributes themselves. This is a little heavy-handed, so we display the markdown
-/// line containing the failure as a note as well.
 fn resolution_failure(
     cx: &DocContext<'_>,
     item: &Item,
@@ -923,15 +918,19 @@ fn resolution_failure(
     dox: &str,
     link_range: Option<Range<usize>>,
 ) {
-    build_diagnostic(
+    report_diagnostic(
         cx,
+        &format!("unresolved link to `{}`", path_str),
         item,
-        path_str,
         dox,
         link_range,
-        "cannot be resolved, ignoring it.",
-        "cannot be resolved, ignoring",
-        Some("to escape `[` and `]` characters, just add '\\' before them like `\\[` or `\\]`"),
+        |diag, sp| {
+            if let Some(sp) = sp {
+                diag.span_label(sp, "unresolved link");
+            }
+
+            diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#);
+        },
     );
 }
 
@@ -941,18 +940,39 @@ fn anchor_failure(
     path_str: &str,
     dox: &str,
     link_range: Option<Range<usize>>,
-    msg: &str,
+    failure: AnchorFailure,
 ) {
-    build_diagnostic(
-        cx,
-        item,
-        path_str,
-        dox,
-        link_range,
-        "has an issue with the link anchor.",
-        msg,
-        None,
-    );
+    let msg = match failure {
+        AnchorFailure::MultipleAnchors => format!("`{}` contains multiple anchors", path_str),
+        AnchorFailure::Primitive
+        | AnchorFailure::Variant
+        | AnchorFailure::AssocConstant
+        | AnchorFailure::AssocType
+        | AnchorFailure::Field
+        | AnchorFailure::Method => {
+            let kind = match failure {
+                AnchorFailure::Primitive => "primitive type",
+                AnchorFailure::Variant => "enum variant",
+                AnchorFailure::AssocConstant => "associated constant",
+                AnchorFailure::AssocType => "associated type",
+                AnchorFailure::Field => "struct field",
+                AnchorFailure::Method => "method",
+                AnchorFailure::MultipleAnchors => unreachable!("should be handled already"),
+            };
+
+            format!(
+                "`{}` contains an anchor, but links to {kind}s are already anchored",
+                path_str,
+                kind = kind
+            )
+        }
+    };
+
+    report_diagnostic(cx, &msg, item, dox, link_range, |diag, sp| {
+        if let Some(sp) = sp {
+            diag.span_label(sp, "contains invalid anchor");
+        }
+    });
 }
 
 fn ambiguity_error(
@@ -963,121 +983,107 @@ fn ambiguity_error(
     link_range: Option<Range<usize>>,
     candidates: PerNS<Option<Res>>,
 ) {
-    let hir_id = match cx.as_local_hir_id(item.def_id) {
-        Some(hir_id) => hir_id,
-        None => {
-            // If non-local, no need to check anything.
-            return;
+    let mut msg = format!("`{}` is ", path_str);
+
+    let candidates = [TypeNS, ValueNS, MacroNS]
+        .iter()
+        .filter_map(|&ns| candidates[ns].map(|res| (res, ns)))
+        .collect::<Vec<_>>();
+    match candidates.as_slice() {
+        [(first_def, _), (second_def, _)] => {
+            msg += &format!(
+                "both {} {} and {} {}",
+                first_def.article(),
+                first_def.descr(),
+                second_def.article(),
+                second_def.descr(),
+            );
         }
-    };
-    let attrs = &item.attrs;
-    let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
-
-    cx.tcx.struct_span_lint_hir(
-        lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-        hir_id,
-        sp,
-        |lint| {
-            let mut msg = format!("`{}` is ", path_str);
-
-            let candidates = [TypeNS, ValueNS, MacroNS]
-                .iter()
-                .filter_map(|&ns| candidates[ns].map(|res| (res, ns)))
-                .collect::<Vec<_>>();
-            match candidates.as_slice() {
-                [(first_def, _), (second_def, _)] => {
-                    msg += &format!(
-                        "both {} {} and {} {}",
-                        first_def.article(),
-                        first_def.descr(),
-                        second_def.article(),
-                        second_def.descr(),
-                    );
-                }
-                _ => {
-                    let mut candidates = candidates.iter().peekable();
-                    while let Some((res, _)) = candidates.next() {
-                        if candidates.peek().is_some() {
-                            msg += &format!("{} {}, ", res.article(), res.descr());
-                        } else {
-                            msg += &format!("and {} {}", res.article(), res.descr());
-                        }
-                    }
+        _ => {
+            let mut candidates = candidates.iter().peekable();
+            while let Some((res, _)) = candidates.next() {
+                if candidates.peek().is_some() {
+                    msg += &format!("{} {}, ", res.article(), res.descr());
+                } else {
+                    msg += &format!("and {} {}", res.article(), res.descr());
                 }
             }
+        }
+    }
 
-            let mut diag = lint.build(&msg);
-
-            if let Some(link_range) = link_range {
-                if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs)
-                {
-                    diag.set_span(sp);
-                    diag.span_label(sp, "ambiguous link");
+    report_diagnostic(cx, &msg, item, dox, link_range.clone(), |diag, sp| {
+        if let Some(sp) = sp {
+            diag.span_label(sp, "ambiguous link");
 
-                    for (res, ns) in candidates {
-                        let (action, mut suggestion) = match res {
-                            Res::Def(DefKind::AssocFn | DefKind::Fn, _) => {
-                                ("add parentheses", format!("{}()", path_str))
-                            }
-                            Res::Def(DefKind::Macro(MacroKind::Bang), _) => {
-                                ("add an exclamation mark", format!("{}!", path_str))
-                            }
-                            _ => {
-                                let type_ = match (res, ns) {
-                                    (Res::Def(DefKind::Const, _), _) => "const",
-                                    (Res::Def(DefKind::Static, _), _) => "static",
-                                    (Res::Def(DefKind::Struct, _), _) => "struct",
-                                    (Res::Def(DefKind::Enum, _), _) => "enum",
-                                    (Res::Def(DefKind::Union, _), _) => "union",
-                                    (Res::Def(DefKind::Trait, _), _) => "trait",
-                                    (Res::Def(DefKind::Mod, _), _) => "module",
-                                    (_, TypeNS) => "type",
-                                    (_, ValueNS) => "value",
-                                    (Res::Def(DefKind::Macro(MacroKind::Derive), _), MacroNS) => {
-                                        "derive"
-                                    }
-                                    (_, MacroNS) => "macro",
-                                };
+            let link_range = link_range.expect("must have a link range if we have a span");
 
-                                // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
-                                ("prefix with the item type", format!("{}@{}", type_, path_str))
-                            }
+            for (res, ns) in candidates {
+                let (action, mut suggestion) = match res {
+                    Res::Def(DefKind::AssocFn | DefKind::Fn, _) => {
+                        ("add parentheses", format!("{}()", path_str))
+                    }
+                    Res::Def(DefKind::Macro(MacroKind::Bang), _) => {
+                        ("add an exclamation mark", format!("{}!", path_str))
+                    }
+                    _ => {
+                        let type_ = match (res, ns) {
+                            (Res::Def(DefKind::Const, _), _) => "const",
+                            (Res::Def(DefKind::Static, _), _) => "static",
+                            (Res::Def(DefKind::Struct, _), _) => "struct",
+                            (Res::Def(DefKind::Enum, _), _) => "enum",
+                            (Res::Def(DefKind::Union, _), _) => "union",
+                            (Res::Def(DefKind::Trait, _), _) => "trait",
+                            (Res::Def(DefKind::Mod, _), _) => "module",
+                            (_, TypeNS) => "type",
+                            (_, ValueNS) => "value",
+                            (Res::Def(DefKind::Macro(MacroKind::Derive), _), MacroNS) => "derive",
+                            (_, MacroNS) => "macro",
                         };
 
-                        if dox.bytes().nth(link_range.start) == Some(b'`') {
-                            suggestion = format!("`{}`", suggestion);
-                        }
-
-                        diag.span_suggestion(
-                            sp,
-                            &format!("to link to the {}, {}", res.descr(), action),
-                            suggestion,
-                            Applicability::MaybeIncorrect,
-                        );
+                        // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
+                        ("prefix with the item type", format!("{}@{}", type_, path_str))
                     }
-                } else {
-                    // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
-                    //                       ^     ~~~~
-                    //                       |     link_range
-                    //                       last_new_line_offset
-                    let last_new_line_offset =
-                        dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
-                    let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
+                };
 
-                    // Print the line containing the `link_range` and manually mark it with '^'s.
-                    diag.note(&format!(
-                        "the link appears in this line:\n\n{line}\n\
-                         {indicator: <before$}{indicator:^<found$}",
-                        line = line,
-                        indicator = "",
-                        before = link_range.start - last_new_line_offset,
-                        found = link_range.len(),
-                    ));
+                if dox.bytes().nth(link_range.start) == Some(b'`') {
+                    suggestion = format!("`{}`", suggestion);
                 }
+
+                // FIXME: Create a version of this suggestion for when we don't have the span.
+                diag.span_suggestion(
+                    sp,
+                    &format!("to link to the {}, {}", res.descr(), action),
+                    suggestion,
+                    Applicability::MaybeIncorrect,
+                );
             }
-            diag.emit();
-        },
-    );
+        }
+    });
+}
+
+fn privacy_error(
+    cx: &DocContext<'_>,
+    item: &Item,
+    path_str: &str,
+    dox: &str,
+    link_range: Option<Range<usize>>,
+) {
+    let item_name = item.name.as_deref().unwrap_or("<unknown>");
+    let msg =
+        format!("public documentation for `{}` links to private item `{}`", item_name, path_str);
+
+    report_diagnostic(cx, &msg, item, dox, link_range, |diag, sp| {
+        if let Some(sp) = sp {
+            diag.span_label(sp, "this item is private");
+        }
+
+        let note_msg = if cx.render_options.document_private {
+            "this link resolves only because you passed `--document-private-items`, but will break without"
+        } else {
+            "this link will resolve properly if you pass `--document-private-items`"
+        };
+        diag.note(note_msg);
+    });
 }
 
 /// Given an enum variant's res, return the res of its enum and the associated fragment.
@@ -1089,7 +1095,7 @@ fn handle_variant(
     use rustc_middle::ty::DefIdTree;
 
     if extra_fragment.is_some() {
-        return Err(ErrorKind::AnchorFailure("variants cannot be followed by anchors"));
+        return Err(ErrorKind::AnchorFailure(AnchorFailure::Variant));
     }
     let parent = if let Some(parent) = cx.tcx.parent(res.def_id()) {
         parent
index 42403bdb1bceaaa46bef7defa7667d796da5de8e..8138dfa580d80c04aa50d356abb2e466c5fad54f 100644 (file)
@@ -2,7 +2,6 @@
 authors = ["The Rust Project Developers"]
 name = "std"
 version = "0.0.0"
-build = "build.rs"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
 description = "The Rust Standard Library"
@@ -25,15 +24,11 @@ profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-dep-of-std'] }
 
-# Dependencies of the `backtrace` crate
-addr2line = { version = "0.13.0", optional = true, default-features = false }
-rustc-demangle = { version = "0.1.4", features = ['rustc-dep-of-std'] }
-miniz_oxide = { version = "0.4.0", optional = true, default-features = false }
-[dependencies.object]
-version = "0.20"
-optional = true
-default-features = false
-features = ['read_core', 'elf', 'macho', 'pe']
+[dependencies.backtrace_rs]
+package = "backtrace"
+version = "0.3.46"
+default-features = false # without the libstd `backtrace` feature, stub out everything
+features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd
 
 [dev-dependencies]
 rand = "0.7"
@@ -52,12 +47,11 @@ wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features =
 
 [features]
 backtrace = [
-  "gimli-symbolize",
-  'addr2line/rustc-dep-of-std',
-  'object/rustc-dep-of-std',
-  'miniz_oxide/rustc-dep-of-std',
+  "backtrace_rs/dbghelp",          # backtrace/symbolize on MSVC
+  "backtrace_rs/libbacktrace",     # symbolize on most platforms
+  "backtrace_rs/libunwind",        # backtrace on most platforms
+  "backtrace_rs/dladdr",           # symbolize on platforms w/o libbacktrace
 ]
-gimli-symbolize = []
 
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
index e65775c1ced67909ad9d5e0954f946e78ffd55b5..02e6811bc3f4357e33b732e17f138925562a31f7 100644 (file)
@@ -91,7 +91,6 @@
 // `Backtrace`, but that's a relatively small price to pay relative to capturing
 // a backtrace or actually symbolizing it.
 
-use crate::backtrace_rs::{self, BytesOrWideString};
 use crate::env;
 use crate::ffi::c_void;
 use crate::fmt;
@@ -99,6 +98,8 @@
 use crate::sync::Mutex;
 use crate::sys_common::backtrace::{lock, output_filename};
 use crate::vec::Vec;
+use backtrace::BytesOrWideString;
+use backtrace_rs as backtrace;
 
 /// A captured OS thread stack backtrace.
 ///
@@ -149,7 +150,7 @@ struct BacktraceFrame {
 }
 
 enum RawFrame {
-    Actual(backtrace_rs::Frame),
+    Actual(backtrace::Frame),
     #[cfg(test)]
     Fake,
 }
@@ -196,7 +197,7 @@ impl fmt::Debug for BacktraceSymbol {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(fmt, "{{ ")?;
 
-        if let Some(fn_name) = self.name.as_ref().map(|b| backtrace_rs::SymbolName::new(b)) {
+        if let Some(fn_name) = self.name.as_ref().map(|b| backtrace::SymbolName::new(b)) {
             write!(fmt, "fn: \"{:#}\"", fn_name)?;
         } else {
             write!(fmt, "fn: <unknown>")?;
@@ -222,7 +223,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
                 BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                 BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
             },
-            backtrace_rs::PrintFmt::Short,
+            backtrace::PrintFmt::Short,
             crate::env::current_dir().as_ref().ok(),
         )
     }
@@ -291,6 +292,12 @@ pub fn force_capture() -> Backtrace {
         Backtrace::create(Backtrace::force_capture as usize)
     }
 
+    /// Forcibly captures a disabled backtrace, regardless of environment
+    /// variable configuration.
+    pub const fn disabled() -> Backtrace {
+        Backtrace { inner: Inner::Disabled }
+    }
+
     // Capture a backtrace which start just before the function addressed by
     // `ip`
     fn create(ip: usize) -> Backtrace {
@@ -298,7 +305,7 @@ fn create(ip: usize) -> Backtrace {
         let mut frames = Vec::new();
         let mut actual_start = None;
         unsafe {
-            backtrace_rs::trace_unsynchronized(|frame| {
+            backtrace::trace_unsynchronized(|frame| {
                 frames.push(BacktraceFrame {
                     frame: RawFrame::Actual(frame.clone()),
                     symbols: Vec::new(),
@@ -349,9 +356,9 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 
         let full = fmt.alternate();
         let (frames, style) = if full {
-            (&capture.frames[..], backtrace_rs::PrintFmt::Full)
+            (&capture.frames[..], backtrace::PrintFmt::Full)
         } else {
-            (&capture.frames[capture.actual_start..], backtrace_rs::PrintFmt::Short)
+            (&capture.frames[capture.actual_start..], backtrace::PrintFmt::Short)
         };
 
         // When printing paths we try to strip the cwd if it exists, otherwise
@@ -363,7 +370,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
             output_filename(fmt, path, style, cwd.as_ref().ok())
         };
 
-        let mut f = backtrace_rs::BacktraceFmt::new(fmt, style, &mut print_path);
+        let mut f = backtrace::BacktraceFmt::new(fmt, style, &mut print_path);
         f.add_context()?;
         for frame in frames {
             let mut f = f.frame();
@@ -373,7 +380,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
                 for symbol in frame.symbols.iter() {
                     f.print_raw(
                         frame.frame.ip(),
-                        symbol.name.as_ref().map(|b| backtrace_rs::SymbolName::new(b)),
+                        symbol.name.as_ref().map(|b| backtrace::SymbolName::new(b)),
                         symbol.filename.as_ref().map(|b| match b {
                             BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                             BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
@@ -408,7 +415,7 @@ fn resolve(&mut self) {
                 RawFrame::Fake => unimplemented!(),
             };
             unsafe {
-                backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
+                backtrace::resolve_frame_unsynchronized(frame, |symbol| {
                     symbols.push(BacktraceSymbol {
                         name: symbol.name().map(|m| m.as_bytes().to_vec()),
                         filename: symbol.filename_raw().map(|b| match b {
index 58fb6fda19aabed41aafde057139836be1c69c2e..43a3327d84b613905ad8c65daaf9ab52ff181633 100644 (file)
@@ -1,6 +1,7 @@
 use std::env;
 
 fn main() {
+    println!("cargo:rerun-if-changed=build.rs");
     let target = env::var("TARGET").expect("TARGET was not set");
     if target.contains("linux") {
         if target.contains("android") {
@@ -87,5 +88,4 @@ fn main() {
         println!("cargo:rustc-cfg=feature=\"restricted-std\"");
     }
     println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());
-    println!("cargo:rustc-cfg=backtrace_in_libstd");
 }
index b392d6e7226d2d7bba2080ebefae53cd89626c45..c905bcf5e3db4255819b3c952eb5277012042add 100644 (file)
@@ -1500,7 +1500,7 @@ fn test_float_bits_conv() {
         assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
         assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);
 
-        // Check that NaNs roundtrip their bits regardless of signalingness
+        // Check that NaNs roundtrip their bits regardless of signaling-ness
         // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
         let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA;
         let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555;
index 72268d2cc2f984be863501d2e4df84197d3fbb61..f09fc8d790b28faade6c3d0a2193263d32b07a42 100644 (file)
@@ -1523,7 +1523,7 @@ fn test_float_bits_conv() {
         assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
         assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
 
-        // Check that NaNs roundtrip their bits regardless of signalingness
+        // Check that NaNs roundtrip their bits regardless of signaling-ness
         // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
         let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
         let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
index 02de3fff29f87131bed42d6449157de5fd7803d4..00f2fff94c9a16928b34e188bad85b7cf27bfcb7 100644 (file)
@@ -511,10 +511,6 @@ pub mod task {
 // compiler
 pub mod rt;
 
-#[path = "../backtrace/src/lib.rs"]
-#[allow(dead_code, unused_attributes)]
-mod backtrace_rs;
-
 // Pull in the `std_detect` crate directly into libstd. The contents of
 // `std_detect` are in a different repository: rust-lang/stdarch.
 //
index d22b44a06666295787ed0a614c5418b35ad51ecb..657737394ab82fe5feb1f29a57f2402cf1a2495c 100644 (file)
@@ -285,7 +285,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ctime_nsec(&self) -> i64;
-    /// Returns the "preferred" blocksize for efficient filesystem I/O.
+    /// Returns the "preferred" block size for efficient filesystem I/O.
     ///
     /// # Examples
     ///
index 6c87df534bdc683c929cbddc584a361bb7b95717..61b5bff380518674c4341fc74f121ea7a5381142 100644 (file)
@@ -289,7 +289,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ctime_nsec(&self) -> i64;
-    /// Returns the "preferred" blocksize for efficient filesystem I/O.
+    /// Returns the "preferred" block size for efficient filesystem I/O.
     ///
     /// # Examples
     ///
index ab2a60103069d6571179c20c565f5e64800d6f0b..9542e7209b4cf168347e18b00cc3253c349fb020 100644 (file)
@@ -171,7 +171,7 @@ fn default_hook(info: &PanicInfo<'_>) {
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
     let backtrace_env = if panic_count::get() >= 2 {
-        RustBacktrace::Print(crate::backtrace_rs::PrintFmt::Full)
+        RustBacktrace::Print(backtrace_rs::PrintFmt::Full)
     } else {
         backtrace::rust_backtrace_env()
     };
index f14a9ff72f62f473ef8437ed5c63650cbab30785..392c815ef2803a5002d03564d49e5f330c55e884 100644 (file)
@@ -2244,6 +2244,9 @@ fn _with_file_name(&self, file_name: &OsStr) -> PathBuf {
     ///
     /// let path = Path::new("foo.rs");
     /// assert_eq!(path.with_extension("txt"), PathBuf::from("foo.txt"));
+    ///
+    /// let path = Path::new("foo.tar.gz");
+    /// assert_eq!(path.with_extension(""), PathBuf::from("foo.tar"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
index 90158030c7fbe19c8a6c00f8d2e367fb8bc6fa45..e5dc5b5adaa934a0ed34de571c425e2e231275da 100644 (file)
@@ -19,7 +19,7 @@ pub fn raw(&self) -> Fd {
         self.fd
     }
 
-    /// Extracts the actual filedescriptor without closing it.
+    /// Extracts the actual file descriptor without closing it.
     pub fn into_raw(self) -> Fd {
         let fd = self.fd;
         mem::forget(self);
index 2b2bbc6e9d6ae473a24ca68f6b2676fa0428fffa..f174a59b49a6ba51b01a1bc50f720ee2a6e4dd37 100644 (file)
@@ -624,7 +624,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime_nsec(&self) -> i64;
-    /// Returns the blocksize for filesystem I/O.
+    /// Returns the block size for filesystem I/O.
     ///
     /// # Examples
     ///
@@ -635,7 +635,7 @@ pub trait MetadataExt {
     ///
     /// fn main() -> io::Result<()> {
     ///     let meta = fs::metadata("some_file")?;
-    ///     let blocksize = meta.blksize();
+    ///     let block_size = meta.blksize();
     ///     Ok(())
     /// }
     /// ```
index c481ca8961f86192a3629e4660690bff33b141e9..84c4d662161bca7fac8a938c71e5799618787e10 100644 (file)
@@ -3,28 +3,28 @@
 use crate::cmp;
 use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
 use crate::mem;
-use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::cvt;
 use crate::sys_common::AsInner;
 
-use libc::{c_int, c_void, ssize_t};
+use libc::{c_int, c_void};
 
 #[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".
-    //
-    // On macOS, however, apparently the 64-bit libc is either buggy or
-    // intentionally showing odd behavior by rejecting any read with a size
-    // larger than or equal to INT_MAX. To handle both of these the read
-    // size is capped on both platforms.
-    if cfg!(target_os = "macos") { <c_int>::MAX as usize - 1 } else { <ssize_t>::MAX as 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".
+//
+// On macOS, however, apparently the 64-bit libc is either buggy or
+// intentionally showing odd behavior by rejecting any read with a size
+// larger than or equal to INT_MAX. To handle both of these the read
+// size is capped on both platforms.
+#[cfg(target_os = "macos")]
+const READ_LIMIT: usize = c_int::MAX as usize - 1;
+#[cfg(not(target_os = "macos"))]
+const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
 
 impl FileDesc {
     pub fn new(fd: c_int) -> FileDesc {
@@ -44,7 +44,7 @@ pub fn into_raw(self) -> c_int {
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
         let ret = cvt(unsafe {
-            libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
+            libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), READ_LIMIT))
         })?;
         Ok(ret as usize)
     }
@@ -92,7 +92,7 @@ unsafe fn cvt_pread64(
             cvt_pread64(
                 self.fd,
                 buf.as_mut_ptr() as *mut c_void,
-                cmp::min(buf.len(), max_len()),
+                cmp::min(buf.len(), READ_LIMIT),
                 offset as i64,
             )
             .map(|n| n as usize)
@@ -101,7 +101,7 @@ unsafe fn cvt_pread64(
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         let ret = cvt(unsafe {
-            libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
+            libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), READ_LIMIT))
         })?;
         Ok(ret as usize)
     }
@@ -144,7 +144,7 @@ unsafe fn cvt_pwrite64(
             cvt_pwrite64(
                 self.fd,
                 buf.as_ptr() as *const c_void,
-                cmp::min(buf.len(), max_len()),
+                cmp::min(buf.len(), READ_LIMIT),
                 offset as i64,
             )
             .map(|n| n as usize)
@@ -223,50 +223,9 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
     pub fn duplicate(&self) -> io::Result<FileDesc> {
         // We want to atomically duplicate this file descriptor and set the
         // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
-        // flag, however, isn't supported on older Linux kernels (earlier than
-        // 2.6.24).
-        //
-        // To detect this and ensure that CLOEXEC is still set, we
-        // follow a strategy similar to musl [1] where if passing
-        // F_DUPFD_CLOEXEC causes `fcntl` to return EINVAL it means it's not
-        // supported (the third parameter, 0, is always valid), so we stop
-        // trying that.
-        //
-        // Also note that Android doesn't have F_DUPFD_CLOEXEC, but get it to
-        // resolve so we at least compile this.
-        //
-        // [1]: http://comments.gmane.org/gmane.linux.lib.musl.general/2963
-        #[cfg(any(target_os = "android", target_os = "haiku"))]
-        use libc::F_DUPFD as F_DUPFD_CLOEXEC;
-        #[cfg(not(any(target_os = "android", target_os = "haiku")))]
-        use libc::F_DUPFD_CLOEXEC;
-
-        let make_filedesc = |fd| {
-            let fd = FileDesc::new(fd);
-            fd.set_cloexec()?;
-            Ok(fd)
-        };
-        static TRY_CLOEXEC: AtomicBool = AtomicBool::new(!cfg!(target_os = "android"));
-        let fd = self.raw();
-        if TRY_CLOEXEC.load(Ordering::Relaxed) {
-            match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) {
-                // We *still* call the `set_cloexec` method as apparently some
-                // linux kernel at some point stopped setting CLOEXEC even
-                // though it reported doing so on F_DUPFD_CLOEXEC.
-                Ok(fd) => {
-                    return Ok(if cfg!(target_os = "linux") {
-                        make_filedesc(fd)?
-                    } else {
-                        FileDesc::new(fd)
-                    });
-                }
-                Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
-                    TRY_CLOEXEC.store(false, Ordering::Relaxed);
-                }
-                Err(e) => return Err(e),
-            }
-        }
-        cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).and_then(make_filedesc)
+        // is a POSIX flag that was added to Linux in 2.6.24.
+        let fd = cvt(unsafe { libc::fcntl(self.raw(), libc::F_DUPFD_CLOEXEC, 0) })?;
+        Ok(FileDesc::new(fd))
     }
 }
 
index 29cdbf05354fbe353ba382332c54d8f927bb20a1..acb18e6d064e6e826d0e3910035e12fd516f1e98 100644 (file)
@@ -708,56 +708,7 @@ pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
         // However, since this is a variadic function, C integer promotion rules mean that on
         // the ABI level, this still gets passed as `c_int` (aka `u32` on Unix platforms).
         let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?;
-        let fd = FileDesc::new(fd);
-
-        // Currently the standard library supports Linux 2.6.18 which did not
-        // have the O_CLOEXEC flag (passed above). If we're running on an older
-        // Linux kernel then the flag is just ignored by the OS. After we open
-        // the first file, we check whether it has CLOEXEC set. If it doesn't,
-        // we will explicitly ask for a CLOEXEC fd for every further file we
-        // open, if it does, we will skip that step.
-        //
-        // The CLOEXEC flag, however, is supported on versions of macOS/BSD/etc
-        // that we support, so we only do this on Linux currently.
-        #[cfg(target_os = "linux")]
-        fn ensure_cloexec(fd: &FileDesc) -> io::Result<()> {
-            use crate::sync::atomic::{AtomicUsize, Ordering};
-
-            const OPEN_CLOEXEC_UNKNOWN: usize = 0;
-            const OPEN_CLOEXEC_SUPPORTED: usize = 1;
-            const OPEN_CLOEXEC_NOTSUPPORTED: usize = 2;
-            static OPEN_CLOEXEC: AtomicUsize = AtomicUsize::new(OPEN_CLOEXEC_UNKNOWN);
-
-            let need_to_set;
-            match OPEN_CLOEXEC.load(Ordering::Relaxed) {
-                OPEN_CLOEXEC_UNKNOWN => {
-                    need_to_set = !fd.get_cloexec()?;
-                    OPEN_CLOEXEC.store(
-                        if need_to_set {
-                            OPEN_CLOEXEC_NOTSUPPORTED
-                        } else {
-                            OPEN_CLOEXEC_SUPPORTED
-                        },
-                        Ordering::Relaxed,
-                    );
-                }
-                OPEN_CLOEXEC_SUPPORTED => need_to_set = false,
-                OPEN_CLOEXEC_NOTSUPPORTED => need_to_set = true,
-                _ => unreachable!(),
-            }
-            if need_to_set {
-                fd.set_cloexec()?;
-            }
-            Ok(())
-        }
-
-        #[cfg(not(target_os = "linux"))]
-        fn ensure_cloexec(_: &FileDesc) -> io::Result<()> {
-            Ok(())
-        }
-
-        ensure_cloexec(&fd)?;
-        Ok(File(fd))
+        Ok(File(FileDesc::new(fd)))
     }
 
     pub fn file_attr(&self) -> io::Result<FileAttr> {
index 3717c660b575d6f1c9e2d353be65fdfa6be3212f..011325fddc5b93b08304406256bcc748d7e8e3eb 100644 (file)
@@ -54,31 +54,26 @@ pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
 
     pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
         unsafe {
-            // On linux we first attempt to pass the SOCK_CLOEXEC flag to
-            // atomically create the socket and set it as CLOEXEC. Support for
-            // this option, however, was added in 2.6.27, and we still support
-            // 2.6.18 as a kernel, so if the returned error is EINVAL we
-            // fallthrough to the fallback.
-            #[cfg(target_os = "linux")]
-            {
-                match cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0)) {
-                    Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
-                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
-                    Err(e) => return Err(e),
-                }
-            }
-
-            let fd = cvt(libc::socket(fam, ty, 0))?;
-            let fd = FileDesc::new(fd);
-            fd.set_cloexec()?;
-            let socket = Socket(fd);
+            cfg_if::cfg_if! {
+                if #[cfg(target_os = "linux")] {
+                    // On Linux we pass the SOCK_CLOEXEC flag to atomically create
+                    // the socket and set it as CLOEXEC, added in 2.6.27.
+                    let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?;
+                    Ok(Socket(FileDesc::new(fd)))
+                } else {
+                    let fd = cvt(libc::socket(fam, ty, 0))?;
+                    let fd = FileDesc::new(fd);
+                    fd.set_cloexec()?;
+                    let socket = Socket(fd);
 
-            // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt`
-            // flag to disable `SIGPIPE` emission on socket.
-            #[cfg(target_vendor = "apple")]
-            setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?;
+                    // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt`
+                    // flag to disable `SIGPIPE` emission on socket.
+                    #[cfg(target_vendor = "apple")]
+                    setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?;
 
-            Ok(socket)
+                    Ok(socket)
+                }
+            }
         }
     }
 
@@ -86,24 +81,20 @@ pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> {
         unsafe {
             let mut fds = [0, 0];
 
-            // Like above, see if we can set cloexec atomically
-            #[cfg(target_os = "linux")]
-            {
-                match cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr())) {
-                    Ok(_) => {
-                        return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
-                    }
-                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
-                    Err(e) => return Err(e),
+            cfg_if::cfg_if! {
+                if #[cfg(target_os = "linux")] {
+                    // Like above, set cloexec atomically
+                    cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?;
+                    Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))))
+                } else {
+                    cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
+                    let a = FileDesc::new(fds[0]);
+                    let b = FileDesc::new(fds[1]);
+                    a.set_cloexec()?;
+                    b.set_cloexec()?;
+                    Ok((Socket(a), Socket(b)))
                 }
             }
-
-            cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
-            let a = FileDesc::new(fds[0]);
-            let b = FileDesc::new(fds[1]);
-            a.set_cloexec()?;
-            b.set_cloexec()?;
-            Ok((Socket(a), Socket(b)))
         }
     }
 
@@ -177,30 +168,20 @@ pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Resul
     pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> {
         // Unfortunately the only known way right now to accept a socket and
         // atomically set the CLOEXEC flag is to use the `accept4` syscall on
-        // Linux. This was added in 2.6.28, however, and because we support
-        // 2.6.18 we must detect this support dynamically.
-        #[cfg(target_os = "linux")]
-        {
-            syscall! {
-                fn accept4(
-                    fd: c_int,
-                    addr: *mut sockaddr,
-                    addr_len: *mut socklen_t,
-                    flags: c_int
-                ) -> c_int
-            }
-            let res = cvt_r(|| unsafe { accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC) });
-            match res {
-                Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
-                Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
-                Err(e) => return Err(e),
+        // Linux. This was added in 2.6.28, glibc 2.10 and musl 0.9.5.
+        cfg_if::cfg_if! {
+            if #[cfg(target_os = "linux")] {
+                let fd = cvt_r(|| unsafe {
+                    libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC)
+                })?;
+                Ok(Socket(FileDesc::new(fd)))
+            } else {
+                let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?;
+                let fd = FileDesc::new(fd);
+                fd.set_cloexec()?;
+                Ok(Socket(fd))
             }
         }
-
-        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<Socket> {
index a9cd5094997bd68b9e2ae6e675f0bcb61862777d..2fcb5b9c4e66e722098efde38810b1ab60389582 100644 (file)
@@ -71,6 +71,7 @@ pub fn errno() -> i32 {
 
 /// Sets the platform-specific value of errno
 #[cfg(all(not(target_os = "linux"), not(target_os = "dragonfly")))] // needed for readdir and syscall!
+#[allow(dead_code)] // but not all target cfgs actually end up using it
 pub fn set_errno(e: i32) {
     unsafe { *errno_location() = e as c_int }
 }
index f2a2eabef9132509db4c864a40ba769b0974fb0f..7ae37bdda70bded963b72d304b7abbbbfed904a9 100644 (file)
@@ -1,11 +1,8 @@
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem;
-use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::fd::FileDesc;
 use crate::sys::{cvt, cvt_r};
 
-use libc::c_int;
-
 ////////////////////////////////////////////////////////////////////////////////
 // Anonymous pipes
 ////////////////////////////////////////////////////////////////////////////////
 pub struct AnonPipe(FileDesc);
 
 pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
-    syscall! { fn pipe2(fds: *mut c_int, flags: c_int) -> c_int }
-    static INVALID: AtomicBool = AtomicBool::new(false);
-
     let mut fds = [0; 2];
 
-    // Unfortunately the only known way right now to create atomically set the
-    // CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in
-    // 2.6.27, however, and because we support 2.6.18 we must detect this
-    // support dynamically.
-    if cfg!(any(
-        target_os = "dragonfly",
-        target_os = "freebsd",
-        target_os = "linux",
-        target_os = "netbsd",
-        target_os = "openbsd",
-        target_os = "redox"
-    )) && !INVALID.load(Ordering::SeqCst)
-    {
-        // Note that despite calling a glibc function here we may still
-        // get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
-        // emulate on older kernels, so if you happen to be running on
-        // an older kernel you may see `pipe2` as a symbol but still not
-        // see the syscall.
-        match cvt(unsafe { pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
-            Ok(_) => {
-                return Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1]))));
-            }
-            Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
-                INVALID.store(true, Ordering::SeqCst);
-            }
-            Err(e) => return Err(e),
+    // The only known way right now to create atomically set the CLOEXEC flag is
+    // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9
+    // and musl 0.9.3, and some other targets also have it.
+    cfg_if::cfg_if! {
+        if #[cfg(any(
+            target_os = "dragonfly",
+            target_os = "freebsd",
+            target_os = "linux",
+            target_os = "netbsd",
+            target_os = "openbsd",
+            target_os = "redox"
+        ))] {
+            cvt(unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) })?;
+            Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1]))))
+        } else {
+            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)))
         }
     }
-    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 {
index 08cbe59617465731a22fdc228c84b9d5ce7e9733..f4b33a00f7c85d79d8b682be0884024283a529f0 100644 (file)
 //! symbol, but that caused Debian to detect an unnecessarily strict versioned
 //! dependency on libc6 (#23628).
 
+// There are a variety of `#[cfg]`s controlling which targets are involved in
+// each instance of `weak!` and `syscall!`. Rather than trying to unify all of
+// that, we'll just allow that some unix targets don't use this module at all.
+#![allow(dead_code, unused_macros)]
+
 use crate::ffi::CStr;
 use crate::marker;
 use crate::mem;
index 7fa86f0db043f21bc2be1efa9a6c719aba73327d..ea186846929be135479736277e31ece1035b4960 100644 (file)
@@ -13,12 +13,10 @@ 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".
-    <ssize_t>::MAX as 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".
+const READ_LIMIT: usize = ssize_t::MAX as usize;
 
 impl FileDesc {
     pub fn new(fd: c_int) -> FileDesc {
@@ -29,7 +27,7 @@ pub fn raw(&self) -> c_int {
         self.fd
     }
 
-    /// Extracts the actual filedescriptor without closing it.
+    /// Extracts the actual file descriptor without closing it.
     pub fn into_raw(self) -> c_int {
         let fd = self.fd;
         mem::forget(self);
@@ -38,7 +36,7 @@ pub fn into_raw(self) -> c_int {
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
         let ret = cvt(unsafe {
-            libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len()))
+            libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), READ_LIMIT))
         })?;
         Ok(ret as usize)
     }
@@ -79,7 +77,7 @@ unsafe fn cvt_pread(
             cvt_pread(
                 self.fd,
                 buf.as_mut_ptr() as *mut c_void,
-                cmp::min(buf.len(), max_len()),
+                cmp::min(buf.len(), READ_LIMIT),
                 offset as i64,
             )
             .map(|n| n as usize)
@@ -88,7 +86,7 @@ unsafe fn cvt_pread(
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         let ret = cvt(unsafe {
-            libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len()))
+            libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), READ_LIMIT))
         })?;
         Ok(ret as usize)
     }
@@ -124,7 +122,7 @@ unsafe fn cvt_pwrite(
             cvt_pwrite(
                 self.fd,
                 buf.as_ptr() as *const c_void,
-                cmp::min(buf.len(), max_len()),
+                cmp::min(buf.len(), READ_LIMIT),
                 offset as i64,
             )
             .map(|n| n as usize)
index 8365c9ee9c995dbdd70c045e30fb573dac424eeb..8f46f4d284f0bf71ad499c3457da75c9faac5a55 100644 (file)
@@ -1,6 +1,6 @@
 use crate::cmp::Ordering;
 use crate::time::Duration;
-use ::core::hash::{Hash, Hasher};
+use core::hash::{Hash, Hasher};
 
 pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
 use crate::convert::TryInto;
index 793daea43c215baf07149e2157d73781a7102634..2eed9e436a956003a200a6af668024da9b786f0c 100644 (file)
@@ -597,14 +597,14 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
 ///
 /// WASI has no fundamental capability to do this. All syscalls and operations
 /// are relative to already-open file descriptors. The C library, however,
-/// manages a map of preopened file descriptors to their path, and then the C
+/// manages a map of pre-opened file descriptors to their path, and then the C
 /// library provides an API to look at this. In other words, when you want to
 /// open a path `p`, you have to find a previously opened file descriptor in a
 /// global table and then see if `p` is relative to that file descriptor.
 ///
 /// This function, if successful, will return two items:
 ///
-/// * The first is a `ManuallyDrop<WasiFd>`. This represents a preopened file
+/// * The first is a `ManuallyDrop<WasiFd>`. This represents a pre-opened file
 ///   descriptor which we don't have ownership of, but we can use. You shouldn't
 ///   actually drop the `fd`.
 ///
@@ -619,7 +619,7 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
 /// appropriate rights for performing `rights` actions.
 ///
 /// Note that this can fail if `p` doesn't look like it can be opened relative
-/// to any preopened file descriptor.
+/// to any pre-opened file descriptor.
 fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
     let p = CString::new(p.as_os_str().as_bytes())?;
     unsafe {
@@ -627,7 +627,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
         let fd = __wasilibc_find_relpath(p.as_ptr(), &mut ret);
         if fd == -1 {
             let msg = format!(
-                "failed to find a preopened file descriptor \
+                "failed to find a pre-opened file descriptor \
                  through which {:?} could be opened",
                 p
             );
index d386a656e4ffdc896aa93fdceb53060d1c75a71c..e9b1e86d7ae49ed8e66a6f5a995be65ceb8ef4d5 100644 (file)
@@ -1,4 +1,3 @@
-use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
 use crate::borrow::Cow;
 /// Common code for printing the backtrace in the same way across the different
 /// supported platforms.
@@ -10,6 +9,8 @@
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
+use backtrace_rs::{BacktraceFmt, BytesOrWideString, PrintFmt};
+
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
 
index 77bcfffd506c93a6913f1f0fea7390a435793814..b6baa9a8c6bcc71b77d42e3ffe1cf2fef45ab7bd 100644 (file)
@@ -2,7 +2,6 @@
 authors = ["The Rust Project Developers"]
 name = "unwind"
 version = "0.0.0"
-build = "build.rs"
 edition = "2018"
 include = [
   '/libunwind/*',
index aebccff01fc69bf62017966a2b6248176ca18113..9d79171c4cb98e120f46390d19bdb128cf48bf88 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
 
 #![feature(start)]
 
index abe2d108eae7d77b21cebde17abf24a03a824eb2..6cf59fdc39694b3488eed5848cc83c90511c5e08 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
 
 #![deny(dead_code)]
 #![feature(start)]
index dc2ad0559b34f9c21cdba0be260f057271173d42..403f68bb170bb34f2fe68ea6f4f43933fabfe195 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=lazy -Copt-level=1
+// compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1
 // ignore-tidy-linelength
 
 #![crate_type = "rlib"]
index 8aeee5859d0adedcf8be1436101ebe03aa35e840..7c61b7809901f81c7f67d1d7c0b45ee5489fffe4 100644 (file)
@@ -2,7 +2,7 @@
 
 // revisions:x86_64 i686 arm
 
-// min-llvm-version 9.0
+// min-llvm-version: 9.0
 
 //[x86_64] compile-flags: --target x86_64-unknown-uefi
 //[i686] compile-flags: --target i686-unknown-linux-musl
index 96a0a321199a37dc6e03eeb8f973cda45862ba64..571a2654bcbfd2f6d7f6543479d009f6abe3cad7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: -Z control-flow-guard=checks
+// compile-flags: -C control-flow-guard=checks
 // only-msvc
 
 #![crate_type = "lib"]
index 925e4e8e2d15557bc4dd9fdb9d43fcddba7cc6c1..c3f8f4116819ce2bf420dce85a50b7c7926dc24c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: -Z control-flow-guard=no
+// compile-flags: -C control-flow-guard=no
 // only-msvc
 
 #![crate_type = "lib"]
index d7dc3d7e89eea007fdeb644d237efab8dd6c181d..3847c3e81ed7a6d78f2e3e6b50741fb549c68431 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: -Z control-flow-guard=nochecks
+// compile-flags: -C control-flow-guard=nochecks
 // only-msvc
 
 #![crate_type = "lib"]
index 4008f0187a0b05bc318262744e5d8bb17d4ff63e..6278a951e35f1565151946520f4919088e9b20eb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-flags: -Z control-flow-guard
+// compile-flags: -C control-flow-guard
 // ignore-msvc
 
 #![crate_type = "lib"]
index fbaf38d69df7fc2608e92060fe69bdc50b3bcefd..eba4a7469f9308d2ade0946fdaa1d916cc82e6e0 100644 (file)
@@ -1,4 +1,4 @@
-// min-llvm-version 8.0
+// min-llvm-version: 8.0
 // compile-flags: -C no-prepopulate-passes -C force-unwind-tables=y
 
 #![crate_type="lib"]
index 789feea12d6d7e8a67ecfd84b406b5fb99571c37..4e3bfcd439744cb77b60cdbcc8575cb9a4e3441f 100644 (file)
@@ -2,6 +2,7 @@
 // unchecked intrinsics.
 
 // compile-flags: -C opt-level=3
+// ignore-wasm32 the wasm target is tested in `wasm_casts_*`
 
 #![crate_type = "lib"]
 
index 45b905190493a12151704411e8b8955842f16d1b..b7f8522fdfb033664327e8e7a65d84e1730af16c 100644 (file)
@@ -38,7 +38,6 @@ pub fn cast_f32_i32(a: f32) -> i32 {
     a as _
 }
 
-
 // CHECK-LABEL: @cast_f64_u64
 #[no_mangle]
 pub fn cast_f64_u64(a: f64) -> u64 {
@@ -84,13 +83,10 @@ pub fn cast_f32_u8(a: f32) -> u8 {
     a as _
 }
 
-
-
 // CHECK-LABEL: @cast_unchecked_f64_i64
 #[no_mangle]
 pub unsafe fn cast_unchecked_f64_i64(a: f64) -> i64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi double {{.*}} to i64
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.signed.{{.*}}
     // CHECK-NEXT: ret i64 {{.*}}
     a.to_int_unchecked()
 }
@@ -98,8 +94,7 @@ pub unsafe fn cast_unchecked_f64_i64(a: f64) -> i64 {
 // CHECK-LABEL: @cast_unchecked_f64_i32
 #[no_mangle]
 pub unsafe fn cast_unchecked_f64_i32(a: f64) -> i32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi double {{.*}} to i32
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.signed.{{.*}}
     // CHECK-NEXT: ret i32 {{.*}}
     a.to_int_unchecked()
 }
@@ -107,8 +102,7 @@ pub unsafe fn cast_unchecked_f64_i32(a: f64) -> i32 {
 // CHECK-LABEL: @cast_unchecked_f32_i64
 #[no_mangle]
 pub unsafe fn cast_unchecked_f32_i64(a: f32) -> i64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi float {{.*}} to i64
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.signed.{{.*}}
     // CHECK-NEXT: ret i64 {{.*}}
     a.to_int_unchecked()
 }
@@ -116,18 +110,15 @@ pub unsafe fn cast_unchecked_f32_i64(a: f32) -> i64 {
 // CHECK-LABEL: @cast_unchecked_f32_i32
 #[no_mangle]
 pub unsafe fn cast_unchecked_f32_i32(a: f32) -> i32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi float {{.*}} to i32
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.signed.{{.*}}
     // CHECK-NEXT: ret i32 {{.*}}
     a.to_int_unchecked()
 }
 
-
 // CHECK-LABEL: @cast_unchecked_f64_u64
 #[no_mangle]
 pub unsafe fn cast_unchecked_f64_u64(a: f64) -> u64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui double {{.*}} to i64
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.unsigned.{{.*}}
     // CHECK-NEXT: ret i64 {{.*}}
     a.to_int_unchecked()
 }
@@ -135,8 +126,7 @@ pub unsafe fn cast_unchecked_f64_u64(a: f64) -> u64 {
 // CHECK-LABEL: @cast_unchecked_f64_u32
 #[no_mangle]
 pub unsafe fn cast_unchecked_f64_u32(a: f64) -> u32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui double {{.*}} to i32
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.unsigned.{{.*}}
     // CHECK-NEXT: ret i32 {{.*}}
     a.to_int_unchecked()
 }
@@ -144,8 +134,7 @@ pub unsafe fn cast_unchecked_f64_u32(a: f64) -> u32 {
 // CHECK-LABEL: @cast_unchecked_f32_u64
 #[no_mangle]
 pub unsafe fn cast_unchecked_f32_u64(a: f32) -> u64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui float {{.*}} to i64
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.unsigned.{{.*}}
     // CHECK-NEXT: ret i64 {{.*}}
     a.to_int_unchecked()
 }
@@ -153,8 +142,7 @@ pub unsafe fn cast_unchecked_f32_u64(a: f32) -> u64 {
 // CHECK-LABEL: @cast_unchecked_f32_u32
 #[no_mangle]
 pub unsafe fn cast_unchecked_f32_u32(a: f32) -> u32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui float {{.*}} to i32
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.unsigned.{{.*}}
     // CHECK-NEXT: ret i32 {{.*}}
     a.to_int_unchecked()
 }
index 98ad8983a60a0bd470360bddc2ac9c196c168ea1..a5d5942b539539861978d420ba2bd61630c7a591 100644 (file)
@@ -1,5 +1,5 @@
 // This test does not passed with gdb < 8.0. See #53497.
-// min-gdb-version 8.0
+// min-gdb-version: 8.0
 
 // compile-flags:-g
 
index 2616c9465246ee5ef96497735086cf26e2961da9..cbd2278f7e27c863f3dd5211e5022f82afc5f0a3 100644 (file)
@@ -2,7 +2,7 @@
 // ignore-freebsd: gdb package too new
 // ignore-android: FIXME(#10381)
 // compile-flags:-g
-// min-gdb-version 8.1
+// min-gdb-version: 8.1
 // min-lldb-version: 310
 
 // === GDB TESTS ===================================================================================
index 4e95a028e074948baadc3a085a515d54dc8a9edd..a4fbff5725c97aa20bbf0694a219199d597384c4 100644 (file)
@@ -6,7 +6,7 @@
 
 // The pretty printers being tested here require the patch from
 // https://sourceware.org/bugzilla/show_bug.cgi?id=21763
-// min-gdb-version 8.1
+// min-gdb-version: 8.1
 
 // min-lldb-version: 310
 
index 57721ce103c3921706a6fe24a33d99aa0c35e463..7ae82d522b09dc37dfe588b52b7da46a4d428501 100644 (file)
@@ -2,7 +2,7 @@
 // only-cdb // "Temporarily" ignored on GDB/LLDB due to debuginfo tests being disabled, see PR 47155
 // ignore-android: FIXME(#10381)
 // compile-flags:-g
-// min-gdb-version 7.7
+// min-gdb-version: 7.7
 // min-lldb-version: 310
 
 // === GDB TESTS ===================================================================================
index 7ce004681e100ab6954382c1567ade4cf2a8a90b..61791f48f4db76683adde4dcbacbed0038a72015 100644 (file)
@@ -2,7 +2,7 @@
 // ignore-freebsd: gdb package too new
 // ignore-android: FIXME(#10381)
 // compile-flags:-g
-// min-gdb-version 8.1
+// min-gdb-version: 8.1
 // min-lldb-version: 310
 
 // === GDB TESTS ===================================================================================
index a0a5b141ec0e19df5eb6b2db83b757a070643b88..5830ef033d38990198300d15843d721b42b41d29 100644 (file)
@@ -91,3 +91,58 @@ unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool {
 pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize {
     0
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize {
+    continue_if!(ap.arg::<c_int>() == 1);
+    continue_if!(ap.arg::<c_int>() == 2);
+    continue_if!(ap.arg::<c_int>() == 3);
+    continue_if!(ap.arg::<c_int>() == 4);
+    continue_if!(ap.arg::<c_int>() == 5);
+    continue_if!(ap.arg::<c_int>() == 6);
+    continue_if!(ap.arg::<c_int>() == 7);
+    continue_if!(ap.arg::<c_int>() == 8);
+    continue_if!(ap.arg::<c_int>() == 9);
+    continue_if!(ap.arg::<c_int>() == 10);
+    0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn check_varargs_4(_: c_double, mut ap: ...) -> usize {
+    continue_if!(ap.arg::<c_double>() == 1.0);
+    continue_if!(ap.arg::<c_double>() == 2.0);
+    continue_if!(ap.arg::<c_double>() == 3.0);
+    continue_if!(ap.arg::<c_double>() == 4.0);
+    continue_if!(ap.arg::<c_double>() == 5.0);
+    continue_if!(ap.arg::<c_double>() == 6.0);
+    continue_if!(ap.arg::<c_double>() == 7.0);
+    continue_if!(ap.arg::<c_double>() == 8.0);
+    continue_if!(ap.arg::<c_double>() == 9.0);
+    continue_if!(ap.arg::<c_double>() == 10.0);
+    0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize {
+    continue_if!(ap.arg::<c_double>() == 1.0);
+    continue_if!(ap.arg::<c_int>() == 1);
+    continue_if!(ap.arg::<c_double>() == 2.0);
+    continue_if!(ap.arg::<c_int>() == 2);
+    continue_if!(ap.arg::<c_double>() == 3.0);
+    continue_if!(ap.arg::<c_int>() == 3);
+    continue_if!(ap.arg::<c_double>() == 4.0);
+    continue_if!(ap.arg::<c_int>() == 4);
+    continue_if!(ap.arg::<c_int>() == 5);
+    continue_if!(ap.arg::<c_double>() == 5.0);
+    continue_if!(ap.arg::<c_int>() == 6);
+    continue_if!(ap.arg::<c_double>() == 6.0);
+    continue_if!(ap.arg::<c_int>() == 7);
+    continue_if!(ap.arg::<c_double>() == 7.0);
+    continue_if!(ap.arg::<c_int>() == 8);
+    continue_if!(ap.arg::<c_double>() == 8.0);
+    continue_if!(ap.arg::<c_int>() == 9);
+    continue_if!(ap.arg::<c_double>() == 9.0);
+    continue_if!(ap.arg::<c_int>() == 10);
+    continue_if!(ap.arg::<c_double>() == 10.0);
+    0
+}
index 91b060dce26f436f6f9f5d21b7d038784dba115d..5bdb51680a6562ec25d03597146de4bdf4cbb417 100644 (file)
@@ -11,6 +11,9 @@ extern size_t check_list_copy_0(va_list ap);
 extern size_t check_varargs_0(int fixed, ...);
 extern size_t check_varargs_1(int fixed, ...);
 extern size_t check_varargs_2(int fixed, ...);
+extern size_t check_varargs_3(int fixed, ...);
+extern size_t check_varargs_4(double fixed, ...);
+extern size_t check_varargs_5(int fixed, ...);
 
 int test_rust(size_t (*fn)(va_list), ...) {
     size_t ret = 0;
@@ -36,5 +39,12 @@ int main(int argc, char* argv[]) {
 
     assert(check_varargs_2(0, "All", "of", "these", "are", "ignored", ".") == 0);
 
+    assert(check_varargs_3(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) == 0);
+
+    assert(check_varargs_4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) == 0);
+
+    assert(check_varargs_5(0, 1.0, 1, 2.0, 2, 3.0, 3, 4.0, 4, 5, 5.0, 6, 6.0, 7, 7.0, 8, 8.0,
+                           9, 9.0, 10, 10.0) == 0);
+
     return 0;
 }
index bc21cfd47c5d1000e535e5db74ebf8e21d634039..894518faa31686f810052fad43a2f3790da9c8e0 100644 (file)
@@ -1,15 +1,15 @@
-error: `[v2]` cannot be resolved, ignoring it.
+error: unresolved link to `v2`
   --> $DIR/deny-intra-link-resolution-failure.rs:3:6
    |
 LL | /// [v2]
-   |      ^^ cannot be resolved, ignoring
+   |      ^^ unresolved link
    |
 note: the lint level is defined here
   --> $DIR/deny-intra-link-resolution-failure.rs:1:9
    |
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
index cf26675163054067e30c40a75bed45e2a9990e86..d2b2b90a4e50d69a7222f0e377c840ad8c302762 100644 (file)
@@ -1,15 +1,15 @@
-error: `[TypeAlias::hoge]` cannot be resolved, ignoring it.
+error: unresolved link to `TypeAlias::hoge`
   --> $DIR/intra-doc-alias-ice.rs:5:30
    |
 LL | /// [broken cross-reference](TypeAlias::hoge)
-   |                              ^^^^^^^^^^^^^^^ cannot be resolved, ignoring
+   |                              ^^^^^^^^^^^^^^^ unresolved link
    |
 note: the lint level is defined here
   --> $DIR/intra-doc-alias-ice.rs:1:9
    |
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
index 44997c90f59320465bbc7a6b063886aca329afe1..95388003f84704a79b8f01637e386c0430987eb4 100644 (file)
@@ -7,7 +7,7 @@
 /// ## For example:
 ///
 /// ï¼ˆarr[i])
-//~^ ERROR `[i]` cannot be resolved, ignoring it.
+//~^ ERROR `i`
 pub fn test_ice() {
     unimplemented!();
 }
index ce31eb3a8a3786cd2bf9712ac1c4c45d3f7dd6f6..156e214a79ff05258fb811d0bbb3d7f1d6bc2555 100644 (file)
@@ -1,15 +1,15 @@
-error: `[i]` cannot be resolved, ignoring it.
+error: unresolved link to `i`
   --> $DIR/intra-link-span-ice-55723.rs:9:10
    |
 LL | /// ï¼ˆarr[i])
-   |           ^ cannot be resolved, ignoring
+   |           ^ unresolved link
    |
 note: the lint level is defined here
   --> $DIR/intra-link-span-ice-55723.rs:1:9
    |
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
index 7f8a8dd3c45e03e7a396cfbaad84e0dd060b4e9e..7e61bd725359a4c57422264bce630bc1244096d7 100644 (file)
@@ -23,23 +23,23 @@ pub enum Enum {
 /// Like [Foo#hola].
 ///
 /// Or maybe [Foo::f#hola].
-//~^ ERROR `[Foo::f#hola]` has an issue with the link anchor.
+//~^ ERROR `Foo::f#hola` contains an anchor
 pub fn foo() {}
 
 /// Empty.
 ///
 /// Another anchor error: [hello#people#!].
-//~^ ERROR `[hello#people#!]` has an issue with the link anchor.
+//~^ ERROR `hello#people#!` contains multiple anchors
 pub fn bar() {}
 
 /// Empty?
 ///
 /// Damn enum's variants: [Enum::A#whatever].
-//~^ ERROR `[Enum::A#whatever]` has an issue with the link anchor.
+//~^ ERROR `Enum::A#whatever` contains an anchor
 pub fn enum_link() {}
 
 /// Primitives?
 ///
 /// [u32#hello]
-//~^ ERROR `[u32#hello]` has an issue with the link anchor.
+//~^ ERROR `u32#hello` contains an anchor
 pub fn x() {}
index 11dee5547db4f541c8ecaea0637609ad985b8757..ef33d8f3e06fefbee4a4c1c0c3987ac6de8345e5 100644 (file)
@@ -1,8 +1,8 @@
-error: `[Foo::f#hola]` has an issue with the link anchor.
+error: `Foo::f#hola` contains an anchor, but links to struct fields are already anchored
   --> $DIR/intra-links-anchors.rs:25:15
    |
 LL | /// Or maybe [Foo::f#hola].
-   |               ^^^^^^^^^^^ struct fields cannot be followed by anchors
+   |               ^^^^^^^^^^^ contains invalid anchor
    |
 note: the lint level is defined here
   --> $DIR/intra-links-anchors.rs:1:9
@@ -10,23 +10,23 @@ note: the lint level is defined here
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: `[hello#people#!]` has an issue with the link anchor.
+error: `hello#people#!` contains multiple anchors
   --> $DIR/intra-links-anchors.rs:31:28
    |
 LL | /// Another anchor error: [hello#people#!].
-   |                            ^^^^^^^^^^^^^^ only one `#` is allowed in a link
+   |                            ^^^^^^^^^^^^^^ contains invalid anchor
 
-error: `[Enum::A#whatever]` has an issue with the link anchor.
+error: `Enum::A#whatever` contains an anchor, but links to enum variants are already anchored
   --> $DIR/intra-links-anchors.rs:37:28
    |
 LL | /// Damn enum's variants: [Enum::A#whatever].
-   |                            ^^^^^^^^^^^^^^^^ variants cannot be followed by anchors
+   |                            ^^^^^^^^^^^^^^^^ contains invalid anchor
 
-error: `[u32#hello]` has an issue with the link anchor.
+error: `u32#hello` contains an anchor, but links to primitive types are already anchored
   --> $DIR/intra-links-anchors.rs:43:6
    |
 LL | /// [u32#hello]
-   |      ^^^^^^^^^ primitive types cannot be followed by anchors
+   |      ^^^^^^^^^ contains invalid anchor
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/rustdoc-ui/intra-links-private.private.stderr b/src/test/rustdoc-ui/intra-links-private.private.stderr
new file mode 100644 (file)
index 0000000..a2148b8
--- /dev/null
@@ -0,0 +1,11 @@
+warning: public documentation for `DocMe` links to private item `DontDocMe`
+  --> $DIR/intra-links-private.rs:5:11
+   |
+LL | /// docs [DontDocMe]
+   |           ^^^^^^^^^ this item is private
+   |
+   = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
+   = note: this link resolves only because you passed `--document-private-items`, but will break without
+
+warning: 1 warning emitted
+
index 0a8dafdaf94667ef591fcc5f9ad5f8fd00c28cb3..56742406992fcc63138c147074c0d176f207b8b8 100644 (file)
@@ -1,10 +1,11 @@
-warning: `[DontDocMe]` public documentation for `DocMe` links to a private item
-  --> $DIR/intra-links-private.rs:6:11
+warning: public documentation for `DocMe` links to private item `DontDocMe`
+  --> $DIR/intra-links-private.rs:5:11
    |
 LL | /// docs [DontDocMe]
    |           ^^^^^^^^^ this item is private
    |
    = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
+   = note: this link will resolve properly if you pass `--document-private-items`
 
 warning: 1 warning emitted
 
index 86cf9fed3dab48cb176a2009969632bc26c7a647..613236d75d2ee952e847f7ac23590a95509bfccd 100644 (file)
@@ -1,10 +1,9 @@
 // check-pass
 // revisions: public private
 // [private]compile-flags: --document-private-items
-#![cfg_attr(private, deny(intra_doc_link_resolution_failure))]
 
 /// docs [DontDocMe]
-//[public]~^ WARNING `[DontDocMe]` public documentation for `DocMe` links to a private item
+//~^ WARNING public documentation for `DocMe` links to private item `DontDocMe`
 // FIXME: for [private] we should also make sure the link was actually generated
 pub struct DocMe;
 struct DontDocMe;
index 18c9837b0bb457e449312e21e811e12cec6b5b97..a19c33b53be09673b8f24197a2ab001812800f13 100644 (file)
@@ -6,16 +6,16 @@
 
 /// [error]
 pub struct A;
-//~^^ WARNING `[error]` cannot be resolved
+//~^^ WARNING `error`
 
 ///
 /// docs [error1]
-//~^ WARNING `[error1]` cannot be resolved
+//~^ WARNING `error1`
 
 /// docs [error2]
 ///
 pub struct B;
-//~^^^ WARNING `[error2]` cannot be resolved
+//~^^^ WARNING `error2`
 
 /**
  * This is a multi-line comment.
@@ -23,4 +23,4 @@
  * It also has an [error].
  */
 pub struct C;
-//~^^^ WARNING `[error]` cannot be resolved
+//~^^^ WARNING `error`
index ac8691a8743ba7dbffe9e984e029f1b07c183f41..bc31264c170eaf3bed48c3bd07eda0fdd4d891f5 100644 (file)
@@ -1,35 +1,35 @@
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning-crlf.rs:7:6
    |
 LL | /// [error]
-   |      ^^^^^ cannot be resolved, ignoring
+   |      ^^^^^ unresolved link
    |
    = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error1]` cannot be resolved, ignoring it.
+warning: unresolved link to `error1`
   --> $DIR/intra-links-warning-crlf.rs:12:11
    |
 LL | /// docs [error1]
-   |           ^^^^^^ cannot be resolved, ignoring
+   |           ^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error2]` cannot be resolved, ignoring it.
+warning: unresolved link to `error2`
   --> $DIR/intra-links-warning-crlf.rs:15:11
    |
 LL | /// docs [error2]
-   |           ^^^^^^ cannot be resolved, ignoring
+   |           ^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning-crlf.rs:23:20
    |
 LL |  * It also has an [error].
-   |                    ^^^^^ cannot be resolved, ignoring
+   |                    ^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: 4 warnings emitted
 
index 623dcc320bb8dcd83a06b860640f4fb3dbba7733..eab1f03480460b2d05d9c722a44aaa41085805bc 100644 (file)
@@ -1,37 +1,37 @@
 // check-pass
 
        //! Test with [Foo::baz], [Bar::foo], ...
-//~^ WARNING `[Foo::baz]` cannot be resolved
-//~| WARNING `[Bar::foo]` cannot be resolved
+//~^ WARNING `Foo::baz`
+//~| WARNING `Bar::foo`
      //! , [Uniooon::X] and [Qux::Z].
-//~^ WARNING `[Uniooon::X]` cannot be resolved
-//~| WARNING `[Qux::Z]` cannot be resolved
+//~^ WARNING `Uniooon::X`
+//~| WARNING `Qux::Z`
        //!
       //! , [Uniooon::X] and [Qux::Z].
-//~^ WARNING `[Uniooon::X]` cannot be resolved
-//~| WARNING `[Qux::Z]` cannot be resolved
+//~^ WARNING `Uniooon::X`
+//~| WARNING `Qux::Z`
 
        /// [Qux:Y]
-//~^ WARNING `[Qux:Y]` cannot be resolved
+//~^ WARNING `Qux:Y`
 pub struct Foo {
     pub bar: usize,
 }
 
 /// Foo
-/// bar [BarA] bar //~ WARNING `[BarA]` cannot be resolved
+/// bar [BarA] bar //~ WARNING `BarA`
 /// baz
 pub fn a() {}
 
 /**
  * Foo
- * bar [BarB] bar //~ WARNING `[BarB]` cannot be resolved
+ * bar [BarB] bar //~ WARNING `BarB`
  * baz
  */
 pub fn b() {}
 
 /** Foo
 
-bar [BarC] bar //~ WARNING `[BarC]` cannot be resolved
+bar [BarC] bar //~ WARNING `BarC`
 baz
 
     let bar_c_1 = 0;
@@ -42,12 +42,12 @@ pub fn b() {}
 */
 pub fn c() {}
 
-#[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `[BarD]` cannot be resolved
+#[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `BarD`
 pub fn d() {}
 
 macro_rules! f {
     ($f:expr) => {
-        #[doc = $f] //~ WARNING `[BarF]` cannot be resolved
+        #[doc = $f] //~ WARNING `BarF`
         pub fn f() {}
     }
 }
@@ -55,30 +55,30 @@ pub fn f() {}
 
 /** # for example,
  *
- * time to introduce a link [error]*/ //~ WARNING `[error]` cannot be resolved
+ * time to introduce a link [error]*/ //~ WARNING `error`
 pub struct A;
 
 /**
  * # for example,
  *
- * time to introduce a link [error] //~ WARNING `[error]` cannot be resolved
+ * time to introduce a link [error] //~ WARNING `error`
  */
 pub struct B;
 
-#[doc = "single line [error]"] //~ WARNING `[error]` cannot be resolved
+#[doc = "single line [error]"] //~ WARNING `error`
 pub struct C;
 
-#[doc = "single line with \"escaping\" [error]"] //~ WARNING `[error]` cannot be resolved
+#[doc = "single line with \"escaping\" [error]"] //~ WARNING `error`
 pub struct D;
 
-/// Item docs. //~ WARNING `[error]` cannot be resolved
+/// Item docs. //~ WARNING `error`
 #[doc="Hello there!"]
 /// [error]
 pub struct E;
 
 ///
-/// docs [error1] //~ WARNING `[error1]` cannot be resolved
+/// docs [error1] //~ WARNING `error1`
 
-/// docs [error2] //~ WARNING `[error2]` cannot be resolved
+/// docs [error2] //~ WARNING `error2`
 ///
 pub struct F;
index 914a19fc536c7f185e6f9126f4b09fe11e1b4ef8..81931399c240a87f29cfa8a5b7aaf658be4c95f9 100644 (file)
@@ -1,77 +1,77 @@
-warning: `[Foo::baz]` cannot be resolved, ignoring it.
+warning: unresolved link to `Foo::baz`
   --> $DIR/intra-links-warning.rs:3:23
    |
 LL |        //! Test with [Foo::baz], [Bar::foo], ...
-   |                       ^^^^^^^^ cannot be resolved, ignoring
+   |                       ^^^^^^^^ unresolved link
    |
    = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[Bar::foo]` cannot be resolved, ignoring it.
+warning: unresolved link to `Bar::foo`
   --> $DIR/intra-links-warning.rs:3:35
    |
 LL |        //! Test with [Foo::baz], [Bar::foo], ...
-   |                                   ^^^^^^^^ cannot be resolved, ignoring
+   |                                   ^^^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[Uniooon::X]` cannot be resolved, ignoring it.
+warning: unresolved link to `Uniooon::X`
   --> $DIR/intra-links-warning.rs:6:13
    |
 LL |      //! , [Uniooon::X] and [Qux::Z].
-   |             ^^^^^^^^^^ cannot be resolved, ignoring
+   |             ^^^^^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[Qux::Z]` cannot be resolved, ignoring it.
+warning: unresolved link to `Qux::Z`
   --> $DIR/intra-links-warning.rs:6:30
    |
 LL |      //! , [Uniooon::X] and [Qux::Z].
-   |                              ^^^^^^ cannot be resolved, ignoring
+   |                              ^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[Uniooon::X]` cannot be resolved, ignoring it.
+warning: unresolved link to `Uniooon::X`
   --> $DIR/intra-links-warning.rs:10:14
    |
 LL |       //! , [Uniooon::X] and [Qux::Z].
-   |              ^^^^^^^^^^ cannot be resolved, ignoring
+   |              ^^^^^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[Qux::Z]` cannot be resolved, ignoring it.
+warning: unresolved link to `Qux::Z`
   --> $DIR/intra-links-warning.rs:10:31
    |
 LL |       //! , [Uniooon::X] and [Qux::Z].
-   |                               ^^^^^^ cannot be resolved, ignoring
+   |                               ^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[Qux:Y]` cannot be resolved, ignoring it.
+warning: unresolved link to `Qux:Y`
   --> $DIR/intra-links-warning.rs:14:13
    |
 LL |        /// [Qux:Y]
-   |             ^^^^^ cannot be resolved, ignoring
+   |             ^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:58:30
    |
 LL |  * time to introduce a link [error]*/
-   |                              ^^^^^ cannot be resolved, ignoring
+   |                              ^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:64:30
    |
 LL |  * time to introduce a link [error]
-   |                              ^^^^^ cannot be resolved, ignoring
+   |                              ^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:68:1
    |
 LL | #[doc = "single line [error]"]
@@ -81,9 +81,9 @@ LL | #[doc = "single line [error]"]
            
            single line [error]
                         ^^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:71:1
    |
 LL | #[doc = "single line with \"escaping\" [error]"]
@@ -93,9 +93,9 @@ LL | #[doc = "single line with \"escaping\" [error]"]
            
            single line with "escaping" [error]
                                         ^^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error]` cannot be resolved, ignoring it.
+warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:74:1
    |
 LL | / /// Item docs.
@@ -107,49 +107,49 @@ LL | | /// [error]
            
            [error]
             ^^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error1]` cannot be resolved, ignoring it.
+warning: unresolved link to `error1`
   --> $DIR/intra-links-warning.rs:80:11
    |
 LL | /// docs [error1]
-   |           ^^^^^^ cannot be resolved, ignoring
+   |           ^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[error2]` cannot be resolved, ignoring it.
+warning: unresolved link to `error2`
   --> $DIR/intra-links-warning.rs:82:11
    |
 LL | /// docs [error2]
-   |           ^^^^^^ cannot be resolved, ignoring
+   |           ^^^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[BarA]` cannot be resolved, ignoring it.
+warning: unresolved link to `BarA`
   --> $DIR/intra-links-warning.rs:21:10
    |
 LL | /// bar [BarA] bar
-   |          ^^^^ cannot be resolved, ignoring
+   |          ^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[BarB]` cannot be resolved, ignoring it.
+warning: unresolved link to `BarB`
   --> $DIR/intra-links-warning.rs:27:9
    |
 LL |  * bar [BarB] bar
-   |         ^^^^ cannot be resolved, ignoring
+   |         ^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[BarC]` cannot be resolved, ignoring it.
+warning: unresolved link to `BarC`
   --> $DIR/intra-links-warning.rs:34:6
    |
 LL | bar [BarC] bar
-   |      ^^^^ cannot be resolved, ignoring
+   |      ^^^^ unresolved link
    |
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[BarD]` cannot be resolved, ignoring it.
+warning: unresolved link to `BarD`
   --> $DIR/intra-links-warning.rs:45:1
    |
 LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
@@ -159,9 +159,9 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
            
            bar [BarD] bar
                 ^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
-warning: `[BarF]` cannot be resolved, ignoring it.
+warning: unresolved link to `BarF`
   --> $DIR/intra-links-warning.rs:50:9
    |
 LL |         #[doc = $f]
@@ -174,7 +174,7 @@ LL | f!("Foo\nbar [BarF] bar\nbaz");
            
            bar [BarF] bar
                 ^^^^
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
    = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 19 warnings emitted
diff --git a/src/test/rustdoc-ui/issue-74134.private.stderr b/src/test/rustdoc-ui/issue-74134.private.stderr
new file mode 100644 (file)
index 0000000..9c5cdf0
--- /dev/null
@@ -0,0 +1,11 @@
+warning: public documentation for `public_item` links to private item `PrivateType`
+  --> $DIR/issue-74134.rs:19:10
+   |
+LL |     /// [`PrivateType`]
+   |          ^^^^^^^^^^^^^ this item is private
+   |
+   = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
+   = note: this link resolves only because you passed `--document-private-items`, but will break without
+
+warning: 1 warning emitted
+
index 03f95f19d326e7b531896f9e2fa56e59de9f6343..ff2951d864e642e6dd57f13068f1bfec40f50e67 100644 (file)
@@ -1,10 +1,11 @@
-warning: `[PrivateType]` public documentation for `public_item` links to a private item
+warning: public documentation for `public_item` links to private item `PrivateType`
   --> $DIR/issue-74134.rs:19:10
    |
 LL |     /// [`PrivateType`]
    |          ^^^^^^^^^^^^^ this item is private
    |
    = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
+   = note: this link will resolve properly if you pass `--document-private-items`
 
 warning: 1 warning emitted
 
index d561c2dd8901502736ab1001b06b3f671b65724f..b1be9123aaf838cf4750c84dc06fb23d1f01b5cd 100644 (file)
@@ -4,7 +4,7 @@
 
 // There are 4 cases here:
 // 1. public item  -> public type:  no warning
-// 2. public item  -> private type: warning, if --document-private-items is not passed
+// 2. public item  -> private type: warning
 // 3. private item -> public type:  no warning
 // 4. private item -> private type: no warning
 // All 4 cases are tested with and without --document-private-items.
@@ -17,7 +17,7 @@
 pub struct Public {
     /// [`PublicType`]
     /// [`PrivateType`]
-    //[public]~^ WARNING public documentation for `public_item` links to a private
+    //~^ WARNING public documentation for `public_item` links to private item `PrivateType`
     pub public_item: u32,
 
     /// [`PublicType`]
index 06766db5335a1eeb4d3c2ec7da0f1db03cac6e7f..e58c8b12f68cb8550ef9bd0c43bbe40f54554175 100644 (file)
@@ -11,7 +11,7 @@
 /// ```
 /// println!("sup");
 /// ```
-pub fn link_error() {} //~^^^^^ ERROR cannot be resolved, ignoring it
+pub fn link_error() {} //~^^^^^ ERROR unresolved link to `error`
 
 /// wait, this doesn't have a doctest?
 pub fn no_doctest() {} //~^ ERROR missing code example in this documentation
index 852c9120e0bf9ca141b9e7cbdca9369a74020965..14d72e9aad3ba8cfaa9a21db2ab5dd41fccc9569 100644 (file)
@@ -15,11 +15,11 @@ LL | #![deny(rustdoc)]
    |         ^^^^^^^
    = note: `#[deny(private_doc_tests)]` implied by `#[deny(rustdoc)]`
 
-error: `[error]` cannot be resolved, ignoring it.
+error: unresolved link to `error`
   --> $DIR/lint-group.rs:9:29
    |
 LL | /// what up, let's make an [error]
-   |                             ^^^^^ cannot be resolved, ignoring
+   |                             ^^^^^ unresolved link
    |
 note: the lint level is defined here
   --> $DIR/lint-group.rs:7:9
@@ -27,7 +27,7 @@ note: the lint level is defined here
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
    = note: `#[deny(intra_doc_link_resolution_failure)]` implied by `#[deny(rustdoc)]`
-   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: missing code example in this documentation
   --> $DIR/lint-group.rs:16:1
index 8c6073e2f7a4918bd468ebad139420b4a70487f3..1eeb01ccc846e9d82691725254e58eac7f0830e4 100644 (file)
@@ -35,7 +35,7 @@ fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
 
 #[cfg(transmute)] // one instantiations: BAD
 fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
-   bar(foo, x) //[transmute]~ ERROR E0495
+   bar(foo, x) //[transmute]~ ERROR E0759
 }
 
 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
index 5ea98dcd4a972a194e603ec6067d98dfb659b873..0be9b37263a48bbea3847ef93b55c4fa4b636950 100644 (file)
@@ -1,26 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/project-fn-ret-contravariant.rs:38:8
    |
-LL |    bar(foo, x)
-   |        ^^^
-   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 37:8...
-  --> $DIR/project-fn-ret-contravariant.rs:37:8
-   |
 LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
-   |        ^^
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/project-fn-ret-contravariant.rs:38:13
-   |
-LL |    bar(foo, x)
-   |             ^
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/project-fn-ret-contravariant.rs:38:4
-   |
+   |                  ------- this data with lifetime `'a`...
 LL |    bar(foo, x)
-   |    ^^^^^^^^^^^
+   |    ----^^^---- ...is captured and required to live as long as `'static` here
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0759`.
index 0034d796826de662b16e8aec226e8e3bfcaf8ada..08d864f7836d20467ad4292d937f2809f154b089 100644 (file)
@@ -46,7 +46,7 @@ fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
     // Cannot instantiate `foo` with any lifetime other than `'a`,
     // since it is provided as input.
 
-    bar(foo, x) //[transmute]~ ERROR E0495
+    bar(foo, x) //[transmute]~ ERROR E0759
 }
 
 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
index ef57f9e0bc480049ba6ed9bfab821693693f1e1f..0a44864b249551b3a03d6f5f792e7f49c00c13ab 100644 (file)
@@ -1,30 +1,12 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/project-fn-ret-invariant.rs:49:9
    |
-LL |     bar(foo, x)
-   |         ^^^
-   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 45:8...
-  --> $DIR/project-fn-ret-invariant.rs:45:8
-   |
 LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
-   |        ^^
-note: ...so that the expression is assignable
-  --> $DIR/project-fn-ret-invariant.rs:49:14
-   |
-LL |     bar(foo, x)
-   |              ^
-   = note: expected `Type<'_>`
-              found `Type<'a>`
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
-  --> $DIR/project-fn-ret-invariant.rs:49:5
-   |
+   |                   -------- this data with lifetime `'a`...
+...
 LL |     bar(foo, x)
-   |     ^^^^^^^^^^^
-   = note: expected `Type<'static>`
-              found `Type<'_>`
+   |     ----^^^---- ...is captured and required to live as long as `'static` here
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0759`.
index ea482d3667e2b575bc5c8fb9ef9b8d76db8c296a..66ebbd83ffa9e4546a0fcfd06b437a658b245dc1 100644 (file)
@@ -9,7 +9,7 @@ async fn foo<F>(fun: F)
 struct Struct;
 
 impl Struct {
-    pub async fn run_dummy_fn(&self) { //~ ERROR cannot infer
+    pub async fn run_dummy_fn(&self) { //~ ERROR E0759
         foo(|| self.bar()).await;
     }
 
index 0f58b158904db0a2fb3aa8fdb2e5c935c07e2707..56a28d904b91d57f29f79c8f6dba321a250422a5 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/issue-62097.rs:12:31
    |
 LL |     pub async fn run_dummy_fn(&self) {
index 21368fad3b05848a47ae08cfaa1c02f3e006e264..3c4f9a1f5ee2c3c0a433022517176f4abc0b7c56 100644 (file)
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags: -Z control-flow-guard
+// compile-flags: -C control-flow-guard
 
 pub fn main() {
     println!("hello, world");
diff --git a/src/test/ui/const-generics/defaults/wrong-order.rs b/src/test/ui/const-generics/defaults/wrong-order.rs
new file mode 100644 (file)
index 0000000..7f17c63
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
+
+struct A<T = u32, const N: usize> {
+    //~^ ERROR type parameters with a default must be trailing
+    arg: T,
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/wrong-order.stderr b/src/test/ui/const-generics/defaults/wrong-order.stderr
new file mode 100644 (file)
index 0000000..283f665
--- /dev/null
@@ -0,0 +1,19 @@
+error: type parameters with a default must be trailing
+  --> $DIR/wrong-order.rs:3:10
+   |
+LL | struct A<T = u32, const N: usize> {
+   |          ^
+   |
+   = note: using type defaults and const parameters in the same parameter list is currently not permitted
+
+warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/wrong-order.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/consts/issue-73976-monomorphic.rs b/src/test/ui/consts/issue-73976-monomorphic.rs
new file mode 100644 (file)
index 0000000..7706a97
--- /dev/null
@@ -0,0 +1,36 @@
+// check-pass
+//
+// This test is complement to the test in issue-73976-polymorphic.rs.
+// In that test we ensure that polymorphic use of type_id and type_name in patterns
+// will be properly rejected. This test will ensure that monomorphic use of these
+// would not be wrongly rejected in patterns.
+
+#![feature(const_type_id)]
+#![feature(const_type_name)]
+
+use std::any::{self, TypeId};
+
+pub struct GetTypeId<T>(T);
+
+impl<T: 'static> GetTypeId<T> {
+    pub const VALUE: TypeId = TypeId::of::<T>();
+}
+
+const fn check_type_id<T: 'static>() -> bool {
+    matches!(GetTypeId::<T>::VALUE, GetTypeId::<usize>::VALUE)
+}
+
+pub struct GetTypeNameLen<T>(T);
+
+impl<T: 'static> GetTypeNameLen<T> {
+    pub const VALUE: usize = any::type_name::<T>().len();
+}
+
+const fn check_type_name_len<T: 'static>() -> bool {
+    matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<usize>::VALUE)
+}
+
+fn main() {
+    assert!(check_type_id::<usize>());
+    assert!(check_type_name_len::<usize>());
+}
diff --git a/src/test/ui/consts/issue-73976-polymorphic.rs b/src/test/ui/consts/issue-73976-polymorphic.rs
new file mode 100644 (file)
index 0000000..28b8451
--- /dev/null
@@ -0,0 +1,40 @@
+// This test is from #73976. We previously did not check if a type is monomorphized
+// before calculating its type id, which leads to the bizzare behaviour below that
+// TypeId of a generic type does not match itself.
+//
+// This test case should either run-pass or be rejected at compile time.
+// Currently we just disallow this usage and require pattern is monomorphic.
+
+#![feature(const_type_id)]
+#![feature(const_type_name)]
+
+use std::any::{self, TypeId};
+
+pub struct GetTypeId<T>(T);
+
+impl<T: 'static> GetTypeId<T> {
+    pub const VALUE: TypeId = TypeId::of::<T>();
+}
+
+const fn check_type_id<T: 'static>() -> bool {
+    matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
+    //~^ ERROR could not evaluate constant pattern
+    //~| ERROR could not evaluate constant pattern
+}
+
+pub struct GetTypeNameLen<T>(T);
+
+impl<T: 'static> GetTypeNameLen<T> {
+    pub const VALUE: usize = any::type_name::<T>().len();
+}
+
+const fn check_type_name_len<T: 'static>() -> bool {
+    matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
+    //~^ ERROR could not evaluate constant pattern
+    //~| ERROR could not evaluate constant pattern
+}
+
+fn main() {
+    assert!(check_type_id::<usize>());
+    assert!(check_type_name_len::<usize>());
+}
diff --git a/src/test/ui/consts/issue-73976-polymorphic.stderr b/src/test/ui/consts/issue-73976-polymorphic.stderr
new file mode 100644 (file)
index 0000000..c90ce2b
--- /dev/null
@@ -0,0 +1,26 @@
+error: could not evaluate constant pattern
+  --> $DIR/issue-73976-polymorphic.rs:20:37
+   |
+LL |     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
+   |                                     ^^^^^^^^^^^^^^^^^^^^^
+
+error: could not evaluate constant pattern
+  --> $DIR/issue-73976-polymorphic.rs:32:42
+   |
+LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: could not evaluate constant pattern
+  --> $DIR/issue-73976-polymorphic.rs:20:37
+   |
+LL |     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
+   |                                     ^^^^^^^^^^^^^^^^^^^^^
+
+error: could not evaluate constant pattern
+  --> $DIR/issue-73976-polymorphic.rs:32:42
+   |
+LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
index d4ad706d01bc2359d73e7198f802bf7617d4aacc..89210fdf137e0d169203d61f79f1b6ff982686e0 100644 (file)
@@ -17,7 +17,7 @@ fn static_val<T: StaticTrait>(_: T) {
 }
 
 fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
-    static_val(x); //~ ERROR cannot infer
+    static_val(x); //~ ERROR E0759
 }
 
 fn not_static_val<T: NotStaticTrait>(_: T) {
index 268008c211129e704f6a5412c127a1aa1a9bf573..b3bef677d19c1c84999b011663277607a8f44ec4 100644 (file)
@@ -1,30 +1,17 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/dyn-trait.rs:20:16
    |
-LL |     static_val(x);
-   |                ^
-   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 19:26...
-  --> $DIR/dyn-trait.rs:19:26
-   |
 LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
-   |                          ^^
-note: ...so that the expression is assignable
-  --> $DIR/dyn-trait.rs:20:16
-   |
+   |                                 ------------------- this data with lifetime `'a`...
 LL |     static_val(x);
-   |                ^
-   = note: expected `std::boxed::Box<dyn std::fmt::Debug>`
-              found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>`
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the types are compatible
+   |                ^ ...is captured here...
+   |
+note: ...and is required to live as long as `'static` here
   --> $DIR/dyn-trait.rs:20:5
    |
 LL |     static_val(x);
    |     ^^^^^^^^^^
-   = note: expected `StaticTrait`
-              found `StaticTrait`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0759`.
index 3b339c5c3d7fc69a75c6a1f00338b8b8a748f2f2..4372de245078fc930be3cb4a27dd1f30e337be7d 100644 (file)
@@ -12,7 +12,7 @@ LL | fn elided(x: &i32) -> impl Copy + '_ { x }
    |                       ^^^^^^^^^^^^^^
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:6:32
+  --> $DIR/must_outlive_least_region_or_bound.rs:5:32
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
    |             --                 ^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
@@ -26,7 +26,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
    |                                ^^^^^^^^^^^^^^
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:9:46
+  --> $DIR/must_outlive_least_region_or_bound.rs:7:46
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               -                              ^ returning this value requires that `'1` must outlive `'static`
@@ -36,7 +36,7 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    = help: consider replacing `'1` with `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:12:55
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:55
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |              -- lifetime `'a` defined here            ^ returning this value requires that `'a` must outlive `'static`
@@ -45,7 +45,7 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    = help: consider replacing `'a` with `'static`
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/must_outlive_least_region_or_bound.rs:15:41
+  --> $DIR/must_outlive_least_region_or_bound.rs:11:41
    |
 LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               ----                      ^ lifetime `'a` required
@@ -53,7 +53,7 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:30:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:24
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |               -        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
@@ -61,7 +61,7 @@ LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |               let's call the lifetime of this reference `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:37:69
+  --> $DIR/must_outlive_least_region_or_bound.rs:28:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |               -- lifetime `'a` defined here                         ^ returning this value requires that `'a` must outlive `'static`
@@ -70,7 +70,7 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    = help: consider replacing `'a` with `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:42:61
+  --> $DIR/must_outlive_least_region_or_bound.rs:32:61
    |
 LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
    |                          --  -- lifetime `'b` defined here  ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
@@ -80,7 +80,7 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
    = help: consider adding the following bound: `'b: 'a`
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:47:51
+  --> $DIR/must_outlive_least_region_or_bound.rs:37:51
    |
 LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
    |                                                   ^^^^^^^^^^^^^^^^^^^^
index 9bf86fa66cdeda4c7ccd2cd6a55d18a2fbdc570a..51f488e45a6f3d14ce6cea95d318c3f06e126ef0 100644 (file)
@@ -1,41 +1,31 @@
 use std::fmt::Debug;
 
-fn elided(x: &i32) -> impl Copy { x }
-//~^ ERROR cannot infer an appropriate lifetime
+fn elided(x: &i32) -> impl Copy { x } //~ ERROR E0759
 
-fn explicit<'a>(x: &'a i32) -> impl Copy { x }
-//~^ ERROR cannot infer an appropriate lifetime
+fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~ ERROR E0759
 
-fn elided2(x: &i32) -> impl Copy + 'static { x }
-//~^ ERROR cannot infer an appropriate lifetime
+fn elided2(x: &i32) -> impl Copy + 'static { x } //~ ERROR E0759
 
-fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
-//~^ ERROR cannot infer an appropriate lifetime
+fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } //~ ERROR E0759
 
 fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
 //~^ ERROR explicit lifetime required in the type of `x`
 
-fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
-//~^ ERROR cannot infer an appropriate lifetime
+fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) } //~ ERROR E0759
 
-fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
-//~^ ERROR cannot infer an appropriate lifetime
+fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) } //~ ERROR E0759
 
-fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-//~^ ERROR cannot infer an appropriate lifetime
+fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
 
-fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-//~^ ERROR cannot infer an appropriate lifetime
+fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
 
-fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
-//~^ ERROR cannot infer an appropriate lifetime
-//~| ERROR cannot infer an appropriate lifetime
+fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) } //~ ERROR E0759
+//~^ ERROR E0759
 
 trait LifetimeTrait<'a> {}
 impl<'a> LifetimeTrait<'a> for &'a i32 {}
 
-fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
-//~^ ERROR cannot infer an appropriate lifetime
+fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } //~ ERROR E0759
 
 // Tests that a closure type containing 'b cannot be returned from a type where
 // only 'a was expected.
index ffadcaae08e05ed165636b369249098c140a5f37..b040889217e47032e23cfcffbd0b301ce63f31fa 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/must_outlive_least_region_or_bound.rs:3:35
    |
 LL | fn elided(x: &i32) -> impl Copy { x }
@@ -16,8 +16,8 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can
 LL | fn elided(x: &i32) -> impl Copy + '_ { x }
    |                                 ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:6:44
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:5:44
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
    |                    -------                 ^ ...is captured here...
@@ -25,7 +25,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
    |                    this data with lifetime `'a`...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:6:32
+  --> $DIR/must_outlive_least_region_or_bound.rs:5:32
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
    |                                ^^^^^^^^^
@@ -34,8 +34,8 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
    |                                          ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:9:46
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:7:46
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               ----                           ^ ...is captured here...
@@ -43,7 +43,7 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               this data with an anonymous lifetime `'_`...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:9:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:7:24
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |                        ^^^^^^^^^^^^^^^^^^^
@@ -56,8 +56,8 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x }
    |               ^^^^^^^^^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:12:55
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:55
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                     -------                           ^ ...is captured here...
@@ -65,7 +65,7 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                     this data with lifetime `'a`...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:12:33
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:33
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                                 ^^^^^^^^^^^^^^^^^^^
@@ -79,15 +79,15 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x }
    |                     ^^^^^^^^^^^^
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/must_outlive_least_region_or_bound.rs:15:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:11:24
    |
 LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               ----     ^^^^^^^^^^^^^^ lifetime `'a` required
    |               |
    |               help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:30:65
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:65
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |               ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static`
@@ -101,14 +101,14 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
    |                                                    ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:30:69
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:69
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |               ---- this data with an anonymous lifetime `'_`...     ^ ...is captured here...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:30:41
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:41
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |                                         ^^^^^^^^^^
@@ -121,14 +121,14 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
    |                                                    ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:37:69
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:28:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |                      ------- this data with lifetime `'a`...        ^ ...is captured here...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:37:34
+  --> $DIR/must_outlive_least_region_or_bound.rs:28:34
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -142,7 +142,7 @@ LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x
    |                      ^^^^^^^^^^^^
 
 error[E0623]: lifetime mismatch
-  --> $DIR/must_outlive_least_region_or_bound.rs:42:61
+  --> $DIR/must_outlive_least_region_or_bound.rs:32:61
    |
 LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
    |                                                 -------     ^^^^^^^^^^^^^^^^
@@ -151,15 +151,15 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
    |                                                 this parameter and the return type are declared with different lifetimes...
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:47:51
+  --> $DIR/must_outlive_least_region_or_bound.rs:37:51
    |
 LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
    |                                 --                ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
    |                                 |
    |                                 help: consider adding an explicit lifetime bound...: `T: 'static +`
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:18:50
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:14:50
    |
 LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
    |               ----                               ^ ...is captured here, requiring it to live as long as `'static`
@@ -171,8 +171,8 @@ help: to declare that the trait object captures data from argument `x`, you can
 LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
    |                                      ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:21:59
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:59
    |
 LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
    |                     -------                               ^ ...is captured here, requiring it to live as long as `'static`
@@ -184,8 +184,8 @@ help: to declare that the trait object captures data from argument `x`, you can
 LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
    |                                               ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:24:60
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:18:60
    |
 LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |               ----                                         ^ ...is captured here, requiring it to live as long as `'static`
@@ -201,8 +201,8 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn elided4(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |               ^^^^^^^^^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/must_outlive_least_region_or_bound.rs:27:69
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/must_outlive_least_region_or_bound.rs:20:69
    |
 LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |                     ------- this data with lifetime `'a`...         ^ ...is captured here, requiring it to live as long as `'static`
index 123ea6af6b019f6e5f171cf54fe57f575a805bac..65178cc9d24c262f3b186f99310df4a36a8c5330 100644 (file)
@@ -12,7 +12,7 @@ LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lifetime may not live long enough
-  --> $DIR/static-return-lifetime-infered.rs:10:37
+  --> $DIR/static-return-lifetime-infered.rs:9:37
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
    |                    --               ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
index 96f3652c226ea0b7eb09a02fab91689ee4158f5e..518c52f5de4d7bfb3b26ce59a59d6668a7259ced 100644 (file)
@@ -4,13 +4,11 @@ struct A {
 
 impl A {
     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-        self.x.iter().map(|a| a.0)
+        self.x.iter().map(|a| a.0) //~ ERROR E0759
     }
-    //~^^ ERROR cannot infer an appropriate lifetime
     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-        self.x.iter().map(|a| a.0)
+        self.x.iter().map(|a| a.0) //~ ERROR E0759
     }
-    //~^^ ERROR cannot infer an appropriate lifetime
 }
 
 fn main() {}
index df0db6e4fc6df927297d9793d271390de5bc21dd..7c289b388223a4b6ebff083f9f32210745ee7d6c 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/static-return-lifetime-infered.rs:7:16
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
@@ -18,8 +18,8 @@ help: to declare that the `impl Trait` captures data from argument `self`, you c
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
    |                                                           ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
-  --> $DIR/static-return-lifetime-infered.rs:11:16
+error[E0759]: `self` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/static-return-lifetime-infered.rs:10:16
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
    |                        -------- this data with lifetime `'a`...
@@ -29,7 +29,7 @@ LL |         self.x.iter().map(|a| a.0)
    |         ...is captured here...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/static-return-lifetime-infered.rs:10:37
+  --> $DIR/static-return-lifetime-infered.rs:9:37
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^
index 827163ef83cf7cf4c7f3fff461b0d28fce7d2333..f048ccd2427cb052cc465de1b9a3302236334e6e 100644 (file)
@@ -1,8 +1,7 @@
 use std::any::Any;
 
 fn foo<T: Any>(value: &T) -> Box<dyn Any> {
-    Box::new(value) as Box<dyn Any>
-    //~^ ERROR cannot infer an appropriate lifetime
+    Box::new(value) as Box<dyn Any> //~ ERROR E0759
 }
 
 fn main() {
index 919594fc9af4b434967d1975e1a23b41346c5f6e..6decc751321f9abfd3a434d39873dd34af7b6b87 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `value` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/issue-16922.rs:4:14
    |
 LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
diff --git a/src/test/ui/issues/issue-74614.rs b/src/test/ui/issues/issue-74614.rs
new file mode 100644 (file)
index 0000000..f5e8deb
--- /dev/null
@@ -0,0 +1,17 @@
+// build-pass
+
+fn test<T>() {
+    std::mem::size_of::<T>();
+}
+
+pub fn foo<T>(_: T) -> &'static fn() {
+    &(test::<T> as fn())
+}
+
+fn outer<T>() {
+    foo(|| ());
+}
+
+fn main() {
+    outer::<u8>();
+}
index 8421dc1d0c1303921e0981db1c908c9c8e4aa4e9..1931934a2112a7ded99b5e6ff3dfc08a4f15732d 100644 (file)
@@ -1,28 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+error[E0759]: `fn` parameter has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/constant-in-expr-inherent-1.rs:8:5
    |
-LL |     <Foo<'a>>::C
-   |     ^^^^^^^^^^^^
-   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 7:8...
-  --> $DIR/constant-in-expr-inherent-1.rs:7:8
-   |
 LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
-   |        ^^
-note: ...so that the types are compatible
-  --> $DIR/constant-in-expr-inherent-1.rs:8:5
-   |
-LL |     <Foo<'a>>::C
-   |     ^^^^^^^^^^^^
-   = note: expected `Foo<'_>`
-              found `Foo<'a>`
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/constant-in-expr-inherent-1.rs:8:5
-   |
+   |               ------- this data with lifetime `'a`...
 LL |     <Foo<'a>>::C
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0759`.
index 708ab1cf38297d2d3778de18bf1039063c09453c..4a2665d8e1694f2d68d04396c83127fe58b875b9 100644 (file)
@@ -15,7 +15,7 @@ fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
     // `Box<SomeTrait>` defaults to a `'static` bound, so this return
     // is illegal.
 
-    ss.r //~ ERROR cannot infer an appropriate lifetime
+    ss.r //~ ERROR E0759
 }
 
 fn store(ss: &mut SomeStruct, b: Box<dyn SomeTrait>) {
index 1b1e0d9610724b6e83c1a48c19e2a0ff427fb158..70b99ef7869ca8cfab83e016c7463e4eb2ef17d9 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `ss` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/object-lifetime-default-from-box-error.rs:18:5
    |
 LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
index 7bbcaebea0125ceb6bb6d1bd626e67d1a44b4ef8..f20605e1b9a610c02f35838c0764ac58c3e6ffda 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(const_generics, rustc_attrs)]
 //~^ WARN the feature `const_generics` is incomplete
 
index eb872eac74c9177c9c4d7a3c7b50373fde983475..266b6e62afd0bf930050b14dd4ac72f5e5763237 100644 (file)
@@ -1,5 +1,5 @@
 warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closures.rs:2:12
+  --> $DIR/closures.rs:3:12
    |
 LL | #![feature(const_generics, rustc_attrs)]
    |            ^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | #![feature(const_generics, rustc_attrs)]
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:18:19
+  --> $DIR/closures.rs:19:19
    |
 LL | pub fn unused<const T: usize>() -> usize {
    |                     - generic parameter `T` is unused
@@ -17,13 +17,13 @@ LL |     let add_one = |x: usize| x + 1;
    |                   ^^^^^^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:16:8
+  --> $DIR/closures.rs:17:8
    |
 LL | pub fn unused<const T: usize>() -> usize {
    |        ^^^^^^       - generic parameter `T` is unused
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:27:19
+  --> $DIR/closures.rs:28:19
    |
 LL | pub fn used_parent<const T: usize>() -> usize {
    |                          - generic parameter `T` is unused
@@ -32,7 +32,7 @@ LL |     let add_one = |x: usize| x + 1;
    |                   ^^^^^^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:47:13
+  --> $DIR/closures.rs:48:13
    |
 LL | pub fn unused_upvar<const T: usize>() -> usize {
    |                           - generic parameter `T` is unused
index 77539b94e489a0a712d17520a007b02142b057e5..04c279de29e6ac5ae9485c40a231d71b003e03ec 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(const_generics, rustc_attrs)]
 //~^ WARN the feature `const_generics` is incomplete
 
index c99a9b788ebc5e012430a69ef8093870f9530e65..e379e32c1fceb11cbc9ef4e4a6e259f5da0b80f2 100644 (file)
@@ -1,5 +1,5 @@
 warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/functions.rs:2:12
+  --> $DIR/functions.rs:3:12
    |
 LL | #![feature(const_generics, rustc_attrs)]
    |            ^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | #![feature(const_generics, rustc_attrs)]
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
 
 error: item has unused generic parameters
-  --> $DIR/functions.rs:14:8
+  --> $DIR/functions.rs:15:8
    |
 LL | pub fn unused<const T: usize>() {
    |        ^^^^^^       - generic parameter `T` is unused
index ce56b7a358861c30d404cd9aa11a6eecd7e454cf..2695dc6d4f177229160116266edadc9055bc8988 100644 (file)
@@ -1,4 +1,5 @@
 // check-pass
+// compile-flags:-Zpolymorphize=on
 
 pub struct OnDrop<F: Fn()>(pub F);
 
index b7ea07b6bc653595cff967c32e345810cbf85f0b..c22891171091ab38bb47484d2e3b7be648e92487 100644 (file)
@@ -1,4 +1,5 @@
 // check-pass
+// compile-flags:-Zpolymorphize=on
 
 pub struct OnDrop<F: Fn()>(pub F);
 
index 1acba7c8bf14cff441da22bb9328b1a87cdecbed..9eb34fb73490b8585d9d4c4bf458e61e0b7ae964 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(const_generics, generators, generator_trait, rustc_attrs)]
 //~^ WARN the feature `const_generics` is incomplete
 
index b3e5a2de0270a6049e27335c1addcb5dd9c7a916..c59055ba9d65473ff191d5463825056a64bde007 100644 (file)
@@ -1,5 +1,5 @@
 warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/generators.rs:2:12
+  --> $DIR/generators.rs:3:12
    |
 LL | #![feature(const_generics, generators, generator_trait, rustc_attrs)]
    |            ^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | #![feature(const_generics, generators, generator_trait, rustc_attrs)]
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
 
 error: item has unused generic parameters
-  --> $DIR/generators.rs:35:5
+  --> $DIR/generators.rs:36:5
    |
 LL |   pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
    |                      - generic parameter `T` is unused
@@ -21,13 +21,13 @@ LL | |     }
    | |_____^
 
 error: item has unused generic parameters
-  --> $DIR/generators.rs:33:8
+  --> $DIR/generators.rs:34:8
    |
 LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
    |        ^^^^^^^^^^^ - generic parameter `T` is unused
 
 error: item has unused generic parameters
-  --> $DIR/generators.rs:61:5
+  --> $DIR/generators.rs:62:5
    |
 LL |   pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
    |                             - generic parameter `T` is unused
@@ -40,7 +40,7 @@ LL | |     }
    | |_____^
 
 error: item has unused generic parameters
-  --> $DIR/generators.rs:59:8
+  --> $DIR/generators.rs:60:8
    |
 LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
    |        ^^^^^^^^^^^^       - generic parameter `T` is unused
index 4bde349a336ea3b2dd85d8264fe53a340b3665a9..f26df45230a5c604a6d6b3894d72ee01ec1eb754 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(rustc_attrs)]
 
 // This test checks that the polymorphization analysis doesn't break when the
index 6c85e4f291611f855d91d4c74d70377b2376072b..2020256717c4de4763257ab5143c4318896d815e 100644 (file)
@@ -1,11 +1,11 @@
 error: item has unused generic parameters
-  --> $DIR/lifetimes.rs:9:8
+  --> $DIR/lifetimes.rs:10:8
    |
 LL | pub fn unused<'a, T>(_: &'a u32) {
    |        ^^^^^^     - generic parameter `T` is unused
 
 error: item has unused generic parameters
-  --> $DIR/lifetimes.rs:16:19
+  --> $DIR/lifetimes.rs:17:19
    |
 LL | pub fn used<'a, T: Default>(_: &'a u32) -> u32 {
    |                 - generic parameter `T` is unused
index fa76b7201e8c3cabfa6e2d47eb0b5e25d843ecfb..d732b1071d8a94830543dfde91f7fbbd82932dd2 100644 (file)
@@ -1,4 +1,5 @@
 // build-pass
+// compile-flags:-Zpolymorphize=on
 
 pub trait ParallelIterator: Sized {
     fn drive<C: Consumer<()>>(_: C) {
index 390ac983aa00779060eccd348aa1750bab5035c7..82a94933b470eba3ef53e7dcd1ffd0198f9cf945 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(rustc_attrs)]
 
 // This test checks that `T` is considered used in `foo`, because it is used in a predicate for
index 1b266083463a2518a4816a3fd1151e077a6b6137..c23730fc995e7fd5058753aafecb6f408832f8bf 100644 (file)
@@ -1,5 +1,5 @@
 error: item has unused generic parameters
-  --> $DIR/predicates.rs:8:4
+  --> $DIR/predicates.rs:9:4
    |
 LL | fn bar<I>() {
    |    ^^^ - generic parameter `I` is unused
index 1fbe13380b5b99ab9cb172dbeff9b680320dee97..07ab1355a47cfe62159c653ae6dcb8d51ef2bd1d 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(stmt_expr_attributes, rustc_attrs)]
 
 // This test checks that the polymorphization analysis correctly detects unused type
index d68e6e25a1eb969ae48bb03f0e3c455dbf7b7311..417feebbc5557d8d4788b2faf28b3810b15c9da2 100644 (file)
@@ -1,5 +1,5 @@
 error: item has unused generic parameters
-  --> $DIR/closures.rs:18:19
+  --> $DIR/closures.rs:19:19
    |
 LL | pub fn unused<T>() -> u32 {
    |               - generic parameter `T` is unused
@@ -8,13 +8,13 @@ LL |     let add_one = |x: u32| x + 1;
    |                   ^^^^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:15:8
+  --> $DIR/closures.rs:16:8
    |
 LL | pub fn unused<T>() -> u32 {
    |        ^^^^^^ - generic parameter `T` is unused
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:27:19
+  --> $DIR/closures.rs:28:19
    |
 LL | pub fn used_parent<T: Default>() -> u32 {
    |                    - generic parameter `T` is unused
@@ -23,7 +23,7 @@ LL |     let add_one = |x: u32| x + 1;
    |                   ^^^^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:93:23
+  --> $DIR/closures.rs:94:23
    |
 LL | impl<F: Default> Foo<F> {
    |      - generic parameter `F` is unused
@@ -35,7 +35,7 @@ LL |         let add_one = |x: u32| x + 1;
    |                       ^^^^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:91:12
+  --> $DIR/closures.rs:92:12
    |
 LL | impl<F: Default> Foo<F> {
    |      - generic parameter `F` is unused
@@ -44,7 +44,7 @@ LL |     pub fn unused_all<G: Default>() -> u32 {
    |            ^^^^^^^^^^ - generic parameter `G` is unused
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:127:23
+  --> $DIR/closures.rs:128:23
    |
 LL |       pub fn used_impl<G: Default>() -> u32 {
    |                        - generic parameter `G` is unused
@@ -58,13 +58,13 @@ LL | |         };
    | |_________^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:125:12
+  --> $DIR/closures.rs:126:12
    |
 LL |     pub fn used_impl<G: Default>() -> u32 {
    |            ^^^^^^^^^ - generic parameter `G` is unused
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:114:23
+  --> $DIR/closures.rs:115:23
    |
 LL |   impl<F: Default> Foo<F> {
    |        - generic parameter `F` is unused
@@ -78,7 +78,7 @@ LL | |         };
    | |_________^
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:112:12
+  --> $DIR/closures.rs:113:12
    |
 LL | impl<F: Default> Foo<F> {
    |      - generic parameter `F` is unused
index 38f10148c2c526ef442ce16222ed8fa59eb9a2c0..aad957e1dd36239a903ad59e21659f94a58dff2e 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(rustc_attrs)]
 
 // This test checks that the polymorphization analysis correctly detects unused type
index be4c6576e964557b5ca0586ea138ada357eff54e..d629ff7bb4d3a2c5eeeeeb8552aa89c0bb264f9f 100644 (file)
@@ -1,11 +1,11 @@
 error: item has unused generic parameters
-  --> $DIR/functions.rs:13:8
+  --> $DIR/functions.rs:14:8
    |
 LL | pub fn unused<T>() {
    |        ^^^^^^ - generic parameter `T` is unused
 
 error: item has unused generic parameters
-  --> $DIR/functions.rs:44:12
+  --> $DIR/functions.rs:45:12
    |
 LL | impl<F: Default> Foo<F> {
    |      - generic parameter `F` is unused
@@ -14,7 +14,7 @@ LL |     pub fn unused_impl() {
    |            ^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/functions.rs:50:12
+  --> $DIR/functions.rs:51:12
    |
 LL | impl<F: Default> Foo<F> {
    |      - generic parameter `F` is unused
@@ -23,7 +23,7 @@ LL |     pub fn unused_both<G: Default>() {
    |            ^^^^^^^^^^^ - generic parameter `G` is unused
 
 error: item has unused generic parameters
-  --> $DIR/functions.rs:62:12
+  --> $DIR/functions.rs:63:12
    |
 LL | impl<F: Default> Foo<F> {
    |      - generic parameter `F` is unused
index d2f3d4f13cdcc0c996147652347dfca45a6eac51..b8facc16070102e414954e52cef47e8ceccacab4 100644 (file)
@@ -1,4 +1,5 @@
 // build-fail
+// compile-flags:-Zpolymorphize=on
 #![feature(fn_traits, rustc_attrs, unboxed_closures)]
 
 // This test checks that the polymorphization analysis considers a closure
index b8b96bbdf15a6e4009950b24f7cbc8057a8add1d..d4727acca9afd9169671d093879b179f101c401a 100644 (file)
@@ -1,5 +1,5 @@
 error: item has unused generic parameters
-  --> $DIR/unsized_cast.rs:10:18
+  --> $DIR/unsized_cast.rs:11:18
    |
 LL | fn foo<T: Default>() {
    |        - generic parameter `T` is unused
@@ -8,7 +8,7 @@ LL |     (|| Box::new(|| {}) as Box<dyn Fn()>)();
    |                  ^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/unsized_cast.rs:10:5
+  --> $DIR/unsized_cast.rs:11:5
    |
 LL | fn foo<T: Default>() {
    |        - generic parameter `T` is unused
@@ -17,7 +17,7 @@ LL |     (|| Box::new(|| {}) as Box<dyn Fn()>)();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: item has unused generic parameters
-  --> $DIR/unsized_cast.rs:20:15
+  --> $DIR/unsized_cast.rs:21:15
    |
 LL | fn foo2<T: Default>() {
    |         - generic parameter `T` is unused
index 1894cd218ee347f94546d2b7fa32a878f5937ad1..301edc0d086b11fee1b251fd47b5ab7ebba36190 100644 (file)
@@ -8,12 +8,12 @@ print-type-size     variant `Some`: 12 bytes
 print-type-size         field `.0`: 12 bytes
 print-type-size     variant `None`: 0 bytes
 print-type-size type: `EmbeddedDiscr`: 8 bytes, alignment: 4 bytes
-print-type-size     discriminant: 1 bytes
 print-type-size     variant `Record`: 7 bytes
-print-type-size         field `.pre`: 1 bytes
-print-type-size         field `.post`: 2 bytes
 print-type-size         field `.val`: 4 bytes
+print-type-size         field `.post`: 2 bytes
+print-type-size         field `.pre`: 1 bytes
 print-type-size     variant `None`: 0 bytes
+print-type-size     end padding: 1 bytes
 print-type-size type: `MyOption<Union1<std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
index 5d199149c39b860d029bc80728988afe33c76b25..9d3f485e314385148fd081174954b3faaf1cedb7 100644 (file)
@@ -5,18 +5,18 @@ trait Foo {}
 impl<'a> Foo for &'a [u8] {}
 
 fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
-    let x: Box<dyn Foo + 'static> = Box::new(v); //~ ERROR cannot infer an appropriate lifetime
+    let x: Box<dyn Foo + 'static> = Box::new(v); //~ ERROR E0759
     x
 }
 
 fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
-    Box::new(v) //~ ERROR cannot infer an appropriate lifetime
+    Box::new(v) //~ ERROR E0759
 }
 
 fn c(v: &[u8]) -> Box<dyn Foo> {
     // same as previous case due to RFC 599
 
-    Box::new(v) //~ ERROR cannot infer an appropriate lifetime
+    Box::new(v) //~ ERROR E0759
 }
 
 fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
index 7f5a3a47976c7d38f812fa9fb9a1232657dd2a1c..63fea1f41626d10e22dda55f34b9a949d772d92d 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/region-object-lifetime-in-coercion.rs:8:46
    |
 LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
@@ -15,7 +15,7 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn a(v: &'static [u8]) -> Box<dyn Foo + 'static> {
    |         ^^^^^^^^^^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/region-object-lifetime-in-coercion.rs:13:14
    |
 LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
@@ -32,7 +32,7 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn b(v: &'static [u8]) -> Box<dyn Foo + 'static> {
    |         ^^^^^^^^^^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/region-object-lifetime-in-coercion.rs:19:14
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo> {
index 647212407fc8a5217178f5324d3a321039378f9c..4eb1b275f163ec77af5f50bb86c28b486e72644f 100644 (file)
@@ -4,7 +4,7 @@ struct Dog {
 
 impl Dog {
     pub fn chase_cat(&mut self) {
-        let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
+        let p: &'static mut usize = &mut self.cats_chased; //~ ERROR E0759
         *p += 1;
     }
 
index a0b8b6b51e5a1b36572ad8567ad4cbfd94ce81b7..738691fd695eb4fe2aa8e05f40fbbe675e108a1b 100644 (file)
@@ -1,29 +1,11 @@
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/regions-addr-of-self.rs:7:37
    |
+LL |     pub fn chase_cat(&mut self) {
+   |                      --------- this data with an anonymous lifetime `'_`...
 LL |         let p: &'static mut usize = &mut self.cats_chased;
-   |                                     ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
-  --> $DIR/regions-addr-of-self.rs:6:5
-   |
-LL | /     pub fn chase_cat(&mut self) {
-LL | |         let p: &'static mut usize = &mut self.cats_chased;
-LL | |         *p += 1;
-LL | |     }
-   | |_____^
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/regions-addr-of-self.rs:7:37
-   |
-LL |         let p: &'static mut usize = &mut self.cats_chased;
-   |                                     ^^^^^^^^^^^^^^^^^^^^^
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/regions-addr-of-self.rs:7:37
-   |
-LL |         let p: &'static mut usize = &mut self.cats_chased;
-   |                                     ^^^^^^^^^^^^^^^^^^^^^
+   |                                     ^^^^^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0759`.
index 2364ba2728600e7f7a4478c3b4621318ee78689c..7144ab5a24c51443ec36b8dffda63669e12317a0 100644 (file)
@@ -7,7 +7,7 @@ trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
-    box B(&*v) as Box<dyn X> //~ ERROR cannot infer
+    box B(&*v) as Box<dyn X> //~ ERROR E0759
 }
 
 fn main() { }
index 114e4052aae09b63159cc61e3899af7c0e982403..aab7ce993aa3c3861a55018bbfb1b46912c75056 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/regions-close-object-into-object-2.rs:10:11
    |
 LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
index d5310770436866d544eae03d33347d6a3027b907..4c087f264f92b964010c16521d98fd6a97f92889 100644 (file)
@@ -7,7 +7,7 @@ trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
-    box B(&*v) as Box<dyn X> //~ ERROR cannot infer
+    box B(&*v) as Box<dyn X> //~ ERROR E0759
 }
 
 fn main() {}
index 850d81940791fd168afbe9224765cf642bbaaf61..90f807a41c5629f07d04aeb0d00a47b1491fa879 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/regions-close-object-into-object-4.rs:10:11
    |
 LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
index 8617c0e9da8f76f51a6319847965b265e8aff148..55d964ac5340569b287a993d650fe88ba70b2f94 100644 (file)
@@ -6,7 +6,7 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box<dyn FnMut()->(isize) + 'a> {
 
 fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
     // This is illegal, because the region bound on `proc` is 'static.
-    Box::new(move || { *x }) //~ ERROR cannot infer an appropriate lifetime
+    Box::new(move || { *x }) //~ ERROR E0759
 }
 
 fn main() { }
index 67eee3bb6e28127bbd8db3417d40386340b6a38f..e76073f4f6b13f5b6be54d1179799ef19cd2c63c 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/regions-proc-bound-capture.rs:9:14
    |
 LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
diff --git a/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/src/test/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
new file mode 100644 (file)
index 0000000..a65c17e
--- /dev/null
@@ -0,0 +1,66 @@
+// Regression test for #74429, where we didn't think that a type parameter
+// outlived `ReEmpty`.
+
+// check-pass
+
+use std::marker::PhantomData;
+use std::ptr::NonNull;
+
+pub unsafe trait RawData {
+    type Elem;
+}
+
+unsafe impl<A> RawData for OwnedRepr<A> {
+    type Elem = A;
+}
+
+unsafe impl<'a, A> RawData for ViewRepr<&'a A> {
+    type Elem = A;
+}
+
+pub struct OwnedRepr<A> {
+    ptr: PhantomData<A>,
+}
+
+// these Copy impls are not necessary for the repro, but allow the code to compile without error
+// on 1.44.1
+#[derive(Copy, Clone)]
+pub struct ViewRepr<A> {
+    life: PhantomData<A>,
+}
+
+#[derive(Copy, Clone)]
+pub struct ArrayBase<S>
+where
+    S: RawData,
+{
+    ptr: NonNull<S::Elem>,
+}
+
+pub type Array<A> = ArrayBase<OwnedRepr<A>>;
+
+pub type ArrayView<'a, A> = ArrayBase<ViewRepr<&'a A>>;
+
+impl<A, S> ArrayBase<S>
+where
+    S: RawData<Elem = A>,
+{
+    pub fn index_axis(&self) -> ArrayView<'_, A> {
+        unimplemented!()
+    }
+
+    pub fn axis_iter<'a>(&'a self) -> std::iter::Empty<&'a A> {
+        unimplemented!()
+    }
+}
+
+pub fn x<T: Copy>(a: Array<T>) {
+    // drop just avoids a must_use warning
+    drop((0..1).filter(|_| true));
+    let y = a.index_axis();
+    a.axis_iter().for_each(|_| {
+        drop(y);
+    });
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs b/src/test/ui/regions/type-param-outlives-reempty-issue-74429.rs
new file mode 100644 (file)
index 0000000..d463f31
--- /dev/null
@@ -0,0 +1,35 @@
+// Regression test for #74429, where we didn't think that a type parameter
+// outlived `ReEmpty`.
+
+// check-pass
+
+use std::marker::PhantomData;
+
+fn apply<T, F: FnOnce(T)>(_: T, _: F) {}
+
+#[derive(Clone, Copy)]
+struct Invariant<T> {
+    t: T,
+    p: PhantomData<fn(T) -> T>,
+}
+
+fn verify_reempty<T>(x: T) {
+    // r is inferred to have type `Invariant<&ReEmpty(U0) T>`
+    let r = Invariant { t: &x, p: PhantomData };
+    // Creates a new universe, all variables from now on are in `U1`, say.
+    let _: fn(&()) = |_| {};
+    // Closure parameter is of type `&ReEmpty(U1) T`, so the closure has an implied
+    // bound of `T: ReEmpty(U1)`
+    apply(&x, |_| {
+        // Requires `typeof(r)` is well-formed, i.e. `T: ReEmpty(U0)`. If we
+        // only have the implied bound from the closure parameter to use this
+        // requires `ReEmpty(U1): ReEmpty(U0)`, which isn't true so we reported
+        // an error.
+        //
+        // This doesn't happen any more because we ensure that `T: ReEmpty(U0)`
+        // is an implicit bound for all type parameters.
+        drop(r);
+    });
+}
+
+fn main() {}
index 64d6ccf34091681d386c7c3f746c7e529e2d15fb..9439df266d59bbe6c7da7b1d0a822e3462f55917 100644 (file)
@@ -2,7 +2,7 @@
 // being run when compiling with new LLVM pass manager and ThinLTO.
 // Note: The issue occurred only on non-zero opt-level.
 //
-// min-llvm-version 9.0
+// min-llvm-version: 9.0
 // needs-sanitizer-support
 // needs-sanitizer-address
 //
index 0afe631f1e3fc03921e8539f2eee46ca69cc546f..43998ca8c5784478dfca0e18aea561c2aab3ef40 100644 (file)
@@ -6,7 +6,7 @@
 
 impl Foo {
     async fn f(self: Pin<&Self>) -> impl Clone { self }
-    //~^ ERROR cannot infer an appropriate lifetime
+    //~^ ERROR E0759
 }
 
 fn main() {
index f2fbb0ba7d7556738dd6951afe48ea920e2553d7..9cd0fd328ffa007a37fda588dbed69e79ce2aca9 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
index 5054568b18970ca0331dfde31bed23c1de9c65ac..04935fc52ab9e31253bb8dce181cacfafdd589ac 100644 (file)
@@ -3,7 +3,7 @@
 struct Foo;
 
 impl Foo {
-    fn f(self: Pin<&Self>) -> impl Clone { self } //~ ERROR cannot infer an appropriate lifetime
+    fn f(self: Pin<&Self>) -> impl Clone { self } //~ ERROR E0759
 }
 
 fn main() {
index 2e10ab3d3f9b84a8c1802524008ab8020e311bd2..cb9d5b56dbc5cbd585691e8647bf4a224f660776 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
index 5db924642e59df3d1f021b83f2f240d0529eef56..80d7ae6dc637d78723cdc17ab762f4d7945bc324 100644 (file)
@@ -62,7 +62,7 @@ fn multiple3() { }
 #[rustc_deprecated(since = "b", reason = "text")]
 #[rustc_const_unstable(feature = "c", issue = "none")]
 #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
-pub const fn multiple4() { } //~ ERROR multiple rustc_deprecated attributes [E0540]
+pub const fn multiple4() { } //~ ERROR multiple deprecated attributes
 //~^ ERROR Invalid stability or deprecation version found
 
 #[rustc_deprecated(since = "a", reason = "text")]
index 3c5da3f14403503d00caf5533ede8b3624fd8f80..134c657c62015b51be3739ec0fa7ba2d048d14a1 100644 (file)
@@ -82,7 +82,7 @@ error[E0544]: multiple stability levels
 LL | #[stable(feature = "a", since = "b")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0540]: multiple rustc_deprecated attributes
+error[E0550]: multiple deprecated attributes
   --> $DIR/stability-attribute-sanity.rs:65:1
    |
 LL | pub const fn multiple4() { }
@@ -108,5 +108,5 @@ LL | fn deprecated_without_unstable_or_stable() { }
 
 error: aborting due to 18 previous errors
 
-Some errors have detailed explanations: E0539, E0541.
+Some errors have detailed explanations: E0539, E0541, E0550.
 For more information about an error, try `rustc --explain E0539`.
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr
new file mode 100644 (file)
index 0000000..acf0c0e
--- /dev/null
@@ -0,0 +1,37 @@
+error[E0597]: `val` does not live long enough
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9
+   |
+LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
+   |               -- lifetime `'a` defined here                  ------------------- opaque type requires that `val` is borrowed for `'a`
+LL |         val.use_self()
+   |         ^^^ borrowed value does not live long enough
+LL |     }
+   |     - `val` dropped here while still borrowed
+   |
+help: you can add a bound to the opaque type to make it last less than `'static` and match `'a`
+   |
+LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> + 'a {
+   |                                                                                  ^^^^
+
+error[E0515]: cannot return value referencing function parameter `val`
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9
+   |
+LL |         val.use_self()
+   |         ---^^^^^^^^^^^
+   |         |
+   |         returns a value referencing data owned by the current function
+   |         `val` is borrowed here
+
+error[E0515]: cannot return value referencing function parameter `val`
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:109:9
+   |
+LL |         val.use_self()
+   |         ---^^^^^^^^^^^
+   |         |
+   |         returns a value referencing data owned by the current function
+   |         `val` is borrowed here
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0515, E0597.
+For more information about an error, try `rustc --explain E0515`.
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
new file mode 100644 (file)
index 0000000..b2dc16a
--- /dev/null
@@ -0,0 +1,113 @@
+// FIXME: the following cases need to suggest more things to make users reach a working end state.
+
+mod bav {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {
+        type Assoc: Bar;
+    }
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Bar {}
+
+    impl MyTrait for Box<dyn ObjectTrait<Assoc = i32>> {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Bar for i32 {}
+
+    fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
+        val.use_self() //~ ERROR E0597
+    }
+}
+
+mod bap {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {
+        type Assoc: Bar;
+    }
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Bar {}
+
+    impl MyTrait for Box<dyn ObjectTrait<Assoc = i32>> {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Bar for i32 {}
+
+    fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> + 'a {
+        val.use_self() //~ ERROR E0515
+    }
+}
+
+// This case in particular requires the user to write all of the bounds we have in `mod bax`.
+mod bay {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {
+        type Assoc: Bar;
+    }
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Bar {}
+
+    impl MyTrait for Box<dyn ObjectTrait<Assoc = i32>> {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Bar for i32 {}
+
+    fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod bax {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {
+        type Assoc: Bar;
+    }
+    trait MyTrait<'a> {
+        fn use_self(&'a self) -> &'a () { panic!() }
+    }
+    trait Bar {}
+
+    impl<'a> MyTrait<'a> for Box<dyn ObjectTrait<Assoc = i32> + 'a> {
+        fn use_self(&'a self) -> &'a () { panic!() }
+    }
+    impl Bar for i32 {}
+
+    fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
+        val.use_self()
+    }
+}
+
+mod baw {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {
+        type Assoc: Bar;
+    }
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Bar {}
+
+    impl<'a> MyTrait for Box<dyn ObjectTrait<Assoc = Box<dyn Bar>>> {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = Box<dyn Bar>>>) -> impl OtherTrait<'a> + 'a{
+        val.use_self() //~ ERROR E0515
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
new file mode 100644 (file)
index 0000000..00971b4
--- /dev/null
@@ -0,0 +1,57 @@
+error[E0597]: `val` does not live long enough
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9
+   |
+LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
+   |               -- lifetime `'a` defined here                  ------------------- opaque type requires that `val` is borrowed for `'a`
+LL |         val.use_self()
+   |         ^^^ borrowed value does not live long enough
+LL |     }
+   |     - `val` dropped here while still borrowed
+   |
+help: you can add a bound to the opaque type to make it last less than `'static` and match `'a`
+   |
+LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> + 'a {
+   |                                                                                  ^^^^
+
+error[E0515]: cannot return value referencing function parameter `val`
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9
+   |
+LL |         val.use_self()
+   |         ---^^^^^^^^^^^
+   |         |
+   |         returns a value referencing data owned by the current function
+   |         `val` is borrowed here
+
+error[E0515]: cannot return value referencing function parameter `val`
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:109:9
+   |
+LL |         val.use_self()
+   |         ---^^^^^^^^^^^
+   |         |
+   |         returns a value referencing data owned by the current function
+   |         `val` is borrowed here
+
+error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an implicit `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:13
+   |
+LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
+   |                        -------------------------------------- this data with lifetime `'a`...
+LL |         val.use_self()
+   |             ^^^^^^^^ ...is captured and required to live as long as `'static` here
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:60:30
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait<Assoc = i32>> {
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait<Assoc = i32> + '_> {
+   |                                                       ^^^^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0515, E0597.
+For more information about an error, try `rustc --explain E0515`.
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.fixed b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.fixed
new file mode 100644 (file)
index 0000000..3c10f85
--- /dev/null
@@ -0,0 +1,112 @@
+// run-rustfix
+#![allow(dead_code)]
+
+mod foo {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait<T> {}
+    trait MyTrait<T> {
+        fn use_self<K>(&self) -> &();
+    }
+    trait Irrelevant {}
+
+    impl<T> MyTrait<T> for dyn ObjectTrait<T> + '_ {
+        fn use_self<K>(&self) -> &() { panic!() }
+    }
+    impl<T> Irrelevant for dyn ObjectTrait<T> {}
+
+    fn use_it<'a, T>(val: &'a dyn ObjectTrait<T>) -> impl OtherTrait<'a> + 'a {
+        val.use_self::<T>() //~ ERROR E0759
+    }
+}
+
+mod bar {
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &();
+    }
+    trait Irrelevant {}
+
+    impl MyTrait for dyn ObjectTrait + '_ {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Irrelevant for dyn ObjectTrait {}
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod baz {
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &();
+    }
+    trait Irrelevant {}
+
+    impl MyTrait for Box<dyn ObjectTrait + '_> {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Irrelevant for Box<dyn ObjectTrait> {}
+
+    fn use_it<'a>(val: &'a Box<dyn ObjectTrait + 'a>) -> &'a () {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod bat {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {}
+
+    impl dyn ObjectTrait + '_ {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod ban {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Irrelevant {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    impl MyTrait for dyn ObjectTrait + '_ {}
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+        val.use_self() //~ ERROR E0759
+    }
+}
+
+mod bal {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Irrelevant {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    impl MyTrait for dyn ObjectTrait + '_ {}
+    impl Irrelevant for dyn ObjectTrait {}
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+        MyTrait::use_self(val) //~ ERROR E0759
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr
new file mode 100644 (file)
index 0000000..697467d
--- /dev/null
@@ -0,0 +1,42 @@
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:20:9
+   |
+LL |     fn use_it<'a, T>(val: &'a dyn ObjectTrait<T>) -> impl OtherTrait<'a> + 'a {
+   |                      --- `val` is a reference that is only valid in the function body
+LL |         val.use_self::<T>()
+   |         ^^^^^^^^^^^^^^^^^^^ `val` escapes the function body here
+   |
+   = help: consider replacing `'a` with `'static`
+
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:69:9
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+   |                   --- `val` is a reference that is only valid in the function body
+LL |         val.use_self()
+   |         ^^^^^^^^^^^^^^ `val` escapes the function body here
+   |
+   = help: consider replacing `'a` with `'static`
+
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:88:9
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> {
+   |                   --- `val` is a reference that is only valid in the function body
+LL |         val.use_self()
+   |         ^^^^^^^^^^^^^^ `val` escapes the function body here
+   |
+   = help: consider replacing `'a` with `'static`
+
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:108:9
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+   |                   --- `val` is a reference that is only valid in the function body
+LL |         MyTrait::use_self(val)
+   |         ^^^^^^^^^^^^^^^^^^^^^^ `val` escapes the function body here
+   |
+   = help: consider replacing `'a` with `'static`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs
new file mode 100644 (file)
index 0000000..88ab03d
--- /dev/null
@@ -0,0 +1,112 @@
+// run-rustfix
+#![allow(dead_code)]
+
+mod foo {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait<T> {}
+    trait MyTrait<T> {
+        fn use_self<K>(&self) -> &();
+    }
+    trait Irrelevant {}
+
+    impl<T> MyTrait<T> for dyn ObjectTrait<T> {
+        fn use_self<K>(&self) -> &() { panic!() }
+    }
+    impl<T> Irrelevant for dyn ObjectTrait<T> {}
+
+    fn use_it<'a, T>(val: &'a dyn ObjectTrait<T>) -> impl OtherTrait<'a> + 'a {
+        val.use_self::<T>() //~ ERROR E0759
+    }
+}
+
+mod bar {
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &();
+    }
+    trait Irrelevant {}
+
+    impl MyTrait for dyn ObjectTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Irrelevant for dyn ObjectTrait {}
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod baz {
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &();
+    }
+    trait Irrelevant {}
+
+    impl MyTrait for Box<dyn ObjectTrait> {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    impl Irrelevant for Box<dyn ObjectTrait> {}
+
+    fn use_it<'a>(val: &'a Box<dyn ObjectTrait + 'a>) -> &'a () {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod bat {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {}
+
+    impl dyn ObjectTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+        val.use_self() //~ ERROR E0772
+    }
+}
+
+mod ban {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Irrelevant {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    impl MyTrait for dyn ObjectTrait {}
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> {
+        val.use_self() //~ ERROR E0759
+    }
+}
+
+mod bal {
+    trait OtherTrait<'a> {}
+    impl<'a> OtherTrait<'a> for &'a () {}
+
+    trait ObjectTrait {}
+    trait MyTrait {
+        fn use_self(&self) -> &() { panic!() }
+    }
+    trait Irrelevant {
+        fn use_self(&self) -> &() { panic!() }
+    }
+
+    impl MyTrait for dyn ObjectTrait {}
+    impl Irrelevant for dyn ObjectTrait {}
+
+    fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+        MyTrait::use_self(val) //~ ERROR E0759
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr
new file mode 100644 (file)
index 0000000..2fb6c25
--- /dev/null
@@ -0,0 +1,134 @@
+error[E0759]: `val` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:20:13
+   |
+LL |     fn use_it<'a, T>(val: &'a dyn ObjectTrait<T>) -> impl OtherTrait<'a> + 'a {
+   |                           ---------------------- this data with lifetime `'a`...
+LL |         val.use_self::<T>()
+   |             ^^^^^^^^ ...is captured and required to live as long as `'static` here
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:14:32
+   |
+LL |     impl<T> MyTrait<T> for dyn ObjectTrait<T> {
+   |                                ^^^^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self<K>(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl<T> MyTrait<T> for dyn ObjectTrait<T> + '_ {
+   |                                               ^^^^
+
+error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an implicit `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:69:13
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+   |                        ------------------- this data with lifetime `'a`...
+LL |         val.use_self()
+   |             ^^^^^^^^ ...is captured and required to live as long as `'static` here because of an implicit lifetime bound on the inherent `impl`
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:64:14
+   |
+LL |     impl dyn ObjectTrait {
+   |              ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl dyn ObjectTrait + '_ {
+   |                          ^^^^
+
+error[E0759]: `val` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:88:13
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> {
+   |                        ------------------- this data with lifetime `'a`...
+LL |         val.use_self()
+   |             ^^^^^^^^ ...is captured and required to live as long as `'static` here
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:85:26
+   |
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+...
+LL |     impl MyTrait for dyn ObjectTrait {}
+   |                          ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for dyn ObjectTrait + '_ {}
+   |                                      ^^^^
+help: to declare that the `impl Trait` captures data from argument `val`, you can add an explicit `'a` lifetime bound
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+   |                                                                    ^^^^
+
+error[E0759]: `val` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:108:27
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
+   |                        ------------------- this data with lifetime `'a`...
+LL |         MyTrait::use_self(val)
+   |                           ^^^ ...is captured here...
+   |
+note: ...and is required to live as long as `'static` here
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:108:9
+   |
+LL |         MyTrait::use_self(val)
+   |         ^^^^^^^^^^^^^^^^^
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:104:26
+   |
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+...
+LL |     impl MyTrait for dyn ObjectTrait {}
+   |                          ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for dyn ObjectTrait + '_ {}
+   |                                      ^^^^
+
+error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an implicit `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:37:13
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
+   |                        ------------------- this data with lifetime `'a`...
+LL |         val.use_self()
+   |             ^^^^^^^^ ...is captured and required to live as long as `'static` here
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:31:26
+   |
+LL |     impl MyTrait for dyn ObjectTrait {
+   |                          ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for dyn ObjectTrait + '_ {
+   |                                      ^^^^
+
+error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an implicit `'static` lifetime requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:54:13
+   |
+LL |     fn use_it<'a>(val: &'a Box<dyn ObjectTrait + 'a>) -> &'a () {
+   |                        ----------------------------- this data with lifetime `'a`...
+LL |         val.use_self()
+   |             ^^^^^^^^ ...is captured and required to live as long as `'static` here
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:48:30
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait> {
+   |                              ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s 'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait + '_> {
+   |                                          ^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0759`.
index d3853445dfdfebb01518eb66ac063a0872c38fcb..94dd826a15cae71be3d0881f4bbeba350e2c2c38 100644 (file)
@@ -16,7 +16,7 @@ fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
 where
     G: Get<T>
 {
-    move || { //~ ERROR cannot infer an appropriate lifetime
+    move || { //~ ERROR `dest`
         *dest = g.get();
     }
 }
index 9ab060328537b56b08f0f3dcf6b023edfcd3fea5..d7051515f11029c04401888c11f9407e529b5a60 100644 (file)
@@ -6,7 +6,7 @@ LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
    |        |
    |        help: consider introducing lifetime `'a` here: `'a,`
 
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `dest` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/missing-lifetimes-in-signature.rs:19:5
    |
 LL |   fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
index f78edb1c83a4c97e549713f99975b073b9b30144..d8446e58dbb63eb9e7b593d69e6ae660492a232e 100644 (file)
@@ -27,7 +27,7 @@ impl Bar {
     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
         Iter {
             current: None,
-            remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+            remaining: self.0.iter(), //~ ERROR E0759
         }
     }
 }
@@ -38,7 +38,7 @@ impl Baz {
     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
         Iter {
             current: None,
-            remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+            remaining: self.0.iter(), //~ ERROR E0759
         }
     }
 }
@@ -49,7 +49,7 @@ impl Bat {
     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
         Iter {
             current: None,
-            remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+            remaining: self.0.iter(), //~ ERROR E0759
         }
     }
 }
@@ -60,7 +60,7 @@ impl Ban {
     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
         Iter {
             current: None,
-            remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
+            remaining: self.0.iter(), //~ ERROR E0759
         }
     }
 }
index 1257e9b172cf71ac9e4458f81fe212e6eb0d2744..9f30787f07cc6d9d9114805811f52a0b0323191a 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/trait-object-nested-in-impl-trait.rs:30:31
    |
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
@@ -23,7 +23,7 @@ help: to declare that the trait object captures data from argument `self`, you c
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> {
    |                                                        ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/trait-object-nested-in-impl-trait.rs:41:31
    |
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
@@ -44,7 +44,7 @@ help: to declare that the trait object captures data from argument `self`, you c
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ {
    |                                                        ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/trait-object-nested-in-impl-trait.rs:52:31
    |
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
@@ -65,7 +65,7 @@ help: to declare that the trait object captures data from argument `self`, you c
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a {
    |                                                               ^^^^
 
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `self` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/trait-object-nested-in-impl-trait.rs:63:31
    |
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
index 73a11a5e743f6a7f85810bfbcc0d86d54cf7fd3d..6a3f3c98f127a96d1b5e0a3c93e7d1e1f95b0018 100644 (file)
@@ -5,7 +5,6 @@
 #![feature(never_type)]
 
 use std::mem::size_of;
-use std::num::NonZeroU8;
 
 struct t {a: u8, b: i8}
 struct u {a: u8, b: i8, c: u8}
@@ -103,23 +102,6 @@ enum Option2<A, B> {
     None
 }
 
-// Two layouts are considered for `CanBeNicheFilledButShouldnt`:
-//   Niche-filling:
-//     { u32 (4 bytes), NonZeroU8 + tag in niche (1 byte), padding (3 bytes) }
-//   Tagged:
-//     { tag (1 byte), NonZeroU8 (1 byte), padding (2 bytes), u32 (4 bytes) }
-// Both are the same size (due to padding),
-// but the tagged layout is better as the tag creates a niche with 254 invalid values,
-// allowing types like `Option<Option<CanBeNicheFilledButShouldnt>>` to fit into 8 bytes.
-pub enum CanBeNicheFilledButShouldnt {
-    A(NonZeroU8, u32),
-    B
-}
-pub enum AlwaysTaggedBecauseItHasNoNiche {
-    A(u8, u32),
-    B
-}
-
 pub fn main() {
     assert_eq!(size_of::<u8>(), 1 as usize);
     assert_eq!(size_of::<u32>(), 4 as usize);
@@ -163,11 +145,4 @@ pub fn main() {
     assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
     assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());
     assert_eq!(size_of::<Option<Option2<&(), bool>>>(), size_of::<(bool, &())>());
-
-    assert_eq!(size_of::<CanBeNicheFilledButShouldnt>(), 8);
-    assert_eq!(size_of::<Option<CanBeNicheFilledButShouldnt>>(), 8);
-    assert_eq!(size_of::<Option<Option<CanBeNicheFilledButShouldnt>>>(), 8);
-    assert_eq!(size_of::<AlwaysTaggedBecauseItHasNoNiche>(), 8);
-    assert_eq!(size_of::<Option<AlwaysTaggedBecauseItHasNoNiche>>(), 8);
-    assert_eq!(size_of::<Option<Option<AlwaysTaggedBecauseItHasNoNiche>>>(), 8);
 }
index 133c5231031fd65a8d86b67159828b3b539d8362..2c8b1e76b1b82984d7a677a07d53c27b6c849f23 100644 (file)
@@ -194,6 +194,8 @@ trait Qux {
     const D: _ = 42;
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
     // type E: _; // FIXME: make the parser propagate the existence of `B`
+    type F: std::ops::Fn(_);
+    //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 }
 impl Qux for Struct {
     type A = _;
index a1945f2b9cf4e88b314f5d395d555a76f3a1ced4..782ff4948cda46e9032450e063bc65acbfbd44e8 100644 (file)
@@ -29,7 +29,7 @@ LL | struct BadStruct2<_, T>(_, T);
    |                   ^ expected identifier, found reserved identifier
 
 error: associated constant in `impl` without body
-  --> $DIR/typeck_type_placeholder_item.rs:203:5
+  --> $DIR/typeck_type_placeholder_item.rs:205:5
    |
 LL |     const C: _;
    |     ^^^^^^^^^^-
@@ -545,6 +545,12 @@ LL |     const D: _ = 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.rs:197:26
+   |
+LL |     type F: std::ops::Fn(_);
+   |                          ^ not allowed in type signatures
+
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:40:24
    |
@@ -582,25 +588,25 @@ LL |         fn clone(&self) -> _ { FnTest9 }
    |                            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:199:14
+  --> $DIR/typeck_type_placeholder_item.rs:201:14
    |
 LL |     type A = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:201:14
+  --> $DIR/typeck_type_placeholder_item.rs:203:14
    |
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:203:14
+  --> $DIR/typeck_type_placeholder_item.rs:205:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:206:14
+  --> $DIR/typeck_type_placeholder_item.rs:208:14
    |
 LL |     const D: _ = 42;
    |              ^
@@ -608,7 +614,7 @@ LL |     const D: _ = 42;
    |              not allowed in type signatures
    |              help: replace `_` with the correct type: `i32`
 
-error: aborting due to 66 previous errors
+error: aborting due to 67 previous errors
 
 Some errors have detailed explanations: E0121, E0282, E0403.
 For more information about an error, try `rustc --explain E0121`.
index d5aa18eb0f4e75f0e4c5969418ac03703d7f8fa4..e951adf030f5c2e9e958b2b45b31839832ec43e1 100644 (file)
@@ -5,7 +5,7 @@
 
 fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
-    Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
+    Box::new(items.iter()) //~ ERROR E0759
 }
 
 fn b<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
index dda5de431d30944e4e0f9a1f4f6c5c221773c609..dd804864dab4f59e0eb96f063b2223e50aa21978 100644 (file)
@@ -1,4 +1,4 @@
-error[E0759]: cannot infer an appropriate lifetime
+error[E0759]: `items` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/dyn-trait-underscore.rs:8:20
    |
 LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
index 43cf77395cad5b79887b20b7cf19d418bbd703a9..aa6872140ab0fa10f641ab0b981d5330d419e927 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 43cf77395cad5b79887b20b7cf19d418bbd703a9
+Subproject commit aa6872140ab0fa10f641ab0b981d5330d419e927
index 5f7373be6594636540e3ba6845bbd5e8a4505cf8..9269a63b41aab9d29f3904c534b6538e213cd4bc 100644 (file)
@@ -271,13 +271,13 @@ pub struct Config {
     pub gdb_native_rust: bool,
 
     /// Version of LLDB
-    pub lldb_version: Option<String>,
+    pub lldb_version: Option<u32>,
 
     /// Whether LLDB has native rust support
     pub lldb_native_rust: bool,
 
     /// Version of LLVM
-    pub llvm_version: Option<String>,
+    pub llvm_version: Option<u32>,
 
     /// Is LLVM a system LLVM
     pub system_llvm: bool,
index d6e28e93c96676aaf5ba632d17916e40d06c4b2f..2ab764eb9207c4fc96680aa20e99a1caac67e39d 100644 (file)
@@ -132,72 +132,46 @@ pub fn from_reader<R: Read>(config: &Config, testfile: &Path, rdr: R) -> Self {
 
         fn ignore_gdb(config: &Config, line: &str) -> bool {
             if let Some(actual_version) = config.gdb_version {
-                if line.starts_with("min-gdb-version") {
-                    let (start_ver, end_ver) = extract_gdb_version_range(line);
+                if let Some(rest) = line.strip_prefix("min-gdb-version:").map(str::trim) {
+                    let (start_ver, end_ver) = extract_version_range(rest, extract_gdb_version)
+                        .unwrap_or_else(|| {
+                            panic!("couldn't parse version range: {:?}", rest);
+                        });
 
                     if start_ver != end_ver {
                         panic!("Expected single GDB version")
                     }
                     // Ignore if actual version is smaller the minimum required
                     // version
-                    actual_version < start_ver
-                } else if line.starts_with("ignore-gdb-version") {
-                    let (min_version, max_version) = extract_gdb_version_range(line);
+                    return actual_version < start_ver;
+                } else if let Some(rest) = line.strip_prefix("ignore-gdb-version:").map(str::trim) {
+                    let (min_version, max_version) =
+                        extract_version_range(rest, extract_gdb_version).unwrap_or_else(|| {
+                            panic!("couldn't parse version range: {:?}", rest);
+                        });
 
                     if max_version < min_version {
                         panic!("Malformed GDB version range: max < min")
                     }
 
-                    actual_version >= min_version && actual_version <= max_version
-                } else {
-                    false
-                }
-            } else {
-                false
-            }
-        }
-
-        // Takes a directive of the form "ignore-gdb-version <version1> [- <version2>]",
-        // returns the numeric representation of <version1> and <version2> as
-        // tuple: (<version1> as u32, <version2> as u32)
-        // If the <version2> part is omitted, the second component of the tuple
-        // is the same as <version1>.
-        fn extract_gdb_version_range(line: &str) -> (u32, u32) {
-            const ERROR_MESSAGE: &'static str = "Malformed GDB version directive";
-
-            let range_components = line
-                .split(&[' ', '-'][..])
-                .filter(|word| !word.is_empty())
-                .map(extract_gdb_version)
-                .skip_while(Option::is_none)
-                .take(3) // 3 or more = invalid, so take at most 3.
-                .collect::<Vec<Option<u32>>>();
-
-            match range_components.len() {
-                1 => {
-                    let v = range_components[0].unwrap();
-                    (v, v)
-                }
-                2 => {
-                    let v_min = range_components[0].unwrap();
-                    let v_max = range_components[1].expect(ERROR_MESSAGE);
-                    (v_min, v_max)
+                    return actual_version >= min_version && actual_version <= max_version;
                 }
-                _ => panic!(ERROR_MESSAGE),
             }
+            false
         }
 
         fn ignore_lldb(config: &Config, line: &str) -> bool {
-            if let Some(ref actual_version) = config.lldb_version {
-                if line.starts_with("min-lldb-version") {
-                    let min_version = line
-                        .trim_end()
-                        .rsplit(' ')
-                        .next()
-                        .expect("Malformed lldb version directive");
+            if let Some(actual_version) = config.lldb_version {
+                if let Some(min_version) = line.strip_prefix("min-lldb-version:").map(str::trim) {
+                    let min_version = min_version.parse().unwrap_or_else(|e| {
+                        panic!(
+                            "Unexpected format of LLDB version string: {}\n{:?}",
+                            min_version, e
+                        );
+                    });
                     // Ignore if actual version is smaller the minimum required
                     // version
-                    lldb_version_to_int(actual_version) < lldb_version_to_int(min_version)
+                    actual_version < min_version
                 } else if line.starts_with("rust-lldb") && !config.lldb_native_rust {
                     true
                 } else {
@@ -212,48 +186,31 @@ fn ignore_llvm(config: &Config, line: &str) -> bool {
             if config.system_llvm && line.starts_with("no-system-llvm") {
                 return true;
             }
-            if let Some(ref actual_version) = config.llvm_version {
-                let actual_version = version_to_int(actual_version);
-                if line.starts_with("min-llvm-version") {
-                    let min_version = line
-                        .trim_end()
-                        .rsplit(' ')
-                        .next()
-                        .expect("Malformed llvm version directive");
+            if let Some(actual_version) = config.llvm_version {
+                if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) {
+                    let min_version = extract_llvm_version(rest).unwrap();
                     // Ignore if actual version is smaller the minimum required
                     // version
-                    actual_version < version_to_int(min_version)
-                } else if line.starts_with("min-system-llvm-version") {
-                    let min_version = line
-                        .trim_end()
-                        .rsplit(' ')
-                        .next()
-                        .expect("Malformed llvm version directive");
+                    actual_version < min_version
+                } else if let Some(rest) =
+                    line.strip_prefix("min-system-llvm-version:").map(str::trim)
+                {
+                    let min_version = extract_llvm_version(rest).unwrap();
                     // Ignore if using system LLVM and actual version
                     // is smaller the minimum required version
-                    config.system_llvm && actual_version < version_to_int(min_version)
-                } else if line.starts_with("ignore-llvm-version") {
-                    // Syntax is: "ignore-llvm-version <version1> [- <version2>]"
-                    let range_components = line
-                        .split(' ')
-                        .skip(1) // Skip the directive.
-                        .map(|s| s.trim())
-                        .filter(|word| !word.is_empty() && word != &"-")
-                        .take(3) // 3 or more = invalid, so take at most 3.
-                        .collect::<Vec<&str>>();
-                    match range_components.len() {
-                        1 => actual_version == version_to_int(range_components[0]),
-                        2 => {
-                            let v_min = version_to_int(range_components[0]);
-                            let v_max = version_to_int(range_components[1]);
-                            if v_max < v_min {
-                                panic!("Malformed LLVM version range: max < min")
-                            }
-                            // Ignore if version lies inside of range.
-                            actual_version >= v_min && actual_version <= v_max
-                        }
-                        _ => panic!("Malformed LLVM version directive"),
+                    config.system_llvm && actual_version < min_version
+                } else if let Some(rest) = line.strip_prefix("ignore-llvm-version:").map(str::trim)
+                {
+                    // Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
+                    let (v_min, v_max) = extract_version_range(rest, extract_llvm_version)
+                        .unwrap_or_else(|| {
+                            panic!("couldn't parse version range: {:?}", rest);
+                        });
+                    if v_max < v_min {
+                        panic!("Malformed LLVM version range: max < min")
                     }
+                    // Ignore if version lies inside of range.
+                    actual_version >= v_min && actual_version <= v_max
                 } else {
                     false
                 }
@@ -261,20 +218,6 @@ fn ignore_llvm(config: &Config, line: &str) -> bool {
                 false
             }
         }
-
-        fn version_to_int(version: &str) -> u32 {
-            let version_without_suffix = version.trim_end_matches("git").split('-').next().unwrap();
-            let components: Vec<u32> = version_without_suffix
-                .split('.')
-                .map(|s| s.parse().expect("Malformed version component"))
-                .collect();
-            match components.len() {
-                1 => components[0] * 10000,
-                2 => components[0] * 10000 + components[1] * 100,
-                3 => components[0] * 10000 + components[1] * 100 + components[2],
-                _ => panic!("Malformed version"),
-            }
-        }
     }
 }
 
@@ -944,12 +887,6 @@ fn parse_edition(&self, line: &str) -> Option<String> {
     }
 }
 
-pub fn lldb_version_to_int(version_string: &str) -> isize {
-    let error_string =
-        format!("Encountered LLDB version string with unexpected format: {}", version_string);
-    version_string.parse().expect(&error_string)
-}
-
 fn expand_variables(mut value: String, config: &Config) -> String {
     const CWD: &'static str = "{{cwd}}";
     const SRC_BASE: &'static str = "{{src-base}}";
@@ -990,3 +927,49 @@ fn parse_normalization_string(line: &mut &str) -> Option<String> {
     *line = &line[end + 1..];
     Some(result)
 }
+
+pub fn extract_llvm_version(version: &str) -> Option<u32> {
+    let version_without_suffix = version.trim_end_matches("git").split('-').next().unwrap();
+    let components: Vec<u32> = version_without_suffix
+        .split('.')
+        .map(|s| s.parse().expect("Malformed version component"))
+        .collect();
+    let version = match *components {
+        [a] => a * 10_000,
+        [a, b] => a * 10_000 + b * 100,
+        [a, b, c] => a * 10_000 + b * 100 + c,
+        _ => panic!("Malformed version"),
+    };
+    Some(version)
+}
+
+// Takes a directive of the form "<version1> [- <version2>]",
+// returns the numeric representation of <version1> and <version2> as
+// tuple: (<version1> as u32, <version2> as u32)
+// If the <version2> part is omitted, the second component of the tuple
+// is the same as <version1>.
+fn extract_version_range<F>(line: &str, parse: F) -> Option<(u32, u32)>
+where
+    F: Fn(&str) -> Option<u32>,
+{
+    let mut splits = line.splitn(2, "- ").map(str::trim);
+    let min = splits.next().unwrap();
+    if min.ends_with('-') {
+        return None;
+    }
+
+    let max = splits.next();
+
+    if min.is_empty() {
+        return None;
+    }
+
+    let min = parse(min)?;
+    let max = match max {
+        Some(max) if max.is_empty() => return None,
+        Some(max) => parse(max)?,
+        _ => min,
+    };
+
+    Some((min, max))
+}
index 72af34d78260ba6007a385300ba0c8be2aeb8622..1f82b137ee6cf1fb312375882c9fbc4e64678157 100644 (file)
@@ -119,17 +119,17 @@ fn no_system_llvm() {
 fn llvm_version() {
     let mut config = config();
 
-    config.llvm_version = Some("8.1.2-rust".to_owned());
-    assert!(parse_rs(&config, "// min-llvm-version 9.0").ignore);
+    config.llvm_version = Some(80102);
+    assert!(parse_rs(&config, "// min-llvm-version: 9.0").ignore);
 
-    config.llvm_version = Some("9.0.1-rust-1.43.0-dev".to_owned());
-    assert!(parse_rs(&config, "// min-llvm-version 9.2").ignore);
+    config.llvm_version = Some(90001);
+    assert!(parse_rs(&config, "// min-llvm-version: 9.2").ignore);
 
-    config.llvm_version = Some("9.3.1-rust-1.43.0-dev".to_owned());
-    assert!(!parse_rs(&config, "// min-llvm-version 9.2").ignore);
+    config.llvm_version = Some(90301);
+    assert!(!parse_rs(&config, "// min-llvm-version: 9.2").ignore);
 
-    config.llvm_version = Some("10.0.0-rust".to_owned());
-    assert!(!parse_rs(&config, "// min-llvm-version 9.0").ignore);
+    config.llvm_version = Some(100000);
+    assert!(!parse_rs(&config, "// min-llvm-version: 9.0").ignore);
 }
 
 #[test]
@@ -220,3 +220,18 @@ fn sanitizers() {
     assert!(parse_rs(&config, "// needs-sanitizer-memory").ignore);
     assert!(parse_rs(&config, "// needs-sanitizer-thread").ignore);
 }
+
+#[test]
+fn test_extract_version_range() {
+    use super::{extract_llvm_version, extract_version_range};
+
+    assert_eq!(extract_version_range("1.2.3 - 4.5.6", extract_llvm_version), Some((10203, 40506)));
+    assert_eq!(extract_version_range("0   - 4.5.6", extract_llvm_version), Some((0, 40506)));
+    assert_eq!(extract_version_range("1.2.3 -", extract_llvm_version), None);
+    assert_eq!(extract_version_range("1.2.3 - ", extract_llvm_version), None);
+    assert_eq!(extract_version_range("- 4.5.6", extract_llvm_version), None);
+    assert_eq!(extract_version_range("-", extract_llvm_version), None);
+    assert_eq!(extract_version_range(" - 4.5.6", extract_llvm_version), None);
+    assert_eq!(extract_version_range("   - 4.5.6", extract_llvm_version), None);
+    assert_eq!(extract_version_range("0  -", extract_llvm_version), None);
+}
index 07eba22c6eeb3a048f0a0322bfd492217ce389d2..bf3510ea0894bfeb74b01b7de1a5fb731dbdc61d 100644 (file)
@@ -166,14 +166,20 @@ fn make_absolute(path: PathBuf) -> PathBuf {
     let cdb = analyze_cdb(matches.opt_str("cdb"), &target);
     let (gdb, gdb_version, gdb_native_rust) =
         analyze_gdb(matches.opt_str("gdb"), &target, &android_cross_path);
-    let (lldb_version, lldb_native_rust) = extract_lldb_version(matches.opt_str("lldb-version"));
-
-    let color = match matches.opt_str("color").as_ref().map(|x| &**x) {
+    let (lldb_version, lldb_native_rust) = matches
+        .opt_str("lldb-version")
+        .as_deref()
+        .and_then(extract_lldb_version)
+        .map(|(v, b)| (Some(v), b))
+        .unwrap_or((None, false));
+    let color = match matches.opt_str("color").as_deref() {
         Some("auto") | None => ColorConfig::AutoColor,
         Some("always") => ColorConfig::AlwaysColor,
         Some("never") => ColorConfig::NeverColor,
         Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x),
     };
+    let llvm_version =
+        matches.opt_str("llvm-version").as_deref().and_then(header::extract_llvm_version);
 
     let src_base = opt_path(matches, "src-base");
     let run_ignored = matches.opt_present("ignored");
@@ -215,7 +221,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
         gdb_native_rust,
         lldb_version,
         lldb_native_rust,
-        llvm_version: matches.opt_str("llvm-version"),
+        llvm_version,
         system_llvm: matches.opt_present("system-llvm"),
         android_cross_path,
         adb_path: opt_str2(matches.opt_str("adb-path")),
@@ -254,7 +260,7 @@ pub fn log_config(config: &Config) {
     logv(c, format!("stage_id: {}", config.stage_id));
     logv(c, format!("mode: {}", config.mode));
     logv(c, format!("run_ignored: {}", config.run_ignored));
-    logv(c, format!("filter: {}", opt_str(&config.filter.as_ref().map(|re| re.to_owned()))));
+    logv(c, format!("filter: {}", opt_str(&config.filter)));
     logv(c, format!("filter_exact: {}", config.filter_exact));
     logv(
         c,
@@ -403,17 +409,14 @@ fn configure_lldb(config: &Config) -> Option<Config> {
         return None;
     }
 
-    if let Some(lldb_version) = config.lldb_version.as_ref() {
-        if lldb_version == "350" {
-            println!(
-                "WARNING: The used version of LLDB ({}) has a \
-                 known issue that breaks debuginfo tests. See \
-                 issue #32520 for more information. Skipping all \
-                 LLDB-based tests!",
-                lldb_version
-            );
-            return None;
-        }
+    if let Some(350) = config.lldb_version {
+        println!(
+            "WARNING: The used version of LLDB (350) has a \
+             known issue that breaks debuginfo tests. See \
+             issue #32520 for more information. Skipping all \
+             LLDB-based tests!",
+        );
+        return None;
     }
 
     // Some older versions of LLDB seem to have problems with multiple
@@ -727,9 +730,7 @@ fn make_test_closure(
     let config = config.clone();
     let testpaths = testpaths.clone();
     let revision = revision.cloned();
-    test::DynTestFn(Box::new(move || {
-        runtest::run(config, &testpaths, revision.as_ref().map(|s| s.as_str()))
-    }))
+    test::DynTestFn(Box::new(move || runtest::run(config, &testpaths, revision.as_deref())))
 }
 
 /// Returns `true` if the given target is an Android target for the
@@ -845,75 +846,40 @@ fn extract_gdb_version(full_version_line: &str) -> Option<u32> {
     // This particular form is documented in the GNU coding standards:
     // https://www.gnu.org/prep/standards/html_node/_002d_002dversion.html#g_t_002d_002dversion
 
-    // don't start parsing in the middle of a number
-    let mut prev_was_digit = false;
-    let mut in_parens = false;
-    for (pos, c) in full_version_line.char_indices() {
-        if in_parens {
-            if c == ')' {
-                in_parens = false;
-            }
-            continue;
-        } else if c == '(' {
-            in_parens = true;
-            continue;
-        }
-
-        if prev_was_digit || !c.is_digit(10) {
-            prev_was_digit = c.is_digit(10);
-            continue;
+    let mut splits = full_version_line.rsplit(' ');
+    let version_string = splits.next().unwrap();
+
+    let mut splits = version_string.split('.');
+    let major = splits.next().unwrap();
+    let minor = splits.next().unwrap();
+    let patch = splits.next();
+
+    let major: u32 = major.parse().unwrap();
+    let (minor, patch): (u32, u32) = match minor.find(not_a_digit) {
+        None => {
+            let minor = minor.parse().unwrap();
+            let patch: u32 = match patch {
+                Some(patch) => match patch.find(not_a_digit) {
+                    None => patch.parse().unwrap(),
+                    Some(idx) if idx > 3 => 0,
+                    Some(idx) => patch[..idx].parse().unwrap(),
+                },
+                None => 0,
+            };
+            (minor, patch)
         }
-
-        prev_was_digit = true;
-
-        let line = &full_version_line[pos..];
-
-        let next_split = match line.find(|c: char| !c.is_digit(10)) {
-            Some(idx) => idx,
-            None => continue, // no minor version
-        };
-
-        if line.as_bytes()[next_split] != b'.' {
-            continue; // no minor version
+        // There is no patch version after minor-date (e.g. "4-2012").
+        Some(idx) => {
+            let minor = minor[..idx].parse().unwrap();
+            (minor, 0)
         }
+    };
 
-        let major = &line[..next_split];
-        let line = &line[next_split + 1..];
-
-        let (minor, patch) = match line.find(|c: char| !c.is_digit(10)) {
-            Some(idx) => {
-                if line.as_bytes()[idx] == b'.' {
-                    let patch = &line[idx + 1..];
-
-                    let patch_len =
-                        patch.find(|c: char| !c.is_digit(10)).unwrap_or_else(|| patch.len());
-                    let patch = &patch[..patch_len];
-                    let patch = if patch_len > 3 || patch_len == 0 { None } else { Some(patch) };
-
-                    (&line[..idx], patch)
-                } else {
-                    (&line[..idx], None)
-                }
-            }
-            None => (line, None),
-        };
-
-        if minor.is_empty() {
-            continue;
-        }
-
-        let major: u32 = major.parse().unwrap();
-        let minor: u32 = minor.parse().unwrap();
-        let patch: u32 = patch.unwrap_or("0").parse().unwrap();
-
-        return Some(((major * 1000) + minor) * 1000 + patch);
-    }
-
-    None
+    Some(((major * 1000) + minor) * 1000 + patch)
 }
 
 /// Returns (LLDB version, LLDB is rust-enabled)
-fn extract_lldb_version(full_version_line: Option<String>) -> (Option<String>, bool) {
+fn extract_lldb_version(full_version_line: &str) -> Option<(u32, bool)> {
     // Extract the major LLDB version from the given version string.
     // LLDB version strings are different for Apple and non-Apple platforms.
     // The Apple variant looks like this:
@@ -922,7 +888,7 @@ fn extract_lldb_version(full_version_line: Option<String>) -> (Option<String>, b
     // lldb-300.2.51 (new versions)
     //
     // We are only interested in the major version number, so this function
-    // will return `Some("179")` and `Some("300")` respectively.
+    // will return `Some(179)` and `Some(300)` respectively.
     //
     // Upstream versions look like:
     // lldb version 6.0.1
@@ -934,53 +900,24 @@ fn extract_lldb_version(full_version_line: Option<String>) -> (Option<String>, b
     // normally fine because the only non-Apple version we test is
     // rust-enabled.
 
-    if let Some(ref full_version_line) = full_version_line {
-        if !full_version_line.trim().is_empty() {
-            let full_version_line = full_version_line.trim();
-
-            for (pos, l) in full_version_line.char_indices() {
-                if l != 'l' && l != 'L' {
-                    continue;
-                }
-                if pos + 5 >= full_version_line.len() {
-                    continue;
-                }
-                let l = full_version_line[pos + 1..].chars().next().unwrap();
-                if l != 'l' && l != 'L' {
-                    continue;
-                }
-                let d = full_version_line[pos + 2..].chars().next().unwrap();
-                if d != 'd' && d != 'D' {
-                    continue;
-                }
-                let b = full_version_line[pos + 3..].chars().next().unwrap();
-                if b != 'b' && b != 'B' {
-                    continue;
-                }
-                let dash = full_version_line[pos + 4..].chars().next().unwrap();
-                if dash != '-' {
-                    continue;
-                }
-
-                let vers = full_version_line[pos + 5..]
-                    .chars()
-                    .take_while(|c| c.is_digit(10))
-                    .collect::<String>();
-                if !vers.is_empty() {
-                    return (Some(vers), full_version_line.contains("rust-enabled"));
-                }
-            }
+    let full_version_line = full_version_line.trim();
 
-            if full_version_line.starts_with("lldb version ") {
-                let vers = full_version_line[13..]
-                    .chars()
-                    .take_while(|c| c.is_digit(10))
-                    .collect::<String>();
-                if !vers.is_empty() {
-                    return (Some(vers + "00"), full_version_line.contains("rust-enabled"));
-                }
-            }
+    if let Some(apple_ver) =
+        full_version_line.strip_prefix("LLDB-").or_else(|| full_version_line.strip_prefix("lldb-"))
+    {
+        if let Some(idx) = apple_ver.find(not_a_digit) {
+            let version: u32 = apple_ver[..idx].parse().unwrap();
+            return Some((version, full_version_line.contains("rust-enabled")));
+        }
+    } else if let Some(lldb_ver) = full_version_line.strip_prefix("lldb version ") {
+        if let Some(idx) = lldb_ver.find(not_a_digit) {
+            let version: u32 = lldb_ver[..idx].parse().unwrap();
+            return Some((version * 100, full_version_line.contains("rust-enabled")));
         }
     }
-    (None, false)
+    None
+}
+
+fn not_a_digit(c: char) -> bool {
+    !c.is_digit(10)
 }
index 31c151d29e916c75bc2607870bfa354ac5ecc0c3..ea9bc1c1a5b7f5a7413c26b0939db1bec0767d98 100644 (file)
@@ -1,8 +1,9 @@
+use super::header::extract_llvm_version;
 use super::*;
 
 #[test]
 fn test_extract_gdb_version() {
-    macro_rules! test { ($($expectation:tt: $input:tt,)*) => {{$(
+    macro_rules! test { ($($expectation:literal: $input:literal,)*) => {{$(
         assert_eq!(extract_gdb_version($input), Some($expectation));
     )*}}}
 
@@ -41,6 +42,17 @@ macro_rules! test { ($($expectation:tt: $input:tt,)*) => {{$(
     }
 }
 
+#[test]
+fn test_extract_lldb_version() {
+    // Apple variants
+    assert_eq!(extract_lldb_version("LLDB-179.5"), Some((179, false)));
+    assert_eq!(extract_lldb_version("lldb-300.2.51"), Some((300, false)));
+
+    // Upstream versions
+    assert_eq!(extract_lldb_version("lldb version 6.0.1"), Some((600, false)));
+    assert_eq!(extract_lldb_version("lldb version 9.0.0"), Some((900, false)));
+}
+
 #[test]
 fn is_test_test() {
     assert_eq!(true, is_test(&OsString::from("a_test.rs")));
@@ -49,3 +61,11 @@ fn is_test_test() {
     assert_eq!(false, is_test(&OsString::from("#a_dog_gif")));
     assert_eq!(false, is_test(&OsString::from("~a_temp_file")));
 }
+
+#[test]
+fn test_extract_llvm_version() {
+    assert_eq!(extract_llvm_version("8.1.2-rust"), Some(80102));
+    assert_eq!(extract_llvm_version("9.0.1-rust-1.43.0-dev"), Some(90001));
+    assert_eq!(extract_llvm_version("9.3.1-rust-1.43.0-dev"), Some(90301));
+    assert_eq!(extract_llvm_version("10.0.0-rust"), Some(100000));
+}
index 992af261b8352f1495f91e8f3d3d01515df40440..787e08404e1c61581768d4425129d939b96cbfb0 100644 (file)
@@ -3,7 +3,6 @@ authors = ["The Rust Project Developers"]
 name = "error_index_generator"
 version = "0.0.0"
 edition = "2018"
-build = "build.rs"
 
 [dependencies]
 rustdoc = { path = "../../librustdoc" }
index 36bd1ab6c1078b686fea8bc215651f99720386d1..559267a494f29a009954f07d66b8f02399e1f8ac 100644 (file)
@@ -17,7 +17,6 @@
     "MIT",
     "Unlicense/MIT",
     "Unlicense OR MIT",
-    "0BSD OR MIT OR Apache-2.0", // adler license
 ];
 
 /// These are exceptions to Rust's permissive licensing policy, and
@@ -37,6 +36,7 @@
     ("ryu", "Apache-2.0 OR BSL-1.0"),       // rls/cargo/... (because of serde)
     ("bytesize", "Apache-2.0"),             // cargo
     ("im-rc", "MPL-2.0+"),                  // cargo
+    ("adler32", "BSD-3-Clause AND Zlib"),   // cargo dep that isn't used
     ("constant_time_eq", "CC0-1.0"),        // rustfmt
     ("sized-chunks", "MPL-2.0+"),           // cargo via im-rc
     ("bitmaps", "MPL-2.0+"),                // cargo via im-rc
@@ -57,8 +57,7 @@
 /// This list is here to provide a speed-bump to adding a new dependency to
 /// rustc. Please check with the compiler team before adding an entry.
 const PERMITTED_DEPENDENCIES: &[&str] = &[
-    "addr2line",
-    "adler",
+    "adler32",
     "aho-corasick",
     "annotate-snippets",
     "ansi_term",
@@ -66,6 +65,7 @@
     "atty",
     "autocfg",
     "backtrace",
+    "backtrace-sys",
     "bitflags",
     "block-buffer",
     "block-padding",
@@ -98,7 +98,6 @@
     "generic-array",
     "getopts",
     "getrandom",
-    "gimli",
     "hashbrown",
     "hermit-abi",
     "humantime",
     "miniz_oxide",
     "nodrop",
     "num_cpus",
-    "object",
     "once_cell",
     "opaque-debug",
     "parking_lot",
index c0671596e19f1b365a990243d3b02ad7a1b51389..b4aafb815fc6b6b169a0caa91aa21de9a8c5b8dc 100644 (file)
@@ -60,7 +60,6 @@ fn filter_dirs(path: &Path) -> bool {
         "src/tools/rust-installer",
         "src/tools/rustfmt",
         "src/doc/book",
-        "src/backtrace",
         // Filter RLS output directories
         "target/rls",
     ];
index 51a29553fdb3dc1f5de8a071bd16326f64a3b7f9..ce4ea895400acdd6dde24a8ec104cc559d538f88 100644 (file)
@@ -81,7 +81,7 @@ topic = "I-prioritize #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* issue #{number} has been requested for prioritization.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#Unprioritized-I-prioritize)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#assign-priority-to-unprioritized-issues-with-i-prioritize-label)
 - Priority?
 - Regression?
 - Notify people/groups?
@@ -96,7 +96,7 @@ topic = "I-nominated #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* #{number} has been nominated for discussion in `T-compiler` meeting.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#I-nominated)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#summarize-i-nominated-issues)
 - Already discussed?
 - Worth the meeting time?
 - Add agenda entry:
@@ -113,7 +113,7 @@ topic = "Backport #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* PR #{number} has been requested for beta backport.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#StableBeta-nominations)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#summarize-stablebeta-nominations)
 Prepare agenda entry:
 - Why nominated?
 - Author, assignee?
@@ -127,7 +127,7 @@ topic = "Backport #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* PR #{number} has been requested for stable backport.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#StableBeta-nominations)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#summarize-stablebeta-nominations)
 Prepare agenda entry:
 - Why nominated?
 - Author, assignee?
@@ -142,7 +142,7 @@ topic = "S-waiting-on-team #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* PR #{number} is waiting on `T-compiler`.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#PR%E2%80%99s-waiting-on-team)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#summarize-prs-waiting-on-team)
 - Prepare agenda entry:
   - What is it waiting for?
   - Important details?
@@ -156,7 +156,7 @@ topic = "P-critical #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* issue #{number} has been assigned `P-critical`.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#P-critical-and-Unassigned-P-high-regressions)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#summarize-p-critical-and-unassigned-p-high-regressions)
 - Notify people/groups?
 - Assign if possible?
 - Add to agenda:
@@ -172,7 +172,7 @@ topic = "P-high regression #{number} {title}"
 message_on_add = """\
 @*WG-prioritization/alerts* issue #{number} has been assigned `P-high` and is a regression.
 
-# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#P-critical-and-Unassigned-P-high-regressions)
+# [Procedure](https://forge.rust-lang.org/compiler/prioritization/procedure.html#summarize-p-critical-and-unassigned-p-high-regressions)
 Is issue assigned? If not:
 - Try to find an assignee?
 - Otherwise add to agenda: