@@ -289,6 +289,10 @@ where
289
289
D : SolverDelegate < Interner = I > ,
290
290
I : Interner ,
291
291
{
292
+ /// Helper function that first tries to normalize the self type of the goal, bailing with
293
+ /// ambiguity if normalizing is ambiguous or if it bottoms out in an infer var, then calls
294
+ /// the `assemble` callback. It additionally manages assembling a coherence-unknowable
295
+ /// candidate if necessary, which takes precedence over all other candidates.
292
296
fn assemble_and_evaluate_candidates_with_normalized_goal < G : GoalKind < D > > (
293
297
& mut self ,
294
298
goal : Goal < I , G > ,
@@ -326,12 +330,28 @@ where
326
330
) -> Vec < Candidate < I > > {
327
331
self . assemble_and_evaluate_candidates_with_normalized_goal ( goal, |ecx, goal| {
328
332
let mut candidates = vec ! [ ] ;
329
- ecx. assemble_alias_bound_candidates ( goal, & mut candidates) ;
330
- ecx. assemble_param_env_candidates ( goal, & mut candidates) ;
333
+ // Only assemble candidates via this helper function, since its logic is shared with
334
+ // `assemble_and_evaluate_candidates` below. Any other candidates that are only
335
+ // assembled by this function (or only by `assemble_and_evaluate_candidates`) will be
336
+ // subtly incomplete when it comes to normalizes-to goals.
337
+ ecx. assemble_param_env_and_bound_candidates ( goal, & mut candidates) ;
338
+ debug_assert ! ( candidates. iter( ) . all( |c| matches!(
339
+ c. source,
340
+ CandidateSource :: AliasBound | CandidateSource :: ParamEnv ( _)
341
+ ) ) ) ;
331
342
candidates
332
343
} )
333
344
}
334
345
346
+ fn assemble_param_env_and_bound_candidates < G : GoalKind < D > > (
347
+ & mut self ,
348
+ goal : Goal < I , G > ,
349
+ candidates : & mut Vec < Candidate < I > > ,
350
+ ) {
351
+ self . assemble_alias_bound_candidates ( goal, candidates) ;
352
+ self . assemble_param_env_candidates ( goal, candidates) ;
353
+ }
354
+
335
355
pub ( super ) fn assemble_and_evaluate_candidates < G : GoalKind < D > > (
336
356
& mut self ,
337
357
goal : Goal < I , G > ,
@@ -341,8 +361,16 @@ where
341
361
ecx. assemble_impl_candidates ( goal, & mut candidates) ;
342
362
ecx. assemble_builtin_impl_candidates ( goal, & mut candidates) ;
343
363
ecx. assemble_object_bound_candidates ( goal, & mut candidates) ;
344
- ecx. assemble_alias_bound_candidates ( goal, & mut candidates) ;
345
- ecx. assemble_param_env_candidates ( goal, & mut candidates) ;
364
+ // NOTE: Make sure that we're not assembling any param-env/bound candidates
365
+ // outside of `assemble_param_env_and_bound_candidates`, since we want to make
366
+ // sure not to *incompletely* assemble candidates in
367
+ // `assemble_and_evaluate_candidates_from_env_and_bounds` which uses the helper
368
+ // `assemble_param_env_and_bound_candidates`.
369
+ debug_assert ! ( !candidates. iter( ) . any( |c| matches!(
370
+ c. source,
371
+ CandidateSource :: AliasBound | CandidateSource :: ParamEnv ( _)
372
+ ) ) ) ;
373
+ ecx. assemble_param_env_and_bound_candidates ( goal, & mut candidates) ;
346
374
candidates
347
375
} )
348
376
}
@@ -766,6 +794,9 @@ where
766
794
} )
767
795
}
768
796
797
+ /// Assemble and merge candidates for goals which are related to an underlying trait
798
+ /// goal. Right now, this is normalizes-to and host effect goals.
799
+ ///
769
800
/// We sadly can't simply take all possible candidates for normalization goals
770
801
/// and check whether they result in the same constraints. We want to make sure
771
802
/// that trying to normalize an alias doesn't result in constraints which aren't
@@ -804,7 +835,7 @@ where
804
835
// We don't care about overflow. If proving the trait goal overflowed, then
805
836
// it's enough to report an overflow error for that, we don't also have to
806
837
// overflow during normalization.
807
- return Ok ( self . make_ambiguous_response_no_constraints ( MaybeCause :: Ambiguity ) ) ;
838
+ return Ok ( self . forced_ambiguity ( MaybeCause :: Ambiguity ) ? . result ) ;
808
839
} ;
809
840
810
841
match proven_via {
@@ -815,11 +846,6 @@ where
815
846
let candidates_from_env_and_bounds: Vec < _ > =
816
847
self . assemble_and_evaluate_candidates_from_env_and_bounds ( goal) ;
817
848
818
- debug_assert ! ( candidates_from_env_and_bounds. iter( ) . all( |c| matches!(
819
- c. source,
820
- CandidateSource :: AliasBound | CandidateSource :: ParamEnv ( _)
821
- ) ) ) ;
822
-
823
849
// We still need to prefer where-bounds over alias-bounds however.
824
850
// See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`.
825
851
let mut considered_candidates: Vec < _ > = if candidates_from_env_and_bounds
0 commit comments