Cannot invoke 'stride' with an argument list of type '(from: Int, to: Int, by: Int)'


(Martin R) #1

It seems that the extension method

    extension Strideable {
        public func stride(to end: Self, by stride: Self.Stride) -> StrideTo<Self>
    }

from Swift 2.2 is still known to the compiler and only marked as unavailable in Swift 3, as this code example demonstrates:

    extension Int {
        func test() {
            for _ in stride(to: 10, by: 2) { }
            // error: 'stride(to:by:)' is unavailable: Use stride(from:to:by:) free function instead
        }
    }

so that in your code

    extension Int {
        func up(to upper: Int, by step: Int = 1, _ closure: @noescape () -> Void) {
            for _ in stride(from: self, to: upper, by: step) {
                closure()
            }
        }
    }

the compiler tries to match the stride() invocation against this (unavailable) extension method. This is also confirmed by the compiler messages:

    error: cannot invoke 'stride' with an argument list of type '(from: Int, to: Int, by: Int)'
    note: overloads for 'stride' exist with these partially matching parameter lists: (to: Self, by: Self.Stride), (through: Self, by: Self.Stride)

This would also explain why it fails to compile in an extension to Int or Float, but compiles without errors in an extension to String or other non-Strideable types.

As a workaround, you can call the global function by explicitly prefixing it with the module name "Swift":

    extension Int {
        func up(to upper: Int, by step: Int = 1, _ closure: @noescape () -> Void) {
            for _ in Swift.stride(from: self, to: upper, by: step) {
                closure()
            }
        }
    }

Regards, Martin

···

You are right. Int conforms to Strideable.

Now it seams like a bug. As in a playground. below are code works and
doesn't work

extension Int {

    func test() {

        let temp = stride(from:1, to:10, by:2) // error

    }

}

extension Float {

    func test() {

        let temp = stride(from:1, to:10, by:2) // error

    }

}

extension String {

    func test() {

        let temp = stride(from:1, to:10, by:2) // works

    }

}

class A {

}

extension A {

    func test() {

        let temp = stride(from:1, to:10, by:2) // works

    }

}

struct B {

}

extension B {

    func test() {

        let temp = stride(from:1, to:10, by:2) // works

    }

}

func test() {

    let temp = stride(from:1, to:10, by:2) //works

}

let temp = stride(from:1, to:10, by:2) // works

​It is nothing bug a bug?​

​Zhaoxin​

On Tue, Jul 5, 2016 at 10:16 PM, Shawn Erickson <shawnce at gmail.com> wrote:

> Int conforms to Strideable byway of Integer <- SignedInteger <- Int (not
> exactly sure how it will be once the integer proposal is implemented but it
> will still be strideable).
>
> -Shawn
>
> On Mon, Jul 4, 2016 at 10:38 PM Zhao Xin via swift-users < > > swift-users at swift.org> wrote:
>
>> In Swift 3,
>>
>> func stride<T : Strideable>(from start: T, to end: T, by stride:
>> T.Stride) -> StrideTo<T>
>>
>> Int does not conform to Strideable.
>>
>> Adopted By
>>
>> CGFloat
>> Decimal
>> Double
>> Float
>> Float80
>> String.UTF16View.Index
>> UnsafeMutablePointer
>> UnsafePointer
>>
>> ​In Swift 2.2,
>>
>> @warn_unused_result func stride(to *end*: Self, by *stride*: Self.Stride)
>> -> StrideTo<Self>
>>
>> It uses Self, which means the type of the variable, instead of T.
>>
>> Zhaoxin
>>
>> On Tue, Jul 5, 2016 at 11:41 AM, Adriano Ferreira via swift-users < > >> swift-users at swift.org> wrote:
>>
>>> Hi everyone!
>>>
>>> I’m converting some code to Swift 3 and got this issue?
>>>
>>>
>>>
>>>
>>> Does anybody know what’s going on?
>>>
>>> Here’s the code, before and after conversion:
>>>
>>>
>>> // Swift 2.2
>>> extension Int {
>>>
>>> // Repeat a block of code from `self` up to a limit
>>> func up(to upper: Int, by step: Int = 1, @noescape closure: () ->
>>> Void) {
>>>
>>> for _ in self.stride(to: upper, by: step) {
>>> closure()
>>> }
>>> }
>>> }
>>>
>>> // Swift 3
>>> extension Int {
>>>
>>> // Repeat a block of code from `self` up to a limit
>>> func up(to upper: Int, by step: Int = 1, _ closure: @noescape () ->
>>> Void) {
>>>
>>> for _ in stride(from: self, to: upper, by: step) {
>>> closure()
>>> }
>>> }
>>> }
>>>
>>>
>>> // Usage
>>> 1.up(to: 10, by: 2) {
>>> print("Hi!")
>>> }
>>>


