]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #87044 - cjgillot:expnhash, r=petrochenkov
authorbors <bors@rust-lang.org>
Tue, 13 Jul 2021 22:32:58 +0000 (22:32 +0000)
committerbors <bors@rust-lang.org>
Tue, 13 Jul 2021 22:32:58 +0000 (22:32 +0000)
Cache expansion hash globally

... instead of computing it multiple times.

Split from #86676
r? `@petrochenkov`

241 files changed:
.gitignore
.gitmodules
Cargo.lock
compiler/rustc_errors/src/emitter.rs
compiler/rustc_errors/src/json.rs
compiler/rustc_errors/src/lib.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_feature/src/builtin_attrs.rs
compiler/rustc_lint/src/internal.rs
compiler/rustc_lint/src/lib.rs
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_lint_defs/src/lib.rs
compiler/rustc_macros/src/symbols.rs
compiler/rustc_metadata/src/rmeta/decoder.rs
compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_metadata/src/rmeta/mod.rs
compiler/rustc_middle/src/hir/map/mod.rs
compiler/rustc_middle/src/lint.rs
compiler/rustc_middle/src/middle/stability.rs
compiler/rustc_middle/src/mir/interpret/allocation.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
compiler/rustc_mir/src/const_eval/machine.rs
compiler/rustc_mir/src/interpret/eval_context.rs
compiler/rustc_mir/src/interpret/memory.rs
compiler/rustc_mir/src/transform/check_consts/validation.rs
compiler/rustc_mir_build/src/build/expr/mod.rs
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_build/src/check_unsafety.rs
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/check_const.rs
compiler/rustc_passes/src/stability.rs
compiler/rustc_session/src/config.rs
compiler/rustc_session/src/session.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
compiler/rustc_target/src/spec/apple_sdk_base.rs
compiler/rustc_target/src/spec/arm_linux_androideabi.rs
compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
compiler/rustc_target/src/spec/armv7a_none_eabi.rs
compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
compiler/rustc_target/src/spec/armv7r_none_eabi.rs
compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs
compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs
compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
compiler/rustc_target/src/spec/mod.rs
compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs
compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs
compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs
compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs
compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs
compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs
compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
compiler/rustc_ty_utils/src/ty.rs
compiler/rustc_typeck/src/check/callee.rs
compiler/rustc_typeck/src/check/coercion.rs
library/core/src/bool.rs
library/core/src/mem/maybe_uninit.rs
library/std/src/f32.rs
library/std/src/f64.rs
library/std/src/io/cursor.rs
library/std/src/io/mod.rs
library/std/src/io/stdio.rs
src/bootstrap/install.rs
src/bootstrap/native.rs
src/bootstrap/test.rs
src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
src/ci/docker/host-x86_64/dist-x86_64-linux/build-binutils.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-cmake.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-curl.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-openssl.sh
src/ci/docker/host-x86_64/dist-x86_64-linux/build-python.sh
src/ci/pgo.sh
src/doc/reference.md
src/librustdoc/clean/blanket_impl.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/utils.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/static/js/main.js
src/librustdoc/html/static/js/search.js
src/librustdoc/lib.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/llvm-project
src/test/run-make-fulldeps/print-cfg/Makefile
src/test/rustdoc-gui/implementors.goml [new file with mode: 0644]
src/test/rustdoc-gui/src/Cargo.lock [new file with mode: 0644]
src/test/rustdoc-gui/src/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/implementors/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/implementors/lib.rs [new file with mode: 0644]
src/test/rustdoc-gui/src/lib.rs [deleted file]
src/test/rustdoc-gui/src/lib2.rs [deleted file]
src/test/rustdoc-gui/src/lib2/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/lib2/lib.rs [new file with mode: 0644]
src/test/rustdoc-gui/src/lib2/src/lib.rs [new file with mode: 0644]
src/test/rustdoc-gui/src/test_docs/Cargo.toml [new file with mode: 0644]
src/test/rustdoc-gui/src/test_docs/lib.rs [new file with mode: 0644]
src/test/rustdoc-ui/intra-doc/field-ice.rs [new file with mode: 0644]
src/test/rustdoc-ui/intra-doc/field-ice.stderr [new file with mode: 0644]
src/test/rustdoc/auxiliary/reexports.rs [new file with mode: 0644]
src/test/rustdoc/duplicate-flags.rs [new file with mode: 0644]
src/test/rustdoc/reexports-priv.rs [new file with mode: 0644]
src/test/rustdoc/reexports.rs [new file with mode: 0644]
src/test/ui-fulldeps/internal-lints/default_hash_types.rs
src/test/ui-fulldeps/internal-lints/default_hash_types.stderr
src/test/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr
src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
src/test/ui/borrowck/borrowck-issue-14498.stderr
src/test/ui/borrowck/issue-69789-iterator-mut-suggestion.stderr
src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs
src/test/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr
src/test/ui/borrowck/issue-85765.rs
src/test/ui/borrowck/issue-85765.stderr
src/test/ui/borrowck/mutability-errors.stderr
src/test/ui/cfg/cfg-target-abi.rs [new file with mode: 0644]
src/test/ui/consts/issue-87046.rs [new file with mode: 0644]
src/test/ui/consts/issue-87046.stderr [new file with mode: 0644]
src/test/ui/deprecation/deprecation-lint-3.stderr
src/test/ui/deprecation/deprecation-lint.stderr
src/test/ui/deprecation/suggestion.fixed
src/test/ui/deprecation/suggestion.rs
src/test/ui/deprecation/suggestion.stderr
src/test/ui/did_you_mean/issue-39544.rs
src/test/ui/did_you_mean/issue-39544.stderr
src/test/ui/error-codes/E0389.rs
src/test/ui/error-codes/E0389.stderr
src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr [new file with mode: 0644]
src/test/ui/issues/issue-51244.rs
src/test/ui/issues/issue-51244.stderr
src/test/ui/issues/issue-51515.rs
src/test/ui/issues/issue-51515.stderr
src/test/ui/lang-items/issue-86238.rs [new file with mode: 0644]
src/test/ui/lang-items/issue-86238.stderr [new file with mode: 0644]
src/test/ui/lint/issue-83477.rs
src/test/ui/lint/issue-83477.stderr
src/test/ui/lint/lint-stability-deprecated.stderr
src/test/ui/lint/lint-stability3.stderr
src/test/ui/mut/mutable-class-fields-2.stderr
src/test/ui/nll/issue-47388.stderr
src/test/ui/nll/issue-51244.rs
src/test/ui/nll/issue-51244.stderr
src/test/ui/nll/issue-57989.rs
src/test/ui/nll/issue-57989.stderr
src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs
src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
src/test/ui/rfc-2005-default-binding-mode/enum.rs
src/test/ui/rfc-2005-default-binding-mode/enum.stderr
src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs
src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr
src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs [deleted file]
src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr [deleted file]
src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr [new file with mode: 0644]
src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs
src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr
src/test/ui/stability-attribute/generics-default-stability.stderr
src/test/ui/suggestions/issue-68049-1.stderr
src/test/ui/suggestions/issue-68049-2.stderr
src/test/ui/suggestions/suggest-mut-method-for-loop.stderr
src/test/ui/suggestions/suggest-ref-mut.stderr
src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs [new file with mode: 0644]
src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints2.rs
src/test/ui/unsafe/ranged_ints2.stderr [deleted file]
src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints2_const.rs
src/test/ui/unsafe/ranged_ints2_const.stderr [deleted file]
src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3.rs
src/test/ui/unsafe/ranged_ints3.stderr [deleted file]
src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3_const.rs
src/test/ui/unsafe/ranged_ints3_const.stderr [deleted file]
src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3_match.rs [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints4.rs
src/test/ui/unsafe/ranged_ints4.stderr [deleted file]
src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints4_const.rs
src/test/ui/unsafe/ranged_ints4_const.stderr [deleted file]
src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/unsafe-assign.rs [new file with mode: 0644]
src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr [new file with mode: 0644]
src/test/ui/unsafe/unsafe-borrow.rs [new file with mode: 0644]
src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/implicit_hasher.rs
src/tools/rust-analyzer
src/tools/tidy/src/pal.rs

index 0cd6b9f648d0fb4bfd0189a66969c39c58e55a40..b7e8e8fa15752d6761bfe49fcd9ad287c6830b78 100644 (file)
@@ -72,4 +72,7 @@ __pycache__/
 **node_modules
 **package-lock.json
 
+## Rustdoc GUI tests
+src/test/rustdoc-gui/src/**.lock
+
 # Before adding new lines, see the comment at the top.
index aee038aa4c8e5e9f267b08a2ca503514c382a289..60ccf9375ee3e7b58b4ef5cc6100efc38057e961 100644 (file)
@@ -34,7 +34,7 @@
 [submodule "src/llvm-project"]
        path = src/llvm-project
        url = https://github.com/rust-lang/llvm-project.git
-       branch = rustc/12.0-2021-04-15
+       branch = rustc/12.0-2021-07-10
 [submodule "src/doc/embedded-book"]
        path = src/doc/embedded-book
        url = https://github.com/rust-embedded/book.git
index f8f1331579406dfb1f7651a727c3018eb78c259a..b432f9ae2272a8fdaa5b3a6d51518be575606b15 100644 (file)
@@ -3044,31 +3044,29 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.4.3"
+version = "1.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
+checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
- "thread_local",
 ]
 
 [[package]]
 name = "regex-automata"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
 dependencies = [
- "byteorder",
  "regex-syntax",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.22"
+version = "0.6.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
 
 [[package]]
 name = "remote-test-client"
index fd024a8ecfa4a8ee09cbc85e3a14021df86045f5..becc1c6db5bbb9c3337c18dee51a0506d7959784 100644 (file)
@@ -9,7 +9,6 @@
 
 use Destination::*;
 
-use rustc_lint_defs::FutureBreakage;
 use rustc_span::source_map::SourceMap;
 use rustc_span::{MultiSpan, SourceFile, Span};
 
@@ -193,7 +192,7 @@ pub trait Emitter {
     /// other formats can, and will, simply ignore it.
     fn emit_artifact_notification(&mut self, _path: &Path, _artifact_type: &str) {}
 
-    fn emit_future_breakage_report(&mut self, _diags: Vec<(FutureBreakage, Diagnostic)>) {}
+    fn emit_future_breakage_report(&mut self, _diags: Vec<Diagnostic>) {}
 
     /// Emit list of unused externs
     fn emit_unused_externs(&mut self, _lint_level: &str, _unused_externs: &[&str]) {}
index 485e7564587ea62925f834e6626cf5a8c476ecab..1b6cd04cca642e213efdf22273ddb62a5cfa0d25 100644 (file)
@@ -16,7 +16,7 @@
 use crate::DiagnosticId;
 use crate::ToolMetadata;
 use crate::{CodeSuggestion, SubDiagnostic};
-use rustc_lint_defs::{Applicability, FutureBreakage};
+use rustc_lint_defs::Applicability;
 
 use rustc_data_structures::sync::Lrc;
 use rustc_span::hygiene::ExpnData;
@@ -134,17 +134,14 @@ fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) {
         }
     }
 
-    fn emit_future_breakage_report(&mut self, diags: Vec<(FutureBreakage, crate::Diagnostic)>) {
+    fn emit_future_breakage_report(&mut self, diags: Vec<crate::Diagnostic>) {
         let data: Vec<FutureBreakageItem> = diags
             .into_iter()
-            .map(|(breakage, mut diag)| {
+            .map(|mut diag| {
                 if diag.level == crate::Level::Allow {
                     diag.level = crate::Level::Warning;
                 }
-                FutureBreakageItem {
-                    future_breakage_date: breakage.date,
-                    diagnostic: Diagnostic::from_errors_diagnostic(&diag, self),
-                }
+                FutureBreakageItem { diagnostic: Diagnostic::from_errors_diagnostic(&diag, self) }
             })
             .collect();
         let report = FutureIncompatReport { future_incompat_report: data };
@@ -326,7 +323,6 @@ struct ArtifactNotification<'a> {
 
 #[derive(Encodable)]
 struct FutureBreakageItem {
-    future_breakage_date: Option<&'static str>,
     diagnostic: Diagnostic,
 }
 
index f8339d6e3f4935d07d0b74ab23a0e1821e4d933f..993a7c2c162c6b7936f5496c1e295e50cc050160 100644 (file)
@@ -23,7 +23,6 @@
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::sync::{self, Lock, Lrc};
 use rustc_data_structures::AtomicRef;
-use rustc_lint_defs::FutureBreakage;
 pub use rustc_lint_defs::{pluralize, Applicability};
 use rustc_serialize::json::Json;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -790,7 +789,7 @@ pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
         self.inner.borrow_mut().emit_artifact_notification(path, artifact_type)
     }
 
-    pub fn emit_future_breakage_report(&self, diags: Vec<(FutureBreakage, Diagnostic)>) {
+    pub fn emit_future_breakage_report(&self, diags: Vec<Diagnostic>) {
         self.inner.borrow_mut().emitter.emit_future_breakage_report(diags)
     }
 
index 9eaf4693811ca100844fe5fd4fc51d614463a468..ede510b6936798717b62109140994d26ac27b969 100644 (file)
@@ -684,6 +684,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
     (active, more_qualified_paths, "1.54.0", Some(86935), None),
 
+    /// Allows `cfg(target_abi = "...")`.
+    (active, cfg_target_abi, "1.55.0", Some(80970), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
index 259a6328a22f6832a6ae275578b532a5ba95550d..77d8f0f920c145846d9559c9e59982276800e719 100644 (file)
@@ -23,6 +23,7 @@ macro_rules! cfg_fn {
 /// `cfg(...)`'s that are feature gated.
 const GATED_CFGS: &[GatedCfg] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
+    (sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)),
     (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
     (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
     (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
@@ -349,6 +350,12 @@ macro_rules! experimental {
     ),
 
     gated!(cmse_nonsecure_entry, AssumedUsed, template!(Word), experimental!(cmse_nonsecure_entry)),
+    // RFC 2632
+    gated!(
+        default_method_body_is_const, AssumedUsed, template!(Word), const_trait_impl,
+        "`default_method_body_is_const` is a temporary placeholder for declaring default bodies \
+        as `const`, which may be removed or renamed in the future."
+    ),
 
     // ==========================================================================
     // Internal attributes: Stability, deprecation, and unsafe:
index 9b1a339572ec3cfe5b9fde1709d72415c3aba51a..8a4a70894375d2f55b0661cecf58587543957d4a 100644 (file)
@@ -2,15 +2,17 @@
 //! Clippy.
 
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::{ImplKind, Item, ItemKind};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_ast as ast;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
+use rustc_hir::{
+    GenericArg, HirId, Item, ItemKind, MutTy, Mutability, Node, Path, PathSegment, QPath, Ty,
+    TyKind,
+};
 use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::hygiene::{ExpnKind, MacroKind};
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
 
 declare_tool_lint! {
     pub rustc::DEFAULT_HASH_TYPES,
     report_in_external_macro: true
 }
 
-pub struct DefaultHashTypes {
-    map: FxHashMap<Symbol, Symbol>,
-}
-
-impl DefaultHashTypes {
-    // we are allowed to use `HashMap` and `HashSet` as identifiers for implementing the lint itself
-    #[allow(rustc::default_hash_types)]
-    pub fn new() -> Self {
-        let mut map = FxHashMap::default();
-        map.insert(sym::HashMap, sym::FxHashMap);
-        map.insert(sym::HashSet, sym::FxHashSet);
-        Self { map }
-    }
-}
-
-impl_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
+declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
 
-impl EarlyLintPass for DefaultHashTypes {
-    fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
-        if let Some(replace) = self.map.get(&ident.name) {
-            cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, |lint| {
-                // FIXME: We can avoid a copy here. Would require us to take String instead of &str.
-                let msg = format!("Prefer {} over {}, it has better performance", replace, ident);
-                lint.build(&msg)
-                    .span_suggestion(
-                        ident.span,
-                        "use",
-                        replace.to_string(),
-                        Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
-                    )
-                    .note(&format!(
-                        "a `use rustc_data_structures::fx::{}` may be necessary",
-                        replace
-                    ))
-                    .emit();
-            });
+impl LateLintPass<'_> for DefaultHashTypes {
+    fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
+        let def_id = match path.res {
+            Res::Def(rustc_hir::def::DefKind::Struct, id) => id,
+            _ => return,
+        };
+        if matches!(cx.tcx.hir().get(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
+            // don't lint imports, only actual usages
+            return;
         }
+        let replace = if cx.tcx.is_diagnostic_item(sym::hashmap_type, def_id) {
+            "FxHashMap"
+        } else if cx.tcx.is_diagnostic_item(sym::hashset_type, def_id) {
+            "FxHashSet"
+        } else {
+            return;
+        };
+        cx.struct_span_lint(DEFAULT_HASH_TYPES, path.span, |lint| {
+            let msg = format!(
+                "prefer `{}` over `{}`, it has better performance",
+                replace,
+                cx.tcx.item_name(def_id)
+            );
+            lint.build(&msg)
+                .note(&format!("a `use rustc_data_structures::fx::{}` may be necessary", replace))
+                .emit();
+        });
     }
 }
 
@@ -242,8 +236,9 @@ fn gen_args(segment: &PathSegment<'_>) -> String {
 declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
 
 impl EarlyLintPass for LintPassImpl {
-    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::Impl(box ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
+        if let ast::ItemKind::Impl(box ast::ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind
+        {
             if let Some(last) = lint_pass.path.segments.last() {
                 if last.ident.name == sym::LintPass {
                     let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
index 28b60603a2dbb36a2a25d7d3c728cd08aca15783..c9478016140b7ad3349d2362dbb8399657d7f544 100644 (file)
@@ -475,10 +475,10 @@ macro_rules! register_passes {
 }
 
 fn register_internals(store: &mut LintStore) {
-    store.register_lints(&DefaultHashTypes::get_lints());
-    store.register_early_pass(|| box DefaultHashTypes::new());
     store.register_lints(&LintPassImpl::get_lints());
     store.register_early_pass(|| box LintPassImpl);
+    store.register_lints(&DefaultHashTypes::get_lints());
+    store.register_late_pass(|| box DefaultHashTypes);
     store.register_lints(&ExistingDocKeyword::get_lints());
     store.register_late_pass(|| box ExistingDocKeyword);
     store.register_lints(&TyTyKind::get_lints());
index 01291de51bdab4024b71099f448b094ccbf0c80e..5b1cd0bcb3ffe72b34ebeca9b8ae714e064f6c7c 100644 (file)
@@ -6,7 +6,7 @@
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
 
-use crate::{declare_lint, declare_lint_pass, FutureBreakage, FutureIncompatibilityReason};
+use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason};
 use rustc_span::edition::Edition;
 
 declare_lint! {
     "detects usage of old versions of certain proc-macro crates",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>",
-        future_breakage: Some(FutureBreakage {
-            date: None
-        })
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
     };
 }
 
index 89453e8e73a2bc4fd7c440136995a9d2bf34b5f5..001198226d9a3a1ee18fce8e3d866402c17d961b 100644 (file)
@@ -152,10 +152,6 @@ pub struct FutureIncompatibleInfo {
     /// Set to false for lints that already include a more detailed
     /// explanation.
     pub explain_reason: bool,
-    /// Information about a future breakage, which will
-    /// be emitted in JSON messages to be displayed by Cargo
-    /// for upstream deps
-    pub future_breakage: Option<FutureBreakage>,
 }
 
 /// The reason for future incompatibility
@@ -164,6 +160,9 @@ pub enum FutureIncompatibilityReason {
     /// This will be an error in a future release
     /// for all editions
     FutureReleaseError,
+    /// This will be an error in a future release, and
+    /// Cargo should create a report even for dependencies
+    FutureReleaseErrorReportNow,
     /// Previously accepted code that will become an
     /// error in the provided edition
     EditionError(Edition),
@@ -182,18 +181,12 @@ pub fn edition(self) -> Option<Edition> {
     }
 }
 
-#[derive(Copy, Clone, Debug)]
-pub struct FutureBreakage {
-    pub date: Option<&'static str>,
-}
-
 impl FutureIncompatibleInfo {
     pub const fn default_fields_for_macro() -> Self {
         FutureIncompatibleInfo {
             reference: "",
             reason: FutureIncompatibilityReason::FutureReleaseError,
             explain_reason: true,
-            future_breakage: None,
         }
     }
 }
index 5b932864dff5da7a8a547bce4a1601de9ac3cbdb..2f063f75eb0ef792634ff566eae9fbb2c5bfbf1d 100644 (file)
@@ -207,7 +207,7 @@ mod kw_generated {
             #keyword_stream
         }
 
-        #[allow(rustc::default_hash_types)]
+        #[cfg_attr(bootstrap, allow(rustc::default_hash_types))]
         #[allow(non_upper_case_globals)]
         #[doc(hidden)]
         pub mod sym_generated {
index e9773bac819bd356b04251a0b5ca0b489bf47d61..d28ebfe107cdd8326ee5fd585ea2bb3710ce8677 100644 (file)
@@ -959,6 +959,10 @@ fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
         self.get_impl_data(id).defaultness
     }
 
+    fn get_impl_constness(&self, id: DefIndex) -> hir::Constness {
+        self.get_impl_data(id).constness
+    }
+
     fn get_coerce_unsized_info(&self, id: DefIndex) -> Option<ty::adjustment::CoerceUnsizedInfo> {
         self.get_impl_data(id).coerce_unsized_info
     }
index 473ae4eb386413725b0dce32629128a4b5d3c89d..d96034c951c6c9454a89490ddb3ead4072aa8f9c 100644 (file)
@@ -168,6 +168,7 @@ fn into_args(self) -> (DefId, DefId) {
     is_no_builtins => { cdata.root.no_builtins }
     symbol_mangling_version => { cdata.root.symbol_mangling_version }
     impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
+    impl_constness => { cdata.get_impl_constness(def_id.index) }
     reachable_non_generics => {
         let reachable_non_generics = tcx
             .exported_symbols(cdata.cnum)
index 6fac8e595d0adad7f81bb40e7d8bbf2096117208..602e1fd822c02a6bcc705e2d3a20655641697b0d 100644 (file)
@@ -1413,7 +1413,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                     adt_def.repr,
                 )
             }
-            hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
+            hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
                 let trait_ref = self.tcx.impl_trait_ref(def_id);
                 let polarity = self.tcx.impl_polarity(def_id);
                 let parent = if let Some(trait_ref) = trait_ref {
@@ -1438,8 +1438,13 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
                     }
                 });
 
-                let data =
-                    ImplData { polarity, defaultness, parent_impl: parent, coerce_unsized_info };
+                let data = ImplData {
+                    polarity,
+                    defaultness,
+                    constness,
+                    parent_impl: parent,
+                    coerce_unsized_info,
+                };
 
                 EntryKind::Impl(self.lazy(data))
             }
index 8cc1935951fe37a40d0be8fbf208ec375fb6731b..f2ebfb9b725ba052d0dfde7d6516b29394374016 100644 (file)
@@ -392,6 +392,7 @@ struct TraitData {
 #[derive(TyEncodable, TyDecodable)]
 struct ImplData {
     polarity: ty::ImplPolarity,
+    constness: hir::Constness,
     defaultness: hir::Defaultness,
     parent_impl: Option<DefId>,
 
index 6f799ea940b05c04bbc9c76a5a90c7b0550610ba..5c32c0fdb6cc8774433dfb12830ff05a44c7289f 100644 (file)
@@ -18,7 +18,7 @@
 use rustc_span::def_id::StableCrateId;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
@@ -465,6 +465,9 @@ pub fn body_owner_kind(&self, id: HirId) -> BodyOwnerKind {
     /// Returns the `ConstContext` of the body associated with this `LocalDefId`.
     ///
     /// Panics if `LocalDefId` does not have an associated body.
+    ///
+    /// This should only be used for determining the context of a body, a return
+    /// value of `Some` does not always suggest that the owner of the body is `const`.
     pub fn body_const_context(&self, did: LocalDefId) -> Option<ConstContext> {
         let hir_id = self.local_def_id_to_hir_id(did);
         let ccx = match self.body_owner_kind(hir_id) {
@@ -473,6 +476,11 @@ pub fn body_const_context(&self, did: LocalDefId) -> Option<ConstContext> {
 
             BodyOwnerKind::Fn if self.tcx.is_constructor(did.to_def_id()) => return None,
             BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(did.to_def_id()) => ConstContext::ConstFn,
+            BodyOwnerKind::Fn
+                if self.tcx.has_attr(did.to_def_id(), sym::default_method_body_is_const) =>
+            {
+                ConstContext::ConstFn
+            }
             BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,
         };
 
index 63872ca9017668c0015993b0347d816bce958b6d..484e30027e521ce3961368584152b64a474a02c2 100644 (file)
@@ -8,7 +8,7 @@
 use rustc_index::vec::IndexVec;
 use rustc_session::lint::{
     builtin::{self, FORBIDDEN_LINT_GROUPS},
-    FutureIncompatibilityReason, Level, Lint, LintId,
+    FutureIncompatibilityReason, FutureIncompatibleInfo, Level, Lint, LintId,
 };
 use rustc_session::{DiagnosticMessageId, Session};
 use rustc_span::hygiene::MacroKind;
@@ -223,8 +223,13 @@ fn struct_lint_level_impl(
         let lint_id = LintId::of(lint);
         let future_incompatible = lint.future_incompatible;
 
-        let has_future_breakage =
-            future_incompatible.map_or(false, |incompat| incompat.future_breakage.is_some());
+        let has_future_breakage = matches!(
+            future_incompatible,
+            Some(FutureIncompatibleInfo {
+                reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
+                ..
+            })
+        );
 
         let mut err = match (level, span) {
             (Level::Allow, span) => {
index aa0f18846d1540c981015f2de000021c19b37d34..2804fe580615c2dfafea4c99c1016762a318939c 100644 (file)
@@ -226,18 +226,19 @@ fn late_report_deprecation(
     suggestion: Option<Symbol>,
     lint: &'static Lint,
     span: Span,
+    method_span: Option<Span>,
     hir_id: HirId,
     def_id: DefId,
 ) {
     if span.in_derive_expansion() {
         return;
     }
-
-    tcx.struct_span_lint_hir(lint, hir_id, span, |lint| {
+    let method_span = method_span.unwrap_or(span);
+    tcx.struct_span_lint_hir(lint, hir_id, method_span, |lint| {
         let mut diag = lint.build(message);
         if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
             let kind = tcx.def_kind(def_id).descr(def_id);
-            deprecation_suggestion(&mut diag, kind, suggestion, span);
+            deprecation_suggestion(&mut diag, kind, suggestion, method_span);
         }
         diag.emit()
     });
@@ -306,13 +307,13 @@ pub fn eval_stability(
                     let path = &with_no_trimmed_paths(|| self.def_path_str(def_id));
                     let kind = self.def_kind(def_id).descr(def_id);
                     let (message, lint) = deprecation_message(&depr_entry.attr, kind, path);
-                    let span = method_span.unwrap_or(span);
                     late_report_deprecation(
                         self,
                         &message,
                         depr_entry.attr.suggestion,
                         lint,
                         span,
+                        method_span,
                         id,
                         def_id,
                     );
index c2645a0914007f012fa2d55f886558dfa2b9a720..75cbb55239c8b21ff8a10ffb566732e724862548 100644 (file)
@@ -512,7 +512,7 @@ pub fn no_bytes_init(&self) -> bool {
 /// Transferring the initialization mask to other allocations.
 impl<Tag, Extra> Allocation<Tag, Extra> {
     /// Creates a run-length encoding of the initialization mask.
-    pub fn compress_uninit_range(&self, src: Pointer<Tag>, size: Size) -> InitMaskCompressed {
+    pub fn compress_uninit_range(&self, range: AllocRange) -> InitMaskCompressed {
         // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
         // a naive initialization mask copying algorithm would repeatedly have to read the initialization mask from
         // the source and write it to the destination. Even if we optimized the memory accesses,
@@ -526,13 +526,13 @@ pub fn compress_uninit_range(&self, src: Pointer<Tag>, size: Size) -> InitMaskCo
         // where each element toggles the state.
 
         let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
-        let initial = self.init_mask.get(src.offset);
+        let initial = self.init_mask.get(range.start);
         let mut cur_len = 1;
         let mut cur = initial;
 
-        for i in 1..size.bytes() {
+        for i in 1..range.size.bytes() {
             // FIXME: optimize to bitshift the current uninitialized block's bits and read the top bit.
-            if self.init_mask.get(src.offset + Size::from_bytes(i)) == cur {
+            if self.init_mask.get(range.start + Size::from_bytes(i)) == cur {
                 cur_len += 1;
             } else {
                 ranges.push(cur_len);
@@ -550,24 +550,23 @@ pub fn compress_uninit_range(&self, src: Pointer<Tag>, size: Size) -> InitMaskCo
     pub fn mark_compressed_init_range(
         &mut self,
         defined: &InitMaskCompressed,
-        dest: Pointer<Tag>,
-        size: Size,
+        range: AllocRange,
         repeat: u64,
     ) {
         // An optimization where we can just overwrite an entire range of initialization
         // bits if they are going to be uniformly `1` or `0`.
         if defined.ranges.len() <= 1 {
             self.init_mask.set_range_inbounds(
-                dest.offset,
-                dest.offset + size * repeat, // `Size` operations
+                range.start,
+                range.start + range.size * repeat, // `Size` operations
                 defined.initial,
             );
             return;
         }
 
         for mut j in 0..repeat {
-            j *= size.bytes();
-            j += dest.offset.bytes();
+            j *= range.size.bytes();
+            j += range.start.bytes();
             let mut cur = defined.initial;
             for range in &defined.ranges {
                 let old_j = j;
index 79a4e94948e5e9a9107d91c55a42caf0445b7be2..bc471aff2d02e092065666a05f7cb0b73e1f86d7 100644 (file)
         desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
     }
 
+    query impl_constness(def_id: DefId) -> hir::Constness {
+        desc { |tcx| "looking up whether `{}` is a const impl", tcx.def_path_str(def_id) }
+    }
+
     query check_item_well_formed(key: LocalDefId) -> () {
         desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
     }
index bf5f2c0eec23edc8382fc0819410dd4811600948..671d947d1b1321f2ac7d1797e53e9914794520d3 100644 (file)
@@ -147,7 +147,7 @@ pub(crate) fn report_mutability_error(
                     if let Some(desc) = access_place_desc {
                         item_msg = format!("`{}`", desc);
                         reason = match error_access {
-                            AccessKind::Mutate => format!(" which is behind {}", pointer_type),
+                            AccessKind::Mutate => format!(", which is behind {}", pointer_type),
                             AccessKind::MutableBorrow => {
                                 format!(", as it is behind {}", pointer_type)
                             }
@@ -897,16 +897,32 @@ fn suggest_ampmut<'tcx>(
 ) -> (Span, String) {
     if let Some(assignment_rhs_span) = opt_assignment_rhs_span {
         if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
+            let is_mutbl = |ty: &str| -> bool {
+                if ty.starts_with("mut") {
+                    let rest = &ty[3..];
+                    match rest.chars().next() {
+                        // e.g. `&mut x`
+                        Some(c) if c.is_whitespace() => true,
+                        // e.g. `&mut(x)`
+                        Some('(') => true,
+                        // e.g. `&mutablevar`
+                        _ => false,
+                    }
+                } else {
+                    false
+                }
+            };
             if let (true, Some(ws_pos)) =
                 (src.starts_with("&'"), src.find(|c: char| -> bool { c.is_whitespace() }))
             {
                 let lt_name = &src[1..ws_pos];
-                let ty = &src[ws_pos..];
-                if !ty.trim_start().starts_with("mut") {
+                let ty = src[ws_pos..].trim_start();
+                if !is_mutbl(ty) {
                     return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
                 }
             } else if let Some(stripped) = src.strip_prefix('&') {
-                if !stripped.trim_start().starts_with("mut") {
+                let stripped = stripped.trim_start();
+                if !is_mutbl(stripped) {
                     return (assignment_rhs_span, format!("&mut {}", stripped));
                 }
             }
index 279f414e7fef14667bfb4d6e08061ccb70cf2731..f8b66badb8a4c2c3f8a9c0f1d760a539d192e6ca 100644 (file)
@@ -235,12 +235,15 @@ fn find_mir_or_eval_fn(
             // sensitive check here.  But we can at least rule out functions that are not const
             // at all.
             if !ecx.tcx.is_const_fn_raw(def.did) {
-                // Some functions we support even if they are non-const -- but avoid testing
-                // that for const fn!
-                ecx.hook_panic_fn(instance, args)?;
-                // We certainly do *not* want to actually call the fn
-                // though, so be sure we return here.
-                throw_unsup_format!("calling non-const function `{}`", instance)
+                // allow calling functions marked with #[default_method_body_is_const].
+                if !ecx.tcx.has_attr(def.did, sym::default_method_body_is_const) {
+                    // Some functions we support even if they are non-const -- but avoid testing
+                    // that for const fn!
+                    ecx.hook_panic_fn(instance, args)?;
+                    // We certainly do *not* want to actually call the fn
+                    // though, so be sure we return here.
+                    throw_unsup_format!("calling non-const function `{}`", instance)
+                }
             }
         }
         // This is a const fn. Call it.
index 648a7abfdc7b12c36d3e483fa8ab1d2e6d935848..8cd459265dfc54fe2a1f81170068eddab5dfdbfc 100644 (file)
@@ -18,8 +18,8 @@
 use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
 
 use super::{
-    Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, Operand, Place, PlaceTy,
-    ScalarMaybeUninit, StackPopJump,
+    Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, MemoryKind, Operand, Place,
+    PlaceTy, ScalarMaybeUninit, StackPopJump,
 };
 use crate::transform::validate::equal_up_to_regions;
 use crate::util::storage::AlwaysLiveLocals;
@@ -900,7 +900,7 @@ fn deallocate_local(&mut self, local: LocalValue<M::PointerTag>) -> InterpResult
             // due to the local having ZST type.
             let ptr = ptr.assert_ptr();
             trace!("deallocating local: {:?}", self.memory.dump_alloc(ptr.alloc_id));
-            self.memory.deallocate_local(ptr)?;
+            self.memory.deallocate(ptr, None, MemoryKind::Stack)?;
         };
         Ok(())
     }
index cb929c21850cb62d2ed7da56260659776edd40fb..5f719cc160706d09aa3fa9d1e0cee62a7ac00d46 100644 (file)
@@ -276,17 +276,6 @@ pub fn reallocate(
         Ok(new_ptr)
     }
 
-    /// Deallocate a local, or do nothing if that local has been made into a global.
-    pub fn deallocate_local(&mut self, ptr: Pointer<M::PointerTag>) -> InterpResult<'tcx> {
-        // The allocation might be already removed by global interning.
-        // This can only really happen in the CTFE instance, not in miri.
-        if self.alloc_map.contains_key(&ptr.alloc_id) {
-            self.deallocate(ptr, None, MemoryKind::Stack)
-        } else {
-            Ok(())
-        }
-    }
-
     pub fn deallocate(
         &mut self,
         ptr: Pointer<M::PointerTag>,
@@ -1049,7 +1038,7 @@ pub fn copy_repeatedly(
             num_copies,
         );
         // Prepare a copy of the initialization mask.
-        let compressed = src_alloc.compress_uninit_range(src, size);
+        let compressed = src_alloc.compress_uninit_range(alloc_range(src.offset, size));
         // This checks relocation edges on the src.
         let src_bytes = src_alloc
             .get_bytes_with_uninit_and_ptr(&tcx, alloc_range(src.offset, size))
@@ -1110,7 +1099,11 @@ pub fn copy_repeatedly(
         }
 
         // now fill in all the "init" data
-        dest_alloc.mark_compressed_init_range(&compressed, dest, size, num_copies);
+        dest_alloc.mark_compressed_init_range(
+            &compressed,
+            alloc_range(dest.offset, size),
+            num_copies,
+        );
         // copy the relocations to the destination
         dest_alloc.mark_relocation_range(relocations);
 
index 6216ff6656e28f0a193125e4456c59bb5e7575cd..646ae8ced7eb442398cee5b2a3808cb8c5567a86 100644 (file)
@@ -886,8 +886,34 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                 }
 
                 if !tcx.is_const_fn_raw(callee) {
-                    self.check_op(ops::FnCallNonConst);
-                    return;
+                    let mut permitted = false;
+
+                    let callee_trait = tcx.trait_of_item(callee);
+                    if let Some(trait_id) = callee_trait {
+                        if tcx.has_attr(caller, sym::default_method_body_is_const) {
+                            // permit call to non-const fn when caller has default_method_body_is_const..
+                            if tcx.trait_of_item(caller) == callee_trait {
+                                // ..and caller and callee are in the same trait.
+                                permitted = true;
+                            }
+                        }
+                        let mut const_impls = true;
+                        tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
+                            if const_impls {
+                                if let hir::Constness::NotConst = tcx.impl_constness(imp) {
+                                    const_impls = false;
+                                }
+                            }
+                        });
+                        if const_impls {
+                            permitted = true;
+                        }
+                    }
+
+                    if !permitted {
+                        self.check_op(ops::FnCallNonConst);
+                        return;
+                    }
                 }
 
                 // If the `const fn` we are trying to call is not const-stable, ensure that we have
index 539de80cab71cae30d19ae47e07183f47ae648f4..7c1a592f5515efbc2d0a948e8bd3428d88a908c6 100644 (file)
@@ -65,6 +65,6 @@
 pub mod as_place;
 mod as_rvalue;
 mod as_temp;
-mod category;
+pub mod category;
 mod into;
 mod stmt;
index f5f6da3ec0bbac4cb4e79fa9155fe9404a422997..60cfd73b19a6e8b5b04c5e64574d197aedee7cf2 100644 (file)
@@ -1131,3 +1131,5 @@ fn get_unit_temp(&mut self) -> Place<'tcx> {
 mod matches;
 mod misc;
 mod scope;
+
+pub(crate) use expr::category::Category as ExprCategory;
index 38111527a4ec719e133138452ad4eea2247238a5..82e19c0552720b8efebf8f1bce74c0ad1eba6fc3 100644 (file)
@@ -1,9 +1,11 @@
+use crate::build::ExprCategory;
 use crate::thir::visit::{self, Visitor};
 
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_middle::mir::BorrowKind;
 use rustc_middle::thir::*;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, ParamEnv, TyCtxt};
 use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
 use rustc_session::lint::Level;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -27,6 +29,8 @@ struct UnsafetyVisitor<'a, 'tcx> {
     body_target_features: &'tcx Vec<Symbol>,
     in_possible_lhs_union_assign: bool,
     in_union_destructure: bool,
+    param_env: ParamEnv<'tcx>,
+    inside_adt: bool,
 }
 
 impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
@@ -133,6 +137,50 @@ fn unsafe_op_in_unsafe_fn_allowed(&self) -> bool {
     }
 }
 
+// Searches for accesses to layout constrained fields.
+struct LayoutConstrainedPlaceVisitor<'a, 'tcx> {
+    found: bool,
+    thir: &'a Thir<'tcx>,
+    tcx: TyCtxt<'tcx>,
+}
+
+impl<'a, 'tcx> LayoutConstrainedPlaceVisitor<'a, 'tcx> {
+    fn new(thir: &'a Thir<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
+        Self { found: false, thir, tcx }
+    }
+}
+
+impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> {
+    fn thir(&self) -> &'a Thir<'tcx> {
+        self.thir
+    }
+
+    fn visit_expr(&mut self, expr: &Expr<'tcx>) {
+        match expr.kind {
+            ExprKind::Field { lhs, .. } => {
+                if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() {
+                    if (Bound::Unbounded, Bound::Unbounded)
+                        != self.tcx.layout_scalar_valid_range(adt_def.did)
+                    {
+                        self.found = true;
+                    }
+                }
+                visit::walk_expr(self, expr);
+            }
+
+            // Keep walking through the expression as long as we stay in the same
+            // place, i.e. the expression is a place expression and not a dereference
+            // (since dereferencing something leads us to a different place).
+            ExprKind::Deref { .. } => {}
+            ref kind if ExprCategory::of(kind).map_or(true, |cat| cat == ExprCategory::Place) => {
+                visit::walk_expr(self, expr);
+            }
+
+            _ => {}
+        }
+    }
+}
+
 impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
     fn thir(&self) -> &'a Thir<'tcx> {
         &self.thir
@@ -160,60 +208,82 @@ fn visit_block(&mut self, block: &Block) {
     }
 
     fn visit_pat(&mut self, pat: &Pat<'tcx>) {
-        use PatKind::*;
-
         if self.in_union_destructure {
             match *pat.kind {
                 // binding to a variable allows getting stuff out of variable
-                Binding { .. }
+                PatKind::Binding { .. }
                 // match is conditional on having this value
-                | Constant { .. }
-                | Variant { .. }
-                | Leaf { .. }
-                | Deref { .. }
-                | Range { .. }
-                | Slice { .. }
-                | Array { .. } => {
+                | PatKind::Constant { .. }
+                | PatKind::Variant { .. }
+                | PatKind::Leaf { .. }
+                | PatKind::Deref { .. }
+                | PatKind::Range { .. }
+                | PatKind::Slice { .. }
+                | PatKind::Array { .. } => {
                     self.requires_unsafe(pat.span, AccessToUnionField);
-                    return; // don't walk pattern
+                    return; // we can return here since this already requires unsafe
                 }
                 // wildcard doesn't take anything
-                Wild |
+                PatKind::Wild |
                 // these just wrap other patterns
-                Or { .. } |
-                AscribeUserType { .. } => {}
+                PatKind::Or { .. } |
+                PatKind::AscribeUserType { .. } => {}
             }
         };
 
-        if let ty::Adt(adt_def, _) = pat.ty.kind() {
-            // check for extracting values from union via destructuring
-            if adt_def.is_union() {
-                match *pat.kind {
-                    // assigning the whole union is okay
-                    // let x = Union { ... };
-                    // let y = x; // safe
-                    Binding { .. } |
-                    // binding to wildcard is okay since that never reads anything and stops double errors
-                    // with implict wildcard branches from `if let`s
-                    Wild |
-                    // doesn't have any effect on semantics
-                    AscribeUserType { .. } |
-                    // creating a union literal
-                    Constant { .. } => {},
-                    Leaf { .. } | Or { .. } => {
-                        // pattern matching with a union and not doing something like v = Union { bar: 5 }
-                        self.in_union_destructure = true;
+        match &*pat.kind {
+            PatKind::Leaf { .. } => {
+                if let ty::Adt(adt_def, ..) = pat.ty.kind() {
+                    if adt_def.is_union() {
+                        let old_in_union_destructure =
+                            std::mem::replace(&mut self.in_union_destructure, true);
+                        visit::walk_pat(self, pat);
+                        self.in_union_destructure = old_in_union_destructure;
+                    } else if (Bound::Unbounded, Bound::Unbounded)
+                        != self.tcx.layout_scalar_valid_range(adt_def.did)
+                    {
+                        let old_inside_adt = std::mem::replace(&mut self.inside_adt, true);
+                        visit::walk_pat(self, pat);
+                        self.inside_adt = old_inside_adt;
+                    } else {
                         visit::walk_pat(self, pat);
-                        self.in_union_destructure = false;
-                        return; // don't walk pattern
                     }
-                    Variant { .. } | Deref { .. } | Range { .. } | Slice { .. } | Array { .. } =>
-                        unreachable!("impossible union destructuring type"),
+                } else {
+                    visit::walk_pat(self, pat);
                 }
             }
+            PatKind::Binding { mode: BindingMode::ByRef(borrow_kind), ty, .. } => {
+                if self.inside_adt {
+                    if let ty::Ref(_, ty, _) = ty.kind() {
+                        match borrow_kind {
+                            BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
+                                if !ty.is_freeze(self.tcx.at(pat.span), self.param_env) {
+                                    self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
+                                }
+                            }
+                            BorrowKind::Mut { .. } => {
+                                self.requires_unsafe(pat.span, MutationOfLayoutConstrainedField);
+                            }
+                        }
+                    } else {
+                        span_bug!(
+                            pat.span,
+                            "BindingMode::ByRef in pattern, but found non-reference type {}",
+                            ty
+                        );
+                    }
+                }
+                visit::walk_pat(self, pat);
+            }
+            PatKind::Deref { .. } => {
+                let old_inside_adt = std::mem::replace(&mut self.inside_adt, false);
+                visit::walk_pat(self, pat);
+                self.inside_adt = old_inside_adt;
+            }
+            _ => {
+                visit::walk_pat(self, pat);
+            }
         }
-
-        visit::walk_pat(self, pat);
     }
 
     fn visit_expr(&mut self, expr: &Expr<'tcx>) {
@@ -350,15 +420,46 @@ fn visit_expr(&mut self, expr: &Expr<'tcx>) {
                     }
                 }
             }
-            // don't have any special handling for AssignOp since it causes a read *and* write to lhs
-            ExprKind::Assign { lhs, rhs } => {
-                // assigning to a union is safe, check here so it doesn't get treated as a read later
-                self.in_possible_lhs_union_assign = true;
-                visit::walk_expr(self, &self.thir()[lhs]);
-                self.in_possible_lhs_union_assign = false;
-                visit::walk_expr(self, &self.thir()[rhs]);
-                return; // don't visit the whole expression
+            ExprKind::Assign { lhs, rhs } | ExprKind::AssignOp { lhs, rhs, .. } => {
+                // First, check whether we are mutating a layout constrained field
+                let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+                visit::walk_expr(&mut visitor, &self.thir[lhs]);
+                if visitor.found {
+                    self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
+                }
+
+                // Second, check for accesses to union fields
+                // don't have any special handling for AssignOp since it causes a read *and* write to lhs
+                if matches!(expr.kind, ExprKind::Assign { .. }) {
+                    // assigning to a union is safe, check here so it doesn't get treated as a read later
+                    self.in_possible_lhs_union_assign = true;
+                    visit::walk_expr(self, &self.thir()[lhs]);
+                    self.in_possible_lhs_union_assign = false;
+                    visit::walk_expr(self, &self.thir()[rhs]);
+                    return; // we have already visited everything by now
+                }
             }
+            ExprKind::Borrow { borrow_kind, arg } => match borrow_kind {
+                BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
+                    if !self.thir[arg]
+                        .ty
+                        .is_freeze(self.tcx.at(self.thir[arg].span), self.param_env)
+                    {
+                        let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+                        visit::walk_expr(&mut visitor, expr);
+                        if visitor.found {
+                            self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField);
+                        }
+                    }
+                }
+                BorrowKind::Mut { .. } => {
+                    let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+                    visit::walk_expr(&mut visitor, expr);
+                    if visitor.found {
+                        self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
+                    }
+                }
+            },
             _ => {}
         }
         visit::walk_expr(self, expr);
@@ -520,6 +621,8 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
         body_target_features,
         in_possible_lhs_union_assign: false,
         in_union_destructure: false,
+        param_env: tcx.param_env(def.did),
+        inside_adt: false,
     };
     visitor.visit_expr(&thir[expr]);
 }
index cb9c89324d6b3098b6b854dc0bd34914497b530c..3859b22223c006bfc39d2d85282e0518efcbff74 100644 (file)
@@ -490,17 +490,29 @@ fn recur(
                 // convert the dereferenced constant to a pattern that is the sub-pattern of the
                 // deref pattern.
                 _ => {
-                    let old = self.behind_reference.replace(true);
-                    // In case there are structural-match violations somewhere in this subpattern,
-                    // we fall back to a const pattern. If we do not do this, we may end up with
-                    // a !structural-match constant that is not of reference type, which makes it
-                    // very hard to invoke `PartialEq::eq` on it as a fallback.
-                    let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
-                        Ok(subpattern) => PatKind::Deref { subpattern },
-                        Err(_) => PatKind::Constant { value: cv },
-                    };
-                    self.behind_reference.set(old);
-                    val
+                    if !pointee_ty.is_sized(tcx.at(span), param_env) {
+                        // `tcx.deref_const()` below will ICE with an unsized type
+                        // (except slices, which are handled in a separate arm above).
+                        let msg = format!("cannot use unsized non-slice type `{}` in constant patterns", pointee_ty);
+                        if self.include_lint_checks {
+                            tcx.sess.span_err(span, &msg);
+                        } else {
+                            tcx.sess.delay_span_bug(span, &msg);
+                        }
+                        PatKind::Wild
+                    } else {
+                        let old = self.behind_reference.replace(true);
+                        // In case there are structural-match violations somewhere in this subpattern,
+                        // we fall back to a const pattern. If we do not do this, we may end up with
+                        // a !structural-match constant that is not of reference type, which makes it
+                        // very hard to invoke `PartialEq::eq` on it as a fallback.
+                        let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
+                            Ok(subpattern) => PatKind::Deref { subpattern },
+                            Err(_) => PatKind::Constant { value: cv },
+                        };
+                        self.behind_reference.set(old);
+                        val
+                    }
                 }
             },
             ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
index d0795841c5359b30f382f27ab27fbaffb3c0ab62..71231830e99a7afe2b2746264eec5efbf97efc87 100644 (file)
@@ -98,6 +98,9 @@ fn check_attributes(
                 | sym::rustc_if_this_changed
                 | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
                 sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
+                sym::default_method_body_is_const => {
+                    self.check_default_method_body_is_const(attr, span, target)
+                }
                 _ => true,
             };
             // lint-only checks
@@ -1465,6 +1468,29 @@ fn check_rustc_allow_const_fn_unstable(
             }
         }
     }
+
+    /// default_method_body_is_const should only be applied to trait methods with default bodies.
+    fn check_default_method_body_is_const(
+        &self,
+        attr: &Attribute,
+        span: &Span,
+        target: Target,
+    ) -> bool {
+        match target {
+            Target::Method(MethodKind::Trait { body: true }) => true,
+            _ => {
+                self.tcx
+                    .sess
+                    .struct_span_err(
+                        attr.span,
+                        "attribute should be applied to a trait method with body",
+                    )
+                    .span_label(*span, "not a trait method or missing a body")
+                    .emit();
+                false
+            }
+        }
+    }
 }
 
 impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
index d783852aacadd205294ff5584939f70e454d668f..6ee54cfe37f306cbbc9a18cdf1885ae8b7c668dc 100644 (file)
@@ -8,6 +8,7 @@
 //! through, but errors for structured control flow in a `const` should be emitted here.
 
 use rustc_attr as attr;
+use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
@@ -85,34 +86,41 @@ fn visit_item(&mut self, item: &'hir hir::Item<'hir>) {
             if let hir::ItemKind::Impl(ref imp) = item.kind {
                 if let hir::Constness::Const = imp.constness {
                     let did = imp.of_trait.as_ref()?.trait_def_id()?;
-                    let trait_fn_cnt = self
-                        .tcx
-                        .associated_item_def_ids(did)
-                        .iter()
-                        .filter(|did| {
-                            matches!(
-                                self.tcx.associated_item(**did),
-                                ty::AssocItem { kind: ty::AssocKind::Fn, .. }
-                            )
-                        })
-                        .count();
+                    let mut to_implement = FxHashSet::default();
+
+                    for did in self.tcx.associated_item_def_ids(did) {
+                        if let ty::AssocItem {
+                            kind: ty::AssocKind::Fn, ident, defaultness, ..
+                        } = self.tcx.associated_item(*did)
+                        {
+                            // we can ignore functions that do not have default bodies:
+                            // if those are unimplemented it will be catched by typeck.
+                            if defaultness.has_value()
+                                && !self.tcx.has_attr(*did, sym::default_method_body_is_const)
+                            {
+                                to_implement.insert(ident);
+                            }
+                        }
+                    }
 
-                    let impl_fn_cnt = imp
+                    for it in imp
                         .items
                         .iter()
                         .filter(|it| matches!(it.kind, hir::AssocItemKind::Fn { .. }))
-                        .count();
+                    {
+                        to_implement.remove(&it.ident);
+                    }
 
-                    // number of trait functions unequal to functions in impl,
-                    // meaning that one or more provided/default functions of the
-                    // trait are used.
-                    if trait_fn_cnt != impl_fn_cnt {
+                    // all nonconst trait functions (not marked with #[default_method_body_is_const])
+                    // must be implemented
+                    if !to_implement.is_empty() {
                         self.tcx
                             .sess
                             .struct_span_err(
                                 item.span,
-                                "const trait implementations may not use default functions",
+                                "const trait implementations may not use non-const default functions",
                             )
+                            .note(&format!("`{}` not implemented", to_implement.into_iter().map(|id| id.to_string()).collect::<Vec<_>>().join("`, `")))
                             .emit();
                     }
                 }
index cd8dd6984d5b9d3f897d623ac85a003fb36b4af9..42a4753c29c9b325b9f0a3585db951f35cff55db 100644 (file)
@@ -875,7 +875,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
 
     fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
         if let Some(def_id) = path.res.opt_def_id() {
-            self.tcx.check_stability(def_id, Some(id), path.span, None)
+            let method_span = path.segments.last().map(|s| s.ident.span);
+            self.tcx.check_stability(def_id, Some(id), path.span, method_span)
         }
         intravisit::walk_path(self, path)
     }
index 88eaa7fe329246a857dec29b79639bb4811acf0c..b444f66258a8e8d76413f5fa4677eb86b4705866 100644 (file)
@@ -805,6 +805,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     let wordsz = sess.target.pointer_width.to_string();
     let os = &sess.target.os;
     let env = &sess.target.env;
+    let abi = &sess.target.abi;
     let vendor = &sess.target.vendor;
     let min_atomic_width = sess.target.min_atomic_width();
     let max_atomic_width = sess.target.max_atomic_width();
@@ -814,7 +815,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     });
 
     let mut ret = FxHashSet::default();
-    ret.reserve(6); // the minimum number of insertions
+    ret.reserve(7); // the minimum number of insertions
     // Target bindings.
     ret.insert((sym::target_os, Some(Symbol::intern(os))));
     for fam in &sess.target.families {
@@ -829,6 +830,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
     ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
     ret.insert((sym::target_env, Some(Symbol::intern(env))));
+    ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
     ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
     if sess.target.has_elf_tls {
         ret.insert((sym::target_thread_local, None));
index 8270bbbe8fd8001f15ac94b3bb0eedcc1eeb3eb8..f3ce78d2d78f89042f146dd66cc99d449c04355a 100644 (file)
@@ -20,8 +20,7 @@
 use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported};
-use rustc_lint_defs::FutureBreakage;
+use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported};
 use rustc_macros::HashStable_Generic;
 pub use rustc_span::def_id::StableCrateId;
 use rustc_span::source_map::{FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
@@ -317,23 +316,7 @@ fn emit_future_breakage(&self) {
         if diags.is_empty() {
             return;
         }
-        // If any future-breakage lints were registered, this lint store
-        // should be available
-        let lint_store = self.lint_store.get().expect("`lint_store` not initialized!");
-        let diags_and_breakage: Vec<(FutureBreakage, Diagnostic)> = diags
-            .into_iter()
-            .map(|diag| {
-                let lint_name = match &diag.code {
-                    Some(DiagnosticId::Lint { name, has_future_breakage: true, .. }) => name,
-                    _ => panic!("Unexpected code in diagnostic {:?}", diag),
-                };
-                let lint = lint_store.name_to_lint(&lint_name);
-                let future_breakage =
-                    lint.lint.future_incompatible.unwrap().future_breakage.unwrap();
-                (future_breakage, diag)
-            })
-            .collect();
-        self.parse_sess.span_diagnostic.emit_future_breakage_report(diags_and_breakage);
+        self.parse_sess.span_diagnostic.emit_future_breakage_report(diags);
     }
 
     pub fn local_stable_crate_id(&self) -> StableCrateId {
index cfa0c79004c002b946f4f31ff2816f18d73e062a..07f22159f96c85d4e2bf58f42e497e98a443d594 100644 (file)
         cfg_eval,
         cfg_panic,
         cfg_sanitize,
+        cfg_target_abi,
         cfg_target_feature,
         cfg_target_has_atomic,
         cfg_target_thread_local,
         decode,
         default_alloc_error_handler,
         default_lib_allocator,
+        default_method_body_is_const,
         default_type_parameter_fallback,
         default_type_params,
         delay_span_bug_from_inside_query,
         sync,
         sync_trait,
         t32,
+        target_abi,
         target_arch,
         target_endian,
         target_env,
index c1adc963425ea6791eb756429f568d738d7d80f4..e05360ea45c6c5b677f07ace67752a0a11f3a31b 100644 (file)
@@ -10,6 +10,11 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { mcount: "\u{1}_mcount".to_string(), endian: Endian::Big, ..base },
+        options: TargetOptions {
+            abi: "ilp32".to_string(),
+            mcount: "\u{1}_mcount".to_string(),
+            endian: Endian::Big,
+            ..base
+        },
     }
 }
index e2618447f2810e69166efb79abbb87f2878a986e..8522405f61feb50fbb2972a9990f72994b6816f6 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
+            abi: "ilp32".to_string(),
             max_atomic_width: Some(128),
             mcount: "\u{1}_mcount".to_string(),
             ..super::linux_gnu_base::opts()
index 482db0c53420e70ad8caeb0b705552bf263160fc..fa93ca80549cf1abc5656565809334845faccc66 100644 (file)
@@ -10,6 +10,7 @@
 
 pub fn target() -> Target {
     let opts = TargetOptions {
+        abi: "softfloat".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         linker: Some("rust-lld".to_owned()),
         features: "+strict-align,-neon,-fp-armv8".to_string(),
index e7f7bb343d0c534541dd31261b886b7a0870efe7..39bc699eef04a366bba8d4b03e253bc9038bf34d 100644 (file)
@@ -14,6 +14,15 @@ pub enum Arch {
     Arm64_sim,
 }
 
+fn target_abi(arch: Arch) -> String {
+    match arch {
+        Armv7 | Armv7s | Arm64 | I386 | X86_64 => "",
+        X86_64_macabi | Arm64_macabi => "macabi",
+        Arm64_sim => "sim",
+    }
+    .to_string()
+}
+
 fn target_cpu(arch: Arch) -> String {
     match arch {
         Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
@@ -39,6 +48,7 @@ fn link_env_remove(arch: Arch) -> Vec<String> {
 
 pub fn opts(os: &str, arch: Arch) -> TargetOptions {
     TargetOptions {
+        abi: target_abi(arch),
         cpu: target_cpu(arch),
         dynamic_linking: false,
         executables: true,
index f2430830afca584484d819d4de987b1e0f62e490..9b5366c576ec6a30b54b0113d61b509a300fb841 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // https://developer.android.com/ndk/guides/abis.html#armeabi
             features: "+strict-align,+v5te".to_string(),
             max_atomic_width: Some(32),
index 225db0032a89d2d9815426c63f368381dc92f200..442f56d4fb5de73ed6697295dca4a304646ad2da 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+strict-align,+v6".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
index 33703195ee751a3df2fcf400a772e8c34e89db3c..2c12a71e29fb825ee9a2a1e57dcf5cfc31da9392 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             features: "+strict-align,+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
index 850844993f95cca9337977e9e90cee5fdba87306..d187dfd918955d0d1c717b08a5692c822daf93a7 100644 (file)
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // Most of these settings are copied from the arm_unknown_linux_gnueabi
             // target.
             features: "+strict-align,+v6".to_string(),
index ff69c462e8ed233d9ef438d998f3b206d8b0e5a2..3d72734f5fadc5bb8fb81cce0cd834601451d206 100644 (file)
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Most of these settings are copied from the arm_unknown_linux_gnueabihf
             // target.
             features: "+strict-align,+v6,+vfp2,-d32".to_string(),
index 547f48c5d3b61d2ad92fd068f688e4e82d9c8279..c98a12cfc4977f7d392340ad3543193e49fac5c0 100644 (file)
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             endian: Endian::Big,
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
index f4f61e87ab9448e2072446228d00c62ba43381bb..292635403fbd476c9d4bc12eb214a960b4fed986 100644 (file)
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             endian: Endian::Big,
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
index 8a289fee7812f4456d9320d5bdee9cdefbf6badc..f1b193a384fc1bc9fc1d01d5eb454fde2ac58eb7 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
index 177ab453b04c49ec05d7ebe09eb9c63e20dcab3a..a6c4f2304c2c12f83a6e98c904f98a5d5b69d749 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
index 1f084443bd991f608504ca20b38f6c6637d4dd54..de2a350e23120b685ebffcfdcf04985dc7b0a6d6 100644 (file)
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
index 4e5b714bded7c93f9829822ca4d774192a5697c5..91b4bd27caa8124b8f56d429b3fc82ed0a322ca6 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
index 08fc51e8a8b57d86b1b6e95ee49ea70e976c6953..ee2f8f6238b592165f4fce97680269b3e4ba93b3 100644 (file)
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: change env to "gnu" when cfg_target_abi becomes stable
             env: "gnueabihf".to_string(),
             features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
index b109aa1e1ab152ab9296b71247ff7d95f5295f71..b046819d4d78442c0a0aa9e16240630fbe30e415 100644 (file)
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: remove env when cfg_target_abi becomes stable
             env: "eabihf".to_string(),
             features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
index 821080ec07de8f370dad99885073d2471ce466ea..55956f3bad4fa7cad5be88bb6b8c4b2aa6977ada 100644 (file)
@@ -17,6 +17,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string(),
             max_atomic_width: Some(64),
             ..base
index 190d3bb691aab8a8ab63d3cc79f2938a18b67c6a..fbfb1c27681eaa81de06c6b5191fef2711f72637 100644 (file)
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: change env to "gnu" when cfg_target_abi becomes stable
             env: "gnueabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
index 088a8cf753402ac32b6987533828ad742cc71066..0a3b8033dd17ccd58497a497ed6619248afceb04 100644 (file)
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
index 521053ec2d3178f76c4cd6d13bfe3b4fc09cc52b..662b81cae3e65acbdaff42f546ac613f77e77815 100644 (file)
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
index 0ee2c3e45e0b1d538c2ce9c7092d9f80d70ecfb1..c0fd1de17cfdd976637d85ac763e4b0c04976a26 100644 (file)
@@ -16,6 +16,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
index a6ce382c7a6661caa20b80d433af52ff6ddc11df..67ff7999dea856f51e959c434aa6bcdcc66f6853 100644 (file)
@@ -15,6 +15,7 @@ pub fn target() -> Target {
         // Most of these settings are copied from the armv7_unknown_linux_gnueabihf
         // target.
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
index e509dcaddaa371de692697c9251181c870f2e8c1..60a552b018d69fab91a9f49a0056deefd82dc842 100644 (file)
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: remove env when cfg_target_abi becomes stable
             env: "eabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
index 0aabf2fe48669915b949a5c8edb3f6b17c4e16d0..27d404b101f3a4de12b5e7625a5d1cdd40c52526 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
index bd703ee3e45e4f78bc61900428b9116342fdb3c3..8bff60e9ed99a64f5f4ca87f7558ac4222441b8c 100644 (file)
@@ -18,6 +18,7 @@
 
 pub fn target() -> Target {
     let opts = TargetOptions {
+        abi: "eabi".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         linker: Some("rust-lld".to_owned()),
         features: "+v7,+thumb2,+soft-float,-neon,+strict-align".to_string(),
index ad86ae1cedcc012ebd5ca66c98eecb5c1ae8dc4e..ea2751e375e0b6078145c92c34fff2e1372d50d9 100644 (file)
@@ -9,6 +9,7 @@
 
 pub fn target() -> Target {
     let opts = TargetOptions {
+        abi: "eabihf".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         linker: Some("rust-lld".to_owned()),
         features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".to_string(),
index c07d6adc37eb5ceb0be80280a8387f0794a0d3ef..c695542805599b00a40a63f02a2e157c6043b8f3 100644 (file)
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
             linker: Some("rust-lld".to_owned()),
index fbf2f8e9b72786c7a71bbdf122647269ea01ae23..50c37021b74e9b9b93529e15e656999741d5080f 100644 (file)
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
             linker: Some("rust-lld".to_owned()),
index 53398539ac20f86019266c45276a8ebc3a1ef9e9..161a27ab6890b452edfe7ab5e53d0a7a626588ea 100644 (file)
@@ -8,6 +8,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             endian: Endian::Big,
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".to_string(),
index 329fbd22721770d0b62560d7b4f6f0f5167f114d..a898464569813aacf43f76e8e7ed30131ec82740 100644 (file)
@@ -12,6 +12,11 @@ pub fn target() -> Target {
         pointer_width: 64,
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
-        options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
+        options: TargetOptions {
+            abi: "abi64".to_string(),
+            endian: Endian::Big,
+            mcount: "_mcount".to_string(),
+            ..base
+        },
     }
 }
index d767705b0459b38c8b6c9c1a0c7d6359042deb4c..2f58560d45021944666871357b8fc472abe374a7 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".to_string(),
             features: "+mips64r2".to_string(),
index 766ed69df4bb8444ecb6ec8b4bedbcaa1ed0275b..01c34bc39924f1afdec9436a0d98f817471e2d30 100644 (file)
@@ -11,6 +11,6 @@ pub fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
-        options: TargetOptions { mcount: "_mcount".to_string(), ..base },
+        options: TargetOptions { abi: "abi64".to_string(), mcount: "_mcount".to_string(), ..base },
     }
 }
index 3bf837fbb411eff6e11ba5ad036753b865b72184..80a155a4865d7fc8b25781684e553cdc6a0bc10f 100644 (file)
@@ -8,6 +8,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             endian: Endian::Big,
             // NOTE(mips64r6) matches C toolchain
             cpu: "mips64r6".to_string(),
index 589d7acba68045f67f9d8b67b9bf52bbec49e667..58f9862715f73099b3881d86e202d756659ed3ed 100644 (file)
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             // NOTE(mips64r6) matches C toolchain
             cpu: "mips64r6".to_string(),
             features: "+mips64r6".to_string(),
index 0a5f8c17c63a6cc201a779482bc12ec9ca0ff66f..aa7dbeb16f21c2201be306696dc3d21c6dc3fed9 100644 (file)
@@ -1025,6 +1025,9 @@ pub struct TargetOptions {
     pub os: String,
     /// Environment name to use for conditional compilation (`target_env`). Defaults to "".
     pub env: String,
+    /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
+    /// or `"eabihf"`. Defaults to "".
+    pub abi: String,
     /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
     pub vendor: String,
     /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
@@ -1342,6 +1345,7 @@ fn default() -> TargetOptions {
             c_int_width: "32".to_string(),
             os: "none".to_string(),
             env: String::new(),
+            abi: String::new(),
             vendor: "unknown".to_string(),
             linker_flavor: LinkerFlavor::Gcc,
             linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
@@ -1919,6 +1923,7 @@ macro_rules! key {
         key!(c_int_width = "target-c-int-width");
         key!(os);
         key!(env);
+        key!(abi);
         key!(vendor);
         key!(linker_flavor, LinkerFlavor)?;
         key!(linker, optional);
@@ -2152,6 +2157,7 @@ macro_rules! target_option_val {
         target_option_val!(c_int_width, "target-c-int-width");
         target_option_val!(os);
         target_option_val!(env);
+        target_option_val!(abi);
         target_option_val!(vendor);
         target_option_val!(linker_flavor);
         target_option_val!(linker);
index 8d8f746f97f121d2f9838815ad214a385fad9606..362d8a104e448d5b89f8613167902592eff8bd32 100644 (file)
@@ -11,6 +11,11 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
         arch: "powerpc".to_string(),
-        options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
+        options: TargetOptions {
+            abi: "spe".to_string(),
+            endian: Endian::Big,
+            mcount: "_mcount".to_string(),
+            ..base
+        },
     }
 }
index 215f1a36227d79571181aa2739c3ef987d0f03f6..a2b85f7dd869afc4c4ff1b6f1b0874a17e6b49fe 100644 (file)
@@ -13,6 +13,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
         arch: "powerpc".to_string(),
         options: TargetOptions {
+            abi: "spe".to_string(),
             endian: Endian::Big,
             // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2
             features: "+secure-plt,+msync".to_string(),
index f996009f830633a15e3865641aa7a3c6b597063e..f86efd5d0f49081c7f0466f4cec7b643b0ad30e5 100644 (file)
@@ -26,6 +26,7 @@ pub fn target() -> Target {
          */
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             linker_flavor: LinkerFlavor::Ld,
             linker: Some("arm-none-eabi-ld".to_string()),
 
index 11c8bf46348738ed19fd75c389590771381b5877..40e3281060f9fa9f6608a9461cb915e33c1e8c78 100644 (file)
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them
             // with +strict-align.
             features: "+strict-align".to_string(),
index 141eb7e78b9e4902f6227273fe0db3f507448090..107474a86bbb28c496fc96d4e84afee42e0adc6c 100644 (file)
@@ -18,6 +18,10 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
 
-        options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+        options: TargetOptions {
+            abi: "eabi".to_string(),
+            max_atomic_width: Some(32),
+            ..super::thumb_base::opts()
+        },
     }
 }
