swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.45k stars 10.35k forks source link

[SR-8123] Invalid redeclaration of `name` when creating a func `name()` in a different extension of the same type with different `where` clause #50655

Open swift-ci opened 6 years ago

swift-ci commented 6 years ago
Previous ID SR-8123
Radar None
Original Reporter scalbatty (JIRA User)
Type Bug
Environment Tested on macOS High Sierra 10.13.4, in Xcode 9.3 (Swift 4.1) and Xcode 10 beta (Swift 4.2)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 393fd19913c431740d871a1350fdb0a4

Issue Description:

When defining 2 extensions for a same protocol with associated type (or generic type), it is possible to define variables or functions with the same name in both extensions with different where clauses.

protocol Foo {
    associatedtype T
}

// This compiles
extension Foo where T: Collection {
    var foo: Bool { return true }
    func bar() -> Bool { return true }
}

extension Foo where T: Numeric {
    var foo: Int { return 0 }
    func bar() -> Int { return 0 }
}

However, the compiler fires an invalid redeclaration error if an extension defines a function with the same name as a variable defined in another extension.

protocol Foo {
    associatedtype T
}

// This does not compile
extension Foo where T: Collection {
    var foo: Bool { return true }
}

extension Foo where T: Numeric {
    func foo() -> Int { return 0 } // <- error: invalid redeclaration of 'foo()'
}

The same is also true the `where` clauses target a specific type (i.e. `where T == Int`) with distinct types.

belkadan commented 6 years ago

Huh. @DougGregor, @hamishknight, what do you think?

DougGregor commented 6 years ago

It's definitely weird to call these redeclarations.

hamishknight commented 6 years ago

I think we should make this legal – currently we're always considering variables to conflict with non-variables (and functions with non-functions) if their overload signatures conflict, regardless of the generic environment. But if the generic environment differs, IMO it's reasonable to allow to allow the overload.

belkadan commented 6 years ago

I feel weird because T could totally conform to both Collection and Numeric, but I guess that's not a new problem—we have it already with functions.

hamishknight commented 6 years ago

I think in the case of conforming to both we should reject attempts to access the overloaded member as ambiguous (unless it can be disambiguated) – but it seems reasonable to allow for cases where T isn't conforming to both (which is likely the common case if the user is writing such code).