Like many other languages, it is possible in VHDL to perform name scoping. This happens if you declare a new object in a nested scope that reuses the name of an object that was already declared. This is not an error in VHDL, but it can be confusing and it can cause errors. In general, I would advice against name scoping unless you have a very good reason. Even then, it would be best if you document (comment) your code so that everybody understands what is going on.

This is a straightforward example of name shadowing:

entity e0 is
end entity e0;
architecture demo of e0 is
    constant c : integer := 1;
    assert c = 1;

    myblock : block
        constant c : integer := 2;
        assert c = 2 report "the second declaration of constant c shadows the first";
    end block myblock;

    assert c = 1 report "this is the scope of the first declaration again";
end architecture demo;

It gets more confusing if you shadow names from the a standardized package:

architecture demo2 of e0 is
    constant true : boolean := false; -- shadowing the name "true". Bad idea!
    assert false = true;
end architecture demo;

A common misconception is that loop iterators need to be declared beforehand. They don't, because they are declared implicitly in the loop statement.

architecture demo4 of e0 is
    process is
        variable i: integer := 1;
        assert i = 1;
        i := 5;
        assert i = 5;
        for i in 0 to 10 loop -- this is a different object, shadowing the variable i
            report integer'image(i);

            -- i behaves like a constant here
            i := i+1; -- error! cannot assign to constants!
        end loop;

        assert i = 5; -- this is still the variable, declared in the process
        i := i+1; 
        assert i = 6;
    end process ;
end architecture;

Note: you can reach these shadowed names by using their expanded names:

entity fun is
end entity;

architecture hide of fun is
        example : process is
                variable x : integer := 0;
                procedure changevar (x : integer) is
                        hide.example.x := x; -- or example.x
                end procedure;
                report "x=" & integer'image(x);
        end process;
end architecture;
VSIM 1> run -all
# ** Note: x=5
#    Time: 0 ns  Iteration: 0  Instance: /fun