function advancedBy() bugs


(Zhao Xin) #1

It seams that I encountered bugs in function advancedBy().

//: Playground - noun: a place where people can play

import Foundation

do {

    var str = "abcdefg"

    var range = str.startIndex..<str.endIndex // 0..<7

    str += "hijklmn"

    range.endIndex = str.endIndex // 0..<14

    let index = range.startIndex.advancedBy(10)

    //fatal error: cannot increment endIndex

}

do {

    var str = "abcdefg"

    str += "hijklmn"

    var range = str.startIndex..<str.endIndex // 0..<14

    let index = range.startIndex.advancedBy(10)

    range // 0..<14

}

do {

    var range = 0..<7

    let index = range.startIndex.advancedBy(10)

    range // 0..<7

}

There are three do blocks. All codes are similar.

First block and second block is the almost same. But I encounter an error
in the first block, saying "fatal error: cannot increment endIndex". It
shouldn't appear as the endIndex of range is 14 instead 7.

Second block and third block both used function advancedBy, however, in the
second block, the method is from BidirectionalIndexType,

extension BidirectionalIndexType {

    @warn_unused_result

    public func advancedBy(n: Self.Distance) -> Self

    @warn_unused_result

    public func advancedBy(n: Self.Distance, limit: Self) -> Self

}

​in the ​third block, it is RandomAccessIndexType,

extension Int : RandomAccessIndexType {

    /// Returns the next consecutive value after `self`.

    ///

    /// - Requires: The next value is representable.

    public func successor() -> Int

    /// Returns the previous consecutive value before `self`.

    ///

    /// - Requires: The previous value is representable.

    public func predecessor() -> Int

    public func distanceTo(other: Int) -> Distance

    public func advancedBy(n: Distance) -> Int

}

​So the range in the third block after advancedBy is unchanged. It makes
sense here. But I think people may feel strange as one is a mutating
function and the other is not.

​Zh​aoxin


(Dmitri Gribenko) #2

Hi,

Thank you for the report. To me, this issue looks the same as
https://bugs.swift.org/browse/SR-1487.

Dmitri

···

On Tue, May 17, 2016 at 5:46 AM, zh ao via swift-users <swift-users@swift.org> wrote:

It seams that I encountered bugs in function advancedBy().

do {
    var str = "abcdefg"
    var range = str.startIndex..<str.endIndex // 0..<7
    str += "hijklmn"
    range.endIndex = str.endIndex // 0..<14
    let index = range.startIndex.advancedBy(10)
    //fatal error: cannot increment endIndex
}

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Zhao Xin) #3

Xcode Version 7.3.1 (7D1014), swift 2.2 along with Xcode.

Zhaoxin

···

On Tue, May 17, 2016 at 8:46 PM, zh ao <owenzx@gmail.com> wrote:

It seams that I encountered bugs in function advancedBy().

//: Playground - noun: a place where people can play

import Foundation

do {

    var str = "abcdefg"

    var range = str.startIndex..<str.endIndex // 0..<7

    str += "hijklmn"

    range.endIndex = str.endIndex // 0..<14

    let index = range.startIndex.advancedBy(10)

    //fatal error: cannot increment endIndex

}

do {

    var str = "abcdefg"

    str += "hijklmn"

    var range = str.startIndex..<str.endIndex // 0..<14

    let index = range.startIndex.advancedBy(10)

    range // 0..<14

}

do {

    var range = 0..<7

    let index = range.startIndex.advancedBy(10)

    range // 0..<7

}

There are three do blocks. All codes are similar.

First block and second block is the almost same. But I encounter an error
in the first block, saying "fatal error: cannot increment endIndex". It
shouldn't appear as the endIndex of range is 14 instead 7.

Second block and third block both used function advancedBy, however, in
the second block, the method is from BidirectionalIndexType,

extension BidirectionalIndexType {

    @warn_unused_result

    public func advancedBy(n: Self.Distance) -> Self

    @warn_unused_result

    public func advancedBy(n: Self.Distance, limit: Self) -> Self

}

​in the ​third block, it is RandomAccessIndexType,

extension Int : RandomAccessIndexType {

    /// Returns the next consecutive value after `self`.

    ///

    /// - Requires: The next value is representable.

    public func successor() -> Int

    /// Returns the previous consecutive value before `self`.

    ///

    /// - Requires: The previous value is representable.

    public func predecessor() -> Int

    public func distanceTo(other: Int) -> Distance

    public func advancedBy(n: Distance) -> Int

}

​So the range in the third block after advancedBy is unchanged. It makes
sense here. But I think people may feel strange as one is a mutating
function and the other is not.

​Zh​aoxin


(Zhao Xin) #4

I just make a clearer example.

do {

    var str = "abcdefg"

    var str1 = str + "hijklmn"

    var range = str.startIndex..<str1.endIndex

    range.startIndex = range.startIndex.advancedBy(10)

    //fatal error: cannot increment endIndex

}

It seams that range.startIndex internally contains a fault
endIndex(str.endIndex, it should be its own endIndex, range.endIndex),
which leads the issue.

