Tracking down instances from use-sites
Matthew Pickering
matthewtpickering at gmail.com
Tue Jun 26 16:18:59 UTC 2018
Chris,
I have also considered this question.
1. Look at the `idDetails` of the `Id`. A class selector is a `ClassOpId`.
2,3,
When a class selector `foo` is typechecked, the instance information
is of course resolved. The selector `foo` is then wrapped in a
`HsWrapper` which when desugared will apply the type arguments and
dictionary arguments.
Thus, in order to understand what instance has been selected, we need
to look into the `HsWrapper`. In particular, one of the constructors
is the `WpEvApp` constructor which is what will apply the dictionary
argument.
In case 2, this will be a type variable. In case 3, this will be the
dictionary variable. I'm not sure how to distinguish these two cases
easily. Then once you have the dictionary id, you can use `idType` to
get the type of the dictionary which will be something like `Show ()`
in order
to tell you which instance was selected.
You can inspect the AST of a typechecked program using the
`-ddump-tc-ast` flag.
Finally, you should considering writing this as a source plugin rather
than using the GHC API as it will be easier to run in a variety of
different scenarios.
Cheers,
Matt
On Tue, Jun 26, 2018 at 4:40 PM, Christopher Done <chrisdone at gmail.com> wrote:
> Hi all,
>
> Given a TypecheckedModule, what's the most direct way given a Var
> expression retrieved from the AST, to determine:
>
> 1) that it's a class method e.g. `read`
> 2) that it's a generic call (no instance chosen) e.g. `Read a => a -> String`
> 3) or if it's a resolved instance, then which instance is it and which
> package, module and declaration is that defined in?
>
> Starting with this file that has a TypecheckedModule in it:
> https://gist.github.com/chrisdone/6fcb9f1cba6324148d481fcd4eab6af6#file-ghc-api-hs-L23
>
> I presume at this point that instance resolution has taken place. I'm
> not sure that dictionaries or chosen instances are inserted into the
> AST, or whether just the resolved types are inserted e.g. `Int ->
> String`, where I want e.g. `Read Int`, which might lead me to finding
> the matching instance from an InstEnv or so.
>
> I'd like to do some analyses of Haskell codebases, and the fact that
> calls to class methods are opaque is a bit of a road-blocker. Any
> handy tips? Prior work?
>
> It'd be neat in tooling to just hit a goto-definition key on `read`
> and be taken to the instance implementation rather than the class
> definition.
>
> Also, listing all functions that use throw# or functions defined in
> terms of throw# or FFI calls would be helpful, especially for doing
> audits. If I could immediately list all partial functions in a
> project, then list all call-sites, it would be a very convenient way
> when doing an audit to see whether partial functions (such as head)
> are used with the proper preconditions or not.
>
> Any tips appreciated,
>
> Chris
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
More information about the ghc-devs
mailing list