@@ -147,24 +147,66 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
147
147
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
148
148
goal : Goal < ' tcx , Self > ,
149
149
) -> 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
+ }
168
210
}
169
211
170
212
ecx. probe_and_evaluate_goal_for_constituent_tys (
0 commit comments