Zhaoxin

···

On Wed, May 18, 2016 at 12:02 AM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Tue, May 17, 2016 at 5:46 AM, zh ao via swift-users > <swift-users@swift.org> wrote:
> It seams that I encountered bugs in function advancedBy().
>
> do {
> var str = "abcdefg"
> var range = str.startIndex..<str.endIndex // 0..<7
> str += "hijklmn"
> range.endIndex = str.endIndex // 0..<14
> let index = range.startIndex.advancedBy(10)
> //fatal error: cannot increment endIndex
> }

Hi,

Thank you for the report. To me, this issue looks the same as
https://bugs.swift.org/browse/SR-1487.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Zhao Xin) #5

The second half on mutating is wrong. Please ignore that.

Zhaoxin

···

On Tue, May 17, 2016 at 8:47 PM, zh ao <owenzx@gmail.com> wrote:

Xcode Version 7.3.1 (7D1014), swift 2.2 along with Xcode.

Zhaoxin

On Tue, May 17, 2016 at 8:46 PM, zh ao <owenzx@gmail.com> wrote:

It seams that I encountered bugs in function advancedBy().

//: Playground - noun: a place where people can play

import Foundation

do {

    var str = "abcdefg"

    var range = str.startIndex..<str.endIndex // 0..<7

    str += "hijklmn"

    range.endIndex = str.endIndex // 0..<14

    let index = range.startIndex.advancedBy(10)

    //fatal error: cannot increment endIndex

}

do {

    var str = "abcdefg"

    str += "hijklmn"

    var range = str.startIndex..<str.endIndex // 0..<14

    let index = range.startIndex.advancedBy(10)

    range // 0..<14

}

do {

    var range = 0..<7

    let index = range.startIndex.advancedBy(10)

    range // 0..<7

}

There are three do blocks. All codes are similar.

First block and second block is the almost same. But I encounter an error
in the first block, saying "fatal error: cannot increment endIndex". It
shouldn't appear as the endIndex of range is 14 instead 7.

Second block and third block both used function advancedBy, however, in
the second block, the method is from BidirectionalIndexType,

extension BidirectionalIndexType {

    @warn_unused_result

    public func advancedBy(n: Self.Distance) -> Self

    @warn_unused_result

    public func advancedBy(n: Self.Distance, limit: Self) -> Self

}

​in the ​third block, it is RandomAccessIndexType,

extension Int : RandomAccessIndexType {

    /// Returns the next consecutive value after `self`.

    ///

    /// - Requires: The next value is representable.

    public func successor() -> Int

    /// Returns the previous consecutive value before `self`.

    ///

    /// - Requires: The previous value is representable.

    public func predecessor() -> Int

    public func distanceTo(other: Int) -> Distance

    public func advancedBy(n: Distance) -> Int

}

​So the range in the third block after advancedBy is unchanged. It makes
sense here. But I think people may feel strange as one is a mutating
function and the other is not.

​Zh​aoxin


(Zhao Xin) #6

Work around:

do {

    var str = "abcdefg"

    var str1 = str + "hijklmn"

* let startIndex =
str1.rangeOfComposedCharacterSequenceAtIndex(str.startIndex).startIndex*

* var range = startIndex..<str1.endIndex*

    range.startIndex = range.startIndex.advancedBy(10)

}

If you encounter this issue, you need to
use rangeOfComposedCharacterSequenceAtIndex to update to hidden endIndex.

do {

    var str = "abcdefg"

    var range = str.startIndex..<str.endIndex // 0..<7

    str += "hijklmn"

// range.endIndex = str.endIndex // 0..<14

    *range = str.**startIndex..<str.endIndex*

    let index = range.startIndex.advancedBy(10)

}

Reassign the whole range instead of just set the endIndex.

Zhaoxin

···

On Wed, May 18, 2016 at 10:14 AM, zh ao <owenzx@gmail.com> wrote:

I just make a clearer example.

do {

    var str = "abcdefg"

    var str1 = str + "hijklmn"

    var range = str.startIndex..<str1.endIndex

    range.startIndex = range.startIndex.advancedBy(10)

    //fatal error: cannot increment endIndex

}

It seams that range.startIndex internally contains a fault
endIndex(str.endIndex, it should be its own endIndex, range.endIndex),
which leads the issue.

Zhaoxin

On Wed, May 18, 2016 at 12:02 AM, Dmitri Gribenko <gribozavr@gmail.com> > wrote:

On Tue, May 17, 2016 at 5:46 AM, zh ao via swift-users >> <swift-users@swift.org> wrote:
> It seams that I encountered bugs in function advancedBy().
>
> do {
> var str = "abcdefg"
> var range = str.startIndex..<str.endIndex // 0..<7
> str += "hijklmn"
> range.endIndex = str.endIndex // 0..<14
> let index = range.startIndex.advancedBy(10)
> //fatal error: cannot increment endIndex
> }

Hi,

Thank you for the report. To me, this issue looks the same as
https://bugs.swift.org/browse/SR-1487.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/