`Set` is specially [overloaded][1] for `Part` in order to allow in-place modification of the expressions:

    a = x -> 2;
    a[[1]] = 1; a
    
>     1 -> 2

It is documented on the Documentation page for [`Part`][2] (the first point under "Details" section):

> You can make an assignment like `t[[spec]]=value` to modify any part or sequence of parts in an expression. »

Your function `hoge` doesn't `Hold` its arguments and hence passes to `Set` the extracted *variable* (a `Symbol`) instead of the `Part` expression what explains why it "works" for you:

    hoge[x_, y_] := Hold[x = y]
    a = x -> 2;
    hoge[a[[1]], a[[2]]]
    
>     Hold[x = 2]

----------


For your particular purpose the simplest approach is to replace `Rule` by `Set`:

    Clear[x, y, z]
    {x -> 2, y -> 5, z -> x + y} /. Rule -> Set
    
>     {2, 5, 7}

Another method is to `Apply` `Set` effectively replacing the head `Rule` by `Set`:

    Clear[x, y, z]
    Set @@@ {x -> 2, y -> 5, z -> x + y}
    
>     {2, 5, 7}

Inside of `Do`:

    Clear[x, y, z]
    Do[Set @@ a, {a, {x -> 2, y -> 5, z -> x + y}}];
    {x, y, z}
    
>     {2, 5, 7}


  [1]: https://mathematica.stackexchange.com/a/55503/280
  [2]: http://reference.wolfram.com/language/ref/Part.html