Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2354,6 +2354,11 @@ impl<'a> RsTypeKind<'a> {
quote! { ::alloc::boxed::Box<#callable_spelling> }
}
BridgeRsTypeKind::C9Co { has_reference_param, result_type, lifetime, .. } => {
let co_crate = db
.ir()
.crate_name(&BazelLabel::from("//util/c9:co"))
.map(|ident| quote! { ::#ident })
.unwrap_or_else(|| quote! { ::co });
let result_type_tokens = if result_type.is_void() {
quote! { () }
} else {
Expand All @@ -2362,9 +2367,9 @@ impl<'a> RsTypeKind<'a> {
// When there are reference parameters, the coroutine must finish before they are
// invalidated (http://shortn/_XPma06AwZh).
match (lifetime, has_reference_param) {
(Some(lt), _) => quote! { ::co::Co<#lt, #result_type_tokens> },
(_, false) => quote! { ::co::Co<'static, #result_type_tokens> },
(_, true) => quote! { ::co::Co<'_, #result_type_tokens> },
(Some(lt), _) => quote! { #co_crate::Co<#lt, #result_type_tokens> },
(_, false) => quote! { #co_crate::Co<'static, #result_type_tokens> },
(_, true) => quote! { #co_crate::Co<'_, #result_type_tokens> },
}
}
}
Expand Down
14 changes: 10 additions & 4 deletions rs_bindings_from_cc/generate_bindings/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1198,13 +1198,19 @@ fn crubit_abi_type<'a>(
generate_dyn_callable::callable_crubit_abi_type(db, &callable)
}
BridgeRsTypeKind::C9Co { result_type, .. } => {
let co_crate = db
.ir()
.crate_name(&BazelLabel::from("//util/c9:co"))
.map(|ident| quote! { ::#ident })
.unwrap_or_else(|| quote! { ::co });

let result_type_tokens = if result_type.is_void() {
quote! { () }
} else {
result_type.all_static_lifetimes(false).to_token_stream(db)
};
let rust_type_tokens = quote! {
::co::internal_crubit::CoCrubitAbi<#result_type_tokens>
#co_crate::internal_crubit::CoCrubitAbi<#result_type_tokens>
};

let result_type_crubit_abi_type = if result_type.is_void() {
Expand All @@ -1215,7 +1221,7 @@ fn crubit_abi_type<'a>(

let rust_expr_tokens = {
let consume_result_fn = match &result_type_crubit_abi_type {
None => quote! { ::co::internal_crubit::consume_void_result },
None => quote! { #co_crate::internal_crubit::consume_void_result },
Some(result_type_crubit_abi_type) => {
let result_type_crubit_abi_type_tokens =
CrubitAbiTypeToRustTokens(result_type_crubit_abi_type);
Expand All @@ -1229,7 +1235,7 @@ fn crubit_abi_type<'a>(
// and a pointer to the buffer, and then decode the stack buffer into
// the native Rust value.
quote! {
|consume_result_into_buffer: ::co::internal_crubit::ConsumeResultIntoBufferFn,
|consume_result_into_buffer: #co_crate::internal_crubit::ConsumeResultIntoBufferFn,
context: *mut ::core::ffi::c_void| -> #result_type_tokens {
::bridge_rust::unstable_return!(@
// Crubit ABI details
Expand All @@ -1251,7 +1257,7 @@ fn crubit_abi_type<'a>(
}
};
quote! {
::co::internal_crubit::CoCrubitAbi::new(#consume_result_fn)
#co_crate::internal_crubit::CoCrubitAbi::new(#consume_result_fn)
}
};

Expand Down
90 changes: 90 additions & 0 deletions rs_bindings_from_cc/test/bazel/co_reproducer/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Part of the Crubit project, under the Apache License v2.0 with LLVM
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

# Regression test for c9::Co crate name hardcoding.
#
# Historically, the Crubit generator hardcoded the name of the `c9::Co`
# bindings crate as `::co`. This caused issues when:
# 1. Crate renaming was enabled (which mangles the crate name to its label-encoded version).
# 2. A user-defined Rust library also named `co` was present in the dependency
# graph (e.g. via `additional_rust_srcs`), causing `::co` to resolve to the
# wrong crate.
#
# This test verifies that we can compile bindings that use `c9::Co` even when
# a conflicting user-defined `co` crate is present in the dependencies,
# provided that crate renaming is enabled.

load("@bazel_tools//tools/build_defs/build_test:build_test.bzl", "build_test")
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_rust//rust:defs.bzl", "rust_library")
load(
"//rs_bindings_from_cc/bazel_support:additional_rust_srcs_for_crubit_bindings_aspect_hint.bzl",
"additional_rust_srcs_for_crubit_bindings",
)

package(
default_testonly = 1,
)

config_setting(
name = "use_label_encoded_names_for_deps_enabled",
flag_values = {
"//common/bazel_support:use_label_encoded_names_for_deps": "True",
},
)

_compatible_with_flag = select({
":use_label_encoded_names_for_deps_enabled": [],
"//conditions:default": ["//third_party/bazel_platforms:incompatible"],
})

_tags = [
"notap",
"noguitar",
"manual",
"nobuilder",
]

rust_library(
name = "co",
srcs = ["rust_co.rs"],
tags = _tags,
)

additional_rust_srcs_for_crubit_bindings(
name = "extra_srcs",
srcs = ["extra.rs"],
deps = [":co"],
)

cc_library(
name = "co_usage_cc",
hdrs = ["co_usage.h"],
aspect_hints = [
":extra_srcs",
"//features:supported",
],
tags = _tags,
target_compatible_with = _compatible_with_flag,
deps = [
"//util/c9:co",
],
)

rust_library(
name = "co_usage_rust",
srcs = ["co_usage.rs"],
cc_deps = [":co_usage_cc"],
tags = _tags,
target_compatible_with = _compatible_with_flag,
)

build_test(
name = "build_test",
tags = _tags,
target_compatible_with = _compatible_with_flag,
targets = [
":co_usage_rust",
],
)
12 changes: 12 additions & 0 deletions rs_bindings_from_cc/test/bazel/co_reproducer/co_usage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_BAZEL_CO_REPRODUCER_CO_USAGE_H_
#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_BAZEL_CO_REPRODUCER_CO_USAGE_H_

#include "util/c9/co.h"

c9::Co<int> func_returning_co();

#endif // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_BAZEL_CO_REPRODUCER_CO_USAGE_H_
5 changes: 5 additions & 0 deletions rs_bindings_from_cc/test/bazel/co_reproducer/co_usage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Placeholder file to satisfy rust_library
9 changes: 9 additions & 0 deletions rs_bindings_from_cc/test/bazel/co_reproducer/extra.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// This imports the placeholder co crate, causing a collision if the generator
// uses the hardcoded `::co` name.
extern crate co;

pub use co::Placeholder;
6 changes: 6 additions & 0 deletions rs_bindings_from_cc/test/bazel/co_reproducer/rust_co.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Placeholder co library to cause collision
pub struct Placeholder;
Loading