> On Dec 31, 2015, at 3:15 PM, Jesse Rusak <m...@jesserusak.com> wrote:
> 
> Hi Doug,
> 
> I’ve been playing around with an implementation of the warning you referenced 
> here: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001584.html
> 
> Would it be helpful for me to take this on?

Yes, absolutely!

> If so, is there any detail in the radar assigned to you about what exactly 
> should trigger such a warning?
> For example, I have it currently triggering whenever there’s a method with a 
> matching name, ignoring parameter/return types; it’s not obvious to me how 
> closely they should have to match, if at all, to trigger the warning.

I just realized that I wrote up a big discussion of a related-but-not-identical 
warning. In either case, there is some kind of radar, and neither gives a lot 
of detail. 

In general: just matching on name alone feels like it might produce too many 
false positives, but exactly matching parameter/return types feels like it 
might miss cases where this warning would be important, so… I think it’s going 
to come down to coming up with cases where you do/don’t want to see the warning 
and tuning the warning to do the right thing. It might be that you want to do 
some simplistic matching (perhaps akin to what lib/Sema/TypeCheckProtocol.cpp 
does when inferring type witnesses) that ignores uses of associated types that 
might have been deduced differently from what the user expected.

That leads to my #1 example I’d love to get a warning for, which is when you 
intended to provide something to satisfy a protocol requirement, but you ended 
up getting a default implementation:

struct MyGenerator {
  mutating func next() -> Int? { return nil }
}

struct MyCollection : CollectionType {
  typealias Index = Int

  var startIndex: Int { return 0 }
  var endIndex: Int { return 10 }

  subscript (index: Int) -> Int {
    return index
  }

  func generate() -> MyGenerator {
    print("using MyGenerator")
    return MyGenerator()
  }
}

func foo<C: CollectionType>(c: C) {
  c.generate()
}

foo(MyCollection())

Note that there is no output from this program, although one would expect to 
see “using MyGenerator”.

The root of the problem is annoying simple (I “forgot” to state that 
MyGenerator conforms to GeneratorType). The result is that the implied 
SequenceType conformance gets a default implementation of “generate” from a 
protocol extension in the standard library (that produces default generator for 
any SequenceType that is also a CollectionType). Our place to warn about this 
is at the point where we decide to use a “generate” from a protocol extension 
rather than the “generate” in the same “struct” that declares conformance to 
CollectionType. Obviously, lots of bonus points if we could say why the 
generate() in the struct wasn’t picked :)

That brings up another point about warnings: it’s useful to have a way to 
suppress them. Let’s say we got a warning for my example above (huzzah!) but I 
wanted to silence it. A fairly natural way to do so would be to move the 
“generate” function I defined into a separate extension, so it’s away from 
where we state conformance to CollectionType:


struct MyGenerator {
  mutating func next() -> Int? { return nil }
}

struct MyCollection : CollectionType {
  typealias Index = Int

  var startIndex: Int { return 0 }
  var endIndex: Int { return 10 }

  subscript (index: Int) -> Int {
    return index
  }
}

extension MyCollection {
  func generate() -> MyGenerator { // no warning
    print("using MyGenerator")
    return MyGenerator()
  }
}

Effectively, we’re using the declaration of conformance to a protocol as 
indicating user intent that the contents of this particular 
definition/extension involve that conformance.

The actual warning you are talking about is very, very similar, and would 
likely use most of the same logic. The part that differs is the trigger: 
whenever one declares something within a type, perform a lookup in that type to 
determine whether there are any similar members of extensions of one of the 
protocols that type conforms to. You'll want to think about how to suppress the 
warning when the user wants to. 

        - Doug

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

Reply via email to