rescript-association / reanalyze

Experimental analyses for ReScript and OCaml: globally dead values/types, exception analysis, and termination analysis.
MIT License
277 stars 20 forks source link

Dead Types wrt consumed types #169

Open AlexMoutonNoble opened 2 years ago

AlexMoutonNoble commented 2 years ago

Hi again Cristiano. Just added dce to our CI process and going through the output i get:

Warning Dead Type
  File "/home/circleci/noble/web/src/requests.res", line 200, characters 2-17
  argsClone.with_data is a record label never used to read a value
  <-- line 200
    @dead("argsClone.with_data") with_data: bool,

argsClone is consumed by an external Axios.post, and this type is a preposition for our clone action, so these warnings seem like false positive to me. Its not wrong, granted, but suggests I can remove that field which is wrong.

Are you doing any work in this direction?

Thanks! Alex

cristianoc commented 2 years ago

How does the Axis post get access to it? Is argsClone exported to JS, and if so is genType used?

cristianoc commented 2 years ago

added dce to our CI process

Great!

AlexMoutonNoble commented 2 years ago
@send
external postImpl: (
  axios,
  string,
  'data,
  config,
) => Js.Promise.t<response<'datasend, 'datarecv, 'headersrecv, 'request>> = "post"

let post = (url, data, config) => axios->postImpl(url, data, config)
type argsClone<'id> = {
  name: string,
  description: string,
  with_data: bool,
  clone_id: 'id,
}

type clone = {id: int}

let clone = (data: argsClone<int>): Js.Promise.t<
  Axios.response<'datasend, cloneCapability, 'headers, 'request>,
> => {
  Axios.post(`/api/capability/`, data, configJson)
}
cristianoc commented 2 years ago

Currently there's no magic that tries to understand flow of values to externals. The only magic is values annotated @genType are automatically treated as not dead. But there's no special provision at the moment for types used in externals.

In these cases, it's best to annotate the type argsClone live manually: @live type argsClone....

cristianoc commented 2 years ago

E.g.

@live("sent to Axios")
type argsClone<'id> = {
  name: string,
  description: string,
  with_data: bool,
  clone_id: 'id,
}
cristianoc commented 2 years ago

The other thing is just because a value is sent to an external, that does not mean that the external function. is going to read all its fields, so any automatic analysis would be pretty coarse.

AlexMoutonNoble commented 2 years ago

That seems pretty reasonable to me. False positives and aggressive annotations are a burden

adding just for context that -dce produces 8500 lines of output for our codebase, so basically too much for our small team

(anyways thanks again!)