diff options
| author | bors <bors@rust-lang.org> | 2023-03-29 09:45:26 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-03-29 09:45:26 +0000 |
| commit | cf32b9de1e8f66526c36ad2927458558d2e81093 (patch) | |
| tree | d2791bbd10641fa720e0cff4ef053e74d519e3bb /compiler/rustc_trait_selection/src | |
| parent | f346fb0bc655acf72e71f1f16065c271447bdbd9 (diff) | |
| parent | 14157561fb6ac5937deb1de37eb9cb6fb8cd802f (diff) | |
| download | rust-cf32b9de1e8f66526c36ad2927458558d2e81093.tar.gz rust-cf32b9de1e8f66526c36ad2927458558d2e81093.zip | |
Auto merge of #109720 - Dylan-DPC:rollup-u564m8s, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #108335 (rustdoc + rustdoc-json support for `feature(non_lifetime_binders)`) - #109534 (rustdoc: Unsupport importing `doc(primitive)` and `doc(keyword)` modules) - #109659 (llvm-wrapper: adapt for LLVM API change) - #109664 (Use span of placeholders in format_args!() expansion.) - #109683 (Check for overflow in `assemble_candidates_after_normalizing_self_ty`) - #109713 (Fix mismatched punctuation in Debug impl of AttrId) - #109718 (Rename `IndexVec::last` → `last_index`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_trait_selection/src')
3 files changed, 54 insertions, 19 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 4fb77d79518..0f7a0eb337b 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -1,5 +1,6 @@ //! Code shared by trait and projection goals for candidate assembly. +use super::search_graph::OverflowHandler; #[cfg(doc)] use super::trait_goals::structural_traits::*; use super::{EvalCtxt, SolverMode}; @@ -279,25 +280,38 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return }; - self.probe(|ecx| { - let normalized_ty = ecx.next_ty_infer(); - let normalizes_to_goal = goal.with( - tcx, - ty::Binder::dummy(ty::ProjectionPredicate { - projection_ty, - term: normalized_ty.into(), - }), - ); - ecx.add_goal(normalizes_to_goal); - if let Ok(_) = ecx.try_evaluate_added_goals() { - let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty); - - // NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate. - // This doesn't work as long as we use `CandidateSource` in winnowing. - let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); - candidates.extend(ecx.assemble_and_evaluate_candidates(goal)); - } + let normalized_self_candidates: Result<_, NoSolution> = self.probe(|ecx| { + ecx.with_incremented_depth( + |ecx| { + let result = ecx.evaluate_added_goals_and_make_canonical_response( + Certainty::Maybe(MaybeCause::Overflow), + )?; + Ok(vec![Candidate { source: CandidateSource::BuiltinImpl, result }]) + }, + |ecx| { + let normalized_ty = ecx.next_ty_infer(); + let normalizes_to_goal = goal.with( + tcx, + ty::Binder::dummy(ty::ProjectionPredicate { + projection_ty, + term: normalized_ty.into(), + }), + ); + ecx.add_goal(normalizes_to_goal); + let _ = ecx.try_evaluate_added_goals()?; + let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty); + // NOTE: Alternatively we could call `evaluate_goal` here and only + // have a `Normalized` candidate. This doesn't work as long as we + // use `CandidateSource` in winnowing. + let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); + Ok(ecx.assemble_and_evaluate_candidates(goal)) + }, + ) }); + + if let Ok(normalized_self_candidates) = normalized_self_candidates { + candidates.extend(normalized_self_candidates); + } } fn assemble_impl_candidates<G: GoalKind<'tcx>>( diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index d7ad730b4a3..aeb67666035 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -70,7 +70,7 @@ impl<'tcx> SearchGraph<'tcx> { /// Whether we're currently in a cycle. This should only be used /// for debug assertions. pub(super) fn in_cycle(&self) -> bool { - if let Some(stack_depth) = self.stack.last() { + if let Some(stack_depth) = self.stack.last_index() { // Either the current goal on the stack is the root of a cycle... if self.stack[stack_depth].has_been_used { return true; diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index 7c9e63f529b..574f3e9a577 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -73,6 +73,27 @@ pub(in crate::solve) trait OverflowHandler<'tcx> { self.search_graph().overflow_data.deal_with_overflow(); on_overflow(self) } + + // Increment the `additional_depth` by one and evaluate `body`, or `on_overflow` + // if the depth is overflown. + fn with_incremented_depth<T>( + &mut self, + on_overflow: impl FnOnce(&mut Self) -> T, + body: impl FnOnce(&mut Self) -> T, + ) -> T { + let depth = self.search_graph().stack.len(); + self.search_graph().overflow_data.additional_depth += 1; + + let result = if self.search_graph().overflow_data.has_overflow(depth) { + self.search_graph().overflow_data.deal_with_overflow(); + on_overflow(self) + } else { + body(self) + }; + + self.search_graph().overflow_data.additional_depth -= 1; + result + } } impl<'tcx> OverflowHandler<'tcx> for EvalCtxt<'_, 'tcx> { |
