From 7d169a60a50a2bdbfb3492b8f6673b22769731df Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 30 Mar 2021 15:00:14 +0200
Subject: [PATCH 1/4] Deprecate #![crate_type]

---
 compiler/rustc_lint/src/builtin.rs      | 20 +++++++++++
 compiler/rustc_lint/src/lib.rs          |  1 +
 compiler/rustc_lint_defs/src/builtin.rs | 48 +++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 218248e715b4b..d7a7710368445 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2961,3 +2961,23 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations {
         }
     }
 }
+
+pub(crate) struct DeprecatedCrateInfoAttrs;
+
+impl_lint_pass!(DeprecatedCrateInfoAttrs => [DEPRECATED_CRATE_INFO_ATTRS]);
+
+impl EarlyLintPass for DeprecatedCrateInfoAttrs {
+    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
+        for attr in &krate.attrs {
+            if attr.has_name(sym::crate_type) {
+                cx.struct_span_lint(DEPRECATED_CRATE_INFO_ATTRS, attr.span, |lint| {
+                    lint.build("using deprecated `#![crate_type]` attribute").emit();
+                })
+            } else if attr.has_name(sym::crate_name) {
+                cx.struct_span_lint(DEPRECATED_CRATE_INFO_ATTRS, attr.span, |lint| {
+                    lint.build("using deprecated `#![crate_name]` attribute").emit();
+                })
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index e2724b52453a5..6a6dd11f73473 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -132,6 +132,7 @@ macro_rules! early_lint_passes {
                 IncompleteFeatures: IncompleteFeatures,
                 RedundantSemicolons: RedundantSemicolons,
                 UnusedDocComment: UnusedDocComment,
+                DeprecatedCrateInfoAttrs: DeprecatedCrateInfoAttrs,
             ]
         );
     };
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 4eaee7bf6e854..1fa9ac9785e39 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2959,6 +2959,7 @@ declare_lint_pass! {
         DISJOINT_CAPTURE_DROP_REORDER,
         LEGACY_DERIVE_HELPERS,
         PROC_MACRO_BACK_COMPAT,
+        DEPRECATED_CRATE_INFO_ATTRS,
     ]
 }
 
@@ -3136,3 +3137,50 @@ declare_lint! {
         })
     };
 }
+
+declare_lint! {
+    /// The `deprecated_crate_info_attrs` lint detects uses of the `#![crate_type]`
+    /// and `#![crate_name]` attributes to specify the crate type and name in the
+    /// source code.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![crate_type = "lib"]
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: using deprecated `#![crate_type]` attribute
+    ///   ::: $DIR/group-compat-hack.rs:1:5
+    ///    |
+    /// LL |     #![crate_type = "lib"]
+    ///    |     ^^^^^^^^^^^^^^^^^^^^^^
+    ///    |
+    ///    = note: `#[warn(deprecated_crate_info_attrs)]` on by default
+    ///    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    ///    = note: for more information, see issue #XXXXX <https://github.com/rust-lang/rust/issues/XXXXX>
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// The `#![crate_type]` and `#![crate_name]` attributes require a hack in the
+    /// compiler to be able to change the used crate type and crate name after the
+    /// program has been parsed. Neither attribute works in combination with Cargo
+    /// as it explicitly passes `--crate-type` and `--crate-name` on the commandline,
+    /// which must match to the value used in the source code.
+    ///
+    /// To fix the warning use `--crate-type` on the commandline when running rustc
+    /// instead of `#![crate_type]` and `--crate-name` instead of `#![crate_name]`.
+    pub DEPRECATED_CRATE_INFO_ATTRS,
+    Warn,
+    "detects deprecated usage of #![crate_type] and #![crate_name]",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #XXXXX <https://github.com/rust-lang/rust/issues/XXXXX>", // FIXME
+        edition: None,
+        future_breakage: Some(FutureBreakage {
+            date: None
+        })
+    };
+}

From 7057644cfe123dced919b6cf8993a8d1b3ca947f Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 30 Mar 2021 15:08:03 +0200
Subject: [PATCH 2/4] Fix file extension for two tests

---
 src/test/ui/{attr-bad-crate-attr.rc => attr-bad-crate-attr.rs} | 0
 src/test/ui/{dupe-first-attr.rc => dupe-first-attr.rs}         | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{attr-bad-crate-attr.rc => attr-bad-crate-attr.rs} (100%)
 rename src/test/ui/{dupe-first-attr.rc => dupe-first-attr.rs} (100%)

