mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:20:10 +01:00
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:
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user