Skip to content

[AutoDiff] Improve @derivative and @transpose diagnostics. #32717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

dan-zheng
Copy link
Contributor

@dan-zheng dan-zheng commented Jul 6, 2020

Improve @derivative and @transpose type-checking diagnostics for resolving
the referenced original declaration.

Previously, an error was produced on one invalid candidate at the attribute's
location. This did not indicate the invalid candidate's location or the total
number of invalid candidates.

Now:

  • Diagnostic notes are produced on all invalid candidates at their location.
    Invalid candidates' descriptive declaration kind (e.g. global function,
    instance method) are shown for clarity.
  • Derivative registration for protocol requirements (not yet supported) now
    has a clear, dedicated diagnostic.
  • The "original declaration type mismatch" diagnostic is improved for expected
    original function types with generic signatures. The message now accurately
    reads "candidate does not have type equal to or less constrained than ...",
    instead of "candidate does not have expected type ...".

Resolves SR-13150.
Paves the way for future diagnostic improvements: SR-13151, SR-13152.


Example (non-comprehensive):

import _Differentiation

// Test multiple invalid candidates.

func invalid<T: BinaryFloatingPoint>(x: T) -> T { x }
func invalid<T: CustomStringConvertible>(x: T) -> T { x }
func invalid<T: FloatingPoint>(x: T) -> T { x }

@derivative(of: invalid)
func vjpInvalid<T: Differentiable>(x: T) -> (
  value: T, pullback: (T.TangentVector) -> T.TangentVector
) {
  fatalError()
}

// Test multiple valid (ambiguous) candidates.

protocol P1 {}
protocol P2 {}
func ambiguous<T: P1>(_ x: T) -> T { x }
func ambiguous<T: P2>(_ x: T) -> T { x }

@derivative(of: ambiguous)
func jvpAmbiguous<T: P1 & P2 & Differentiable>(x: T) -> (
  value: T, differential: (T.TangentVector) -> (T.TangentVector)
) {
  fatalError()
}

Before:

$ swift test.swift
test.swift:9:17: error: could not find function 'invalid' with expected type '<T where T : Differentiable> (x: T) -> T'
@derivative(of: invalid)
                ^
test.swift:23:17: error: ambiguous reference to 'ambiguous' in '@derivative' attribute
@derivative(of: ambiguous)
                ^

After:

$ swift test.swift
test.swift:9:17: error: referenced declaration 'invalid' could not be resolved
@derivative(of: invalid)
                ^
test.swift:5:6: note: candidate global function does not have type equal to or less constrained than '<T where T : Differentiable> (x: T) -> T'
func invalid<T: BinaryFloatingPoint>(x: T) -> T { x }
     ^
test.swift:6:6: note: candidate global function does not have type equal to or less constrained than '<T where T : Differentiable> (x: T) -> T'
func invalid<T: CustomStringConvertible>(x: T) -> T { x }
     ^
test.swift:7:6: note: candidate global function does not have type equal to or less constrained than '<T where T : Differentiable> (x: T) -> T'
func invalid<T: FloatingPoint>(x: T) -> T { x }
     ^
test.swift:23:17: error: referenced declaration 'ambiguous' is ambiguous
@derivative(of: ambiguous)
                ^
test.swift:20:6: note: candidate global function found here
func ambiguous<T: P1>(_ x: T) -> T { x }
     ^
test.swift:21:6: note: candidate global function found here
func ambiguous<T: P2>(_ x: T) -> T { x }
     ^

@dan-zheng dan-zheng requested review from rxwei, marcrasi and ematejska July 6, 2020 06:57
@dan-zheng
Copy link
Contributor Author

@swift-ci Please smoke test

Comment on lines +476 to 477
// expected-note @+1 {{candidate initializer does not have type equal to or less constrained than '<T where T : Differentiable, T == T.TangentVector> (Struct<T>) -> (Float) -> Struct<T>'}}
struct Struct<T> {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this diagnostic note appears for a compiler-synthesized struct memberwise initializer, which isn't explicit in source code. I think the note is pretty clear, it's emitted on the struct declaration and includes candidate *initializer*.

Comment on lines +557 to 558
// expected-note @+1 {{candidate getter does not have expected type '(StoredProperty) -> () -> StoredProperty'}}
var stored: Float
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: it's nice that this note mentions candidate *getter* does not have expected type ... instead of just candidate does not have expected type ..., so that it clearly refers to the stored property getter's type, not the stored property's type.

Improve `@derivative` and `@transpose` type-checking diagnostics for resolving
the referenced original declaration.

Previously, an error was produced on one invalid candidate at the attribute's
location. This did not indicate the invalid candidate's location or the total
number of invalid candidates.

Now:
- Diagnostic notes are produced on all invalid candidates at their location.
  Invalid candidates' descriptive declaration kind are shown for clarity.
- Derivative registration for protocol requirements (not yet supported, TF-982)
  now has a clear, dedicated diagnostic.
- The "original declaration type mismatch" diagnostic is improved for expected
  original function types with generic signatures. The message now accurately
  reads "candidate does not have type equal to *or less constrained than* ...",
  instead of "candidate does not have expected type ...".

Resolves SR-13150.
Paves the way for future diagnostic improvements: SR-13151, SR-13152.
@dan-zheng dan-zheng force-pushed the autodiff-type-checking-diagnostics branch from c5ca14e to 06b05c5 Compare July 6, 2020 11:42
@dan-zheng
Copy link
Contributor Author

@swift-ci Please smoke test

@dan-zheng dan-zheng merged commit c7cd497 into swiftlang:master Jul 6, 2020
@dan-zheng dan-zheng deleted the autodiff-type-checking-diagnostics branch July 6, 2020 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants