Skip to content

Commit 0a083b1

Browse files
Merge pull request #65997 from nate-chandler/cherrypick/release/5.9/rdar108963047
5.9: [RequirementMachine] InferredGenericSignatureRequest uses valid location for generic signature requirements.
2 parents 14305ef + 21e7a31 commit 0a083b1

16 files changed

+127
-70
lines changed

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,29 @@ InferredGenericSignatureRequest::evaluate(
748748

749749
SmallVector<StructuralRequirement, 4> requirements;
750750
SmallVector<RequirementError, 4> errors;
751+
752+
SourceLoc loc = [&]() {
753+
if (genericParamList) {
754+
auto loc = genericParamList->getLAngleLoc();
755+
if (loc.isValid())
756+
return loc;
757+
}
758+
if (whereClause) {
759+
auto loc = whereClause.getLoc();
760+
if (loc.isValid())
761+
return loc;
762+
}
763+
for (auto sourcePair : inferenceSources) {
764+
auto *typeRepr = sourcePair.getTypeRepr();
765+
auto loc = typeRepr ? typeRepr->getStartLoc() : SourceLoc();
766+
if (loc.isValid())
767+
return loc;
768+
}
769+
return SourceLoc();
770+
}();
771+
751772
for (const auto &req : parentSig.getRequirements())
752-
requirements.push_back({req, SourceLoc(), /*wasInferred=*/false});
773+
requirements.push_back({req, loc, /*wasInferred=*/false});
753774

754775
DeclContext *lookupDC = nullptr;
755776

@@ -760,10 +781,7 @@ InferredGenericSignatureRequest::evaluate(
760781
return false;
761782
};
762783

763-
SourceLoc loc;
764784
if (genericParamList) {
765-
loc = genericParamList->getLAngleLoc();
766-
767785
// Extensions never have a parent signature.
768786
assert(genericParamList->getOuterParameters() == nullptr || !parentSig);
769787

@@ -810,9 +828,6 @@ InferredGenericSignatureRequest::evaluate(
810828
if (whereClause) {
811829
lookupDC = whereClause.dc;
812830

813-
if (loc.isInvalid())
814-
loc = whereClause.getLoc();
815-
816831
std::move(whereClause).visitRequirements(
817832
TypeResolutionStage::Structural,
818833
visitRequirement);
@@ -825,8 +840,6 @@ InferredGenericSignatureRequest::evaluate(
825840
for (auto sourcePair : inferenceSources) {
826841
auto *typeRepr = sourcePair.getTypeRepr();
827842
auto typeLoc = typeRepr ? typeRepr->getStartLoc() : SourceLoc();
828-
if (loc.isInvalid())
829-
loc = typeLoc;
830843

831844
inferRequirements(sourcePair.getType(), typeLoc, moduleForInference,
832845
lookupDC, requirements);

test/AutoDiff/SILOptimizer/generics.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ func foo<T>(_ x: Wrapper<T>) {
5252
// Test case where associated derivative function's requirements are met.
5353
extension Wrapper where Scalar : Numeric {
5454
@differentiable(reverse, wrt: self where Scalar : Differentiable & FloatingPoint) // expected-warning {{redundant conformance constraint 'Scalar' : 'Differentiable'}}
55+
// expected-warning@-1 {{redundant conformance constraint 'Scalar' : 'Numeric'}}
5556
func mean() -> Wrapper {
5657
return self
5758
}
5859

5960
@differentiable(reverse, wrt: self where Scalar : Differentiable & FloatingPoint) // expected-warning {{redundant conformance constraint 'Scalar' : 'Differentiable'}}
61+
// expected-warning@-1 {{redundant conformance constraint 'Scalar' : 'Numeric'}}
6062
func variance() -> Wrapper {
6163
return mean() // ok
6264
}
@@ -217,7 +219,7 @@ let _: @differentiable(reverse) (Float, Float) -> TF_546<Float> = { r, i in
217219
struct TF_652<Scalar> {}
218220
extension TF_652 : Differentiable where Scalar : FloatingPoint {}
219221

220-
@differentiable(reverse, wrt: x where Scalar: FloatingPoint)
222+
@differentiable(reverse, wrt: x where Scalar: FloatingPoint) // expected-warning {{redundant conformance constraint 'Scalar' : 'Numeric'}}
221223
func test<Scalar: Numeric>(x: TF_652<Scalar>) -> TF_652<Scalar> {
222224
for _ in 0..<10 {
223225
let _ = x
@@ -293,7 +295,7 @@ struct TF_697_Sequential<Layer1: TF_697_Module, Layer2: TF_697_Layer>: TF_697_Mo
293295
layer2.callLayer(layer1.callModule(input))
294296
}
295297
}
296-
extension TF_697_Sequential: TF_697_Layer where Layer1: TF_697_Layer {
298+
extension TF_697_Sequential: TF_697_Layer where Layer1: TF_697_Layer { // expected-warning {{redundant conformance constraint 'Layer1' : 'TF_697_Module'}}
297299
@differentiable(reverse)
298300
func callLayer(_ input: Layer1.Input) -> Layer2.Output {
299301
layer2.callLayer(layer1.callLayer(input))

test/Generics/concrete_contraction_unrelated_typealias.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class GenericDelegateProxy<P : AnyObject, D> {
2525

2626
// CHECK-LABEL: .GenericDelegateProxy.init(_:)@
2727
// CHECK-NEXT: <P, D, Proxy where P == Proxy.[DelegateProxyType]Parent, D == Proxy.[DelegateProxyType]Delegate, Proxy : GenericDelegateProxy<P, D>, Proxy : DelegateProxyType>
28-
init<Proxy: DelegateProxyType>(_: Proxy.Type)
28+
init<Proxy: DelegateProxyType>(_: Proxy.Type) // expected-warning {{redundant constraint 'P' : 'AnyObject'}}
2929
where Proxy: GenericDelegateProxy<P, D>,
3030
Proxy.Parent == P, // expected-warning {{redundant same-type constraint 'GenericDelegateProxy<P, D>.Parent' (aka 'P') == 'P'}}
3131
Proxy.Delegate == D {} // expected-warning {{redundant same-type constraint 'GenericDelegateProxy<P, D>.Delegate' (aka 'D') == 'D'}}

test/Generics/concrete_same_type_versus_anyobject.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extension G1 where T == S {}
1313

1414
// CHECK: ExtensionDecl line={{.*}} base=G1
1515
// CHECK-NEXT: Generic signature: <T where T == C>
16-
extension G1 where T == C {}
16+
extension G1 where T == C {} // expected-warning {{redundant constraint 'T' : 'AnyObject'}}
1717

1818
struct G2<U> {}
1919

test/Generics/conditional_conformances.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct OverlappingSub<T: P1> {}
6464
// CHECK-NEXT: (normal_conformance type=OverlappingSub<T> protocol=P2
6565
// CHECK-NEXT: conforms_to: T P4)
6666
extension OverlappingSub: P2 where T: P4 {} // expected-note {{requirement from conditional conformance of 'OverlappingSub<U>' to 'P2'}}
67+
// expected-warning@-1 {{redundant conformance constraint 'T' : 'P1'}}
6768
func overlapping_sub_good<U: P4>(_: U) {
6869
takes_P2(OverlappingSub<U>())
6970
}
@@ -175,6 +176,7 @@ struct ClassMoreSpecific<T: C1> {}
175176
// CHECK-NEXT: (normal_conformance type=ClassMoreSpecific<T> protocol=P2
176177
// CHECK-NEXT: superclass: T C3)
177178
extension ClassMoreSpecific: P2 where T: C3 {} // expected-note {{requirement from conditional conformance of 'ClassMoreSpecific<U>' to 'P2'}}
179+
// expected-warning@-1 {{redundant superclass constraint 'T' : 'C1'}}
178180
func class_more_specific_good<U: C3>(_: U) {
179181
takes_P2(ClassMoreSpecific<U>())
180182
}
@@ -343,7 +345,7 @@ struct RedundancyOrderDependenceBad<T, U: P1> {}
343345
// CHECK-NEXT: (normal_conformance type=RedundancyOrderDependenceBad<T, U> protocol=P2
344346
// CHECK-NEXT: conforms_to: T P1
345347
// CHECK-NEXT: same_type: T U)
346-
extension RedundancyOrderDependenceBad: P2 where T: P1, T == U {}
348+
extension RedundancyOrderDependenceBad: P2 where T: P1, T == U {} // expected-warning {{redundant conformance constraint 'U' : 'P1'}}
347349

348350
// Checking of conditional requirements for existential conversions.
349351
func existential_good<T: P1>(_: T.Type) {

test/Generics/derived_via_concrete.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,4 @@ struct G<X : Base, Y> {}
6363

6464
// CHECK-LABEL: ExtensionDecl line={{.*}} base=G
6565
// CHECK-NEXT: Generic signature: <X, Y where X == Derived<Y>, Y : C>
66-
extension G where X == Derived<Y> {}
66+
extension G where X == Derived<Y> {} // expected-warning {{redundant superclass constraint 'X' : 'Base'}}

test/Generics/issue-61192.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ struct G<A>: P {}
1111
struct Body<T: P> where T.A == C {
1212
// CHECK-LABEL: .init(_:)@
1313
// CHECK-NEXT: <T, U where T == G<C>, U : P, U.[P]A == C>
14-
init<U: P>(_: U) where T == G<T.A>, U.A == T.A {}
14+
init<U: P>(_: U) where T == G<T.A>, U.A == T.A {} // expected-warning {{redundant same-type constraint 'T.A' == 'C'}}
15+
// expected-warning@-1 {{redundant conformance constraint 'T' : 'P'}}
1516
}

test/Generics/rdar108963047.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol HasElt {
4+
associatedtype Element
5+
}
6+
struct IntElement : HasElt {
7+
typealias Element = Int
8+
}
9+
struct FloatElement : HasElt {
10+
typealias Element = Float
11+
}
12+
13+
struct G<T: HasElt> where T.Element == Float {
14+
func foo() where T == IntElement {} // expected-error {{generic signature requires types 'IntElement.Element' (aka 'Int') and 'Float' to be the same}}
15+
}

test/Generics/rdar75656022.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct UnresolvedWithConcreteBase<A, B> {
4545
// produces two warnings about redundant requirements.
4646
struct OriginalExampleWithWarning<A, B> where A : P2, B : P2, A.T == B.T {
4747
// CHECK-LABEL: Generic signature: <A, B, C, D, E where A == S1<C, E, S2<D>>, B : P2, C : P1, D == B.[P2]T, E == D.[P1]T, B.[P2]T == C.[P1]T>
48-
init<C, D, E>(_: C)
48+
init<C, D, E>(_: C) // expected-warning {{redundant conformance constraint 'S1<C, C.T.T, S2<C.T>>' : 'P2'}}
4949
where C : P1,
5050
D : P1, // expected-warning {{redundant conformance constraint 'D' : 'P1'}}
5151
C.T : P1, // expected-warning {{redundant conformance constraint 'C.T' : 'P1'}}
@@ -57,7 +57,7 @@ struct OriginalExampleWithWarning<A, B> where A : P2, B : P2, A.T == B.T {
5757
// Same as above but without the warnings.
5858
struct OriginalExampleWithoutWarning<A, B> where A : P2, B : P2, A.T == B.T {
5959
// CHECK-LABEL: Generic signature: <A, B, C, D, E where A == S1<C, E, S2<D>>, B : P2, C : P1, D == B.[P2]T, E == D.[P1]T, B.[P2]T == C.[P1]T>
60-
init<C, D, E>(_: C)
60+
init<C, D, E>(_: C) // expected-warning {{redundant conformance constraint 'S1<C, C.T.T, S2<C.T>>' : 'P2'}}
6161
where C : P1,
6262
A == S1<C, C.T.T, S2<C.T>>,
6363
C.T == D,
@@ -67,7 +67,7 @@ struct OriginalExampleWithoutWarning<A, B> where A : P2, B : P2, A.T == B.T {
6767
// Same as above but without unnecessary generic parameters.
6868
struct WithoutBogusGenericParametersWithWarning<A, B> where A : P2, B : P2, A.T == B.T {
6969
// CHECK-LABEL: Generic signature: <A, B, C where A == S1<C, B.[P2]T.[P1]T, S2<B.[P2]T>>, B : P2, C : P1, B.[P2]T == C.[P1]T>
70-
init<C>(_: C)
70+
init<C>(_: C) // expected-warning {{redundant conformance constraint 'S1<C, C.T.T, S2<C.T>>' : 'P2'}}
7171
where C : P1,
7272
C.T : P1, // expected-warning {{redundant conformance constraint 'C.T' : 'P1'}}
7373
A == S1<C, C.T.T, S2<C.T>> {}
@@ -77,7 +77,7 @@ struct WithoutBogusGenericParametersWithWarning<A, B> where A : P2, B : P2, A.T
7777
// or the warning.
7878
struct WithoutBogusGenericParametersWithoutWarning<A, B> where A : P2, B : P2, A.T == B.T {
7979
// CHECK-LABEL: Generic signature: <A, B, C where A == S1<C, B.[P2]T.[P1]T, S2<B.[P2]T>>, B : P2, C : P1, B.[P2]T == C.[P1]T>
80-
init<C>(_: C)
80+
init<C>(_: C) // expected-warning {{redundant conformance constraint 'S1<C, C.T.T, S2<C.T>>' : 'P2'}}
8181
where C : P1,
8282
A == S1<C, C.T.T, S2<C.T>> {}
8383
}

test/Generics/rdar77462797.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ class S<T : P> : Q {}
1111

1212
struct G<X, Y> where X : Q {
1313
// no redundancies
14-
func foo1() where X == S<Y> {}
14+
func foo1() where X == S<Y> {} // expected-warning {{redundant conformance constraint 'S<Y>' : 'Q'}}
1515
// CHECK: Generic signature: <X, Y where X == S<Y>, Y : P>
1616

1717
// 'Y : P' is redundant, but only via an inferred requirement from S<Y>,
1818
// so we should not diagnose it
19-
func foo2() where X == S<Y>, Y : P {}
19+
func foo2() where X == S<Y>, Y : P {} // expected-warning {{redundant conformance constraint 'S<Y>' : 'Q'}}
2020
// CHECK: Generic signature: <X, Y where X == S<Y>, Y : P>
2121

2222
// 'X : Q' is redundant
23-
func foo3() where X : Q, X == S<Y>, Y : P {}
23+
func foo3() where X : Q, X == S<Y>, Y : P {} // expected-warning {{redundant conformance constraint 'S<Y>' : 'Q'}}
2424
// expected-warning@-1 {{redundant conformance constraint 'S<Y>' : 'Q'}}
2525
// CHECK: Generic signature: <X, Y where X == S<Y>, Y : P>
2626

2727
// 'T.T : P' is redundant
28-
func foo4<T : Q>(_: T) where X == S<Y>, T.T : P {}
28+
func foo4<T : Q>(_: T) where X == S<Y>, T.T : P {} // expected-warning {{redundant conformance constraint 'S<Y>' : 'Q'}}
2929
// expected-warning@-1 {{redundant conformance constraint 'T.T' : 'P'}}
3030
// CHECK: Generic signature: <X, Y, T where X == S<Y>, Y : P, T : Q>
3131
}

0 commit comments

Comments
 (0)