diff --git a/src/test/ui/attr-bad-crate-attr.rc b/src/test/ui/attr-bad-crate-attr.rs
similarity index 100%
rename from src/test/ui/attr-bad-crate-attr.rc
rename to src/test/ui/attr-bad-crate-attr.rs
diff --git a/src/test/ui/dupe-first-attr.rc b/src/test/ui/dupe-first-attr.rs
similarity index 100%
rename from src/test/ui/dupe-first-attr.rc
rename to src/test/ui/dupe-first-attr.rs

From 5f290b6f211288674cce4b5de42901ed8693d0c9 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 30 Mar 2021 15:10:00 +0200
Subject: [PATCH 3/4] Add tests

---
 src/test/ui/attributes/deprecated-crate-info-attrs.rs     | 2 ++
 src/test/ui/attributes/deprecated-crate-info-attrs.stderr | 0
 2 files changed, 2 insertions(+)
 create mode 100644 src/test/ui/attributes/deprecated-crate-info-attrs.rs
 create mode 100644 src/test/ui/attributes/deprecated-crate-info-attrs.stderr

diff --git a/src/test/ui/attributes/deprecated-crate-info-attrs.rs b/src/test/ui/attributes/deprecated-crate-info-attrs.rs
new file mode 100644
index 0000000000000..9d175f944253f
--- /dev/null
+++ b/src/test/ui/attributes/deprecated-crate-info-attrs.rs
@@ -0,0 +1,2 @@
+#![crate_type = "lib"] //~WARN using deprecated `#![crate_type]` attribute
+#![crate_name = "foo"] //~WARN using deprecated `#![crate_name]` attribute
diff --git a/src/test/ui/attributes/deprecated-crate-info-attrs.stderr b/src/test/ui/attributes/deprecated-crate-info-attrs.stderr
new file mode 100644
index 0000000000000..e69de29bb2d1d

From 117aa27ed4b5dcd53a26a43ecceb0b8224b1cf17 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 30 Mar 2021 15:26:12 +0200
Subject: [PATCH 4/4] Remove #![crate_type] and #![crate_name] usage from a few
 crates

---
 library/rtstartup/rsbegin.rs      | 1 -
 library/rtstartup/rsend.rs        | 1 -
 library/test/src/lib.rs           | 1 -
 src/bootstrap/compile.rs          | 2 ++
 src/tools/compiletest/src/main.rs | 1 -
 5 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs
index c6a4548ec0c2d..de0d59e07ba1b 100644
--- a/library/rtstartup/rsbegin.rs
+++ b/library/rtstartup/rsbegin.rs
@@ -15,7 +15,6 @@
 #![feature(no_core)]
 #![feature(lang_items)]
 #![feature(auto_traits)]
-#![crate_type = "rlib"]
 #![no_core]
 #![allow(non_camel_case_types)]
 
diff --git a/library/rtstartup/rsend.rs b/library/rtstartup/rsend.rs
index d5aca80edf9e0..2f3cb5091b464 100644
--- a/library/rtstartup/rsend.rs
+++ b/library/rtstartup/rsend.rs
@@ -3,7 +3,6 @@
 #![feature(no_core)]
 #![feature(lang_items)]
 #![feature(auto_traits)]
-#![crate_type = "rlib"]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 7683f792b8dbf..77f86096032f1 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -17,7 +17,6 @@
 // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by
 // cargo) to detect this crate.
 
-#![crate_name = "test"]
 #![unstable(feature = "test", issue = "50297")]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
 #![cfg_attr(unix, feature(libc))]
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 9398f211721b8..5ef1b1bd957ea 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -467,6 +467,8 @@ impl Step for StartupObjects {
                         .arg("--target")
                         .arg(target.rustc_target_arg())
                         .arg("--emit=obj")
+                        .arg("--crate-type")
+                        .arg("rlib")
                         .arg("-o")
                         .arg(dst_file)
                         .arg(src_file),
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 1d4b5e1247de7..4cb6a59970487 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -1,4 +1,3 @@
-#![crate_name = "compiletest"]
 // The `test` crate is the only unstable feature
 // allowed here, just to share similar code.
 #![feature(test)]