obj Parent = o1:O1 and o2:O2; func Foo(p:Parent)->string = p.o1.s; obj O1 = i:integer and s:string; obj O2; obj Child < Parent where: O1 = O3; -- ERROR: this must be prevented per latest -- semantics that say instantiating type must -- be subtype of type it replaces end; obj O3 = i:integer and s:O1; func Foo2(c:Child)->string = c.o1.s; -- This egregiously breaks typing -- since if the bogus where clause -- actually worked c.o1.s is no longer -- a string, but rather an O1 -- We be in trouble here, since both the preceding and next lines should not -- be working. I.e., we can't have it both ways -- c.o1.s is either a string -- or an O1, but not both. Somethings wrong somewhere, either because we -- haven't finished type checking the return type of a function body, or the -- where clause instantiation is bogus, or some of both. func Foo3(c:Child)->string = c.o1.s.s; func Foo4(c:Child)->string = c.o1.s.s.s; -- Sanity check -- this is in -- fact an error, as it should be func Foo5(c:Child)->string = c; -- OK, it looks like the problem -- that the type checking of func bods -- against return types is not done -- yet. Never-the-less, the above -- bogosity observations still hold and -- need to be fixed. -- OK, the preceding misses the point that we're trying to get at. Here it is. func Foo6(c:Child)->string = Foo(c); -- Breaks types if where instantiation -- worked as it appears it should. -- The deal with Foo6 is that its call to Foo with c as an arg breaks types -- inside Foo, since c is sent in as a Parent, but when it gets there, its -- mutated o1.s component ends up mascarading as a string when its really -- another O1. This be the reason that where instantiators must be subtypes of -- what the sub for.