Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Judgment prove_predicate

judgment_fn! {
    /// The "heart" of the trait system -- prove that a where-clause holds given a set of declarations, variable environment, and set of assumptions.
    /// If successful, returns the constraints under which the where-clause holds.
    pub fn prove_predicate(
        _decls: Program,
        env: Env,
        assumptions: Predicates,
        goal: Predicate,
    ) => Constraints {
        /* rules omitted */
    }
}

Source: crates/formality-rust/src/prove/prove_predicate.rs:22

The number on each rule’s conclusion is positive coverage; the number on each premise is negative coverage. Click a number to browse the tests.

forall
LineCoverageSource
34✗(scope(enter_universally_with_constraints(env, binder) => (env, p1)) with(c)
(prove_predicate(decls, env, assumptions, p1) => c))
──────── ("forall")
3714(prove_predicate(decls, env, assumptions, Predicate::ForAll(binder)) => c)
implies
LineCoverageSource
413(prove_predicate(decls, env, (assumptions, p1), p2) => c)
──────── ("implies")
434(prove_predicate(decls, env, assumptions, Predicate::Implies(p1, p2)) => c)
assumption
LineCoverageSource
47✗(a in assumptions)
4834(prove_via(decls, env, assumptions, a, goal) => c)
──────── ("assumption")
5023(prove_predicate(decls, env, assumptions, Predicate::AtomicPredicate(goal)) => c)
positive impl
LineCoverageSource
57✗(i in decls.impl_decls(&trait_ref.trait_id))
60✗(scope(enter_existentially_with_constraints(env, &i.binder) => (env, i)) with(c)
// Instantiate trait where-clauses from `Foo<?B>`. If we had `trait Foo<X: Debug>`, for example,
// this would yield `?B: Debug`.
(let t = decls.trait_decl(&i.trait_ref.trait_id).binder.instantiate_with(&i.trait_ref.parameters).unwrap())

// Create a set of assumptions `co_assumptions` that include the predicate the impl itself
// is asserting (i.e., `A: Foo<B>`). When proving the impl's where-clauses, we are allowed
// to assume this is true (in a coinductive fashion).
//
// NB: This is actually not what Rust currently does, but it is what "we" (types team) want it to do.
(let co_assumptions = (assumptions, trait_ref))
(prove(decls, env, co_assumptions, Predicates::all_eq(&trait_ref.parameters, &i.trait_ref.parameters)) => c)
(prove_after(decls, c, co_assumptions, &i.where_clause) => c)

// Prove that the well-formedness requirements of the *trait* hold -- for this proof, we cannot
// assume that the trait is implemented, because that would allow specious implied bounds
// (i.e., we could assume that `B: Debug` based on the trait definition + the existence of an impl,
// but actually the impl is responsible for proving that `B: Debug`).
(prove_after(decls, c, assumptions, &t.where_clause) => c))
──────── ("positive impl")
80219(prove_predicate(decls, env, assumptions, AtomicPredicate::IsImplemented(trait_ref)) => c)
coherence / remote impl
LineCoverageSource
84✗(if env.bias() == Bias::Completeness)
85✗(may_be_remote(decls, env, assumptions, trait_ref) => c)
──────── ("coherence / remote impl")
87✗(prove_predicate(decls, env, assumptions, AtomicPredicate::IsImplemented(trait_ref)) => c)
negative impl
LineCoverageSource
918(i in decls.neg_impl_decls(&trait_ref.trait_id))
92✗(scope(enter_existentially_with_constraints(env, &i.binder) => (env, i)) with(c)
(prove(decls, env, assumptions, Predicates::all_eq(&trait_ref.parameters, &i.trait_ref.parameters)) => c)
(prove_after(decls, c, assumptions, &i.where_clause) => c))
──────── ("negative impl")
963(prove_predicate(decls, env, assumptions, AtomicPredicate::NotImplemented(trait_ref)) => c)
alias eq
LineCoverageSource
100✗(prove_eq(decls, env, assumptions, alias_ty, ty) => c)
──────── ("alias eq")
1021(prove_predicate(decls, env, assumptions, AtomicPredicate::AliasEq(alias_ty, ty)) => c)
trait implied bound
LineCoverageSource
10619(ti in decls.trait_invariants())
107✗(scope(enter_existentially_with_constraints(env, &ti.binder) => (env, ti)) with(c)
(prove_via(decls, env, assumptions, &ti.where_clause, trait_ref) => c)
(prove_after(decls, c, assumptions, &ti.trait_ref) => c))
──────── ("trait implied bound")
1111(prove_predicate(decls, env, assumptions, AtomicPredicate::IsImplemented(trait_ref)) => c)
eq
LineCoverageSource
11517(prove_eq(decls, env, assumptions, a, b) => c)
──────── ("eq")
117231(prove_predicate(decls, env, assumptions, AtomicPredicate::Equals(a, b)) => c)
subtype
LineCoverageSource
12111(prove_sub(decls, env, assumptions, a, b) => c)
──────── ("subtype")
123134(prove_predicate(decls, env, assumptions, AtomicPredicate::Sub(a, b)) => c)
trait well formed
LineCoverageSource
1271(for_all(decls, env, assumptions, &trait_ref.parameters, &prove_wf) => c)
128N/A(let t = decls.trait_decl(&trait_ref.trait_id))
129N/A(let t = t.binder.instantiate_with(&trait_ref.parameters).unwrap())
1302(prove_after(decls, c, assumptions, &t.where_clause) => c)
──────── ("trait well formed")
13230(prove_predicate(decls, env, assumptions, AtomicPredicate::WellFormedTraitRef(trait_ref)) => c)
trait ref is local
LineCoverageSource
13612(is_local_trait_ref(decls, env, assumptions, trait_ref) => c)
──────── ("trait ref is local")
138211(prove_predicate(decls, env, assumptions, AtomicPredicate::IsLocal(trait_ref)) => c)
outlives
LineCoverageSource
1428(prove_outlives(decls, env, assumptions, a, b) => c)
──────── ("outlives")
144195(prove_predicate(decls, env, assumptions, AtomicPredicate::Outlives(a, b)) => c)
parameter well formed
LineCoverageSource
1494(prove_wf(decls, env, assumptions, p) => c)
──────── ("parameter well formed")
151204(prove_predicate(decls, env, assumptions, AtomicPredicate::WellFormed(p)) => c)
const has ty
LineCoverageSource
1551(prove_const_has_type(decls, env, assumptions, constant) => (ty_constant, c))
1561(prove_after(decls, c, assumptions, AtomicPredicate::equals(ty_constant, ty)) => c)
──────── ("const has ty")
1584(prove_predicate(decls, env, assumptions, AtomicPredicate::ConstHasType(constant, ty)) => c)

How to read this page