
#9813: Error when reifying type constructor -------------------------------------+------------------------------------- Reporter: owst | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Template Haskell | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D1899 Wiki Page: | -------------------------------------+------------------------------------- Comment (by owst): Replying to [comment:19 rwbarton]:
I think this is too optimistic. In general we can't analyze the argument of `reify` in `g` to know that it refers only to `f`. Plus the `...` could contain arbitrary code that could use functions in other packages that reify arbitrary names.
Oh of course, yes. I was only thinking about `reify 'name`, rather than passing an arbitrary `Name` to `reify`.
I would say that both `f` and `g` can only refer to `h`.
I agree. I think we must rule out dependencies on expressions that contain splices. e.g. in the following: {{{#!hs f x = $(...) g y = f ... }}} `g` does not contain a splice, but depends on `f`, which does. Therefore, if this is to be allowed, we must process `f` before `g`. I think it could be done, but that way probably lies madness. Taking goldfire and rwbarton's suggestions into account, I think the procedure would be: 1. Split the module into declaration groups and process top-to-bottom, 2. For each declaration group, partition the declarations within to those that contain splices (S), and those that do not (NS), 3. Process NS first, then S. Splices within S can refer (either in `reify` or via evaluation) to all names declared in NS, but no names within S. This allows: {{{#!hs f = () data C = C g = $(reify 'f >> reify 'C >> reify ''C >> ...) $(return []) h = $(reify 'f >> reify 'C >> reify ''C >> reify 'g >> ...) }}} but not: {{{#!hs f = () g = $(reify 'f ...) -- ok h = $(reify 'g ...) -- f not in type environment in reify i = ... g ... h ... -- Not in scope g or h j = k $(reify 'k ...) -- Not in scope k (and k not in type environment in reify) $(return []) k x = ... }}} Does that seem reasonable, and likely to be implementable? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9813#comment:20 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler