Ok. I'm not sure what is done in each pass, so an example would probably do well.
Basically, the first pass resolves identifiers to look up types and the second generates the code.
You can see an example on line 2265 in the test suite as a disabled test. What it tests is that it ought to be possible to have two modules in different files where each contains a subclass which inherits a subclass from the other module.
I understand this as: during a programs second pass the compiler generates messages when types are in conflict (e.g. wrong type for function argument) but might not notice if the type used or checked against has only gone through the first pass. Correct me when necessary.
No, that's not what I meant. It's been a while since I dug into this, so what follows might not be completely correct. Anyway I _think_ this part of the problem stems from the placeholder programs.
Placeholders are deployed when the compiler discovers a cyclic dependency, i.e. the program being resolved is currently being compiled in an outer context. In that case the placeholder, which is a completely bogus program or object, is returned instead. Any identifier is successfully looked up inside it, and that just yields the placeholder again. The theory is that it's gone in the second pass so that the lookup is done correctly then (which perhaps yields a lookup error if it turns out to not exist). But as you've seen you can get these meaningless messages about placeholder problems, so that theory doesn't work.
The types of the placeholders are of course incorrect, and that makes the type of the program they are used in incorrect in turn. Those incorrect types can sometimes escalate to the second pass in other programs; exactly how I don't recall right now.
I'm convinced that the placeholders are fundamentally wrong. A 100% correct solution shouldn't need them. A 100% correct solution should also always ensure that the type of a class/program is completely accurate after the first pass; the trick to sometimes correct it in the second pass doesn't always cut it.
You might be aware of the design paradigm in Pike that compilation never is dependent on the declaration order in the file. As I'm sure you've encountered at some point or another, that isn't true in practice (it shows especially when inherits are used in reverse order). Anyway, I don't think that problem is very severe, so it's not overly important that a solution makes Pike any better in that regard.
/.../ Any hints on which disabled tests in the testsuite? (will have a look to see if I find them).
Come to think of it, I doubt there's more than the one mentioned above.