Merge pull request #18 from google:ssbr-patch-1 PiperOrigin-RevId: 825256803 Change-Id: I2b7a27195f025f2f7d85a5bf56fcda32374d57af
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7424520..80706d9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml
@@ -1,4 +1,7 @@ -name: Rust +# 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 +name: Cargo on: push: @@ -18,5 +21,3 @@ - uses: actions/checkout@v4 - name: Build run: cargo build --verbose --bin cc_bindings_from_rs - # - name: Run tests - # run: cargo test --verbose
diff --git a/support/rs_std/char.h b/support/rs_std/char.h index 47577ae..b2b4e84 100644 --- a/support/rs_std/char.h +++ b/support/rs_std/char.h
@@ -9,6 +9,7 @@ #include <cstddef> #include <cstdint> #include <optional> +#include <type_traits> #include "absl/base/optimization.h" #include "absl/types/span.h" @@ -44,10 +45,22 @@ // for C++ which argues that zero-initialization may mitigate 10% of exploits. constexpr char_() noexcept = default; - // Constant-time implicit constructor which converts a Unicode scalar value - // `uint32_t` into an `rs_std::char_`. This function performs compile-time - // validation that the `uint32_t` is a valid Unicode scalar value. - explicit consteval char_(char32_t c) noexcept : value_(c) { + // Constant-time implicit constructor which converts a character + // literal into an `rs_std::char_`. This function performs compile-time + // validation that the argument is a valid Unicode scalar value. + // + // Note: this constructor is templated in order to ensure that implicit + // conversions from `int` values are not applied. + template <typename Char, typename CharNoCv = std::remove_cvref_t<Char>, + typename = std::enable_if_t<std::is_same_v<CharNoCv, char> || + std::is_same_v<CharNoCv, char8_t> || + std::is_same_v<CharNoCv, char16_t> || + std::is_same_v<CharNoCv, char32_t>>> + consteval char_( // NOLINT(google-explicit-constructor) + // Style waiver for implicit conversions granted in + // cl/825200658. + Char c) noexcept + : value_(c) { if (!IsValidCodePoint(c)) { internal::CharArgumentMustBeUnicodeCodePoint(); }
diff --git a/support/rs_std/str_ref.h b/support/rs_std/str_ref.h index 3b7e930..7f24653 100644 --- a/support/rs_std/str_ref.h +++ b/support/rs_std/str_ref.h
@@ -66,18 +66,21 @@ return StrRef(UnsafePromiseUtf8(), string_view); } - // consteval implict conversion from `const char*` so that string + // consteval implicit conversion from `const char*` so that string // literals can be used as `StrRef` arguments while still requiring runtime // UTF8 validation to be explicit. - // - // Note: consider this constructor for an implicit conversion waiver. - explicit consteval StrRef(const char* absl_nonnull char_ptr) noexcept + consteval StrRef( // NOLINT(google-explicit-constructor) + // Style waiver for implicit conversions granted in + // cl/825200658. + const char* absl_nonnull char_ptr) noexcept : StrRef(absl::string_view(char_ptr)) {} - // consteval implict conversion from `absl::string_view`. - // - // Note: consider this constructor for an implicit conversion waiver. - explicit consteval StrRef(absl::string_view string_view) noexcept : slice_() { + // consteval implicit conversion from `absl::string_view`. + consteval StrRef( // NOLINT(google-explicit-constructor) + // Style waiver for implicit conversions granted in + // cl/825200658. + absl::string_view string_view) noexcept + : slice_() { if (!string_view.empty()) { // We cannot use `static_assert` because C++ does not treat arguments // to `consteval` functions as constants. @@ -90,8 +93,11 @@ } } - // Note: consider conversion operator for an implicit conversion waiver. - explicit constexpr operator absl::string_view() const noexcept { + constexpr + operator absl::string_view() // NOLINT(google-explicit-constructor) + // Style waiver for implicit + // conversions granted in cl/825200658. + const noexcept { return absl::string_view(slice_.data(), slice_.size()); } @@ -145,6 +151,14 @@ return rhs == lhs; } +constexpr bool operator==(StrRef lhs, const char* rhs) noexcept { + return lhs.to_string_view() == absl::string_view(rhs); +} + +constexpr bool operator==(const char* lhs, StrRef rhs) noexcept { + return rhs == lhs; +} + constexpr auto operator<=>(StrRef lhs, StrRef rhs) noexcept { return lhs.to_string_view() <=> rhs.to_string_view(); } @@ -157,6 +171,14 @@ return lhs <=> rhs.to_string_view(); } +constexpr auto operator<=>(StrRef lhs, const char* rhs) noexcept { + return lhs.to_string_view() <=> absl::string_view(rhs); +} + +constexpr auto operator<=>(const char* lhs, StrRef rhs) noexcept { + return absl::string_view(lhs) <=> rhs.to_string_view(); +} + } // namespace rs_std namespace crubit::internal {
diff --git a/support/rs_std/str_ref_test.cc b/support/rs_std/str_ref_test.cc index 5d04634..361d50f 100644 --- a/support/rs_std/str_ref_test.cc +++ b/support/rs_std/str_ref_test.cc
@@ -64,20 +64,20 @@ static constexpr absl::string_view kStr = "12345"; static constexpr absl::string_view kStrCopy = "12345"; - static constexpr StrRef kStrRef = StrRef(kStr); + static constexpr StrRef kStrRef = kStr; static constexpr StrRef kStrRefCopy = kStrRef; - static constexpr StrRef kStrRef2 = StrRef(kStrCopy); + static constexpr StrRef kStrRef2 = kStrCopy; static_assert(kStrRef == kStrRef); static_assert(kStrRef == kStrRefCopy); static_assert(kStrRef == kStrRef2); static constexpr StrRef kStrRef_prefix = - StrRef(absl::string_view(kStr.data(), kStr.size() - 1)); + absl::string_view(kStr.data(), kStr.size() - 1); static constexpr StrRef kStrRef_suffix = - StrRef(absl::string_view(kStr.data() + 1, kStr.size() - 1)); + absl::string_view(kStr.data() + 1, kStr.size() - 1); static constexpr StrRef kStrRef_infix = - StrRef(absl::string_view(kStr.data() + 1, kStr.size() - 2)); + absl::string_view(kStr.data() + 1, kStr.size() - 2); EXPECT_GT(kStrRef, kStrRef_prefix); EXPECT_LT(kStrRef, kStrRef_suffix); @@ -86,7 +86,7 @@ TEST(StrTest, FromAndTo) { static constexpr absl::string_view kStr = "12345"; - static constexpr StrRef kStrRef = StrRef(kStr); + static constexpr StrRef kStrRef = kStr; EXPECT_EQ(kStr, kStrRef); } @@ -101,7 +101,7 @@ // `StrRef` is correct. TEST(StrTest, Layout) { static constexpr absl::string_view kStr = "foo"; - const StrRef s = StrRef(kStr); + const StrRef s = kStr; const auto fields = std::bit_cast<StrRefFields>(s); EXPECT_EQ(fields.ptr, kStr.data()); EXPECT_EQ(fields.size, kStr.size()); @@ -109,7 +109,7 @@ TEST(StrTest, Empty) { static constexpr const char* kEmpty = ""; - const StrRef empty = StrRef(absl::string_view(kEmpty, 0)); + const StrRef empty = absl::string_view(kEmpty, 0); static constexpr StrRef default_constructed; EXPECT_EQ(empty, default_constructed); @@ -125,7 +125,7 @@ TEST(StrTest, StrCat) { static constexpr absl::string_view kStr = "12345"; - static constexpr StrRef kStrRef = StrRef("12345"); + static constexpr StrRef kStrRef = "12345"; EXPECT_EQ(absl::StrCat(kStrRef), kStr); } @@ -144,7 +144,7 @@ TEST(ImplicitConversionTest, FromConstCharPtr) { static constexpr const char* kConstCharPtr = "12"; - static constexpr StrRef kStrRef = StrRef(kConstCharPtr); + static constexpr StrRef kStrRef = kConstCharPtr; EXPECT_EQ(kStrRef, "12"); }