Skip to content

[SR-10752] Trouble with Generic Constraints and Associated Types #53142

@stephencelis

Description

@stephencelis
Previous ID SR-10752
Radar rdar://problem/51068593
Original Reporter @stephencelis
Type Bug
Status Resolved
Resolution Done
Environment

Swift 5.1

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, TypeChecker
Assignee None
Priority Medium

md5: 9d6ac07735765d370875cf592220ea2b

is duplicated by:

  • SR-13019 Bad compiler error on generic constraint of associated types

Issue Description:

Given the following parser type:

struct Parser<I, O> {
  let run: (inout I) -> O?
} 

I can define the following parse function from inout Substring:

extension Parser where I == Substring {
  func parse(_ input: String) -> O? {
    var sub = input[...]
    guard
      let result = self.run(&sub),
      sub.isEmpty
      else { return nil }
    return result
  }
} 

I'd preferably like to work more generically on any Collection, but the following doesn't compile.

extension Parser where I: Collection {
  func parse<C: Collection>(_ input: C) -> O? where I == C.SubSequence {
    var sub = input[...]
    guard
      let result = self.run(&sub), // ERROR: Use of extraneous '&'
      sub.isEmpty
      else { return nil }
    return result
  }
} 

The error is puzzling, but it seems to be that Swift isn't considering the I generic and C.SubSequence equivalent, despite the where clause.

extension Parser where I: Collection {
  func parse<C: Collection>(_ input: C) -> O? where I == C.SubSequence {
    var sub = input[...] as I // ERROR: 'C.SubSequence' is not convertible to 'I'
    guard
      let result = self.run(&sub),
      sub.isEmpty
      else { return nil }
    return result
  }
}  

We can force-cast our way to another error:

 extension Parser where I: Collection {
  func parse<C: Collection>(_ input: C) -> O? where I == C.SubSequence {
    var sub = input[...] as! I
    guard
      let result = self.run(&sub),
      sub.isEmpty // ERROR: Value of type 'I' has no member 'isEmpty'
      else { return nil }
    return result
  }
}  

But now we're stuck. I is constrained to Collection but it doesn't seem to think it has isEmpty as a member.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselftype checkerArea → compiler: Semantic analysis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions