diff options
| author | bors <bors@rust-lang.org> | 2023-02-14 10:01:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-02-14 10:01:19 +0000 |
| commit | 9bb6e60d1f1360234aae90c97964c0fa5524f141 (patch) | |
| tree | caaac596c791f95348d587f5c68976d46a6aafd7 /compiler | |
| parent | e9ab7872fd77861e3d182ea85a82c4649c5bb3f8 (diff) | |
| parent | d16444803836fa5fd665f9f5e303a9f4d113edd6 (diff) | |
Auto merge of #103695 - LYF1999:yf/103563, r=lcnr
fix: Unexpected trait bound not satisfied in HRTB and Associated Type fix https://github.com/rust-lang/rust/issues/103563
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 302adb79766..fc9678233c3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -27,6 +27,7 @@ use super::{ use crate::infer::{InferCtxt, InferOk, TypeFreshener}; use crate::traits::error_reporting::TypeErrCtxtExt; +use crate::traits::project::try_normalize_with_depth_to; use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; @@ -1049,7 +1050,51 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Ok(cycle_result); } - let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack)); + let (result, dep_node) = self.in_task(|this| { + let mut result = this.evaluate_stack(&stack)?; + + // fix issue #103563, we don't normalize + // nested obligations which produced by `TraitDef` candidate + // (i.e. using bounds on assoc items as assumptions). + // because we don't have enough information to + // normalize these obligations before evaluating. + // so we will try to normalize the obligation and evaluate again. + // we will replace it with new solver in the future. + if EvaluationResult::EvaluatedToErr == result + && fresh_trait_pred.has_projections() + && fresh_trait_pred.is_global() + { + let mut nested_obligations = Vec::new(); + let predicate = try_normalize_with_depth_to( + this, + param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + obligation.predicate, + &mut nested_obligations, + ); + if predicate != obligation.predicate { + let mut nested_result = EvaluationResult::EvaluatedToOk; + for obligation in nested_obligations { + nested_result = cmp::max( + this.evaluate_predicate_recursively(stack.list(), obligation)?, + nested_result, + ); + } + + if nested_result.must_apply_modulo_regions() { + let obligation = obligation.with(this.tcx(), predicate); + result = cmp::max( + nested_result, + this.evaluate_trait_predicate_recursively(stack.list(), obligation)?, + ); + } + } + } + + Ok::<_, OverflowError>(result) + }); + let result = result?; if !result.must_apply_modulo_regions() { |
