diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/GHC/Tc/Gen/Head.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Tc/Instance/Class.hs | 20 | ||||
-rw-r--r-- | compiler/GHC/Tc/Types.hs | 3 |
3 files changed, 23 insertions, 2 deletions
diff --git a/compiler/GHC/Tc/Gen/Head.hs b/compiler/GHC/Tc/Gen/Head.hs index eb5da5ca26..3d6d51ff22 100644 --- a/compiler/GHC/Tc/Gen/Head.hs +++ b/compiler/GHC/Tc/Gen/Head.hs @@ -546,7 +546,9 @@ finish_ambiguous_selector lr@(L _ rdr) parent_type Nothing -> failWithTc (fieldNotInType parent rdr) ; Just gre -> + -- See Note [Unused name reporting and HasField] in GHC.Tc.Instance.Class do { addUsedGRE True gre + ; keepAlive (greMangledName gre) ; return (greMangledName gre) } } } } } -- This field name really is ambiguous, so add a suitable "ambiguous diff --git a/compiler/GHC/Tc/Instance/Class.hs b/compiler/GHC/Tc/Instance/Class.hs index 54749efcbf..84b523eb93 100644 --- a/compiler/GHC/Tc/Instance/Class.hs +++ b/compiler/GHC/Tc/Instance/Class.hs @@ -30,7 +30,7 @@ import GHC.Builtin.Types import GHC.Builtin.Types.Prim( eqPrimTyCon, eqReprPrimTyCon ) import GHC.Builtin.Names -import GHC.Types.Name.Reader( lookupGRE_FieldLabel ) +import GHC.Types.Name.Reader( lookupGRE_FieldLabel, greMangledName ) import GHC.Types.SafeHaskell import GHC.Types.Name ( Name, pprDefinedAt ) import GHC.Types.Var.Env ( VarEnv ) @@ -672,6 +672,20 @@ may be solved by a user-supplied HasField instance. Similarly, if we encounter a HasField constraint where the field is not a literal string, or does not belong to the type, then we fall back on the normal constraint solver behaviour. + + +Note [Unused name reporting and HasField] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When a HasField constraint is solved by the type-checker, we must record a use +of the corresponding field name, as otherwise it might be reported as unused. +See #19213. We need to call keepAlive to add the name to the tcg_keep set, +which accumulates names used by the constraint solver, as described by +Note [Tracking unused binding and imports] in GHC.Tc.Types. + +We need to call addUsedGRE as well because there may be a deprecation warning on +the field, which will be reported by addUsedGRE. But calling addUsedGRE without +keepAlive is not enough, because the field might be defined locally, and +addUsedGRE extends tcg_used_gres with imported GREs only. -} -- See Note [HasField instances] @@ -721,7 +735,9 @@ matchHasField dflags short_cut clas tys -- cannot have an existentially quantified type), and -- it must not be higher-rank. ; if not (isNaughtyRecordSelector sel_id) && isTauTy sel_ty - then do { addUsedGRE True gre + then do { -- See Note [Unused name reporting and HasField] + addUsedGRE True gre + ; keepAlive (greMangledName gre) ; return OneInst { cir_new_theta = theta , cir_mk_ev = mk_ev , cir_what = BuiltinInstance } } diff --git a/compiler/GHC/Tc/Types.hs b/compiler/GHC/Tc/Types.hs index aad52c5d93..2a54afc570 100644 --- a/compiler/GHC/Tc/Types.hs +++ b/compiler/GHC/Tc/Types.hs @@ -680,6 +680,9 @@ We gather three sorts of usage information Coercible solver updates tcg_keep's TcRef whenever it encounters a use of `coerce` that crosses newtype boundaries. + (e) Record fields that are used to solve HasField constraints + (see Note [Unused name reporting and HasField] in GHC.Tc.Instance.Class) + The tcg_keep field is used in two distinct ways: * Desugar.addExportFlagsAndRules. Where things like (a-c) are locally |