Skip to content

Commit b2fbb0f

Browse files
ssbrcopybara-github
authored andcommitted
Prevent compilation errors with CtorNew when the arguments have lifetimes.
This doesn't actually give the functions bindings -- that's harder and requires multiple releases. But it stops compilation from outright failing, by disabling bindings. PiperOrigin-RevId: 896733406
1 parent 3efb3e7 commit b2fbb0f

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

rs_bindings_from_cc/generate_bindings/generate_function.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,11 +785,18 @@ fn api_func_shape_for_constructor(
785785

786786
if !record.is_unpin() {
787787
let func_name = make_rs_ident("ctor_new");
788+
788789
let [_this, params @ ..] = param_types else {
789-
panic!("Missing `__this` parameter in a constructor: {:?}", func)
790+
errors.add(anyhow!(
791+
"This is a bug in Crubit. Could not find `__this` parameter in a constructor: {:?}",
792+
func
793+
));
794+
return None;
790795
};
791796
// Elided lifetimes won't "just work" when split across the `Ctor` trait impl, so we replace
792797
// them with a single named lifetime.
798+
// TODO(b/331685208): instead, return `impl Ctor` from `ctor_new`. It's infeasible (and
799+
// expensive) to deep-copy the RsTypeKind and mutate all sublifetimes.
793800
for param in &mut params[..] {
794801
if let RsTypeKind::Reference { lifetime, .. }
795802
| RsTypeKind::RvalueReference { lifetime, .. } = param
@@ -799,6 +806,14 @@ fn api_func_shape_for_constructor(
799806
}
800807
}
801808
}
809+
// Check if there's still any elided lifetimes after the minimal transform above:
810+
for param in &params[..] {
811+
for lifetime in param.lifetimes() {
812+
if lifetime.is_elided() {
813+
errors.add(anyhow!("b/331685208: Found a lifetime in a function parameter type {}, which prevents CtorNew bindings", param.display(db)));
814+
}
815+
}
816+
}
802817
let impl_kind = ImplKind::Trait {
803818
record: record.clone(),
804819
trait_name: TraitName::CtorNew(params.iter().cloned().collect()),
@@ -814,7 +829,13 @@ fn api_func_shape_for_constructor(
814829
return Some((func_name, impl_kind));
815830
}
816831
match func.params.len() {
817-
0 => panic!("Missing `__this` parameter in a constructor: {:?}", func),
832+
0 => {
833+
errors.add(anyhow!(
834+
"This is a bug in Crubit. Could not find `__this` parameter in a constructor: {:?}",
835+
func
836+
));
837+
None
838+
}
818839
1 => {
819840
let func_name = make_rs_ident("default");
820841
let impl_kind = ImplKind::new_trait(

rs_bindings_from_cc/test/struct/constructors/BUILD

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ crubit_test_cc_library(
1717
aspect_hints = ["//features:experimental"],
1818
)
1919

20+
crubit_test_cc_library(
21+
name = "span_constructors",
22+
hdrs = ["span_constructors.h"],
23+
# operator lifetime inference and ctor
24+
aspect_hints = ["//features:experimental"],
25+
deps = ["@abseil-cpp//absl/types:span"],
26+
)
27+
2028
golden_test(
2129
name = "constructors_golden_test",
2230
basename = "constructors",
@@ -30,6 +38,7 @@ crubit_rust_test(
3038
srcs = ["test.rs"],
3139
cc_deps = [
3240
":constructors",
41+
":span_constructors",
3342
],
3443
deps = [
3544
"//support:ctor",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Part of the Crubit project, under the Apache License v2.0 with LLVM
2+
// Exceptions. See /LICENSE for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_CONSTRUCTORS_SPAN_CONSTRUCTORS_H_
6+
#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_CONSTRUCTORS_SPAN_CONSTRUCTORS_H_
7+
8+
#include "absl/types/span.h"
9+
10+
struct MyStruct {
11+
explicit MyStruct(absl::Span<const int> values) {}
12+
~MyStruct() {
13+
// Nontrivial so that the constructor must return an `impl Ctor`.
14+
}
15+
};
16+
17+
#endif // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_CONSTRUCTORS_SPAN_CONSTRUCTORS_H_

rs_bindings_from_cc/test/struct/constructors/test.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,12 @@ fn test_nontrivial_struct() {
131131
let s_clone = emplace!(ctor::copy(&*s));
132132
assert_eq!(s_clone.int_field, 123);
133133
}
134+
135+
// Ideally, this test would work.
136+
//
137+
// // TODO(b/331685208): make this test compile and pass.
138+
//
139+
// #[gest]
140+
// fn test_span_constructors() {
141+
// let _ = span_constructors::MyStruct::new(...);
142+
// }

0 commit comments

Comments
 (0)