index f5bd054f8598ca61ba69e1a1e91b4167fe24ed0c..65fc0db65285d8b936ceea752ff0d3e5dd0f50da 100644 (file)
@@ -18,6 +18,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
             // Cortex-M7 (vfp5)
             // `-d32` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
index 7af28cd9c9f9b9a2d001a1fde3369663a8fea099..ff939348c35f3aad006c06698a350dccd2df2d04 100644 (file)
@@ -9,6 +9,10 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
 
-        options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+        options: TargetOptions {
+            abi: "eabi".to_string(),
+            max_atomic_width: Some(32),
+            ..super::thumb_base::opts()
+        },
     }
 }
index 14020b88695ac15a762739e8f31bd40e21ed98df..fcb7b5d718cfbc8b7406446a549be51ea75feadc 100644 (file)
@@ -17,6 +17,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
             ..base
index 4042d5394167695326012dc6c4a6efbc414ab384..9d34d9ac874b0ee43d2369eb1aa0cb8a88074dba 100644 (file)
@@ -13,6 +13,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
index 318b864a9cf08ebcaf3b26319b7a8f35a98f4eb4..4e339cbd6be27e9a9129e2d1f3d0d36af5fe59ec 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf
         // target.
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
index a2200bc64e7d1bc01972bed9928c017b4927cb71..ef0f52d21992c0fdebb2780919593102f4c5f12b 100644 (file)
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them
             // with +strict-align.
             features: "+strict-align".to_string(),
