Почему drop принимает ссылку, а не значение?
Потому что метод drop трейта Drop вызывается компилятором, каждый раз когда переменная владеющая чем-либо выходит из области видимости. И сам метод drop тут не исключение. То есть если бы self тут был по значению, компилятор был бы
обязан его дропнуть в конце функции, что вызвало бы бесконечную рекурсию.
Причём если вызывать drop() руками
Функция core::mem::drop никакого отношения к трейту Drop не имеет. Если Вы глянете на её реализацию, то это просто пустая функция, которая принимает аргумент по значению, а он уже дропается на общих основаниях, так как выходит из области видимости в ней.
Почему сначала вызывается drop для A, а потом для B? По логике drop должен сначала вызываться для полей.
У Вас неверная логика. В метод трейта Drop приходит ссылка, а значит должна быть гарантия того что данные по ней полностью валидные. Всегда дропается сначала внешняя структура,а затем её поля. Более того компилятор не даст Вам даже мувнуть части структуры имплиментирующей Drop.
Если очень нужно, то владение из поля можно забрать через std::mem::swap/std::mem::replace/std::mem::take
Хотя проще это сделать обернув такое поле в Option и забирая владение его методом take