changeset 29943:80c86b9bb40b

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.
author Yuya Nishihara <yuya@tcha.org>
date Wed, 01 Jun 2016 20:54:04 +0900
parents 3664537386ab
children 5f56a3b9675e
files mercurial/revset.py tests/test-revset.t
diffstat 2 files changed, 30 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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: