Files
swift-mirror/test/Constraints/variadic_generic_constraints.swift
Hamish Knight 5c3f6703a0 Remove diag::type_of_expression_is_ambiguous
This is a diagnostic that is only really emitted as a fallback when
the constraint system isn't able to better diagnose the expression.
It's not particulary helpful for the user, and can be often be
misleading since the underlying issue might not actually be an
ambiguity, and the user may well already have a type annotation. Let's
instead just emit the fallback diagnostic that we emit in all other
cases, asking the user to file a bug.
2025-08-19 17:14:23 +01:00

105 lines
3.6 KiB
Swift

// RUN: %target-typecheck-verify-swift
// Test instantiation of constraint solver constraints from generic requirements
// involving type pack parameters
// Conformance requirements
protocol P {}
func takesP<each T: P>(_: repeat each T) {} // expected-note {{where 'each T' = 'DoesNotConformToP'}}
struct ConformsToP: P {}
struct DoesNotConformToP {}
takesP() // ok
takesP(ConformsToP(), ConformsToP(), ConformsToP()) // ok
takesP(ConformsToP(), DoesNotConformToP(), ConformsToP()) // expected-error {{global function 'takesP' requires that 'DoesNotConformToP' conform to 'P'}}
// Superclass requirements
class C {}
class SubclassOfC: C {}
class NotSubclassOfC {}
func takesC<each T: C>(_: repeat each T) {} // expected-note {{where 'each T' = 'NotSubclassOfC'}}
takesC() // ok
takesC(SubclassOfC(), SubclassOfC(), SubclassOfC()) // ok
takesC(SubclassOfC(), NotSubclassOfC(), SubclassOfC()) // expected-error {{global function 'takesC' requires that 'NotSubclassOfC' inherit from 'C'}}
// Layout requirements
struct S {}
func takesAnyObject<each T: AnyObject>(_: repeat each T) {}
takesAnyObject()
takesAnyObject(C(), C(), C())
// FIXME: Bad diagnostic
takesAnyObject(C(), S(), C()) // expected-error {{failed to produce diagnostic for expression}}
// Same-type requirements
// expected-note@+1 {{where '(each T).Element' = 'String', '(each U).Element' = 'Int'}}
func takesParallelSequences<each T, each U>(t: repeat each T, u: repeat each U)
where repeat each T: Sequence,
repeat each U: Sequence,
repeat (each T).Element == (each U).Element {}
takesParallelSequences() // ok
takesParallelSequences(t: Array<Int>(), u: Set<Int>()) // ok
takesParallelSequences(t: Array<String>(), Set<Int>(), u: Set<String>(), Array<Int>()) // ok
takesParallelSequences(t: Array<String>(), Set<Int>(), u: Array<Int>(), Set<String>()) // expected-error {{global function 'takesParallelSequences(t:u:)' requires the types 'String' and 'Int' be equivalent}}
// Same-shape requirements
func zip<each T, each U>(t: repeat each T, u: repeat each U) -> (repeat (each T, each U)) {}
// expected-note@-1 {{'zip(t:u:)' declared here}}
let _ = zip() // ok
let _ = zip(t: 1, u: "hi") // ok
let _ = zip(t: 1, 2, u: "hi", "hello") // ok
let _ = zip(t: 1, 2, 3, u: "hi", "hello", "greetings") // ok
let _ = zip(t: 1, u: "hi", "hello", "greetings") // expected-error {{extra arguments at positions #3, #4 in call}}
// expected-error@-1 {{global function 'zip(t:u:)' requires the type packs 'Int' and 'String, String, String' have the same shape}}
func goodCallToZip<each T, each U>(t: repeat each T, u: repeat each U) where (repeat (each T, each U)): Any {
_ = zip(t: repeat each t, u: repeat each u)
}
func badCallToZip<each T, each U>(t: repeat each T, u: repeat each U) {
_ = zip(t: repeat each t, u: repeat each u)
// expected-error@-1 {{global function 'zip(t:u:)' requires the type packs 'each T' and 'each U' have the same shape}}
// expected-error@-2 {{pack expansion requires that 'each U' and 'each T' have the same shape}}
}
func variadicGenericsInOptionalContext(v: Int?) {
func test1<A, B, each C>(
_: A,
_: B,
_: repeat each C
) throws -> (A, B, repeat each C) {
fatalError()
}
func test2<A, B, each C>(
_: A,
_: B,
_: (repeat each C)
) throws -> (A, B, repeat each C) {
fatalError()
}
func test() {
guard let _ = try? test1(1, 2, 3) else { return } // Ok
guard let _ = try? test1(1, 2, v) else { return } // Ok
guard let _ = try? test2(1, 2, 3) else { return } // Ok
guard let _ = try? test2(1, 2, v) else { return } // Ok
}
}