implement a performant and fuzzed solver cache
This commit is contained in:
parent
f860873983
commit
0aa17a4c4d
4 changed files with 740 additions and 358 deletions
|
@ -2,12 +2,12 @@ use std::convert::Infallible;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::search_graph::{self, CycleKind, UsageKind};
|
||||
use rustc_type_ir::search_graph::{self, PathKind};
|
||||
use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult};
|
||||
use rustc_type_ir::Interner;
|
||||
|
||||
use super::inspect::ProofTreeBuilder;
|
||||
use super::FIXPOINT_STEP_LIMIT;
|
||||
use super::{has_no_inference_or_external_constraints, FIXPOINT_STEP_LIMIT};
|
||||
use crate::delegate::SolverDelegate;
|
||||
|
||||
/// This type is never constructed. We only use it to implement `search_graph::Delegate`
|
||||
|
@ -23,10 +23,11 @@ where
|
|||
{
|
||||
type Cx = D::Interner;
|
||||
|
||||
const ENABLE_PROVISIONAL_CACHE: bool = true;
|
||||
type ValidationScope = Infallible;
|
||||
fn enter_validation_scope(
|
||||
_cx: Self::Cx,
|
||||
_input: <Self::Cx as search_graph::Cx>::Input,
|
||||
_input: CanonicalInput<I>,
|
||||
) -> Option<Self::ValidationScope> {
|
||||
None
|
||||
}
|
||||
|
@ -38,39 +39,32 @@ where
|
|||
inspect.is_noop()
|
||||
}
|
||||
|
||||
const DIVIDE_AVAILABLE_DEPTH_ON_OVERFLOW: usize = 4;
|
||||
fn recursion_limit(cx: I) -> usize {
|
||||
cx.recursion_limit()
|
||||
}
|
||||
|
||||
fn initial_provisional_result(
|
||||
cx: I,
|
||||
kind: CycleKind,
|
||||
kind: PathKind,
|
||||
input: CanonicalInput<I>,
|
||||
) -> QueryResult<I> {
|
||||
match kind {
|
||||
CycleKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
|
||||
CycleKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
|
||||
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
|
||||
PathKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
|
||||
}
|
||||
}
|
||||
|
||||
fn reached_fixpoint(
|
||||
cx: I,
|
||||
kind: UsageKind,
|
||||
fn is_initial_provisional_result(
|
||||
cx: Self::Cx,
|
||||
kind: PathKind,
|
||||
input: CanonicalInput<I>,
|
||||
provisional_result: Option<QueryResult<I>>,
|
||||
result: QueryResult<I>,
|
||||
) -> bool {
|
||||
if let Some(r) = provisional_result {
|
||||
r == result
|
||||
} else {
|
||||
match kind {
|
||||
UsageKind::Single(CycleKind::Coinductive) => {
|
||||
response_no_constraints(cx, input, Certainty::Yes) == result
|
||||
}
|
||||
UsageKind::Single(CycleKind::Inductive) => {
|
||||
response_no_constraints(cx, input, Certainty::overflow(false)) == result
|
||||
}
|
||||
UsageKind::Mixed => false,
|
||||
match kind {
|
||||
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes) == result,
|
||||
PathKind::Inductive => {
|
||||
response_no_constraints(cx, input, Certainty::overflow(false)) == result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +82,22 @@ where
|
|||
response_no_constraints(cx, input, Certainty::overflow(false))
|
||||
}
|
||||
|
||||
fn is_ambiguous_result(result: QueryResult<I>) -> bool {
|
||||
result.is_ok_and(|response| {
|
||||
has_no_inference_or_external_constraints(response)
|
||||
&& matches!(response.value.certainty, Certainty::Maybe(_))
|
||||
})
|
||||
}
|
||||
|
||||
fn propagate_ambiguity(
|
||||
cx: I,
|
||||
for_input: CanonicalInput<I>,
|
||||
from_result: QueryResult<I>,
|
||||
) -> QueryResult<I> {
|
||||
let certainty = from_result.unwrap().value.certainty;
|
||||
response_no_constraints(cx, for_input, certainty)
|
||||
}
|
||||
|
||||
fn step_is_coinductive(cx: I, input: CanonicalInput<I>) -> bool {
|
||||
input.value.goal.predicate.is_coinductive(cx)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue