Help with correct behavior of default trait methods for mir2wasm


#1

I’m working on updating the mir2wasm project to the current nightly compiler (as of nightly-2016-09-15, for reference). You can see my current progress here: https://github.com/brson/mir2wasm/pull/39.

I’ll duplicate a little bit of the context from that thread here, and try to describe the problem as concretely as possible.

I’m running into an internal compiler error when translating the following snippet:

pub trait Test {
    fn test(&self) { } // removing the body here gets us passed the ICE
}

impl Test for isize {
    fn test(&self) { }
}

The error is this: internal compiler error: ../src/librustc/ty/subst.rs:457: Type parameterSelf/#0(Self/0) out of range when substituting (root type=Some(&Self)) substs=[]

I’ve thus far tracked the problem down to translating the body of the default method in the trait (apologies if that’s not the correct terminology). In particular, the crash occurs when trying to compute the concrete layout of the &Self type, which is unbound when translating the trait method itself.

Here are the solutions I can think of:

  1. Skip translating default trait methods for now (just to see how much further I can get). I think the right place to insert that check is here - but I’m not sure what that condition should look like.
  2. When visiting each of the impls of that trait that doesn’t have a corresponding method, either “inject” the default method there, or visit it in that context. Again, I’m not sure how to accomplish this.

Am I on the right track? Any guidance is appreciated.

Thanks!


#2

You should get on IRC, this is just one of many small bugs, and it’s easier to go through them in real-time. The solution is to resolve the method to the default if it’s not overriden, and this is more complex with specialization. Some of the relevant code should be in miri although I’m not sure it works perfectly there.

As for translating the method when visiting the trait, you should just not try to do that. The method is generic (over Self) and as such it needs to be instantiated through an use. The new collector takes care of finding all instances in rustc_trans, so the whole “visit the crate, item by item” thing shouldn’t be needed if you had access to that.


#3

I’ll try to be on IRC (as jwarner), but personally I prefer asynchronous communication when possible. Would you be able to write up a list of the problems you see that I can start knocking out one bullet point at a time? I think this default trait method problem is the most pressing, if for no other reason than it’s currently the most visible.

It sounds to me like making collector::collect_crate_translation_items accessible (or perhaps some of its components, or at least something similar) is the right long-term solution. What issues might there be with moving in that direction? What’s the process on changing something like that?

Are you suggesting that using some code / ideas from miri is a better sort-term solution? Given the amount of logic in collector, I find it hard to believe that miri actually correctly emulates all of that. Do you think there’s a shortcut to just get the tests passing in the mean time?