Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: local variable 'cc_toolchain' is referenced before assignment. #635

Open
iffyio opened this issue Mar 16, 2021 · 16 comments
Open

Error: local variable 'cc_toolchain' is referenced before assignment. #635

iffyio opened this issue Mar 16, 2021 · 16 comments
Labels

Comments

@iffyio
Copy link

iffyio commented Mar 16, 2021

Hi! I get this error from rust_library targets after updating to commit 76c44206c4d37491767446c6ccdf1a98274a0887

Traceback (most recent call last):
        File "/home/iffy/.cache/bazel/_bazel_iffy/7f16182b13b4a660f93298499007a04c/external/rules_rust/rust/toolchain.bzl", line 154, column 72, in _rust_toolchain_impl
                libstd_and_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, ctx.attr.rust_lib, ctx.attr.allocator_library),
        File "/home/iffy/.cache/bazel/_bazel_iffy/7f16182b13b4a660f93298499007a04c/external/rules_rust/rust/toolchain.bzl", line 43, column 60, in _make_libstd_and_allocator_ccinfo
                cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
        File "/home/iffy/.cache/bazel/_bazel_iffy/7f16182b13b4a660f93298499007a04c/external/rules_rust/rust/private/utils.bzl", line 43, column 24, in find_cc_toolchain
                cc_toolchain = cc_toolchain,
Error: local variable 'cc_toolchain' is referenced before assignment.

it seems like somehow @bazel_tools//tools/cpp:toolchain_type was supposed to be set but no longer isnt?

@UebelAndre
Copy link
Collaborator

Can you provide an example that demonstrates this issue?

@iffyio
Copy link
Author

iffyio commented Mar 17, 2021

The issue occurs when using --incompatible_enable_cc_toolchain_resolution

given WORKSPACE file

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "rules_rust",
    strip_prefix = "rules_rust-76c44206c4d37491767446c6ccdf1a98274a0887",
    urls = [
        "https://github.com/bazelbuild/rules_rust/archive/76c44206c4d37491767446c6ccdf1a98274a0887.tar.gz",
    ],
)
load("@rules_rust//rust:repositories.bzl", "rust_repositories")
rust_repositories(version="1.49.0")

given the target

