Thread Crubit feature flags into the IR and `src_code_gen.rs`.
This does not yet use it for anything except to display which features are enabled, as a comment at the top of the file.
PiperOrigin-RevId: 513385210
diff --git a/rs_bindings_from_cc/BUILD b/rs_bindings_from_cc/BUILD
index 73a956e..51e1db4 100644
--- a/rs_bindings_from_cc/BUILD
+++ b/rs_bindings_from_cc/BUILD
@@ -169,6 +169,7 @@
":cc_ir",
"//common:status_macros",
"@absl//absl/container:flat_hash_map",
+ "@absl//absl/container:flat_hash_set",
"@absl//absl/flags:flag",
"@absl//absl/log",
"@absl//absl/status:statusor",
@@ -302,6 +303,7 @@
srcs = ["ir.rs"],
deps = [
"//common:arc_anyhow",
+ "@crate_index//:flagset",
"@crate_index//:itertools",
"@crate_index//:once_cell",
"@crate_index//:proc-macro2",
@@ -338,6 +340,7 @@
":cc_ir",
":frontend_action",
"@absl//absl/container:flat_hash_map",
+ "@absl//absl/container:flat_hash_set",
"@absl//absl/log:check",
"@absl//absl/status",
"@absl//absl/status:statusor",
@@ -402,6 +405,7 @@
"//common:code_gen_utils",
"//common:ffi_types",
"//common:token_stream_printer",
+ "@crate_index//:flagset",
"@crate_index//:itertools",
"@crate_index//:once_cell",
"@crate_index//:proc-macro2",
diff --git a/rs_bindings_from_cc/cmdline.cc b/rs_bindings_from_cc/cmdline.cc
index 5b89bf3..4305344 100644
--- a/rs_bindings_from_cc/cmdline.cc
+++ b/rs_bindings_from_cc/cmdline.cc
@@ -87,13 +87,15 @@
struct TargetArgs {
std::string target;
std::vector<std::string> headers;
+ std::vector<std::string> features;
};
bool fromJSON(const llvm::json::Value& json, TargetArgs& out,
llvm::json::Path path) {
llvm::json::ObjectMapper mapper(json, path);
return mapper && mapper.map("t", out.target) &&
- mapper.mapOptional("h", out.headers);
+ mapper.mapOptional("h", out.headers) &&
+ mapper.mapOptional("f", out.features);
}
} // namespace
@@ -216,6 +218,14 @@
}
}
}
+ for (const std::string& feature : it.features) {
+ if (feature.empty()) {
+ return absl::InvalidArgumentError(
+ "Expected `f` (feature) fields of `--target_args` to be an "
+ "array of non-empty strings");
+ }
+ cmdline.target_to_features_[BazelLabel(target)].insert(feature);
+ }
}
for (const HeaderName& public_header : cmdline.public_headers_) {
diff --git a/rs_bindings_from_cc/cmdline.h b/rs_bindings_from_cc/cmdline.h
index 6d557dc..8eb3b7e 100644
--- a/rs_bindings_from_cc/cmdline.h
+++ b/rs_bindings_from_cc/cmdline.h
@@ -10,6 +10,7 @@
#include <vector>
#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "rs_bindings_from_cc/bazel_types.h"
@@ -82,6 +83,11 @@
return headers_to_targets_;
}
+ const absl::flat_hash_map<BazelLabel, absl::flat_hash_set<std::string>>&
+ target_to_features() const {
+ return target_to_features_;
+ }
+
private:
Cmdline();
@@ -117,6 +123,8 @@
std::string instantiations_out_;
std::string namespaces_out_;
+ absl::flat_hash_map<BazelLabel, absl::flat_hash_set<std::string>>
+ target_to_features_;
};
} // namespace crubit
diff --git a/rs_bindings_from_cc/cmdline_test.cc b/rs_bindings_from_cc/cmdline_test.cc
index 61063fd..97fef2b 100644
--- a/rs_bindings_from_cc/cmdline_test.cc
+++ b/rs_bindings_from_cc/cmdline_test.cc
@@ -212,6 +212,28 @@
Pair(HeaderName("d.h"), BazelLabel("//:target2"))));
}
+TEST(CmdlineTest, TargetArgsIntInsteadOfFeaturesArray) {
+ ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "f": 123}])"),
+ StatusIs(absl::StatusCode::kInvalidArgument,
+ AllOf(HasSubstr("--target_args"), HasSubstr(".f"),
+ HasSubstr("array"))));
+}
+
+TEST(CmdlineTest, TargetArgsEmptyFeature) {
+ ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "f": ["", "h2"]}])"),
+ StatusIs(absl::StatusCode::kInvalidArgument,
+ AllOf(HasSubstr("--target_args"), HasSubstr("`f`"),
+ HasSubstr("empty string"))));
+}
+
+TEST(CmdlineTest, TargetArgsIntInsteadOfFeature) {
+ ASSERT_THAT(
+ TestCmdline({"h1"}, R"([{"t": "t1", "f": [123, "experimental"]}])"),
+ StatusIs(absl::StatusCode::kInvalidArgument,
+ AllOf(HasSubstr("--target_args"), HasSubstr(".f"),
+ HasSubstr("string"))));
+}
+
TEST(CmdlineTest, InstantiationsOutEmpty) {
constexpr absl::string_view kTargetsAndHeaders = R"([
{"t": "//:target1", "h": ["a.h", "b.h"]}
diff --git a/rs_bindings_from_cc/generate_bindings_and_metadata.cc b/rs_bindings_from_cc/generate_bindings_and_metadata.cc
index 3a4ca04..2e3da3e 100644
--- a/rs_bindings_from_cc/generate_bindings_and_metadata.cc
+++ b/rs_bindings_from_cc/generate_bindings_and_metadata.cc
@@ -72,7 +72,8 @@
/* extra_source_code_for_testing= */ "", cmdline.current_target(),
cmdline.public_headers(), virtual_headers_contents_for_testing,
cmdline.headers_to_targets(), cmdline.extra_rs_srcs(),
- clang_args_view, requested_instantiations));
+ clang_args_view, requested_instantiations,
+ cmdline.target_to_features()));
if (!cmdline.instantiations_out().empty()) {
ir.crate_root_path = "__cc_template_instantiations_rs_api";
diff --git a/rs_bindings_from_cc/ir.cc b/rs_bindings_from_cc/ir.cc
index a2f7342..161089a 100644
--- a/rs_bindings_from_cc/ir.cc
+++ b/rs_bindings_from_cc/ir.cc
@@ -542,11 +542,21 @@
top_level_ids.push_back(id.value());
}
+ llvm::json::Object features_json;
+ for (const auto& [target, features] : crubit_features) {
+ std::vector<llvm::json::Value> feature_array;
+ for (const std::string& feature : features) {
+ feature_array.push_back(feature);
+ }
+ features_json[target.value()] = std::move(feature_array);
+ }
+
llvm::json::Object result{
{"public_headers", public_headers},
{"current_target", current_target},
{"items", std::move(json_items)},
{"top_level_item_ids", std::move(top_level_ids)},
+ {"crubit_features", std::move(features_json)},
};
if (!crate_root_path.empty()) {
result["crate_root_path"] = crate_root_path;
diff --git a/rs_bindings_from_cc/ir.h b/rs_bindings_from_cc/ir.h
index 9a5f0a6..ed4e12d 100644
--- a/rs_bindings_from_cc/ir.h
+++ b/rs_bindings_from_cc/ir.h
@@ -788,6 +788,9 @@
// TODO(hlopko): Replace empty strings with std::optional<std::string>
// throughout the codebase
std::string crate_root_path;
+
+ absl::flat_hash_map<BazelLabel, absl::flat_hash_set<std::string>>
+ crubit_features;
};
inline std::string IrToJson(const IR& ir) {
diff --git a/rs_bindings_from_cc/ir.rs b/rs_bindings_from_cc/ir.rs
index a6fd468..859b644 100644
--- a/rs_bindings_from_cc/ir.rs
+++ b/rs_bindings_from_cc/ir.rs
@@ -26,14 +26,28 @@
/// Create a testing `IR` instance from given parts. This function does not use
/// any mock values.
-pub fn make_ir_from_parts(
+pub fn make_ir_from_parts<CrubitFeatures>(
items: Vec<Item>,
public_headers: Vec<HeaderName>,
current_target: BazelLabel,
top_level_item_ids: Vec<ItemId>,
crate_root_path: Option<Rc<str>>,
-) -> Result<IR> {
- make_ir(FlatIR { public_headers, current_target, items, top_level_item_ids, crate_root_path })
+ crubit_features: HashMap<BazelLabel, CrubitFeatures>,
+) -> Result<IR>
+where
+ CrubitFeatures: Into<flagset::FlagSet<CrubitFeature>>,
+{
+ make_ir(FlatIR {
+ public_headers,
+ current_target,
+ items,
+ top_level_item_ids,
+ crate_root_path,
+ crubit_features: crubit_features
+ .into_iter()
+ .map(|(label, features)| (label, CrubitFeaturesIR(features.into())))
+ .collect(),
+ })
}
fn make_ir(flat_ir: FlatIR) -> Result<IR> {
@@ -683,7 +697,52 @@
}
}
-#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize)]
+flagset::flags! {
+ pub enum CrubitFeature : u8 {
+ Supported,
+ /// Experimental is never *set* without also setting Supported, but we allow it to be
+ /// *required* without also requiring Supported, so that error messages can be more direct.
+ Experimental,
+ }
+}
+
+impl CrubitFeature {
+ /// The name of this feature.
+ pub fn short_name(&self) -> &'static str {
+ match self {
+ Self::Supported => "supported",
+ Self::Experimental => "experimental",
+ }
+ }
+}
+
+/// A newtype around a flagset of features, so that it can be deserialized from
+/// an array of strings instead of an integer.
+#[derive(Debug, Default, PartialEq, Eq, Clone)]
+struct CrubitFeaturesIR(pub(crate) flagset::FlagSet<CrubitFeature>);
+
+impl<'de> serde::Deserialize<'de> for CrubitFeaturesIR {
+ fn deserialize<D>(deserializer: D) -> Result<CrubitFeaturesIR, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let mut features = flagset::FlagSet::<CrubitFeature>::default();
+ for feature in <Vec<String> as serde::Deserialize<'de>>::deserialize(deserializer)? {
+ features |= match &*feature {
+ "experimental" => CrubitFeature::Experimental,
+ "supported" => CrubitFeature::Supported,
+ other => {
+ return Err(<D::Error as serde::de::Error>::custom(format!(
+ "Unexpected Crubit feature: {other}"
+ )));
+ }
+ };
+ }
+ Ok(CrubitFeaturesIR(features))
+ }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Deserialize)]
#[serde(rename(deserialize = "IR"))]
struct FlatIR {
#[serde(default)]
@@ -695,6 +754,8 @@
top_level_item_ids: Vec<ItemId>,
#[serde(default)]
crate_root_path: Option<Rc<str>>,
+ #[serde(default)]
+ crubit_features: HashMap<BazelLabel, CrubitFeaturesIR>,
}
/// Struct providing the necessary information about the API of a C++ target to
@@ -793,13 +854,19 @@
self.flat_ir.items.get(idx).with_context(|| format!("Couldn't find an item at idx {}", idx))
}
- // Returns whether `target` is the current target.
+ /// Returns whether `target` is the current target.
pub fn is_current_target(&self, target: &BazelLabel) -> bool {
// TODO(hlopko): Make this be a pointer comparison, now it's comparing string
// values.
*target == *self.current_target()
}
+ /// Returns the Crubit features enabled for the given `target`.
+ #[must_use]
+ pub fn target_crubit_features(&self, target: &BazelLabel) -> flagset::FlagSet<CrubitFeature> {
+ self.flat_ir.crubit_features.get(target).cloned().unwrap_or_default().0
+ }
+
pub fn current_target(&self) -> &BazelLabel {
&self.flat_ir.current_target
}
@@ -896,6 +963,7 @@
top_level_item_ids: vec![],
items: vec![],
crate_root_path: None,
+ crubit_features: Default::default(),
};
assert_eq!(ir.flat_ir, expected);
}
diff --git a/rs_bindings_from_cc/ir_from_cc.cc b/rs_bindings_from_cc/ir_from_cc.cc
index 4fff0ac..2a45a07 100644
--- a/rs_bindings_from_cc/ir_from_cc.cc
+++ b/rs_bindings_from_cc/ir_from_cc.cc
@@ -39,7 +39,9 @@
absl::flat_hash_map<HeaderName, BazelLabel> headers_to_targets,
absl::Span<const std::string> extra_rs_srcs,
absl::Span<const absl::string_view> clang_args,
- absl::Span<const std::string> extra_instantiations) {
+ absl::Span<const std::string> extra_instantiations,
+ const absl::flat_hash_map<BazelLabel, absl::flat_hash_set<std::string>>&
+ crubit_features) {
// Caller should verify that the inputs are not empty.
CHECK(!extra_source_code_for_testing.empty() || !public_headers.empty() ||
!extra_instantiations.empty());
@@ -115,6 +117,7 @@
invocation.ir_.top_level_item_ids.push_back(id);
++i;
}
+ invocation.ir_.crubit_features = std::move(crubit_features);
return invocation.ir_;
}
diff --git a/rs_bindings_from_cc/ir_from_cc.h b/rs_bindings_from_cc/ir_from_cc.h
index 9dc7345..347d9b0 100644
--- a/rs_bindings_from_cc/ir_from_cc.h
+++ b/rs_bindings_from_cc/ir_from_cc.h
@@ -8,6 +8,7 @@
#include <string>
#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
@@ -41,9 +42,10 @@
// `virtual_headers_contents_for_testing` are not added automatically.
// * `clang_args`: additional command line arguments for Clang
// * `extra_rs_srcs`: A list of paths for additional rust files to include into
-// the crate. This is done via `#[path="..."] mod <...>; pub use <...>::*;`.
+// the crate. This is done via `#[path="..."] mod <...>; pub use <...>::*;`.
// * `extra_instantiations`: names of full C++ class template specializations
-// to instantiate and generate bindings from.
+// to instantiate and generate bindings from.
+// * `crubit_features`: The set of Crubit features to enable for each target.
//
absl::StatusOr<IR> IrFromCc(
absl::string_view extra_source_code_for_testing,
@@ -54,7 +56,9 @@
absl::flat_hash_map<HeaderName, BazelLabel> headers_to_targets = {},
absl::Span<const std::string> extra_rs_srcs = {},
absl::Span<const absl::string_view> clang_args = {},
- absl::Span<const std::string> extra_instantiations = {});
+ absl::Span<const std::string> extra_instantiations = {},
+ const absl::flat_hash_map<BazelLabel, absl::flat_hash_set<std::string>>&
+ crubit_features = {});
} // namespace crubit
diff --git a/rs_bindings_from_cc/ir_testing.rs b/rs_bindings_from_cc/ir_testing.rs
index c2cb35b..1cfe5d7 100644
--- a/rs_bindings_from_cc/ir_testing.rs
+++ b/rs_bindings_from_cc/ir_testing.rs
@@ -35,12 +35,14 @@
/// Create a testing `IR` instance from given items, using mock values for other
/// fields.
pub fn make_ir_from_items(items: impl IntoIterator<Item = Item>) -> Result<IR> {
+ let target: ir::BazelLabel = TESTING_TARGET.into();
make_ir_from_parts(
items.into_iter().collect_vec(),
/* public_headers= */ vec![],
- /* current_target= */ TESTING_TARGET.into(),
+ /* current_target= */ target.clone(),
/* top_level_item_ids= */ vec![],
/* crate_root_path= */ None,
+ /* crubit_features= */ [(target, ir::CrubitFeature::Experimental)].into()
)
}
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 55dca09..ebe975d 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -191,9 +191,24 @@
//
// TODO(b/255784681): Consider including cmdline arguments.
let target = &ir.current_target().0;
+
+ let crubit_features = {
+ let mut crubit_features: Vec<&str> = ir
+ .target_crubit_features(ir.current_target())
+ .into_iter()
+ .map(|feature| feature.short_name())
+ .collect();
+ crubit_features.sort();
+ if crubit_features.is_empty() {
+ "<none>".to_string()
+ } else {
+ crubit_features.join(", ")
+ }
+ };
format!(
"// Automatically @generated Rust bindings for the following C++ target:\n\
- // {target}\n"
+ // {target}\n\
+ // Features: {crubit_features}\n"
)
};
// TODO(lukasza): Try to remove `#![rustfmt:skip]` - in theory it shouldn't
diff --git a/rs_bindings_from_cc/test/golden/BUILD b/rs_bindings_from_cc/test/golden/BUILD
index 3a80e06..345b00f 100644
--- a/rs_bindings_from_cc/test/golden/BUILD
+++ b/rs_bindings_from_cc/test/golden/BUILD
@@ -44,6 +44,7 @@
[cc_library(
name = name + "_cc",
hdrs = [name + ".h"],
+ aspect_hints = ["//third_party/crubit:experimental"],
copts = ["-Wno-google3-inline-namespace"],
deps = [
((d + "_cc") if d in TESTS else d)
diff --git a/rs_bindings_from_cc/test/golden/bitfields_rs_api.rs b/rs_bindings_from_cc/test/golden/bitfields_rs_api.rs
index 87dead5..954e92d 100644
--- a/rs_bindings_from_cc/test/golden/bitfields_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/bitfields_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:bitfields_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/bitfields_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/bitfields_rs_api_impl.cc
index 7165dc5..dee8348 100644
--- a/rs_bindings_from_cc/test/golden/bitfields_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/bitfields_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:bitfields_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/clang_attrs_rs_api.rs b/rs_bindings_from_cc/test/golden/clang_attrs_rs_api.rs
index 60a624f..bbebdb2 100644
--- a/rs_bindings_from_cc/test/golden/clang_attrs_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/clang_attrs_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:clang_attrs_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/clang_attrs_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/clang_attrs_rs_api_impl.cc
index b509508..c9a9342 100644
--- a/rs_bindings_from_cc/test/golden/clang_attrs_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/clang_attrs_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:clang_attrs_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/comment_rs_api.rs b/rs_bindings_from_cc/test/golden/comment_rs_api.rs
index 5b08ebd..b6c3002 100644
--- a/rs_bindings_from_cc/test/golden/comment_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/comment_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:comment_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/comment_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/comment_rs_api_impl.cc
index 3b44348..ea6f18a 100644
--- a/rs_bindings_from_cc/test/golden/comment_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/comment_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:comment_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/doc_comment_rs_api.rs b/rs_bindings_from_cc/test/golden/doc_comment_rs_api.rs
index beb2148..4045942 100644
--- a/rs_bindings_from_cc/test/golden/doc_comment_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/doc_comment_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:doc_comment_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/doc_comment_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/doc_comment_rs_api_impl.cc
index fe80667..d07ec2e 100644
--- a/rs_bindings_from_cc/test/golden/doc_comment_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/doc_comment_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:doc_comment_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/enums_rs_api.rs b/rs_bindings_from_cc/test/golden/enums_rs_api.rs
index fb0f89a..ca12000 100644
--- a/rs_bindings_from_cc/test/golden/enums_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/enums_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:enums_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/enums_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/enums_rs_api_impl.cc
index da5308c..cc3fe57 100644
--- a/rs_bindings_from_cc/test/golden/enums_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/enums_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:enums_cc
+// Features: experimental, supported
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api.rs b/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api.rs
index 0b92b58..0bb4e43 100644
--- a/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:escaping_keywords_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api_impl.cc
index 5e5f9da..faae6af 100644
--- a/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/escaping_keywords_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:escaping_keywords_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/friend_functions_rs_api.rs b/rs_bindings_from_cc/test/golden/friend_functions_rs_api.rs
index 1d9a6d0..20101a1 100644
--- a/rs_bindings_from_cc/test/golden/friend_functions_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/friend_functions_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:friend_functions_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/friend_functions_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/friend_functions_rs_api_impl.cc
index baee514..e3d1a5a 100644
--- a/rs_bindings_from_cc/test/golden/friend_functions_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/friend_functions_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:friend_functions_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/includes_rs_api.rs b/rs_bindings_from_cc/test/golden/includes_rs_api.rs
index b36d324..9a47ca5 100644
--- a/rs_bindings_from_cc/test/golden/includes_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/includes_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:includes_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/includes_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/includes_rs_api_impl.cc
index 773f407..fce529a 100644
--- a/rs_bindings_from_cc/test/golden/includes_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/includes_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:includes_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs b/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs
index da29d0e..d385932 100644
--- a/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/inheritance_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:inheritance_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/inheritance_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/inheritance_rs_api_impl.cc
index 63c6784..807a8f5 100644
--- a/rs_bindings_from_cc/test/golden/inheritance_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/inheritance_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:inheritance_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/item_order_rs_api.rs b/rs_bindings_from_cc/test/golden/item_order_rs_api.rs
index c1bedce..1b65fae 100644
--- a/rs_bindings_from_cc/test/golden/item_order_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/item_order_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:item_order_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/item_order_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/item_order_rs_api_impl.cc
index 06fb8ee..d17bfca 100644
--- a/rs_bindings_from_cc/test/golden/item_order_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/item_order_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:item_order_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/lifetimes_rs_api.rs b/rs_bindings_from_cc/test/golden/lifetimes_rs_api.rs
index 1e4a5f0..c18a296 100644
--- a/rs_bindings_from_cc/test/golden/lifetimes_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/lifetimes_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:lifetimes_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/lifetimes_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/lifetimes_rs_api_impl.cc
index 892b44f..a9ab319 100644
--- a/rs_bindings_from_cc/test/golden/lifetimes_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/lifetimes_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:lifetimes_cc
+// Features: experimental, supported
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api.rs b/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api.rs
index 2cf3714..a44ac4d 100644
--- a/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:method_qualifiers_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls)]
diff --git a/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api_impl.cc
index a27db28..0dbf4e9 100644
--- a/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/method_qualifiers_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:method_qualifiers_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/namespace_rs_api.rs b/rs_bindings_from_cc/test/golden/namespace_rs_api.rs
index 8490e3e..24fcbc9 100644
--- a/rs_bindings_from_cc/test/golden/namespace_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/namespace_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:namespace_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/namespace_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/namespace_rs_api_impl.cc
index 8ff05e9..0fd038b 100644
--- a/rs_bindings_from_cc/test/golden/namespace_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/namespace_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:namespace_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs b/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs
index 96f2d80..7475538 100644
--- a/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:no_elided_lifetimes_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls)]
diff --git a/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api_impl.cc
index 7ca63d9..fdc5480 100644
--- a/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/no_elided_lifetimes_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:no_elided_lifetimes_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs b/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs
index 1fb6361..09d6ea1 100644
--- a/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/no_unique_address_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:no_unique_address_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/no_unique_address_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/no_unique_address_rs_api_impl.cc
index 3afab36..1ada90f 100644
--- a/rs_bindings_from_cc/test/golden/no_unique_address_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/no_unique_address_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:no_unique_address_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
index a3e07b1..631ba4a 100644
--- a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:nontrivial_type_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api_impl.cc
index b3d7556..8f35418 100644
--- a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:nontrivial_type_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/operators_rs_api.rs b/rs_bindings_from_cc/test/golden/operators_rs_api.rs
index 2b3561e..0aa0933 100644
--- a/rs_bindings_from_cc/test/golden/operators_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/operators_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:operators_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/operators_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/operators_rs_api_impl.cc
index 55074ab..0b2cdd9 100644
--- a/rs_bindings_from_cc/test/golden/operators_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/operators_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:operators_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/overloads_rs_api.rs b/rs_bindings_from_cc/test/golden/overloads_rs_api.rs
index b57543d..ac9debe 100644
--- a/rs_bindings_from_cc/test/golden/overloads_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/overloads_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:overloads_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc
index 2548a3f..90413ce 100644
--- a/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:overloads_cc
+// Features: experimental, supported
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs b/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs
index 36c41c3..96812a3 100644
--- a/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/polymorphic_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:polymorphic_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/polymorphic_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/polymorphic_rs_api_impl.cc
index e3b4a6a..83fc5a4 100644
--- a/rs_bindings_from_cc/test/golden/polymorphic_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/polymorphic_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:polymorphic_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/private_members_rs_api.rs b/rs_bindings_from_cc/test/golden/private_members_rs_api.rs
index 0310832..7807ace 100644
--- a/rs_bindings_from_cc/test/golden/private_members_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/private_members_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:private_members_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/private_members_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/private_members_rs_api_impl.cc
index 8decf98..99c8391 100644
--- a/rs_bindings_from_cc/test/golden/private_members_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/private_members_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:private_members_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/private_method_rs_api.rs b/rs_bindings_from_cc/test/golden/private_method_rs_api.rs
index 943a487..b06101f 100644
--- a/rs_bindings_from_cc/test/golden/private_method_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/private_method_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:private_method_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls)]
diff --git a/rs_bindings_from_cc/test/golden/private_method_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/private_method_rs_api_impl.cc
index 0201bf4..e94439c 100644
--- a/rs_bindings_from_cc/test/golden/private_method_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/private_method_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:private_method_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api.rs b/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api.rs
index d52db59..74a303a 100644
--- a/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:source_location_doc_comments_macro_def_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api_impl.cc
index 9d58a96..a79f03a 100644
--- a/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/source_location_doc_comments_macro_def_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:source_location_doc_comments_macro_def_cc
+// Features: experimental, supported
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api.rs b/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api.rs
index d2aca22..7285529 100644
--- a/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:source_location_doc_comments_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls)]
diff --git a/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api_impl.cc
index d668cc0..60d445c 100644
--- a/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/source_location_doc_comments_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:source_location_doc_comments_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/static_methods_rs_api.rs b/rs_bindings_from_cc/test/golden/static_methods_rs_api.rs
index 1b34904..725595d 100644
--- a/rs_bindings_from_cc/test/golden/static_methods_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/static_methods_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:static_methods_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/static_methods_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/static_methods_rs_api_impl.cc
index 96f63dd..d1a2cfc 100644
--- a/rs_bindings_from_cc/test/golden/static_methods_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/static_methods_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:static_methods_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/templates_rs_api.rs b/rs_bindings_from_cc/test/golden/templates_rs_api.rs
index 1cbe589..b807471 100644
--- a/rs_bindings_from_cc/test/golden/templates_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/templates_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:templates_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
index e50fb99..21b7939 100644
--- a/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:templates_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs
index 913332f..df8937c 100644
--- a/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:templates_source_order_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc
index 9501da4..506004d 100644
--- a/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:templates_source_order_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/trivial_type_rs_api.rs b/rs_bindings_from_cc/test/golden/trivial_type_rs_api.rs
index 3334fae..d814f8b 100644
--- a/rs_bindings_from_cc/test/golden/trivial_type_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/trivial_type_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:trivial_type_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/trivial_type_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/trivial_type_rs_api_impl.cc
index caf61c3..f384b17 100644
--- a/rs_bindings_from_cc/test/golden/trivial_type_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/trivial_type_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:trivial_type_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/typedefs_rs_api.rs b/rs_bindings_from_cc/test/golden/typedefs_rs_api.rs
index cfbd0d7..034f943 100644
--- a/rs_bindings_from_cc/test/golden/typedefs_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/typedefs_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:typedefs_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/typedefs_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/typedefs_rs_api_impl.cc
index b8a7ab6..90f56d8 100644
--- a/rs_bindings_from_cc/test/golden/typedefs_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/typedefs_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:typedefs_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/types_rs_api.rs b/rs_bindings_from_cc/test/golden/types_rs_api.rs
index 32d8003..862cb24 100644
--- a/rs_bindings_from_cc/test/golden/types_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/types_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:types_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc
index 4c64f0e..9df2718 100644
--- a/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:types_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/unions_rs_api.rs b/rs_bindings_from_cc/test/golden/unions_rs_api.rs
index 9d87bd1..01cec48 100644
--- a/rs_bindings_from_cc/test/golden/unions_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/unions_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:unions_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/unions_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/unions_rs_api_impl.cc
index 83342a6..81bfb26 100644
--- a/rs_bindings_from_cc/test/golden/unions_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/unions_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:unions_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs b/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs
index a2f66d6..6d4870b 100644
--- a/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:unsupported_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc
index c1cc0d3..6374ed7 100644
--- a/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:unsupported_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs b/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs
index e9c7f29..a53cd15 100644
--- a/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:user_of_base_class_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes, negative_impls, type_alias_impl_trait)]
diff --git a/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api_impl.cc
index 902f739..42d5acf 100644
--- a/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/user_of_base_class_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:user_of_base_class_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api.rs b/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api.rs
index 50f4b50..f66eff8 100644
--- a/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:user_of_imported_type_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api_impl.cc
index 8178b21..e25837c 100644
--- a/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/user_of_imported_type_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:user_of_imported_type_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>
diff --git a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs
index 9f531f8..1a33c57 100644
--- a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:user_of_unsupported_cc
+// Features: experimental, supported
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
diff --git a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api_impl.cc
index f11da7c..e214a87 100644
--- a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api_impl.cc
@@ -4,6 +4,7 @@
// Automatically @generated Rust bindings for the following C++ target:
// //rs_bindings_from_cc/test/golden:user_of_unsupported_cc
+// Features: experimental, supported
#include <cstddef>
#include <memory>