index 67cdbab4860a3a6f469dfcbd7bb66eaaa465fd8b..dbd184debcb083f1d180b75cc8844bc64f42e0ba 100644 (file)
@@ -10,6 +10,10 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
 
-        options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+        options: TargetOptions {
+            abi: "eabi".to_string(),
+            max_atomic_width: Some(32),
+            ..super::thumb_base::opts()
+        },
     }
 }
index 49748f5ec6da4e7f8091b8aeac5fed1be8774854..3caf705421c6d35d6bab3ed6499ad854a59d381a 100644 (file)
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // If the Floating Point extension is implemented in the Cortex-M33
             // processor, the Cortex-M33 Technical Reference Manual states that
             // the FPU uses the FPv5 architecture, single-precision instructions
index 67d1be399b3f1f7141a8674f7676394f9830036a..86df816f10dc214d019700352596fdd6cef17f05 100644 (file)
@@ -25,6 +25,7 @@ pub fn opts() -> TargetOptions {
     late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
 
     TargetOptions {
+        abi: "uwp".to_string(),
         vendor: "uwp".to_string(),
         executables: false,
         limit_rdylib_exports: false,
index b3fa5c22f98221127cf8b380e623d4eda5ce5241..7b56b468c28ed2a2050297f28775d36ba177fbea 100644 (file)
@@ -3,6 +3,7 @@
 pub fn opts() -> TargetOptions {
     let mut opts = super::windows_msvc_base::opts();
 
+    opts.abi = "uwp".to_string();
     opts.vendor = "uwp".to_string();
     let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()];
     opts.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
index 06eb33d8d82e97d1f2750c406d31ad4d8f103e1a..59cd56ebcd535eb8d0a00d2c3f99b7c4e5a87d4e 100644 (file)
@@ -55,6 +55,7 @@ pub fn target() -> Target {
         os: "unknown".into(),
         env: "sgx".into(),
         vendor: "fortanix".into(),
+        abi: "fortanix".into(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         executables: true,
         linker: Some("rust-lld".to_owned()),
index 7b77ad668cd2ff4ec042d4e8e43839ed0f67ff65..1ffaa9b78c85ef6d7aae8e869f68d4965ef3fcb7 100644 (file)
@@ -3,6 +3,7 @@
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.cpu = "x86-64".to_string();
+    base.abi = "x32".to_string();
     base.max_atomic_width = Some(64);
     base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mx32".to_string());
     // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
index ffde9b79265a5b5bacd166aaad4ff247be71a37e..b0d644ae028ce3711036c58254eea6329fef759b 100644 (file)
@@ -168,6 +168,16 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
     }
 }
 
+fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+    let item = tcx.hir().expect_item(hir_id);
+    if let hir::ItemKind::Impl(impl_) = &item.kind {
+        impl_.constness
+    } else {
+        bug!("`impl_constness` called on {:?}", item);
+    }
+}
+
 /// Calculates the `Sized` constraint.
 ///
 /// In fact, there are only a few options for the types in the constraint:
@@ -535,6 +545,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
         instance_def_size_estimate,
         issue33140_self_ty,
         impl_defaultness,
+        impl_constness,
         conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
         ..*providers
     };
index ed62899c04ebb0a47b3b6caf091f0841b7c9e3e1..d101551085976077688375471a3592fcfe0567f5 100644 (file)
@@ -588,10 +588,17 @@ pub fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
                 fcx.write_method_call(self.call_expr.hir_id, method_callee);
             }
             None => {
-                span_bug!(
+                // This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
+                // lang items are not defined (issue #86238).
+                let mut err = fcx.inh.tcx.sess.struct_span_err(
                     self.call_expr.span,
-                    "failed to find an overloaded call trait for closure call"
+                    "failed to find an overloaded call trait for closure call",
                 );
+                err.help(
+                    "make sure the `fn`/`fn_mut`/`fn_once` lang items are defined \
+                     and have associated `call`/`call_mut`/`call_once` functions",
+                );
+                err.emit();
             }
         }
     }
index afa4d0f1c4de9067948fe5219c5e040df6f907a2..9e89804b74713bd8fdda10a1af3d4e3d2741ae95 100644 (file)
@@ -1456,11 +1456,15 @@ fn report_return_mismatched_types<'a>(
                 expected.is_unit(),
                 pointing_at_return_type,
             ) {
-                // If the block is from an external macro, then do not suggest
-                // adding a semicolon, because there's nowhere to put it.
-                // See issue #81943.
+                // If the block is from an external macro or try (`?`) desugaring, then
+                // do not suggest adding a semicolon, because there's nowhere to put it.
+                // See issues #81943 and #87051.
                 if cond_expr.span.desugaring_kind().is_none()
                     && !in_external_macro(fcx.tcx.sess, cond_expr.span)
+                    && !matches!(
+                        cond_expr.kind,
+                        hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
+                    )
                 {
                     err.span_label(cond_expr.span, "expected this to be `()`");
                     if expr.can_have_side_effects() {
index 00164c631b305799cd760426cdfda0f08c752433..dcafaae2f5b493a4a858462f589cc52ade71e76b 100644 (file)
@@ -12,7 +12,7 @@ impl bool {
     /// assert_eq!(false.then_some(0), None);
     /// assert_eq!(true.then_some(0), Some(0));
     /// ```
-    #[unstable(feature = "bool_to_option", issue = "64260")]
+    #[unstable(feature = "bool_to_option", issue = "80967")]
     #[inline]
     pub fn then_some<T>(self, t: T) -> Option<T> {
         if self { Some(t) } else { None }
index 3dfbd98fa6c7bf4c1929209eb4a7c82e7d883679..5122421ea8c852fdef7afbbba7c3f58075f49a0f 100644 (file)
@@ -79,7 +79,7 @@
 /// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
 /// let mut x = MaybeUninit::<&i32>::uninit();
 /// // Set it to a valid value.
-/// unsafe { x.as_mut_ptr().write(&0); }
+/// x.write(&0);
 /// // Extract the initialized data -- this is only allowed *after* properly
 /// // initializing `x`!
 /// let x = unsafe { x.assume_init() };
 ///     // this loop, we have a memory leak, but there is no memory safety
 ///     // issue.
 ///     for elem in &mut data[..] {
-///         *elem = MaybeUninit::new(vec![42]);
+///         elem.write(vec![42]);
 ///     }
 ///
 ///     // Everything is initialized. Transmute the array to the
 /// let mut data_len: usize = 0;
 ///
 /// for elem in &mut data[0..500] {
-///     *elem = MaybeUninit::new(String::from("hello"));
+///     elem.write(String::from("hello"));
 ///     data_len += 1;
 /// }
 ///
@@ -410,7 +410,7 @@ pub fn zeroed() -> MaybeUninit<T> {
     /// (now safely initialized) contents of `self`.
     ///
     /// As the content is stored inside a `MaybeUninit`, the destructor is not
-    /// ran for the inner data if the MaybeUninit leaves scope without a call to
+    /// run for the inner data if the MaybeUninit leaves scope without a call to
     /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
     /// the mutable reference returned by this function needs to keep this in
     /// mind. The safety model of Rust regards leaks as safe, but they are
@@ -426,7 +426,6 @@ pub fn zeroed() -> MaybeUninit<T> {
     /// Correct usage of this method:
     ///
     /// ```rust
-    /// #![feature(maybe_uninit_extra)]
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<Vec<u8>>::uninit();
@@ -445,7 +444,6 @@ pub fn zeroed() -> MaybeUninit<T> {
     /// This usage of the method causes a leak:
     ///
     /// ```rust
-    /// #![feature(maybe_uninit_extra)]
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<String>::uninit();
@@ -456,8 +454,38 @@ pub fn zeroed() -> MaybeUninit<T> {
     /// // x is initialized now:
     /// let s = unsafe { x.assume_init() };
     /// ```
-    #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
-    #[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")]
+    ///
+    /// This method can be used to avoid unsafe in some cases. The example below
+    /// shows a part of an implementation of a fixed sized arena that lends out
+    /// pinned references.
+    /// With `write`, we can avoid the need to write through a raw pointer:
+    ///
+    /// ```rust
+    /// #![feature(maybe_uninit_extra)]
+    /// use core::pin::Pin;
+    /// use core::mem::MaybeUninit;
+    ///
+    /// struct PinArena<T> {
+    ///     memory: Box<[MaybeUninit<T>]>,
+    ///     len: usize,
+    /// }
+    ///
+    /// impl <T> PinArena<T> {
+    ///     pub fn capacity(&self) -> usize {
+    ///         self.memory.len()
+    ///     }
+    ///     pub fn push(&mut self, val: T) -> Pin<&mut T> {
+    ///         if self.len >= self.capacity() {
+    ///             panic!("Attempted to push to a full pin arena!");
+    ///         }
+    ///         let ref_ = self.memory[self.len].write(val);
+    ///         self.len += 1;
+    ///         unsafe { Pin::new_unchecked(ref_) }
+    ///     }
+    /// }
+    /// ```
+    #[stable(feature = "maybe_uninit_write", since = "1.55.0")]
+    #[rustc_const_unstable(feature = "const_maybe_uninit_write", issue = "63567")]
     #[inline(always)]
     pub const fn write(&mut self, val: T) -> &mut T {
         *self = MaybeUninit::new(val);
@@ -478,7 +506,7 @@ pub const fn write(&mut self, val: T) -> &mut T {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
+    /// x.write(vec![0, 1, 2]);
     /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
     /// let x_vec = unsafe { &*x.as_ptr() };
     /// assert_eq!(x_vec.len(), 3);
@@ -515,7 +543,7 @@ pub const fn as_ptr(&self) -> *const T {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
+    /// x.write(vec![0, 1, 2]);
     /// // Create a reference into the `MaybeUninit<Vec<u32>>`.
     /// // This is okay because we initialized it.
     /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
@@ -574,7 +602,7 @@ pub const fn as_mut_ptr(&mut self) -> *mut T {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<bool>::uninit();
-    /// unsafe { x.as_mut_ptr().write(true); }
+    /// x.write(true);
     /// let x_init = unsafe { x.assume_init() };
     /// assert_eq!(x_init, true);
     /// ```
@@ -723,7 +751,7 @@ pub unsafe fn assume_init_drop(&mut self) {
     ///
     /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
     /// // Initialize `x`:
-    /// unsafe { x.as_mut_ptr().write(vec![1, 2, 3]); }
+    /// x.write(vec![1, 2, 3]);
     /// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
     /// // create a shared reference to it:
     /// let x: &Vec<u32> = unsafe {
@@ -897,9 +925,9 @@ pub unsafe fn assume_init_drop(&mut self) {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
-    /// array[0] = MaybeUninit::new(0);
-    /// array[1] = MaybeUninit::new(1);
-    /// array[2] = MaybeUninit::new(2);
+    /// array[0].write(0);
+    /// array[1].write(1);
+    /// array[2].write(2);
     ///
     /// // SAFETY: Now safe as we initialised all elements
     /// let array = unsafe {
index 21bd79611a5e519d6dc6ad6ee206d36c96502b64..e0cc6ad1d4231731b75470337b2c02260944d980 100644 (file)
@@ -324,18 +324,20 @@ pub fn powf(self, n: f32) -> f32 {
 
     /// Returns the square root of a number.
     ///
-    /// Returns NaN if `self` is a negative number.
+    /// Returns NaN if `self` is a negative number other than `-0.0`.
     ///
     /// # Examples
     ///
     /// ```
     /// let positive = 4.0_f32;
     /// let negative = -4.0_f32;
+    /// let negative_zero = -0.0_f32;
     ///
     /// let abs_difference = (positive.sqrt() - 2.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// assert!(negative.sqrt().is_nan());
+    /// assert!(negative_zero.sqrt() == negative_zero);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
index 8c8cf73741b512aa4fa1f76833f7518ef94f4b8f..7ed65b7dafec5ccb2c8d7214bf27c37e6c87c916 100644 (file)
@@ -324,18 +324,20 @@ pub fn powf(self, n: f64) -> f64 {
 
     /// Returns the square root of a number.
     ///
-    /// Returns NaN if `self` is a negative number.
+    /// Returns NaN if `self` is a negative number other than `-0.0`.
     ///
     /// # Examples
     ///
     /// ```
     /// let positive = 4.0_f64;
     /// let negative = -4.0_f64;
+    /// let negative_zero = -0.0_f64;
     ///
     /// let abs_difference = (positive.sqrt() - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// assert!(negative.sqrt().is_nan());
+    /// assert!(negative_zero.sqrt() == negative_zero);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
index 04f13cdeb88e353f629c282ddf8bc904bf3d684b..ae0cea985d77c9b8314044d7eaad75e2e07581a1 100644 (file)
@@ -209,32 +209,6 @@ impl<T> Cursor<T>
 where
     T: AsRef<[u8]>,
 {
-    /// Returns the remaining length.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(cursor_remaining)]
-    /// use std::io::Cursor;
-    ///
-    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
-    ///
-    /// assert_eq!(buff.remaining(), 5);
-    ///
-    /// buff.set_position(2);
-    /// assert_eq!(buff.remaining(), 3);
-    ///
-    /// buff.set_position(4);
-    /// assert_eq!(buff.remaining(), 1);
-    ///
-    /// buff.set_position(6);
-    /// assert_eq!(buff.remaining(), 0);
-    /// ```
-    #[unstable(feature = "cursor_remaining", issue = "86369")]
-    pub fn remaining(&self) -> u64 {
-        (self.inner.as_ref().len() as u64).checked_sub(self.pos).unwrap_or(0)
-    }
-
     /// Returns the remaining slice.
     ///
     /// # Examples
index 9daeee711adea59b136c1f3433dda234f3ae8561..ad8975c03f17564228ef611170eeabe27d08095e 100644 (file)
 pub use self::stdio::set_output_capture;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
 pub use self::stdio::{stderr_locked, stdin_locked, stdout_locked};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{StderrLock, StdinLock, StdoutLock};
index 293f0e31ce050e293a2fc9288dce34f3d9652570..206687e38fb9cfc402121d3c24c000124092102e 100644 (file)
@@ -347,7 +347,7 @@ pub fn stdin() -> Stdin {
 ///     Ok(())
 /// }
 /// ```
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
 pub fn stdin_locked() -> StdinLock<'static> {
     stdin().into_locked()
 }
@@ -442,7 +442,7 @@ fn lock_any<'a>(&self) -> StdinLock<'a> {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "stdio_locked", issue = "none")]
+    #[unstable(feature = "stdio_locked", issue = "86845")]
     pub fn into_locked(self) -> StdinLock<'static> {
         self.lock_any()
     }
@@ -668,7 +668,7 @@ pub fn stdout() -> Stdout {
 ///     Ok(())
 /// }
 /// ```
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
 pub fn stdout_locked() -> StdoutLock<'static> {
     stdout().into_locked()
 }
@@ -745,7 +745,7 @@ fn lock_any<'a>(&self) -> StdoutLock<'a> {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "stdio_locked", issue = "none")]
+    #[unstable(feature = "stdio_locked", issue = "86845")]
     pub fn into_locked(self) -> StdoutLock<'static> {
         self.lock_any()
     }
@@ -945,7 +945,7 @@ pub fn stderr() -> Stderr {
 ///     Ok(())
 /// }
 /// ```
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
 pub fn stderr_locked() -> StderrLock<'static> {
     stderr().into_locked()
 }
@@ -1005,7 +1005,7 @@ fn lock_any<'a>(&self) -> StderrLock<'a> {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "stdio_locked", issue = "none")]
+    #[unstable(feature = "stdio_locked", issue = "86845")]
     pub fn into_locked(self) -> StderrLock<'static> {
         self.lock_any()
     }
index 13ee909afd5e408897a32d1a23395dd0efe5629e..8a1b6df0dafe34910e2631733e8cb4642c7ddb65 100644 (file)
@@ -139,11 +139,17 @@ fn run($sel, $builder: &Builder<'_>) {
 
 install!((self, builder, _config),
     Docs, "src/doc", _config.docs, only_hosts: false, {
-        let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs");
-        install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
+        if let Some(tarball) = builder.ensure(dist::Docs { host: self.target }) {
+            install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
+        } else {
+            panic!("docs are not available to install, \
+                check that `build.docs` is true in `config.toml`");
+        }
     };
     Std, "library/std", true, only_hosts: false, {
         for target in &builder.targets {
+            // `expect` should be safe, only None when host != build, but this
+            // only runs when host == build
             let tarball = builder.ensure(dist::Std {
                 compiler: self.compiler,
                 target: *target
@@ -165,10 +171,15 @@ fn run($sel, $builder: &Builder<'_>) {
         }
     };
     RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, {
-        let tarball = builder
-            .ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
-            .expect("missing rust-analyzer");
-        install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
+        if let Some(tarball) =
+            builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
+        {
+            install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
+        } else {
+            builder.info(
+                &format!("skipping Install rust-analyzer stage{} ({})", self.compiler.stage, self.target),
+            );
+        }
     };
     Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
         let tarball = builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
@@ -212,6 +223,8 @@ fn run($sel, $builder: &Builder<'_>) {
         }
     };
     Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
+        // `expect` should be safe, only None with host != build, but this
+        // only uses the `build` compiler
         let tarball = builder.ensure(dist::Analysis {
             // Find the actual compiler (handling the full bootstrap option) which
             // produced the save-analysis data because that data isn't copied
index b967b6dbd2daebc0acc2bf7cb110d048973821be..0be42d9b2348623abf72d4c256df3a4966d8a4fb 100644 (file)
@@ -99,6 +99,10 @@ fn dir_is_empty(dir: &Path) -> bool {
         t!(std::fs::read_dir(dir)).next().is_none()
     }
 
+    if !build.config.submodules {
+        return;
+    }
+
     // NOTE: The check for the empty directory is here because when running x.py
     // the first time, the llvm submodule won't be checked out. Check it out
     // now so we can build it.
index e4d6a3f587b0526eec7eb0b5cf824e0a6bf6b6e0..61ffae47e2ad02a24bc1d2d8afade03f34e1509c 100644 (file)
@@ -907,27 +907,25 @@ fn run(self, builder: &Builder<'_>) {
         // We remove existing folder to be sure there won't be artifacts remaining.
         let _ = fs::remove_dir_all(&out_dir);
 
-        let mut nb_generated = 0;
+        let src_path = "src/test/rustdoc-gui/src";
         // We generate docs for the libraries present in the rustdoc-gui's src folder.
-        let libs_dir = builder.build.src.join("src/test/rustdoc-gui/src");
-        for entry in libs_dir.read_dir().expect("read_dir call failed") {
-            let entry = entry.expect("invalid entry");
-            let path = entry.path();
-            if path.extension().map(|e| e == "rs").unwrap_or(false) {
-                let mut command = builder.rustdoc_cmd(self.compiler);
-                command.arg(path).arg("-o").arg(&out_dir);
-                builder.run(&mut command);
-                nb_generated += 1;
-            }
-        }
-        assert!(nb_generated > 0, "no documentation was generated...");
+        let mut cargo = Command::new(&builder.initial_cargo);
+        cargo
+            .arg("doc")
+            .arg("--workspace")
+            .arg("--target-dir")
+            .arg(&out_dir)
+            .env("RUSTDOC", builder.rustdoc(self.compiler))
+            .env("RUSTC", builder.rustc(self.compiler))
+            .current_dir(&builder.build.src.join(src_path));
+        builder.run(&mut cargo);
 
         // We now run GUI tests.
         let mut command = Command::new(&nodejs);
         command
             .arg(builder.build.src.join("src/tools/rustdoc-gui/tester.js"))
             .arg("--doc-folder")
-            .arg(out_dir)
+            .arg(out_dir.join("doc"))
             .arg("--tests-folder")
             .arg(builder.build.src.join("src/test/rustdoc-gui"));
         for path in &builder.paths {
index 247b539652b15971a49fff3ab396142fb1418319..42fda98bc7a4b1a9e02e9c665d155bb60bd6f4cb 100644 (file)
@@ -69,8 +69,6 @@ COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
 RUN ./build-gcc.sh && apt-get remove -y gcc g++
 
 COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/
-# Build Python 2.7 needed for Clang 10.
-RUN ./build-python.sh 2.7.12
 # Build Python 3 needed for LLVM 12.
 RUN ./build-python.sh 3.9.1
 
@@ -97,7 +95,7 @@ ENV RUST_CONFIGURE_ARGS \
       --build=i686-unknown-linux-gnu \
       --set llvm.ninja=false \
       --set rust.jemalloc
-ENV SCRIPT python2.7 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS
+ENV SCRIPT python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS
 ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang
 
 # This was added when we switched from gcc to clang. It's not clear why this is
index 4dd4378f196922bbb97ebf809e61cfd869cb976d..8242e091cd4c7890999140b6762762cb81f40cff 100644 (file)
@@ -69,8 +69,6 @@ COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
 RUN ./build-gcc.sh && apt-get remove -y gcc g++
 
 COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/
-# Build Python 2.7 needed for Clang 10.
-RUN ./build-python.sh 2.7.12
 # Build Python 3 needed for LLVM 12.
 RUN ./build-python.sh 3.9.1
 
@@ -102,7 +100,7 @@ ENV RUST_CONFIGURE_ARGS \
       --set llvm.thin-lto=true \
       --set llvm.ninja=false \
       --set rust.jemalloc
-ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist \
+ENV SCRIPT ../src/ci/pgo.sh python3 ../x.py dist \
     --host $HOSTS --target $HOSTS \
     --include-default-paths \
     src/tools/build-manifest
index ed0b5c85f7ca9e9706c0b4a376d4c516d79112da..b5378244b793c6cd559b159c19241fed823f8c62 100755 (executable)
@@ -4,14 +4,16 @@ set -ex
 
 source shared.sh
 
-curl https://ftp.gnu.org/gnu/binutils/binutils-2.25.1.tar.bz2 | tar xfj -
+VERSION=2.26.1
+
+curl https://ftp.gnu.org/gnu/binutils/binutils-$VERSION.tar.bz2 | tar xfj -
 
 mkdir binutils-build
 cd binutils-build
-hide_output ../binutils-2.25.1/configure --prefix=/rustroot
-hide_output make -j10
+hide_output ../binutils-$VERSION/configure --prefix=/rustroot
+hide_output make -j$(nproc)
 hide_output make install
 
 cd ..
 rm -rf binutils-build
-rm -rf binutils-2.25.1
+rm -rf binutils-$VERSION
index 969443ac0949bf6ab837373bccc03dea2bb6de58..40a637616d35f1fe434bac93a88a19f3a68b382a 100755 (executable)
@@ -4,7 +4,7 @@ set -ex
 
 source shared.sh
 
-LLVM=llvmorg-10.0.0
+LLVM=llvmorg-12.0.1
 
 mkdir llvm-project
 cd llvm-project
@@ -30,7 +30,7 @@ hide_output \
       -DLLVM_ENABLE_PROJECTS="clang;lld" \
       -DC_INCLUDE_DIRS="$INC"
 
-hide_output make -j10
+hide_output make -j$(nproc)
 hide_output make install
 
 cd ../..
index e17831a1afee56da93229799ff3ac6ae2113c005..2f6b1fa9b8e3e657c344943d2adb07e1fac28ead 100755 (executable)
@@ -9,7 +9,7 @@ curl -L https://github.com/Kitware/CMake/releases/download/v$CMAKE/cmake-$CMAKE.
 mkdir cmake-build
 cd cmake-build
 hide_output ../cmake-$CMAKE/configure --prefix=/rustroot
-hide_output make -j10
+hide_output make -j$(nproc)
 hide_output make install
 
 cd ..
index a60c6be9f322211ad3be6371c2809dc1169236cc..6efa789756619fcaf3e318159da75bf2a1051c9b 100755 (executable)
@@ -30,7 +30,7 @@ hide_output ../curl-$VERSION/configure \
       --disable-rtsp \
       --disable-ldaps \
       --disable-ldap
-hide_output make -j10
+hide_output make -j$(nproc)
 hide_output make install
 
 cd ..
index 25f99596099f3ec3cd6ed0f1f0e1956ea9882047..3a03eb2bdc8384557067160e5ece530535a21f0d 100755 (executable)
@@ -32,7 +32,7 @@ hide_output ../gcc-$GCC/configure \
     --prefix=/rustroot \
     --enable-languages=c,c++ \
     --disable-gnu-unique-object
-hide_output make -j10
+hide_output make -j$(nproc)
 hide_output make install
 ln -s gcc /rustroot/bin/cc
 
index d8f6bdb51b8d5bad24e0995de30e5babde6d0fa9..34bbe19d2fac331cec92db088c24190512273174 100755 (executable)
@@ -14,7 +14,7 @@ curl $URL | tar xzf -
 
 cd openssl-$VERSION
 hide_output ./config --prefix=/rustroot shared -fPIC
-hide_output make -j10
+hide_output make -j$(nproc)
 hide_output make install
 cd ..
 rm -rf openssl-$VERSION
index 970d67b6db3ddc495ef6923411348eb8d045da42..9a203beadd1033ef903be18f94af77839bc923ad 100755 (executable)
@@ -14,7 +14,7 @@ cd python-build
 # than that fairly normal.
 CFLAGS='-I /rustroot/include' LDFLAGS='-L /rustroot/lib -L /rustroot/lib64' \
     hide_output ../Python-$VERSION/configure --prefix=/rustroot
-hide_output make -j10
+hide_output make -j$(nproc)
 hide_output make install
 
 cd ..
index d2962179eea31283980704df80c3d0f2c5b06562..aa009a4eac6af877e4e4dc005a2fd9abd19d2f2b 100755 (executable)
@@ -4,7 +4,7 @@ set -euxo pipefail
 
 rm -rf /tmp/rustc-pgo
 
-python2.7 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
+python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
     --stage 2 library/std --rust-profile-generate=/tmp/rustc-pgo
 
 RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
index fdeea17ed1124bde8b8453bd4c6b0a6035079074..5e09cdc5cf5cd1e7c4efbf283aeedaf3bcd3f108 100644 (file)
@@ -1,4 +1,4 @@
 % The Rust Reference has moved
 
 We've split up the reference into chapters. Please find it at its new
-home [here](reference/index.html).
+home [here](https://doc.rust-lang.org/stable/reference/introduction.html).
index c257d362694feffdb4d225a591fa0f7c1c5f702c..8f74a48547d8833c0f88a12e6ec8ac111cda1af4 100644 (file)
@@ -98,7 +98,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     visibility: Inherited,
                     def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
                     kind: box ImplItem(Impl {
-                        span: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
+                        span: Span::from_rustc_span(self.cx.tcx.def_span(impl_def_id)),
                         unsafety: hir::Unsafety::Normal,
                         generics: (
                             self.cx.tcx.generics_of(impl_def_id),
index 175c7facfdbeb7c89430ba66504c8239fcb6c307..b3b89e6e673a29f1a438e3ce3d6d9ebaeab5e17b 100644 (file)
@@ -41,6 +41,7 @@
 crate fn try_inline(
     cx: &mut DocContext<'_>,
     parent_module: DefId,
+    import_def_id: Option<DefId>,
     res: Res,
     name: Symbol,
     attrs: Option<Attrs<'_>>,
             clean::ConstantItem(build_const(cx, did))
         }
         Res::Def(DefKind::Macro(kind), did) => {
-            let mac = build_macro(cx, did, name);
+            let mac = build_macro(cx, did, name, import_def_id);
 
             let type_kind = match kind {
                 MacroKind::Bang => ItemType::Macro,
 
     let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone);
     cx.inlined.insert(did.into());
-    ret.push(clean::Item::from_def_id_and_attrs_and_parts(
-        did,
-        Some(name),
-        kind,
-        box attrs,
-        cx,
-        cfg,
-    ));
+    let mut item =
+        clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box attrs, cx, cfg);
+    if let Some(import_def_id) = import_def_id {
+        // The visibility needs to reflect the one from the reexport and not from the "source" DefId.
+        item.visibility = cx.tcx.visibility(import_def_id).clean(cx);
+    }
+    ret.push(item);
     Some(ret)
 }
 
@@ -509,7 +509,9 @@ fn build_module(
                     )),
                     cfg: None,
                 });
-            } else if let Some(i) = try_inline(cx, did, item.res, item.ident.name, None, visited) {
+            } else if let Some(i) =
+                try_inline(cx, did, None, item.res, item.ident.name, None, visited)
+            {
                 items.extend(i)
             }
         }
@@ -543,21 +545,26 @@ fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::St
     }
 }
 
-fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
-    let imported_from = cx.tcx.crate_name(did.krate);
-    match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
-        LoadedMacro::MacroDef(def, _) => {
-            if let ast::ItemKind::MacroDef(ref def) = def.kind {
-                let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
-                let matchers = tts.chunks(4).map(|arm| &arm[0]);
-
-                let source = format!(
-                    "macro_rules! {} {{\n{}}}",
-                    name,
-                    utils::render_macro_arms(matchers, ";")
-                );
-
-                clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
+fn build_macro(
+    cx: &mut DocContext<'_>,
+    def_id: DefId,
+    name: Symbol,
+    import_def_id: Option<DefId>,
+) -> clean::ItemKind {
+    let imported_from = cx.tcx.crate_name(def_id.krate);
+    match cx.enter_resolver(|r| r.cstore().load_macro_untracked(def_id, cx.sess())) {
+        LoadedMacro::MacroDef(item_def, _) => {
+            if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
+                clean::MacroItem(clean::Macro {
+                    source: utils::display_macro_source(
+                        cx,
+                        name,
+                        def,
+                        def_id,
+                        cx.tcx.visibility(import_def_id.unwrap_or(def_id)),
+                    ),
+                    imported_from: Some(imported_from),
+                })
             } else {
                 unreachable!()
             }
index cc086427dd0cd09032a3e98bce63fa277fa99c90..80aaae1580114752da8ebe3a610719c814ce5624 100644 (file)
@@ -227,20 +227,6 @@ fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
     }
 }
 
-impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Option<Vec<GenericBound>> {
-        let mut v = Vec::new();
-        v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives));
-        v.extend(self.types().map(|t| {
-            GenericBound::TraitBound(
-                PolyTrait { trait_: t.clean(cx), generic_params: Vec::new() },
-                hir::TraitBoundModifier::None,
-            )
-        }));
-        if !v.is_empty() { Some(v) } else { None }
-    }
-}
-
 impl Clean<Lifetime> for hir::Lifetime {
     fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime {
         let def = cx.tcx.named_region(self.hir_id);
@@ -296,12 +282,6 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Constant {
     }
 }
 
-impl Clean<Lifetime> for ty::GenericParamDef {
-    fn clean(&self, _cx: &mut DocContext<'_>) -> Lifetime {
-        Lifetime(self.name)
-    }
-}
-
 impl Clean<Option<Lifetime>> for ty::RegionKind {
     fn clean(&self, _cx: &mut DocContext<'_>) -> Option<Lifetime> {
         match *self {
@@ -1764,12 +1744,6 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
     }
 }
 
-impl Clean<Span> for rustc_span::Span {
-    fn clean(&self, _cx: &mut DocContext<'_>) -> Span {
-        Span::from_rustc_span(*self)
-    }
-}
-
 impl Clean<Path> for hir::Path<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Path {
         Path {
@@ -1997,6 +1971,7 @@ fn clean_extern_crate(
         if let Some(items) = inline::try_inline(
             cx,
             cx.tcx.parent_module(krate.hir_id()).to_def_id(),
+            Some(krate.def_id.to_def_id()),
             res,
             name,
             Some(attrs),
@@ -2052,7 +2027,8 @@ fn clean_use_statement(
     // forcefully don't inline if this is not public or if the
     // #[doc(no_inline)] attribute is present.
     // Don't inline doc(hidden) imports so they can be stripped at a later stage.
-    let mut denied = !import.vis.node.is_pub()
+    let mut denied = !(import.vis.node.is_pub()
+        || (cx.render_options.document_private && import.vis.node.is_pub_restricted()))
         || pub_underscore
         || attrs.iter().any(|a| {
             a.has_name(sym::doc)
@@ -2088,17 +2064,19 @@ fn clean_use_statement(
         }
         if !denied {
             let mut visited = FxHashSet::default();
+            let import_def_id = import.def_id.to_def_id();
 
             if let Some(mut items) = inline::try_inline(
                 cx,
                 cx.tcx.parent_module(import.hir_id()).to_def_id(),
+                Some(import_def_id),
                 path.res,
                 name,
                 Some(attrs),
                 &mut visited,
             ) {
                 items.push(Item::from_def_id_and_parts(
-                    import.def_id.to_def_id(),
+                    import_def_id,
                     None,
                     ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
                     cx,
@@ -2157,37 +2135,15 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
     fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let (item, renamed) = self;
         let name = renamed.unwrap_or(item.ident.name);
-        let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>();
-        // Extract the macro's matchers. They represent the "interface" of the macro.
-        let matchers = tts.chunks(4).map(|arm| &arm[0]);
-
-        let source = if item.ast.macro_rules {
-            format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
-        } else {
-            let vis = item.vis.clean(cx);
-            let def_id = item.def_id.to_def_id();
-
-            if matchers.len() <= 1 {
-                format!(
-                    "{}macro {}{} {{\n    ...\n}}",
-                    vis.to_src_with_space(cx.tcx, def_id),
-                    name,
-                    matchers.map(render_macro_matcher).collect::<String>(),
-                )
-            } else {
-                format!(
-                    "{}macro {} {{\n{}}}",
-                    vis.to_src_with_space(cx.tcx, def_id),
-                    name,
-                    render_macro_arms(matchers, ","),
-                )
-            }
-        };
+        let def_id = item.def_id.to_def_id();
 
         Item::from_hir_id_and_parts(
             item.hir_id(),
             Some(name),
-            MacroItem(Macro { source, imported_from: None }),
+            MacroItem(Macro {
+                source: display_macro_source(cx, name, &item.ast, def_id, &item.vis),
+                imported_from: None,
+            }),
             cx,
         )
     }
@@ -2211,22 +2167,3 @@ fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind {
         }
     }
 }
-
-enum SimpleBound {
-    TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier),
-    Outlives(Lifetime),
-}
-
-impl From<GenericBound> for SimpleBound {
-    fn from(bound: GenericBound) -> Self {
-        match bound.clone() {
-            GenericBound::Outlives(l) => SimpleBound::Outlives(l),
-            GenericBound::TraitBound(t, mod_) => match t.trait_ {
-                Type::ResolvedPath { path, .. } => {
-                    SimpleBound::TraitBound(path.segments, Vec::new(), t.generic_params, mod_)
-                }
-                _ => panic!("Unexpected bound {:?}", bound),
-            },
-        }
-    }
-}
index fb46b81102caaf0e3b024cb56a4c150a53a1f397..7ae602c8033f8f65530936397aca0a6553b3d557 100644 (file)
@@ -3,10 +3,12 @@
 use crate::clean::{
     inline, Clean, Crate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime,
     Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding,
+    Visibility,
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
 
+use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenTree;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -577,3 +579,37 @@ pub(super) fn render_macro_arms<'a>(
 pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
     rustc_ast_pretty::pprust::tt_to_string(matcher)
 }
+
+pub(super) fn display_macro_source(
+    cx: &mut DocContext<'_>,
+    name: Symbol,
+    def: &ast::MacroDef,
+    def_id: DefId,
+    vis: impl Clean<Visibility>,
+) -> String {
+    let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
+    // Extract the spans of all matchers. They represent the "interface" of the macro.
+    let matchers = tts.chunks(4).map(|arm| &arm[0]);
+
+    if def.macro_rules {
+        format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
+    } else {
+        let vis = vis.clean(cx);
+
+        if matchers.len() <= 1 {
+            format!(
+                "{}macro {}{} {{\n    ...\n}}",
+                vis.to_src_with_space(cx.tcx, def_id),
+                name,
+                matchers.map(render_macro_matcher).collect::<String>(),
+            )
+        } else {
+            format!(
+                "{}macro {} {{\n{}}}",
+                vis.to_src_with_space(cx.tcx, def_id),
+                name,
+                render_macro_arms(matchers, ","),
+            )
+        }
+    }
+}
index eeac9d1a9db76365d87d810ba56b0c5962825ee1..f7073a8751fa18723622c06d15c6e26a29adae86 100644 (file)
@@ -133,7 +133,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
         clean::StructItem(ref s) => item_struct(buf, cx, item, s),
         clean::UnionItem(ref s) => item_union(buf, cx, item, s),
         clean::EnumItem(ref e) => item_enum(buf, cx, item, e),
-        clean::TypedefItem(ref t, _) => item_typedef(buf, cx, item, t),
+        clean::TypedefItem(ref t, is_associated) => item_typedef(buf, cx, item, t, is_associated),
         clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
         clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
         clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
@@ -837,9 +837,18 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean:
     render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
 }
 
-fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
+fn item_typedef(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    it: &clean::Item,
+    t: &clean::Typedef,
+    is_associated: bool,
+) {
     w.write_str("<pre class=\"rust typedef\">");
     render_attributes_in_pre(w, it, "");
+    if !is_associated {
+        write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
+    }
     write!(
         w,
         "type {}{}{where_clause} = {type_};</pre>",
index 98128878999e4b36460ae92848dcf20e04107b67..38ddbb3ad74278d68d2c9623fbdb46f7ca07b603 100644 (file)
@@ -683,6 +683,9 @@ function hideThemeButtonState() {
             });
         }
 
+        var currentNbImpls = implementors.getElementsByClassName("impl").length;
+        var traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent;
+        var baseIdName = "impl-" + traitName + "-";
         var libs = Object.getOwnPropertyNames(imp);
         for (var i = 0, llength = libs.length; i < llength; ++i) {
             if (libs[i] === window.currentCrate) { continue; }
@@ -705,6 +708,7 @@ function hideThemeButtonState() {
 
                 var code = document.createElement("code");
                 code.innerHTML = struct.text;
+                addClass(code, "in-band");
 
                 onEachLazy(code.getElementsByTagName("a"), function(elem) {
                     var href = elem.getAttribute("href");
@@ -714,12 +718,18 @@ function hideThemeButtonState() {
                     }
                 });
 
-                var display = document.createElement("h3");
+                var currentId = baseIdName + currentNbImpls;
+                var anchor = document.createElement("a");
+                anchor.href = "#" + currentId;
+                addClass(anchor, "anchor");
+
+                var display = document.createElement("div");
+                display.id = currentId;
                 addClass(display, "impl");
-                display.innerHTML = "<span class=\"in-band\"><table class=\"table-display\">" +
-                    "<tbody><tr><td><code>" + code.outerHTML + "</code></td><td></td></tr>" +
-                    "</tbody></table></span>";
+                display.appendChild(anchor);
+                display.appendChild(code);
                 list.appendChild(display);
+                currentNbImpls += 1;
             }
         }
     };
index a7fc0b831f410f5a91ee7eadb37592d398166cb1..76e7295bce329df295ae279b0748a9f4780d9768 100644 (file)
@@ -289,13 +289,6 @@ window.initSearch = function(rawSearchIndex) {
             };
         }
 
-        function getObjectNameFromId(id) {
-            if (typeof id === "number") {
-                return searchIndex[id].name;
-            }
-            return id;
-        }
-
         function checkGenerics(obj, val) {
             // The names match, but we need to be sure that all generics kinda
             // match as well.
@@ -306,10 +299,10 @@ window.initSearch = function(rawSearchIndex) {
                     var elems = Object.create(null);
                     var elength = obj[GENERICS_DATA].length;
                     for (var x = 0; x < elength; ++x) {
-                        if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
-                            elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+                        if (!elems[obj[GENERICS_DATA][x]]) {
+                            elems[obj[GENERICS_DATA][x]] = 0;
                         }
-                        elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
+                        elems[obj[GENERICS_DATA][x]] += 1;
                     }
                     var total = 0;
                     var done = 0;
@@ -318,7 +311,7 @@ window.initSearch = function(rawSearchIndex) {
                     var vlength = val.generics.length;
                     for (x = 0; x < vlength; ++x) {
                         var lev = MAX_LEV_DISTANCE + 1;
-                        var firstGeneric = getObjectNameFromId(val.generics[x]);
+                        var firstGeneric = val.generics[x];
                         var match = null;
                         if (elems[firstGeneric]) {
                             match = firstGeneric;
@@ -361,16 +354,16 @@ window.initSearch = function(rawSearchIndex) {
                             var elems = Object.create(null);
                             len = obj[GENERICS_DATA].length;
                             for (x = 0; x < len; ++x) {
-                                if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
-                                    elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+                                if (!elems[obj[GENERICS_DATA][x]]) {
+                                    elems[obj[GENERICS_DATA][x]] = 0;
                                 }
-                                elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
+                                elems[obj[GENERICS_DATA][x]] += 1;
                             }
 
                             var allFound = true;
                             len = val.generics.length;
                             for (x = 0; x < len; ++x) {
-                                firstGeneric = getObjectNameFromId(val.generics[x]);
+                                firstGeneric = val.generics[x];
                                 if (elems[firstGeneric]) {
                                     elems[firstGeneric] -= 1;
                                 } else {
index 64a9905b33f155406839e3ca9a640e9643a975fc..bc635190f4281047557df305da92ee074088509f 100644 (file)
@@ -269,9 +269,9 @@ fn opts() -> Vec<RustcOptGroup> {
     let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable;
     let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable;
     vec![
-        stable("h", |o| o.optflag("h", "help", "show this help message")),
-        stable("V", |o| o.optflag("V", "version", "print rustdoc's version")),
-        stable("v", |o| o.optflag("v", "verbose", "use verbose output")),
+        stable("h", |o| o.optflagmulti("h", "help", "show this help message")),
+        stable("V", |o| o.optflagmulti("V", "version", "print rustdoc's version")),
+        stable("v", |o| o.optflagmulti("v", "verbose", "use verbose output")),
         stable("r", |o| {
             o.optopt("r", "input-format", "the input type of the specified file", "[rust]")
         }),
@@ -309,14 +309,14 @@ fn opts() -> Vec<RustcOptGroup> {
             )
         }),
         stable("plugins", |o| o.optmulti("", "plugins", "removed", "PLUGINS")),
-        stable("no-default", |o| o.optflag("", "no-defaults", "don't run the default passes")),
+        stable("no-default", |o| o.optflagmulti("", "no-defaults", "don't run the default passes")),
         stable("document-private-items", |o| {
-            o.optflag("", "document-private-items", "document private items")
+            o.optflagmulti("", "document-private-items", "document private items")
         }),
         unstable("document-hidden-items", |o| {
-            o.optflag("", "document-hidden-items", "document items that have doc(hidden)")
+            o.optflagmulti("", "document-hidden-items", "document items that have doc(hidden)")
         }),
-        stable("test", |o| o.optflag("", "test", "run code examples as tests")),
+        stable("test", |o| o.optflagmulti("", "test", "run code examples as tests")),
         stable("test-args", |o| {
             o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS")
         }),
@@ -386,7 +386,7 @@ fn opts() -> Vec<RustcOptGroup> {
             o.optopt("", "markdown-playground-url", "URL to send code snippets to", "URL")
         }),
         stable("markdown-no-toc", |o| {
-            o.optflag("", "markdown-no-toc", "don't include table of contents")
+            o.optflagmulti("", "markdown-no-toc", "don't include table of contents")
         }),
         stable("e", |o| {
             o.optopt(
@@ -412,13 +412,13 @@ fn opts() -> Vec<RustcOptGroup> {
             )
         }),
         unstable("display-warnings", |o| {
-            o.optflag("", "display-warnings", "to print code warnings when testing doc")
+            o.optflagmulti("", "display-warnings", "to print code warnings when testing doc")
         }),
         stable("crate-version", |o| {
             o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
         }),
         unstable("sort-modules-by-appearance", |o| {
-            o.optflag(
+            o.optflagmulti(
                 "",
                 "sort-modules-by-appearance",
                 "sort modules by where they appear in the program, rather than alphabetically",
@@ -495,7 +495,7 @@ fn opts() -> Vec<RustcOptGroup> {
             o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG")
         }),
         unstable("disable-minification", |o| {
-            o.optflag("", "disable-minification", "Disable minification applied on JS files")
+            o.optflagmulti("", "disable-minification", "Disable minification applied on JS files")
         }),
         stable("warn", |o| o.optmulti("W", "warn", "Set lint warnings", "OPT")),
         stable("allow", |o| o.optmulti("A", "allow", "Set lint allowed", "OPT")),
@@ -523,7 +523,7 @@ fn opts() -> Vec<RustcOptGroup> {
             o.optopt("", "index-page", "Markdown file to be used as index page", "PATH")
         }),
         unstable("enable-index-page", |o| {
-            o.optflag("", "enable-index-page", "To enable generation of the index page")
+            o.optflagmulti("", "enable-index-page", "To enable generation of the index page")
         }),
         unstable("static-root-path", |o| {
             o.optopt(
@@ -535,7 +535,7 @@ fn opts() -> Vec<RustcOptGroup> {
             )
         }),
         unstable("disable-per-crate-search", |o| {
-            o.optflag(
+            o.optflagmulti(
                 "",
                 "disable-per-crate-search",
                 "disables generating the crate selector on the search box",
@@ -550,14 +550,14 @@ fn opts() -> Vec<RustcOptGroup> {
             )
         }),
         unstable("show-coverage", |o| {
-            o.optflag(
+            o.optflagmulti(
                 "",
                 "show-coverage",
                 "calculate percentage of public items with documentation",
             )
         }),
         unstable("enable-per-target-ignores", |o| {
-            o.optflag(
+            o.optflagmulti(
                 "",
                 "enable-per-target-ignores",
                 "parse ignore-foo for ignoring doctests on a per-target basis",
@@ -582,9 +582,9 @@ fn opts() -> Vec<RustcOptGroup> {
         unstable("test-builder", |o| {
             o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
         }),
-        unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")),
+        unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")),
         unstable("generate-redirect-map", |o| {
-            o.optflag(
+            o.optflagmulti(
                 "",
                 "generate-redirect-map",
                 "Generate JSON file at the top level instead of generating HTML redirection files",
@@ -598,9 +598,11 @@ fn opts() -> Vec<RustcOptGroup> {
                 "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
             )
         }),
-        unstable("no-run", |o| o.optflag("", "no-run", "Compile doctests without running them")),
+        unstable("no-run", |o| {
+            o.optflagmulti("", "no-run", "Compile doctests without running them")
+        }),
         unstable("show-type-layout", |o| {
-            o.optflag("", "show-type-layout", "Include the memory layout of types in the docs")
+            o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs")
         }),
     ]
 }
index 44a3faf6f7be26317fdb6961d4f61ac14c942622..21bd3ebd21bc838d86cd89f2c6ef0d52fbc87a97 100644 (file)
@@ -1610,6 +1610,8 @@ fn suggestion(self) -> Suggestion {
             return Suggestion::Macro;
         } else if kind == DefKind::Fn || kind == DefKind::AssocFn {
             return Suggestion::Function;
+        } else if kind == DefKind::Field {
+            return Suggestion::RemoveDisambiguator;
         }
 
         let prefix = match kind {
@@ -1674,6 +1676,8 @@ enum Suggestion {
     Function,
     /// `m!`
     Macro,
+    /// `foo` without any disambiguator
+    RemoveDisambiguator,
 }
 
 impl Suggestion {
@@ -1682,6 +1686,7 @@ fn descr(&self) -> Cow<'static, str> {
             Self::Prefix(x) => format!("prefix with `{}@`", x).into(),
             Self::Function => "add parentheses".into(),
             Self::Macro => "add an exclamation mark".into(),
+            Self::RemoveDisambiguator => "remove the disambiguator".into(),
         }
     }
 
@@ -1691,6 +1696,7 @@ fn as_help(&self, path_str: &str) -> String {
             Self::Prefix(prefix) => format!("{}@{}", prefix, path_str),
             Self::Function => format!("{}()", path_str),
             Self::Macro => format!("{}!", path_str),
+            Self::RemoveDisambiguator => path_str.into(),
         }
     }
 }
index 39c5555872cc5d379cc3535a31dc0cdac969466f..bdb386270f55cb8e95793daa296f27a95a6d4834 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 39c5555872cc5d379cc3535a31dc0cdac969466f
+Subproject commit bdb386270f55cb8e95793daa296f27a95a6d4834
index 08303a46d19299e590e59b1e1d38a74632d87bf2..013bf3baca45f1d18d321ba80ea4641bbc72ecbc 100644 (file)
@@ -6,6 +6,8 @@ all: default
        $(RUSTC) --target i686-pc-windows-msvc --print cfg | $(CGREP) msvc
        $(RUSTC) --target i686-apple-darwin --print cfg | $(CGREP) macos
        $(RUSTC) --target i686-unknown-linux-gnu --print cfg | $(CGREP) gnu
+       $(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) target_abi=
+       $(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) eabihf
 
 ifdef IS_WINDOWS
 default:
diff --git a/src/test/rustdoc-gui/implementors.goml b/src/test/rustdoc-gui/implementors.goml
new file mode 100644 (file)
index 0000000..a4db5ce
--- /dev/null
@@ -0,0 +1,16 @@
+// The goal of this test is to check that the external trait implementors, generated with JS,
+// have the same display than the "local" ones.
+goto: file://|DOC_PATH|/implementors/trait.Whatever.html
+assert: "#implementors-list"
+// There are supposed to be two implementors listed.
+assert-count: ("#implementors-list > .impl", 2)
+// Now we check that both implementors have an anchor, an ID and a similar DOM.
+assert: ("#implementors-list > .impl:nth-child(1) > a.anchor")
+assert-attribute: ("#implementors-list > .impl:nth-child(1)", {"id": "impl-Whatever"})
+assert-attribute: ("#implementors-list > .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever"})
+assert: "#implementors-list > .impl:nth-child(1) > code.in-band"
+
+assert: ("#implementors-list > .impl:nth-child(2) > a.anchor")
+assert-attribute: ("#implementors-list > .impl:nth-child(2)", {"id": "impl-Whatever-1"})
+assert-attribute: ("#implementors-list > .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"})
+assert: "#implementors-list > .impl:nth-child(2) > code.in-band"
diff --git a/src/test/rustdoc-gui/src/Cargo.lock b/src/test/rustdoc-gui/src/Cargo.lock
new file mode 100644 (file)
index 0000000..a72ccff
--- /dev/null
@@ -0,0 +1,18 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
+
+[[package]]
+name = "lib2"
+version = "0.1.0"
+dependencies = [
+ "implementors",
+]
+
+[[package]]
+name = "test_docs"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/Cargo.toml b/src/test/rustdoc-gui/src/Cargo.toml
new file mode 100644 (file)
index 0000000..9c8c0c6
--- /dev/null
@@ -0,0 +1,6 @@
+[workspace]
+members = [
+    "test_docs",
+    "lib2",
+    "implementors",
+]
diff --git a/src/test/rustdoc-gui/src/implementors/Cargo.toml b/src/test/rustdoc-gui/src/implementors/Cargo.toml
new file mode 100644 (file)
index 0000000..7ef1052
--- /dev/null
@@ -0,0 +1,7 @@
+[package]
+name = "implementors"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/implementors/lib.rs b/src/test/rustdoc-gui/src/implementors/lib.rs
new file mode 100644 (file)
index 0000000..4b2f696
--- /dev/null
@@ -0,0 +1,7 @@
+pub trait Whatever {
+    fn method() {}
+}
+
+pub struct Struct;
+
+impl Whatever for Struct {}
diff --git a/src/test/rustdoc-gui/src/lib.rs b/src/test/rustdoc-gui/src/lib.rs
deleted file mode 100644 (file)
index 3e753cb..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-//! The point of this crate is to be able to have enough different "kinds" of
-//! documentation generated so we can test each different features.
-
-#![crate_name = "test_docs"]
-#![feature(doc_keyword)]
-#![feature(doc_cfg)]
-
-use std::fmt;
-
-/// Basic function with some code examples:
-///
-/// ```
-/// println!("nothing fancy");
-/// ```
-///
-/// A failing to compile one:
-///
-/// ```compile_fail
-/// println!("where did my argument {} go? :'(");
-/// ```
-///
-/// An ignored one:
-///
-/// ```ignore (it's a test)
-/// Let's say I'm just some text will ya?
-/// ```
-pub fn foo() {}
-
-/// Just a normal struct.
-pub struct Foo;
-
-impl Foo {
-    #[must_use]
-    pub fn must_use(&self) -> bool {
-        true
-    }
-}
-
-/// Just a normal enum.
-#[doc(alias = "ThisIsAnAlias")]
-pub enum WhoLetTheDogOut {
-    /// Woof!
-    Woof,
-    /// Meoooooooow...
-    Meow,
-}
-
-/// Who doesn't love to wrap a `format!` call?
-pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
-    format!("{:?}", t)
-}
-
-/// Woohoo! A trait!
-pub trait AnotherOne {
-    /// Some func 3.
-    fn func3();
-
-    /// Some func 1.
-    fn func1();
-
-    fn another();
-    fn why_not();
-
-    /// Some func 2.
-    fn func2();
-
-    fn hello();
-}
-
-/// ```compile_fail
-/// whatever
-/// ```
-///
-/// Check for "i" signs in lists!
-///
-/// 1. elem 1
-/// 2. test 1
-///    ```compile_fail
-///    fn foo() {}
-///    ```
-/// 3. elem 3
-/// 4. ```ignore (it's a test)
-///    fn foo() {}
-///    ```
-/// 5. elem 5
-///
-/// Final one:
-///
-/// ```ignore (still a test)
-/// let x = 12;
-/// ```
-pub fn check_list_code_block() {}
-
-/// a thing with a label
-#[deprecated(since = "1.0.0", note = "text why this deprecated")]
-#[doc(cfg(unix))]
-pub fn replaced_function() {}
-
-pub enum AnEnum {
-    WithVariants { and: usize, sub: usize, variants: usize },
-}
-
-#[doc(keyword = "CookieMonster")]
-pub mod keyword {}
-
-/// Just some type alias.
-pub type SomeType = u32;
diff --git a/src/test/rustdoc-gui/src/lib2.rs b/src/test/rustdoc-gui/src/lib2.rs
deleted file mode 100644 (file)
index 77d384f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-pub mod module {
-    pub mod sub_module {
-        pub mod sub_sub_module {
-            pub fn foo() {}
-        }
-        pub fn bar() {}
-    }
-    pub fn whatever() {}
-}
-
-pub fn foobar() {}
-
-pub type Alias = u32;
-
-pub struct Foo {
-    pub x: Alias,
-}
-
-impl Foo {
-    pub fn a_method(&self) {}
-}
-
-pub trait Trait {
-    type X;
-    const Y: u32;
-
-    fn foo() {}
-}
-
-impl Trait for Foo {
-    type X = u32;
-    const Y: u32 = 0;
-}
diff --git a/src/test/rustdoc-gui/src/lib2/Cargo.toml b/src/test/rustdoc-gui/src/lib2/Cargo.toml
new file mode 100644 (file)
index 0000000..6041a79
--- /dev/null
@@ -0,0 +1,10 @@
+[package]
+name = "lib2"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+implementors = { path = "../implementors" }
diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
new file mode 100644 (file)
index 0000000..72ef3cb
--- /dev/null
@@ -0,0 +1,35 @@
+pub mod module {
+    pub mod sub_module {
+        pub mod sub_sub_module {
+            pub fn foo() {}
+        }
+        pub fn bar() {}
+    }
+    pub fn whatever() {}
+}
+
+pub fn foobar() {}
+
+pub type Alias = u32;
+
+pub struct Foo {
+    pub x: Alias,
+}
+
+impl Foo {
+    pub fn a_method(&self) {}
+}
+
+pub trait Trait {
+    type X;
+    const Y: u32;
+
+    fn foo() {}
+}
+
+impl Trait for Foo {
+    type X = u32;
+    const Y: u32 = 0;
+}
+
+impl implementors::Whatever for Foo {}
diff --git a/src/test/rustdoc-gui/src/lib2/src/lib.rs b/src/test/rustdoc-gui/src/lib2/src/lib.rs
new file mode 100644 (file)
index 0000000..31e1bb2
--- /dev/null
@@ -0,0 +1,7 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        assert_eq!(2 + 2, 4);
+    }
+}
diff --git a/src/test/rustdoc-gui/src/test_docs/Cargo.toml b/src/test/rustdoc-gui/src/test_docs/Cargo.toml
new file mode 100644 (file)
index 0000000..7f3c657
--- /dev/null
@@ -0,0 +1,7 @@
+[package]
+name = "test_docs"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
new file mode 100644 (file)
index 0000000..3e753cb
--- /dev/null
@@ -0,0 +1,107 @@
+//! The point of this crate is to be able to have enough different "kinds" of
+//! documentation generated so we can test each different features.
+
+#![crate_name = "test_docs"]
+#![feature(doc_keyword)]
+#![feature(doc_cfg)]
+
+use std::fmt;
+
+/// Basic function with some code examples:
+///
+/// ```
+/// println!("nothing fancy");
+/// ```
+///
+/// A failing to compile one:
+///
+/// ```compile_fail
+/// println!("where did my argument {} go? :'(");
+/// ```
+///
+/// An ignored one:
+///
+/// ```ignore (it's a test)
+/// Let's say I'm just some text will ya?
+/// ```
+pub fn foo() {}
+
+/// Just a normal struct.
+pub struct Foo;
+
+impl Foo {
+    #[must_use]
+    pub fn must_use(&self) -> bool {
+        true
+    }
+}
+
+/// Just a normal enum.
+#[doc(alias = "ThisIsAnAlias")]
+pub enum WhoLetTheDogOut {
+    /// Woof!
+    Woof,
+    /// Meoooooooow...
+    Meow,
+}
+
+/// Who doesn't love to wrap a `format!` call?
+pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
+    format!("{:?}", t)
+}
+
+/// Woohoo! A trait!
+pub trait AnotherOne {
+    /// Some func 3.
+    fn func3();
+
+    /// Some func 1.
+    fn func1();
+
+    fn another();
+    fn why_not();
+
+    /// Some func 2.
+    fn func2();
+
+    fn hello();
+}
+
+/// ```compile_fail
+/// whatever
+/// ```
+///
+/// Check for "i" signs in lists!
+///
+/// 1. elem 1
+/// 2. test 1
+///    ```compile_fail
+///    fn foo() {}
+///    ```
+/// 3. elem 3
+/// 4. ```ignore (it's a test)
+///    fn foo() {}
+///    ```
+/// 5. elem 5
+///
+/// Final one:
+///
+/// ```ignore (still a test)
+/// let x = 12;
+/// ```
+pub fn check_list_code_block() {}
+
+/// a thing with a label
+#[deprecated(since = "1.0.0", note = "text why this deprecated")]
+#[doc(cfg(unix))]
+pub fn replaced_function() {}
+
+pub enum AnEnum {
+    WithVariants { and: usize, sub: usize, variants: usize },
+}
+
+#[doc(keyword = "CookieMonster")]
+pub mod keyword {}
+
+/// Just some type alias.
+pub type SomeType = u32;
diff --git a/src/test/rustdoc-ui/intra-doc/field-ice.rs b/src/test/rustdoc-ui/intra-doc/field-ice.rs
new file mode 100644 (file)
index 0000000..c5d501e
--- /dev/null
@@ -0,0 +1,11 @@
+#![deny(rustdoc::broken_intra_doc_links)]
+//~^NOTE the lint level is defined here
+
+/// [`Foo::bar`]
+/// [`Foo::bar()`]
+//~^ERROR incompatible link kind for `Foo::bar`
+//~|HELP to link to the field, remove the disambiguator
+//~|NOTE this link resolved to a field, which is not a function
+pub struct Foo {
+    pub bar: u8
+}
diff --git a/src/test/rustdoc-ui/intra-doc/field-ice.stderr b/src/test/rustdoc-ui/intra-doc/field-ice.stderr
new file mode 100644 (file)
index 0000000..ccb05b8
--- /dev/null
@@ -0,0 +1,15 @@
+error: incompatible link kind for `Foo::bar`
+  --> $DIR/field-ice.rs:5:6
+   |
+LL | /// [`Foo::bar()`]
+   |      ^^^^^^^^^^^^ help: to link to the field, remove the disambiguator: ``Foo::bar``
+   |
+note: the lint level is defined here
+  --> $DIR/field-ice.rs:1:9
+   |
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this link resolved to a field, which is not a function
+
+error: aborting due to previous error
+
diff --git a/src/test/rustdoc/auxiliary/reexports.rs b/src/test/rustdoc/auxiliary/reexports.rs
new file mode 100644 (file)
index 0000000..e04b786
--- /dev/null
@@ -0,0 +1,42 @@
+#![feature(decl_macro)]
+
+pub macro addr_of($place:expr) {
+    &raw const $place
+}
+
+pub macro addr_of_self($place:expr) {
+    &raw const $place
+}
+
+pub macro addr_of_crate($place:expr) {
+    &raw const $place
+}
+
+pub struct Foo;
+pub struct FooSelf;
+pub struct FooCrate;
+
+pub enum Bar { Foo, }
+pub enum BarSelf { Foo, }
+pub enum BarCrate { Foo, }
+
+pub fn foo() {}
+pub fn foo_self() {}
+pub fn foo_crate() {}
+
+pub type Type = i32;
+pub type TypeSelf = i32;
+pub type TypeCrate = i32;
+
+pub union Union {
+    a: i8,
+    b: i8,
+}
+pub union UnionSelf {
+    a: i8,
+    b: i8,
+}
+pub union UnionCrate {
+    a: i8,
+    b: i8,
+}
diff --git a/src/test/rustdoc/duplicate-flags.rs b/src/test/rustdoc/duplicate-flags.rs
new file mode 100644 (file)
index 0000000..dde36df
--- /dev/null
@@ -0,0 +1,4 @@
+// compile-flags: --document-private-items --document-private-items
+
+// @has duplicate_flags/struct.Private.html
+struct Private;
diff --git a/src/test/rustdoc/reexports-priv.rs b/src/test/rustdoc/reexports-priv.rs
new file mode 100644 (file)
index 0000000..ff74240
--- /dev/null
@@ -0,0 +1,53 @@
+// aux-build: reexports.rs
+// compile-flags: --document-private-items
+
+#![crate_name = "foo"]
+
+extern crate reexports;
+
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
+pub use reexports::addr_of;
+// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
+pub(crate) use reexports::addr_of_crate;
+// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
+pub(self) use reexports::addr_of_self;
+
+// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
+pub use reexports::Foo;
+// @has 'foo/struct.FooCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooCrate;'
+pub(crate) use reexports::FooCrate;
+// @has 'foo/struct.FooSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooSelf;'
+pub(self) use reexports::FooSelf;
+
+// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
+pub use reexports::Bar;
+// @has 'foo/enum.BarCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarCrate {'
+pub(crate) use reexports::BarCrate;
+// @has 'foo/enum.BarSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarSelf {'
+pub(self) use reexports::BarSelf;
+
+// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
+pub use reexports::foo;
+// @has 'foo/fn.foo_crate.html' '//*[@class="rust fn"]' 'pub(crate) fn foo_crate()'
+pub(crate) use reexports::foo_crate;
+// @has 'foo/fn.foo_self.html' '//*[@class="rust fn"]' 'pub(crate) fn foo_self()'
+pub(self) use reexports::foo_self;
+
+// @has 'foo/type.Type.html' '//*[@class="rust typedef"]' 'pub type Type ='
+pub use reexports::Type;
+// @has 'foo/type.TypeCrate.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeCrate ='
+pub(crate) use reexports::TypeCrate;
+// @has 'foo/type.TypeSelf.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeSelf ='
+pub(self) use reexports::TypeSelf;
+
+// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
+pub use reexports::Union;
+// @has 'foo/union.UnionCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionCrate {'
+pub(crate) use reexports::UnionCrate;
+// @has 'foo/union.UnionSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionSelf {'
+pub(self) use reexports::UnionSelf;
+
+pub mod foo {
+    // @!has 'foo/foo/union.Union.html'
+    use crate::reexports::Union;
+}
diff --git a/src/test/rustdoc/reexports.rs b/src/test/rustdoc/reexports.rs
new file mode 100644 (file)
index 0000000..ab4c5bc
--- /dev/null
@@ -0,0 +1,47 @@
+// aux-build: reexports.rs
+
+#![crate_name = "foo"]
+
+extern crate reexports;
+
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
+pub use reexports::addr_of;
+// @!has 'foo/macro.addr_of_crate.html'
+pub(crate) use reexports::addr_of_crate;
+// @!has 'foo/macro.addr_of_self.html'
+pub(self) use reexports::addr_of_self;
+
+// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
+pub use reexports::Foo;
+// @!has 'foo/struct.FooCrate.html'
+pub(crate) use reexports::FooCrate;
+// @!has 'foo/struct.FooSelf.html'
+pub(self) use reexports::FooSelf;
+
+// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
+pub use reexports::Bar;
+// @!has 'foo/enum.BarCrate.html'
+pub(crate) use reexports::BarCrate;
+// @!has 'foo/enum.BarSelf.html'
+pub(self) use reexports::BarSelf;
+
+// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
+pub use reexports::foo;
+// @!has 'foo/fn.foo_crate.html'
+pub(crate) use reexports::foo_crate;
+// @!has 'foo/fn.foo_self.html'
+pub(self) use reexports::foo_self;
+
+// @has 'foo/type.Type.html' '//*[@class="rust typedef"]' 'pub type Type ='
+pub use reexports::Type;
+// @!has 'foo/type.TypeCrate.html'
+pub(crate) use reexports::TypeCrate;
+// @!has 'foo/type.TypeSelf.html'
+pub(self) use reexports::TypeSelf;
+
+// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
+pub use reexports::Union;
+// @!has 'foo/union.UnionCrate.html'
+pub(crate) use reexports::UnionCrate;
+// @!has 'foo/union.UnionSelf.html'
+pub(self) use reexports::UnionSelf;
index 3786c6de7e78c400a827cf3f4e339e47d232e6c1..795c7d2dcb7354270bcf64004ddd9810fea6587e 100644 (file)
@@ -1,22 +1,29 @@
 // compile-flags: -Z unstable-options
 
 #![feature(rustc_private)]
+#![deny(rustc::default_hash_types)]
 
 extern crate rustc_data_structures;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use std::collections::{HashMap, HashSet};
 
-#[deny(rustc::default_hash_types)]
+mod foo {
+    pub struct HashMap;
+}
+
 fn main() {
     let _map: HashMap<String, String> = HashMap::default();
-    //~^ ERROR Prefer FxHashMap over HashMap, it has better performance
-    //~^^ ERROR Prefer FxHashMap over HashMap, it has better performance
+    //~^ ERROR prefer `FxHashMap` over `HashMap`, it has better performance
+    //~^^ ERROR prefer `FxHashMap` over `HashMap`, it has better performance
     let _set: HashSet<String> = HashSet::default();
-    //~^ ERROR Prefer FxHashSet over HashSet, it has better performance
-    //~^^ ERROR Prefer FxHashSet over HashSet, it has better performance
+    //~^ ERROR prefer `FxHashSet` over `HashSet`, it has better performance
+    //~^^ ERROR prefer `FxHashSet` over `HashSet`, it has better performance
 
     // test that the lint doesn't also match the Fx variants themselves
     let _fx_map: FxHashMap<String, String> = FxHashMap::default();
     let _fx_set: FxHashSet<String> = FxHashSet::default();
+
+    // test another struct of the same name
+    let _ = foo::HashMap;
 }
index 4f78f51b676f4110f6359467475d31104b46f925..9d13ee89bca649d66d9921e1e49e628aa727ae7b 100644 (file)
@@ -1,37 +1,37 @@
-error: Prefer FxHashMap over HashMap, it has better performance
-  --> $DIR/default_hash_types.rs:12:15
+error: prefer `FxHashMap` over `HashMap`, it has better performance
+  --> $DIR/default_hash_types.rs:16:41
    |
 LL |     let _map: HashMap<String, String> = HashMap::default();
-   |               ^^^^^^^ help: use: `FxHashMap`
+   |                                         ^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/default_hash_types.rs:10:8
+  --> $DIR/default_hash_types.rs:4:9
    |
-LL | #[deny(rustc::default_hash_types)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustc::default_hash_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 
-error: Prefer FxHashMap over HashMap, it has better performance
-  --> $DIR/default_hash_types.rs:12:41
+error: prefer `FxHashMap` over `HashMap`, it has better performance
+  --> $DIR/default_hash_types.rs:16:15
    |
 LL |     let _map: HashMap<String, String> = HashMap::default();
-   |                                         ^^^^^^^ help: use: `FxHashMap`
+   |               ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 
-error: Prefer FxHashSet over HashSet, it has better performance
-  --> $DIR/default_hash_types.rs:15:15
+error: prefer `FxHashSet` over `HashSet`, it has better performance
+  --> $DIR/default_hash_types.rs:19:33
    |
 LL |     let _set: HashSet<String> = HashSet::default();
-   |               ^^^^^^^ help: use: `FxHashSet`
+   |                                 ^^^^^^^
    |
    = note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
 
-error: Prefer FxHashSet over HashSet, it has better performance
-  --> $DIR/default_hash_types.rs:15:33
+error: prefer `FxHashSet` over `HashSet`, it has better performance
+  --> $DIR/default_hash_types.rs:19:15
    |
 LL |     let _set: HashSet<String> = HashSet::default();
-   |                                 ^^^^^^^ help: use: `FxHashSet`
+   |               ^^^^^^^^^^^^^^^
    |
    = note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
 
index d8ccf36852a512a206caf90411db783dad2a6e13..0475df447445df05067ce82fab23feb4ebe0b11e 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*s.pointer` which is behind a `&` reference
+error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
   --> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:9:5
    |
 LL | fn a(s: &S) {
@@ -6,7 +6,7 @@ LL | fn a(s: &S) {
 LL |     *s.pointer += 1;
    |     ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*s.pointer` which is behind a `&` reference
+error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
   --> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5
    |
 LL | fn c(s: & &mut S) {
index 1fdeb812bf8bb8e4ca8f1ddd73141d425cd9e762..0866f54b9fab6237b1ab07ed15ba9860d5579868 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `**t1` which is behind a `&` reference
+error[E0594]: cannot assign to `**t1`, which is behind a `&` reference
   --> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:9:5
    |
 LL |     let t1 = t0;
index ae9167757a0ae756dd1df38adab93ded49a04ef6..4c0e46d453142eeb838bd463b2a857e981ae559f 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `***p` which is behind a `&` reference
+error[E0594]: cannot assign to `***p`, which is behind a `&` reference
   --> $DIR/borrowck-issue-14498.rs:16:5
    |
 LL |     let p = &y;
index d2865ffd196a50f67d4dd910c772982a975504a2..369a8c61d2c99b73b3561db0881f17d1e8d36460 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*item` which is behind a `&` reference
+error[E0594]: cannot assign to `*item`, which is behind a `&` reference
   --> $DIR/issue-69789-iterator-mut-suggestion.rs:7:9
    |
 LL |     for item in &mut std::iter::empty::<&'static ()>() {
index 6da88bed2c6ba0caf6a8e6da8b68c57fdc775a72..d301e7b3524b82f41a9b10def2647bc3c81ca6b5 100644 (file)
@@ -9,7 +9,7 @@ fn main() {
     for v in Query.iter_mut() {
         //~^ NOTE this iterator yields `&` references
         *v -= 1;
-        //~^ ERROR cannot assign to `*v` which is behind a `&` reference
+        //~^ ERROR cannot assign to `*v`, which is behind a `&` reference
         //~| NOTE `v` is a `&` reference, so the data it refers to cannot be written
     }
 }
index 143b74c39ba86b9a8bf7206e972ad9e033814ac2..26ce007dd346a33c503b190edad1c1100a3d1e2c 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*v` which is behind a `&` reference
+error[E0594]: cannot assign to `*v`, which is behind a `&` reference
   --> $DIR/issue-83309-ice-immut-in-for-loop.rs:11:9
    |
 LL |     for v in Query.iter_mut() {
index b82e0298158aa7c0a22af435a46a5efcd00d930c..1a5f7434fe2bb2173d8183a060bfa7d8790033cd 100644 (file)
@@ -5,4 +5,11 @@ fn main() {
     rofl.push(Vec::new());
     //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
     //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+    let mut mutvar = 42;
+    let r = &mutvar;
+    //~^ HELP consider changing this to be a mutable reference
+    *r = 0;
+    //~^ ERROR cannot assign to `*r`, which is behind a `&` reference
+    //~| NOTE `r` is a `&` reference, so the data it refers to cannot be written
 }
index 863c2e8eccc8c65952cf31701ec247cb7c175e2f..4da4c8f59466666baa5f47b4094fd9296aea4abb 100644 (file)
@@ -7,6 +7,16 @@ LL |
 LL |     rofl.push(Vec::new());
    |     ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
-error: aborting due to previous error
+error[E0594]: cannot assign to `*r`, which is behind a `&` reference
+  --> $DIR/issue-85765.rs:12:5
+   |
+LL |     let r = &mutvar;
+   |             ------- help: consider changing this to be a mutable reference: `&mut mutvar`
+LL |
+LL |     *r = 0;
+   |     ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0596`.
+Some errors have detailed explanations: E0594, E0596.
+For more information about an error, try `rustc --explain E0594`.
index 5361ebe3916d712d5170d6ff8a6899a2ce487dfc..edab22569b34f7e6aef5a290d2c333e6f8ac2b3b 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/mutability-errors.rs:9:5
    |
 LL | fn named_ref(x: &(i32,)) {
@@ -6,7 +6,7 @@ LL | fn named_ref(x: &(i32,)) {
 LL |     *x = (1,);
    |     ^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `x.0` which is behind a `&` reference
+error[E0594]: cannot assign to `x.0`, which is behind a `&` reference
   --> $DIR/mutability-errors.rs:10:5
    |
 LL | fn named_ref(x: &(i32,)) {
@@ -57,7 +57,7 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
 LL |     &mut f().0;
    |     ^^^^^^^^^^ cannot borrow as mutable
 
-error[E0594]: cannot assign to `*x` which is behind a `*const` pointer
+error[E0594]: cannot assign to `*x`, which is behind a `*const` pointer
   --> $DIR/mutability-errors.rs:23:5
    |
 LL | unsafe fn named_ptr(x: *const (i32,)) {
@@ -65,7 +65,7 @@ LL | unsafe fn named_ptr(x: *const (i32,)) {
 LL |     *x = (1,);
    |     ^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `x.0` which is behind a `*const` pointer
+error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer
   --> $DIR/mutability-errors.rs:24:5
    |
 LL | unsafe fn named_ptr(x: *const (i32,)) {
diff --git a/src/test/ui/cfg/cfg-target-abi.rs b/src/test/ui/cfg/cfg-target-abi.rs
new file mode 100644 (file)
index 0000000..acc570f
--- /dev/null
@@ -0,0 +1,10 @@
+// run-pass
+#![feature(cfg_target_abi)]
+
+#[cfg(target_abi = "eabihf")]
+pub fn main() {
+}
+
+#[cfg(not(target_abi = "eabihf"))]
+pub fn main() {
+}
diff --git a/src/test/ui/consts/issue-87046.rs b/src/test/ui/consts/issue-87046.rs
new file mode 100644 (file)
index 0000000..1f14743
--- /dev/null
@@ -0,0 +1,34 @@
+// Regression test for the ICE described in #87046.
+
+#![crate_type="lib"]
+#![allow(unreachable_patterns)]
+#![feature(const_fn_union)]
+
+#[derive(PartialEq, Eq)]
+#[repr(transparent)]
+pub struct Username(str);
+
+pub const ROOT_USER: &Username = Username::from_str("root");
+
+impl Username {
+    pub const fn from_str(raw: &str) -> &Self {
+        union Transmute<'a> {
+            raw: &'a str,
+            typed: &'a Username,
+        }
+
+        unsafe { Transmute { raw }.typed }
+    }
+
+    pub const fn as_str(&self) -> &str {
+        &self.0
+    }
+
+    pub fn is_root(&self) -> bool {
+        match self {
+            ROOT_USER => true,
+            //~^ ERROR: cannot use unsized non-slice type `Username` in constant patterns
+            _ => false,
+        }
+    }
+}
diff --git a/src/test/ui/consts/issue-87046.stderr b/src/test/ui/consts/issue-87046.stderr
new file mode 100644 (file)
index 0000000..5da7a9e
--- /dev/null
@@ -0,0 +1,8 @@
+error: cannot use unsized non-slice type `Username` in constant patterns
+  --> $DIR/issue-87046.rs:29:13
+   |
+LL |             ROOT_USER => true,
+   |             ^^^^^^^^^
+
+error: aborting due to previous error
+
index c33ad1519bcc5ca4f6465682b9e7f9eb693574da..f499ff85e5da8dad7fb48d72df07d4b93b00e3d0 100644 (file)
@@ -1,15 +1,14 @@
 error: use of deprecated function `deprecation_lint::deprecated_text`: text
-  --> $DIR/deprecation-lint-3.rs:13:5
+  --> $DIR/deprecation-lint-3.rs:13:28
    |
 LL |     macro_test_arg_nested!(deprecated_text);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                            ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/deprecation-lint-3.rs:4:9
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
-   = note: this error originates in the macro `macro_test_arg_nested` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
index 3699a939e27882e21e5a0a5363b9461f21cff183..20af4f62e6502cc78af28a3b2bf97afcd8878bd6 100644 (file)
@@ -11,16 +11,16 @@ LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:21:9
+  --> $DIR/deprecation-lint.rs:21:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:23:9
+  --> $DIR/deprecation-lint.rs:23:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `deprecation_lint::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:25:9
@@ -29,16 +29,16 @@ LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:30:9
+  --> $DIR/deprecation-lint.rs:30:16
    |
 LL | ...   Trait::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:32:9
+  --> $DIR/deprecation-lint.rs:32:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated struct `deprecation_lint::DeprecatedStruct`: text
   --> $DIR/deprecation-lint.rs:34:17
@@ -53,10 +53,10 @@ LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text
-  --> $DIR/deprecation-lint.rs:40:17
+  --> $DIR/deprecation-lint.rs:40:23
    |
 LL |         let _ = Enum::DeprecatedVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^
 
 error: use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text
   --> $DIR/deprecation-lint.rs:42:17
@@ -65,28 +65,28 @@ LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text
-  --> $DIR/deprecation-lint.rs:44:17
+  --> $DIR/deprecation-lint.rs:44:25
    |
 LL |         let _ = nested::DeprecatedStruct {
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 error: use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text
-  --> $DIR/deprecation-lint.rs:48:17
+  --> $DIR/deprecation-lint.rs:48:25
    |
 LL |         let _ = nested::DeprecatedUnitStruct;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text
-  --> $DIR/deprecation-lint.rs:50:17
+  --> $DIR/deprecation-lint.rs:50:31
    |
 LL | ...   let _ = nested::Enum::DeprecatedVariant;
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^^^^^
 
 error: use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text
-  --> $DIR/deprecation-lint.rs:52:17
+  --> $DIR/deprecation-lint.rs:52:25
    |
 LL | ...   let _ = nested::DeprecatedTupleStruct (1);
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `deprecation_lint::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:59:25
@@ -101,28 +101,28 @@ LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:65:9
+  --> $DIR/deprecation-lint.rs:65:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:67:9
+  --> $DIR/deprecation-lint.rs:67:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:69:9
+  --> $DIR/deprecation-lint.rs:69:16
    |
 LL | ...   Trait::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:71:9
+  --> $DIR/deprecation-lint.rs:71:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text
   --> $DIR/deprecation-lint.rs:81:10
@@ -173,10 +173,10 @@ LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
 error: use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text
-  --> $DIR/deprecation-lint.rs:162:9
+  --> $DIR/deprecation-lint.rs:162:25
    |
 LL |         deprecated_mod::deprecated();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^
 
 error: use of deprecated function `this_crate::deprecated`: text
   --> $DIR/deprecation-lint.rs:245:9
@@ -185,16 +185,16 @@ LL |         deprecated();
    |         ^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:250:9
+  --> $DIR/deprecation-lint.rs:250:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:252:9
+  --> $DIR/deprecation-lint.rs:252:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `this_crate::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:254:9
@@ -203,16 +203,16 @@ LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:259:9
+  --> $DIR/deprecation-lint.rs:259:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:261:9
+  --> $DIR/deprecation-lint.rs:261:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `this_crate::deprecated_future`: text
   --> $DIR/deprecation-lint.rs:264:9
@@ -239,10 +239,10 @@ LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
-  --> $DIR/deprecation-lint.rs:274:17
+  --> $DIR/deprecation-lint.rs:274:23
    |
 LL |         let _ = Enum::DeprecatedVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^
 
 error: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
   --> $DIR/deprecation-lint.rs:276:17
@@ -251,52 +251,52 @@ LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated struct `this_crate::nested::DeprecatedStruct`: text
-  --> $DIR/deprecation-lint.rs:278:17
+  --> $DIR/deprecation-lint.rs:278:25
    |
 LL |         let _ = nested::DeprecatedStruct {
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 error: use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text
-  --> $DIR/deprecation-lint.rs:283:17
+  --> $DIR/deprecation-lint.rs:283:25
    |
 LL |         let _ = nested::DeprecatedUnitStruct;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text
-  --> $DIR/deprecation-lint.rs:285:17
+  --> $DIR/deprecation-lint.rs:285:31
    |
 LL | ...   let _ = nested::Enum::DeprecatedVariant;
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^^^^^
 
 error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text
-  --> $DIR/deprecation-lint.rs:287:17
+  --> $DIR/deprecation-lint.rs:287:25
    |
 LL | ...   let _ = nested::DeprecatedTupleStruct (1);
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:292:9
+  --> $DIR/deprecation-lint.rs:292:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/deprecation-lint.rs:294:9
+  --> $DIR/deprecation-lint.rs:294:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:296:9
+  --> $DIR/deprecation-lint.rs:296:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/deprecation-lint.rs:298:9
+  --> $DIR/deprecation-lint.rs:298:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 error: use of deprecated function `this_crate::test_fn_closure_body::{closure#0}::bar`
   --> $DIR/deprecation-lint.rs:316:13
index eba72f88a89115cefd1c018221477a124d41d7f4..7d662227881ace5d0af3631968b9f4b1d2627add 100644 (file)
@@ -21,8 +21,22 @@ impl Foo {
     fn replacement(&self) {}
 }
 
+mod bar {
+    #[rustc_deprecated(
+    since = "1.0.0",
+    reason = "replaced by `replacement`",
+    suggestion = "replacement",
+    )]
+    #[stable(since = "1.0.0", feature = "test")]
+    pub fn deprecated() {}
+
+    pub fn replacement() {}
+}
+
 fn main() {
     let foo = Foo;
 
     foo.replacement(); //~ ERROR use of deprecated
+
+    bar::replacement(); //~ ERROR use of deprecated
 }
index 8f9791c13e8563651988f115e89a17c5fdc3ff16..b34dc0eb83a206264a30eda1c5279fb03651f372 100644 (file)
@@ -21,8 +21,22 @@ fn deprecated(&self) {}
     fn replacement(&self) {}
 }
 
+mod bar {
+    #[rustc_deprecated(
+    since = "1.0.0",
+    reason = "replaced by `replacement`",
+    suggestion = "replacement",
+    )]
+    #[stable(since = "1.0.0", feature = "test")]
+    pub fn deprecated() {}
+
+    pub fn replacement() {}
+}
+
 fn main() {
     let foo = Foo;
 
     foo.deprecated(); //~ ERROR use of deprecated
+
+    bar::deprecated(); //~ ERROR use of deprecated
 }
index 8a7cb1def909e3a818d6d2ca588e3dc018456dc9..7d78b2222444f1b769827ebe4f034d7633555d09 100644 (file)
@@ -1,8 +1,8 @@
-error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement`
-  --> $DIR/suggestion.rs:27:9
+error: use of deprecated function `bar::deprecated`: replaced by `replacement`
+  --> $DIR/suggestion.rs:41:10
    |
-LL |     foo.deprecated();
-   |         ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement`
+LL |     bar::deprecated();
+   |          ^^^^^^^^^^ help: replace the use of the deprecated function: `replacement`
    |
 note: the lint level is defined here
   --> $DIR/suggestion.rs:7:9
@@ -10,5 +10,11 @@ note: the lint level is defined here
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
-error: aborting due to previous error
+error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement`
+  --> $DIR/suggestion.rs:39:9
+   |
+LL |     foo.deprecated();
+   |         ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement`
+
+error: aborting due to 2 previous errors
 
index 3c86f29a89c3068d7c920b1ce606a0d2463bde2c..a19d3f7047cea0ca9155f9e287422e31d49445ac 100644 (file)
@@ -46,5 +46,5 @@ pub fn with_tuple() {
     let mut y = 0;
     let x = (&y,);
     *x.0 = 1;
-    //~^ ERROR cannot assign to `*x.0` which is behind a `&` reference
+    //~^ ERROR cannot assign to `*x.0`, which is behind a `&` reference
 }
index ce0d697238c6b6c85338ac280b94bf47eee2965c..68180eaee036c41f1fa7d80fa88fead6bb498250 100644 (file)
@@ -90,7 +90,7 @@ LL |     let _ = &mut z.x;
 LL |     let _ = &mut w.x;
    |             ^^^^^^^^ `w` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
-error[E0594]: cannot assign to `*x.0` which is behind a `&` reference
+error[E0594]: cannot assign to `*x.0`, which is behind a `&` reference
   --> $DIR/issue-39544.rs:48:5
    |
 LL |     *x.0 = 1;
index 9dab2c3092434d6645b3dbfe4d43957379df0c4f..41172b362f495b296ce790ec1539dd36d63447f8 100644 (file)
@@ -5,6 +5,6 @@ struct FancyNum {
 fn main() {
     let mut fancy = FancyNum{ num: 5 };
     let fancy_ref = &(&mut fancy);
-    fancy_ref.num = 6; //~ ERROR cannot assign to `fancy_ref.num` which is behind a `&` reference
+    fancy_ref.num = 6; //~ ERROR cannot assign to `fancy_ref.num`, which is behind a `&` reference
     println!("{}", fancy_ref.num);
 }
index c47750b6f4e69cc72dda552ed86444396b7a7f7d..3d615bd932f436fe42e5c529664424ded3959616 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
+error[E0594]: cannot assign to `fancy_ref.num`, which is behind a `&` reference
   --> $DIR/E0389.rs:8:5
    |
 LL |     let fancy_ref = &(&mut fancy);
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs b/src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs
new file mode 100644 (file)
index 0000000..f265149
--- /dev/null
@@ -0,0 +1,11 @@
+#[cfg(target_abi = "x")] //~ ERROR `cfg(target_abi)` is experimental
+#[cfg_attr(target_abi = "x", x)] //~ ERROR `cfg(target_abi)` is experimental
+struct Foo(u64, u64);
+
+#[cfg(not(any(all(target_abi = "x"))))] //~ ERROR `cfg(target_abi)` is experimental
+fn foo() {}
+
+fn main() {
+    cfg!(target_abi = "x");
+    //~^ ERROR `cfg(target_abi)` is experimental and subject to change
+}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr b/src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr
new file mode 100644 (file)
index 0000000..ed8cbcb
--- /dev/null
@@ -0,0 +1,39 @@
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:2:12
+   |
+LL | #[cfg_attr(target_abi = "x", x)]
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:1:7
+   |
+LL | #[cfg(target_abi = "x")]
+   |       ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:5:19
+   |
+LL | #[cfg(not(any(all(target_abi = "x"))))]
+   |                   ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:9:10
+   |
+LL |     cfg!(target_abi = "x");
+   |          ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
index 509060e1ad81bbed5acee50f2555f81b93ace98a..d634b8bf80079ce8f885c5ffea40b9455f52847e 100644 (file)
@@ -1,4 +1,4 @@
 fn main() {
     let ref my_ref @ _ = 0;
-    *my_ref = 0; //~ ERROR cannot assign to `*my_ref` which is behind a `&` reference [E0594]
+    *my_ref = 0; //~ ERROR cannot assign to `*my_ref`, which is behind a `&` reference [E0594]
 }
index c91083955b8205b30678ec9c4abc18d370113a8f..19f0223a357a53e1fee7727c77516654b4e3a158 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference
+error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference
   --> $DIR/issue-51244.rs:3:5
    |
 LL |     let ref my_ref @ _ = 0;
index 8eab7b2fa3ae9b215555e4633a4203d6619bee1b..54fd176de75f033f20935e787431d6a88d3be638 100644 (file)
@@ -3,10 +3,10 @@ fn main() {
     //~^ HELP consider changing this to be a mutable reference
     //~| SUGGESTION &mut 16
     *foo = 32;
-    //~^ ERROR cannot assign to `*foo` which is behind a `&` reference
+    //~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
     let bar = foo;
     //~^ HELP consider changing this to be a mutable reference
     //~| SUGGESTION &mut i32
     *bar = 64;
-    //~^ ERROR cannot assign to `*bar` which is behind a `&` reference
+    //~^ ERROR cannot assign to `*bar`, which is behind a `&` reference
 }
index 3c208935f31f6ddeaebebc86d3d1b38633110a58..62bb462faa208b8ae61890000cdb7c0b2b159d33 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*foo` which is behind a `&` reference
+error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
   --> $DIR/issue-51515.rs:5:5
    |
 LL |     let foo = &16;
@@ -7,7 +7,7 @@ LL |     let foo = &16;
 LL |     *foo = 32;
    |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*bar` which is behind a `&` reference
+error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
   --> $DIR/issue-51515.rs:10:5
    |
 LL |     let bar = foo;
diff --git a/src/test/ui/lang-items/issue-86238.rs b/src/test/ui/lang-items/issue-86238.rs
new file mode 100644 (file)
index 0000000..509f94f
--- /dev/null
@@ -0,0 +1,16 @@
+// Regression test for the ICE described in issue #86238.
+
+#![feature(lang_items)]
+#![feature(no_core)]
+
+#![no_core]
+fn main() {
+    let one = || {};
+    one()
+    //~^ ERROR: failed to find an overloaded call trait for closure call
+    //~| HELP: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined
+}
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
diff --git a/src/test/ui/lang-items/issue-86238.stderr b/src/test/ui/lang-items/issue-86238.stderr
new file mode 100644 (file)
index 0000000..767e6de
--- /dev/null
@@ -0,0 +1,10 @@
+error: failed to find an overloaded call trait for closure call
+  --> $DIR/issue-86238.rs:9:5
+   |
+LL |     one()
+   |     ^^^^^
+   |
+   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
+
+error: aborting due to previous error
+
index ab62f0c8b8c897bcc37e586d4df23f4533c24a1c..4262a28799db26ac412e30a243e34c9a7824d82e 100644 (file)
@@ -12,6 +12,5 @@
 //~| SUGGESTION rustc::default_hash_types
 fn main() {
     let _ = std::collections::HashMap::<String, String>::new();
-    //~^ WARN Prefer FxHashMap over HashMap, it has better performance
-    //~| HELP use
+    //~^ WARN prefer `FxHashMap` over `HashMap`, it has better performance
 }
index 028890f3623df8a477493ef022784aed4b48d079..e619bcfe23f6408740678c9a0eb916cd6743e9f0 100644 (file)
@@ -12,11 +12,11 @@ warning: unknown lint: `rustc::foo::default_hash_types`
 LL | #[allow(rustc::foo::default_hash_types)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
 
-warning: Prefer FxHashMap over HashMap, it has better performance
-  --> $DIR/issue-83477.rs:14:31
+warning: prefer `FxHashMap` over `HashMap`, it has better performance
+  --> $DIR/issue-83477.rs:14:13
    |
 LL |     let _ = std::collections::HashMap::<String, String>::new();
-   |                               ^^^^^^^ help: use: `FxHashMap`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/issue-83477.rs:3:9
index 94fc1a7b46dbaf85e1234f8e109091572ad66541..4b082fcd35951147a71aa9e01b9bb94c9590fd8a 100644 (file)
@@ -11,16 +11,16 @@ LL | #![warn(deprecated)]
    |         ^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:29:9
+  --> $DIR/lint-stability-deprecated.rs:29:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:31:9
+  --> $DIR/lint-stability-deprecated.rs:31:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:33:9
@@ -29,16 +29,16 @@ LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:38:9
+  --> $DIR/lint-stability-deprecated.rs:38:16
    |
 LL | ...   Trait::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:40:9
+  --> $DIR/lint-stability-deprecated.rs:40:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:42:9
@@ -47,16 +47,16 @@ LL |         deprecated_unstable();
    |         ^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:47:9
+  --> $DIR/lint-stability-deprecated.rs:47:16
    |
 LL | ...   Trait::trait_deprecated_unstable(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:49:9
+  --> $DIR/lint-stability-deprecated.rs:49:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:51:9
@@ -65,16 +65,16 @@ LL |         deprecated_unstable_text();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:56:9
+  --> $DIR/lint-stability-deprecated.rs:56:16
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:58:9
+  --> $DIR/lint-stability-deprecated.rs:58:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text
   --> $DIR/lint-stability-deprecated.rs:108:17
@@ -101,16 +101,16 @@ LL |         let _ = DeprecatedUnstableUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated variant `lint_stability::Enum::DeprecatedVariant`: text
-  --> $DIR/lint-stability-deprecated.rs:123:17
+  --> $DIR/lint-stability-deprecated.rs:123:23
    |
 LL |         let _ = Enum::DeprecatedVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`: text
-  --> $DIR/lint-stability-deprecated.rs:124:17
+  --> $DIR/lint-stability-deprecated.rs:124:23
    |
 LL |         let _ = Enum::DeprecatedUnstableVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `lint_stability::DeprecatedTupleStruct`: text
   --> $DIR/lint-stability-deprecated.rs:128:17
@@ -143,52 +143,52 @@ LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:145:9
+  --> $DIR/lint-stability-deprecated.rs:145:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:147:9
+  --> $DIR/lint-stability-deprecated.rs:147:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:149:9
+  --> $DIR/lint-stability-deprecated.rs:149:16
    |
 LL | ...   Trait::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:151:9
+  --> $DIR/lint-stability-deprecated.rs:151:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:153:9
+  --> $DIR/lint-stability-deprecated.rs:153:16
    |
 LL | ...   Trait::trait_deprecated_unstable(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:155:9
+  --> $DIR/lint-stability-deprecated.rs:155:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:157:9
+  --> $DIR/lint-stability-deprecated.rs:157:16
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:159:9
+  --> $DIR/lint-stability-deprecated.rs:159:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
   --> $DIR/lint-stability-deprecated.rs:187:10
@@ -203,10 +203,10 @@ LL |     trait LocalTrait2 : DeprecatedTrait { }
    |                         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:208:9
+  --> $DIR/lint-stability-deprecated.rs:208:23
    |
 LL |         unstable_mod::deprecated();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:330:9
@@ -215,16 +215,16 @@ LL |         deprecated();
    |         ^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:335:9
+  --> $DIR/lint-stability-deprecated.rs:335:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:337:9
+  --> $DIR/lint-stability-deprecated.rs:337:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:339:9
@@ -233,16 +233,16 @@ LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:344:9
+  --> $DIR/lint-stability-deprecated.rs:344:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:346:9
+  --> $DIR/lint-stability-deprecated.rs:346:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `this_crate::DeprecatedStruct`: text
   --> $DIR/lint-stability-deprecated.rs:384:17
@@ -257,10 +257,10 @@ LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
-  --> $DIR/lint-stability-deprecated.rs:395:17
+  --> $DIR/lint-stability-deprecated.rs:395:23
    |
 LL |         let _ = Enum::DeprecatedVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
   --> $DIR/lint-stability-deprecated.rs:399:17
@@ -269,28 +269,28 @@ LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:406:9
+  --> $DIR/lint-stability-deprecated.rs:406:16
    |
 LL |         Trait::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:408:9
+  --> $DIR/lint-stability-deprecated.rs:408:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:410:9
+  --> $DIR/lint-stability-deprecated.rs:410:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:412:9
+  --> $DIR/lint-stability-deprecated.rs:412:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
   --> $DIR/lint-stability-deprecated.rs:439:9
index 56d4ffc4727b2e2e627f76e5d9b4bdaf4d633bea..3bbb60dd35927f38833215860d5f543762c37263 100644 (file)
@@ -1,15 +1,14 @@
 error: use of deprecated function `lint_stability::deprecated_text`: text
-  --> $DIR/lint-stability3.rs:13:5
+  --> $DIR/lint-stability3.rs:13:28
    |
 LL |     macro_test_arg_nested!(deprecated_text);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                            ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/lint-stability3.rs:4:9
    |
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
-   = note: this error originates in the macro `macro_test_arg_nested` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
index 15323ce9a9755561f943f3d797cd97f5fbdc5e23..5a4e31947f2b2e889a1ceee9b40625fe3c4a0270 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `self.how_hungry` which is behind a `&` reference
+error[E0594]: cannot assign to `self.how_hungry`, which is behind a `&` reference
   --> $DIR/mutable-class-fields-2.rs:9:5
    |
 LL |   pub fn eat(&self) {
index 8d48b00f8d1f19088a89c8fb53ec583fe309afbf..a4ee7781753060f0bb8c6fbd7f5227d692f031c0 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
+error[E0594]: cannot assign to `fancy_ref.num`, which is behind a `&` reference
   --> $DIR/issue-47388.rs:8:5
    |
 LL |     let fancy_ref = &(&mut fancy);
index 743415d58afadb3b01e53473bdf25210cf1742c7..c4cbee6754c0461432785589aae247b71392fbcc 100644 (file)
@@ -1,5 +1,5 @@
 fn main() {
     let ref my_ref @ _ = 0;
     *my_ref = 0;
-    //~^ ERROR cannot assign to `*my_ref` which is behind a `&` reference [E0594]
+    //~^ ERROR cannot assign to `*my_ref`, which is behind a `&` reference [E0594]
 }
index c91083955b8205b30678ec9c4abc18d370113a8f..19f0223a357a53e1fee7727c77516654b4e3a158 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference
+error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference
   --> $DIR/issue-51244.rs:3:5
    |
 LL |     let ref my_ref @ _ = 0;
index c410f0b0bfb4da6fd4d8b73d1ec5298cf5666c8a..8f3dec454d5ff9640212bd710a7b37c9a06bcfdb 100644 (file)
@@ -2,7 +2,7 @@
 
 fn f(x: &i32) {
     let g = &x;
-    *x = 0;     //~ ERROR cannot assign to `*x` which is behind a `&` reference
+    *x = 0;     //~ ERROR cannot assign to `*x`, which is behind a `&` reference
                 //~| ERROR cannot assign to `*x` because it is borrowed
     g;
 }
index 4c416105035d7e7681d022d0432ce73503634105..e85e63e52ecc37bbec6731f5b2f1c34078cddf92 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/issue-57989.rs:5:5
    |
 LL | fn f(x: &i32) {
index 9c320edc4dc0ec0f6a6ac5021d0ef5fb6485b685..a6144c9497d0483255c3fbaa23c314d36ab49292 100644 (file)
@@ -23,8 +23,8 @@ fn tuple() {
     _x1 = U; //~ ERROR cannot assign twice to immutable variable
     let _x0_hold = &mut tup.0; //~ ERROR cannot borrow `tup.0` as mutable because it is also
     let (ref mut _x0_hold, ..) = tup; //~ ERROR cannot borrow `tup.0` as mutable because it is also
-    *_x0 = U; //~ ERROR cannot assign to `*_x0` which is behind a `&` reference
-    *_x2 = U; //~ ERROR cannot assign to `*_x2` which is behind a `&` reference
+    *_x0 = U; //~ ERROR cannot assign to `*_x0`, which is behind a `&` reference
+    *_x2 = U; //~ ERROR cannot assign to `*_x2`, which is behind a `&` reference
     drop(tup.1); //~ ERROR use of moved value: `tup.1`
     let _x1_hold = &tup.1; //~ ERROR borrow of moved value: `tup.1`
     let (.., ref mut _x3) = tup;
index d0726f05cc3be01d2a48f2a667d86d52afdeacc5..5beca04d285901aafc840a7b0aba00f63903e7f7 100644 (file)
@@ -101,7 +101,7 @@ LL |     let (ref mut _x0_hold, ..) = tup;
 LL |     *_x0 = U;
    |     -------- immutable borrow later used here
 
-error[E0594]: cannot assign to `*_x0` which is behind a `&` reference
+error[E0594]: cannot assign to `*_x0`, which is behind a `&` reference
   --> $DIR/borrowck-move-ref-pattern.rs:26:5
    |
 LL |     let (ref _x0, _x1, ref _x2, ..) = tup;
@@ -110,7 +110,7 @@ LL |     let (ref _x0, _x1, ref _x2, ..) = tup;
 LL |     *_x0 = U;
    |     ^^^^^^^^ `_x0` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*_x2` which is behind a `&` reference
+error[E0594]: cannot assign to `*_x2`, which is behind a `&` reference
   --> $DIR/borrowck-move-ref-pattern.rs:27:5
    |
 LL |     let (ref _x0, _x1, ref _x2, ..) = tup;
index af82d36f87eb080e7046c2ee29663726fb744408..4e57769d6e24c877885437173092118d558a9e52 100644 (file)
@@ -6,17 +6,17 @@ enum Wrapper {
 
 pub fn main() {
     let Wrap(x) = &Wrap(3);
-    *x += 1; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+    *x += 1; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
 
 
     if let Some(x) = &Some(3) {
-        *x += 1; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+        *x += 1; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
     } else {
         panic!();
     }
 
     while let Some(x) = &Some(3) {
-        *x += 1; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+        *x += 1; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
         break;
     }
 }
index d6a89006bc0fb9a489ef4934089e0cacd6c8b04e..21e3d3d273d7f3295435089754d57ef04e10aea2 100644 (file)
@@ -1,16 +1,16 @@
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/enum.rs:9:5
    |
 LL |     *x += 1;
    |     ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/enum.rs:13:9
    |
 LL |         *x += 1;
    |         ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/enum.rs:19:9
    |
 LL |         *x += 1;
index 212fd94ded3e7f38231f20424a1926807e1907d0..b8fde2208acd5a1bf4fd7d3ba4ed670b6e435aac 100644 (file)
@@ -4,7 +4,7 @@
 fn main() {
     match &&Some(5i32) {
         Some(n) => {
-            *n += 1; //~ ERROR cannot assign to `*n` which is behind a `&` reference
+            *n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
             let _ = n;
         }
         None => {},
@@ -12,7 +12,7 @@ fn main() {
 
     match &mut &Some(5i32) {
         Some(n) => {
-            *n += 1; //~ ERROR cannot assign to `*n` which is behind a `&` reference
+            *n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
             let _ = n;
         }
         None => {},
@@ -20,7 +20,7 @@ fn main() {
 
     match &&mut Some(5i32) {
         Some(n) => {
-            *n += 1; //~ ERROR cannot assign to `*n` which is behind a `&` reference
+            *n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
             let _ = n;
         }
         None => {},
index a6f2f3ec3096858df5aacd0b9078ff330b191166..c3f64f65a412ec40e5bdd79ce18fffa0b90ccc83 100644 (file)
@@ -1,16 +1,16 @@
-error[E0594]: cannot assign to `*n` which is behind a `&` reference
+error[E0594]: cannot assign to `*n`, which is behind a `&` reference
   --> $DIR/explicit-mut.rs:7:13
    |
 LL |             *n += 1;
    |             ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*n` which is behind a `&` reference
+error[E0594]: cannot assign to `*n`, which is behind a `&` reference
   --> $DIR/explicit-mut.rs:15:13
    |
 LL |             *n += 1;
    |             ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*n` which is behind a `&` reference
+error[E0594]: cannot assign to `*n`, which is behind a `&` reference
   --> $DIR/explicit-mut.rs:23:13
    |
 LL |             *n += 1;
diff --git a/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs b/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs
deleted file mode 100644 (file)
index 3f75974..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// only-i686-pc-windows-msvc
-// compile-flags: --crate-type lib --emit link
-#![allow(clashing_extern_declarations)]
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
-#[link(name = "foo", kind = "raw-dylib")]
-extern "C" {
-    fn f(x: i32);
-    //~^ ERROR multiple definitions of external function `f` from library `foo.dll` have different calling conventions
-}
-
-pub fn lib_main() {
-    #[link(name = "foo", kind = "raw-dylib")]
-    extern "stdcall" {
-        fn f(x: i32);
-    }
-
-    unsafe { f(42); }
-}
diff --git a/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr b/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr
deleted file mode 100644 (file)
index 91f6f0c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multiple-definitions.rs:4:12
-   |
-LL | #![feature(raw_dylib)]
-   |            ^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
-
-error: multiple definitions of external function `f` from library `foo.dll` have different calling conventions
-  --> $DIR/multiple-definitions.rs:8:5
-   |
-LL |     fn f(x: i32);
-   |     ^^^^^^^^^^^^^
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs
new file mode 100644 (file)
index 0000000..338ac3d
--- /dev/null
@@ -0,0 +1,14 @@
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+#[default_method_body_is_const] //~ ERROR attribute should be applied
+trait A {
+    #[default_method_body_is_const] //~ ERROR attribute should be applied
+    fn no_body(self);
+
+    #[default_method_body_is_const]
+    fn correct_use(&self) {}
+}
+
+#[default_method_body_is_const] //~ ERROR attribute should be applied
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.stderr
new file mode 100644 (file)
index 0000000..3af71d6
--- /dev/null
@@ -0,0 +1,32 @@
+error: attribute should be applied to a trait method with body
+  --> $DIR/attr-misuse.rs:4:1
+   |
+LL |   #[default_method_body_is_const]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / trait A {
+LL | |     #[default_method_body_is_const]
+LL | |     fn no_body(self);
+LL | |
+LL | |     #[default_method_body_is_const]
+LL | |     fn correct_use(&self) {}
+LL | | }
+   | |_- not a trait method or missing a body
+
+error: attribute should be applied to a trait method with body
+  --> $DIR/attr-misuse.rs:13:1
+   |
+LL | #[default_method_body_is_const]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn main() {}
+   | ------------ not a trait method or missing a body
+
+error: attribute should be applied to a trait method with body
+  --> $DIR/attr-misuse.rs:6:5
+   |
+LL |     #[default_method_body_is_const]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn no_body(self);
+   |     ----------------- not a trait method or missing a body
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs
new file mode 100644 (file)
index 0000000..d08c017
--- /dev/null
@@ -0,0 +1,31 @@
+#![feature(const_trait_impl)]
+#![feature(const_fn_trait_bound)] // FIXME is this needed?
+#![allow(incomplete_features)]
+
+trait ConstDefaultFn: Sized {
+    fn b(self);
+
+    #[default_method_body_is_const]
+    fn a(self) {
+        self.b();
+    }
+}
+
+struct NonConstImpl;
+struct ConstImpl;
+
+impl ConstDefaultFn for NonConstImpl {
+    fn b(self) {}
+}
+
+impl const ConstDefaultFn for ConstImpl {
+    fn b(self) {}
+}
+
+const fn test() {
+    NonConstImpl.a();
+    //~^ ERROR calls in constant functions are limited to constant functions, tuple structs and tuple variants
+    ConstImpl.a();
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
new file mode 100644 (file)
index 0000000..d52e836
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/const-default-method-bodies.rs:26:5
+   |
+LL |     NonConstImpl.a();
+   |     ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
index 4ff4fa0d83b2c41c92e4b13b54d1b681d131166b..def7c34b4e50e2e4cf6435bad316f251e0802ff2 100644 (file)
@@ -8,13 +8,31 @@ fn prov(&self) {
         println!("lul");
         self.req();
     }
+
+    #[default_method_body_is_const]
+    fn default() {}
 }
 
 struct S;
 
 impl const Tr for S {
     fn req(&self) {}
+} //~^^ ERROR const trait implementations may not use non-const default functions
+
+impl const Tr for u8 {
+    fn req(&self) {}
+    fn prov(&self) {}
 }
-//~^^^ ERROR const trait implementations may not use default functions
+
+impl const Tr for u16 {
+    fn prov(&self) {}
+    fn default() {}
+} //~^^^ ERROR not all trait items implemented
+
+
+impl const Tr for u32 {
+    fn req(&self) {}
+    fn default() {}
+} //~^^^ ERROR const trait implementations may not use non-const default functions
 
 fn main() {}
index 51a7b18fa8d550d68b2bb323590bc0a5d4c89434..eb7f899b4dee212bed27ba19d81da55fb4c2ba78 100644 (file)
@@ -1,10 +1,33 @@
-error: const trait implementations may not use default functions
-  --> $DIR/impl-with-default-fn.rs:15:1
+error: const trait implementations may not use non-const default functions
+  --> $DIR/impl-with-default-fn.rs:18:1
    |
 LL | / impl const Tr for S {
 LL | |     fn req(&self) {}
 LL | | }
    | |_^
+   |
+   = note: `prov` not implemented
+
+error: const trait implementations may not use non-const default functions
+  --> $DIR/impl-with-default-fn.rs:33:1
+   |
+LL | / impl const Tr for u32 {
+LL | |     fn req(&self) {}
+LL | |     fn default() {}
+LL | | }
+   | |_^
+   |
+   = note: `prov` not implemented
+
+error[E0046]: not all trait items implemented, missing: `req`
+  --> $DIR/impl-with-default-fn.rs:27:1
+   |
+LL |     fn req(&self);
+   |     -------------- `req` from trait
+...
+LL | impl const Tr for u16 {
+   | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0046`.
index 99523f8eb645d5877260abc8b62f03ee0215f949..bc59844f77c8b80fee37bd70e692cdab785d7295 100644 (file)
@@ -34,7 +34,7 @@ warning: use of deprecated struct `unstable_generic_param::Struct4`: test
   --> $DIR/generics-default-stability.rs:83:12
    |
 LL |     let _: Struct4<isize> = Struct4 { field: 1 };
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^
 
 warning: use of deprecated struct `unstable_generic_param::Struct4`: test
   --> $DIR/generics-default-stability.rs:88:12
@@ -46,7 +46,7 @@ warning: use of deprecated struct `unstable_generic_param::Struct4`: test
   --> $DIR/generics-default-stability.rs:89:12
    |
 LL |     let _: Struct4<usize> = STRUCT4;
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^
 
 warning: use of deprecated struct `unstable_generic_param::Struct4`: test
   --> $DIR/generics-default-stability.rs:90:29
@@ -58,7 +58,7 @@ warning: use of deprecated struct `unstable_generic_param::Struct4`: test
   --> $DIR/generics-default-stability.rs:90:12
    |
 LL |     let _: Struct4<isize> = Struct4 { field: 0 };
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^
 
 warning: use of deprecated struct `unstable_generic_param::Struct5`: test
   --> $DIR/generics-default-stability.rs:96:29
@@ -70,7 +70,7 @@ warning: use of deprecated struct `unstable_generic_param::Struct5`: test
   --> $DIR/generics-default-stability.rs:96:12
    |
 LL |     let _: Struct5<isize> = Struct5 { field: 1 };
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^
 
 warning: use of deprecated struct `unstable_generic_param::Struct5`: test
   --> $DIR/generics-default-stability.rs:101:12
@@ -82,7 +82,7 @@ warning: use of deprecated struct `unstable_generic_param::Struct5`: test
   --> $DIR/generics-default-stability.rs:102:12
    |
 LL |     let _: Struct5<usize> = STRUCT5;
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^
 
 warning: use of deprecated struct `unstable_generic_param::Struct5`: test
   --> $DIR/generics-default-stability.rs:104:29
@@ -94,7 +94,7 @@ warning: use of deprecated struct `unstable_generic_param::Struct5`: test
   --> $DIR/generics-default-stability.rs:104:12
    |
 LL |     let _: Struct5<isize> = Struct5 { field: 0 };
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^
 
 warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
   --> $DIR/generics-default-stability.rs:159:28
@@ -106,7 +106,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
   --> $DIR/generics-default-stability.rs:159:12
    |
 LL |     let _: Alias4<isize> = Alias4::Some(1);
-   |            ^^^^^^^^^^^^^
+   |            ^^^^^^
 
 warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
   --> $DIR/generics-default-stability.rs:163:12
@@ -118,7 +118,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
   --> $DIR/generics-default-stability.rs:164:12
    |
 LL |     let _: Alias4<usize> = ALIAS4;
-   |            ^^^^^^^^^^^^^
+   |            ^^^^^^
 
 warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
   --> $DIR/generics-default-stability.rs:165:28
@@ -130,7 +130,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
   --> $DIR/generics-default-stability.rs:165:12
    |
 LL |     let _: Alias4<isize> = Alias4::Some(0);
-   |            ^^^^^^^^^^^^^
+   |            ^^^^^^
 
 warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
   --> $DIR/generics-default-stability.rs:170:28
@@ -142,7 +142,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
   --> $DIR/generics-default-stability.rs:170:12
    |
 LL |     let _: Alias5<isize> = Alias5::Some(1);
-   |            ^^^^^^^^^^^^^
+   |            ^^^^^^
 
 warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
   --> $DIR/generics-default-stability.rs:174:12
@@ -154,7 +154,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
   --> $DIR/generics-default-stability.rs:175:12
    |
 LL |     let _: Alias5<usize> = ALIAS5;
-   |            ^^^^^^^^^^^^^
+   |            ^^^^^^
 
 warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
   --> $DIR/generics-default-stability.rs:177:28
@@ -166,19 +166,19 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
   --> $DIR/generics-default-stability.rs:177:12
    |
 LL |     let _: Alias5<isize> = Alias5::Some(0);
-   |            ^^^^^^^^^^^^^
+   |            ^^^^^^
 
 warning: use of deprecated variant `unstable_generic_param::Enum4::Some`: test
-  --> $DIR/generics-default-stability.rs:231:27
+  --> $DIR/generics-default-stability.rs:231:34
    |
 LL |     let _: Enum4<isize> = Enum4::Some(1);
-   |                           ^^^^^^^^^^^
+   |                                  ^^^^
 
 warning: use of deprecated enum `unstable_generic_param::Enum4`: test
   --> $DIR/generics-default-stability.rs:231:12
    |
 LL |     let _: Enum4<isize> = Enum4::Some(1);
-   |            ^^^^^^^^^^^^
+   |            ^^^^^
 
 warning: use of deprecated enum `unstable_generic_param::Enum4`: test
   --> $DIR/generics-default-stability.rs:235:12
@@ -190,31 +190,31 @@ warning: use of deprecated enum `unstable_generic_param::Enum4`: test
   --> $DIR/generics-default-stability.rs:236:12
    |
 LL |     let _: Enum4<usize> = ENUM4;
-   |            ^^^^^^^^^^^^
+   |            ^^^^^
 
 warning: use of deprecated variant `unstable_generic_param::Enum4::Some`: test
-  --> $DIR/generics-default-stability.rs:237:27
+  --> $DIR/generics-default-stability.rs:237:34
    |
 LL |     let _: Enum4<isize> = Enum4::Some(0);
-   |                           ^^^^^^^^^^^
+   |                                  ^^^^
 
 warning: use of deprecated enum `unstable_generic_param::Enum4`: test
   --> $DIR/generics-default-stability.rs:237:12
    |
 LL |     let _: Enum4<isize> = Enum4::Some(0);
-   |            ^^^^^^^^^^^^
+   |            ^^^^^
 
 warning: use of deprecated variant `unstable_generic_param::Enum5::Some`: test
-  --> $DIR/generics-default-stability.rs:242:27
+  --> $DIR/generics-default-stability.rs:242:34
    |
 LL |     let _: Enum5<isize> = Enum5::Some(1);
-   |                           ^^^^^^^^^^^
+   |                                  ^^^^
 
 warning: use of deprecated enum `unstable_generic_param::Enum5`: test
   --> $DIR/generics-default-stability.rs:242:12
    |
 LL |     let _: Enum5<isize> = Enum5::Some(1);
-   |            ^^^^^^^^^^^^
+   |            ^^^^^
 
 warning: use of deprecated enum `unstable_generic_param::Enum5`: test
   --> $DIR/generics-default-stability.rs:246:12
@@ -226,19 +226,19 @@ warning: use of deprecated enum `unstable_generic_param::Enum5`: test
   --> $DIR/generics-default-stability.rs:247:12
    |
 LL |     let _: Enum5<usize> = ENUM5;
-   |            ^^^^^^^^^^^^
+   |            ^^^^^
 
 warning: use of deprecated variant `unstable_generic_param::Enum5::Some`: test
-  --> $DIR/generics-default-stability.rs:249:27
+  --> $DIR/generics-default-stability.rs:249:34
    |
 LL |     let _: Enum5<isize> = Enum5::Some(0);
-   |                           ^^^^^^^^^^^
+   |                                  ^^^^
 
 warning: use of deprecated enum `unstable_generic_param::Enum5`: test
   --> $DIR/generics-default-stability.rs:249:12
    |
 LL |     let _: Enum5<isize> = Enum5::Some(0);
-   |            ^^^^^^^^^^^^
+   |            ^^^^^
 
 error[E0658]: use of unstable library feature 'unstable_default'
   --> $DIR/generics-default-stability.rs:35:20
index 32367d2d0cf213b1acc49cd88865911899572709..7f931f0cdc9e8d11133f978284628b1ee70fe83c 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
   --> $DIR/issue-68049-1.rs:7:9
    |
 LL |         self.0 += 1;
index f10a83c68a81b062a6cb84c8ab28b168f29ec447..2f31193e4a4a2b1717bf3d1bd5acd45e9e21a74b 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `*input` which is behind a `&` reference
+error[E0594]: cannot assign to `*input`, which is behind a `&` reference
   --> $DIR/issue-68049-2.rs:9:7
    |
 LL |   fn example(&self, input: &i32); // should suggest here
@@ -7,7 +7,7 @@ LL |   fn example(&self, input: &i32); // should suggest here
 LL |       *input = self.0;
    |       ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
   --> $DIR/issue-68049-2.rs:17:5
    |
 LL |   fn example(&self, input: &i32); // should suggest here
index 6ab08197441c39a2654826518983683c503b9108..3eb9e1031d7067101cf620aa4f64aa06ad08c6dd 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `t.v` which is behind a `&` reference
+error[E0594]: cannot assign to `t.v`, which is behind a `&` reference
   --> $DIR/suggest-mut-method-for-loop.rs:14:9
    |
 LL |     for mut t in buzz.values() {
index b4981279a238b1f955d98aafdcd2f1727f5470b3..9fd2658ec702db71609de9cba8ea44458c58bc86 100644 (file)
@@ -1,4 +1,4 @@
-error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
   --> $DIR/suggest-ref-mut.rs:7:9
    |
 LL |     fn zap(&self) {
@@ -7,7 +7,7 @@ LL |     fn zap(&self) {
 LL |         self.0 = 32;
    |         ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*foo` which is behind a `&` reference
+error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
   --> $DIR/suggest-ref-mut.rs:16:5
    |
 LL |     let ref foo = 16;
@@ -16,7 +16,7 @@ LL |     let ref foo = 16;
 LL |     *foo = 32;
    |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*bar` which is behind a `&` reference
+error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
   --> $DIR/suggest-ref-mut.rs:21:9
    |
 LL |     if let Some(ref bar) = Some(16) {
@@ -25,7 +25,7 @@ LL |     if let Some(ref bar) = Some(16) {
 LL |         *bar = 32;
    |         ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
 
-error[E0594]: cannot assign to `*quo` which is behind a `&` reference
+error[E0594]: cannot assign to `*quo`, which is behind a `&` reference
   --> $DIR/suggest-ref-mut.rs:25:22
    |
 LL |         ref quo => { *quo = 32; },
diff --git a/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs b/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs
new file mode 100644 (file)
index 0000000..f882a15
--- /dev/null
@@ -0,0 +1,27 @@
+// Regression test for #87051, where a double semicolon was erroneously
+// suggested after a `?` operator.
+
+fn main() -> Result<(), ()> {
+    a(|| {
+        b()
+        //~^ ERROR: mismatched types [E0308]
+        //~| NOTE: expected `()`, found `i32`
+        //~| HELP: consider using a semicolon here
+    })?;
+
+    // Here, we do want to suggest a semicolon:
+    let x = Ok(42);
+    if true {
+    //~^ NOTE: expected this to be `()`
+        x?
+        //~^ ERROR: mismatched types [E0308]
+        //~| NOTE: expected `()`, found integer
+        //~| HELP: consider using a semicolon here
+    }
+    //~^ HELP: consider using a semicolon here
+
+    Ok(())
+}
+
+fn a<F>(f: F) -> Result<(), ()> where F: FnMut() { Ok(()) }
+fn b() -> i32 { 42 }
diff --git a/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr b/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr
new file mode 100644 (file)
index 0000000..4f7e187
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0308]: mismatched types
+  --> $DIR/try-operator-dont-suggest-semicolon.rs:6:9
+   |
+LL |         b()
+   |         ^^^- help: consider using a semicolon here: `;`
+   |         |
+   |         expected `()`, found `i32`
+
+error[E0308]: mismatched types
+  --> $DIR/try-operator-dont-suggest-semicolon.rs:16:9
+   |
+LL | /     if true {
+LL | |
+LL | |         x?
+   | |         ^^ expected `()`, found integer
+LL | |
+LL | |
+LL | |
+LL | |     }
+   | |_____- expected this to be `()`
+   |
+help: consider using a semicolon here
+   |
+LL |         x?;
+   |           ^
+help: consider using a semicolon here
+   |
+LL |     };
+   |      ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..427843f
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints2.rs:11:13
+   |
+LL |     let y = &mut x.0;
+   |             ^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
index 68ba120b279c02a80bdde064cea4bd3fe7f581ba..9a6bb18f9266494cd926f8f4d05b84d5cfeac803 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![feature(rustc_attrs)]
 
 #[rustc_layout_scalar_valid_range_start(1)]
diff --git a/src/test/ui/unsafe/ranged_ints2.stderr b/src/test/ui/unsafe/ranged_ints2.stderr
deleted file mode 100644 (file)
index ee1d1f1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
-  --> $DIR/ranged_ints2.rs:8:13
-   |
-LL |     let y = &mut x.0;
-   |             ^^^^^^^^ mutation of layout constrained field
-   |
-   = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..427843f
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints2.rs:11:13
+   |
+LL |     let y = &mut x.0;
+   |             ^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2_const.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..c16550a
--- /dev/null
@@ -0,0 +1,39 @@
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/ranged_ints2_const.rs:14:13
+   |
+LL |     let y = &mut x.0;
+   |             ^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/ranged_ints2_const.rs:21:22
+   |
+LL |     let y = unsafe { &mut x.0 };
+   |                      ^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/ranged_ints2_const.rs:27:22
+   |
+LL |     unsafe { let y = &mut x.0; }
+   |                      ^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints2_const.rs:14:13
+   |
+LL |     let y = &mut x.0;
+   |             ^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
index b7178c2b52bfbff8424977ee5d71a5c90ac0cbf7..56f5407bb6ebe6dc1e54238f1a2f293d7f9027c1 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![feature(rustc_attrs)]
 
 #[rustc_layout_scalar_valid_range_start(1)]
diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr
deleted file mode 100644 (file)
index a0dc950..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/ranged_ints2_const.rs:11:13
-   |
-LL |     let y = &mut x.0;
-   |             ^^^^^^^^
-   |
-   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/ranged_ints2_const.rs:18:22
-   |
-LL |     let y = unsafe { &mut x.0 };
-   |                      ^^^^^^^^
-   |
-   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error[E0658]: mutable references are not allowed in constant functions
-  --> $DIR/ranged_ints2_const.rs:24:22
-   |
-LL |     unsafe { let y = &mut x.0; }
-   |                      ^^^^^^^^
-   |
-   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
-  --> $DIR/ranged_ints2_const.rs:11:13
-   |
-LL |     let y = &mut x.0;
-   |             ^^^^^^^^ mutation of layout constrained field
-   |
-   = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0133, E0658.
-For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints2_const.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..b3f139f
--- /dev/null
@@ -0,0 +1,39 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints2_const.rs:14:13
+   |
+LL |     let y = &mut x.0;
+   |             ^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/ranged_ints2_const.rs:14:13
+   |
+LL |     let y = &mut x.0;
+   |             ^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/ranged_ints2_const.rs:21:22
+   |
+LL |     let y = unsafe { &mut x.0 };
+   |                      ^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/ranged_ints2_const.rs:27:22
+   |
+LL |     unsafe { let y = &mut x.0; }
+   |                      ^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..9eec0b0
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3.rs:13:13
+   |
+LL |     let y = &x.0;
+   |             ^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
index 47d67fac6785c651f030b15970cc7d16caea7dd4..76d4bfe95307d763e9b52742b3c2a919fc822a05 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![feature(rustc_attrs)]
 
 use std::cell::Cell;
diff --git a/src/test/ui/unsafe/ranged_ints3.stderr b/src/test/ui/unsafe/ranged_ints3.stderr
deleted file mode 100644 (file)
index 4d4c916..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
-  --> $DIR/ranged_ints3.rs:10:13
-   |
-LL |     let y = &x.0;
-   |             ^^^^ borrow of layout constrained field with interior mutability
-   |
-   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..9eec0b0
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3.rs:13:13
+   |
+LL |     let y = &x.0;
+   |             ^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_const.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..62df933
--- /dev/null
@@ -0,0 +1,30 @@
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+  --> $DIR/ranged_ints3_const.rs:15:13
+   |
+LL |     let y = &x.0;
+   |             ^^^^
+   |
+   = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+   = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+  --> $DIR/ranged_ints3_const.rs:22:22
+   |
+LL |     let y = unsafe { &x.0 };
+   |                      ^^^^
+   |
+   = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+   = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_const.rs:15:13
+   |
+LL |     let y = &x.0;
+   |             ^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
index c069ae7da021232d8ab79ec6e543440857152d89..637198d36042239e8edb0f5aba0c9eb62540ecb1 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![feature(rustc_attrs)]
 
 use std::cell::Cell;
diff --git a/src/test/ui/unsafe/ranged_ints3_const.stderr b/src/test/ui/unsafe/ranged_ints3_const.stderr
deleted file mode 100644 (file)
index 2150055..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
-  --> $DIR/ranged_ints3_const.rs:12:13
-   |
-LL |     let y = &x.0;
-   |             ^^^^
-   |
-   = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
-   = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
-
-error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
-  --> $DIR/ranged_ints3_const.rs:19:22
-   |
-LL |     let y = unsafe { &x.0 };
-   |                      ^^^^
-   |
-   = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
-   = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
-
-error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
-  --> $DIR/ranged_ints3_const.rs:12:13
-   |
-LL |     let y = &x.0;
-   |             ^^^^ borrow of layout constrained field with interior mutability
-   |
-   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0133, E0658.
-For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_const.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..5dbc563
--- /dev/null
@@ -0,0 +1,30 @@
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_const.rs:15:13
+   |
+LL |     let y = &x.0;
+   |             ^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+  --> $DIR/ranged_ints3_const.rs:15:13
+   |
+LL |     let y = &x.0;
+   |             ^^^^
+   |
+   = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+   = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+  --> $DIR/ranged_ints3_const.rs:22:22
+   |
+LL |     let y = unsafe { &x.0 };
+   |                      ^^^^
+   |
+   = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+   = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_match.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..27c0664
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_match.rs:14:17
+   |
+LL |         NonZero(ref x) => { x }
+   |                 ^^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_match.rs:20:23
+   |
+LL |     match y { NonZero(ref mut y) => { y } };
+   |                       ^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3_match.rs b/src/test/ui/unsafe/ranged_ints3_match.rs
new file mode 100644 (file)
index 0000000..d9fcf0b
--- /dev/null
@@ -0,0 +1,22 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+    let mut x = unsafe { NonZero(Cell::new(1)) };
+    match x {
+        NonZero(ref x) => { x }
+        //~^ ERROR borrow of layout constrained field with interior mutability
+    };
+
+    let mut y = unsafe { NonZero(42) };
+    match y { NonZero(ref y) => { y } }; // OK, type of `y` is freeze
+    match y { NonZero(ref mut y) => { y } };
+    //~^ ERROR mutation of layout constrained field
+}
diff --git a/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints3_match.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..27c0664
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_match.rs:14:17
+   |
+LL |         NonZero(ref x) => { x }
+   |                 ^^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_match.rs:20:23
+   |
+LL |     match y { NonZero(ref mut y) => { y } };
+   |                       ^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..493483d
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4.rs:11:5
+   |
+LL |     x.0 = 0;
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
index d8632c48434f25f1653ea41aeec4c889b2739e65..fe80af454cb8d1396a097fcbc441d5e401ddf7b3 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![feature(rustc_attrs)]
 
 #[rustc_layout_scalar_valid_range_start(1)]
diff --git a/src/test/ui/unsafe/ranged_ints4.stderr b/src/test/ui/unsafe/ranged_ints4.stderr
deleted file mode 100644 (file)
index 68c2258..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
-  --> $DIR/ranged_ints4.rs:8:5
-   |
-LL |     x.0 = 0;
-   |     ^^^^^^^ mutation of layout constrained field
-   |
-   = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..493483d
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4.rs:11:5
+   |
+LL |     x.0 = 0;
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4_const.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..a06c6f4
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4_const.rs:13:5
+   |
+LL |     x.0 = 0;
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
index f09168c3d3f9ca48a8225cc0b165cb0d62d6fb1a..a43c8be71c4fd2e2338a4b35cb8ea12e7288cb2e 100644 (file)
@@ -1,3 +1,6 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
 #![feature(rustc_attrs)]
 
 #[rustc_layout_scalar_valid_range_start(1)]
diff --git a/src/test/ui/unsafe/ranged_ints4_const.stderr b/src/test/ui/unsafe/ranged_ints4_const.stderr
deleted file mode 100644 (file)
index fe83b15..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
-  --> $DIR/ranged_ints4_const.rs:10:5
-   |
-LL |     x.0 = 0;
-   |     ^^^^^^^ mutation of layout constrained field
-   |
-   = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr b/src/test/ui/unsafe/ranged_ints4_const.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..a06c6f4
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4_const.rs:13:5
+   |
+LL |     x.0 = 0;
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr b/src/test/ui/unsafe/unsafe-assign.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..9abc514
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-assign.rs:12:5
+   |
+LL |     foo.0.0 = 0;
+   |     ^^^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/unsafe-assign.rs b/src/test/ui/unsafe/unsafe-assign.rs
new file mode 100644 (file)
index 0000000..1527316
--- /dev/null
@@ -0,0 +1,25 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(rustc_attrs)]
+#![allow(unused,dead_code)]
+
+fn nested_field() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<T>(T);
+
+    let mut foo = unsafe { NonZero((1,)) };
+    foo.0.0 = 0;
+    //~^ ERROR: mutation of layout constrained field is unsafe
+}
+
+fn block() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<T>(T);
+
+    let mut foo = unsafe { NonZero((1,)) };
+    { foo.0 }.0 = 0;
+    // ^ not unsafe because the result of the block expression is a new place
+}
+
+fn main() {}
diff --git a/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr b/src/test/ui/unsafe/unsafe-assign.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..9abc514
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-assign.rs:12:5
+   |
+LL |     foo.0.0 = 0;
+   |     ^^^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr b/src/test/ui/unsafe/unsafe-borrow.mirunsafeck.stderr
new file mode 100644 (file)
index 0000000..a206722
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-borrow.rs:12:13
+   |
+LL |     let a = &mut foo.0.0;
+   |             ^^^^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-borrow.rs:32:13
+   |
+LL |     let a = &mut foo.0[2];
+   |             ^^^^^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-borrow.rs:51:18
+   |
+LL |         NonZero((a,)) => *a = 0,
+   |                  ^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/unsafe-borrow.rs b/src/test/ui/unsafe/unsafe-borrow.rs
new file mode 100644 (file)
index 0000000..8dddc70
--- /dev/null
@@ -0,0 +1,56 @@
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(rustc_attrs)]
+#![allow(unused,dead_code)]
+
+fn tuple_struct() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<T>(T);
+
+    let mut foo = unsafe { NonZero((1,)) };
+    let a = &mut foo.0.0;
+    //~^ ERROR: mutation of layout constrained field is unsafe
+}
+
+fn slice() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<'a, T>(&'a mut [T]);
+
+    let mut nums = [1, 2, 3, 4];
+    let mut foo = unsafe { NonZero(&mut nums[..]) };
+    let a = &mut foo.0[2];
+    // ^ not unsafe because there is an implicit dereference here
+}
+
+fn array() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<T>([T; 4]);
+
+    let nums = [1, 2, 3, 4];
+    let mut foo = unsafe { NonZero(nums) };
+    let a = &mut foo.0[2];
+    //~^ ERROR: mutation of layout constrained field is unsafe
+}
+
+fn block() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<T>(T);
+
+    let foo = unsafe { NonZero((1,)) };
+    &mut { foo.0 }.0;
+    // ^ not unsafe because the result of the block expression is a new place
+}
+
+fn mtch() {
+    #[rustc_layout_scalar_valid_range_start(1)]
+    struct NonZero<T>(T);
+
+    let mut foo = unsafe { NonZero((1,)) };
+    match &mut foo {
+        NonZero((a,)) => *a = 0,
+        //~^ ERROR: mutation of layout constrained field is unsafe
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr b/src/test/ui/unsafe/unsafe-borrow.thirunsafeck.stderr
new file mode 100644 (file)
index 0000000..a206722
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-borrow.rs:12:13
+   |
+LL |     let a = &mut foo.0.0;
+   |             ^^^^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-borrow.rs:32:13
+   |
+LL |     let a = &mut foo.0[2];
+   |             ^^^^^^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-borrow.rs:51:18
+   |
+LL |         NonZero((a,)) => *a = 0,
+   |                  ^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
index 03fe0d16d480f792f8138a3480812604ab183cb4..9a040ca572af51613733a328828800d25ec6693b 100644 (file)
@@ -1,4 +1,4 @@
-#![allow(rustc::default_hash_types)]
+#![cfg_attr(bootstrap, allow(rustc::default_hash_types))]
 
 use std::borrow::Cow;
 use std::collections::BTreeMap;
index e5c1c8cf2fcfae3e15c8bcf5256e84cad3bd3436..fe00358888a24c64878abc15f09b0e60e16db9d6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit e5c1c8cf2fcfae3e15c8bcf5256e84cad3bd3436
+Subproject commit fe00358888a24c64878abc15f09b0e60e16db9d6
index 31cdc6865a4022c199880c2b57a693ada29ef3bc..24a100187797256866b86df0d2f5cb8d2e7fb427 100644 (file)
@@ -122,6 +122,7 @@ fn check_cfgs(
 
         let contains_platform_specific_cfg = cfg.contains("target_os")
             || cfg.contains("target_env")
+            || cfg.contains("target_abi")
             || cfg.contains("target_vendor")
             || cfg.contains("unix")
             || cfg.contains("windows");