@@ -290,6 +290,59 @@ impl<'tcx> BestObligation<'tcx> {
290
290
ControlFlow :: Continue ( ( ) )
291
291
}
292
292
}
293
+
294
+ /// It is likely that `NormalizesTo` failed without any applicable candidates
295
+ /// because the alias is not well-formed.
296
+ ///
297
+ /// As we only enter `RigidAlias` candidates if the trait bound of the associated type
298
+ /// holds, we discard these candidates in `non_trivial_candidates` and always manually
299
+ /// check this here.
300
+ fn detect_non_well_formed_assoc_item (
301
+ & mut self ,
302
+ goal : & inspect:: InspectGoal < ' _ , ' tcx > ,
303
+ alias : ty:: AliasTerm < ' tcx > ,
304
+ ) -> ControlFlow < PredicateObligation < ' tcx > > {
305
+ let tcx = goal. infcx ( ) . tcx ;
306
+ let obligation = Obligation :: new (
307
+ tcx,
308
+ self . obligation . cause . clone ( ) ,
309
+ goal. goal ( ) . param_env ,
310
+ alias. trait_ref ( tcx) ,
311
+ ) ;
312
+ self . with_derived_obligation ( obligation, |this| {
313
+ goal. infcx ( ) . visit_proof_tree_at_depth (
314
+ goal. goal ( ) . with ( tcx, alias. trait_ref ( tcx) ) ,
315
+ goal. depth ( ) + 1 ,
316
+ this,
317
+ )
318
+ } )
319
+ }
320
+
321
+ /// If we have no candidates, then it's likely that we a non-well-formed alias
322
+ /// in the goal.
323
+ fn detect_error_from_empty_candidates (
324
+ & mut self ,
325
+ goal : & inspect:: InspectGoal < ' _ , ' tcx > ,
326
+ ) -> ControlFlow < PredicateObligation < ' tcx > > {
327
+ let tcx = goal. infcx ( ) . tcx ;
328
+ let pred_kind = goal. goal ( ) . predicate . kind ( ) ;
329
+
330
+ match pred_kind. no_bound_vars ( ) {
331
+ Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) ) => {
332
+ self . detect_error_in_self_ty_normalization ( goal, pred. self_ty ( ) ) ?;
333
+ }
334
+ Some ( ty:: PredicateKind :: NormalizesTo ( pred) )
335
+ if let ty:: AliasTermKind :: ProjectionTy | ty:: AliasTermKind :: ProjectionConst =
336
+ pred. alias . kind ( tcx) =>
337
+ {
338
+ self . detect_error_in_self_ty_normalization ( goal, pred. alias . self_ty ( ) ) ?;
339
+ self . detect_non_well_formed_assoc_item ( goal, pred. alias ) ?;
340
+ }
341
+ Some ( _) | None => { }
342
+ }
343
+
344
+ ControlFlow :: Break ( self . obligation . clone ( ) )
345
+ }
293
346
}
294
347
295
348
impl < ' tcx > ProofTreeVisitor < ' tcx > for BestObligation < ' tcx > {
@@ -311,40 +364,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
311
364
312
365
let candidates = self . non_trivial_candidates ( goal) ;
313
366
let candidate = match candidates. as_slice ( ) {
314
- [ ] => {
315
- match pred_kind. no_bound_vars ( ) {
316
- Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) ) => {
317
- self . detect_error_in_self_ty_normalization ( goal, pred. self_ty ( ) ) ?;
318
- }
319
- Some ( ty:: PredicateKind :: NormalizesTo ( pred) )
320
- if let ty:: AliasTermKind :: ProjectionTy
321
- | ty:: AliasTermKind :: ProjectionConst = pred. alias . kind ( tcx) =>
322
- {
323
- self . detect_error_in_self_ty_normalization ( goal, pred. alias . self_ty ( ) ) ?;
324
- // It is likely that `NormalizesTo` failed because the alias is not well-formed.
325
- // As we only enter `RigidAlias` candidates if the trait bound of the associated type
326
- // holds, we discard these candidates in `non_trivial_candidates` and always manually
327
- // check this here.
328
- let obligation = Obligation :: new (
329
- tcx,
330
- self . obligation . cause . clone ( ) ,
331
- goal. goal ( ) . param_env ,
332
- pred. alias . trait_ref ( tcx) ,
333
- ) ;
334
- self . with_derived_obligation ( obligation, |this| {
335
- goal. infcx ( ) . visit_proof_tree_at_depth (
336
- goal. goal ( ) . with ( tcx, pred. alias . trait_ref ( tcx) ) ,
337
- goal. depth ( ) + 1 ,
338
- this,
339
- )
340
- } ) ?;
341
- }
342
- Some ( _) | None => { }
343
- }
344
-
345
- return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
346
- }
347
367
[ candidate] => candidate,
368
+ [ ] => return self . detect_error_from_empty_candidates ( goal) ,
348
369
_ => return ControlFlow :: Break ( self . obligation . clone ( ) ) ,
349
370
} ;
350
371
0 commit comments