diff --git a/lib/Sema/CSSyntacticElement.cpp b/lib/Sema/CSSyntacticElement.cpp index 5fc06c2135c51..ae1c58b3c8135 100644 --- a/lib/Sema/CSSyntacticElement.cpp +++ b/lib/Sema/CSSyntacticElement.cpp @@ -211,6 +211,14 @@ class TypeVariableRefFinder : public ASTWalker { return; } + // Desugar type before collecting type variables, otherwise + // we can bring in scope unrelated type variables passed + // into the closure (via parameter/result) from contextual type. + // For example `Typealias<$T, $U>.Context` which desugars into + // `_Context<$U>` would bring in `$T` that could be inferrable + // only after the body of the closure is solved. + type = type->getDesugaredType(); + // Don't walk into the opaque archetypes because they are not // transparent in this context - `some P` could reference a // type variables as substitutions which are visible only to diff --git a/validation-test/Sema/SwiftUI/rdar107835060.swift b/validation-test/Sema/SwiftUI/rdar107835060.swift new file mode 100644 index 0000000000000..022d6a52896bd --- /dev/null +++ b/validation-test/Sema/SwiftUI/rdar107835060.swift @@ -0,0 +1,51 @@ +// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5 -disable-availability-checking + +// REQUIRES: objc_interop +// REQUIRES: OS=macosx + +import SwiftUI + +protocol Model { + associatedtype ReturnType +} + +struct AnyModel: Model { +} + +protocol ContentProtocol : View { + associatedtype _Context +} + +struct CollectionContext { + let offset: Data.Index +} + +struct ContinuousContent : ContentProtocol + where Data.Element: Model, Data.Element.ReturnType: Sequence, Data.Index: Hashable { + + typealias _Context = CollectionContext + + var body: some View { EmptyView() } +} + +struct TestView : View { + typealias Context = Content._Context where Content: ContentProtocol + + init(_ data: Data, + @ViewBuilder shelfContent: @escaping (Context) -> C) + where Data.Element == any Model, + Content == ContinuousContent>, C> { + } + + var body: some View { EmptyView() } +} + +@ViewBuilder +func test(values: [any Model<[Int]>]) -> some View { + TestView(values) { context in + VStack { + if context.offset == 0 { + } + } + } +}