This merely illustrates Morten's answer for those wanting to understand the issue and solution otherwise obscured by shared variable name changes and lack of LRM reference.
This example analyzes:
library ieee;
use ieee.std_logic_1164.all;
package declare is
-- type buff_array is array(2 downto 0, 7 downto 0) of std_logic_vector(31 downto 0);
type ram_array is array(7 downto 0) of std_logic_vector(31 downto 0);
type buff_array is array (2 downto 0) of ram_array; -- added declaration
shared variable ram: ram_array;
shared variable buff: buff_array;
end package;
library ieee;
use ieee.std_logic_1164.all;
use work.declare.all;
entity ramarray is
end entity;
architecture foo of ramarray is
signal we: std_logic;
begin
we <= '1';
SOMELABEL:
process (we)
begin
if we = '1' then
ram := buff(1); -- unchanged
end if;
end process;
end architecture;
Multidimensional slices are not allowed[1]. Separating the indexes for each dimension by converting buff into an array of an array type of an array subtype allows you to have the same base type on both sides of the assignment operator providing a slice name to a single dimensional array whose element type is ram_array.
[1] IEEE Std 1076-2008, Section 8.5 Slice names "A slice name denotes a one-dimensional array composed of a sequence of consecutive elements of another one-dimensional array. A slice of a signal is a signal; a slice of a variable is a variable; a slice of a constant is a constant; a slice of a value is a value."
See also Fast Track Change Proposal FT-15 Slicing of multidimensional arrays and arrays of arrays
from June 2004, still in progress.