@@ -147,24 +147,66 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
147147 ecx : & mut EvalCtxt < ' _ , ' tcx > ,
148148 goal : Goal < ' tcx , Self > ,
149149 ) -> QueryResult < ' tcx > {
150- // This differs from the current stable behavior and
151- // fixes #84857. Due to breakage found via crater, we
152- // currently instead lint patterns which can be used to
153- // exploit this unsoundness on stable, see #93367 for
154- // more details.
155- //
156- // Using `TreatProjections::NextSolverLookup` is fine here because
157- // `instantiate_constituent_tys_for_auto_trait` returns nothing for
158- // projection types anyways. So it doesn't really matter what we do
159- // here, and this is faster.
160- if let Some ( def_id) = ecx. tcx ( ) . find_map_relevant_impl (
161- goal. predicate . def_id ( ) ,
162- goal. predicate . self_ty ( ) ,
163- TreatProjections :: NextSolverLookup ,
164- Some ,
165- ) {
166- debug ! ( ?def_id, ?goal, "disqualified auto-trait implementation" ) ;
167- return Err ( NoSolution ) ;
150+ let self_ty = goal. predicate . self_ty ( ) ;
151+ match * self_ty. kind ( ) {
152+ // Stall int and float vars until they are resolved to a concrete
153+ // numerical type. That's because the check for impls below treats
154+ // int vars as matching any impl. Even if we filtered such impls,
155+ // we probably don't want to treat an `impl !AutoTrait for i32` as
156+ // disqualifying the built-in auto impl for `i64: AutoTrait` either.
157+ ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) ) => {
158+ return ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: AMBIGUOUS ) ;
159+ }
160+
161+ // These types cannot be structurally decomposed into constitutent
162+ // types, and therefore have no builtin impl.
163+ ty:: Dynamic ( ..)
164+ | ty:: Param ( ..)
165+ | ty:: Foreign ( ..)
166+ | ty:: Alias ( ty:: Projection , ..)
167+ | ty:: Placeholder ( ..) => return Err ( NoSolution ) ,
168+
169+ ty:: Infer ( _) | ty:: Bound ( _, _) => bug ! ( "unexpected type `{self_ty}`" ) ,
170+
171+ // For rigid types, we only register a builtin auto implementation
172+ // if there is no implementation that could ever apply to the self
173+ // type.
174+ //
175+ // This differs from the current stable behavior and fixes #84857.
176+ // Due to breakage found via crater, we currently instead lint
177+ // patterns which can be used to exploit this unsoundness on stable,
178+ // see #93367 for more details.
179+ ty:: Bool
180+ | ty:: Char
181+ | ty:: Int ( _)
182+ | ty:: Uint ( _)
183+ | ty:: Float ( _)
184+ | ty:: Str
185+ | ty:: Array ( _, _)
186+ | ty:: Slice ( _)
187+ | ty:: RawPtr ( _)
188+ | ty:: Ref ( _, _, _)
189+ | ty:: FnDef ( _, _)
190+ | ty:: FnPtr ( _)
191+ | ty:: Closure ( _, _)
192+ | ty:: Generator ( _, _, _)
193+ | ty:: GeneratorWitness ( _)
194+ | ty:: GeneratorWitnessMIR ( _, _)
195+ | ty:: Never
196+ | ty:: Tuple ( _)
197+ | ty:: Error ( _)
198+ | ty:: Adt ( _, _)
199+ | ty:: Alias ( ty:: Opaque , _) => {
200+ if let Some ( def_id) = ecx. tcx ( ) . find_map_relevant_impl (
201+ goal. predicate . def_id ( ) ,
202+ goal. predicate . self_ty ( ) ,
203+ TreatProjections :: NextSolverLookup ,
204+ Some ,
205+ ) {
206+ debug ! ( ?def_id, ?goal, "disqualified auto-trait implementation" ) ;
207+ return Err ( NoSolution ) ;
208+ }
209+ }
168210 }
169211
170212 ecx. probe_and_evaluate_goal_for_constituent_tys (
0 commit comments