Great question.  My first reaction is that this shouldn't happen.  `h` appears explicitly inside the `Module` and it should be substituted with the localized equivalent, e.g. `h$123`, even if it is held:

    Module[{h}, HoldComplete[h^2]]

>     HoldComplete[h$6992^2]

However named patterns in constructs such as `Set` and `Rule` are exempt from this substitution:

    Module[{h}, Hold[h_ -> h^2]]

>     Hold[h_ -> h^2]

    Module[{h}, Hold[f[h_] = h^2]]

>     Hold[f[h_] = h^2]

This is related to:

- http://mathematica.stackexchange.com/q/20766/121

However until now I did not realize that this affected constructs without a Hold attribute.  That is I knew that `Module` handles `Function`, `SetDelayed`, and `RuleDelayed` differently:

    Module[{x}, Function[x, x^2]]

>     Function[x, x^2]

    Module[{x}, f[x_] := x^2]
    ?f

>     f[x_] := x^2

    Module[{x}, x_ :> x^2]

>     x_ :> x^2

This actually makes sense as the `x` is already being localized by these constructs and additional substitution by `Module` would only result in e.g.:

>     Function[x$123, x$123^2]

However in the case of `Set` or `Rule`, which do not have hold attributes, this is problematic, as these are not localizing constructs as correctly recognized by the syntax highlighter.   Daniel Lichtblau wrote plainly:

> No need to dance around this: it's a flaw in the implementation of the scoping mechanism. Set `SetSystemOptions["StrictLexicalScoping" -> True];` and it gives 16.

So it seems that my first reaction was correct, and this *shouldn't* happen but does.