From 912783402fe2f0d1fff41b047b0918e7e58e18ae Mon Sep 17 00:00:00 2001
From: David Wood <david.wood@huawei.com>
Date: Wed, 8 Feb 2023 13:25:38 +0000
Subject: [PATCH 01/12] const_eval: `implies_by` in `rustc_const_unstable`

Extend support for `implies_by` (from `#[stable]` and `#[unstable]`)
to `#[rustc_const_stable]` and `#[rustc_const_unstable]`.

Signed-off-by: David Wood <david.wood@huawei.com>
---
 .../src/const_eval/fn_queries.rs              | 13 ++++++++---
 .../src/transform/check_consts/check.rs       | 16 ++++++++++----
 compiler/rustc_passes/src/stability.rs        |  9 ++++++++
 .../const-stability-attribute-implies.rs      | 12 ++++++++++
 ...nst-stability-attribute-implies-missing.rs | 16 ++++++++++++++
 ...stability-attribute-implies-missing.stderr |  8 +++++++
 ...-stability-attribute-implies-no-feature.rs | 16 ++++++++++++++
 ...bility-attribute-implies-no-feature.stderr | 10 +++++++++
 ...tability-attribute-implies-using-stable.rs | 19 ++++++++++++++++
 ...lity-attribute-implies-using-stable.stderr | 22 +++++++++++++++++++
 ...bility-attribute-implies-using-unstable.rs | 21 ++++++++++++++++++
 ...ty-attribute-implies-using-unstable.stderr | 22 +++++++++++++++++++
 12 files changed, 177 insertions(+), 7 deletions(-)
 create mode 100644 tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs
 create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr

diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index f92277b111374..b7e05376c0e2c 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -1,3 +1,4 @@
+use rustc_attr as attr;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -5,11 +6,17 @@ use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{DefIdTree, TyCtxt};
 use rustc_span::symbol::Symbol;
 
-/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
-pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
+/// Whether the `def_id` is an unstable const fn and what feature gate(s) are necessary to enable
+/// it.
+pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<(Symbol, Option<Symbol>)> {
     if tcx.is_const_fn_raw(def_id) {
         let const_stab = tcx.lookup_const_stability(def_id)?;
-        if const_stab.is_const_unstable() { Some(const_stab.feature) } else { None }
+        match const_stab.level {
+            attr::StabilityLevel::Unstable { implied_by, .. } => {
+                Some((const_stab.feature, implied_by))
+            }
+            attr::StabilityLevel::Stable { .. } => None,
+        }
     } else {
         None
     }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 1a23b06d2e89c..d11cc65da16da 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -926,15 +926,24 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                 // If the `const fn` we are trying to call is not const-stable, ensure that we have
                 // the proper feature gate enabled.
-                if let Some(gate) = is_unstable_const_fn(tcx, callee) {
+                if let Some((gate, implied_by)) = is_unstable_const_fn(tcx, callee) {
                     trace!(?gate, "calling unstable const fn");
                     if self.span.allows_unstable(gate) {
                         return;
                     }
+                    if let Some(implied_by_gate) = implied_by && self.span.allows_unstable(implied_by_gate) {
+                        return;
+                    }
 
                     // Calling an unstable function *always* requires that the corresponding gate
-                    // be enabled, even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`.
-                    if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate) {
+                    // (or implied gate) be enabled, even if the function has
+                    // `#[rustc_allow_const_fn_unstable(the_gate)]`.
+                    let gate_declared = |gate| {
+                        tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate)
+                    };
+                    let feature_gate_declared = gate_declared(gate);
+                    let implied_gate_declared = implied_by.map(gate_declared).unwrap_or(false);
+                    if !feature_gate_declared && !implied_gate_declared {
                         self.check_op(ops::FnCallUnstable(callee, Some(gate)));
                         return;
                     }
@@ -947,7 +956,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     }
 
                     // Otherwise, we are something const-stable calling a const-unstable fn.
-
                     if super::rustc_allow_const_fn_unstable(tcx, caller, gate) {
                         trace!("rustc_allow_const_fn_unstable gate active");
                         return;
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 7299fc9705cc6..7617818f64280 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -265,6 +265,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 self.index.implications.insert(implied_by, feature);
             }
 
+            if let Some(ConstStability {
+                level: Unstable { implied_by: Some(implied_by), .. },
+                feature,
+                ..
+            }) = const_stab
+            {
+                self.index.implications.insert(implied_by, feature);
+            }
+
             self.index.stab_map.insert(def_id, stab);
             stab
         });
diff --git a/tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs b/tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs
new file mode 100644
index 0000000000000..f78871b5a1d66
--- /dev/null
+++ b/tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs
@@ -0,0 +1,12 @@
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "stability_attribute_implies", since = "1.0.0")]
+#![rustc_const_stable(feature = "stability_attribute_implies", since = "1.0.0")]
+
+#[stable(feature = "stability_attribute_implies", since = "1.0.0")]
+#[rustc_const_stable(feature = "const_foo", since = "1.62.0")]
+pub const fn foo() {}
+
+#[stable(feature = "stability_attribute_implies", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_foo")]
+pub const fn foobar() {}
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs
new file mode 100644
index 0000000000000..6d6d793c62b76
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs
@@ -0,0 +1,16 @@
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "stability_attribute_implies", since = "1.0.0")]
+#![rustc_const_stable(feature = "stability_attribute_implies", since = "1.0.0")]
+
+// Tests that `implied_by = "const_bar"` results in an error being emitted if `const_bar` does not
+// exist.
+
+#[stable(feature = "stability_attribute_implies", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_bar")]
+//~^ ERROR feature `const_bar` implying `const_foobar` does not exist
+pub const fn foobar() -> u32 {
+    0
+}
+
+const VAR: u32 = foobar();
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr
new file mode 100644
index 0000000000000..6d8b01a549523
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr
@@ -0,0 +1,8 @@
+error: feature `const_bar` implying `const_foobar` does not exist
+  --> $DIR/const-stability-attribute-implies-missing.rs:10:1
+   |
+LL | #[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_bar")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs
new file mode 100644
index 0000000000000..47e8d2b3609c5
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs
@@ -0,0 +1,16 @@
+// aux-build:const-stability-attribute-implies.rs
+#![crate_type = "lib"]
+
+// Tests that despite the `const_foobar` feature being implied by now-stable feature `const_foo`,
+// if `const_foobar` isn't allowed in this crate then an error will be emitted.
+
+extern crate const_stability_attribute_implies;
+use const_stability_attribute_implies::{foo, foobar};
+
+pub const fn bar() -> u32 {
+    foo(); // no error - stable
+    foobar(); //~ ERROR `foobar` is not yet stable as a const fn
+    0
+}
+
+pub const VAR: u32 = bar();
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr
new file mode 100644
index 0000000000000..8ef5a364ecc45
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr
@@ -0,0 +1,10 @@
+error: `foobar` is not yet stable as a const fn
+  --> $DIR/const-stability-attribute-implies-no-feature.rs:12:5
+   |
+LL |     foobar();
+   |     ^^^^^^^^
+   |
+   = help: add `#![feature(const_foobar)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs
new file mode 100644
index 0000000000000..ffaa171d8a5f7
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs
@@ -0,0 +1,19 @@
+// aux-build:const-stability-attribute-implies.rs
+#![crate_type = "lib"]
+#![deny(stable_features)]
+#![feature(const_foo)]
+//~^ ERROR the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar`
+
+// Tests that the use of `implied_by` in the `#[rustc_const_unstable]` attribute results in a
+// diagnostic mentioning partial stabilization, and that given the implied unstable feature is
+// unused (there is no `foobar` call), that the compiler suggests removing the flag.
+
+extern crate const_stability_attribute_implies;
+use const_stability_attribute_implies::foo;
+
+pub const fn bar() -> u32 {
+    foo();
+    0
+}
+
+pub const VAR: u32 = bar();
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr
new file mode 100644
index 0000000000000..f6a099cd25e7a
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr
@@ -0,0 +1,22 @@
+error: the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar`
+  --> $DIR/const-stability-attribute-implies-using-stable.rs:4:12
+   |
+LL | #![feature(const_foo)]
+   |            ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/const-stability-attribute-implies-using-stable.rs:3:9
+   |
+LL | #![deny(stable_features)]
+   |         ^^^^^^^^^^^^^^^
+help: if you are using features which are still unstable, change to using `const_foobar`
+   |
+LL | #![feature(const_foobar)]
+   |            ~~~~~~~~~~~~
+help: if you are using features which are now stable, remove this line
+   |
+LL - #![feature(const_foo)]
+   |
+
+error: aborting due to previous error
+
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs
new file mode 100644
index 0000000000000..2061c5c75bd81
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs
@@ -0,0 +1,21 @@
+// aux-build:const-stability-attribute-implies.rs
+#![crate_type = "lib"]
+#![deny(stable_features)]
+#![feature(const_foo)]
+//~^ ERROR the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar`
+
+// Tests that the use of `implied_by` in the `#[rustc_const_unstable]` attribute results in a
+// diagnostic mentioning partial stabilization and that given the implied unstable feature is
+// used (there is a `const_foobar` call), that the compiler suggests changing to that feature and
+// doesn't error about its use.
+
+extern crate const_stability_attribute_implies;
+use const_stability_attribute_implies::{foo, foobar};
+
+pub const fn bar() -> u32 {
+    foo();
+    foobar(); // no error!
+    0
+}
+
+pub const VAR: u32 = bar();
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr
new file mode 100644
index 0000000000000..0638566765822
--- /dev/null
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr
@@ -0,0 +1,22 @@
+error: the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar`
+  --> $DIR/const-stability-attribute-implies-using-unstable.rs:4:12
+   |
+LL | #![feature(const_foo)]
+   |            ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/const-stability-attribute-implies-using-unstable.rs:3:9
+   |
+LL | #![deny(stable_features)]
+   |         ^^^^^^^^^^^^^^^
+help: if you are using features which are still unstable, change to using `const_foobar`
+   |
+LL | #![feature(const_foobar)]
+   |            ~~~~~~~~~~~~
+help: if you are using features which are now stable, remove this line
+   |
+LL - #![feature(const_foo)]
+   |
+
+error: aborting due to previous error
+

From b2f8f60c070ca369d07fd4bae6fb6e3d8fd97cb9 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 21 Feb 2023 05:16:35 +0000
Subject: [PATCH 02/12] Place binder correctly for arbitrary trait bound
 suggestion

---
 compiler/rustc_middle/src/ty/diagnostics.rs   |  4 ++--
 ...correct-binder-for-arbitrary-bound-sugg.rs | 16 ++++++++++++++
 ...ect-binder-for-arbitrary-bound-sugg.stderr | 22 +++++++++++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs
 create mode 100644 tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr

diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index a029c1b209df4..ba58f2df376e7 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -118,7 +118,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
     }
 
     let param_name = trait_pred.skip_binder().self_ty().to_string();
-    let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string();
+    let mut constraint = trait_pred.to_string();
 
     if let Some((name, term)) = associated_ty {
         // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
@@ -145,7 +145,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
              this requirement",
             if generics.where_clause_span.is_empty() { "introducing a" } else { "extending the" },
         ),
-        format!("{} {}: {}", generics.add_where_or_trailing_comma(), param_name, constraint),
+        format!("{} {constraint}", generics.add_where_or_trailing_comma()),
         Applicability::MaybeIncorrect,
     );
     true
diff --git a/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs
new file mode 100644
index 0000000000000..e56c8622ece03
--- /dev/null
+++ b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs
@@ -0,0 +1,16 @@
+trait Foo
+where
+    for<'a> &'a Self: Bar,
+{
+}
+
+impl Foo for () {}
+
+trait Bar {}
+
+impl Bar for &() {}
+
+fn foo<T: Foo>() {}
+//~^ ERROR the trait bound `for<'a> &'a T: Bar` is not satisfied
+
+fn main() {}
diff --git a/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr
new file mode 100644
index 0000000000000..e024cbb161074
--- /dev/null
+++ b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `for<'a> &'a T: Bar` is not satisfied
+  --> $DIR/correct-binder-for-arbitrary-bound-sugg.rs:13:11
+   |
+LL | fn foo<T: Foo>() {}
+   |           ^^^ the trait `for<'a> Bar` is not implemented for `&'a T`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/correct-binder-for-arbitrary-bound-sugg.rs:3:23
+   |
+LL | trait Foo
+   |       --- required by a bound in this
+LL | where
+LL |     for<'a> &'a Self: Bar,
+   |                       ^^^ required by this bound in `Foo`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn foo<T: Foo>() where for<'a> &'a T: Bar {}
+   |                  ++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.

From 1f92c61e733482b08bed894c069a5f2ba38292da Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Sat, 4 Mar 2023 20:57:30 +0000
Subject: [PATCH 03/12] sub is not sup

---
 compiler/rustc_trait_selection/src/traits/engine.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index b20636174eeac..62d5e50dbc548 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -158,7 +158,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         self.infcx
             .at(cause, param_env)
             .define_opaque_types(true)
-            .sup(expected, actual)
+            .sub(expected, actual)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
 

From beebd3a4c6ab38a71d4ff7cafcd1bf37def5b721 Mon Sep 17 00:00:00 2001
From: Giacomo Pasini <giacomo@status.im>
Date: Sun, 5 Mar 2023 16:56:57 +0100
Subject: [PATCH 04/12] Add regression tests for issue 70919

Desugaring DropAndReplace at MIR build (#107844) fixed issue
70919. Add regressions tests, borrowed from #102078, to ensure we
check for this in the future.

Co-authored-by: Aaron Hill <aa1ronham@gmail.com>
---
 tests/ui/borrowck/drop-in-loop.rs             | 24 ++++++++++++++++++
 tests/ui/borrowck/drop-in-loop.stderr         | 14 +++++++++++
 tests/ui/borrowck/issue-70919-drop-in-loop.rs | 25 +++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 tests/ui/borrowck/drop-in-loop.rs
 create mode 100644 tests/ui/borrowck/drop-in-loop.stderr
 create mode 100644 tests/ui/borrowck/issue-70919-drop-in-loop.rs

diff --git a/tests/ui/borrowck/drop-in-loop.rs b/tests/ui/borrowck/drop-in-loop.rs
new file mode 100644
index 0000000000000..866c27ef20324
--- /dev/null
+++ b/tests/ui/borrowck/drop-in-loop.rs
@@ -0,0 +1,24 @@
+// A version of `issue-70919-drop-in-loop`, but without
+// the necessary `drop` call.
+//
+// This should fail to compile, since the `Drop` impl
+// for `WrapperWithDrop` could observe the changed
+// `base` value.
+
+struct WrapperWithDrop<'a>(&'a mut bool);
+impl<'a> Drop for WrapperWithDrop<'a> {
+    fn drop(&mut self) {
+    }
+}
+
+fn drop_in_loop() {
+    let mut base = true;
+    let mut wrapper = WrapperWithDrop(&mut base);
+    loop {
+        base = false; //~ ERROR: cannot assign to `base`
+        wrapper = WrapperWithDrop(&mut base);
+    }
+}
+
+fn main() {
+}
diff --git a/tests/ui/borrowck/drop-in-loop.stderr b/tests/ui/borrowck/drop-in-loop.stderr
new file mode 100644
index 0000000000000..d5734e7ec9770
--- /dev/null
+++ b/tests/ui/borrowck/drop-in-loop.stderr
@@ -0,0 +1,14 @@
+error[E0506]: cannot assign to `base` because it is borrowed
+  --> $DIR/drop-in-loop.rs:18:9
+   |
+LL |     let mut wrapper = WrapperWithDrop(&mut base);
+   |                                       --------- `base` is borrowed here
+LL |     loop {
+LL |         base = false;
+   |         ^^^^^^^^^^^^ `base` is assigned to here but it was already borrowed
+LL |         wrapper = WrapperWithDrop(&mut base);
+   |         ------- borrow might be used here, when `wrapper` is dropped and runs the `Drop` code for type `WrapperWithDrop`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/tests/ui/borrowck/issue-70919-drop-in-loop.rs b/tests/ui/borrowck/issue-70919-drop-in-loop.rs
new file mode 100644
index 0000000000000..a8d5849a31c0b
--- /dev/null
+++ b/tests/ui/borrowck/issue-70919-drop-in-loop.rs
@@ -0,0 +1,25 @@
+// Regression test for issue #70919
+// Tests that we don't emit a spurious "borrow might be used" error
+// when we have an explicit `drop` in a loop
+
+// check-pass
+
+struct WrapperWithDrop<'a>(&'a mut bool);
+impl<'a> Drop for WrapperWithDrop<'a> {
+    fn drop(&mut self) {
+    }
+}
+
+fn drop_in_loop() {
+    let mut base = true;
+    let mut wrapper = WrapperWithDrop(&mut base);
+    loop {
+        drop(wrapper);
+
+        base = false;
+        wrapper = WrapperWithDrop(&mut base);
+    }
+}
+
+fn main() {
+}

From cb4ebc1453a69145d6602de798dc704871a200da Mon Sep 17 00:00:00 2001
From: Ben Kimock <kimockb@gmail.com>
Date: Sun, 5 Mar 2023 13:20:17 -0500
Subject: [PATCH 05/12] Check for free regions in MIR validation

---
 compiler/rustc_const_eval/src/transform/validate.rs | 11 +++++++++++
 compiler/rustc_mir_transform/src/lib.rs             |  6 ------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index fb37eb79a335f..272fe3d1b3109 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -72,6 +72,17 @@ impl<'tcx> MirPass<'tcx> for Validator {
         };
         checker.visit_body(body);
         checker.check_cleanup_control_flow();
+
+        if let MirPhase::Runtime(_) = body.phase {
+            if let ty::InstanceDef::Item(_) = body.source.instance {
+                if body.has_free_regions() {
+                    checker.fail(
+                        Location::START,
+                        format!("Free regions in optimized {} MIR", body.phase.name()),
+                    );
+                }
+            }
+        }
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index cdd28ae0c0197..5fd923190ef59 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -416,8 +416,6 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
 
     pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None);
 
-    debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE");
-
     body
 }
 
@@ -626,8 +624,6 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
     debug!("body: {:#?}", body);
     run_optimization_passes(tcx, &mut body);
 
-    debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR");
-
     body
 }
 
@@ -651,7 +647,5 @@ fn promoted_mir(
         run_analysis_to_runtime_passes(tcx, body);
     }
 
-    debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR");
-
     tcx.arena.alloc(promoted)
 }

From 5d7234abb65fa8cf0007ed03dfd8448eb9128f5d Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Sun, 5 Mar 2023 20:55:29 +0000
Subject: [PATCH 06/12] Add test.

---
 tests/ui/mir/unsize-trait.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 tests/ui/mir/unsize-trait.rs

diff --git a/tests/ui/mir/unsize-trait.rs b/tests/ui/mir/unsize-trait.rs
new file mode 100644
index 0000000000000..45b5308c0938f
--- /dev/null
+++ b/tests/ui/mir/unsize-trait.rs
@@ -0,0 +1,15 @@
+// Check that the interpreter does not ICE when trying to unsize `B` to `[u8]`.
+// This is a `build` test to ensure that const-prop-lint runs.
+// build-pass
+
+#![feature(unsize)]
+
+fn foo<B>(buffer: &mut [B; 2])
+    where B: std::marker::Unsize<[u8]>,
+{
+    let buffer: &[u8] = &buffer[0];
+}
+
+fn main() {
+    foo(&mut [[0], [5]]);
+}

From 858eab63912db10ee5e6706724df9c909c6502e7 Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Fri, 10 Feb 2023 18:17:52 +0000
Subject: [PATCH 07/12] Do not ICE when casting polymorphic values.

---
 .../rustc_const_eval/src/interpret/cast.rs    | 35 ++++++++++++-------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 2be5ed896ec80..c14152a916a29 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -67,12 +67,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             Pointer(PointerCast::ReifyFnPointer) => {
+                // All reifications must be monomorphic, bail out otherwise.
+                ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
+
                 // The src operand does not matter, just its type
                 match *src.layout.ty.kind() {
                     ty::FnDef(def_id, substs) => {
-                        // All reifications must be monomorphic, bail out otherwise.
-                        ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
-
                         let instance = ty::Instance::resolve_for_fn_ptr(
                             *self.tcx,
                             self.param_env,
@@ -100,12 +100,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             Pointer(PointerCast::ClosureFnPointer(_)) => {
+                // All reifications must be monomorphic, bail out otherwise.
+                ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
+
                 // The src operand does not matter, just its type
                 match *src.layout.ty.kind() {
                     ty::Closure(def_id, substs) => {
-                        // All reifications must be monomorphic, bail out otherwise.
-                        ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
-
                         let instance = ty::Instance::resolve_closure(
                             *self.tcx,
                             def_id,
@@ -359,8 +359,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx);
                 self.write_immediate(val, dest)
             }
-
             _ => {
+                // Do not ICE if we are not monomorphic enough.
+                ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
+                ensure_monomorphic_enough(*self.tcx, cast_ty)?;
+
                 span_bug!(
                     self.cur_span(),
                     "invalid pointer unsizing {:?} -> {:?}",
@@ -404,12 +407,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
                 Ok(())
             }
-            _ => span_bug!(
-                self.cur_span(),
-                "unsize_into: invalid conversion: {:?} -> {:?}",
-                src.layout,
-                dest.layout
-            ),
+            _ => {
+                // Do not ICE if we are not monomorphic enough.
+                ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
+                ensure_monomorphic_enough(*self.tcx, cast_ty.ty)?;
+
+                span_bug!(
+                    self.cur_span(),
+                    "unsize_into: invalid conversion: {:?} -> {:?}",
+                    src.layout,
+                    dest.layout
+                )
+            }
         }
     }
 }

From 8c0cbd87671c283707cbaf4f60db36a5184d8cef Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Mon, 6 Mar 2023 09:24:46 +0000
Subject: [PATCH 08/12] Do not ICE when failing to normalize in ConstProp.

---
 .../rustc_const_eval/src/interpret/eval_context.rs    | 11 ++---------
 tests/ui/associated-types/issue-67684.rs              |  8 +++++++-
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 3db102e484dfa..39c7419125829 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -7,7 +7,7 @@ use either::{Either, Left, Right};
 use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir;
-use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidProgramInfo};
+use rustc_middle::mir::interpret::{ErrorHandled, InterpError};
 use rustc_middle::ty::layout::{
     self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
     TyAndLayout,
@@ -508,14 +508,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         frame
             .instance
             .try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
-            .map_err(|e| {
-                self.tcx.sess.delay_span_bug(
-                    self.cur_span(),
-                    format!("failed to normalize {}", e.get_type_for_failure()).as_str(),
-                );
-
-                InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric)
-            })
+            .map_err(|_| err_inval!(TooGeneric))
     }
 
     /// The `substs` are assumed to already be in our interpreter "universe" (param_env).
diff --git a/tests/ui/associated-types/issue-67684.rs b/tests/ui/associated-types/issue-67684.rs
index 49efe8a1bdaac..c6920cf8d40c1 100644
--- a/tests/ui/associated-types/issue-67684.rs
+++ b/tests/ui/associated-types/issue-67684.rs
@@ -1,4 +1,10 @@
-// check-pass
+// revisions: check build
+// [check]check-pass
+//
+// This second configuration aims to verify that we do not ICE in ConstProp because of
+// normalization failure.
+// [build]build-pass
+// [build]compile-flags: -Zmir-opt-level=3 --emit=mir
 
 #![allow(dead_code)]
 

From 2fe288fd2974a781991f6050cdc13bd39e97563d Mon Sep 17 00:00:00 2001
From: Mu42 <mu001999@outlook.com>
Date: Mon, 6 Mar 2023 20:04:33 +0800
Subject: [PATCH 09/12] emit the suspicious_auto_trait_impls for negative impls
 as well

---
 .../src/coherence/orphan.rs                   |  4 --
 tests/ui/auto-traits/suspicious-impls-lint.rs | 10 +++
 .../auto-traits/suspicious-impls-lint.stderr  | 69 +++++++++++++++----
 3 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 1f2de3f21f8d9..47c47de8cedba 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -478,10 +478,6 @@ fn lint_auto_trait_impl<'tcx>(
     trait_ref: ty::TraitRef<'tcx>,
     impl_def_id: LocalDefId,
 ) {
-    if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
-        return;
-    }
-
     assert_eq!(trait_ref.substs.len(), 1);
     let self_ty = trait_ref.self_ty();
     let (self_type_did, substs) = match self_ty.kind() {
diff --git a/tests/ui/auto-traits/suspicious-impls-lint.rs b/tests/ui/auto-traits/suspicious-impls-lint.rs
index 7712e84f4a243..86ee2fd67039d 100644
--- a/tests/ui/auto-traits/suspicious-impls-lint.rs
+++ b/tests/ui/auto-traits/suspicious-impls-lint.rs
@@ -1,3 +1,4 @@
+#![feature(negative_impls)]
 #![deny(suspicious_auto_trait_impls)]
 
 use std::marker::PhantomData;
@@ -21,6 +22,9 @@ struct ContainsVec<T>(Vec<T>);
 unsafe impl Send for ContainsVec<i32> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
+impl !Send for ContainsVec<u32> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
 
 struct TwoParams<T, U>(T, U);
 unsafe impl<T: Send, U: Send> Send for TwoParams<T, U> {} // ok
@@ -40,11 +44,17 @@ pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
 unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
+impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
 
 pub struct WithLifetime<'a, T>(&'a (), T);
 unsafe impl<T> Send for WithLifetime<'static, T> {} // ok
 unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
+impl<T> !Sync for WithLifetime<'static, Option<T>> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
 
 fn main() {}
diff --git a/tests/ui/auto-traits/suspicious-impls-lint.stderr b/tests/ui/auto-traits/suspicious-impls-lint.stderr
index 9cd4e79f851eb..d4e7fe636e677 100644
--- a/tests/ui/auto-traits/suspicious-impls-lint.stderr
+++ b/tests/ui/auto-traits/suspicious-impls-lint.stderr
@@ -1,5 +1,5 @@
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:9:1
+  --> $DIR/suspicious-impls-lint.rs:10:1
    |
 LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,18 +8,18 @@ LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `&T` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:8:1
+  --> $DIR/suspicious-impls-lint.rs:9:1
    |
 LL | struct MayImplementSendErr<T>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the lint level is defined here
-  --> $DIR/suspicious-impls-lint.rs:1:9
+  --> $DIR/suspicious-impls-lint.rs:2:9
    |
 LL | #![deny(suspicious_auto_trait_impls)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:21:1
+  --> $DIR/suspicious-impls-lint.rs:22:1
    |
 LL | unsafe impl Send for ContainsVec<i32> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,13 +28,28 @@ LL | unsafe impl Send for ContainsVec<i32> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `i32` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:20:1
+  --> $DIR/suspicious-impls-lint.rs:21:1
    |
 LL | struct ContainsVec<T>(Vec<T>);
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:32:1
+  --> $DIR/suspicious-impls-lint.rs:25:1
+   |
+LL | impl !Send for ContainsVec<u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `u32` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:21:1
+   |
+LL | struct ContainsVec<T>(Vec<T>);
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:36:1
    |
 LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,13 +58,13 @@ LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `T` is mentioned multiple times
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:31:1
+  --> $DIR/suspicious-impls-lint.rs:35:1
    |
 LL | struct TwoParamsSame<T, U>(T, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:40:1
+  --> $DIR/suspicious-impls-lint.rs:44:1
    |
 LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -58,13 +73,28 @@ LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `*const T` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:39:1
+  --> $DIR/suspicious-impls-lint.rs:43:1
+   |
+LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:47:1
+   |
+LL | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `*const T` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:43:1
    |
 LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Sync`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:46:1
