Wrong "Redundant conformance constraint" warning

Ok, sorry for assuming otherwise, I'm just surprised that setting the flag to 'on' would break your code since the default setting for now is 'verify' which runs both the old and new generics implementation.

Anyway, in case it helps I kicked off a build toolchain job on this PR: RequirementMachine: Enable loop normalization by default by slavapestov · Pull Request #41975 · apple/swift · GitHub It will produce a toolchain with the latest code from main + the performance flag enabled by default.

1 Like

I just retried a build with -Xfrontend -requirement-machine-protocol-signatures=on and -Xfrontend -enable-requirement-machine-loop-normalization, I still get Abort trap: 6.

Where can I share the build log? On a GitHub gist?

A gist is fine, thanks.

Note: @Slava_Pestov The code has changed quite a lot since you tried it, do you want me to push my changes?

1 Like

Yes, if you can do that I’ll reproduce locally. Does it build with just -Xfrontend -enable-requirement-machine-loop-normalization but not the other two flags?

I'll have a try

However I get Abort trap: 6 as soon as I use "-Xfrontend", "-requirement-machine-protocol-signatures=on"

With -Xfrontend -enable-requirement-machine-loop-normalization, it builds, but it took 227s just to build my GeoModels target :confused:

Ah, I remembered the March 22nd snapshot doesn't have a performance fix I landed yesterday.

Can you push your latest code so I can reproduce the abort trap 6 in diagnostics?

Yes, I was pushing it

Should I download the latest toolchain?

I have a fix for the diagnostics crash and your project now builds. I'll create a PR soon.

1 Like

Thank you sooo much :heart: I'll have a look ASAP

Here is a fix for the diagnostics crash: RequirementMachine: Fix request evaluator cycle if a typealias requirement becomes redundant by slavapestov · Pull Request #42043 · apple/swift · GitHub.

I reduced the core set of protocols from the updated version of swift-geo you checked in to play around with.

public protocol NonEmptyProtocol: Collection
  where Element == C.Element,
        Index == C.Index {
  associatedtype C: Collection
}

public protocol MultiPoint {
  associatedtype C: CoordinateSystem
  typealias P = Self.C.P

  associatedtype X: NonEmptyProtocol
    where X.C: NonEmptyProtocol,
          X.Element == Self.P 
}

public protocol CoordinateSystem {
  associatedtype P: Point where Self.P.C == Self
  associatedtype S: Size where Self.S.C == Self
  associatedtype L: Line where Self.L.C == Self
  associatedtype B: BoundingBox where Self.B.C == Self
}

public protocol Line: MultiPoint {}

public protocol Size {
  associatedtype C: CoordinateSystem where Self.C.S == Self
}

public protocol BoundingBox {
  associatedtype C: CoordinateSystem
  typealias P = Self.C.P
  typealias S = Self.C.S
}

public protocol Point { 
  associatedtype C: CoordinateSystem where Self.C.P == Self
}

Swift 5.6 typechecks this file in 13 seconds on my machine. With the requirement machine flags enabled, a compiler built from main takes less than 50 milliseconds.

However, the requirement machine produces a bogus diagnostic:

reduced.swift:11:13: warning: redundant same-type constraint 'Self.P' == 'Self.C.P'
  typealias P = Self.C.P
            ^

Removing the typealias breaks the code, so this requirement is not really redundant. We're back to where we started ;-) We'll have a fix soon.

However, to close the loop on the original problem: with the latest fixes on main, your first version of swift-geo where Point is an associated type of MultiPoint seems to build correctly, and it is slightly faster than 5.6. The requirement machine diagnoses the redundant 'Point : GeoModels.Point' conformance, just like 5.6, however after removing it, everything still works correctly.

Thank you for reporting the original problem and for testing the developer snapshots; your code is really pushing the limits of the generics system, and it has directly helped improve the compiler as a result.

2 Likes

Looking at the requirement signatures in 5.6 vs main:

