`syn` 1.0.58 breaks `test-case` and `parameterized`

The syn crate, in version 1.0.58, conditionalized the publication of its syn::export module. Unfortunately, this breaking change did exactly that: it broke the previously working latest build of the test-case crate. In an attempt to avoid the consequences (and ever run a test again), I switched over to using the parameterized crate. It's also broken in the same way.

Until the syn authors get a chance to back out this breaking change and move it into a 1.1.0 release (which won't be automatically pulled into the test-case and parameterized crates), how should I bypass this broken version in this transitive dependency?

I know how to update the Cargo.lock file appropriately, but I'm in the habit of erasing that entirely. It's also .gitignored in my project, so it won't "just work" for the other developers.

The [patch.crates-io] syntax in the Crates.toml file is another possibility, but it doesn't seem to do what I want. Meanwhile, the [replace] syntax is deprecated, and probably wouldn't solve this either.

Perhaps I should manually check out the GitHub version of 1.0.58, and clobber it into working, then use a patch?

How do long-time Rust users deal with these occasional instabilities from below?

1.1.0 is still considered semver-compatible. Crates that depend on "1" or even "1.0" will be resolved like ">=1.0.0, <2.0.0". You would have to use a tilde-requirement ~1.0 to restrict it to <1.1.0.

You could add a direct dependency on exactly the version you want, or even the new version with the necessary features enabled if that will fix it.

1 Like

The syn commit responsible seems to be this one:

So test-case and parameterized were relying on a (morally) non-public implementation detail. I'd guess there won't be a new semver-incompatible syn release for that reason, and the other crates will have to update instead to remove uses of syn::export.

2 Likes

I did see that it was an incorrect use of private information. I'll go with the theory that this was a consequence of earlier Rust not being able to set a more precise bound on publication, and I respect the decision to break this unwanted dependency. Unfortunately, I don't know enough to figure out how to force these modules to use the earlier (1.0.57) version of syn. My proposed solutions haven't panned out yet. Any hints?

test-case has already removed their references to syn::export on the master branch, but a new version has yet to be published.

I believe if you add a direct dependency like this:

[dependencies]
syn = "=1.0.57"

then Cargo will use syn v1.0.57 everywhere in the build (because it should be semver-compatible with the dependency expressed by test-case or whatever). This is what @cuviper was suggesting.

4 Likes

Excellent! It's all working again, and it's just what I needed! I was under the misapprehension that because multiple versions could end up inside the same binary, that each crate's toml file solely determined which versions they were using. Thanks so much for the heads-up about how to force the version for any crate requesting a compatible version! I'll mark @cole-miller's message as the solution, but only because I was too slow to figure out @cuviper's earlier comment. Thanks to all!

2 Likes

Good to hear! This page has all the details on how Cargo picks a version of each dependency:

https://doc.rust-lang.org/stable/cargo/reference/resolver.html

Basically, two different semver-compatible versions of the same crate will never be compiled in a single build.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.