about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-04-03 23:24:47 +0000
committerMichael Goulet <michael@errs.io>2023-04-10 15:54:14 +0000
commit8d2dbba63eaa61252c4c533e1490ac75f97374b9 (patch)
tree129eb9041d8b1e6bce831513c10aef22e2740e91 /compiler/rustc_trait_selection/src
parent2a198c7f62a6dea507ba950750bc928237ad7a00 (diff)
downloadrust-8d2dbba63eaa61252c4c533e1490ac75f97374b9.tar.gz
rust-8d2dbba63eaa61252c4c533e1490ac75f97374b9.zip
Stall auto-trait assembly for int/float vars in new solver
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs78
2 files changed, 64 insertions, 24 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index cbec39d8285..1a566e87dc8 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -24,21 +24,19 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
         | ty::FnDef(..)
         | ty::FnPtr(_)
         | ty::Error(_)
-        | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
         | ty::Never
         | ty::Char => Ok(vec![]),
 
-        // Treat this like `struct str([u8]);`
+        // Treat `str` like it's defined as `struct str([u8]);`
         ty::Str => Ok(vec![tcx.mk_slice(tcx.types.u8)]),
 
         ty::Dynamic(..)
         | ty::Param(..)
         | ty::Foreign(..)
         | ty::Alias(ty::Projection, ..)
-        | ty::Placeholder(..) => Err(NoSolution),
-
-        ty::Bound(..)
-        | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+        | ty::Placeholder(..)
+        | ty::Bound(..)
+        | ty::Infer(_) => {
             bug!("unexpected type `{ty}`")
         }
 
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 81f89fd950c..cb7cf9b936c 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -147,24 +147,66 @@ 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.
-        //
-        // Using `TreatProjections::NextSolverLookup` is fine here because
-        // `instantiate_constituent_tys_for_auto_trait` returns nothing for
-        // projection types anyways. So it doesn't really matter what we do
-        // here, and this is faster.
-        if let Some(def_id) = ecx.tcx().find_map_relevant_impl(
-            goal.predicate.def_id(),
-            goal.predicate.self_ty(),
-            TreatProjections::NextSolverLookup,
-            Some,
-        ) {
-            debug!(?def_id, ?goal, "disqualified auto-trait implementation");
-            return Err(NoSolution);
+        let self_ty = goal.predicate.self_ty();
+        match *self_ty.kind() {
+            // Stall int and float vars until they are resolved to a concrete
+            // numerical type. That's because the check for impls below treats
+            // int vars as matching any impl. Even if we filtered such impls,
+            // we probably don't want to treat an `impl !AutoTrait for i32` as
+            // disqualifying the built-in auto impl for `i64: AutoTrait` either.
+            ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
+                return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
+            }
+
+            // These types cannot be structurally decomposed into constitutent
+            // types, and therefore have no builtin impl.
+            ty::Dynamic(..)
+            | ty::Param(..)
+            | ty::Foreign(..)
+            | ty::Alias(ty::Projection, ..)
+            | ty::Placeholder(..) => return Err(NoSolution),
+
+            ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"),
+
+            // For rigid types, we only register a builtin auto implementation
+            // if there is no implementation that could ever apply to the self
+            // type.
+            //
+            // 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.
+            ty::Bool
+            | ty::Char
+            | ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Str
+            | ty::Array(_, _)
+            | ty::Slice(_)
+            | ty::RawPtr(_)
+            | ty::Ref(_, _, _)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(_)
+            | ty::Closure(_, _)
+            | ty::Generator(_, _, _)
+            | ty::GeneratorWitness(_)
+            | ty::GeneratorWitnessMIR(_, _)
+            | ty::Never
+            | ty::Tuple(_)
+            | ty::Error(_)
+            | ty::Adt(_, _)
+            | ty::Alias(ty::Opaque, _) => {
+                if let Some(def_id) = ecx.tcx().find_map_relevant_impl(
+                    goal.predicate.def_id(),
+                    goal.predicate.self_ty(),
+                    TreatProjections::NextSolverLookup,
+                    Some,
+                ) {
+                    debug!(?def_id, ?goal, "disqualified auto-trait implementation");
+                    return Err(NoSolution);
+                }
+            }
         }
 
         ecx.probe_and_evaluate_goal_for_constituent_tys(