load("@rules_rust//rust:rust.bzl", "rust_library")
rust_library(
    name = "hello-world",
    srcs = [
        "src/main.rs",
    ],
    edition = "2018",
    visibility = ["//visibility:public"],
)
$ bazel build --incompatible_enable_cc_toolchain_resolution hello-world
INFO: SHA256 (https://github.com/bazelbuild/rules_rust/archive/76c44206c4d37491767446c6ccdf1a98274a0887.tar.gz) = 0044473997e40c5467aa410912ae8771aa328e2d44d71df073b87f147ab5cfcf
DEBUG: Rule 'rules_rust' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "0044473997e40c5467aa410912ae8771aa328e2d44d71df073b87f147ab5cfcf"
DEBUG: Repository rules_rust instantiated at:
  /tmp/repro/WORKSPACE:3:13: in <toplevel>
Repository rule http_archive defined at:
  /home/iffy/.cache/bazel/_bazel_iffy/a81b5ac6b5d7900969957b5de3807d8b/external/bazel_tools/tools/build_defs/repo/http.bzl:336:31: in <toplevel>
ERROR: /home/iffy/.cache/bazel/_bazel_iffy/a81b5ac6b5d7900969957b5de3807d8b/external/rust_linux_x86_64/BUILD.bazel:82:15: in rust_toolchain rule @rust_linux_x86_64//:toolchain_for_x86_64-unknown-linux-gnu_impl:
Traceback (most recent call last):
        File "/home/iffy/.cache/bazel/_bazel_iffy/a81b5ac6b5d7900969957b5de3807d8b/external/rules_rust/rust/toolchain.bzl", line 154, column 72, in _rust_toolchain_impl
                libstd_and_allocator_ccinfo = _make_libstd_and_allocator_ccinfo(ctx, ctx.attr.rust_lib, ctx.attr.allocator_library),
        File "/home/iffy/.cache/bazel/_bazel_iffy/a81b5ac6b5d7900969957b5de3807d8b/external/rules_rust/rust/toolchain.bzl", line 43, column 60, in _make_libstd_and_allocator_ccinfo
                cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
        File "/home/iffy/.cache/bazel/_bazel_iffy/a81b5ac6b5d7900969957b5de3807d8b/external/rules_rust/rust/private/utils.bzl", line 43, column 24, in find_cc_toolchain
                cc_toolchain = cc_toolchain,
Error: local variable 'cc_toolchain' is referenced before assignment.
ERROR: While resolving toolchains for target //hello-world:hello-world: Analysis of target '@rust_linux_x86_64//:toolchain_for_x86_64-unknown-linux-gnu_impl' failed
ERROR: Analysis of target '//hello-world:hello-world' failed; build aborted: Analysis of target '@rust_linux_x86_64//:toolchain_for_x86_64-unknown-linux-gnu_impl' failed
INFO: Elapsed time: 4.123s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (28 packages loaded, 27940 targets configured)

@illicitonion
Copy link
Collaborator

I reproduce, this looks like it was introduced in in #624, but looks really weird - the actual error message given:
Error: local variable 'cc_toolchain' is referenced before assignment.
seems weirdly spurious, as the variable is clearly assigned, and that file didn't even change in that pull request, which suggests at least there's a bug in Bazel's starlark interpreter somewhere...

I'll keep digging for a bit...

@iffyio
Copy link
Author

iffyio commented Mar 17, 2021

The problematic part occurs here while trying to resolve the toolchain https://github.com/bazelbuild/bazel/blob/master/tools/cpp/toolchain_utils.bzl#L41. Even though the check succeeds, ctx.toolchains["@bazel_tools//tools/cpp:toolchain_type"] returns weirdly null which causes the referenced before assignment error when hasattr tries to use toolchain_info. Not at all clear on why this happens, it sounds potentially internal to bazel.

This works around the issue by skipping that code path entirely and always falling back

diff --git rust/private/utils.bzl rust/private/utils.bzl
index 06ed842..be8904e 100644
--- rust/private/utils.bzl
+++ rust/private/utils.bzl
@@ -14,7 +14,11 @@
 
 """Utility functions not specific to the rust toolchain."""
 
-load("@bazel_tools//tools/cpp:toolchain_utils.bzl", find_rules_cc_toolchain = "find_cpp_toolchain")
+def find_rules_cc_toolchain(ctx):
+    if hasattr(ctx.attr, "_cc_toolchain"):
+        return ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]
+    fail("In order to use find_cpp_toolchain, you must define the '_cc_toolchain' attribute on your rule or aspect.")
+
 
 def find_toolchain(ctx):
     """Finds the first rust toolchain that is configured.

@illicitonion
Copy link
Collaborator

I probably don't have time to dig much deeper into this at the moment, but definitely feels like a bug internal to bazel to me

@hlopko
Copy link
Member

hlopko commented Mar 18, 2021

One thing that we missed is that rust_toolchain doesn't declare

    toolchains = [
        "@bazel_tools//tools/cpp:toolchain_type",
    ],

But even with that the build still fails. I am starting to worry that toolchains cannot depend on other toolchains. @katre may help us there?

@katre
Copy link
Member

katre commented Mar 18, 2021

Let me take a look and see if I can reproduce this.

@katre
Copy link
Member

katre commented Mar 18, 2021

Using the setup from @iffyio (and a hello world for rust that I grabbed from somewhere), I can see the same problem. Even after adding the toolchain type (and the incompatible_use_toolchain_transition argument to rule) it's still happening.

Debugging into Bazel I can see that the toolchain context exists, and has no toolchains, which is very odd, so I'm going to debug further.

@katre
Copy link
Member

katre commented Mar 18, 2021

Ah ha, found the problem. In ConfiguredTargetFunction.computeUnloadedToolchainContexts, we remove all toolchains from the context to prevent a self-loop. What is actually needed is to remove only the current configured target, which conveniently we know about and can do.

I'll work up a patch for Bazel and send it shortly. I'll also upload a PR to add the proper toolchain declaration to rust_toolchain. Technically, it's not needed: when loaded as a toolchain, all rust_toolchain targets use the parent's toolchain context, not their own, but it's better to be correct. I will take a look at a way to fix this, as well.

Filed bazelbuild/bazel#13243 to track this on Bazel's side.

illicitonion pushed a commit that referenced this issue Mar 18, 2021
Part of the work on #635, but not sufficient to fix it.
@katre
Copy link
Member

katre commented Mar 23, 2021

I've fixed bazelbuild/bazel#13243 with Bazel at head. My repro now works, please test yourselves and let me know if there are still problems.

illicitonion added a commit to illicitonion/rules_rust that referenced this issue Mar 25, 2021
illicitonion added a commit to illicitonion/rules_rust that referenced this issue Mar 25, 2021
@sayrer
Copy link
Contributor

sayrer commented Mar 27, 2021

I hit this trying to make rules_rust use the correct cc_toolchain, and I would say the error local variable 'cc_toolchain' is referenced before assignment. is misleading. Maybe its assignment triggered something like an exception or an undefined value, but it was assigned in a lexical sense.

I assigned this variable to 0, and got an error I would expect for an incorrect type. Whatever find_cpp_toolchain is/was doing seems to result in a lexical error that is difficult to interpret.

@katre
Copy link
Member

katre commented Apr 5, 2021

@sayrer That's a valid point, can you file a separate issue in bazelbuild/bazel and I'll try and route it to the correct people?

@XAMPPRocky
Copy link

Hey, wanted to note that this was fixed, but with e7b1e5a it regressed and now fails with the following error.

Traceback (most recent call last):
        File "/private/var/tmp/_bazel_ep/04a4b9ac557e5ef6522180eaf2121d09/external/rules_rust/rust/private/rustdoc.bzl", line 180, column 36, in _rust_doc_impl
                action = rustdoc_compile_action(
        File "/private/var/tmp/_bazel_ep/04a4b9ac557e5ef6522180eaf2121d09/external/rules_rust/rust/private/rustdoc.bzl", line 72, column 60, in rustdoc_compile_action
                cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
        File "/private/var/tmp/_bazel_ep/04a4b9ac557e5ef6522180eaf2121d09/external/rules_rust/rust/private/utils.bzl", line 40, column 43, in find_cc_toolchain
                cc_toolchain = find_rules_cc_toolchain(ctx)
        File "/private/var/tmp/_bazel_ep/04a4b9ac557e5ef6522180eaf2121d09/external/bazel_tools/tools/cpp/toolchain_utils.bzl", line 41, column 13, in find_cpp_toolchain
                fail("In order to use find_cpp_toolchain, you must include the '@bazel_tools//tools/cpp:toolchain_type' in the toolchains argument to your rule.")
Error in fail: In order to use find_cpp_toolchain, you must include the '@bazel_tools//tools/cpp:toolchain_type' in the toolchains argument to your rule.

@UebelAndre
Copy link
Collaborator

Oh no! What are you redoing to repro this? And what Bazel version are you using?

@XAMPPRocky
Copy link

And what Bazel version are you using?

4.1.0, but I also tried with 4.2.1.

This is what the rules look like, but I can try and make a fuller repro if you need. I should clarify that it seems like it only happens with rust_doc. rust_library and rust_doc_test for example, don't have this issue.

rust_library(
    name = "server",
    srcs = glob(["**/*.rs"]),
    edition = "2021",
    proc_macro_deps = [
        "//crates:async_trait",
    ],
    deps = [
        "//crates:cfg_if",
        "//crates:clap",
        "//crates:dashmap",
        "//crates:eyre",
        "//crates:futures",
        "//crates:http",
        "//crates:hyper",
        "//crates:prometheus",
        "//crates:tokio",
        "//crates:tower",
        "//crates:tower_http",
        "//crates:tracing",
        "//crates:tracing_subscriber",
        "//crates:tryhard",
    ],
)

rust_doc(
    name = "doc",
    crate = ":server",
)

@UebelAndre
Copy link
Collaborator

This is what the rules look like, but I can try and make a fuller repro if you need. I should clarify that it seems like it only happens with rust_doc. rust_library and rust_doc_test for example, don't have this issue.

@XAMPPRocky A fuller example would be helpful. But can you see if #1021 would fix the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants