Hannes Siebenhandl pushed to branch wip/fendor/has-field-hie at Glasgow Haskell Compiler / GHC
Commits:
-
fabdfe82
by fendor at 2026-09-17T11:29:46+02:00
-
0ec259eb
by fendor at 2026-09-17T11:32:11+02:00
-
ce94ad34
by fendor at 2026-09-17T11:33:19+02:00
15 changed files:
- + changelog.d/record-dot-evidence
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Rename/Expr.hs
- + testsuite/tests/hiefile/should_run/HasFieldQueries.hs
- + testsuite/tests/hiefile/should_run/HasFieldQueries.stdout
- + testsuite/tests/hiefile/should_run/HieTypeable.hs
- + testsuite/tests/hiefile/should_run/HieTypeable.stdout
- + testsuite/tests/hiefile/should_run/NoFieldSelectorQueries.hs
- + testsuite/tests/hiefile/should_run/NoFieldSelectorQueries.stdout
- testsuite/tests/hiefile/should_run/RecordDotTypes.hs
- testsuite/tests/hiefile/should_run/RecordDotTypes.stdout
- testsuite/tests/hiefile/should_run/T23492.stdout
- testsuite/tests/hiefile/should_run/all.T
Changes:
| 1 | +section: compiler
|
|
| 2 | +synopsis: Record selector functions as evidence for `HasField` constraints during .hie file generation.
|
|
| 3 | +description: {
|
|
| 4 | + We record the record selector `foo` of an expression such as `f.foo` as evidence for
|
|
| 5 | + solving the constraint `HasField "foo" record ty`.
|
|
| 6 | + |
|
| 7 | + This allows us to point to the definition source location of the record selector `foo`, allowing
|
|
| 8 | + users to jump to definition using the evidence variables.
|
|
| 9 | +}
|
|
| 10 | + |
|
| 11 | +issues: #25418
|
|
| 12 | +mrs: !16694 |
| ... | ... | @@ -23,7 +23,6 @@ import GHC.Core.DataCon ( dataConWrapperType ) |
| 23 | 23 | import GHC.Core.Type ( Type, ForAllTyFlag(..) )
|
| 24 | 24 | import GHC.Core.TyCon ( TyCon, tyConClass_maybe )
|
| 25 | 25 | import GHC.Core.InstEnv
|
| 26 | -import GHC.Core.Predicate ( isEvId )
|
|
| 27 | 26 | |
| 28 | 27 | import GHC.Hs
|
| 29 | 28 | import GHC.Hs.Syn.Type
|
| ... | ... | @@ -33,7 +32,7 @@ import GHC.Types.Basic |
| 33 | 32 | import GHC.Types.UnresolvedImport ( isGeneratedImport )
|
| 34 | 33 | import GHC.Types.FieldLabel
|
| 35 | 34 | import GHC.Types.Avail ( Avails )
|
| 36 | -import GHC.Types.Id ( isDataConId_maybe )
|
|
| 35 | +import GHC.Types.Id ( isDataConId_maybe, isId, idDetails )
|
|
| 37 | 36 | import GHC.Types.Name ( Name, nameSrcSpan, nameUnique, wiredInNameTyThing_maybe, getName )
|
| 38 | 37 | import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnv, lookupNameEnv )
|
| 39 | 38 | import GHC.Types.Name.Reader ( RecFieldInfo(..), WithUserRdr(..) )
|
| ... | ... | @@ -81,6 +80,7 @@ import Control.Applicative ( (<|>) ) |
| 81 | 80 | import GHC.Types.TypeEnv ( TypeEnv )
|
| 82 | 81 | import Control.Arrow ( second )
|
| 83 | 82 | import Data.Traversable ( mapAccumR )
|
| 83 | +import GHC.Types.Id.Info (IdDetails(..), recSelParentName)
|
|
| 84 | 84 | |
| 85 | 85 | {- Note [Updating HieAst for changes in the GHC AST]
|
| 86 | 86 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -682,7 +682,7 @@ instance ToHie (Context (Located (WithUserRdr Name))) where |
| 682 | 682 | |
| 683 | 683 | hieEvIdsOfTerm :: EvTerm -> [EvId]
|
| 684 | 684 | -- Returns only EvIds satisfying relevantEvId
|
| 685 | -hieEvIdsOfTerm = runFVSelectiveList isEvId . evTermFVs
|
|
| 685 | +hieEvIdsOfTerm = runFVSelectiveList isId . evTermFVs
|
|
| 686 | 686 | |
| 687 | 687 | instance ToHie (EvBindContext (LocatedA TcEvBinds)) where
|
| 688 | 688 | toHie (EvBindContext sc sp (L span (EvBinds bs)))
|
| ... | ... | @@ -690,7 +690,7 @@ instance ToHie (EvBindContext (LocatedA TcEvBinds)) where |
| 690 | 690 | where
|
| 691 | 691 | go evbind = do
|
| 692 | 692 | let evDeps = hieEvIdsOfTerm $ eb_rhs evbind
|
| 693 | - depNames = EvBindDeps $ map varName evDeps
|
|
| 693 | + depNames = EvBindDeps $ map classifyEvBindDep evDeps
|
|
| 694 | 694 | concatM $
|
| 695 | 695 | [ toHie (C (EvidenceVarBind (EvLetBind depNames) (combineScopes sc (mkScope span)) sp)
|
| 696 | 696 | (L span $ eb_lhs evbind))
|
| ... | ... | @@ -698,6 +698,12 @@ instance ToHie (EvBindContext (LocatedA TcEvBinds)) where |
| 698 | 698 | ]
|
| 699 | 699 | toHie _ = pure []
|
| 700 | 700 | |
| 701 | +classifyEvBindDep :: EvId -> EvBindDep
|
|
| 702 | +classifyEvBindDep evId =
|
|
| 703 | + case idDetails evId of
|
|
| 704 | + RecSelId{sel_tycon} -> RecordField (varName evId) (recSelParentName sel_tycon)
|
|
| 705 | + _ -> EvidenceVar (varName evId)
|
|
| 706 | + |
|
| 701 | 707 | instance ToHie (LocatedA HsWrapper) where
|
| 702 | 708 | toHie (L osp wrap)
|
| 703 | 709 | = case wrap of
|
| ... | ... | @@ -598,17 +598,79 @@ instance Outputable EvVarSource where |
| 598 | 598 | ppr (EvInstBind True cls) = text "bound due to a superclass of " <+> ppr cls
|
| 599 | 599 | ppr (EvLetBind deps) = text "bound by a let, depending on:" <+> ppr deps
|
| 600 | 600 | |
| 601 | +-- | Evidence binding dependency with additional details.
|
|
| 602 | +data EvBindDep
|
|
| 603 | + = EvidenceVar Name
|
|
| 604 | + -- ^ Evidence variable such as a type class constructor.
|
|
| 605 | + --
|
|
| 606 | + -- For example, @C:HasField@, @$dShow@ (dictionaries) or @$fCList@.
|
|
| 607 | + --
|
|
| 608 | + -- This is the default representation of a 'EvBindDep'.
|
|
| 609 | + | RecordField
|
|
| 610 | + -- ^ Evidence variable of a record selector.
|
|
| 611 | + --
|
|
| 612 | + -- This is for example generated with @-XOverloadedRecordDot@, where
|
|
| 613 | + -- the evidence includes a reference to which record selector is used
|
|
| 614 | + -- to implement @getField@.
|
|
| 615 | + Name
|
|
| 616 | + -- ^ 'Name' of the record selector
|
|
| 617 | + Name
|
|
| 618 | + -- ^ 'Name' of the parent type.
|
|
| 619 | + | TypeableEvidence
|
|
| 620 | + -- ^ Evidence of a @Typeable@ constraint.
|
|
| 621 | + Name
|
|
| 622 | + -- ^ Name of the type the evidence was generated for.
|
|
| 623 | + deriving (Eq, Ord)
|
|
| 624 | + |
|
| 625 | +instance Outputable EvBindDep where
|
|
| 626 | + ppr = \ case
|
|
| 627 | + EvidenceVar n -> ppr n
|
|
| 628 | + RecordField sel parent -> ppr sel <+> text "of Record" <+> ppr parent
|
|
| 629 | + TypeableEvidence n -> ppr n <+> text "bound by Typeable"
|
|
| 630 | + |
|
| 631 | +evBindDepName :: EvBindDep -> Name
|
|
| 632 | +evBindDepName = \ case
|
|
| 633 | + EvidenceVar n -> n
|
|
| 634 | + RecordField selector _record -> selector
|
|
| 635 | + TypeableEvidence n -> n
|
|
| 636 | + |
|
| 637 | +evBindDepHieName :: EvBindDep -> HieName
|
|
| 638 | +evBindDepHieName = toHieName . evBindDepName
|
|
| 639 | + |
|
| 640 | +instance Binary EvBindDep where
|
|
| 641 | + put_ bh = \ case
|
|
| 642 | + EvidenceVar n -> do
|
|
| 643 | + putByte bh 0
|
|
| 644 | + put_ bh n
|
|
| 645 | + RecordField n sel -> do
|
|
| 646 | + putByte bh 1
|
|
| 647 | + put_ bh n
|
|
| 648 | + put_ bh sel
|
|
| 649 | + TypeableEvidence n -> do
|
|
| 650 | + putByte bh 2
|
|
| 651 | + put_ bh n
|
|
| 652 | + |
|
| 653 | + get bh =
|
|
| 654 | + getByte bh >>= \ case
|
|
| 655 | + 0 -> EvidenceVar <$> get bh
|
|
| 656 | + 1 -> RecordField <$> get bh <*> get bh
|
|
| 657 | + 2 -> TypeableEvidence <$> get bh
|
|
| 658 | + t -> fail $ "EvBindDep: Unknown tag: " ++ show t
|
|
| 659 | + |
|
| 601 | 660 | -- | Eq/Ord instances compare on the converted HieName,
|
| 602 | 661 | -- as non-exported names may have different uniques after
|
| 603 | 662 | -- a roundtrip
|
| 604 | -newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [Name] }
|
|
| 663 | +newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [EvBindDep] }
|
|
| 605 | 664 | deriving Outputable
|
| 606 | 665 | |
| 666 | +evBindDepsNames :: EvBindDeps -> [Name]
|
|
| 667 | +evBindDepsNames = map evBindDepName . getEvBindDeps
|
|
| 668 | + |
|
| 607 | 669 | instance Eq EvBindDeps where
|
| 608 | - (==) = coerce ((==) `on` map toHieName)
|
|
| 670 | + (==) = coerce ((==) `on` map evBindDepHieName)
|
|
| 609 | 671 | |
| 610 | 672 | instance Ord EvBindDeps where
|
| 611 | - compare = coerce (compare `on` map toHieName)
|
|
| 673 | + compare = coerce (compare `on` map evBindDepHieName)
|
|
| 612 | 674 | |
| 613 | 675 | instance Binary EvBindDeps where
|
| 614 | 676 | put_ bh (EvBindDeps xs) = put_ bh xs
|
| ... | ... | @@ -82,15 +82,19 @@ resolveVisibility kind ty_args |
| 82 | 82 | foldType :: (HieType a -> a) -> HieTypeFix -> a
|
| 83 | 83 | foldType f (Roll t) = f $ fmap (foldType f) t
|
| 84 | 84 | |
| 85 | -selectPoint :: HieFile -> (Int,Int) -> Maybe (HieAST Int)
|
|
| 86 | -selectPoint hf (sl,sc) = getFirst $
|
|
| 85 | +selectPoint :: HieFile -> (Int,Int) -> Maybe (HieAST TypeIndex)
|
|
| 86 | +selectPoint hf p = selectRange hf p p
|
|
| 87 | + |
|
| 88 | +selectRange :: HieFile -> (Int,Int) -> (Int,Int) -> Maybe (HieAST TypeIndex)
|
|
| 89 | +selectRange hf (sl,sc) (el, ec) = getFirst $
|
|
| 87 | 90 | flip foldMap (M.toList (getAsts $ hie_asts hf)) $ \(HiePath fs,ast) -> First $
|
| 88 | 91 | case selectSmallestContaining (sp fs) ast of
|
| 89 | 92 | Nothing -> Nothing
|
| 90 | 93 | Just ast' -> Just ast'
|
| 91 | 94 | where
|
| 92 | 95 | sloc fs = mkRealSrcLoc fs sl sc
|
| 93 | - sp fs = mkRealSrcSpan (sloc fs) (sloc fs)
|
|
| 96 | + eloc fs = mkRealSrcLoc fs el ec
|
|
| 97 | + sp fs = mkRealSrcSpan (sloc fs) (eloc fs)
|
|
| 94 | 98 | |
| 95 | 99 | findEvidenceUse :: NodeIdentifiers a -> [Name]
|
| 96 | 100 | findEvidenceUse ni = [n | (Right n, dets) <- xs, any isEvidenceUse (identInfo dets)]
|
| ... | ... | @@ -141,7 +145,7 @@ getEvidenceTree refmap var = go emptyNameSet var |
| 141 | 145 | det <- S.toList $ identInfo dets
|
| 142 | 146 | case det of
|
| 143 | 147 | EvidenceVarBind src@(EvLetBind (getEvBindDeps -> xs)) scp spn ->
|
| 144 | - pure $ Just ((src,scp,spn),mapMaybe (go $ extendNameSet seen var) xs)
|
|
| 148 | + pure $ Just ((src,scp,spn),mapMaybe (go (extendNameSet seen var) . evBindDepName) xs)
|
|
| 145 | 149 | EvidenceVarBind src scp spn -> pure $ Just ((src,scp,spn),[])
|
| 146 | 150 | _ -> pure Nothing
|
| 147 | 151 | pure $ Tree.Node (EvidenceInfo var sp typ (Just evdet)) children
|
| ... | ... | @@ -386,7 +390,7 @@ definedInAsts asts n = case nameSrcSpan n of |
| 386 | 390 | |
| 387 | 391 | getEvidenceBindDeps :: ContextInfo -> [Name]
|
| 388 | 392 | getEvidenceBindDeps (EvidenceVarBind (EvLetBind xs) _ _) =
|
| 389 | - getEvBindDeps xs
|
|
| 393 | + evBindDepsNames xs
|
|
| 390 | 394 | getEvidenceBindDeps _ = []
|
| 391 | 395 | |
| 392 | 396 | isEvidenceBind :: ContextInfo -> Bool
|
| ... | ... | @@ -422,7 +422,7 @@ rnExpr (HsGetField _ e f) |
| 422 | 422 | ; let f' = rnDotFieldOcc <$> f
|
| 423 | 423 | ; return ( mkExpandedExpr
|
| 424 | 424 | (HsGetField noExtField e f')
|
| 425 | - (mkGetField getField e (fmap (unLoc . dfoLabel) f'))
|
|
| 425 | + (mkGetField getField e (dfoLabel $ unLoc f'))
|
|
| 426 | 426 | , fv_e `plusFN` fv_getField ) }
|
| 427 | 427 | |
| 428 | 428 | rnExpr (HsProjection _ fs)
|
| ... | ... | @@ -431,7 +431,7 @@ rnExpr (HsProjection _ fs) |
| 431 | 431 | ; let fs' = NE.map rnDotFieldOcc fs
|
| 432 | 432 | ; return ( mkExpandedExpr
|
| 433 | 433 | (HsProjection noExtField fs')
|
| 434 | - (mkProjection getField circ $ NE.map (unLoc . dfoLabel) fs')
|
|
| 434 | + (mkProjection getField circ $ NE.map dfoLabel fs')
|
|
| 435 | 435 | , unitFN circ `plusFN` fv_getField) }
|
| 436 | 436 | |
| 437 | 437 | ------------------------------------------
|
| ... | ... | @@ -2882,8 +2882,9 @@ rnHsIf p b1 b2 |
| 2882 | 2882 | |
| 2883 | 2883 | -- mkGetField arg field calculates a get_field @field arg expression.
|
| 2884 | 2884 | -- e.g. z.x = mkGetField z x = get_field @x z
|
| 2885 | -mkGetField :: Name -> LHsExpr GhcRn -> LocatedAn NoEpAnns FieldLabelString -> HsExpr GhcRn
|
|
| 2886 | -mkGetField get_field arg field = unLoc (head $ mkGet get_field (arg :| []) field)
|
|
| 2885 | +mkGetField :: Name -> LHsExpr GhcRn -> XRec GhcRn FieldLabelString -> HsExpr GhcRn
|
|
| 2886 | +mkGetField get_field arg field =
|
|
| 2887 | + HsApp noExtField (mkGetFieldExpr get_field field) arg
|
|
| 2887 | 2888 | |
| 2888 | 2889 | -- mkSetField a field b calculates a set_field @field expression.
|
| 2889 | 2890 | -- e.g mkSetSetField a field b = set_field @"field" a b (read as "set field 'field' to a on b").
|
| ... | ... | @@ -2902,14 +2903,16 @@ mkSet set_field acc (field, g) = wrapGenSpan (mkSetField set_field g field acc) |
| 2902 | 2903 | -- mkProjection fields calculates a projection.
|
| 2903 | 2904 | -- e.g. .x = mkProjection [x] = getField @"x"
|
| 2904 | 2905 | -- .x.y = mkProjection [.x, .y] = (.y) . (.x) = getField @"y" . getField @"x"
|
| 2905 | -mkProjection :: Name -> Name -> NonEmpty FieldLabelString -> HsExpr GhcRn
|
|
| 2906 | -mkProjection getFieldName circName (field :| fields) = foldl' f (proj field) fields
|
|
| 2906 | +mkProjection :: Name -> Name -> NonEmpty (XRec GhcRn FieldLabelString) -> HsExpr GhcRn
|
|
| 2907 | +mkProjection getFieldName circName (field :| fields) =
|
|
| 2908 | + unLoc $ foldl' f (mkGetFieldExpr getFieldName field) fields
|
|
| 2907 | 2909 | where
|
| 2908 | - f :: HsExpr GhcRn -> FieldLabelString -> HsExpr GhcRn
|
|
| 2909 | - f acc field = genHsApps circName $ map wrapGenSpan [proj field, acc]
|
|
| 2910 | + f :: LHsExpr GhcRn -> XRec GhcRn FieldLabelString -> LHsExpr GhcRn
|
|
| 2911 | + f acc field = wrapGenSpan $ genHsApps circName [mkGetFieldExpr getFieldName field, acc]
|
|
| 2910 | 2912 | |
| 2911 | - proj :: FieldLabelString -> HsExpr GhcRn
|
|
| 2912 | - proj (FieldLabelString f) = genHsVar getFieldName `genAppType` genHsTyLit f
|
|
| 2913 | +mkGetFieldExpr :: Name -> XRec GhcRn FieldLabelString -> LHsExpr GhcRn
|
|
| 2914 | +mkGetFieldExpr getFieldName (L ann (FieldLabelString f)) =
|
|
| 2915 | + wrapGenSpan' (getHasLoc ann) (genHsVar getFieldName `genAppType` genHsTyLit f)
|
|
| 2913 | 2916 | |
| 2914 | 2917 | -- mkProjUpdateSetField calculates functions representing dot notation record updates.
|
| 2915 | 2918 | -- e.g. Suppose an update like foo.bar = 1.
|
| 1 | +{-# LANGUAGE OverloadedRecordDot #-}
|
|
| 2 | +module Main where
|
|
| 3 | + |
|
| 4 | +import TestUtils
|
|
| 5 | +import GHC.Records
|
|
| 6 | +import GHC.TypeLits
|
|
| 7 | +import Data.Tree
|
|
| 8 | + |
|
| 9 | +data Thing = Thing {field1 :: Char, field2 :: Bool}
|
|
| 10 | + deriving (Show, Eq)
|
|
| 11 | + |
|
| 12 | +foo :: Thing -> String
|
|
| 13 | +foo t = show t.field1
|
|
| 14 | +-- ^ this is the point
|
|
| 15 | + |
|
| 16 | +testing2 (x :: Thing) = x.field1
|
|
| 17 | +-- ^ this is the point
|
|
| 18 | +-- ^ this is the point
|
|
| 19 | + |
|
| 20 | +data NestedThing = NestedThing { nested1 :: Thing }
|
|
| 21 | + |
|
| 22 | +nestedSig :: NestedThing -> Char
|
|
| 23 | +nestedSig n = n.nested1.field1
|
|
| 24 | +-- ^ this is the point
|
|
| 25 | +-- ^ this is the point
|
|
| 26 | + |
|
| 27 | +nestedNoSig n = n.nested1.field2 :: Bool
|
|
| 28 | +-- ^ this is the point
|
|
| 29 | +-- ^ this is the point
|
|
| 30 | + |
|
| 31 | + |
|
| 32 | +withConstraint :: HasField "field1" x Char => x -> Char
|
|
| 33 | +withConstraint x = x.field1
|
|
| 34 | +-- ^ this is the point
|
|
| 35 | + |
|
| 36 | +prefix :: Thing -> Char
|
|
| 37 | +prefix x = (.field1) x
|
|
| 38 | +-- ^ this is the point
|
|
| 39 | + |
|
| 40 | +prefixNested :: NestedThing -> Char
|
|
| 41 | +prefixNested x = (.nested1.field1) x
|
|
| 42 | +-- ^ this is the point
|
|
| 43 | +-- ^ this is the point
|
|
| 44 | + |
|
| 45 | + |
|
| 46 | +points =
|
|
| 47 | + [ (13,17)
|
|
| 48 | + , (16,25)
|
|
| 49 | + , (16,27)
|
|
| 50 | + , (23,17)
|
|
| 51 | + , (23,25)
|
|
| 52 | + , (27,20)
|
|
| 53 | + , (27,28)
|
|
| 54 | + , (33,22)
|
|
| 55 | + , (37,14)
|
|
| 56 | + , (41,21)
|
|
| 57 | + , (41,30)
|
|
| 58 | + ]
|
|
| 59 | + |
|
| 60 | +main = do
|
|
| 61 | + (df, hf) <- readTestHie "HasFieldQueries.hie"
|
|
| 62 | + let refmap = generateReferencesMap $ getAsts $ hie_asts hf
|
|
| 63 | + |
|
| 64 | + traverse (explainEv df hf refmap) points
|
|
| 65 | + return () |
| 1 | +==========================
|
|
| 2 | +At point (13,17), we found:
|
|
| 3 | +==========================
|
|
| 4 | +┌
|
|
| 5 | +│ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char
|
|
| 6 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 7 | +│ field1 of Record Thing]
|
|
| 8 | +│ with scope: ModuleScope
|
|
| 9 | +│
|
|
| 10 | +│ Defined at <no location info>
|
|
| 11 | +└
|
|
| 12 | +|
|
|
| 13 | ++- ┌
|
|
| 14 | +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 15 | +| │ is a usage of an external evidence variable
|
|
| 16 | +| │ Defined in `GHC.Internal.Records'
|
|
| 17 | +| └
|
|
| 18 | +|
|
|
| 19 | +`- ┌
|
|
| 20 | + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char
|
|
| 21 | + │ is a usage of an external evidence variable
|
|
| 22 | + │ Defined at HasFieldQueries.hs:9:21
|
|
| 23 | + └
|
|
| 24 | + |
|
| 25 | +==========================
|
|
| 26 | +At point (16,25), we found:
|
|
| 27 | +==========================
|
|
| 28 | +==========================
|
|
| 29 | +At point (16,27), we found:
|
|
| 30 | +==========================
|
|
| 31 | +┌
|
|
| 32 | +│ $dHasField at HasFieldQueries.hs:16:1-32, of type: HasField "field1" Thing Char
|
|
| 33 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 34 | +│ field1 of Record Thing]
|
|
| 35 | +│ with scope: LocalScope HasFieldQueries.hs:16:1-32
|
|
| 36 | +│ bound at: HasFieldQueries.hs:16:1-32
|
|
| 37 | +│ Defined at <no location info>
|
|
| 38 | +└
|
|
| 39 | +|
|
|
| 40 | ++- ┌
|
|
| 41 | +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 42 | +| │ is a usage of an external evidence variable
|
|
| 43 | +| │ Defined in `GHC.Internal.Records'
|
|
| 44 | +| └
|
|
| 45 | +|
|
|
| 46 | +`- ┌
|
|
| 47 | + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char
|
|
| 48 | + │ is a usage of an external evidence variable
|
|
| 49 | + │ Defined at HasFieldQueries.hs:9:21
|
|
| 50 | + └
|
|
| 51 | + |
|
| 52 | +==========================
|
|
| 53 | +At point (23,17), we found:
|
|
| 54 | +==========================
|
|
| 55 | +┌
|
|
| 56 | +│ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "nested1" NestedThing Thing
|
|
| 57 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 58 | +│ nested1 of Record NestedThing]
|
|
| 59 | +│ with scope: ModuleScope
|
|
| 60 | +│
|
|
| 61 | +│ Defined at <no location info>
|
|
| 62 | +└
|
|
| 63 | +|
|
|
| 64 | ++- ┌
|
|
| 65 | +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 66 | +| │ is a usage of an external evidence variable
|
|
| 67 | +| │ Defined in `GHC.Internal.Records'
|
|
| 68 | +| └
|
|
| 69 | +|
|
|
| 70 | +`- ┌
|
|
| 71 | + │ nested1 at HasFieldQueries.hs:1:1, of type: NestedThing -> Thing
|
|
| 72 | + │ is a usage of an external evidence variable
|
|
| 73 | + │ Defined at HasFieldQueries.hs:20:34
|
|
| 74 | + └
|
|
| 75 | + |
|
| 76 | +==========================
|
|
| 77 | +At point (23,25), we found:
|
|
| 78 | +==========================
|
|
| 79 | +┌
|
|
| 80 | +│ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char
|
|
| 81 | +│ is an evidence variable bound by a let, depending on: [$dHasField]
|
|
| 82 | +│ with scope: ModuleScope
|
|
| 83 | +│
|
|
| 84 | +│ Defined at <no location info>
|
|
| 85 | +└
|
|
| 86 | +|
|
|
| 87 | +`- ┌
|
|
| 88 | + │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char
|
|
| 89 | + │ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 90 | + │ field1 of Record Thing]
|
|
| 91 | + │ with scope: ModuleScope
|
|
| 92 | + │
|
|
| 93 | + │ Defined at <no location info>
|
|
| 94 | + └
|
|
| 95 | + |
|
|
| 96 | + +- ┌
|
|
| 97 | + | │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 98 | + | │ is a usage of an external evidence variable
|
|
| 99 | + | │ Defined in `GHC.Internal.Records'
|
|
| 100 | + | └
|
|
| 101 | + |
|
|
| 102 | + `- ┌
|
|
| 103 | + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char
|
|
| 104 | + │ is a usage of an external evidence variable
|
|
| 105 | + │ Defined at HasFieldQueries.hs:9:21
|
|
| 106 | + └
|
|
| 107 | + |
|
| 108 | +==========================
|
|
| 109 | +At point (27,20), we found:
|
|
| 110 | +==========================
|
|
| 111 | +┌
|
|
| 112 | +│ $dHasField at HasFieldQueries.hs:27:1-40, of type: HasField "nested1" r r
|
|
| 113 | +│ is an evidence variable bound by a let, depending on: [$dHasField]
|
|
| 114 | +│ with scope: LocalScope HasFieldQueries.hs:27:1-40
|
|
| 115 | +│ bound at: HasFieldQueries.hs:27:1-40
|
|
| 116 | +│ Defined at <no location info>
|
|
| 117 | +└
|
|
| 118 | +|
|
|
| 119 | +`- ┌
|
|
| 120 | + │ $dHasField at HasFieldQueries.hs:27:1-40, of type: HasField "nested1" r r
|
|
| 121 | + │ is an evidence variable bound by a type signature
|
|
| 122 | + │ with scope: LocalScope HasFieldQueries.hs:27:1-40
|
|
| 123 | + │ bound at: HasFieldQueries.hs:27:1-40
|
|
| 124 | + │ Defined at <no location info>
|
|
| 125 | + └
|
|
| 126 | + |
|
| 127 | +==========================
|
|
| 128 | +At point (27,28), we found:
|
|
| 129 | +==========================
|
|
| 130 | +┌
|
|
| 131 | +│ $dHasField at HasFieldQueries.hs:27:1-40, of type: HasField "field2" r Bool
|
|
| 132 | +│ is an evidence variable bound by a let, depending on: [$dHasField]
|
|
| 133 | +│ with scope: LocalScope HasFieldQueries.hs:27:1-40
|
|
| 134 | +│ bound at: HasFieldQueries.hs:27:1-40
|
|
| 135 | +│ Defined at <no location info>
|
|
| 136 | +└
|
|
| 137 | +|
|
|
| 138 | +`- ┌
|
|
| 139 | + │ $dHasField at HasFieldQueries.hs:27:1-40, of type: HasField "field2" r Bool
|
|
| 140 | + │ is an evidence variable bound by a type signature
|
|
| 141 | + │ with scope: LocalScope HasFieldQueries.hs:27:1-40
|
|
| 142 | + │ bound at: HasFieldQueries.hs:27:1-40
|
|
| 143 | + │ Defined at <no location info>
|
|
| 144 | + └
|
|
| 145 | + |
|
| 146 | +==========================
|
|
| 147 | +At point (33,22), we found:
|
|
| 148 | +==========================
|
|
| 149 | +┌
|
|
| 150 | +│ $dHasField at HasFieldQueries.hs:33:1-27, of type: HasField "field1" x Char
|
|
| 151 | +│ is an evidence variable bound by a let, depending on: [$dHasField]
|
|
| 152 | +│ with scope: LocalScope HasFieldQueries.hs:33:1-27
|
|
| 153 | +│ bound at: HasFieldQueries.hs:33:1-27
|
|
| 154 | +│ Defined at <no location info>
|
|
| 155 | +└
|
|
| 156 | +|
|
|
| 157 | +`- ┌
|
|
| 158 | + │ $dHasField at HasFieldQueries.hs:33:1-27, of type: HasField "field1" x Char
|
|
| 159 | + │ is an evidence variable bound by a HsWrapper
|
|
| 160 | + │ with scope: LocalScope HasFieldQueries.hs:33:1-27
|
|
| 161 | + │ bound at: HasFieldQueries.hs:33:1-27
|
|
| 162 | + │ Defined at <no location info>
|
|
| 163 | + └
|
|
| 164 | + |
|
| 165 | +==========================
|
|
| 166 | +At point (37,14), we found:
|
|
| 167 | +==========================
|
|
| 168 | +┌
|
|
| 169 | +│ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char
|
|
| 170 | +│ is an evidence variable bound by a let, depending on: [$dHasField]
|
|
| 171 | +│ with scope: ModuleScope
|
|
| 172 | +│
|
|
| 173 | +│ Defined at <no location info>
|
|
| 174 | +└
|
|
| 175 | +|
|
|
| 176 | +`- ┌
|
|
| 177 | + │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char
|
|
| 178 | + │ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 179 | + │ field1 of Record Thing]
|
|
| 180 | + │ with scope: ModuleScope
|
|
| 181 | + │
|
|
| 182 | + │ Defined at <no location info>
|
|
| 183 | + └
|
|
| 184 | + |
|
|
| 185 | + +- ┌
|
|
| 186 | + | │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 187 | + | │ is a usage of an external evidence variable
|
|
| 188 | + | │ Defined in `GHC.Internal.Records'
|
|
| 189 | + | └
|
|
| 190 | + |
|
|
| 191 | + `- ┌
|
|
| 192 | + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char
|
|
| 193 | + │ is a usage of an external evidence variable
|
|
| 194 | + │ Defined at HasFieldQueries.hs:9:21
|
|
| 195 | + └
|
|
| 196 | + |
|
| 197 | +==========================
|
|
| 198 | +At point (41,21), we found:
|
|
| 199 | +==========================
|
|
| 200 | +┌
|
|
| 201 | +│ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "nested1" NestedThing Thing
|
|
| 202 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 203 | +│ nested1 of Record NestedThing]
|
|
| 204 | +│ with scope: ModuleScope
|
|
| 205 | +│
|
|
| 206 | +│ Defined at <no location info>
|
|
| 207 | +└
|
|
| 208 | +|
|
|
| 209 | ++- ┌
|
|
| 210 | +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 211 | +| │ is a usage of an external evidence variable
|
|
| 212 | +| │ Defined in `GHC.Internal.Records'
|
|
| 213 | +| └
|
|
| 214 | +|
|
|
| 215 | +`- ┌
|
|
| 216 | + │ nested1 at HasFieldQueries.hs:1:1, of type: NestedThing -> Thing
|
|
| 217 | + │ is a usage of an external evidence variable
|
|
| 218 | + │ Defined at HasFieldQueries.hs:20:34
|
|
| 219 | + └
|
|
| 220 | + |
|
| 221 | +==========================
|
|
| 222 | +At point (41,30), we found:
|
|
| 223 | +==========================
|
|
| 224 | +┌
|
|
| 225 | +│ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char
|
|
| 226 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 227 | +│ field1 of Record Thing]
|
|
| 228 | +│ with scope: ModuleScope
|
|
| 229 | +│
|
|
| 230 | +│ Defined at <no location info>
|
|
| 231 | +└
|
|
| 232 | +|
|
|
| 233 | ++- ┌
|
|
| 234 | +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 235 | +| │ is a usage of an external evidence variable
|
|
| 236 | +| │ Defined in `GHC.Internal.Records'
|
|
| 237 | +| └
|
|
| 238 | +|
|
|
| 239 | +`- ┌
|
|
| 240 | + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char
|
|
| 241 | + │ is a usage of an external evidence variable
|
|
| 242 | + │ Defined at HasFieldQueries.hs:9:21
|
|
| 243 | + └
|
|
| 244 | + |
| 1 | +module Main where
|
|
| 2 | + |
|
| 3 | +import Data.Dynamic
|
|
| 4 | +import Data.Typeable
|
|
| 5 | +import TestUtils
|
|
| 6 | + |
|
| 7 | +data Thing = Thing {field1 :: Char, field2 :: Bool}
|
|
| 8 | + deriving (Show, Eq)
|
|
| 9 | + |
|
| 10 | +castFromDynamic :: Dynamic -> Maybe Thing
|
|
| 11 | +castFromDynamic d = fromDynamic d
|
|
| 12 | + -- ^ this is the point
|
|
| 13 | + |
|
| 14 | +rep :: Thing -> TypeRep
|
|
| 15 | +rep d = typeOf d
|
|
| 16 | + -- ^ this is the point
|
|
| 17 | + |
|
| 18 | +points =
|
|
| 19 | + [ (11,21)
|
|
| 20 | + , (15,10)
|
|
| 21 | + ]
|
|
| 22 | + |
|
| 23 | +main = do
|
|
| 24 | + (df, hf) <- readTestHie "HieTypeable.hie"
|
|
| 25 | + let refmap = generateReferencesMap $ getAsts $ hie_asts hf
|
|
| 26 | + |
|
| 27 | + traverse (explainEv df hf refmap) points
|
|
| 28 | + return () |
| 1 | +==========================
|
|
| 2 | +At point (11,21), we found:
|
|
| 3 | +==========================
|
|
| 4 | +┌
|
|
| 5 | +│ $dTypeable at HieTypeable.hs:1:1, of type: Typeable Thing
|
|
| 6 | +│ is an evidence variable bound by a let, depending on: [$dTypeable]
|
|
| 7 | +│ with scope: ModuleScope
|
|
| 8 | +│
|
|
| 9 | +│ Defined at <no location info>
|
|
| 10 | +└
|
|
| 11 | +|
|
|
| 12 | +`- ┌
|
|
| 13 | + │ $dTypeable at HieTypeable.hs:1:1, of type: Typeable Thing
|
|
| 14 | + │ is an evidence variable bound by a let, depending on: []
|
|
| 15 | + │ with scope: ModuleScope
|
|
| 16 | + │
|
|
| 17 | + │ Defined at <no location info>
|
|
| 18 | + └
|
|
| 19 | + |
|
| 20 | +==========================
|
|
| 21 | +At point (15,10), we found:
|
|
| 22 | +==========================
|
|
| 23 | +┌
|
|
| 24 | +│ $dTypeable at HieTypeable.hs:1:1, of type: Typeable Thing
|
|
| 25 | +│ is an evidence variable bound by a let, depending on: []
|
|
| 26 | +│ with scope: ModuleScope
|
|
| 27 | +│
|
|
| 28 | +│ Defined at <no location info>
|
|
| 29 | +└
|
|
| 30 | + |
| 1 | +{-# LANGUAGE NoFieldSelectors #-}
|
|
| 2 | +{-# LANGUAGE DuplicateRecordFields #-}
|
|
| 3 | +{-# LANGUAGE OverloadedRecordDot #-}
|
|
| 4 | +module Main where
|
|
| 5 | + |
|
| 6 | +import TestUtils
|
|
| 7 | +import GHC.Records
|
|
| 8 | + |
|
| 9 | +data A = A { a :: Int, b :: Char }
|
|
| 10 | +data B = B { a :: Int, n :: A }
|
|
| 11 | +data C
|
|
| 12 | + = C { c :: Float }
|
|
| 13 | + | D { c :: Float }
|
|
| 14 | + | E { e :: Int }
|
|
| 15 | + |
|
| 16 | +valA = A { a = 1, b = 'b' }
|
|
| 17 | +valB = B { a = 1, n = valA }
|
|
| 18 | +valC = C { c = 1.0 }
|
|
| 19 | +valD = D { c = 2.0 }
|
|
| 20 | +valE = E { e = 1 }
|
|
| 21 | + |
|
| 22 | +accessA :: Int
|
|
| 23 | +accessA = valA.a
|
|
| 24 | +-- ^ 1
|
|
| 25 | + |
|
| 26 | +accessField :: HasField "a" r Int => r -> Int
|
|
| 27 | +accessField r = r.a
|
|
| 28 | +-- ^ 2
|
|
| 29 | + |
|
| 30 | +nested = valB.n.b
|
|
| 31 | +-- ^ ^
|
|
| 32 | +-- 3 4
|
|
| 33 | +multi1a = valC.c
|
|
| 34 | +-- ^
|
|
| 35 | +-- 5
|
|
| 36 | +multi1b = valD.c
|
|
| 37 | +-- ^
|
|
| 38 | +-- 6
|
|
| 39 | +multi1c :: C -> Float
|
|
| 40 | +multi1c someC = someC.c -- Where does this point to?
|
|
| 41 | +-- ^
|
|
| 42 | +-- 7
|
|
| 43 | +multi3 = valE.e
|
|
| 44 | +-- ^
|
|
| 45 | +-- 8
|
|
| 46 | +multi4 = valD.e -- This is a run-time error, but where does it point to?
|
|
| 47 | +-- ^
|
|
| 48 | +-- 9
|
|
| 49 | + |
|
| 50 | +points =
|
|
| 51 | + [ (23, 16)
|
|
| 52 | + , (27, 19)
|
|
| 53 | + , (30, 15)
|
|
| 54 | + , (30, 17)
|
|
| 55 | + , (33, 16)
|
|
| 56 | + , (36, 16)
|
|
| 57 | + , (40, 23)
|
|
| 58 | + , (43, 15)
|
|
| 59 | + , (46, 15)
|
|
| 60 | + ]
|
|
| 61 | + |
|
| 62 | +main = do
|
|
| 63 | + (df, hf) <- readTestHie "NoFieldSelectorQueries.hie"
|
|
| 64 | + let refmap = generateReferencesMap $ getAsts $ hie_asts hf
|
|
| 65 | + |
|
| 66 | + traverse (explainEv df hf refmap) points
|
|
| 67 | + return () |
| 1 | +==========================
|
|
| 2 | +At point (23,16), we found:
|
|
| 3 | +==========================
|
|
| 4 | +┌
|
|
| 5 | +│ $dHasField at NoFieldSelectorQueries.hs:1:1, of type: HasField "a" A Int
|
|
| 6 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 7 | +│ a of Record A]
|
|
| 8 | +│ with scope: ModuleScope
|
|
| 9 | +│
|
|
| 10 | +│ Defined at <no location info>
|
|
| 11 | +└
|
|
| 12 | +|
|
|
| 13 | ++- ┌
|
|
| 14 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 15 | +| │ is a usage of an external evidence variable
|
|
| 16 | +| │ Defined in `GHC.Internal.Records'
|
|
| 17 | +| └
|
|
| 18 | +|
|
|
| 19 | +`- ┌
|
|
| 20 | + │ a at NoFieldSelectorQueries.hs:1:1, of type: A -> Int
|
|
| 21 | + │ is a usage of an external evidence variable
|
|
| 22 | + │ Defined at NoFieldSelectorQueries.hs:9:14
|
|
| 23 | + └
|
|
| 24 | + |
|
| 25 | +==========================
|
|
| 26 | +At point (27,19), we found:
|
|
| 27 | +==========================
|
|
| 28 | +┌
|
|
| 29 | +│ $dHasField at NoFieldSelectorQueries.hs:27:1-19, of type: HasField "a" r Int
|
|
| 30 | +│ is an evidence variable bound by a let, depending on: [$dHasField]
|
|
| 31 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:27:1-19
|
|
| 32 | +│ bound at: NoFieldSelectorQueries.hs:27:1-19
|
|
| 33 | +│ Defined at <no location info>
|
|
| 34 | +└
|
|
| 35 | +|
|
|
| 36 | +`- ┌
|
|
| 37 | + │ $dHasField at NoFieldSelectorQueries.hs:27:1-19, of type: HasField "a" r Int
|
|
| 38 | + │ is an evidence variable bound by a HsWrapper
|
|
| 39 | + │ with scope: LocalScope NoFieldSelectorQueries.hs:27:1-19
|
|
| 40 | + │ bound at: NoFieldSelectorQueries.hs:27:1-19
|
|
| 41 | + │ Defined at <no location info>
|
|
| 42 | + └
|
|
| 43 | + |
|
| 44 | +==========================
|
|
| 45 | +At point (30,15), we found:
|
|
| 46 | +==========================
|
|
| 47 | +┌
|
|
| 48 | +│ $dHasField at NoFieldSelectorQueries.hs:30:1-17, of type: HasField "n" B A
|
|
| 49 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 50 | +│ n of Record B]
|
|
| 51 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:30:1-17
|
|
| 52 | +│ bound at: NoFieldSelectorQueries.hs:30:1-17
|
|
| 53 | +│ Defined at <no location info>
|
|
| 54 | +└
|
|
| 55 | +|
|
|
| 56 | ++- ┌
|
|
| 57 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 58 | +| │ is a usage of an external evidence variable
|
|
| 59 | +| │ Defined in `GHC.Internal.Records'
|
|
| 60 | +| └
|
|
| 61 | +|
|
|
| 62 | +`- ┌
|
|
| 63 | + │ n at NoFieldSelectorQueries.hs:30:1-17, of type: B -> A
|
|
| 64 | + │ is a usage of an external evidence variable
|
|
| 65 | + │ Defined at NoFieldSelectorQueries.hs:10:24
|
|
| 66 | + └
|
|
| 67 | + |
|
| 68 | +==========================
|
|
| 69 | +At point (30,17), we found:
|
|
| 70 | +==========================
|
|
| 71 | +┌
|
|
| 72 | +│ $dHasField at NoFieldSelectorQueries.hs:30:1-17, of type: HasField "b" A Char
|
|
| 73 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 74 | +│ b of Record A]
|
|
| 75 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:30:1-17
|
|
| 76 | +│ bound at: NoFieldSelectorQueries.hs:30:1-17
|
|
| 77 | +│ Defined at <no location info>
|
|
| 78 | +└
|
|
| 79 | +|
|
|
| 80 | ++- ┌
|
|
| 81 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 82 | +| │ is a usage of an external evidence variable
|
|
| 83 | +| │ Defined in `GHC.Internal.Records'
|
|
| 84 | +| └
|
|
| 85 | +|
|
|
| 86 | +`- ┌
|
|
| 87 | + │ b at NoFieldSelectorQueries.hs:30:1-17, of type: A -> Char
|
|
| 88 | + │ is a usage of an external evidence variable
|
|
| 89 | + │ Defined at NoFieldSelectorQueries.hs:9:24
|
|
| 90 | + └
|
|
| 91 | + |
|
| 92 | +==========================
|
|
| 93 | +At point (33,16), we found:
|
|
| 94 | +==========================
|
|
| 95 | +┌
|
|
| 96 | +│ $dHasField at NoFieldSelectorQueries.hs:33:1-16, of type: HasField "c" C Float
|
|
| 97 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 98 | +│ c of Record C]
|
|
| 99 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:33:1-16
|
|
| 100 | +│ bound at: NoFieldSelectorQueries.hs:33:1-16
|
|
| 101 | +│ Defined at <no location info>
|
|
| 102 | +└
|
|
| 103 | +|
|
|
| 104 | ++- ┌
|
|
| 105 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 106 | +| │ is a usage of an external evidence variable
|
|
| 107 | +| │ Defined in `GHC.Internal.Records'
|
|
| 108 | +| └
|
|
| 109 | +|
|
|
| 110 | +`- ┌
|
|
| 111 | + │ c at NoFieldSelectorQueries.hs:1:1, of type: C -> Float
|
|
| 112 | + │ is a usage of an external evidence variable
|
|
| 113 | + │ Defined at NoFieldSelectorQueries.hs:12:9
|
|
| 114 | + └
|
|
| 115 | + |
|
| 116 | +==========================
|
|
| 117 | +At point (36,16), we found:
|
|
| 118 | +==========================
|
|
| 119 | +┌
|
|
| 120 | +│ $dHasField at NoFieldSelectorQueries.hs:36:1-16, of type: HasField "c" C Float
|
|
| 121 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 122 | +│ c of Record C]
|
|
| 123 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:36:1-16
|
|
| 124 | +│ bound at: NoFieldSelectorQueries.hs:36:1-16
|
|
| 125 | +│ Defined at <no location info>
|
|
| 126 | +└
|
|
| 127 | +|
|
|
| 128 | ++- ┌
|
|
| 129 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 130 | +| │ is a usage of an external evidence variable
|
|
| 131 | +| │ Defined in `GHC.Internal.Records'
|
|
| 132 | +| └
|
|
| 133 | +|
|
|
| 134 | +`- ┌
|
|
| 135 | + │ c at NoFieldSelectorQueries.hs:1:1, of type: C -> Float
|
|
| 136 | + │ is a usage of an external evidence variable
|
|
| 137 | + │ Defined at NoFieldSelectorQueries.hs:12:9
|
|
| 138 | + └
|
|
| 139 | + |
|
| 140 | +==========================
|
|
| 141 | +At point (40,23), we found:
|
|
| 142 | +==========================
|
|
| 143 | +┌
|
|
| 144 | +│ $dHasField at NoFieldSelectorQueries.hs:1:1, of type: HasField "c" C Float
|
|
| 145 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 146 | +│ c of Record C]
|
|
| 147 | +│ with scope: ModuleScope
|
|
| 148 | +│
|
|
| 149 | +│ Defined at <no location info>
|
|
| 150 | +└
|
|
| 151 | +|
|
|
| 152 | ++- ┌
|
|
| 153 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 154 | +| │ is a usage of an external evidence variable
|
|
| 155 | +| │ Defined in `GHC.Internal.Records'
|
|
| 156 | +| └
|
|
| 157 | +|
|
|
| 158 | +`- ┌
|
|
| 159 | + │ c at NoFieldSelectorQueries.hs:1:1, of type: C -> Float
|
|
| 160 | + │ is a usage of an external evidence variable
|
|
| 161 | + │ Defined at NoFieldSelectorQueries.hs:12:9
|
|
| 162 | + └
|
|
| 163 | + |
|
| 164 | +==========================
|
|
| 165 | +At point (43,15), we found:
|
|
| 166 | +==========================
|
|
| 167 | +┌
|
|
| 168 | +│ $dHasField at NoFieldSelectorQueries.hs:43:1-15, of type: HasField "e" C Int
|
|
| 169 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 170 | +│ e of Record C]
|
|
| 171 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:43:1-15
|
|
| 172 | +│ bound at: NoFieldSelectorQueries.hs:43:1-15
|
|
| 173 | +│ Defined at <no location info>
|
|
| 174 | +└
|
|
| 175 | +|
|
|
| 176 | ++- ┌
|
|
| 177 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 178 | +| │ is a usage of an external evidence variable
|
|
| 179 | +| │ Defined in `GHC.Internal.Records'
|
|
| 180 | +| └
|
|
| 181 | +|
|
|
| 182 | +`- ┌
|
|
| 183 | + │ e at NoFieldSelectorQueries.hs:43:1-15, of type: C -> Int
|
|
| 184 | + │ is a usage of an external evidence variable
|
|
| 185 | + │ Defined at NoFieldSelectorQueries.hs:14:9
|
|
| 186 | + └
|
|
| 187 | + |
|
| 188 | +==========================
|
|
| 189 | +At point (46,15), we found:
|
|
| 190 | +==========================
|
|
| 191 | +┌
|
|
| 192 | +│ $dHasField at NoFieldSelectorQueries.hs:46:1-15, of type: HasField "e" C Int
|
|
| 193 | +│ is an evidence variable bound by a let, depending on: [C:HasField,
|
|
| 194 | +│ e of Record C]
|
|
| 195 | +│ with scope: LocalScope NoFieldSelectorQueries.hs:46:1-15
|
|
| 196 | +│ bound at: NoFieldSelectorQueries.hs:46:1-15
|
|
| 197 | +│ Defined at <no location info>
|
|
| 198 | +└
|
|
| 199 | +|
|
|
| 200 | ++- ┌
|
|
| 201 | +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a
|
|
| 202 | +| │ is a usage of an external evidence variable
|
|
| 203 | +| │ Defined in `GHC.Internal.Records'
|
|
| 204 | +| └
|
|
| 205 | +|
|
|
| 206 | +`- ┌
|
|
| 207 | + │ e at NoFieldSelectorQueries.hs:43:1-15, of type: C -> Int
|
|
| 208 | + │ is a usage of an external evidence variable
|
|
| 209 | + │ Defined at NoFieldSelectorQueries.hs:14:9
|
|
| 210 | + └
|
|
| 211 | + |
| ... | ... | @@ -22,6 +22,11 @@ x = MyRecord { a = "Hello", b = 12, c = MyChild { z = "there" } } |
| 22 | 22 | y = x.a ++ show x.b ++ x.c.z
|
| 23 | 23 | -- ^ ^ ^ ^^
|
| 24 | 24 | -- 1 2 3 45
|
| 25 | +-- ^-^ ^-^ ^-^
|
|
| 26 | +-- 6 7 8
|
|
| 27 | +-- ^---^
|
|
| 28 | +-- 9
|
|
| 29 | + |
|
| 25 | 30 | |
| 26 | 31 | p1,p2,p3,p4 :: (Int,Int)
|
| 27 | 32 | p1 = (22,6)
|
| ... | ... | @@ -30,10 +35,19 @@ p3 = (22,25) |
| 30 | 35 | p4 = (22,28)
|
| 31 | 36 | p5 = (22,29)
|
| 32 | 37 | |
| 38 | +r6 = (p1, (22, 8))
|
|
| 39 | +r7 = ((22,17), p2)
|
|
| 40 | +r8 = (p3, (22, 27))
|
|
| 41 | +r9 = (p3, p5)
|
|
| 42 | + |
|
| 33 | 43 | selectPoint' :: HieFile -> (Int,Int) -> HieAST Int
|
| 34 | 44 | selectPoint' hf loc =
|
| 35 | 45 | maybe (error "point not found") id $ selectPoint hf loc
|
| 36 | 46 | |
| 47 | +selectRange' :: HieFile -> ((Int,Int), (Int, Int)) -> HieAST Int
|
|
| 48 | +selectRange' hf (s, e) =
|
|
| 49 | + maybe (error "range not found") id $ selectRange hf s e
|
|
| 50 | + |
|
| 37 | 51 | main = do
|
| 38 | 52 | (df, hf) <- readTestHie "RecordDotTypes.hie"
|
| 39 | 53 | forM_ [p1,p2,p3,p4,p5] $ \point -> do
|
| ... | ... | @@ -41,3 +55,11 @@ main = do |
| 41 | 55 | let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point
|
| 42 | 56 | forM_ types $ \typ -> do
|
| 43 | 57 | putStrLn (renderHieType df $ recoverFullType typ (hie_types hf))
|
| 58 | + |
|
| 59 | + forM_ [r6, r7, r8, r9] $ \range -> do
|
|
| 60 | + putStr $ "At " ++ showRange range ++ ", got type: "
|
|
| 61 | + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectRange' hf range
|
|
| 62 | + forM_ types $ \typ -> do
|
|
| 63 | + putStrLn (renderHieType df $ recoverFullType typ (hie_types hf))
|
|
| 64 | + where
|
|
| 65 | + showRange (p1, p2) = show p1 ++ " - " ++ show p2 |
| 1 | 1 | At (22,6), got type: MyRecord
|
| 2 | -At (22,20), got type: Integer
|
|
| 2 | +At (22,20), got type: MyRecord -> Integer
|
|
| 3 | 3 | At (22,25), got type: MyRecord
|
| 4 | -At (22,28), got type: String
|
|
| 5 | -At (22,29), got type: String |
|
| \ No newline at end of file | ||
| 4 | +At (22,28), got type: MyChild -> [Char]
|
|
| 5 | +At (22,29), got type: MyChild -> [Char]
|
|
| 6 | +At (22,6) - (22,8), got type: [Char]
|
|
| 7 | +At (22,17) - (22,20), got type: Integer
|
|
| 8 | +At (22,25) - (22,27), got type: MyChild
|
|
| 9 | +At (22,25) - (22,29), got type: [Char] |
| ... | ... | @@ -4,4 +4,4 @@ PartialFieldSelector |
| 4 | 4 | At (18,7), got type: PartialFieldSelector -> Bool
|
| 5 | 5 | At (23,7), got type: PartialFieldSelector
|
| 6 | 6 | At (23,8), got type: PartialFieldSelector
|
| 7 | -At (23,9), got type: Bool |
|
| 7 | +At (23,9), got type: PartialFieldSelector -> Bool |
| ... | ... | @@ -10,3 +10,6 @@ test('T23120', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUti |
| 10 | 10 | test('T24544', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info'])
|
| 11 | 11 | test('HieGadtConSigs', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info'])
|
| 12 | 12 | test('T25709', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info'])
|
| 13 | +test('HasFieldQueries', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info'])
|
|
| 14 | +test('NoFieldSelectorQueries', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info'])
|
|
| 15 | +test('HieTypeable', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) |