@@ -27,6 +27,7 @@ use super::{
27
27
28
28
use crate :: infer:: { InferCtxt , InferOk , TypeFreshener } ;
29
29
use crate :: traits:: error_reporting:: TypeErrCtxtExt ;
30
+ use crate :: traits:: project:: try_normalize_with_depth_to;
30
31
use crate :: traits:: project:: ProjectAndUnifyResult ;
31
32
use crate :: traits:: project:: ProjectionCacheKeyExt ;
32
33
use crate :: traits:: ProjectionCacheKey ;
@@ -1017,7 +1018,51 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1017
1018
return Ok ( cycle_result) ;
1018
1019
}
1019
1020
1020
- let ( result, dep_node) = self . in_task ( |this| this. evaluate_stack ( & stack) ) ;
1021
+ let ( result, dep_node) = self . in_task ( |this| {
1022
+ let mut result = this. evaluate_stack ( & stack) ?;
1023
+
1024
+ // fix issue #103563, we don't normalize
1025
+ // nested obligations which produced by `TraitDef` candidate
1026
+ // (i.e. using bounds on assoc items as assumptions).
1027
+ // because we don't have enough information to
1028
+ // normalize these obligations before evaluating.
1029
+ // so we will try to normalize the obligation and evaluate again.
1030
+ // we will replace it with new solver in the future.
1031
+ if EvaluationResult :: EvaluatedToErr == result
1032
+ && fresh_trait_pred. has_projections ( )
1033
+ && fresh_trait_pred. is_global ( )
1034
+ {
1035
+ let mut nested_obligations = Vec :: new ( ) ;
1036
+ let predicate = try_normalize_with_depth_to (
1037
+ this,
1038
+ param_env,
1039
+ obligation. cause . clone ( ) ,
1040
+ obligation. recursion_depth + 1 ,
1041
+ obligation. predicate ,
1042
+ & mut nested_obligations,
1043
+ ) ;
1044
+ if predicate != obligation. predicate {
1045
+ let mut nested_result = EvaluationResult :: EvaluatedToOk ;
1046
+ for obligation in nested_obligations {
1047
+ nested_result = cmp:: max (
1048
+ this. evaluate_predicate_recursively ( stack. list ( ) , obligation) ?,
1049
+ nested_result,
1050
+ ) ;
1051
+ }
1052
+
1053
+ if nested_result. must_apply_modulo_regions ( ) {
1054
+ let obligation = obligation. with ( this. tcx ( ) , predicate) ;
1055
+ result = cmp:: max (
1056
+ nested_result,
1057
+ this. evaluate_trait_predicate_recursively ( stack. list ( ) , obligation) ?,
1058
+ ) ;
1059
+ }
1060
+ }
1061
+ }
1062
+
1063
+ Ok :: < _ , OverflowError > ( result)
1064
+ } ) ;
1065
+
1021
1066
let result = result?;
1022
1067
1023
1068
if !result. must_apply_modulo_regions ( ) {
0 commit comments