Okay, so I tried to implement the first example (with hash tables) from that github page in SML and found that I was actually entirely unable to get the described behavior, and now I'm kind of confused.
How are, um, things (objects, I guess?) implemented in Rust? Are they passed around as packages of their value and their methods? Because if so, that seems awfully...not-systemsy to me, but I don't currently see any other way of getting that behavior out of that code.
Specifically, when I write the SML version of that code and run it, I get a hash table with only (3, "ho") in it, because once I call Module2::bar (or in my version, S2.foo) it is doing everything in Module2 land, even when it hashes the key from Module1. The only way I can see to get this behavior would be to pass around all of the methods with the object itself so that it "knows" to call its version of hash instead of the new one. Am I wrong?
I think the Haskell solution to this (since it looks like interfaces in their current form are basically typeclasses) is to only allow one instance per class, probably to avoid exactly this problem; iirc, this also allows the correct methods to be inserted at compile time. I think there are extensions (or at least talk of extensions) that allow instantiation of typeclasses at multiple types, which result in more verbosity (and I think something exactly as expressive as ML functors, or at least closer than typeclasses).
The solution you describe seems pretty legit (just what you want, validation from someone who isn't on the team and who has only thought about this for like an hour!); just to be clear, you require that any implementation of a trait native to a different module must be with a new (local) abstract type, correct? I can't help but think that there's a better way, but I'm not sure what it is right now.
Here's my SML code that attempted to implement the same behavior: http://pastebin.com/4VbvBL5u
What I really want in SML is some way to say "these two structures both have Key.t = int, but they are not necessarily the same structure" (as opposed to "these two are the same structure", which I'd also like). I have no idea if this is feasible/decidable, though. I know sml/nj has the ability to declare structure equality (so "where Key = Key1" instead of "where type Key.t = int" or whatever), but type equality is enough to get the two to interoperate, so *shrug*. I was trying to find a way to make MainFn not compile, but still be able to use integers for the inputs. Maybe someone more clever than me (like you!) can tell me how to get this to work/why it doesn't work.
So yeah, anyway, this is kind of a long, rambly post, sorry. I guess it's time for a tldr?
tldr: the behavior of the example in the wiki page seems wonky and like an inherent problem with OO that an ML style module system would treat better, but it still doesn't solve the problem of multiple instantiation, which is pretty interesting, especially when trying to solve it at (separate)-compile time!