diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -27,13 +27,8 @@ from . import (
     util,
 )
 
-try:
-    from . import rustext
-    rustext.__name__  # force actual import (see hgdemandimport)
-except ImportError:
-    rustext = None
-
 parsers = policy.importmod(r'parsers')
+dirstatemod = policy.importrust(r'dirstate', default=parsers)
 
 propertycache = util.propertycache
 filecache = scmutil.filecache
@@ -1468,12 +1463,7 @@ class dirstatemap(object):
         # parsing the dirstate.
         #
         # (we cannot decorate the function directly since it is in a C module)
-        if rustext is not None:
-            parse_dirstate = rustext.dirstate.parse_dirstate
-        else:
-            parse_dirstate = parsers.parse_dirstate
-
-        parse_dirstate = util.nogc(parse_dirstate)
+        parse_dirstate = util.nogc(dirstatemod.parse_dirstate)
         p = parse_dirstate(self._map, self.copymap, st)
         if not self._dirtyparents:
             self.setparents(*p)
@@ -1484,13 +1474,8 @@ class dirstatemap(object):
         self.get = self._map.get
 
     def write(self, st, now):
-        if rustext is not None:
-            pack_dirstate = rustext.dirstate.pack_dirstate
-        else:
-            pack_dirstate = parsers.pack_dirstate
-
-        st.write(pack_dirstate(self._map, self.copymap,
-                                       self.parents(), now))
+        st.write(dirstatemod.pack_dirstate(self._map, self.copymap,
+                                           self.parents(), now))
         st.close()
         self._dirtyparents = False
         self.nonnormalset, self.otherparentset = self.nonnormalentries()
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -17,6 +17,7 @@ from . import (
     encoding,
     error,
     pathutil,
+    policy,
     pycompat,
     util,
 )
@@ -24,11 +25,7 @@ from .utils import (
     stringutil,
 )
 
-try:
-    from . import rustext
-    rustext.__name__  # force actual import (see hgdemandimport)
-except ImportError:
-    rustext = None
+rustmod = policy.importrust('filepatterns')
 
 allpatternkinds = ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
                    'rootglob',
@@ -1197,14 +1194,14 @@ def _regex(kind, pat, globsuffix):
     regular expression.
     globsuffix is appended to the regexp of globs.'''
 
-    if rustext is not None:
+    if rustmod is not None:
         try:
-            return rustext.filepatterns.build_single_regex(
+            return rustmod.build_single_regex(
                 kind,
                 pat,
                 globsuffix
             )
-        except rustext.filepatterns.PatternError:
+        except rustmod.PatternError:
             raise error.ProgrammingError(
                 'not a regex pattern: %s:%s' % (kind, pat)
             )
@@ -1460,8 +1457,8 @@ def readpatternfile(filepath, warn, sour
     This is useful to debug ignore patterns.
     '''
 
-    if rustext is not None:
-        result, warnings = rustext.filepatterns.read_pattern_file(
+    if rustmod is not None:
+        result, warnings = rustmod.read_pattern_file(
             filepath,
             bool(warn),
             sourceinfo,
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -97,11 +97,8 @@ REVIDX_KNOWN_FLAGS
 REVIDX_RAWTEXT_CHANGING_FLAGS
 
 parsers = policy.importmod(r'parsers')
-try:
-    from . import rustext
-    rustext.__name__  # force actual import (see hgdemandimport)
-except ImportError:
-    rustext = None
+rustancestor = policy.importrust(r'ancestor')
+rustdagop = policy.importrust(r'dagop')
 
 # Aliased for performance.
 _zlibdecompress = zlib.decompress
@@ -825,8 +822,8 @@ class revlog(object):
             checkrev(r)
         # and we're sure ancestors aren't filtered as well
 
-        if rustext is not None:
-            lazyancestors = rustext.ancestor.LazyAncestors
+        if rustancestor is not None:
+            lazyancestors = rustancestor.LazyAncestors
             arg = self.index
         elif util.safehasattr(parsers, 'rustlazyancestors'):
             lazyancestors = ancestor.rustlazyancestors
@@ -915,8 +912,8 @@ class revlog(object):
         if common is None:
             common = [nullrev]
 
-        if rustext is not None:
-            return rustext.ancestor.MissingAncestors(self.index, common)
+        if rustancestor is not None:
+            return rustancestor.MissingAncestors(self.index, common)
         return ancestor.incrementalmissingancestors(self.parentrevs, common)
 
     def findmissingrevs(self, common=None, heads=None):
@@ -1130,8 +1127,8 @@ class revlog(object):
                 return self.index.headrevs()
             except AttributeError:
                 return self._headrevs()
-        if rustext is not None:
-            return rustext.dagop.headrevs(self.index, revs)
+        if rustdagop is not None:
+            return rustdagop.headrevs(self.index, revs)
         return dagop.headrevs(revs, self._uncheckedparentrevs)
 
     def computephases(self, roots):