Skip to content

Commit 4693e52

Browse files
committed
Detect some narrowing conversions to types like std::optional, closes #199
1 parent b655f22 commit 4693e52

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

include/cpp2util.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,19 @@ auto as( X const& x ) -> decltype(auto) {
798798

799799
template< typename C, typename X >
800800
auto as( X const& x ) -> auto
801-
requires (!std::is_same_v<C, X> && requires { C{x}; } && !is_narrowing_v<C, X>)
801+
requires (!std::is_same_v<C, X> && requires { C{x}; })
802802
{
803+
// Experiment: Recognize the nested `::value_type` pattern for some dynamic library types
804+
// like std::optional, and try to prevent accidental narrowing conversions even when
805+
// those types themselves don't defend against them
806+
if constexpr( requires{ typename C::value_type; } && std::is_convertible_v<X, typename C::value_type> ) {
807+
if constexpr( is_narrowing_v<typename C::value_type, X>) {
808+
static_assert(
809+
program_violates_type_safety_guarantee<C, CPP2_TYPEOF(x)>,
810+
"This is a narrowing 'as' cast to a dynamic library type - if you're sure you want this unsafe conversion, consider adding an `unsafe_narrow<T>()` separately first to force the narrowing conversion, then 'as' to the library type"
811+
);
812+
}
813+
}
803814
return C{x};
804815
}
805816

0 commit comments

Comments
 (0)