Which arguments for deinit (or other invalidating functions)?

Technically yes. But there’s something special about deinit (and other invalidating functions), which is that the function “consumes” the value (semantically, not technically). Speaking of “contracts”, that means that the function’s argument (or the pointed-by value, in case of self: *T) shouldn’t be touched anymore when deinit is called.

So nothing stops us from doing something like this:

const std = @import("std");

const T = struct {
    some_state: i32 = 5,
    // Let's imagine there are many more fields in addition
    // to `some_state`.
    pub fn deinit(self: T) void {
        // Let's imagine we must mutate `self`.
        // We can do that simply by copying it (not efficient,
        // but works).
        var this = self;
        while (this.some_state > 0) {
            this.some_state -= 1;
        }
    }
};

pub fn main() void {
    const x = T{};
    x.deinit();
}

My point is that disregarding whether we declare deinit to take a self: T or self: *T, we can always get our work done. But one of those is (in practice) more efficient than the other.

Now my argument in the second post of this thread is that if we always use noalias self: *T, we can always achieve maximum efficiency while simply not needing to expose the implementation’s needs/internals to the caller.

“Forcing” the programmer to use var instead const (consistently) and allowing self.* = undefined; (consistently) is just a bonus. Of course you may argue if each of those bonuses is a pro or con. In my opinion they are advantages, but some people might consider requiring var consistently being a disadvantage (and prefer to be able to use const at least in some cases, even if that’s just due to implementation details of ArrayList.deinit, Thread.detach, etc).

Note that std.StringHashMap.deinit currently does not allow the programmer to use const, even if it could by following the scheme I demonstrated in the code above.

Now I propose consistency by always forbidding it, while #6322 proposed consistency by always allowing it. And, if I get you right, you propose that whether it’s allowed or not should depend on the deinit implementation (which I don’t think is a good idea, but maybe there are arguments that I overlook).

I don’t think types (structs) are mutable/immutable, but bindings (and maybe pointers) are?