Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;
Здесь есть принципиальная разница. Язык разрешает занулять поинтеры. Поэтому трап в этом случае вполне ожидаем. Но язык не позволяет написать p := pBase, если p имеет тип указателя на наследника (он таким становится после проверки WITH). То, что есть
неявные средства поработать с p "опять" как с указателем на базовый тип - изъян дизайна. Который довольно легко лечится без кардинальной передлки языка. Решений предлагалось несколько. Но Вирт, как всегда, предпочел лечить проблему избавлением от проблемной конструкции. Хотя может он был даже и не в курсе проблемы - просто выпилил WITH, потому что в данный момент оно ему не надо.