Comment by kachapopopow

Comment by kachapopopow 21 hours ago

12 replies

I was slightly curious: cargo tree llm v0.1.0 (RustGPT) ├── ndarray v0.16.1 │ ├── matrixmultiply v0.3.9 │ │ └── rawpointer v0.2.1 │ │ [build-dependencies] │ │ └── autocfg v1.4.0 │ ├── num-complex v0.4.6 │ │ └── num-traits v0.2.19 │ │ └── libm v0.2.15 │ │ [build-dependencies] │ │ └── autocfg v1.4.0 │ ├── num-integer v0.1.46 │ │ └── num-traits v0.2.19 () │ ├── num-traits v0.2.19 () │ └── rawpointer v0.2.1 ├── rand v0.9.0 │ ├── rand_chacha v0.9.0 │ │ ├── ppv-lite86 v0.2.20 │ │ │ └── zerocopy v0.7.35 │ │ │ ├── byteorder v1.5.0 │ │ │ └── zerocopy-derive v0.7.35 (proc-macro) │ │ │ ├── proc-macro2 v1.0.94 │ │ │ │ └── unicode-ident v1.0.18 │ │ │ ├── quote v1.0.39 │ │ │ │ └── proc-macro2 v1.0.94 () │ │ │ └── syn v2.0.99 │ │ │ ├── proc-macro2 v1.0.94 () │ │ │ ├── quote v1.0.39 () │ │ │ └── unicode-ident v1.0.18 │ │ └── rand_core v0.9.3 │ │ └── getrandom v0.3.1 │ │ ├── cfg-if v1.0.0 │ │ └── libc v0.2.170 │ ├── rand_core v0.9.3 () │ └── zerocopy v0.8.23 └── rand_distr v0.5.1 ├── num-traits v0.2.19 () └── rand v0.9.0 ()

yep, still looks relatively good.

imtringued 19 hours ago

    cargo tree llm v0.1.0 (RustGPT)
    ├── ndarray v0.16.1
    │   ├── matrixmultiply v0.3.9
    │   │   └── rawpointer v0.2.1
    │   │       [build-dependencies]
    │   │       └── autocfg v1.4.
    │   ├── num-complex v0.4.6
    │   │   └── num-traits v0.2.19
    │   │       └── libm v0.2.15
    │   │           [build-dependencies]
    │   │           └── autocfg v1.4.0
    │   ├── num-integer v0.1.46
    │   │   └── num-traits v0.2.19 ()
    │   ├── num-traits v0.2.19 ()
    │   └── rawpointer v0.2.1
    ├── rand v0.9.0
    │   ├── rand_chacha v0.9.0
    │   │   ├── ppv-lite86 v0.2.20
    │   │   │   └── zerocopy v0.7.35
    │   │   │       ├── byteorder v1.5.0
    │   │   │       └── zerocopy-derive v0.7.35 (proc-macro)
    │   │   │           ├── proc-macro2 v1.0.94
    │   │   │           │   └── unicode-ident v1.0.18
    │   │   │           ├── quote v1.0.39
    │   │   │           │   └── proc-macro2 v1.0.94 ()
    │   │   │           └── syn v2.0.99
    │   │   │               ├── proc-macro2 v1.0.94 ()
    │   │   │               ├── quote v1.0.39 ()
    │   │   │               └── unicode-ident v1.0.18
    │   │   └── rand_core v0.9.3
    │   │       └── getrandom v0.3.1
    │   │           ├── cfg-if v1.0.0
    │   │           └── libc v0.2.170
    │   ├── rand_core v0.9.3 ()
    │   └── zerocopy v0.8.23
    └── rand_distr v0.5.1
        ├── num-traits v0.2.19 ()
        └── rand v0.9.0 ()
cmrdporcupine 20 hours ago

