Skip to content

InternalError: Expected root cause #7643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
tayloraswift opened this issue Jun 7, 2024 · 1 comment
Closed
1 task done

InternalError: Expected root cause #7643

tayloraswift opened this issue Jun 7, 2024 · 1 comment
Labels

Comments

@tayloraswift
Copy link
Member

tayloraswift commented Jun 7, 2024

Is it reproducible with SwiftPM command-line tools: swift build, swift test, swift package etc?

  • Confirmed reproduction steps with SwiftPM CLI.

Description

swift package resolve fails with an InternalError for this manifest:

// swift-tools-version: 5.10

import PackageDescription

let package = Package(
    name: "dependency-test",
    products: [],
    dependencies: [
        .package(url: "https://github.com/tayloraswift/swift-dom", .upToNextMinor(from: "1.0.1")),
        .package(url: "https://github.com/apple/swift-testing", .upToNextMinor(from: "0.9.0")),
        .package(url: "https://github.com/apple/swift-syntax", "510.0.1" ..< "601.0.0-pre"),
    ],
    targets: []
)
error: InternalError(description: "Internal error. Please file a bug at https://github.com/apple/swift-package-manager/issues with this info. Expected root cause {swift-dom[everything] 1.0.1, ¬swift-syntax[everything] 510.0.1..<601.0.0} to almost satisfy the current partial solution:\n * [Decision 0: dependency-test[everything] 1.0.0]\n * [Derivation: swift-syntax[everything] 510.0.1..<601.0.0-pre ← {dependency-test[everything] 1.0.0, ¬swift-syntax[everything] 510.0.1..<601.0.0-pre}]\n * [Derivation: swift-testing[everything] 0.9.0..<0.10.0 ← {dependency-test[everything] 1.0.0, ¬swift-testing[everything] 0.9.0..<0.10.0}]\n * [Derivation: swift-dom[everything] 1.0.1..<1.1.0 ← {dependency-test[everything] 1.0.0, ¬swift-dom[everything] 1.0.1..<1.1.0}]\n * [Derivation: ¬swift-dom[everything] 1.0.2..<1.1.0 ← {swift-dom[everything] 1.0.2..<1.1.0}]\n")

Swift Package Manager version/commit hash

$ swift package --version Swift Package Manager - Swift 5.10.0-dev

Swift & OS version (output of swift --version ; uname -a)

Swift version 5.10 (swift-5.10-RELEASE)
Target: x86_64-unknown-linux-gnu
Linux 832f7bfa3820 6.5.0-35-generic #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

xedin added a commit that referenced this issue Jul 19, 2024
…alid (#7799)

Pre-release decisions are valid if the derived range they were inferred
from supports pre-release versions.

### Motivation:

Currently, after deriving a pre-release assignment, the solver would
assert
in some circumstances depending on order in which the dependencies are
specified in the manifest.

This change makes it possible to infer pre-release verison of a package 
even when intermediate derivations did not support pre-release versions.

For example one package could declare `swift-syntax` dependency as
`508.0.1` ..< `601.0.0` and another could narrow it to `600.0.0-latest`
..< `601.0.0`.

Since the most constrained range in such case supports pre-releases a
decision
to use the lastest pre-release version of `600.0.0` should be valid if
there
is no `600.0.0` release yet.

It's important to note that on each path a decision for a package is
always
made based on the last undecided term's requirements which means -
based on the current semantics - if such derivation doesn't support
pre-release,
even though intermediate ones did, the solver would select a released
version.
This PR is not aim to change that.

There is a caveat which we cannot narrowly fix - if package depends on
an exact
pre-release version the inference is going to fail when there is another
dependency
to the same package that doesn't support pre-releases. For example:

Package `A` depends on packages `B` and `C` as follows:

`A` depends on `B` = `0.0.1-alpha` and `C` = `1.0.0`
`B` version `0.0.1-alpha` has no dependencies
`C` version `1.0.0` depends on `B` - `0.0.1` ..< `0.0.2`

In this situation the solver would fail because `0.0.1-alpha` does not
satisfy range - `0.0.1` ..< `0.0.2` inferred from `C`.

### Modifications:

- Delays version decisions for packages with pre-release ranges until
there are no more packages without pre-release versions. This also means
that if a previous decision narrows down the range to releases-only the
package would be made a contender on the next step of the solver.

- Relaxes the `isValidDecision` check for pre-release decisions but
makes sure that the last derivation supports pre-release versions.

### Result:

In situations like
#7658 and
#7643 the
solver would no longer assert and would produce a solution with a
pre-release version for `swift-syntax`.
xedin added a commit to xedin/swift-package-manager that referenced this issue Jul 22, 2024
…alid (swiftlang#7799)

Pre-release decisions are valid if the derived range they were inferred
from supports pre-release versions.

Currently, after deriving a pre-release assignment, the solver would
assert
in some circumstances depending on order in which the dependencies are
specified in the manifest.

This change makes it possible to infer pre-release verison of a package
even when intermediate derivations did not support pre-release versions.

For example one package could declare `swift-syntax` dependency as
`508.0.1` ..< `601.0.0` and another could narrow it to `600.0.0-latest`
..< `601.0.0`.

Since the most constrained range in such case supports pre-releases a
decision
to use the lastest pre-release version of `600.0.0` should be valid if
there
is no `600.0.0` release yet.

It's important to note that on each path a decision for a package is
always
made based on the last undecided term's requirements which means -
based on the current semantics - if such derivation doesn't support
pre-release,
even though intermediate ones did, the solver would select a released
version.
This PR is not aim to change that.

There is a caveat which we cannot narrowly fix - if package depends on
an exact
pre-release version the inference is going to fail when there is another
dependency
to the same package that doesn't support pre-releases. For example:

Package `A` depends on packages `B` and `C` as follows:

`A` depends on `B` = `0.0.1-alpha` and `C` = `1.0.0`
`B` version `0.0.1-alpha` has no dependencies
`C` version `1.0.0` depends on `B` - `0.0.1` ..< `0.0.2`

In this situation the solver would fail because `0.0.1-alpha` does not
satisfy range - `0.0.1` ..< `0.0.2` inferred from `C`.

- Delays version decisions for packages with pre-release ranges until
there are no more packages without pre-release versions. This also means
that if a previous decision narrows down the range to releases-only the
package would be made a contender on the next step of the solver.

- Relaxes the `isValidDecision` check for pre-release decisions but
makes sure that the last derivation supports pre-release versions.

In situations like
swiftlang#7658 and
swiftlang#7643 the
solver would no longer assert and would produce a solution with a
pre-release version for `swift-syntax`.

(cherry picked from commit 43fd240)
bnbarham pushed a commit that referenced this issue Jul 23, 2024
…alid (#7799)

Pre-release decisions are valid if the derived range they were inferred
from supports pre-release versions.

Currently, after deriving a pre-release assignment, the solver would
assert
in some circumstances depending on order in which the dependencies are
specified in the manifest.

This change makes it possible to infer pre-release verison of a package
even when intermediate derivations did not support pre-release versions.

For example one package could declare `swift-syntax` dependency as
`508.0.1` ..< `601.0.0` and another could narrow it to `600.0.0-latest`
..< `601.0.0`.

Since the most constrained range in such case supports pre-releases a
decision
to use the lastest pre-release version of `600.0.0` should be valid if
there
is no `600.0.0` release yet.

It's important to note that on each path a decision for a package is
always
made based on the last undecided term's requirements which means -
based on the current semantics - if such derivation doesn't support
pre-release,
even though intermediate ones did, the solver would select a released
version.
This PR is not aim to change that.

There is a caveat which we cannot narrowly fix - if package depends on
an exact
pre-release version the inference is going to fail when there is another
dependency
to the same package that doesn't support pre-releases. For example:

Package `A` depends on packages `B` and `C` as follows:

`A` depends on `B` = `0.0.1-alpha` and `C` = `1.0.0`
`B` version `0.0.1-alpha` has no dependencies
`C` version `1.0.0` depends on `B` - `0.0.1` ..< `0.0.2`

In this situation the solver would fail because `0.0.1-alpha` does not
satisfy range - `0.0.1` ..< `0.0.2` inferred from `C`.

- Delays version decisions for packages with pre-release ranges until
there are no more packages without pre-release versions. This also means
that if a previous decision narrows down the range to releases-only the
package would be made a contender on the next step of the solver.

- Relaxes the `isValidDecision` check for pre-release decisions but
makes sure that the last derivation supports pre-release versions.

In situations like
#7658 and
#7643 the
solver would no longer assert and would produce a solution with a
pre-release version for `swift-syntax`.

(cherry picked from commit 43fd240)
@xedin
Copy link
Contributor

xedin commented Jul 23, 2024

Resolved by #7799 and #7808

@xedin xedin closed this as completed Jul 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants