 }
 
 //===----------------------------------------------------------------------===//
-// Conversion to `@differentiable(linear)` (not yet supported)
-//===----------------------------------------------------------------------===//
-
-// expected-error @+1 {{conversion to '@differentiable(linear)' function type is not yet supported}}
-let _: @differentiable(linear) (Float) -> Float = { x in x }
-
-//===----------------------------------------------------------------------===//
-// Non-differentiable arguments and results
+// Global variables
+//===----------------------------------------------------------------------===//
+
+var global: Float = 3.0
+
+// expected-error @+2 {{function is not differentiable}}
+// expected-note @+2 {{when differentiating this function definition}}
+@differentiable(wrt: x)
+func testWriteToGlobalVariable(x: Float) -> Float {
+  // expected-note @+1 {{cannot differentiate writes to global variables}}
+  global = global + x
+  return global
+}
+
+//===----------------------------------------------------------------------===//
+// Class differentiation
+//===----------------------------------------------------------------------===//
+
+class Class : Differentiable {
+  @differentiable
+  var stored: Float = 1
+
+  @differentiable
+  func testRefElementAddr(_ x: Float) -> Float {
+    return stored * x
+  }
+
+  var nonDifferentiableStored: Float = 1
+
+  @differentiable
+  func testNonDifferentiableRefElementAddr(_ x: Float) -> Float {
+    // expected-error @+2 {{expression is not differentiable}}
+    // expected-note @+1 {{member is not differentiable because the corresponding class member is not '@differentiable'}}
+    return nonDifferentiableStored * x
+  }
+
+  @differentiable
+  func method(_ x: Float) -> Float { x }
+
+  @differentiable
+  static func testClassMethod(x: Float) -> Float {
+    return Class().method(x)
+  }
+
+  func nonDifferentiableMethod(_ x: Float) -> Float { x }
+
+  @differentiable
+  static func testDifferentiableClassMethod(x: Float) -> Float {
+    // expected-error @+2 {{expression is not differentiable}}
+    // expected-note @+1 {{member is not differentiable because the corresponding class member is not '@differentiable'}}
+    return Class().nonDifferentiableMethod(x)
+  }
+}
+
+// TF-676: Test differentiation of class method with multiple `@differentiable`
+// attributes.
+class ClassMethodMultipleDifferentiableAttribute : Differentiable {
+  @differentiable(wrt: (self, x))
+  @differentiable(wrt: x)
+  func f(_ x: Float) -> Float { x }
+}
+func testMultipleDiffAttrsClass<C: ClassMethodMultipleDifferentiableAttribute>(
+  _ c: C, _ x: Float
+) {
+  _ = gradient(at: c, x) { c, x in c.f(x) }
+  _ = gradient(at: x) { x in c.f(x) }
+}
+
+// TF-1149: Test class with loadable type but address-only `TangentVector` type.
+class C<T: Differentiable>: Differentiable {
+  // expected-error @+1 {{function is not differentiable}}
+  @differentiable
+  // expected-note @+2 {{when differentiating this function definition}}
+  // expected-note @+1 {{cannot yet differentiate value whose type 'C<T>' has a compile-time known size, but whose 'TangentVector' contains stored properties of unknown size; consider modifying 'C<τ_0_0>.TangentVector' to use fewer generic parameters in stored properties}}
+  var stored: T
+
+  init(_ stored: T) {
+    self.stored = stored
+  }
+
+  // expected-error @+1 {{function is not differentiable}}
+  @differentiable
+  // expected-note @+2 {{when differentiating this function definition}}
+  // expected-note @+1 {{cannot yet differentiate value whose type 'C<T>' has a compile-time known size, but whose 'TangentVector' contains stored properties of unknown size; consider modifying 'C<τ_0_0>.TangentVector' to use fewer generic parameters in stored properties}}
+  func method(_ x: T) -> T {
+    stored
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Enum differentiation
+//===----------------------------------------------------------------------===//
+
+// expected-error @+1 {{function is not differentiable}}
+@differentiable
+// expected-note @+1 {{when differentiating this function definition}}
+func usesOptionals(_ x: Float) -> Float {
+  // expected-note @+1 {{differentiating enum values is not yet supported}}
+  var maybe: Float? = 10
+  maybe = x
+  return maybe!
+}
+
+enum DirectEnum: Differentiable & AdditiveArithmetic {
+  case leaf(Float)
+
+  typealias TangentVector = Self
+
+  static var zero: Self { fatalError() }
+  static func +(_ lhs: Self, _ rhs: Self) -> Self { fatalError() }
+  static func -(_ lhs: Self, _ rhs: Self) -> Self { fatalError() }
+}
+
+// expected-error @+1 {{function is not differentiable}}
+@differentiable(wrt: e)
+// expected-note @+2 {{when differentiating this function definition}}
+// expected-note @+1 {{differentiating enum values is not yet supported}}
+func enum_active(_ e: DirectEnum, _ x: Float) -> Float {
+  switch e {
+  case let .leaf(y): return y
+  }
+}
+
+// expected-error @+1 {{function is not differentiable}}
+@differentiable(wrt: e)
+// expected-note @+2 {{when differentiating this function definition}}
+// expected-note @+1 {{differentiating enum values is not yet supported}}
+func activeEnumValue(_ e: DirectEnum, _ x: Float) -> Float {
+  switch e {
+  case let .leaf(y): return y
+  }
+}
+
+enum IndirectEnum<T: Differentiable>: Differentiable & AdditiveArithmetic {
+  case leaf(T)
+
+  typealias TangentVector = Self
+
+  static func ==(_ lhs: Self, _ rhs: Self) -> Bool { fatalError() }
+  static var zero: Self { fatalError() }
+  static func +(_ lhs: Self, _ rhs: Self) -> Self { fatalError() }
+  static func -(_ lhs: Self, _ rhs: Self) -> Self { fatalError() }
+}
+
+// expected-error @+1 {{function is not differentiable}}
+@differentiable(wrt: e)
+// expected-note @+2 {{when differentiating this function definition}}
+// expected-note @+1 {{differentiating enum values is not yet supported}}
+func activeEnumAddr(_ e: IndirectEnum<Float>, _ x: Float) -> Float {
+  switch e {
+  case let .leaf(y): return y
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Unmet derivative generic requirements
 //===----------------------------------------------------------------------===//
 
 @differentiable

  // expected-note @+1 {{member is not differentiable because the corresponding protocol requirement is not '@differentiable'}}
  return x + 1
}
_ = gradient(at: 1.0, in: generic)

// Test unmet generic requirements.


  }
}

protocol TF8_Proto : Differentiable {
  associatedtype Scalar
  @differentiable(wrt: (self, input))
  func applied(to input: Float) -> Float
}

struct TF8_Struct<Scalar> : TF8_Proto where Scalar : FloatingPoint & Differentiable {
  @noDerivative let bar: Scalar

  @differentiable(wrt: (self, input))