linking both rand-core 0.9.0 and rand-core 0.9.3 which the project could maybe avoid by just specifying 0.9 for its own dep on it

  • Diggsey 16 hours ago

    It doesn't link two versions of `rand-core`. That's not even possible with rust (you can only link two semver-incompatible versions of the same crate). And dependency specifications in Rust don't work like that - unless you explicitly override it, all dependencies are semver constraints, so "0.9.0" will happily match "0.9.3".

    • 0xffff2 14 hours ago

      So there's no difference at all between "0", "0.9" and "0.9.3" in cargo.toml (Since semver says only major version numbers are breaking)? As a decently experienced Rust developer, that's deeply surprising to me.

      What if devs don't do a good job of versioning and there is a real incompatibility between 0.9.3 and 0.9.4? Surely there's some way to actually require an exact version?

      • Diggsey 8 hours ago

        They are different:

            "0": ">=0.0.0, <1.0.0"
            "0.9": ">=0.9.0, <1.0.0"
            "0.9.3": ">=0.9.3, <1.0.0"
        
        Notice how the the minimum bound changes while the upper bound is the same for all of them.

        The reason for this is that unless otherwise specified, the ^ operator is used, so "0.9" is actually "^0.9", which then gets translated into the kind of range specifier I showed above.

        There are other operators you can use, these are the common ones:

            (default) ^ Semver compatible, as described above
            >= Inclusive lower bound only
            < Exclusive upper bound only
            = Exact bound
        
        Note that while an exact bound will force that exact version to be used, it still doesn't allow two semver compatible versions of a crate to exist together. For example. If cargo can't find a single version that satisfies all constraints, it will just error.

        For this reason, if you are writing a library, you should in almost all cases stick to regular semver-compatible dependency specifications.

        For binaries, it is more common to want exact control over versions and you don't have downstream consumers for whom your exact constraints would be a nightmare.

      • [removed] 13 hours ago
        [deleted]
      • steveklabnik 13 hours ago

        Note that in the output, there is rand 0.9.0, and two instances of rand_core 0.9.3. You may have thought it selected two versions because you missed the _core there.

        > So there's no difference at all between "0", "0.9" and "0.9.3" in cargo.toml

        No, there is a difference, in particular, they all specify different minimum bounds.

        The trick is that these are using the ^ operator to match, which means that the version "0.9.3" will satisfy all of those constraints, and so Cargo will select 0.9.3 (the latest version at the time I write this comment) as the one version to satisfy all of them.

        Cargo will only select multiple versions when it's not compatible, that is, if you had something like "1.0.0" and "0.9.0".

        > Surely there's some way to actually require an exact version?

        Yes, you'd have to use `=`, like `=0.9.3`. This is heavily discouraged because it would lead to a proliferation of duplication in dependency versions, which aren't necessarily unless you are trying to avoid some sort of specific bugfix. This is sometimes done in applications, but basically should never be done in libraries.

    • eximius 15 hours ago

      This doesn't sound right. If A depends on B and C - B and C can each bring their own versions of D, I thought?

      • Diggsey 8 hours ago

        Within a crate graph, for any given major version of a crate (eg. D v1) only a single minor version can exist. So if B depends on D v1.x, and C depends on D v2.x, then two versions of D will exist. If B depends on Dv1.2 and C depends on Dv1.3, then only Dv1.3 will exist.

        I'm over-simplifying a few things here:

        1. Semver has special treatment of 0.x versions. For these crates the minor version depends like the major version and the patch version behaves like the minor version. So technically you could have v0.1 and v0.2 of a crate in the same crate graph.

        2. I'm assuming all dependencies are specified "the default way", ie. as just a number. When a dependency looks like "1.3", cargo actually treats this as "^1.3", ie. the version must be at least 1.3, but can be any semver compatible version (eg. 1.4). When you specify an exact dependency like "=1.3" instead, the rules above still apply (you still can't have 1.3 and 1.4 in the same crate graph) but cargo will error if no version can be found that satisfies all constraints, instead of just picking a version that's compatible with all dependents.

      • steveklabnik 13 hours ago

        can does not mean must. Cargo attempts to unify (aka deduplicate) dependencies where possible, and in this case, it can find a singular version that satisfies the entire thing.