We have answer of your question!

100% solved queries, no empty question

Question: Cannot infer generic parameter when defining generic in different module


0

Advertisement


I have a swift repository that defines 2 modules:

Sources/Parser/Parser.swift contains:

public struct Parser<Token, Output> {
  public let parse: (AnyCollection<Token>) throws -> (Output, AnyCollection<Token>)
}

public func countingParser() -> Parser<Character,Int> {
  return Parser { input in
    return ( 1, input.dropFirst( 1 ) )
  }
}

Sources/External/Parser.swift contains:

import Parser

func externalCountingParser() -> Parser<Character,Int> {
  return Parser { input in
    return ( 1, input.dropFirst( 1 ) )
  }
}

And for completeness, my Package.swift contains:

import PackageDescription

let package = Package(
    name: "SwiftBug",
    targets: [ Target( name: "External", dependencies: [ "Parser" ] ) ]
)

Despite countingParser and externalCountingParser being basically the same code, I get a compile error in External/Parser.swift with swift 3.0.1.

Sources/External/Parser.swift:4:10: error: generic parameter 'Token' could not be inferred
  return Parser { input in
         ^
Parser.Parser:1:15: note: 'Token' declared as parameter to type 'Parser'
public struct Parser<Token, Output> {
              ^
Sources/External/Parser.swift:4:10: note: explicitly specify the generic arguments to fix this issue
  return Parser { input in
         ^
               <Any, Any>

No matter what I do to further specify the type of Parser inside the function, I cannot get this to compile. Why does it work fine when defined inside the module that defines Parser, but fails to compile when defined outside the same module?

Edit: If i make @PEEJWEEJ's edits, as suggested below, there is still a compile error, but the error message has changed:

Sources/External/Parser.swift:

import Parser

func externalCountingParser() -> Parser<Character,Int> {
  let p: Parser<Character, Int> = Parser<Character,Int>( parse: { input in
    return ( 1, input.dropFirst(1) )
  } )

  return p
}

Now produces the error:

Sources/External/Parser.swift:4:35: error: expression type 'Parser<Character, Int>' is ambiguous without more context
  let p: Parser<Character, Int> = Parser<Character,Int>( parse: { input in
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

With more type info specified like so in Sources/External/Parser.swift:

import Parser

func externalCountingParser() -> Parser<Character,Int> {
  let p: Parser<Character, Int> = Parser<Character,Int> { (input: AnyCollection<Character>) -> (Int,AnyCollection<Character>) in
    return ( 1, input.dropFirst(1) )
  }

  return p
}

Results in the following diagnostic:

Sources/External/Parser.swift:4:96: error: declared closure result '(Int, AnyCollection<Character>)' is incompatible with contextual type '(_, AnyCollection<_>)'
  let p: Parser<Character, Int> = Parser<Character,Int> { (input: AnyCollection<Character>) -> (Int,AnyCollection<Character>) in
                                                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                                               (_, AnyCollection<_>)
Question author Peter-kovacs | Source

Answer


1


Advertisement


The issue seems to be the fact that the default constructor for Parser is by default internal. Chalk this up to another bad diagnostic message.

If I change the declaration of struct Parser to:

public struct Parser<Token, Output> {
  public typealias ParseFunction = (AnyCollection<Token>) throws -> (Output, AnyCollection<Token>)
  public let parse: ParseFunction
  public init( parse: @escaping ParseFunction ) {
    self.parse = parse
  }
}

Then we compile just fine.

Answer author Peter-kovacs

Advertisement


Tickanswer.com is providing the only single recommended solution of the question Cannot infer generic parameter when defining generic in different module under the categories i.e swift , generics , . Our team of experts filter the best solution for you.

Related Search Queries:

You may also add your answer!