diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java index b4b215a18f1db3..525dead381f0c7 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java @@ -643,18 +643,18 @@ public RepoRuleProxy useRepoRule(String bzlFile, String ruleName, StarlarkThread throws EvalException { ModuleThreadContext context = ModuleThreadContext.fromOrFail(thread, "use_repo_rule()"); context.setNonModuleCalled(); - // The builder for the singular "innate" extension of this module. + // Find or create the builder for the singular "innate" extension of this module. + for (ModuleExtensionUsageBuilder usageBuilder : context.getExtensionUsageBuilders()) { + if (usageBuilder.isForExtension("//:MODULE.bazel", ModuleExtensionId.INNATE_EXTENSION_NAME)) { + return new RepoRuleProxy(usageBuilder, bzlFile + '%' + ruleName); + } + } ModuleExtensionUsageBuilder newUsageBuilder = new ModuleExtensionUsageBuilder( context, "//:MODULE.bazel", ModuleExtensionId.INNATE_EXTENSION_NAME, /* isolate= */ false); - for (ModuleExtensionUsageBuilder usageBuilder : context.getExtensionUsageBuilders()) { - if (usageBuilder.isForExtension("//:MODULE.bazel", ModuleExtensionId.INNATE_EXTENSION_NAME)) { - return new RepoRuleProxy(usageBuilder, bzlFile + '%' + ruleName); - } - } context.getExtensionUsageBuilders().add(newUsageBuilder); return new RepoRuleProxy(newUsageBuilder, bzlFile + '%' + ruleName); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleThreadContext.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleThreadContext.java index ed70e57f7fdb81..19ba4f7caa153f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleThreadContext.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleThreadContext.java @@ -249,6 +249,10 @@ public InterimModule buildModule(@Nullable Registry registry) throws EvalExcepti // Build module extension usages and the rest of the module. var extensionUsages = ImmutableList.builder(); for (var extensionUsageBuilder : extensionUsageBuilders) { + if (extensionUsageBuilder.proxyBuilders.isEmpty()) { + // This can happen for the special extension used for "use_repo_rule" calls. + continue; + } extensionUsages.add(extensionUsageBuilder.buildUsage()); } return module diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java index 05cb51caa8632e..dcab466f8b2908 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java @@ -1538,6 +1538,20 @@ public void isolatedUsage_notEnabled() throws Exception { + "--experimental_isolated_extension_usages"); } + @Test + public void testNoUsages() throws Exception { + scratch.overwriteFile( + rootDirectory.getRelative("MODULE.bazel").getPathString(), + "module(name='aaa')", + "http_archive = use_repo_rule('@bazel_tools//tools/build_defs/repo:http.bzl'," + + " 'http_archive')"); + + EvaluationResult result = + evaluator.evaluate( + ImmutableList.of(ModuleFileValue.KEY_FOR_ROOT_MODULE), evaluationContext); + assertThat(result.hasError()).isFalse(); + } + @Test public void testInvalidRepoInPatches() throws Exception { scratch.overwriteFile(