+ # REQUIRE: `can_resolve_for(mtype, anchor, mmodule)`
+ # ENSURE: `not self.need_anchor implies result == self`
+ fun resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule, cleanup_virtual: Bool): MType is abstract
+
+ # Resolve formal type to its verbatim bound.
+ # If the type is not formal, just return self
+ #
+ # The result is returned exactly as declared in the "type" property (verbatim).
+ # So it could be another formal type.
+ #
+ # In case of conflicts or inconsistencies in the model, the method returns a `MErrorType`.
+ fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType do return self
+
+ # Resolve the formal type to its simplest equivalent form.
+ #
+ # Formal types are either free or fixed.
+ # When it is fixed, it means that it is equivalent with a simpler type.
+ # When a formal type is free, it means that it is only equivalent with itself.
+ # This method return the most simple equivalent type of `self`.
+ #
+ # This method is mainly used for subtype test in order to sanely compare fixed.
+ #
+ # By default, return self.
+ # See the redefinitions for specific behavior in each kind of type.
+ #
+ # In case of conflicts or inconsistencies in the model, the method returns a `MErrorType`.
+ fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType do return self
+
+ # Is the type a `MErrorType` or contains an `MErrorType`?
+ #
+ # `MErrorType` are used in result with conflict or inconsistencies.
+ #
+ # See `is_legal_in` to check conformity with generic bounds.
+ fun is_ok: Bool do return true
+
+ # Is the type legal in a given `mmodule` (with an optional `anchor`)?
+ #
+ # A type is valid if:
+ #
+ # * it does not contain a `MErrorType` (see `is_ok`).
+ # * its generic formal arguments are within their bounds.
+ fun is_legal_in(mmodule: MModule, anchor: nullable MClassType): Bool do return is_ok
+
+ # Can the type be resolved?
+ #
+ # In order to resolve open types, the formal types must make sence.
+ #
+ # ## Example
+ #
+ # class A[E]
+ # end
+ # class B[F]
+ # end
+ #
+ # ~~~nitish
+ # E.can_resolve_for(A[Int]) #-> true, E make sense in A
+ #
+ # E.can_resolve_for(B[Int]) #-> false, E does not make sense in B
+ #
+ # B[E].can_resolve_for(A[F], B[Object]) #-> true,
+ # # B[E] is a red hearing only the E is important,
+ # # E make sense in A
+ # ~~~
+ #
+ # REQUIRE: `anchor != null implies not anchor.need_anchor`
+ # REQUIRE: `mtype.need_anchor implies anchor != null and mtype.can_resolve_for(anchor, null, mmodule)`
+ # ENSURE: `not self.need_anchor implies result == true`
+ fun can_resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule): Bool is abstract