Passing argument of non-sendable type 'LazyAsyncVariable<Int>' outside of actor-isolated context may introduce data races [non_sendable_call_argument]

I've crafted a class that encapsulates a variable that's lazily initialized via an async function. If overridden, the initializer task and result are discarded.

/// A wrapper for a mutable variable that is lazily initialized via an async function.
///
/// If [set] is called before or while the variable is being initialized, the initialization is
/// canceled and the new value is stored instead.
actor LazyAsyncVariable<T: Sendable> {
  private var state: State = .unset
  private let initializer: @Sendable () async -> T

  init(_ initializer: @escaping @Sendable () async -> T) {
    self.initializer = initializer
  }

  /// Returns the value, initializing it if necessary.
  func get() async -> T {
    if case .unset = state {
      state = .initializing(Task { [initializer] in await initializer() })
    }

    if case .initializing(let task) = state {
      state = .set(await task.value)
    }

    guard case .set(let value) = state else {
      fatalError("Impossible state")
    }

    return value
  }

  /// Sets the value, canceling the initialization if it is still in progress.
  func set(_ value: T) {
    if case .initializing(let task) = state {
      task.cancel()
    }

    self.state = .set(value)
  }

  private enum State {
    case unset
    case initializing(Task<T, Never>)
    case set(T)
  }
}

When using this class in an actor, I get a warning from the compiler. I'm not sure what to do about it:

actor MyActor {
  private var asyncVariableHolder: LazyAsyncVariable<Int>
  private func resetAsyncVariable() {
    asyncVariableHolder = LazyAsyncVariable<Int>({ return 1 })
  }
  var asyncVariable: Int {
    get async {
      await asyncVariableHolder.get()
        //  ------------------- <- warning is here
    }
  }
}

Here's the warning:

passing argument of non-sendable type 'LazyAsyncVariable' outside of actor-isolated context may introduce data races [non_sendable_call_argument]

I have no idea what to do with this. If I make LazyAsyncVariable an actor, the warning disappears. But I'm really not sure why it would need to be an actor. Any suggestions are welcome, as well as explanations. I really don't know why it's warning me here.

LazyAsyncVariable is a non-Sendable type with an async function. This is almost always a problem, and something that trips up many people. It has unprotected mutable state. I think making it an actor, which both protects its state and defines the isolation that the async methods will execute on is a great option.

But, there are other ways to do this, depending on what you are after. I wrote up a whole bunch of stuff on non-Sendable types that might be useful too: Non-Sendable types are cool too you know | massicotte.org

The issue where this error was added has a simpler example and some good discussion: Sendable checking hole when actors call non-mutating async methods on non-Sendable types · Issue #65315 · swiftlang/swift · GitHub