On Wed, Jul 24, 2013 at 1:12 PM, Alex Burr <[email protected]> wrote:

> I have the impression that rust doesn't quite do that - rather, it
> prevents clashes from occurring between crates at distance greater than 1
> in some metric.
>
> A crate is allowed to define the implementation of a trait R for a type Y
> if it defines either Y or R. So if cR is a crate defining R, and cY is a
> create defining Y, then they could both define the impl of R for Y and
> clash. I get the feeling that this is considered okay because one of the
> crates must be a direct dependency of the other, and so the author of the
> dependent must know what is exported by the other one. Whereas if third
> party crates were allowed to define the impl, then they could clash
> 'innocently'.
>

This is effectively the same rule that Haskell uses. It works because: both
the Trait definition R and the type definition Y must be lexically visible.
One of these must import the other, so checking this requirement is a
compile-time error for whichever crate is compiled second.

It is link safe barring substantial rearrangement of both crates combined
with a significant failure of deployment and dependency checking. As long
as assembly versioning is done properly, it should be link safe.

In order to have a potential link safety problem, you need to have

  1. An orphaned instance, that
  2. Is a candidate for automatic (i.e. non-lexical) instance resolution.

Where (borrowing names from the quoted text) an "orphaned instance" is one
defined in *neither* crate cR nor crate cY.

In large programs, orphan instances aren't as uncommon as people want to
believe. They are the whole reason for the so-called "Koenig rule" in C++.
One very common way for them to arise is in I/O:

  - Developer A creates some new stream class SC
  - Developer B creates some type R
  - Developer A and B work in unrelated organizations, and are mutually
oblivious
  - Developer C wants to use SC on R, and must therefore define an overload
    resolution. Since developer C doesn't "own" cSC or cR, the overload
resolution
    must necessarily be an orphan instance.

This is actually fine under the proposal that I outlined. In fact, we
really only need to document (in the type) instance resolutions that
deviate from the "cR or cY" rule.

There is a link safety failure, however, if developer C adds an orphan
instance, and Developer A or B later decides to add an instance of their
own that *follows* the "cR or cY" rule. After that change is made,
developer C's crate will no longer compile, because the orphan instance
shadows the "official" instance. As long as developer C's crate is getting
recompiled, that's perfectly fine. The problem comes when we have multiple
versions of crates being dynamically loaded in the field. This reduces to a
previously semi-solved problem, which is the dynamic library version
management problem.


Jonathan
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to