diff --git a/glean/db/Glean/Query/Reorder.hs b/glean/db/Glean/Query/Reorder.hs index 4d6b17573e..75837d89e4 100644 --- a/glean/db/Glean/Query/Reorder.hs +++ b/glean/db/Glean/Query/Reorder.hs @@ -929,7 +929,9 @@ toCgStatement stmt = case stmt of lhs' <- fixVars IsPat lhs return [CgStatement lhs' gen'] FlatAllStatement v e g -> do - cg <- withScopeFor (scopeVars g <> vars e) $ do + -- withinNegation enforces that bindings within the all are local + -- to this scope and not visible outside. + cg <- withinNegation $ withScopeFor (scopeVars g <> vars e) $ do stmts <- reorderGroup g e' <- fixVars IsExpr e return [CgAllStatement v e' stmts] diff --git a/glean/db/Glean/Query/Vars.hs b/glean/db/Glean/Query/Vars.hs index 79671c59b0..7065497d35 100644 --- a/glean/db/Glean/Query/Vars.hs +++ b/glean/db/Glean/Query/Vars.hs @@ -29,6 +29,7 @@ import Data.IntSet (IntSet) import qualified Data.IntMap as IntMap import Data.IntMap (IntMap) import Data.List.NonEmpty (NonEmpty) +import Data.Maybe import Glean.Display import Glean.Query.Codegen.Types @@ -185,29 +186,28 @@ reWildGenerator used gen = case gen of PrimCall op args ty -> PrimCall op (map (reWild used) args) ty -reWildStatement :: VarMap -> CgStatement -> CgStatement +reWildStatement :: VarMap -> CgStatement -> Maybe CgStatement reWildStatement used (CgStatement lhs rhs) = - CgStatement (reWild used lhs) (reWildGenerator used rhs) -reWildStatement used s@(CgAllStatement (Var ty n x) expr stmts) = + Just $ CgStatement (reWild used lhs) (reWildGenerator used rhs) +reWildStatement used (CgAllStatement (Var ty n x) expr stmts) = case IntMap.lookup n used of - Nothing -> error $ - "reWildStatement: var " <> show n <> - " not in scope in " <> show (displayVerbose s) <> - "\nVarMap: " <> show used + Nothing -> + -- the variable isn't used, so the statement has no effect + Nothing Just new -> - CgAllStatement + Just $ CgAllStatement (Var ty new x) (reWild used expr) - (map (reWildStatement used) stmts) + (mapMaybe (reWildStatement used) stmts) reWildStatement used (CgNegation stmts) = - CgNegation (map (reWildStatement used) stmts) + Just $ CgNegation (mapMaybe (reWildStatement used) stmts) reWildStatement used (CgDisjunction stmtss) = - CgDisjunction (map (map (reWildStatement used)) stmtss) + Just $ CgDisjunction (map (mapMaybe (reWildStatement used)) stmtss) reWildStatement used (CgConditional cond then_ else_) = - CgConditional - (map (reWildStatement used) cond) - (map (reWildStatement used) then_) - (map (reWildStatement used) else_) + Just $ CgConditional + (mapMaybe (reWildStatement used) cond) + (mapMaybe (reWildStatement used) then_) + (mapMaybe (reWildStatement used) else_) reWildQuery :: VarMap -> CgQuery -> CgQuery reWildQuery used (CgQuery head stmts) = - CgQuery (reWild used head) (map (reWildStatement used) stmts) + CgQuery (reWild used head) (mapMaybe (reWildStatement used) stmts) diff --git a/glean/test/tests/Angle/SetTest.hs b/glean/test/tests/Angle/SetTest.hs index 742f8c6700..9c2e1de414 100644 --- a/glean/test/tests/Angle/SetTest.hs +++ b/glean/test/tests/Angle/SetTest.hs @@ -36,7 +36,7 @@ import Glean.Typed.Binary import Glean.Types import qualified Data.HashMap.Strict as HashMap -import Data.Set +import Data.Set as Set import Test.HUnit import TestRunner @@ -157,6 +157,15 @@ setSemanticsTest dbTestCase = TestList [set] <- runQuery_ env repo $ angleData @(Set Glean.Test.Predicate) [s| all (glean.test.Predicate _) |] assertEqual "angle - set matching" 4 (size set) + , TestLabel "unused all" $ dbTestCase $ \env repo -> do + r <- runQuery_ env repo $ angleData @Nat + [s| X where _ = all (X = 1); X = 0 |] + assertEqual "unused all" r [Nat 0] + , TestLabel "local constraint" $ dbTestCase $ \env repo -> do + r <- runQuery_ env repo $ angleData @(Set Nat) + [s| all (X where X = 1) where X = 1|2 |] + assertEqual "local constraint" + (sort r) [Set.empty, Set.fromList [Nat 1]] ] setLimitTest :: Test