about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-02-08 20:28:12 +0000
committerMichael Goulet <michael@errs.io>2023-02-09 17:23:50 +0000
commit68e27b305290352a21dfec9c6ce2e2e48323f528 (patch)
tree2b2583c6252b9d6bddac4f60ca42932eff2408be
parent8cca42a47f5d574c8f7302c98c3f918cdc772fbb (diff)
Disqualify auto-trait builtin impl in new solver if impl exists
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs14
-rw-r--r--tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs8
2 files changed, 22 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 06a72e95d49..4f0a83f203a 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -89,6 +89,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx> {
+        // This differs from the current stable behavior and
+        // fixes #84857. Due to breakage found via crater, we
+        // currently instead lint patterns which can be used to
+        // exploit this unsoundness on stable, see #93367 for
+        // more details.
+        if let Some(def_id) = ecx.tcx().find_map_relevant_impl(
+            goal.predicate.def_id(),
+            goal.predicate.self_ty(),
+            Some,
+        ) {
+            debug!(?def_id, ?goal, "disqualified auto-trait implementation");
+            return Err(NoSolution);
+        }
+
         ecx.probe_and_evaluate_goal_for_constituent_tys(
             goal,
             structural_traits::instantiate_constituent_tys_for_auto_trait,
diff --git a/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs b/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs
new file mode 100644
index 00000000000..bcfc747ebb1
--- /dev/null
+++ b/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs
@@ -0,0 +1,8 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+struct Foo(*mut ());
+
+unsafe impl Sync for Foo {}
+
+fn main() {}