-
Notifications
You must be signed in to change notification settings - Fork 406
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
Fixed inability to use crate
attribute in wrapper rules with proc-macro targets.
#807
Conversation
2521ee8
to
678ab71
Compare
If it's fine with you, I'll not review this PR until Organized examples #803 is merged, the diff is huge right now. Could you please ping me here once it happens? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! Now that I'm thinking about it I might have hit this bug in the past, I just didn't know it was in the rules.
@@ -27,6 +27,10 @@ CrateInfo = provider( | |||
"root": "File: The source File entrypoint to this crate, eg. lib.rs", | |||
"rustc_env": "Dict[String, String]: Additional `\"key\": \"value\"` environment variables to set for rustc.", | |||
"srcs": "depset[File]: All source Files that are part of the crate.", | |||
"transitive_type": ( | |||
"str, optional: The original crate type for targets generated using a previously defined " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems this is the only optional field in this provider, and you seem to be adding it everywhere explicitly. Are you trying to make the code backwards compatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never introduced an optional parameter on a provider before so I had assumed I needed to plug it in everywhere. But Assuming I don't set it, does it default to None
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By leaving this blank, I run into
Traceback (most recent call last):
File "/Users/user/Code/rules_rust/rust/private/rust.bzl", line 182, column 32, in _rust_library_impl
return _rust_library_common(ctx, "rlib")
File "/Users/user/Code/rules_rust/rust/private/rust.bzl", line 253, column 32, in _rust_library_common
return rustc_compile_action(
File "/Users/user/Code/rules_rust/rust/private/rustc.bzl", line 533, column 36, in rustc_compile_action
args, env = construct_arguments(
File "/Users/user/Code/rules_rust/rust/private/rustc.bzl", line 462, column 71, in construct_arguments
is_type_proc_macro = crate_info.type == "proc-macro" or crate_info.wrapped_crate_type == "proc-macro"
Error: 'CrateInfo' value has no field or method 'wrapped_crate_type'
Available attributes: aliases, deps, edition, is_test, name, output, proc_macro_deps, root, rustc_env, srcs, type
Error: 'CrateInfo' value has no field or method 'wrapped_crate_type'
Available attributes: aliases, deps, edition, is_test, name, output, proc_macro_deps, root, rustc_env, srcs, type
It seems the field needs to be explicitly created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is very unfortunate. This makes this a backwards incompatible change (and the field is not optional so please fix the documentation).
This could have been prevented if we had rust_common.create_crate_info
function. I propose following:
- let's create
rust_common.create_crate_info
function. I'm happy to do it if you want. - let's update the docs of
rust_common.crate_info
and say this is not supposed to be used for construction, only for accessing the provider (unfortunately provider constructor is used as both constructor and type declaration that we use in rule definitions or when getting providers from target). - let's call this function in all the places in this repo where we currently call
rust_common.crate_info(...)
. - let's recommend people migrating for this PR to use
create_crate_info
instead ofcrate_info
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was #818 what you were thinking here?
rust_test::crate
with proc-macro targets.crate
attribute in wrapper rules with proc-macro targets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, only minor comments and should be good to go.
edition = edition, | ||
) | ||
|
||
rust_test( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move the integration test to //test/proc_macro
. Let's only keep unit tests in //test/unit/...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't they all just considered tests and go in the root of test? It feels like we're gonna exponentially gain nearly identical rust files if we need to split everything like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have order of magnitude more unit tests than integration tests. If they are duplicated, delete the integration test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the thing that bothers me is that targets and unit tests are declare together. I'd like to think of unit tests as assertions on existing targets but that I could organize it such that I have a bunch of targets in test/*
and then potentially only define unit test targets (which wouldn't be rust_*
targets) in test/unit/**
. But maybe that doesn't make sense (I struggle greatly with starlark unittests and really dislike them 😅)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. But I think the coupling (decoupling) here will become unmaintainable if we continue with this pattern. I see no reason why there's a need for the test/unit
directory. I would say each test/*
directory defines integration tests as the base targets that are used for the relevant unit tests in the same package or a unit
subpackage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I'd like to go the other way. I'm bothered that the test setup and assertions are too far away from each other (and test setup is below assertions in the file, that is also bad). Ideally I'd like to write a test like:
def test_that_yolo_is_foo(ctx):
ctx.package("//foo", """
rust_library(name = "asdf", srcs = ["..."])
rust_test(name="asdf_test", crate=":asdf")
"""
argv = ctx.target("//foo:asdf_test").actions[0].argv
assert_list_contains_adjacent_elements("--extern", "yolo")
And even more ideally this test would not execute any actions.
It's incorrect to totally disregard the crate type of a target passed to
rust_test::crate
since that info is needed to determine some flags at compile time. There may be more but this was the one I found when trying to flip theexamples/proc_macro
example to use edition2018
for the default example. I was unable to build with the following issue:By keeping track of the original crate type, we can appropriately include
--extern proc_macro
in the linker flags for these kinds of test targets. I was able to confirm that Cargo is setting this extern flag for the same test target by copying the code from the example into a cargo workspace and adding the following diffThe workspace structure was:
and the results of
cargo test --verbose
were:Requires: