From af9b4f4457e6bd8d51462ee450a770288d36a053 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 4 Sep 2025 13:03:41 +0200 Subject: [PATCH] Rust: Use `doublyBoundedFastTC` in `TraitIsVisible` --- .../codeql/rust/internal/PathResolution.qll | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 77faaa747b96..f3a7eb03c72e 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -1425,24 +1425,56 @@ signature predicate relevantTraitVisibleSig(Element element, Trait trait); * at a given element. */ module TraitIsVisible { - /** Holds if the trait might be looked up in `encl`. */ - private predicate traitLookup(ItemNode encl, Element element, Trait trait) { - // lookup in immediately enclosing item - relevantTraitVisible(element, trait) and - encl.getADescendant() = element + private newtype TNode = + TTrait(Trait t) { relevantTraitVisible(_, t) } or + TItemNode(ItemNode i) or + TElement(Element e) { relevantTraitVisible(e, _) } + + private predicate isTrait(TNode n) { n instanceof TTrait } + + private predicate step(TNode n1, TNode n2) { + exists(Trait t1, ItemNode i2 | + n1 = TTrait(t1) and + n2 = TItemNode(i2) and + t1 = i2.getASuccessor(_, _) + ) or - // lookup in an outer scope, but only if the trait is not declared in inner scope - exists(ItemNode mid | - traitLookup(mid, element, trait) and - not trait = mid.getASuccessor(_, _) and - encl = getOuterScope(mid) + exists(ItemNode i1, ItemNode i2 | + n1 = TItemNode(i1) and + n2 = TItemNode(i2) and + i1 = getOuterScope(i2) + ) + or + exists(ItemNode i1, Element e2 | + n1 = TItemNode(i1) and + n2 = TElement(e2) and + i1.getADescendant() = e2 + ) + } + + private predicate isElement(TNode n) { n instanceof TElement } + + private predicate traitIsVisibleTC(TNode trait, TNode element) = + doublyBoundedFastTC(step/2, isTrait/1, isElement/1)(trait, element) + + pragma[nomagic] + private predicate relevantTraitVisibleLift(TNode trait, TElement element) { + exists(Trait t, Element e | + trait = TTrait(t) and + element = TElement(e) and + relevantTraitVisible(e, t) ) } /** Holds if the trait `trait` is visible at `element`. */ pragma[nomagic] predicate traitIsVisible(Element element, Trait trait) { - exists(ItemNode encl | traitLookup(encl, element, trait) and trait = encl.getASuccessor(_, _)) + exists(TNode t, TNode e | + traitIsVisibleTC(t, e) and + relevantTraitVisibleLift(t, e) and + t = TTrait(trait) and + e = TElement(element) + ) } }