revset: forward ordering requirement to argument of present()
authorYuya Nishihara <yuya@tcha.org>
Wed, 01 Jun 2016 20:54:04 +0900
changeset 29947 80c86b9bb40b
parent 29946 3664537386ab
child 29948 5f56a3b9675e
revset: forward ordering requirement to argument of present() present() is special in that it returns the argument set with no modification, so the ordering requirement should be forwarded. We could make present() fix the order like orset(), but that would be silly because we know the extra filtering cost is unnecessary.
mercurial/revset.py
tests/test-revset.t
--- a/mercurial/revset.py	Wed Sep 14 11:39:47 2016 -0500
+++ b/mercurial/revset.py	Wed Jun 01 20:54:04 2016 +0900
@@ -2473,7 +2473,13 @@
     elif op == 'keyvalue':
         return (op, x[1], _analyze(x[2], order))
     elif op == 'func':
-        return (op, x[1], _analyze(x[2], defineorder), order)
+        f = getsymbol(x[1])
+        d = defineorder
+        if f == 'present':
+            # 'present(set)' is known to return the argument set with no
+            # modification, so forward the current order to its argument
+            d = order
+        return (op, x[1], _analyze(x[2], d), order)
     raise ValueError('invalid operator %r' % op)
 
 def analyze(x, order=defineorder):
--- a/tests/test-revset.t	Wed Sep 14 11:39:47 2016 -0500
+++ b/tests/test-revset.t	Wed Jun 01 20:54:04 2016 +0900
@@ -1485,7 +1485,23 @@
       <baseset [0, 1]>>>
   2
 
- 'present()' should do nothing other than suppressing an error:
+ because 'present()' does nothing other than suppressing an error, the
+ ordering requirement should be forwarded to the nested expression
+
+  $ try -p optimized 'present(2 + 0 + 1)'
+  * optimized:
+  (func
+    ('symbol', 'present')
+    (func
+      ('symbol', '_list')
+      ('string', '2\x000\x001')
+      define)
+    define)
+  * set:
+  <baseset [2, 0, 1]>
+  2
+  0
+  1
 
   $ try --optimize '2:0 & present(0 + 1 + 2)'
   (and
@@ -1510,15 +1526,16 @@
       (func
         ('symbol', '_list')
         ('string', '0\x001\x002')
-        define)
+        follow)
       follow)
     define)
   * set:
-  <baseset [0, 1, 2]>
-  0
+  <filteredset
+    <spanset- 0:2>,
+    <baseset [0, 1, 2]>>
+  2
   1
-  2
- BROKEN: should be '2 1 0'
+  0
 
  'reverse()' should take effect only if it is the outermost expression: