There are a few issues.
1) auto determining the correct size of the integer type (word, int ,int64, un/signed)
IIRC (not tested) you can have overloaded procedures (word vs int). Without declaration there is a lack of clarity which one is called.
Further, if you change the return type of foo in "for a := 0 to foo", the loop will call a different foo function, that might do something completely different. (and yes there could be reasons why such overloaded functions may not be interchangeable). Similar for conflicts when mixing signed and unsigned.
2) "reserving" the identifier.
If "a" is in the var section then, I can see it is used. If it is not I might add a new boolean (or otherwise incompatible) "a", and get an error as it conflicts with the loop.
3) one identifier 2 types
begin
for a := 0 to 9 do write(a);
for a := false to true do write(a);
end
confusing, since "a" in the same procedure is at some time int, and then bool.
4)
Hides a global var. Of course same can happen with any local var in the var section.
But if loop vars are no longer declared in the var block, then I must search *ALL* surrounding "for" statements, instead of just one var section.
5) There is no optional. Even if by default loop vars must be declared, and the proposal must be explicitly enabled (mode/flag).
Someone will use it, and eventually I will have to look at code that uses this.