+  --> $DIR/suspicious-impls-lint.rs:53:1
    |
 LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,10 +103,25 @@ LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `Vec<T>` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:44:1
+  --> $DIR/suspicious-impls-lint.rs:51:1
+   |
+LL | pub struct WithLifetime<'a, T>(&'a (), T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Sync`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:56:1
+   |
+LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `Option<T>` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:51:1
    |
 LL | pub struct WithLifetime<'a, T>(&'a (), T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 8 previous errors
 

From 5c0f55d508b49dbea5b5d69a41d998a00e7d95d2 Mon Sep 17 00:00:00 2001
From: Mu42 <mu001999@outlook.com>
Date: Mon, 6 Mar 2023 21:05:23 +0800
Subject: [PATCH 10/12] Moves the negative impls into a separate test file

---
 tests/ui/auto-traits/suspicious-impls-lint.rs | 10 ---
 .../auto-traits/suspicious-impls-lint.stderr  | 69 +++-------------
 .../suspicious-negative-impls-lint.rs         | 21 +++++
 .../suspicious-negative-impls-lint.stderr     | 82 +++++++++++++++++++
 4 files changed, 115 insertions(+), 67 deletions(-)
 create mode 100644 tests/ui/auto-traits/suspicious-negative-impls-lint.rs
 create mode 100644 tests/ui/auto-traits/suspicious-negative-impls-lint.stderr

diff --git a/tests/ui/auto-traits/suspicious-impls-lint.rs b/tests/ui/auto-traits/suspicious-impls-lint.rs
index 86ee2fd67039d..7712e84f4a243 100644
--- a/tests/ui/auto-traits/suspicious-impls-lint.rs
+++ b/tests/ui/auto-traits/suspicious-impls-lint.rs
@@ -1,4 +1,3 @@
-#![feature(negative_impls)]
 #![deny(suspicious_auto_trait_impls)]
 
 use std::marker::PhantomData;
@@ -22,9 +21,6 @@ struct ContainsVec<T>(Vec<T>);
 unsafe impl Send for ContainsVec<i32> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
-impl !Send for ContainsVec<u32> {}
-//~^ ERROR
-//~| WARNING this will change its meaning
 
 struct TwoParams<T, U>(T, U);
 unsafe impl<T: Send, U: Send> Send for TwoParams<T, U> {} // ok
@@ -44,17 +40,11 @@ pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
 unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
-impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
-//~^ ERROR
-//~| WARNING this will change its meaning
 
 pub struct WithLifetime<'a, T>(&'a (), T);
 unsafe impl<T> Send for WithLifetime<'static, T> {} // ok
 unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
-impl<T> !Sync for WithLifetime<'static, Option<T>> {}
-//~^ ERROR
-//~| WARNING this will change its meaning
 
 fn main() {}
diff --git a/tests/ui/auto-traits/suspicious-impls-lint.stderr b/tests/ui/auto-traits/suspicious-impls-lint.stderr
index d4e7fe636e677..9cd4e79f851eb 100644
--- a/tests/ui/auto-traits/suspicious-impls-lint.stderr
+++ b/tests/ui/auto-traits/suspicious-impls-lint.stderr
@@ -1,5 +1,5 @@
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:10:1
+  --> $DIR/suspicious-impls-lint.rs:9:1
    |
 LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,18 +8,18 @@ LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `&T` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:9:1
+  --> $DIR/suspicious-impls-lint.rs:8:1
    |
 LL | struct MayImplementSendErr<T>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the lint level is defined here
-  --> $DIR/suspicious-impls-lint.rs:2:9
+  --> $DIR/suspicious-impls-lint.rs:1:9
    |
 LL | #![deny(suspicious_auto_trait_impls)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:22:1
+  --> $DIR/suspicious-impls-lint.rs:21:1
    |
 LL | unsafe impl Send for ContainsVec<i32> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,28 +28,13 @@ LL | unsafe impl Send for ContainsVec<i32> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `i32` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:21:1
+  --> $DIR/suspicious-impls-lint.rs:20:1
    |
 LL | struct ContainsVec<T>(Vec<T>);
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:25:1
-   |
-LL | impl !Send for ContainsVec<u32> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this will change its meaning in a future release!
-   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
-   = note: `u32` is not a generic parameter
-note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:21:1
-   |
-LL | struct ContainsVec<T>(Vec<T>);
-   | ^^^^^^^^^^^^^^^^^^^^^
-
-error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:36:1
+  --> $DIR/suspicious-impls-lint.rs:32:1
    |
 LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -58,13 +43,13 @@ LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `T` is mentioned multiple times
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:35:1
+  --> $DIR/suspicious-impls-lint.rs:31:1
    |
 LL | struct TwoParamsSame<T, U>(T, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:44:1
+  --> $DIR/suspicious-impls-lint.rs:40:1
    |
 LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,28 +58,13 @@ LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `*const T` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:43:1
-   |
-LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:47:1
-   |
-LL | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this will change its meaning in a future release!
-   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
-   = note: `*const T` is not a generic parameter
-note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:43:1
+  --> $DIR/suspicious-impls-lint.rs:39:1
    |
 LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Sync`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:53:1
+  --> $DIR/suspicious-impls-lint.rs:46:1
    |
 LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -103,25 +73,10 @@ LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `Vec<T>` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:51:1
-   |
-LL | pub struct WithLifetime<'a, T>(&'a (), T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cross-crate traits with a default impl, like `Sync`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:56:1
-   |
-LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this will change its meaning in a future release!
-   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
-   = note: `Option<T>` is not a generic parameter
-note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:51:1
+  --> $DIR/suspicious-impls-lint.rs:44:1
    |
 LL | pub struct WithLifetime<'a, T>(&'a (), T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/auto-traits/suspicious-negative-impls-lint.rs b/tests/ui/auto-traits/suspicious-negative-impls-lint.rs
new file mode 100644
index 0000000000000..34842e5944b46
--- /dev/null
+++ b/tests/ui/auto-traits/suspicious-negative-impls-lint.rs
@@ -0,0 +1,21 @@
+#![feature(negative_impls)]
+#![deny(suspicious_auto_trait_impls)]
+
+use std::marker::PhantomData;
+
+struct ContainsVec<T>(Vec<T>);
+impl !Send for ContainsVec<u32> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
+pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
+impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
+pub struct WithLifetime<'a, T>(&'a (), T);
+impl<T> !Sync for WithLifetime<'static, Option<T>> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
+fn main() {}
diff --git a/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
new file mode 100644
index 0000000000000..14785b98a17dd
--- /dev/null
+++ b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
@@ -0,0 +1,82 @@
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-negative-impls-lint.rs:7:1
+   |
+LL | impl !Send for ContainsVec<u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `u32` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-negative-impls-lint.rs:6:1
+   |
+LL | struct ContainsVec<T>(Vec<T>);
+   | ^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/suspicious-negative-impls-lint.rs:2:9
+   |
+LL | #![deny(suspicious_auto_trait_impls)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-negative-impls-lint.rs:12:1
+   |
+LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `*const T` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-negative-impls-lint.rs:11:1
+   |
+LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-negative-impls-lint.rs:15:1
+   |
+LL | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `*const T` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-negative-impls-lint.rs:11:1
+   |
+LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Sync`, should not be specialized
+  --> $DIR/suspicious-negative-impls-lint.rs:21:1
+   |
+LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `Vec<T>` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-negative-impls-lint.rs:19:1
+   |
+LL | pub struct WithLifetime<'a, T>(&'a (), T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cross-crate traits with a default impl, like `Sync`, should not be specialized
+  --> $DIR/suspicious-negative-impls-lint.rs:24:1
+   |
+LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `Option<T>` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-negative-impls-lint.rs:19:1
+   |
+LL | pub struct WithLifetime<'a, T>(&'a (), T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+

From 23ba4ceb9edbd3ab962c91f5852367b4529ad8a7 Mon Sep 17 00:00:00 2001
From: Mu42 <mu001999@outlook.com>
Date: Mon, 6 Mar 2023 21:05:35 +0800
Subject: [PATCH 11/12] Bless the remaining ui tests

---
 ...oherence-conflicting-negative-trait-impl.rs |  2 ++
 ...ence-conflicting-negative-trait-impl.stderr | 18 +++++++++++++++++-
 tests/ui/coherence/coherence-orphan.rs         |  5 +++--
 tests/ui/coherence/coherence-orphan.stderr     | 15 ++++++++++++++-
 tests/ui/issues/issue-106755.rs                |  2 ++
 tests/ui/issues/issue-106755.stderr            | 18 +++++++++++++++++-
 6 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
index 24b878927530c..76a57936e6985 100644
--- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
+++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
@@ -13,5 +13,7 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
 unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
 
 impl !Send for TestType<i32> {}
+//~^ WARNING
+//~| WARNING this will change its meaning
 
 fn main() {}
diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
index 2463f38a92251..020199da99141 100644
--- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
+++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
@@ -16,7 +16,23 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
 LL | unsafe impl<T: 'static> Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
 
-error: aborting due to 2 previous errors
+warning: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1
+   |
+LL | impl !Send for TestType<i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `i32` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(suspicious_auto_trait_impls)]` on by default
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0119, E0751.
 For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs
