From 792d17c223ef5d170814940b28b4a3c69b799a2b Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 22 May 2024 15:18:37 -0700 Subject: [PATCH] Fix a crash on `use_repo_rule` with no repos Fixes #22489 Closes #22493. PiperOrigin-RevId: 636310898 Change-Id: If2fb41fd8d51f15aa1047cb62d55035e81187e41 --- .../build/lib/bazel/bzlmod/ModuleFileGlobals.java | 12 ++++++------ .../lib/bazel/bzlmod/ModuleThreadContext.java | 4 ++++ .../lib/bazel/bzlmod/ModuleFileFunctionTest.java | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) 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 0cf5ca0e2c1a76..b8775754d01fea 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 @@ -656,18 +656,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 51afe0425e5fdb..e9347b514f8fc1 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 @@ -1612,6 +1612,20 @@ public void testRegisterToolchains_singlePackageRestriction() throws Exception { assertThat(result.hasError()).isFalse(); } + @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(