Skip to content

Commit 3d7b7bd

Browse files
authored
Merge pull request #19233 from AnthonyLatsis/same-type-constr-commutativity
[SR-8239][Parse] Fix same-type constraint commutativity
2 parents 864167f + e78a42b commit 3d7b7bd

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

lib/Parse/ParseGeneric.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,9 @@ ParserStatus Parser::parseGenericWhereClause(
275275
bool HasNextReq;
276276
do {
277277
SyntaxParsingContext ReqContext(SyntaxContext, SyntaxContextKind::Syntax);
278-
// Parse the leading type-identifier.
279-
ParserResult<TypeRepr> FirstType = parseTypeIdentifier();
278+
// Parse the leading type. It doesn't necessarily have to be just a type
279+
// identifier if we're dealing with a same-type constraint.
280+
ParserResult<TypeRepr> FirstType = parseType();
280281

281282
if (FirstType.hasCodeCompletion()) {
282283
Status.setHasCodeCompletion();

test/Constraints/same_types.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,29 @@ func test9<T: P6, U: P6>(_ t: T, u: U)
281281

282282
// FIXME: Remove -verify-ignore-unknown.
283283
// <unknown>:0: error: unexpected error produced: generic parameter τ_0_0.Bar.Foo cannot be equal to both 'Y.Foo' (aka 'X') and 'Z'
284+
285+
func testMetatypeSameType<T, U>(_ t: T, _ u: U)
286+
where T.Type == U.Type { }
287+
// expected-error@-1{{same-type requirement makes generic parameters 'T' and 'U' equivalent}}
288+
289+
func testSameTypeCommutativity1<U, T>(_ t: T, _ u: U)
290+
where T.Type == U { } // Equivalent to U == T.Type
291+
// expected-error@-1{{same-type requirement makes generic parameter 'U' non-generic}}
292+
293+
func testSameTypeCommutativity2<U, T: P1>(_ t: T, _ u: U)
294+
where U? == T.Assoc { } // Ok, equivalent to T.Assoc == U?
295+
296+
func testSameTypeCommutativity3<U, T: P1>(_ t: T, _ u: U)
297+
where (U) -> () == T.Assoc { } // Ok, equivalent to T.Assoc == (U) -> ()
298+
299+
func testSameTypeCommutativity4<U, T>(_ t: T, _ u: U)
300+
where (U) -> () == T { } // Equivalent to T == (U) -> ()
301+
// expected-error@-1{{same-type requirement makes generic parameter 'T' non-generic}}
302+
303+
func testSameTypeCommutativity5<U, T: P1>(_ t: T, _ u: U)
304+
where P1 & P2 == T.Assoc { } // Ok, equivalent to T.Assoc == P1 & P2
305+
306+
// FIXME: Error emitted twice.
307+
func testSameTypeCommutativity6<U, T: P1>(_ t: T, _ u: U)
308+
where U & P2 == T.Assoc { } // Equivalent to T.Assoc == U & P2
309+
// expected-error@-1 2 {{non-protocol, non-class type 'U' cannot be used within a protocol-constrained type}}

test/Generics/function_defs.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,5 +295,23 @@ func badTypeConformance1<T>(_: T) where Int : EqualComparable {} // expected-err
295295

296296
func badTypeConformance2<T>(_: T) where T.Blarg : EqualComparable { } // expected-error{{'Blarg' is not a member type of 'T'}}
297297

298+
func badTypeConformance3<T>(_: T) where (T) -> () : EqualComparable { }
299+
// expected-error@-1{{type '(T) -> ()' in conformance requirement does not refer to a generic parameter or associated type}}
300+
301+
func badTypeConformance4<T>(_: T) where @escaping (inout T) throws -> () : EqualComparable { }
302+
// expected-error@-1{{type '(inout T) throws -> ()' in conformance requirement does not refer to a generic parameter or associated type}}
303+
// expected-error@-2 2 {{@escaping attribute may only be used in function parameter position}}
304+
305+
// FIXME: Error emitted twice.
306+
func badTypeConformance5<T>(_: T) where T & Sequence : EqualComparable { }
307+
// expected-error@-1 2 {{non-protocol, non-class type 'T' cannot be used within a protocol-constrained type}}
308+
// expected-error@-2{{type 'Sequence' in conformance requirement does not refer to a generic parameter or associated type}}
309+
310+
func badTypeConformance6<T>(_: T) where [T] : Collection { }
311+
// expected-error@-1{{type '[T]' in conformance requirement does not refer to a generic parameter or associated type}}
312+
313+
func badTypeConformance7<T, U>(_: T, _: U) where T? : U { }
314+
// expected-error@-1{{type 'T?' constrained to non-protocol, non-class type 'U'}}
315+
298316
func badSameType<T, U : GeneratesAnElement, V>(_ : T, _ : U)
299317
where T == U.Element, U.Element == V {} // expected-error{{same-type requirement makes generic parameters 'T' and 'V' equivalent}}

test/attr/attr_specialize.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public func requirementOnNonGenericFunction(x: Int, y: Int) {
102102
public func missingRequirement<X:P, Y>(x: X, y: Y) {
103103
}
104104

105-
@_specialize(where) // expected-error{{expected identifier for type name}}
105+
@_specialize(where) // expected-error{{expected type}}
106106
@_specialize() // expected-error{{expected a parameter label or a where clause in '_specialize' attribute}} expected-error{{expected declaration}}
107107
public func funcWithEmptySpecializeAttr<X: P, Y>(x: X, y: Y) {
108108
}

0 commit comments

Comments
 (0)