> On 14. Oct 2017, at 13:15, Geordie Jay via swift-users
> <[email protected]> wrote:
>
> Chris Lattner <[email protected]> schrieb am Sa. 14. Okt. 2017 um 05:18:
>
>> On Oct 13, 2017, at 7:40 PM, Andrew Trick via swift-users
>> <[email protected]> wrote:
>>
>>
>>
>>> On Oct 12, 2017, at 3:52 AM, Geordie Jay via swift-users
>>> <[email protected]> wrote:
>>>
>>>
>>> Guillaume Lessard via swift-users <[email protected]> schrieb am Mi.
>>> 11. Okt. 2017 um 23:49:
>>> A lot of the MutableCollection implementation is in protocol extensions
>>> (swapAt, for example.)
>>>
>>> Should an additional version be written just for the Unsafe*BufferPointer
>>> types?
>>>
>>> Makes sense to me, given the examples above. It doesn’t seem to be a high
>>> priority task though, and one one suited to a contributor pull request
>>> rather than taking resources away from the core team.
>>>
>>> Would this kind of change need to go through swift evolution or is it a “no
>>> brainer”?
>>>
>>> Geordie
>>
>> I’ll just point out that it’s already the case that methods defined in
>> Unsafe*BufferPointer that write to memory are “nonmutating”. So I think it’s
>> both a “no brainer” and needs to go through evolution.
>
> I’m not familiar with the specifics of this “proposal” but if it really is
> just moving something obvious from being a mutating member to a nonmutating
> member, then I’m sure the core team can find a fast-path way to accept it
> without a formal review period.
>
> I’m not 100% sure either tbh, although I can imagine putting in a PR for it
> once i understand it.
>
> The issue with changing .swapTo (et al.?) to nonmutating is that semantically
> it really is a mutation. But pointers as collections have different mutation
> semantics to other collections: Mutating an Array’s storage is the same as
> mutating its value, whereas a pointer’s value is its address, not its storage.
>
> Making the Unsafe*Pointer MutableCollection methods themselves nonmutating
> probably wouldn’t be a source-breaking change (it’d just lower the “bar of
> entry” to include let constant instances too). I imagine this is
> noncontroversial.
>
> The original question though was about why .withUnsafeMutableBufferPointer
> takes a closure whose first argument is an *inout*
> UnsafeMutableBufferPointer, implying that its base address could legally be
> mutated. This was probably done to ease use of MutableCollection methods
> given the var parameter. That would no longer be necessary given the first
> change.
>
> But removing the inout attribute would be source-breaking. And maybe people
> really are moving around the array storage’s base address? This seems like a
> very bad idea to me but it’s currently part of that API contract. In any case
> this change would need to go through evolution, right?
At present, the withUnsafeMutableBufferPointer() method verifies that the base
address has not been modified upon return from the closure:
https://github.com/apple/swift/blob/master/stdlib/public/core/Arrays.swift.gyb#L1750
// Put the working array back before returning.
defer {
_precondition(
inoutBufferPointer.baseAddress == pointer &&
inoutBufferPointer.count == count,
"${Self} withUnsafeMutableBufferPointer: replacing the buffer is not
allowed")
(work, self) = (self, work)
}
That check would become obsolete if the buffer pointer is a constant.
As far as I can see, MutableCollection defines four mutating methods: swapAt(),
sort(), reverse(), and partition(). Implementing those as non-mutating methods
of UnsafeMutableBufferPointer seems natural to me.
In addition, it would allow to make the closure parameter in
withUnsafeMutableBufferPointer() a constant. Mutating that pointer in the
closure is not allowed anyway.
Btw, I came up with these questions because I noticed that this compiles:
func foo(bufptr: UnsafeMutableBufferPointer<Int>) { }
var a = [1, 2, 3, 4, 5]
a.withUnsafeMutableBufferPointer { foo(bufptr: $0) }
but this does not compile:
a.withUnsafeMutableBufferPointer(foo)
// error: cannot convert value of type '(UnsafeMutableBufferPointer<Int>)
-> ()'
// to expected argument type '(inout UnsafeMutableBufferPointer<Int>) -> _'
which looks strange at first sight. With a constant closure parameter, the
second version would compile as well.
Any advice how to proceed with this "issue" would be appreciated: File a bug
report? Post on swift-evolution? Make a proposal? ... However, I am not
familiar with those evolution procedures. I won't mind to sidestep if someone
else want to jump in.
Martin
>
> - Geordie
>
>
> -Chris
>
>
> _______________________________________________
> swift-users mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users