Requirement signature: <Self where Self : Collection, Self.C : Collection, Self.Element == Self.C.Element, Self.Index == Self.C.Index>
Requirement signature: <Self where Self.C : CoordinateSystem, Self.X : NonEmptyProtocol, Self.C.B == Self.C.B.C.B.C.B, Self.X.C : NonEmptyProtocol, Self.C.B.C.B.C.B == Self.C.P.C.B.C.B, Self.C.P.C.B.C.B == Self.C.S.C.B.C.B, Self.C.S.C.B.C.B == Self.C.B.C.P.C.B.C.B, Self.C.B.C.P.C.B.C.B == Self.C.P.C.S.C.B.C.B, Self.C.P.C.S.C.B.C.B == Self.C.S.C.P.C.B.C.B>
Requirement signature: <Self where Self == Self.B.C, Self.B : BoundingBox, Self.L : Line, Self.P : Point, Self.S : Size, Self.B.C == Self.L.C, Self.L.C == Self.P.C, Self.P.C == Self.S.C, Self.L.X.Indices == Self.L.X.Indices.SubSequence, Self.L.X.SubSequence == Self.L.X.SubSequence.SubSequence, Self.L.X.C.Indices == Self.L.X.C.Indices.SubSequence, Self.L.X.C.SubSequence == Self.L.X.C.SubSequence.SubSequence, Self.L.X.Indices.Indices == Self.L.X.Indices.Indices.SubSequence, Self.L.X.SubSequence.Indices == Self.L.X.SubSequence.Indices.SubSequence, Self.L.X.C.C.Indices == Self.L.X.C.C.Indices.SubSequence, Self.L.X.C.C.SubSequence == Self.L.X.C.C.SubSequence.SubSequence, Self.L.X.C.Indices.Indices == Self.L.X.C.Indices.Indices.SubSequence, Self.L.X.C.SubSequence.Indices == Self.L.X.C.SubSequence.Indices.SubSequence, Self.L.X.SubSequence.Indices.Indices == Self.L.X.SubSequence.Indices.Indices.SubSequence, Self.L.X.C.C.Indices.Indices == Self.L.X.C.C.Indices.Indices.SubSequence, Self.L.X.C.C.SubSequence.Indices == Self.L.X.C.C.SubSequence.Indices.SubSequence, Self.L.X.C.SubSequence.Indices.Indices == Self.L.X.C.SubSequence.Indices.Indices.SubSequence, Self.L.X.C.C.SubSequence.Indices.Indices == Self.L.X.C.C.SubSequence.Indices.Indices.SubSequence>
Requirement signature: <Self where Self : MultiPoint>
Requirement signature: <Self where Self == Self.C.S, Self.C : CoordinateSystem, Self.C.L.X.Indices == Self.C.L.X.Indices.SubSequence, Self.C.L.X.SubSequence == Self.C.L.X.SubSequence.SubSequence, Self.C.L.X.C.Indices == Self.C.L.X.C.Indices.SubSequence, Self.C.L.X.C.SubSequence == Self.C.L.X.C.SubSequence.SubSequence, Self.C.L.X.Indices.Indices == Self.C.L.X.Indices.Indices.SubSequence, Self.C.L.X.SubSequence.Indices == Self.C.L.X.SubSequence.Indices.SubSequence, Self.C.L.X.C.C.Indices == Self.C.L.X.C.C.Indices.SubSequence, Self.C.L.X.C.C.SubSequence == Self.C.L.X.C.C.SubSequence.SubSequence, Self.C.L.X.C.Indices.Indices == Self.C.L.X.C.Indices.Indices.SubSequence, Self.C.L.X.C.SubSequence.Indices == Self.C.L.X.C.SubSequence.Indices.SubSequence, Self.C.L.X.SubSequence.Indices.Indices == Self.C.L.X.SubSequence.Indices.Indices.SubSequence, Self.C.L.X.C.C.Indices.Indices == Self.C.L.X.C.C.Indices.Indices.SubSequence, Self.C.L.X.C.C.SubSequence.Indices == Self.C.L.X.C.C.SubSequence.Indices.SubSequence, Self.C.L.X.C.SubSequence.Indices.Indices == Self.C.L.X.C.SubSequence.Indices.Indices.SubSequence, Self.C.L.X.C.C.SubSequence.Indices.Indices == Self.C.L.X.C.C.SubSequence.Indices.Indices.SubSequence>
Requirement signature: <Self where Self.C : CoordinateSystem>
Requirement signature: <Self where Self == Self.C.P, Self.C : CoordinateSystem, Self.C.L.X.Indices == Self.C.L.X.Indices.SubSequence, Self.C.L.X.SubSequence == Self.C.L.X.SubSequence.SubSequence, Self.C.L.X.C.Indices == Self.C.L.X.C.Indices.SubSequence, Self.C.L.X.C.SubSequence == Self.C.L.X.C.SubSequence.SubSequence, Self.C.L.X.Indices.Indices == Self.C.L.X.Indices.Indices.SubSequence, Self.C.L.X.SubSequence.Indices == Self.C.L.X.SubSequence.Indices.SubSequence, Self.C.L.X.C.C.Indices == Self.C.L.X.C.C.Indices.SubSequence, Self.C.L.X.C.C.SubSequence == Self.C.L.X.C.C.SubSequence.SubSequence, Self.C.L.X.C.Indices.Indices == Self.C.L.X.C.Indices.Indices.SubSequence, Self.C.L.X.C.SubSequence.Indices == Self.C.L.X.C.SubSequence.Indices.SubSequence, Self.C.L.X.SubSequence.Indices.Indices == Self.C.L.X.SubSequence.Indices.Indices.SubSequence, Self.C.L.X.C.C.Indices.Indices == Self.C.L.X.C.C.Indices.Indices.SubSequence, Self.C.L.X.C.C.SubSequence.Indices == Self.C.L.X.C.C.SubSequence.Indices.SubSequence, Self.C.L.X.C.SubSequence.Indices.Indices == Self.C.L.X.C.SubSequence.Indices.Indices.SubSequence, Self.C.L.X.C.C.SubSequence.Indices.Indices == Self.C.L.X.C.C.SubSequence.Indices.Indices.SubSequence>
Requirement signature: <Self where Self : Collection, Self.[NonEmptyProtocol]C : Collection, Self.[Sequence]Element == Self.[NonEmptyProtocol]C.[Sequence]Element, Self.[Collection]Index == Self.[NonEmptyProtocol]C.[Collection]Index>
Requirement signature: <Self where Self.[MultiPoint]C : CoordinateSystem, Self.[MultiPoint]X : NonEmptyProtocol, Self.[MultiPoint]C.[CoordinateSystem]P == Self.[MultiPoint]X.[Sequence]Element, Self.[MultiPoint]X.[NonEmptyProtocol]C : NonEmptyProtocol>
Requirement signature: <Self where Self == Self.[CoordinateSystem]B.[BoundingBox]C, Self.[CoordinateSystem]B : BoundingBox, Self.[CoordinateSystem]L : Line, Self.[CoordinateSystem]P : Point, Self.[CoordinateSystem]S : Size, Self.[CoordinateSystem]B.[BoundingBox]C == Self.[CoordinateSystem]L.[MultiPoint]C, Self.[CoordinateSystem]L.[MultiPoint]C == Self.[CoordinateSystem]P.[Point]C, Self.[CoordinateSystem]P.[Point]C == Self.[CoordinateSystem]S.[Size]C>
Requirement signature: <Self where Self : MultiPoint>
Requirement signature: <Self where Self == Self.[Size]C.[CoordinateSystem]S, Self.[Size]C : CoordinateSystem>
Requirement signature: <Self where Self.[BoundingBox]C : CoordinateSystem>
Requirement signature: <Self where Self == Self.[Point]C.[CoordinateSystem]P, Self.[Point]C : CoordinateSystem>

