hlint icon indicating copy to clipboard operation
hlint copied to clipboard

confused scope causing invalid suggestion

Open MarcusDunn opened this issue 4 years ago • 2 comments

the following code

{-# LANGUAGE TypeApplications #-}

module Database.Doctors where

import Control.Monad.Reader (ReaderT)
import Database
import Database.Esqueleto.Experimental

getPatients :: Entity Doctor -> ReaderT SqlBackend IO [Entity Patient]
getPatients dbDoctor =
  select $ do
    (pats :& _ :& docs) <-
      from $
        table @Patient
          `InnerJoin` table @PatientDoctor
          `on` (\(pats :& patientDoctorMap) -> pats ^. PatientId ==. patientDoctorMap ^. PatientDoctorPatientId)
          `InnerJoin` table @Doctor
          `on` (\(_ :& patientDoctorMap :& docs) -> patientDoctorMap ^. PatientDoctorDoctorId ==. docs ^. DoctorId)
    where_ (docs ^. DoctorId ==. val (entityKey dbDoctor))
    return pats

yeilds a suggestion to "Fuse on/on". Which leads to the very broken:

getPatients :: Entity Doctor -> ReaderT SqlBackend IO [Entity Patient]
getPatients dbDoctor =
  select $ do
    (pats :& _ :& docs) <-
      ( from $
          table @Patient
            `InnerJoin` table @PatientDoctor
        )
        `on` ( ( (\(pats :& patientDoctorMap) -> pats ^. PatientId ==. patientDoctorMap ^. PatientDoctorPatientId)
                   `InnerJoin` table @Doctor
               )
                 . (\(_ :& patientDoctorMap :& docs) -> patientDoctorMap ^. PatientDoctorDoctorId ==. docs ^. DoctorId)
             )
    where_ (docs ^. DoctorId ==. val (entityKey dbDoctor))
    return pats

Not sure how useful of a bug report this as when https://github.com/ndmitchell/hlint/issues/1001 is resolved I'd imagine my issue would also be resolved (the issue obviously does not occur with a qualified import of Database.Esqueleto.Experimental). I'd be happy to be pinged when that fix goes through and be used as a test case if desired.

MarcusDunn avatar Aug 28 '21 03:08 MarcusDunn

never mind I'm pretty sure this falls under

HLint operates on each module at a time in isolation, as a result HLint does not know about types or which names are in scope. This decision is deliberate, allowing HLint to parallelise and be used incrementally on code that may not type-check.

MarcusDunn avatar Aug 28 '21 03:08 MarcusDunn

Thanks for the report - I think you're right that #1001 will probably fix this, but useful to leave it tagged so the test case can be extracted from it.

ndmitchell avatar Aug 28 '21 13:08 ndmitchell