[Feature discussion] overwrite for substitude obsolete crate and buggy implementations

TL;DR Is there anyway to fix bug in a old crate without modify its source code?

With system update, it might be a small chance that old crate (*-sys) might not fully compatitable to the new system.

Thus, such thing could happen:

  • bar depends on bar-sys
  • foo depends on bar v1.2.3
  • as time goes by, bar update to v2.0, which is incompatitable with v1.2.3, thus foo may not decide to update the dependence of bar into v2.0
  • as time goes by, current bar-sys is not compatitable with the new system, thus bar update the dependence of bar-sys, and a new version, v2.3.0 is published.

Now, foo is not compatitable with the new system, since it only depend on the unsupported v1.x bar. AFAIK, the only thing crate foo could do is download the source of bar and even bar-sys, then fix them.

My question is, If we know the incompatitable function here is only bar::baz, could we overwrite it directly?

the benefit of the overwrite is that, imaging foo is also a lib which is useful but lack of maintance for years, users must download the source of foo, bar and bar-sys, and then change thedependence of foo, bar and bar-sys to the local crate. and finally fix them, which introduce a huge amount of crate to maintance, but actually we only want a small change. Allow overwrite could let us only modify the specific buggy function, which might be better.

In real world, crate InputBox have such bug due to one of its dependencies is locked to a low and buggy major version. We could only fix them by obtaining the source file and edit them, which might be really annoying since this unofficial fix might contain bugs, and the author may provide further update, which might not compatitable with the unofficial fix.

This is (as written) a question about using Rust, thus a better fit for the users forum.

You might be interested in the [patch] support in Cargo. This allows you to patch crates anywhere in a dependency tree. The unit of source replacement is the crate, but you should also be able to make shim crates in the style of the semver trick to overlay individual publicly-implementable item.

1 Like

Thanks for your suggestion, which solve the real-world problem. But that might not be what I want, since

  1. [patch] must download the whole source file of the modified crate, thus we could not figure out what modification I've made, and what file is the original crate file. Maybe git log / git diff helps, but why don't we just allow write a simple patch?
  2. If a simple patch is allowed, crate maintainers could just publish bugfixs, rather than bump every minor version of the crate. Sometimes even minor bump could break the dependence, If we allow fine-grained overwrite, we could just pick version like v3.1.41+patch:*-5,9-26,53-58(patch number might not start with 1, since some patch number already been used by previous patch, thus those patch should not valid in new version.), or pick up the correct patch from the unmerged PRs / maintainer's patch list.
  3. If someone wrote a crate, hashviolet, which implementation of HashMap is fully compatitable with std::collections::HashMap, and its performance is 10x faster [1], we could not just overwrite the original implementation gracefully.
  4. I once found that RwLock is slower than what I think, I want to write a personal RwLock, I tried to import the used crate and namespace in std, but finally failed since some of the namespace is not public. If a overwrite is allowed, contributors could test their PRs more efficient.

That's why I want a fine-grained overwrite technique. It seems that there is no such thing, thus I post this thread, in IRLO rather than URLO.

  1. seems impossible, but consider that, hashbrown is firstly a crate which is faster than the old std::collections::HashMap, I'm not talking about a non-exist thing. ↩ī¸Ž

What if some unsafe code is relying on the (properly documented) behaviour of a function and you overwrite it?

How would overwriting functions change this? It just slightly reduce the scope, but doesn't solve the problem

1 Like

crate owners could write test code for unsafe code. If we overwrite them in a wrong way, run tests could figure out the error we made.

Actually, what I proposed here is what crate maintainers could do.

The overwrite feature I propose could be regard as a dirty-fix. We could edit only what affect us, test whether the core feature suits our situation, and ignore all the warnings.

As you can see, my dirty fix is actually "update dependence and edit a single line", which generate 6 warnings, suggests there might be potential bugs.

Crate users usually not the professional crate editors, they are not expected to fix bugs in the only right way. provide an (un)official dirty-fix might be better than just fork the original crate and patch.

Mistakes in unsafe code generally result in UB or unsoundness. Tests don't catch UB most of the time. Miri can catch many cases of UB. Unsoundness however is impossible to rule out using tests as it only causes UB if you compose methods in specific ways.

Yes, actually you point to a question for generally patching a crate, not only what I proposed.

An unofficial patch may often met such problems, and IMHO, my propose might be better than just replace the buggy crate into another unofficially patched crate.

If we patch a crate by directly edit its source, we could not know what code is affected and what is deserved for a test, but things become different with an "overwrite" section, since we know the fine-grained modification, thus we could do further analysis to show what is affected.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.