@@ -6,7 +6,7 @@ mod weak_types;
6
6
use rustc_type_ir:: fast_reject:: DeepRejectCtxt ;
7
7
use rustc_type_ir:: inherent:: * ;
8
8
use rustc_type_ir:: lang_items:: TraitSolverLangItem ;
9
- use rustc_type_ir:: { self as ty, Interner , NormalizesTo , Upcast as _} ;
9
+ use rustc_type_ir:: { self as ty, Interner , NormalizesTo , PredicateKind , Upcast as _} ;
10
10
use tracing:: instrument;
11
11
12
12
use crate :: delegate:: SolverDelegate ;
@@ -221,13 +221,21 @@ where
221
221
Ok ( Some ( target_item_def_id) ) => target_item_def_id,
222
222
Ok ( None ) => {
223
223
match ecx. typing_mode ( ) {
224
- // In case the associated item is hidden due to specialization, we have to
225
- // return ambiguity this would otherwise be incomplete, resulting in
226
- // unsoundness during coherence (#105782).
224
+ // In case the associated item is hidden due to specialization,
225
+ // normalizing this associated item is always ambiguous. Treating
226
+ // the associated item as rigid would be incomplete and allow for
227
+ // overlapping impls, see #105782.
228
+ //
229
+ // As this ambiguity is unavoidable we emit a nested ambiguous
230
+ // goal instead of using `Certainty::AMBIGUOUS`. This allows us to
231
+ // return the nested goals to the parent `AliasRelate` goal. This
232
+ // would be relevant if any of the nested goals refer to the `term`.
233
+ // This is not the case here and we only prefer adding an ambiguous
234
+ // nested goal for consistency.
227
235
ty:: TypingMode :: Coherence => {
228
- return ecx. evaluate_added_goals_and_make_canonical_response (
229
- Certainty :: AMBIGUOUS ,
230
- ) ;
236
+ ecx. add_goal ( GoalSource :: Misc , goal . with ( cx , PredicateKind :: Ambiguous ) ) ;
237
+ return ecx
238
+ . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes ) ;
231
239
}
232
240
// Outside of coherence, we treat the associated item as rigid instead.
233
241
ty:: TypingMode :: Analysis { .. }
@@ -254,10 +262,20 @@ where
254
262
// treat it as rigid.
255
263
if cx. impl_self_is_guaranteed_unsized ( impl_def_id) {
256
264
match ecx. typing_mode ( ) {
265
+ // Trying to normalize such associated items is always ambiguous
266
+ // during coherence to avoid cyclic reasoning. See the example in
267
+ // tests/ui/traits/trivial-unsized-projection-in-coherence.rs.
268
+ //
269
+ // As this ambiguity is unavoidable we emit a nested ambiguous
270
+ // goal instead of using `Certainty::AMBIGUOUS`. This allows us to
271
+ // return the nested goals to the parent `AliasRelate` goal. This
272
+ // would be relevant if any of the nested goals refer to the `term`.
273
+ // This is not the case here and we only prefer adding an ambiguous
274
+ // nested goal for consistency.
257
275
ty:: TypingMode :: Coherence => {
258
- return ecx. evaluate_added_goals_and_make_canonical_response (
259
- Certainty :: AMBIGUOUS ,
260
- ) ;
276
+ ecx. add_goal ( GoalSource :: Misc , goal . with ( cx , PredicateKind :: Ambiguous ) ) ;
277
+ return ecx
278
+ . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes ) ;
261
279
}
262
280
ty:: TypingMode :: Analysis { .. }
263
281
| ty:: TypingMode :: Borrowck { .. }
0 commit comments