1. A method of type-checking a programming language in a compiler according to one or more rule sets comprising: selecting one or more of the rule sets based upon the present stage of compilation; and type-checking the programming language based on the selected one or more rule sets.