index 3beac04c7e829..bed782203af50 100644
--- a/tests/ui/coherence/coherence-orphan.rs
+++ b/tests/ui/coherence/coherence-orphan.rs
@@ -14,7 +14,8 @@ impl TheTrait<TheType> for isize { }
 
 impl TheTrait<isize> for TheType { }
 
-impl !Send for Vec<isize> { }
-//~^ ERROR E0117
+impl !Send for Vec<isize> { } //~ ERROR E0117
+//~^ WARNING
+//~| WARNING this will change its meaning
 
 fn main() { }
diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr
index 01f166a21f768..9ec1d0dc32aa4 100644
--- a/tests/ui/coherence/coherence-orphan.stderr
+++ b/tests/ui/coherence/coherence-orphan.stderr
@@ -21,6 +21,19 @@ LL | impl !Send for Vec<isize> { }
    |
    = note: define and implement a trait or new type instead
 
-error: aborting due to 2 previous errors
+warning: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/coherence-orphan.rs:17:1
+   |
+LL | impl !Send for Vec<isize> { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `isize` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+   = note: `#[warn(suspicious_auto_trait_impls)]` on by default
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs
index 46ece725fb7c1..5eabc3bfb1384 100644
--- a/tests/ui/issues/issue-106755.rs
+++ b/tests/ui/issues/issue-106755.rs
@@ -15,5 +15,7 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
 unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
 
 impl !Send for TestType<i32> {}
+//~^ WARNING
+//~| WARNING this will change its meaning
 
 fn main() {}
diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr
index 543970340620d..6b3a8427e7738 100644
--- a/tests/ui/issues/issue-106755.stderr
+++ b/tests/ui/issues/issue-106755.stderr
@@ -16,7 +16,23 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
 LL | unsafe impl<T: 'static> Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
 
-error: aborting due to 2 previous errors
+warning: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/issue-106755.rs:17:1
+   |
+LL | impl !Send for TestType<i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+   = note: `i32` is not a generic parameter
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/issue-106755.rs:9:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(suspicious_auto_trait_impls)]` on by default
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0119, E0751.
 For more information about an error, try `rustc --explain E0119`.

From 717f93cec57606e83b20c26bedad1e0cdf5154c2 Mon Sep 17 00:00:00 2001
From: Mu42 <mu001999@outlook.com>
Date: Mon, 6 Mar 2023 21:25:43 +0800
Subject: [PATCH 12/12] Bless the suspicious-negative-impls-lint.rs

---
 .../suspicious-negative-impls-lint.stderr     | 36 ++-----------------
 1 file changed, 3 insertions(+), 33 deletions(-)

diff --git a/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
index 14785b98a17dd..ee03ea1255757 100644
--- a/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
+++ b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
@@ -21,21 +21,6 @@ LL | #![deny(suspicious_auto_trait_impls)]
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
   --> $DIR/suspicious-negative-impls-lint.rs:12:1
    |
-LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this will change its meaning in a future release!
-   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
-   = note: `*const T` is not a generic parameter
-note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-negative-impls-lint.rs:11:1
-   |
-LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-negative-impls-lint.rs:15:1
-   |
 LL | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
@@ -49,22 +34,7 @@ LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Sync`, should not be specialized
-  --> $DIR/suspicious-negative-impls-lint.rs:21:1
-   |
-LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this will change its meaning in a future release!
-   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
-   = note: `Vec<T>` is not a generic parameter
-note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-negative-impls-lint.rs:19:1
-   |
-LL | pub struct WithLifetime<'a, T>(&'a (), T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cross-crate traits with a default impl, like `Sync`, should not be specialized
-  --> $DIR/suspicious-negative-impls-lint.rs:24:1
+  --> $DIR/suspicious-negative-impls-lint.rs:17:1
    |
 LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,10 +43,10 @@ LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `Option<T>` is not a generic parameter
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-negative-impls-lint.rs:19:1
+  --> $DIR/suspicious-negative-impls-lint.rs:16:1
    |
 LL | pub struct WithLifetime<'a, T>(&'a (), T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors