diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -545,10 +545,20 @@ def date(context, mapping, args):
         # i18n: "date" is a keyword
         raise error.ParseError(_("date expects a date information"))
 
-@templatefunc('dict([key=value...])', argspec='**kwargs')
+@templatefunc('dict([[key=]value...])', argspec='*args **kwargs')
 def dict_(context, mapping, args):
-    """Construct a dict from key-value pairs."""
+    """Construct a dict from key-value pairs. A key may be omitted if
+    a value expression can provide an unambiguous name."""
     data = util.sortdict()
+
+    for v in args['args']:
+        k = findsymbolicname(v)
+        if not k:
+            raise error.ParseError(_('dict key cannot be inferred'))
+        if k in data or k in args['kwargs']:
+            raise error.ParseError(_("duplicated dict key '%s' inferred") % k)
+        data[k] = evalfuncarg(context, mapping, v)
+
     data.update((k, evalfuncarg(context, mapping, v))
                 for k, v in args['kwargs'].iteritems())
     return templatekw.hybriddict(data)
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -3424,6 +3424,21 @@ Test dict constructor:
   $ hg log -r 0 -T '{dict()|json}\n'
   {}
 
+  $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
+  rev=0 node=f7769ec2ab97
+  $ hg log -r 0 -T '{dict(rev, node|short)}\n'
+  rev=0 node=f7769ec2ab97
+
+  $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
+  hg: parse error: duplicated dict key 'rev' inferred
+  [255]
+  $ hg log -r 0 -T '{dict(node, node|short)}\n'
+  hg: parse error: duplicated dict key 'node' inferred
+  [255]
+  $ hg log -r 0 -T '{dict(1 + 2)}'
+  hg: parse error: dict key cannot be inferred
+  [255]
+
   $ hg log -r 0 -T '{dict(x=rev, x=node)}'
   hg: parse error: dict got multiple values for keyword argument 'x'
   [255]