Allow conversions between all pointer types with unsafe as. (#6635)

Previously we only allowed conversions from `void*` to `U*` this way,
requiring casting via `void*` to get from `T*` to `U*`. That seems like
an unnecessary circumlocution.
This commit is contained in:
Richard Smith
2026-01-21 15:47:51 +00:00
committed by GitHub
parent a448792207
commit 8353965ca3
10 changed files with 86 additions and 40 deletions
+10
View File
@@ -20,18 +20,22 @@ interface ImplicitAs(Dest:! type) {
fn Convert[self: Self]() -> Dest;
}
// Workaround: ImplicitAs extends As.
impl forall [U:! type, T:! ImplicitAs(U)] T as As(U) {
fn Convert[self: Self]() -> U { return self.Convert(); }
}
// Workaround: As extends UnsafeAs.
impl forall [U:! type, T:! As(U)] T as UnsafeAs(U) {
fn Convert[self: Self]() -> U { return self.Convert(); }
}
// Copyable types have an identity conversion that performs a copy.
impl forall [T:! Copy] T as ImplicitAs(T) {
fn Convert[self: Self]() -> Self { return self.(Copy.Op)(); }
}
// `const` can be added and removed when converting a value.
impl forall [T:! type, U:! ImplicitAs(T)] U as ImplicitAs(const T) {
fn Convert[self: U]() -> const T { return self.Convert(); }
}
@@ -39,3 +43,9 @@ impl forall [T:! type, U:! ImplicitAs(T)] U as ImplicitAs(const T) {
impl forall [T:! type, U:! ImplicitAs(T)] const U as ImplicitAs(T) {
fn Convert[self: const U]() -> T { return (self as U).Convert(); }
}
// Pointer types can be unsafely cast to other pointer types.
// TODO: Should `unsafe as` be able to remove `const`?
impl forall [T:! type, U:! type] T* as UnsafeAs(U*) {
fn Convert[self: T*]() -> U* = "pointer.unsafe_convert";
}
-5
View File
@@ -43,8 +43,3 @@ impl forall [T:! type] T* as ImplicitAs(const CppCompat.VoidBase*) {
impl forall [T:! type] CppCompat.VoidBase* as UnsafeAs(T*) {
fn Convert[self: CppCompat.VoidBase*]() -> T* = "pointer.unsafe_convert";
}
// TODO: Should `unsafe as` be able to remove `const`?
impl forall [T:! type] const CppCompat.VoidBase* as UnsafeAs(const T*) {
fn Convert[self: const CppCompat.VoidBase*]() -> const T* = "pointer.unsafe_convert";
}