Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

8 changed files:

Changes:

  • compiler/GHC/HsToCore/Expr.hs
    ... ... @@ -721,6 +721,15 @@ ds_app (XExpr (ConLikeTc con)) _hs_args core_args
    721 721
     ds_app (XExpr (HsRecSelTc (FieldOcc { foLabel = L _ sel_id }))) _hs_args core_args
    
    722 722
       = ds_app_rec_sel sel_id sel_id core_args
    
    723 723
     
    
    724
    +ds_app (XExpr (ExpandedThingTc _orig e)) hs_args core_args
    
    725
    +  = ds_app e hs_args core_args
    
    726
    +  -- NB: this is important for the 'getField' case of 'ds_app_var', which needs
    
    727
    +  -- to see all type arguments to 'getField' at once, while for record field
    
    728
    +  -- projections such as (.fld) we may get:
    
    729
    +  --
    
    730
    +  --   XExpr (ExpandedThingTc (.fld) (getField @Symbol @LiftedRep @LiftedRep "fld"))
    
    731
    +  --     `HsAppType` rec_ty `HsAppType` fld
    
    732
    +
    
    724 733
     ds_app (HsVar _ lfun) hs_args core_args
    
    725 734
       = ds_app_var lfun hs_args core_args
    
    726 735
     
    
    ... ... @@ -736,8 +745,10 @@ ds_app_var (L loc fun_id) hs_args core_args
    736 745
       -----------------------
    
    737 746
       -- Deal with getField applications. General form:
    
    738 747
       --   getField
    
    739
    -  --     @GHC.Types.Symbol                        {k}
    
    740
    -  --     @"sel"                                   x_ty
    
    748
    +  --     @Symbol                                  {k}
    
    749
    +  --     @LiftedRep                               {r_rep}
    
    750
    +  --     @LiftedRep                               {a_rep}
    
    751
    +  --     @"sel"                                   fld
    
    741 752
       --     @T                                       r_ty
    
    742 753
       --     @Int                                     a_ty
    
    743 754
       --     ($dHasField :: HasField "sel" T Int)     dict
    

  • compiler/GHC/HsToCore/Pmc.hs
    ... ... @@ -375,6 +375,10 @@ Finally, there are two more items addressing -XOverloadedRecordDot:
    375 375
       the (IRS6) warning in the typechecker for a `HasField` constraint that
    
    376 376
       arises from a record-dot HsGetField occurrence.  Happily, this is easy to do
    
    377 377
       by looking at its `CtOrigin`. Tested in T24891.
    
    378
    +
    
    379
    +  The same applies for record field projection operators such as (.fld) and
    
    380
    +  (.fld1.fld2), which have different 'CtOrigin's. The 'isHasFieldOrigin'
    
    381
    +  function catches those as well. Tested in T26686.
    
    378 382
     -}
    
    379 383
     
    
    380 384
     pmcRecSel :: Id       -- ^ Id of the selector
    

  • compiler/GHC/Tc/Errors.hs
    ... ... @@ -97,6 +97,7 @@ import Data.Ord ( comparing )
    97 97
     import Data.Either        ( partitionEithers )
    
    98 98
     import Data.Map.Strict (Map)
    
    99 99
     import qualified Data.Map.Strict as Map
    
    100
    +import qualified Data.Semigroup as Semi
    
    100 101
     
    
    101 102
     {-
    
    102 103
     ************************************************************************
    
    ... ... @@ -2714,15 +2715,34 @@ hasFieldInfo_maybe rdr_env fam_inst_envs item
    2714 2715
     
    
    2715 2716
       -- (HF2e) It's a custom HasField constraint, not the one from GHC.Records.
    
    2716 2717
       | Just (tc, _) <- splitTyConApp_maybe (errorItemPred item)
    
    2717
    -  , getOccString tc == "HasField"
    
    2718
    -  , isHasFieldOrigin (errorItemOrigin item)
    
    2719
    -  = return $ Just $ CustomHasField tc
    
    2718
    +  = do { rebindable_syntax <- xoptM LangExt.RebindableSyntax
    
    2719
    +       ; return $
    
    2720
    +           if want_custom_hasfield_msg tc rebindable_syntax
    
    2721
    +           then Just $ CustomHasField tc
    
    2722
    +           else Nothing
    
    2723
    +       }
    
    2720 2724
     
    
    2721 2725
       | otherwise
    
    2722 2726
       = return Nothing
    
    2723 2727
     
    
    2724 2728
       where
    
    2725 2729
     
    
    2730
    +    orig = errorItemOrigin item
    
    2731
    +
    
    2732
    +    want_custom_hasfield_msg tc rebindable_syntax
    
    2733
    +      | getOccString tc == "HasField"
    
    2734
    +      = Semi.getAny $ foldMapCtOrigin (Semi.Any . is_has_field) orig
    
    2735
    +      | otherwise
    
    2736
    +      = False
    
    2737
    +      where
    
    2738
    +        -- Handle custom 'getField'/'setField' with RebindableSyntax.
    
    2739
    +        is_has_field (OccurrenceOf n)
    
    2740
    +          | rebindable_syntax
    
    2741
    +          , getOccString n `elem` ["getField", "setField"]
    
    2742
    +          = True
    
    2743
    +        is_has_field o
    
    2744
    +          = isHasFieldOrigin o
    
    2745
    +
    
    2726 2746
         get_parent_nm :: Name -> TcM (Maybe (Either PatSyn TyCon))
    
    2727 2747
         get_parent_nm nm =
    
    2728 2748
           do { fld_id <- tcLookupId nm
    
    ... ... @@ -2762,22 +2782,6 @@ hasField_maybe pred =
    2762 2782
       -- NB: we deliberately don't handle rebound 'HasField' (with -XRebindableSyntax),
    
    2763 2783
       -- as GHC only has built-in instances for the built-in 'HasField' class.
    
    2764 2784
     
    
    2765
    --- | Does this constraint arise from GHC internal mechanisms that desugar to
    
    2766
    --- usage of the 'HasField' typeclass (e.g. OverloadedRecordDot, etc)?
    
    2767
    ---
    
    2768
    --- Just used heuristically to decide whether to print an informative message to
    
    2769
    --- the user (see (H2e) in Note [Error messages for unsolved HasField constraints]).
    
    2770
    -isHasFieldOrigin :: CtOrigin -> Bool
    
    2771
    -isHasFieldOrigin = \case
    
    2772
    -  OccurrenceOf n ->
    
    2773
    -    -- A heuristic...
    
    2774
    -    getOccString n `elem` ["getField", "setField"]
    
    2775
    -  OccurrenceOfRecSel {} -> True
    
    2776
    -  RecordUpdOrigin {} -> True
    
    2777
    -  RecordFieldProjectionOrigin {} -> True
    
    2778
    -  GetFieldOrigin {} -> True
    
    2779
    -  _ -> False
    
    2780
    -
    
    2781 2785
     -----------------------
    
    2782 2786
     -- relevantBindings looks at the value environment and finds values whose
    
    2783 2787
     -- types mention any of the offending type variables.  It has to be
    

  • compiler/GHC/Tc/Instance/Class.hs
    ... ... @@ -20,7 +20,7 @@ import GHC.Tc.Instance.Typeable
    20 20
     import GHC.Tc.Utils.TcMType
    
    21 21
     import GHC.Tc.Types.Evidence
    
    22 22
     import GHC.Tc.Types.CtLoc
    
    23
    -import GHC.Tc.Types.Origin ( InstanceWhat (..), SafeOverlapping, CtOrigin(GetFieldOrigin) )
    
    23
    +import GHC.Tc.Types.Origin ( InstanceWhat (..), SafeOverlapping, isHasFieldOrigin )
    
    24 24
     import GHC.Tc.Instance.Family( tcGetFamInstEnvs, tcLookupDataFamInst, FamInstEnvs )
    
    25 25
     
    
    26 26
     import GHC.Rename.Env( addUsedGRE, addUsedDataCons, DeprecationWarnings (..) )
    
    ... ... @@ -1275,8 +1275,8 @@ warnIncompleteRecSel :: DynFlags -> Id -> CtLoc -> TcM ()
    1275 1275
     -- Warn about incomplete record selectors
    
    1276 1276
     -- See (IRS6) in Note [Detecting incomplete record selectors] in GHC.HsToCore.Pmc
    
    1277 1277
     warnIncompleteRecSel dflags sel_id ct_loc
    
    1278
    -  | not (isGetFieldOrigin (ctLocOrigin ct_loc))
    
    1279
    -      -- isGetFieldOrigin: see (IRS7) in
    
    1278
    +  | not $ isHasFieldOrigin (ctLocOrigin ct_loc)
    
    1279
    +      -- isHasFieldOrigin: see (IRS7) in
    
    1280 1280
           -- Note [Detecting incomplete record selectors] in GHC.HsToCore.Pmc
    
    1281 1281
       , RecSelId { sel_cons = RSI { rsi_undef = fallible_cons } } <- idDetails sel_id
    
    1282 1282
       , not (null fallible_cons)
    
    ... ... @@ -1288,11 +1288,6 @@ warnIncompleteRecSel dflags sel_id ct_loc
    1288 1288
       where
    
    1289 1289
         maxCons = maxUncoveredPatterns dflags
    
    1290 1290
     
    
    1291
    -    -- GHC.Tc.Gen.App.tcInstFun arranges that the CtOrigin of (r.x) is GetFieldOrigin,
    
    1292
    -    -- despite the expansion to (getField @"x" r)
    
    1293
    -    isGetFieldOrigin (GetFieldOrigin {}) = True
    
    1294
    -    isGetFieldOrigin _                   = False
    
    1295
    -
    
    1296 1291
     lookupHasFieldLabel
    
    1297 1292
       :: FamInstEnvs -> GlobalRdrEnv -> [Type]
    
    1298 1293
       -> Maybe ( Name          -- Name of the record selector
    

  • compiler/GHC/Tc/Types/Origin.hs
    ... ... @@ -16,7 +16,8 @@ module GHC.Tc.Types.Origin (
    16 16
       CtOrigin(..), exprCtOrigin, lexprCtOrigin, matchesCtOrigin, grhssCtOrigin,
    
    17 17
       invisibleOrigin_maybe, isVisibleOrigin, toInvisibleOrigin,
    
    18 18
       pprCtOrigin, pprCtOriginBriefly, isGivenOrigin,
    
    19
    -  defaultReprEqOrigins, isWantedSuperclassOrigin,
    
    19
    +  foldMapCtOrigin,
    
    20
    +  defaultReprEqOrigins, isWantedSuperclassOrigin, isHasFieldOrigin,
    
    20 21
       ClsInstOrQC(..), NakedScFlag(..), NonLinearPatternReason(..),
    
    21 22
       HsImplicitLiftSplice(..),
    
    22 23
       StandaloneDeriv,
    
    ... ... @@ -52,6 +53,8 @@ import GHC.Tc.Utils.TcType
    52 53
     
    
    53 54
     import GHC.Hs
    
    54 55
     
    
    56
    +import GHC.Builtin.Names (getFieldName)
    
    57
    +
    
    55 58
     import GHC.Core.DataCon
    
    56 59
     import GHC.Core.ConLike
    
    57 60
     import GHC.Core.TyCon
    
    ... ... @@ -79,6 +82,8 @@ import GHC.Types.Unique.Supply
    79 82
     import qualified Data.Kind as Hs
    
    80 83
     import Data.List.NonEmpty (NonEmpty (..))
    
    81 84
     import Data.Maybe (isNothing)
    
    85
    +import qualified Data.Semigroup as Semi
    
    86
    +import GHC.Generics
    
    82 87
     
    
    83 88
     {- *********************************************************************
    
    84 89
     *                                                                      *
    
    ... ... @@ -993,6 +998,95 @@ pprNonLinearPatternReason PatternSynonymReason = parens (text "pattern synonyms
    993 998
     pprNonLinearPatternReason ViewPatternReason = parens (text "view patterns aren't linear")
    
    994 999
     pprNonLinearPatternReason OtherPatternReason = empty
    
    995 1000
     
    
    1001
    +
    
    1002
    +{- *********************************************************************
    
    1003
    +*                                                                      *
    
    1004
    +                     Recursing through CtOrigin
    
    1005
    +*                                                                      *
    
    1006
    +********************************************************************* -}
    
    1007
    +
    
    1008
    +-- | Fold over a 'CtOrigin', looking through all recursive
    
    1009
    +-- occurrences of 'CtOrigin' within 'CtOrigin'.
    
    1010
    +foldMapCtOrigin :: forall m. Semigroup m => (CtOrigin -> m) -> CtOrigin -> m
    
    1011
    +foldMapCtOrigin f = go
    
    1012
    +  where
    
    1013
    +    go :: CtOrigin -> m
    
    1014
    +    go orig =
    
    1015
    +      case orig of
    
    1016
    +        KindEqOrigin _ _ o _ -> recur o
    
    1017
    +        CycleBreakerOrigin o -> recur o
    
    1018
    +        WantedSuperclassOrigin _ o -> recur o
    
    1019
    +        DefaultReprEqOrigin _ _ o -> recur o
    
    1020
    +        ScOrigin cls_or_qc _sc_flag ->
    
    1021
    +          case cls_or_qc of
    
    1022
    +            IsQC _ o -> recur o
    
    1023
    +            IsClsInst -> f orig
    
    1024
    +
    
    1025
    +        -- Explicit pattern match on remaining constructors, in order to get
    
    1026
    +        -- better pattern-match warnings when constructors are changed or
    
    1027
    +        -- added/removed. This isn't entirely fool-proof, as someone may still
    
    1028
    +        -- change the type of one of the fields and hide a 'CtOrigin' inside.
    
    1029
    +        --
    
    1030
    +        -- This approach was chosen instead of using 'syb'/'GHC.Generics',
    
    1031
    +        -- because those would require deriving 'Data.Data'/'Generic' on
    
    1032
    +        -- a huge number of datatypes.
    
    1033
    +        GivenOrigin {} -> f orig
    
    1034
    +        GivenSCOrigin {} -> f orig
    
    1035
    +        OccurrenceOf {} -> f orig
    
    1036
    +        OccurrenceOfRecSel {} -> f orig
    
    1037
    +        AppOrigin {} -> f orig
    
    1038
    +        SpecPragOrigin {} -> f orig
    
    1039
    +        TypeEqOrigin {}-> f orig
    
    1040
    +        IPOccOrigin {} -> f orig
    
    1041
    +        OverLabelOrigin {} -> f orig
    
    1042
    +        LiteralOrigin {} -> f orig
    
    1043
    +        QualLiteralOrigin {} -> f orig
    
    1044
    +        NegateOrigin {} -> f orig
    
    1045
    +        ArithSeqOrigin {} -> f orig
    
    1046
    +        AssocFamPatOrigin {} -> f orig
    
    1047
    +        SectionOrigin {} -> f orig
    
    1048
    +        GetFieldOrigin {} -> f orig
    
    1049
    +        RecordFieldProjectionOrigin {} -> f orig
    
    1050
    +        TupleOrigin {} -> f orig
    
    1051
    +        ExprSigOrigin {} -> f orig
    
    1052
    +        PatSigOrigin {} -> f orig
    
    1053
    +        PatOrigin {} -> f orig
    
    1054
    +        ProvCtxtOrigin {} -> f orig
    
    1055
    +        RecordUpdOrigin {} -> f orig
    
    1056
    +        ViewPatOrigin {} -> f orig
    
    1057
    +        DerivOrigin {} -> f orig
    
    1058
    +        DerivOriginDC {} -> f orig
    
    1059
    +        DerivOriginCoerce {}  -> f orig
    
    1060
    +        DefaultOrigin {} -> f orig
    
    1061
    +        DoOrigin {} -> f orig
    
    1062
    +        DoPatOrigin {} -> f orig
    
    1063
    +        MCompOrigin {} -> f orig
    
    1064
    +        MCompPatOrigin {} -> f orig
    
    1065
    +        ProcOrigin {} -> f orig
    
    1066
    +        ArrowCmdOrigin {} -> f orig
    
    1067
    +        AnnOrigin {} -> f orig
    
    1068
    +        FunDepOrigin {} -> f orig
    
    1069
    +        ExprHoleOrigin {} -> f orig
    
    1070
    +        TypeHoleOrigin {} -> f orig
    
    1071
    +        PatCheckOrigin {} -> f orig
    
    1072
    +        ListOrigin {} -> f orig
    
    1073
    +        IfThenElseOrigin {} -> f orig
    
    1074
    +        BracketOrigin {} -> f orig
    
    1075
    +        StaticOrigin {} -> f orig
    
    1076
    +        ImpedanceMatching {} -> f orig
    
    1077
    +        Shouldn'tHappenOrigin {} -> f orig
    
    1078
    +        InstProvidedOrigin {} -> f orig
    
    1079
    +        NonLinearPatternOrigin {} -> f orig
    
    1080
    +        OmittedFieldOrigin {} -> f orig
    
    1081
    +        UsageEnvironmentOf {} -> f orig
    
    1082
    +        FRROrigin {} -> f orig
    
    1083
    +        InstanceSigOrigin {} -> f orig
    
    1084
    +        AmbiguityCheckOrigin {} -> f orig
    
    1085
    +        ImplicitLiftOrigin {} -> f orig
    
    1086
    +
    
    1087
    +      where
    
    1088
    +        recur o = f orig Semi.<> go o
    
    1089
    +
    
    996 1090
     {- *********************************************************************
    
    997 1091
     *                                                                      *
    
    998 1092
                    Defaulting of representational equalities
    
    ... ... @@ -1004,21 +1098,10 @@ pprNonLinearPatternReason OtherPatternReason = empty
    1004 1098
     -- That is, this function extracts all occurrences of the 'DefaultReprEqOrigin'
    
    1005 1099
     -- constructor from within a 'CtOrigin'.
    
    1006 1100
     defaultReprEqOrigins :: CtOrigin -> [(CtOrigin, (TcType, TcType))]
    
    1007
    -defaultReprEqOrigins = go
    
    1101
    +defaultReprEqOrigins = foldMapCtOrigin go
    
    1008 1102
       where
    
    1009 1103
         go = \case
    
    1010
    -      DefaultReprEqOrigin l r o -> (o, (l, r)) : go o
    
    1011
    -
    
    1012
    -      -- Handle recursive occurrences of 'CtOrigin' within 'CtOrigin'.
    
    1013
    -      -- TODO: use syb to derive this, so that the following never goes out of date.
    
    1014
    -      ScOrigin cls_or_qc _ ->
    
    1015
    -        case cls_or_qc of
    
    1016
    -          IsClsInst -> []
    
    1017
    -          IsQC _ o -> go o
    
    1018
    -      KindEqOrigin _ _ o _ -> go o
    
    1019
    -      CycleBreakerOrigin o -> go o
    
    1020
    -      WantedSuperclassOrigin _ o -> go o
    
    1021
    -
    
    1104
    +      DefaultReprEqOrigin l r o -> [(o, (l, r))]
    
    1022 1105
           _ -> []
    
    1023 1106
     
    
    1024 1107
     {- *********************************************************************
    
    ... ... @@ -1046,6 +1129,37 @@ isPushCallStackOrigin_maybe orig = Just orig_fs
    1046 1129
       where
    
    1047 1130
         orig_fs = mkFastString (showSDocUnsafe (pprCtOriginBriefly orig))
    
    1048 1131
     
    
    1132
    +{- *********************************************************************
    
    1133
    +*                                                                      *
    
    1134
    +                       HasField and CtOrigin
    
    1135
    +*                                                                      *
    
    1136
    +********************************************************************* -}
    
    1137
    +
    
    1138
    +-- | Does this constraint arise from GHC internal mechanisms that desugar to
    
    1139
    +-- usage of the 'HasField' typeclass (e.g. OverloadedRecordDot, etc)?
    
    1140
    +--
    
    1141
    +-- Used in two places:
    
    1142
    +--
    
    1143
    +--  - When reporting an unsolved 'HasField' constraint, to decide whether to
    
    1144
    +--    print an informative message to the user.
    
    1145
    +--    See (H2e) in Note [Error messages for unsolved HasField constraints]
    
    1146
    +--    in GHC.Tc.Errors.
    
    1147
    +--  - To avoid emitting a poor "incomplete record selector" warning directly
    
    1148
    +--    in typechecker, in cases when the desugarer will be able to emit a better
    
    1149
    +--    error message, due to having better pattern match checking information.
    
    1150
    +--    See (IRS7) in Note [Detecting incomplete record selectors]
    
    1151
    +--    in GHC.HsToCore.Pmc
    
    1152
    +isHasFieldOrigin :: CtOrigin -> Bool
    
    1153
    +isHasFieldOrigin = Semi.getAny . foldMapCtOrigin (Semi.Any . go)
    
    1154
    +  where
    
    1155
    +    go = \case
    
    1156
    +      OccurrenceOf n -> n == getFieldName
    
    1157
    +      OccurrenceOfRecSel {} -> True
    
    1158
    +      RecordFieldProjectionOrigin {} -> True
    
    1159
    +      GetFieldOrigin {} -> True
    
    1160
    +      RecordUpdOrigin {} -> True
    
    1161
    +      _ -> False
    
    1162
    +
    
    1049 1163
     {-
    
    1050 1164
     ************************************************************************
    
    1051 1165
     *                                                                      *
    

  • testsuite/tests/overloadedrecflds/should_compile/T26686.hs
    1
    +{-# LANGUAGE OverloadedRecordDot #-}
    
    2
    +{-# LANGUAGE GADTs #-}
    
    3
    +
    
    4
    +{-# OPTIONS_GHC -Wincomplete-record-selectors #-}
    
    5
    +
    
    6
    +module T26686 where
    
    7
    +
    
    8
    +import Data.Kind
    
    9
    +
    
    10
    +data A
    
    11
    +data B
    
    12
    +
    
    13
    +data G = G { f2 :: Int }
    
    14
    +
    
    15
    +data T x where
    
    16
    +  TA :: { ta :: G } -> T x
    
    17
    +  TB :: { tb :: G } -> T B
    
    18
    +
    
    19
    +data H a = H { f1 :: T a }
    
    20
    +
    
    21
    +test1_ok :: T A -> G
    
    22
    +test1_ok = (.ta)
    
    23
    +test2_ok :: T A -> Int
    
    24
    +test2_ok = (.ta.f2)
    
    25
    +test3_ok :: H A -> G
    
    26
    +test3_ok = (.f1.ta)
    
    27
    +test4_ok :: H A -> Int
    
    28
    +test4_ok = (.f1.ta.f2)
    
    29
    +
    
    30
    +test1_bad :: T x -> G
    
    31
    +test1_bad = (.ta)
    
    32
    +test2_bad :: T x -> Int
    
    33
    +test2_bad = (.ta.f2)
    
    34
    +test3_bad :: H x -> G
    
    35
    +test3_bad = (.f1.ta)
    
    36
    +test4_bad :: H x -> Int
    
    37
    +test4_bad = (.f1.ta.f2)

  • testsuite/tests/overloadedrecflds/should_compile/T26686.stderr
    1
    +T26686.hs:31:13: warning: [GHC-17335] [-Wincomplete-record-selectors (in -Wall)]
    
    2
    +    Selecting the record field ‘ta’ may fail for the following constructors:
    
    3
    +      TB
    
    4
    +
    
    5
    +T26686.hs:33:13: warning: [GHC-17335] [-Wincomplete-record-selectors (in -Wall)]
    
    6
    +    Selecting the record field ‘ta’ may fail for the following constructors:
    
    7
    +      TB
    
    8
    +
    
    9
    +T26686.hs:35:13: warning: [GHC-17335] [-Wincomplete-record-selectors (in -Wall)]
    
    10
    +    Selecting the record field ‘ta’ may fail for the following constructors:
    
    11
    +      TB
    
    12
    +
    
    13
    +T26686.hs:37:13: warning: [GHC-17335] [-Wincomplete-record-selectors (in -Wall)]
    
    14
    +    Selecting the record field ‘ta’ may fail for the following constructors:
    
    15
    +      TB
    
    16
    +

  • testsuite/tests/overloadedrecflds/should_compile/all.T
    ... ... @@ -30,6 +30,7 @@ test('T21720', req_th, compile, [''])
    30 30
     test('T21898', normal, compile, [''])
    
    31 31
     test('T22160', [extra_files(['T22160_A.hs', 'T22160_B.hs', 'T22160_C.hs'])]
    
    32 32
                  , multimod_compile, ['T22160_A T22160_B T22160_C T22160', '-v0'])
    
    33
    +test('T26686', normal, compile, [''])
    
    33 34
     test('DupFldFixity3', normal, compile, [''])
    
    34 35
     test('overloadedrecflds10'
    
    35 36
         , [extra_files(['OverloadedRecFlds10_A.hs', 'OverloadedRecFlds10_B.hs', 'OverloadedRecFlds10_C.hs'])]