The GenericSignatureBuilder's version of MultiPoint, besides having some redundant requirements, is also missing the requirement 'C.P == X.Element' (in your original source this corresponds to 'Self.CoordinateSystem.Point == Points.Element'). Indeed, the 5.6 compiler cannot derive the equivalence:

func sameType<T>(_: T, _: T) {}

func foo<T : MultiPoint>(_: T) {
  sameType(T.C.P.self, T.X.Element.self)
}
reduced.swift:42:3: error: conflicting arguments to generic parameter 'T' ('T.C.P.Type' vs. 'T.X.Element.Type')
  sameType(T.C.P.self, T.X.Element.self)
  ^
1 Like

Thank you very much @Slava_Pestov :pray:t2:

I don't see a new toolchain on Swift.org - Download Swift, how can I use the latest fixes?

I don't know when the nightly toolchain will be built, so I'm building the toolchain locally.

For those interested to do the same, instructions are available at https://github.com/apple/swift/blob/main/docs/HowToGuides/GettingStarted.md.

1 Like

A toolchain was released for March 30, 2022, I just dowloaded it, and it works :tada:

Thank you so much @Slava_Pestov :pray:t2:

(For some reason, I couldn't use the toolchain I built locally in Xcode, so I was waiting for the official nightly build.)

1 Like

Great to hear. I think we had a few flaky tests in CI that were preventing a toolchain from being released for that week, sorry about that.

Oh, that's why it wasn't available. I saw you requested a toolchain build, but I was starting to think it's a veeerrryyy long process seing the time it took to make it available :upside_down_face:

On a worse note, I said

but I tried compiling my package swift-geo and the GeoModels target clean compiles in 245s… I think there might still be an issue.

I'll try with the different flags you recommended me, to see if it changes something. I'll write down the build times.

Edit: With the previous flags it doesn't compile, I suppose you removed them. Here is the build log: swift-geo build log - Very slow · GitHub. Tell me if you need me to push the current commit.

I removed the -enable-requirement-machine-loop-normalization flag because it is now the default.

1 Like