(Adriano Ferreira) #2

Thanks Martin, now it works!

Do you think this should be filed as a bug or just wait until the Swift team removes the old stride method?

Best,

— A

···

On Jul 5, 2016, at 1:25 PM, Martin R via swift-users <swift-users@swift.org> wrote:

It seems that the extension method

   extension Strideable {
       public func stride(to end: Self, by stride: Self.Stride) -> StrideTo<Self>
   }

from Swift 2.2 is still known to the compiler and only marked as unavailable in Swift 3, as this code example demonstrates:

   extension Int {
       func test() {
           for _ in stride(to: 10, by: 2) { }
           // error: 'stride(to:by:)' is unavailable: Use stride(from:to:by:) free function instead
       }
   }

so that in your code

   extension Int {
       func up(to upper: Int, by step: Int = 1, _ closure: @noescape () -> Void) {
           for _ in stride(from: self, to: upper, by: step) {
               closure()
           }
       }
   }

the compiler tries to match the stride() invocation against this (unavailable) extension method. This is also confirmed by the compiler messages:

   error: cannot invoke 'stride' with an argument list of type '(from: Int, to: Int, by: Int)'
   note: overloads for 'stride' exist with these partially matching parameter lists: (to: Self, by: Self.Stride), (through: Self, by: Self.Stride)

This would also explain why it fails to compile in an extension to Int or Float, but compiles without errors in an extension to String or other non-Strideable types.

As a workaround, you can call the global function by explicitly prefixing it with the module name "Swift":

   extension Int {
       func up(to upper: Int, by step: Int = 1, _ closure: @noescape () -> Void) {
           for _ in Swift.stride(from: self, to: upper, by: step) {
               closure()
           }
       }
   }

Regards, Martin

You are right. Int conforms to Strideable.

Now it seams like a bug. As in a playground. below are code works and
doesn't work

extension Int {

   func test() {

       let temp = stride(from:1, to:10, by:2) // error

   }

}

extension Float {

   func test() {

       let temp = stride(from:1, to:10, by:2) // error

   }

}

extension String {

   func test() {

       let temp = stride(from:1, to:10, by:2) // works

   }

}

class A {

}

extension A {

   func test() {

       let temp = stride(from:1, to:10, by:2) // works

   }

}

struct B {

}

extension B {

   func test() {

       let temp = stride(from:1, to:10, by:2) // works

   }

}

func test() {

   let temp = stride(from:1, to:10, by:2) //works

}

let temp = stride(from:1, to:10, by:2) // works

​It is nothing bug a bug?​

​Zhaoxin​

On Tue, Jul 5, 2016 at 10:16 PM, Shawn Erickson <shawnce at gmail.com> wrote:

Int conforms to Strideable byway of Integer <- SignedInteger <- Int (not
exactly sure how it will be once the integer proposal is implemented but it
will still be strideable).

-Shawn

On Mon, Jul 4, 2016 at 10:38 PM Zhao Xin via swift-users < >>> swift-users at swift.org> wrote:

In Swift 3,

func stride<T : Strideable>(from start: T, to end: T, by stride:
T.Stride) -> StrideTo<T>

Int does not conform to Strideable.

Adopted By

CGFloat
Decimal
Double
Float
Float80
String.UTF16View.Index
UnsafeMutablePointer
UnsafePointer

​In Swift 2.2,

@warn_unused_result func stride(to *end*: Self, by *stride*: Self.Stride)
-> StrideTo<Self>

It uses Self, which means the type of the variable, instead of T.

Zhaoxin

On Tue, Jul 5, 2016 at 11:41 AM, Adriano Ferreira via swift-users < >>>> swift-users at swift.org> wrote:

Hi everyone!

I’m converting some code to Swift 3 and got this issue?

Does anybody know what’s going on?

Here’s the code, before and after conversion:

// Swift 2.2
extension Int {

   // Repeat a block of code from `self` up to a limit
   func up(to upper: Int, by step: Int = 1, @noescape closure: () ->
Void) {

       for _ in self.stride(to: upper, by: step) {
           closure()
       }
   }
}

// Swift 3
extension Int {

   // Repeat a block of code from `self` up to a limit
   func up(to upper: Int, by step: Int = 1, _ closure: @noescape () ->
Void) {

       for _ in stride(from: self, to: upper, by: step) {
           closure()
       }
   }
}

// Usage
1.up(to: 10, by: 2) {
   print("Hi!")
}

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Brent Royal-Gordon) #3

The old method is probably a stub that tells the fix-its how to find the new one, so it's there to stay. File a bug.

···

On Jul 5, 2016, at 11:39 AM, Adriano Ferreira via swift-users <swift-users@swift.org> wrote:

Do you think this should be filed as a bug or just wait until the Swift team removes the old stride method?

--
Brent Royal-Gordon
Architechies