Hehe thank you (again) to the authors of Hugs. The answer seems to be in exactly one place -- it just took a long time to make sure there weren't other places interfering.
type.c routine typeFreshPat(l,p) /* find type of pattern, assigning fresh type variables to each var */
This sets tcMode = NEW_PATTERN /* type-checking Mode */
then recurses on typeExpr(l,p) -- so tcMode is in effect an additional parameter
typeExpr( ) returns `p` with suitable bindings; but also returns the induced context in global var `preds` -- updated as a side-effect by calling a slather of worker routines -- chiefly in the #include'd preds.c.
If I save `preds` before recursing on typeExpr(l,p); and restore upon return; I get no context induced for a datatype constructor appearing in pattern position. The datatype context _is_ still inferred for the constructor appearing in an expression, so the constraints still apply for building.
I did break something, though: numeric patterns -- that is, literals -- aren't getting recognised, so are giving pattern match fails. The Language Report 3.17.2, point 7 says matching to numeric literals should succeed if `v == k`; that still works if I move the `==` test into a guard. It works as a pattern ok for Char or String literals, so I guess I've broken how Hugs translates the numeric literals to the `fromInteger` etc equality test.
Mod'ing this behaviour is giving some interesting semantics -- I'll discuss on Hugs Users list.
From this discussion 'Contexts on datatype declarations'
It looks like (at least at the time) GHC had separate functions for matching vs building using a constructor. ...
What I can't find is where Hugs infers the type for a data constructor appearing in matching position.
Any hints? Thanks in advance