Hannes Siebenhandl pushed to branch wip/fendor/has-field-hie at Glasgow Haskell Compiler / GHC Commits: ca321a62 by fendor at 2026-09-17T11:49:20+02:00 Allow any `Id` to be used for HIE evidence HIE evidence is used to show how a constraint has been solved and allows users to go directly to the definition or introduction of a particular evidence variable. So far, we only looked at evidence introduced by type class variables, but some evidence terms refer to other variables as well, such as record selectors. Such evidence terms add additional details and source locations. For generated evidence, such as `HasField` evidence to support `-XRecordDotSyntax`, the type class evidence is lacking and doesn't give us any usable source span pointing to the actual record selector. See this example evidence: $dHasField_aLw = GHC.Internal.Records.C:HasField @GHC.Internal.Types.Symbol @GHC.Internal.Types.LiftedRep @GHC.Internal.Types.LiftedRep @"foo" @Foo @Int (foo `cast` (<Foo -> Int>_R :: (Foo -> Int) ~R# (Foo -> Int))) The free variables of this term are `{C:HasField, foo}`. `foo` is the record selector from the type `Foo` and is crucial to guide users how this evidence is constructed, as the evidence `HasField` is not helpful. During HIE generation, we now take any `Id` into account to provide additional source spans to point to user to the definition site of the record selector. As a direct consequence, this allows HLS to implement a limited form of `Goto Definition` for expressions of the form `x.foo`, where `x :: Foo`. Capturing more `Id`s for evidence may have some side effects that are somewhat tricky to predict, since the tests are quite lacking. - - - - - e99b2061 by fendor at 2026-09-17T11:49:32+02:00 Add additional details to evidence bindings Evidence bindings can be all sorts of things, such as tpe class evidence, a record selector or other builtin constructs such as `Typeable`. For some special evidence binding dependencies, we can include additional information for the user. For example, when we have a record selector, we can say from which type the record selector originates from. - - - - - edb461ac by fendor at 2026-09-17T11:49:36+02:00 Typeable test - - - - - 10 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 - 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.stdout - testsuite/tests/hiefile/should_run/RecordDotTypes.stdout - testsuite/tests/hiefile/should_run/all.T Changes: ===================================== changelog.d/record-dot-evidence ===================================== @@ -0,0 +1,12 @@ +section: compiler +synopsis: Record selector functions as evidence for `HasField` constraints during .hie file generation. +description: { + We record the record selector `foo` of an expression such as `f.foo` as evidence for + solving the constraint `HasField "foo" record ty`. + + This allows us to point to the definition source location of the record selector `foo`, allowing + users to jump to definition using the evidence variables. +} + +issues: #25418 +mrs: !16694 ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -23,7 +23,6 @@ import GHC.Core.DataCon ( dataConWrapperType ) import GHC.Core.Type ( Type, ForAllTyFlag(..) ) import GHC.Core.TyCon ( TyCon, tyConClass_maybe ) import GHC.Core.InstEnv -import GHC.Core.Predicate ( isEvId ) import GHC.Hs import GHC.Hs.Syn.Type @@ -33,7 +32,7 @@ import GHC.Types.Basic import GHC.Types.UnresolvedImport ( isGeneratedImport ) import GHC.Types.FieldLabel import GHC.Types.Avail ( Avails ) -import GHC.Types.Id ( isDataConId_maybe ) +import GHC.Types.Id ( isDataConId_maybe, isId, idDetails ) import GHC.Types.Name ( Name, nameSrcSpan, nameUnique, wiredInNameTyThing_maybe, getName ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnv, lookupNameEnv ) import GHC.Types.Name.Reader ( RecFieldInfo(..), WithUserRdr(..) ) @@ -682,7 +681,7 @@ instance ToHie (Context (Located (WithUserRdr Name))) where hieEvIdsOfTerm :: EvTerm -> [EvId] -- Returns only EvIds satisfying relevantEvId -hieEvIdsOfTerm = runFVSelectiveList isEvId . evTermFVs +hieEvIdsOfTerm = runFVSelectiveList isId . evTermFVs instance ToHie (EvBindContext (LocatedA TcEvBinds)) where toHie (EvBindContext sc sp (L span (EvBinds bs))) ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -598,17 +598,79 @@ instance Outputable EvVarSource where ppr (EvInstBind True cls) = text "bound due to a superclass of " <+> ppr cls ppr (EvLetBind deps) = text "bound by a let, depending on:" <+> ppr deps +-- | Evidence binding dependency with additional details. +data EvBindDep + = EvidenceVar Name + -- ^ Evidence variable such as a type class constructor. + -- + -- For example, @C:HasField@, @$dShow@ (dictionaries) or @$fCList@. + -- + -- This is the default representation of a 'EvBindDep'. + | RecordField + -- ^ Evidence variable of a record selector. + -- + -- This is for example generated with @-XOverloadedRecordDot@, where + -- the evidence includes a reference to which record selector is used + -- to implement @getField@. + Name + -- ^ 'Name' of the record selector + Name + -- ^ 'Name' of the parent type. + | TypeableEvidence + -- ^ Evidence of a @Typeable@ constraint. + Name + -- ^ Name of the type the evidence was generated for. + deriving (Eq, Ord) + +instance Outputable EvBindDep where + ppr = \ case + EvidenceVar n -> ppr n + RecordField sel parent -> ppr sel <+> text "of Record" <+> ppr parent + TypeableEvidence n -> ppr n <+> text "bound by Typeable" + +evBindDepName :: EvBindDep -> Name +evBindDepName = \ case + EvidenceVar n -> n + RecordField selector _record -> selector + TypeableEvidence n -> n + +evBindDepHieName :: EvBindDep -> HieName +evBindDepHieName = toHieName . evBindDepName + +instance Binary EvBindDep where + put_ bh = \ case + EvidenceVar n -> do + putByte bh 0 + put_ bh n + RecordField n sel -> do + putByte bh 1 + put_ bh n + put_ bh sel + TypeableEvidence n -> do + putByte bh 2 + put_ bh n + + get bh = + getByte bh >>= \ case + 0 -> EvidenceVar <$> get bh + 1 -> RecordField <$> get bh <*> get bh + 2 -> TypeableEvidence <$> get bh + t -> fail $ "EvBindDep: Unknown tag: " ++ show t + -- | Eq/Ord instances compare on the converted HieName, -- as non-exported names may have different uniques after -- a roundtrip -newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [Name] } +newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [EvBindDep] } deriving Outputable +evBindDepsNames :: EvBindDeps -> [Name] +evBindDepsNames = map evBindDepName . getEvBindDeps + instance Eq EvBindDeps where - (==) = coerce ((==) `on` map toHieName) + (==) = coerce ((==) `on` map evBindDepHieName) instance Ord EvBindDeps where - compare = coerce (compare `on` map toHieName) + compare = coerce (compare `on` map evBindDepHieName) instance Binary EvBindDeps where put_ bh (EvBindDeps xs) = put_ bh xs ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -145,7 +145,7 @@ getEvidenceTree refmap var = go emptyNameSet var det <- S.toList $ identInfo dets case det of EvidenceVarBind src@(EvLetBind (getEvBindDeps -> xs)) scp spn -> - pure $ Just ((src,scp,spn),mapMaybe (go $ extendNameSet seen var) xs) + pure $ Just ((src,scp,spn),mapMaybe (go (extendNameSet seen var) . evBindDepName) xs) EvidenceVarBind src scp spn -> pure $ Just ((src,scp,spn),[]) _ -> pure Nothing pure $ Tree.Node (EvidenceInfo var sp typ (Just evdet)) children @@ -390,7 +390,7 @@ definedInAsts asts n = case nameSrcSpan n of getEvidenceBindDeps :: ContextInfo -> [Name] getEvidenceBindDeps (EvidenceVarBind (EvLetBind xs) _ _) = - getEvBindDeps xs + evBindDepsNames xs getEvidenceBindDeps _ = [] isEvidenceBind :: ContextInfo -> Bool ===================================== testsuite/tests/hiefile/should_run/HasFieldQueries.stdout ===================================== @@ -3,16 +3,23 @@ At point (13,17), we found: ========================== ┌ │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ field1 of Record Thing] │ with scope: ModuleScope │ │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:9:21 └ ========================== @@ -23,16 +30,23 @@ At point (16,27), we found: ========================== ┌ │ $dHasField at HasFieldQueries.hs:16:1-32, of type: HasField "field1" Thing Char -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ field1 of Record Thing] │ with scope: LocalScope HasFieldQueries.hs:16:1-32 │ bound at: HasFieldQueries.hs:16:1-32 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:9:21 └ ========================== @@ -40,16 +54,23 @@ At point (23,17), we found: ========================== ┌ │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "nested1" NestedThing Thing -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ nested1 of Record NestedThing] │ with scope: ModuleScope │ │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ nested1 at HasFieldQueries.hs:1:1, of type: NestedThing -> Thing │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:20:34 └ ========================== @@ -65,16 +86,23 @@ At point (23,25), we found: | `- ┌ │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char - │ is an evidence variable bound by a let, depending on: [C:HasField] + │ is an evidence variable bound by a let, depending on: [C:HasField, + │ field1 of Record Thing] │ with scope: ModuleScope │ │ Defined at <no location info> └ | + +- ┌ + | │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Internal.Records' + | └ + | `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:9:21 └ ========================== @@ -147,16 +175,23 @@ At point (37,14), we found: | `- ┌ │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char - │ is an evidence variable bound by a let, depending on: [C:HasField] + │ is an evidence variable bound by a let, depending on: [C:HasField, + │ field1 of Record Thing] │ with scope: ModuleScope │ │ Defined at <no location info> └ | + +- ┌ + | │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Internal.Records' + | └ + | `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:9:21 └ ========================== @@ -164,16 +199,23 @@ At point (41,21), we found: ========================== ┌ │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "nested1" NestedThing Thing -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ nested1 of Record NestedThing] │ with scope: ModuleScope │ │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ nested1 at HasFieldQueries.hs:1:1, of type: NestedThing -> Thing │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:20:34 └ ========================== @@ -181,15 +223,22 @@ At point (41,30), we found: ========================== ┌ │ $dHasField at HasFieldQueries.hs:1:1, of type: HasField "field1" Thing Char -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ field1 of Record Thing] │ with scope: ModuleScope │ │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at HasFieldQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ field1 at HasFieldQueries.hs:1:1, of type: Thing -> Char │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at HasFieldQueries.hs:9:21 └ ===================================== testsuite/tests/hiefile/should_run/HieTypeable.hs ===================================== @@ -0,0 +1,28 @@ +module Main where + +import Data.Dynamic +import Data.Typeable +import TestUtils + +data Thing = Thing {field1 :: Char, field2 :: Bool} + deriving (Show, Eq) + +castFromDynamic :: Dynamic -> Maybe Thing +castFromDynamic d = fromDynamic d + -- ^ this is the point + +rep :: Thing -> TypeRep +rep d = typeOf d + -- ^ this is the point + +points = + [ (11,21) + , (15,10) + ] + +main = do + (df, hf) <- readTestHie "HieTypeable.hie" + let refmap = generateReferencesMap $ getAsts $ hie_asts hf + + traverse (explainEv df hf refmap) points + return () ===================================== testsuite/tests/hiefile/should_run/HieTypeable.stdout ===================================== @@ -0,0 +1,30 @@ +========================== +At point (11,21), we found: +========================== +┌ +│ $dTypeable at HieTypeable.hs:1:1, of type: Typeable Thing +│ is an evidence variable bound by a let, depending on: [$dTypeable] +│ with scope: ModuleScope +│ +│ Defined at <no location info> +└ +| +`- ┌ + │ $dTypeable at HieTypeable.hs:1:1, of type: Typeable Thing + │ is an evidence variable bound by a let, depending on: [] + │ with scope: ModuleScope + │ + │ Defined at <no location info> + └ + +========================== +At point (15,10), we found: +========================== +┌ +│ $dTypeable at HieTypeable.hs:1:1, of type: Typeable Thing +│ is an evidence variable bound by a let, depending on: [] +│ with scope: ModuleScope +│ +│ Defined at <no location info> +└ + ===================================== testsuite/tests/hiefile/should_run/NoFieldSelectorQueries.stdout ===================================== @@ -3,16 +3,23 @@ At point (23,16), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:1:1, of type: HasField "a" A Int -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ a of Record A] │ with scope: ModuleScope │ │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ a at NoFieldSelectorQueries.hs:1:1, of type: A -> Int │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:9:14 └ ========================== @@ -39,16 +46,23 @@ At point (30,15), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:30:1-17, of type: HasField "n" B A -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ n of Record B] │ with scope: LocalScope NoFieldSelectorQueries.hs:30:1-17 │ bound at: NoFieldSelectorQueries.hs:30:1-17 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ n at NoFieldSelectorQueries.hs:30:1-17, of type: B -> A │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:10:24 └ ========================== @@ -56,16 +70,23 @@ At point (30,17), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:30:1-17, of type: HasField "b" A Char -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ b of Record A] │ with scope: LocalScope NoFieldSelectorQueries.hs:30:1-17 │ bound at: NoFieldSelectorQueries.hs:30:1-17 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ b at NoFieldSelectorQueries.hs:30:1-17, of type: A -> Char │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:9:24 └ ========================== @@ -73,16 +94,23 @@ At point (33,16), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:33:1-16, of type: HasField "c" C Float -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ c of Record C] │ with scope: LocalScope NoFieldSelectorQueries.hs:33:1-16 │ bound at: NoFieldSelectorQueries.hs:33:1-16 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ c at NoFieldSelectorQueries.hs:1:1, of type: C -> Float │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:12:9 └ ========================== @@ -90,16 +118,23 @@ At point (36,16), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:36:1-16, of type: HasField "c" C Float -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ c of Record C] │ with scope: LocalScope NoFieldSelectorQueries.hs:36:1-16 │ bound at: NoFieldSelectorQueries.hs:36:1-16 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ c at NoFieldSelectorQueries.hs:1:1, of type: C -> Float │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:12:9 └ ========================== @@ -107,16 +142,23 @@ At point (40,23), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:1:1, of type: HasField "c" C Float -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ c of Record C] │ with scope: ModuleScope │ │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ c at NoFieldSelectorQueries.hs:1:1, of type: C -> Float │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:12:9 └ ========================== @@ -124,16 +166,23 @@ At point (43,15), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:43:1-15, of type: HasField "e" C Int -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ e of Record C] │ with scope: LocalScope NoFieldSelectorQueries.hs:43:1-15 │ bound at: NoFieldSelectorQueries.hs:43:1-15 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ e at NoFieldSelectorQueries.hs:43:1-15, of type: C -> Int │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:14:9 └ ========================== @@ -141,15 +190,22 @@ At point (46,15), we found: ========================== ┌ │ $dHasField at NoFieldSelectorQueries.hs:46:1-15, of type: HasField "e" C Int -│ is an evidence variable bound by a let, depending on: [C:HasField] +│ is an evidence variable bound by a let, depending on: [C:HasField, +│ e of Record C] │ with scope: LocalScope NoFieldSelectorQueries.hs:46:1-15 │ bound at: NoFieldSelectorQueries.hs:46:1-15 │ Defined at <no location info> └ | ++- ┌ +| │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Internal.Records' +| └ +| `- ┌ - │ C:HasField at NoFieldSelectorQueries.hs:1:1, of type: forall {k} (x :: k) r a. (r -> a) -> HasField x r a + │ e at NoFieldSelectorQueries.hs:43:1-15, of type: C -> Int │ is a usage of an external evidence variable - │ Defined in `GHC.Internal.Records' + │ Defined at NoFieldSelectorQueries.hs:14:9 └ ===================================== testsuite/tests/hiefile/should_run/RecordDotTypes.stdout ===================================== @@ -1,9 +1,9 @@ At (22,6), got type: MyRecord At (22,20), got type: MyRecord -> Integer At (22,25), got type: MyRecord -At (22,28), got type: MyChild -> String -At (22,29), got type: MyChild -> String -At (22,6) - (22,8), got type: String +At (22,28), got type: MyChild -> [Char] +At (22,29), got type: MyChild -> [Char] +At (22,6) - (22,8), got type: [Char] At (22,17) - (22,20), got type: Integer At (22,25) - (22,27), got type: MyChild -At (22,25) - (22,29), got type: String +At (22,25) - (22,29), got type: [Char] ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -12,3 +12,4 @@ test('HieGadtConSigs', [extra_run_opts('"' + config.libdir + '"'), extra_files([ test('T25709', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) test('HasFieldQueries', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) test('NoFieldSelectorQueries', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('HieTypeable', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dece0fbb4d3d9ffc9021f5e8933e0a5... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dece0fbb4d3d9ffc9021f5e8933e0a5... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Hannes Siebenhandl (@fendor)