Vladislav Zavialov pushed to branch wip/int-index/enforce-namespaces at Glasgow Haskell Compiler / GHC

Commits:

20 changed files:

Changes:

  • compiler/GHC/Rename/Names.hs
    ... ... @@ -1268,7 +1268,7 @@ filterImports hsc_env iface decl_spec (Just (want_hiding, L l import_items))
    1268 1268
                 warning_msg (BadImportW ie sub) = do
    
    1269 1269
                   -- 'BadImportW' is only constructed below in 'bad_import_w', in
    
    1270 1270
                   -- the 'EverythingBut' case, so here we assume a 'hiding' clause.
    
    1271
    -              (reason : _) <- badImportItemErr iface decl_spec ie sub all_avails
    
    1271
    +              (reason :| _) <- badImportItemErr iface decl_spec ie sub all_avails
    
    1272 1272
                   pure (TcRnDodgyImports (DodgyImportsHiding reason))
    
    1273 1273
                 warning_msg (DeprecatedExport n w) =
    
    1274 1274
                   pure $ TcRnPragmaWarning
    
    ... ... @@ -1281,14 +1281,14 @@ filterImports hsc_env iface decl_spec (Just (want_hiding, L l import_items))
    1281 1281
                 run_lookup def m = case m of
    
    1282 1282
                   Failed err -> do
    
    1283 1283
                     msgs <- lookup_err_msgs err
    
    1284
    -                mapM_ addErr [TcRnImportLookup msg | msg <- msgs]
    
    1284
    +                forM_ msgs $ \msg -> addErr (TcRnImportLookup msg)
    
    1285 1285
                     return def
    
    1286 1286
                   Succeeded a -> return a
    
    1287 1287
     
    
    1288 1288
                 lookup_err_msgs err = case err of
    
    1289 1289
                   BadImport ie sub    -> badImportItemErr iface decl_spec ie sub all_avails
    
    1290
    -              IllegalImport       -> pure [ImportLookupIllegal]
    
    1291
    -              QualImportError rdr -> pure [ImportLookupQualified rdr]
    
    1290
    +              IllegalImport       -> pure $ NE.singleton ImportLookupIllegal
    
    1291
    +              QualImportError rdr -> pure $ NE.singleton (ImportLookupQualified rdr)
    
    1292 1292
     
    
    1293 1293
             -- For each import item, we convert its RdrNames to Names,
    
    1294 1294
             -- and at the same time compute all the GlobalRdrElt corresponding
    
    ... ... @@ -1642,7 +1642,7 @@ lookupChildren :: [GlobalRdrElt]
    1642 1642
                    -> ( [LookupChildError]   -- The ones for which the lookup failed
    
    1643 1643
                       , [LocatedA GlobalRdrElt] )
    
    1644 1644
     -- (lookupChildren all_kids rdr_items) maps each rdr_item to its
    
    1645
    --- corresponding Name all_kids, if the former exists
    
    1645
    +-- corresponding Name in all_kids, if the former exists
    
    1646 1646
     -- The matching is done by FastString, not OccName, so that
    
    1647 1647
     --    Cls( meth, AssocTy )
    
    1648 1648
     -- will correctly find AssocTy among the all_kids of Cls, even though
    
    ... ... @@ -1652,20 +1652,34 @@ lookupChildren all_kids rdr_items = (fails, successes)
    1652 1652
       where
    
    1653 1653
         mb_xs     = map do_one rdr_items
    
    1654 1654
         fails     = [ err | Failed err    <- mb_xs ]
    
    1655
    -    successes = [ ok  | Succeeded oks <- mb_xs, ok <- oks ]
    
    1655
    +    successes = [ ok  | Succeeded oks <- mb_xs, ok <- NE.toList oks ]
    
    1656 1656
     
    
    1657
    -    do_one :: LIEWrappedName GhcPs -> MaybeErr LookupChildError [LocatedA GlobalRdrElt]
    
    1657
    +    do_one :: LIEWrappedName GhcPs -> MaybeErr LookupChildError (NonEmpty (LocatedA GlobalRdrElt))
    
    1658 1658
         do_one item@(L l r) =
    
    1659 1659
           case r of
    
    1660
    -        IEName{} | notNull val_gs -> Succeeded [L l g | g <- val_gs]
    
    1661
    -        IEName{} | notNull typ_gs -> Succeeded [L l g | g <- typ_gs]
    
    1662
    -        IEType{} | notNull typ_gs -> Succeeded [L l g | g <- typ_gs]
    
    1663
    -        IEType{} | (g:_) <- val_gs -> Failed $ LookupChildNonType item g
    
    1664
    -        _ -> Failed $ LookupChildNotFound item
    
    1660
    +        IEName{}
    
    1661
    +          -- IEName (unadorned name) places no restriction on the namespace of
    
    1662
    +          -- the imported entity, so we look in both `val_gres` and `typ_gres`.
    
    1663
    +          -- In case of conflict (punning), the value namespace takes priority.
    
    1664
    +          -- See Note [Prioritise the value namespace in subordinate import lists]
    
    1665
    +          | (gre:gres) <- val_gres -> Succeeded $ fmap (L l) (gre:|gres)
    
    1666
    +          | (gre:gres) <- typ_gres -> Succeeded $ fmap (L l) (gre:|gres)
    
    1667
    +          | otherwise              -> Failed $ LookupChildNotFound item
    
    1668
    +
    
    1669
    +        IEType{}
    
    1670
    +          -- IEType ('type' namespace specifier) restricts the lookup to the
    
    1671
    +          -- type namespace, i.e. to `typ_gres`. In case of failure, we check
    
    1672
    +          -- `val_gres` to produce a more helpful error message.
    
    1673
    +          | (gre:gres) <- typ_gres -> Succeeded $ fmap (L l) (gre:|gres)
    
    1674
    +          | (gre:_)    <- val_gres -> Failed $ LookupChildNonType item gre
    
    1675
    +          | otherwise              -> Failed $ LookupChildNotFound item
    
    1676
    +
    
    1677
    +        IEPattern{} -> panic "lookupChildren: IEPattern"  -- Never happens (invalid syntax)
    
    1678
    +        IEDefault{} -> panic "lookupChildren: IEDefault"  -- Never happens (invalid syntax)
    
    1665 1679
           where
    
    1666 1680
             fs = (occNameFS . rdrNameOcc . ieWrappedName) r
    
    1667
    -        gs = fromMaybe [] (lookupFsEnv kid_env fs)
    
    1668
    -        (val_gs, typ_gs) = partition (isValNameSpace . greNameSpace) gs
    
    1681
    +        gres = fromMaybe [] (lookupFsEnv kid_env fs)
    
    1682
    +        (val_gres, typ_gres) = partition (isValNameSpace . greNameSpace) gres
    
    1669 1683
     
    
    1670 1684
         -- See Note [Children for duplicate record fields]
    
    1671 1685
         kid_env :: FastStringEnv [GlobalRdrElt]
    
    ... ... @@ -1673,6 +1687,38 @@ lookupChildren all_kids rdr_items = (fails, successes)
    1673 1687
                   [(occNameFS (occName x), [x]) | x <- all_kids]
    
    1674 1688
     
    
    1675 1689
     
    
    1690
    +{- Note [Prioritise the value namespace in subordinate import lists]
    
    1691
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1692
    +Consider this program that defines a class that has both an associated type
    
    1693
    +named (#) and a method named (#)
    
    1694
    +
    
    1695
    +  module M_assoc where
    
    1696
    +    class C a b where
    
    1697
    +      type a # b
    
    1698
    +      (#) :: a -> b -> ()
    
    1699
    +  module N_assoc where
    
    1700
    +    import M_assoc( C((#)) )
    
    1701
    +
    
    1702
    +In the import declaration, when we see the unadorned name (#) in the subordinate
    
    1703
    +import list of C, which children should we bring into scope? Our options are:
    
    1704
    +
    
    1705
    +  a) only the method (#)
    
    1706
    +  b) only the associated type (#)
    
    1707
    +  c) both the method and the associated type
    
    1708
    +
    
    1709
    +To follow the precedent established by top-level items, we go with option (a).
    
    1710
    +Indeed, consider a slightly different program
    
    1711
    +
    
    1712
    +  module M_top where
    
    1713
    +    type family a # b
    
    1714
    +    a # b = ()
    
    1715
    +  module N_top where
    
    1716
    +    import M_top( (#) )
    
    1717
    +
    
    1718
    +Here the import brings only the function (#) into scope, and one has to say
    
    1719
    +`type (#)` to get the type family.
    
    1720
    +-}
    
    1721
    +
    
    1676 1722
     -------------------------------
    
    1677 1723
     
    
    1678 1724
     {-
    
    ... ... @@ -2331,27 +2377,31 @@ badImportItemErr
    2331 2377
       :: ModIface -> ImpDeclSpec -> IE GhcPs
    
    2332 2378
       -> IsSubordinateError
    
    2333 2379
       -> [AvailInfo]
    
    2334
    -  -> TcRn [ImportLookupReason]   -- non-empty
    
    2380
    +  -> TcRn (NonEmpty ImportLookupReason)
    
    2335 2381
     badImportItemErr iface decl_spec ie sub avails = do
    
    2336 2382
       patsyns_enabled <- xoptM LangExt.PatternSynonyms
    
    2337 2383
       expl_ns_enabled <- xoptM LangExt.ExplicitNamespaces
    
    2384
    +  let import_lookup_bad :: BadImportKind -> ImportLookupReason
    
    2385
    +      import_lookup_bad k = ImportLookupBad k iface decl_spec ie patsyns_enabled
    
    2338 2386
       dflags <- getDynFlags
    
    2339 2387
       hsc_env <- getTopEnv
    
    2340 2388
       let rdr_env = mkGlobalRdrEnv
    
    2341 2389
                   $ gresFromAvails hsc_env (Just imp_spec) all_avails
    
    2342
    -  pure [ImportLookupBad k iface decl_spec ie patsyns_enabled | k <- importErrorKind dflags rdr_env expl_ns_enabled ]
    
    2390
    +  pure $ fmap import_lookup_bad (importErrorKind dflags rdr_env expl_ns_enabled)
    
    2343 2391
       where
    
    2392
    +    importErrorKind :: DynFlags -> GlobalRdrEnv -> Bool -> NonEmpty BadImportKind
    
    2344 2393
         importErrorKind dflags rdr_env expl_ns_enabled
    
    2345 2394
           | any checkIfTyCon avails = case sub of
    
    2346
    -          IsNotSubordinate -> [BadImportAvailTyCon expl_ns_enabled]
    
    2395
    +          IsNotSubordinate -> NE.singleton (BadImportAvailTyCon expl_ns_enabled)
    
    2347 2396
               IsSubordinateError { subordinate_err_parent = gre
    
    2348 2397
                                  , subordinate_err_unavailable = unavailable
    
    2349 2398
                                  , subordinate_err_nontype = nontype }
    
    2350
    -            -> [BadImportNotExportedSubordinates gre unavailable | notNull unavailable] ++
    
    2351
    -               [BadImportNonTypeSubordinates gre nontype | notNull nontype ]
    
    2352
    -      | any checkIfVarName avails = [BadImportAvailVar]
    
    2353
    -      | Just con <- find checkIfDataCon avails = [BadImportAvailDataCon (availOccName con)]
    
    2354
    -      | otherwise = [BadImportNotExported suggs]
    
    2399
    +            -> NE.fromList $ catMaybes $
    
    2400
    +                [ fmap (BadImportNotExportedSubordinates gre) (NE.nonEmpty unavailable)
    
    2401
    +                , fmap (BadImportNonTypeSubordinates gre) (NE.nonEmpty nontype) ]
    
    2402
    +      | any checkIfVarName avails = NE.singleton BadImportAvailVar
    
    2403
    +      | Just con <- find checkIfDataCon avails = NE.singleton (BadImportAvailDataCon (availOccName con))
    
    2404
    +      | otherwise = NE.singleton (BadImportNotExported suggs)
    
    2355 2405
             where
    
    2356 2406
               suggs = similar_suggs ++ fieldSelectorSuggestions rdr_env rdr
    
    2357 2407
               what_look = case sub of
    

  • compiler/GHC/Tc/Errors/Ppr.hs
    ... ... @@ -119,6 +119,7 @@ import GHC.Data.List.SetOps ( nubOrdBy )
    119 119
     import GHC.Data.Maybe
    
    120 120
     import GHC.Data.Pair
    
    121 121
     import GHC.Settings.Constants (mAX_TUPLE_SIZE, mAX_CTUPLE_SIZE)
    
    122
    +import GHC.Utils.Lexeme
    
    122 123
     import GHC.Utils.Misc
    
    123 124
     import GHC.Utils.Outputable
    
    124 125
     import GHC.Utils.Panic
    
    ... ... @@ -5886,24 +5887,35 @@ pprImportLookup = \case
    5886 5887
             where
    
    5887 5888
               tycon_occ = rdrNameOcc $ ieName ie
    
    5888 5889
               tycon = parenSymOcc tycon_occ (ppr tycon_occ)
    
    5889
    -      BadImportNotExportedSubordinates gre unavailable ->
    
    5890
    +      BadImportNotExportedSubordinates gre unavailable1 ->
    
    5890 5891
             withContext
    
    5891 5892
               [ what <+> text "called" <+> parent_name <+> text "is exported, but it does not export"
    
    5892 5893
               , text "any" <+> what_children <+> text "called" <+> unavailable_names <> dot
    
    5893 5894
               ]
    
    5894 5895
               where
    
    5896
    +            unavailable = NE.toList unavailable1
    
    5895 5897
                 parent_name = (quotes . pprPrefixOcc . nameOccName . gre_name) gre
    
    5896 5898
                 unavailable_names = pprWithCommas (quotes . ppr) unavailable
    
    5897
    -            (what, what_children) = case greInfo gre of
    
    5898
    -              IAmTyCon ClassFlavour -> (text "a class",     text "class methods or associated types")
    
    5899
    -              IAmTyCon _            -> (text "a data type", text "constructors or record fields")
    
    5900
    -              _                     -> (text "an item",     text "children")
    
    5901
    -      BadImportNonTypeSubordinates gre nontype ->
    
    5899
    +            any_names p = any (p . unpackFS) unavailable
    
    5900
    +            what = case greInfo gre of
    
    5901
    +              IAmTyCon ClassFlavour -> text "a class"
    
    5902
    +              IAmTyCon _            -> text "a data type"
    
    5903
    +              _                     -> text "an item"
    
    5904
    +            what_children = unquotedListWith "or" $ case greInfo gre of
    
    5905
    +              IAmTyCon ClassFlavour ->
    
    5906
    +                [text "class methods"    | any_names okVarOcc ] ++
    
    5907
    +                [text "associated types" | any_names okTcOcc ]
    
    5908
    +              IAmTyCon _ ->
    
    5909
    +                [text "constructors"  | any_names okConOcc ] ++
    
    5910
    +                [text "record fields" | any_names okVarOcc ]
    
    5911
    +              _ -> [text "children"]
    
    5912
    +      BadImportNonTypeSubordinates gre nontype1 ->
    
    5902 5913
             withContext
    
    5903 5914
               [ what <+> text "called" <+> parent_name <+> text "is exported,"
    
    5904 5915
               , sep [ text "but its subordinate" <+> "item" <> plural nontype <+> nontype_names
    
    5905 5916
                     , isOrAre nontype <+> "not in the type namespace." ] ]
    
    5906 5917
               where
    
    5918
    +            nontype = NE.toList nontype1
    
    5907 5919
                 parent_name = (quotes . pprPrefixOcc . nameOccName . gre_name) gre
    
    5908 5920
                 nontype_names = pprWithCommas (quotes . pprPrefixOcc . nameOccName . gre_name) nontype
    
    5909 5921
                 what = case greInfo gre of
    

  • compiler/GHC/Tc/Errors/Types.hs
    ... ... @@ -5837,9 +5837,9 @@ data BadImportKind
    5837 5837
       -- @import Data.Maybe (Just)@ instead of @import Data.Maybe (Maybe(Just))@
    
    5838 5838
       | BadImportAvailDataCon OccName
    
    5839 5839
       -- | The parent does not export the given children.
    
    5840
    -  | BadImportNotExportedSubordinates !GlobalRdrElt [FastString]
    
    5840
    +  | BadImportNotExportedSubordinates !GlobalRdrElt (NonEmpty FastString)
    
    5841 5841
       -- | Incorrect @type@ keyword when importing subordinates that aren't types.
    
    5842
    -  | BadImportNonTypeSubordinates !GlobalRdrElt [GlobalRdrElt]
    
    5842
    +  | BadImportNonTypeSubordinates !GlobalRdrElt (NonEmpty GlobalRdrElt)
    
    5843 5843
       -- | Incorrect @type@ keyword when importing something which isn't a type.
    
    5844 5844
       | BadImportAvailVar
    
    5845 5845
       deriving Generic
    

  • testsuite/tests/rename/should_compile/T25983a.hs
    1
    +{-# OPTIONS -Wdodgy-imports #-}
    
    2
    +
    
    3
    +module T25983a where
    
    4
    +
    
    5
    +import Prelude hiding (Bool(X,Y))

  • testsuite/tests/rename/should_compile/T25983.stderrtestsuite/tests/rename/should_compile/T25983a.stderr
    1
    -T25983.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    1
    +T25983a.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2 2
         In the import of ‘Prelude’:
    
    3 3
           a data type called ‘Bool’ is exported, but it does not export
    
    4
    -      any constructors or record fields called ‘X’.
    
    4
    +      any constructors called ‘X’, ‘Y’.
    
    5 5
     

  • testsuite/tests/rename/should_compile/T25983b.hs
    1
    +{-# OPTIONS -Wdodgy-imports #-}
    
    2
    +
    
    3
    +module T25983b where
    
    4
    +
    
    5
    +import Prelude hiding (Bool(fld1,fld2))

  • testsuite/tests/rename/should_compile/T25983b.stderr
    1
    +T25983b.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2
    +    In the import of ‘Prelude’:
    
    3
    +      a data type called ‘Bool’ is exported, but it does not export
    
    4
    +      any record fields called ‘fld1’, ‘fld2’.
    
    5
    +

  • testsuite/tests/rename/should_compile/T25983c.hs
    1
    +{-# OPTIONS -Wdodgy-imports #-}
    
    2
    +
    
    3
    +module T25983c where
    
    4
    +
    
    5
    +import Prelude hiding (Bool(X,Y,fld1,fld2))

  • testsuite/tests/rename/should_compile/T25983c.stderr
    1
    +T25983c.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2
    +    In the import of ‘Prelude’:
    
    3
    +      a data type called ‘Bool’ is exported, but it does not export
    
    4
    +      any constructors or record fields called ‘X’, ‘Y’, ‘fld1’, ‘fld2’.
    
    5
    +

  • testsuite/tests/rename/should_compile/T25983.hstestsuite/tests/rename/should_compile/T25983d.hs
    1 1
     {-# OPTIONS -Wdodgy-imports #-}
    
    2 2
     
    
    3
    -module T25983 where
    
    3
    +module T25983d where
    
    4 4
     
    
    5
    -import Prelude hiding (Bool(X))
    5
    +import Prelude hiding (Num((#)))

  • testsuite/tests/rename/should_compile/T25983d.stderr
    1
    +T25983d.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2
    +    In the import of ‘Prelude’:
    
    3
    +      a class called ‘Num’ is exported, but it does not export
    
    4
    +      any class methods or associated types called ‘#’.
    
    5
    +

  • testsuite/tests/rename/should_compile/T25983e.hs
    1
    +{-# OPTIONS -Wdodgy-imports #-}
    
    2
    +
    
    3
    +module T25983e where
    
    4
    +
    
    5
    +import Prelude hiding (Num(f,g))

  • testsuite/tests/rename/should_compile/T25983e.stderr
    1
    +T25983e.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2
    +    In the import of ‘Prelude’:
    
    3
    +      a class called ‘Num’ is exported, but it does not export
    
    4
    +      any class methods called ‘f’, ‘g’.
    
    5
    +

  • testsuite/tests/rename/should_compile/T25983f.hs
    1
    +{-# OPTIONS -Wdodgy-imports #-}
    
    2
    +
    
    3
    +module T25983f where
    
    4
    +
    
    5
    +import Prelude hiding (Num(F,G))

  • testsuite/tests/rename/should_compile/T25983f.stderr
    1
    +T25983f.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2
    +    In the import of ‘Prelude’:
    
    3
    +      a class called ‘Num’ is exported, but it does not export
    
    4
    +      any associated types called ‘F’, ‘G’.
    
    5
    +

  • testsuite/tests/rename/should_compile/T25983g.hs
    1
    +{-# OPTIONS -Wdodgy-imports #-}
    
    2
    +
    
    3
    +module T25983g where
    
    4
    +
    
    5
    +import Prelude hiding (Num(F,G,f,g))

  • testsuite/tests/rename/should_compile/T25983g.stderr
    1
    +T25983g.hs:5:24: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2
    +    In the import of ‘Prelude’:
    
    3
    +      a class called ‘Num’ is exported, but it does not export
    
    4
    +      any class methods or associated types called ‘F’, ‘G’, ‘f’, ‘g’.
    
    5
    +

  • testsuite/tests/rename/should_compile/T25984a.stderr
    1 1
     T25984a.hs:5:31: warning: [GHC-10237] [-Wdodgy-imports (in -Wextra)]
    
    2 2
         In the import of ‘T25984a_helper’:
    
    3 3
           a data type called ‘H’ is exported, but it does not export
    
    4
    -      any constructors or record fields called ‘C’.
    
    4
    +      any constructors called ‘C’.
    
    5 5
     

  • testsuite/tests/rename/should_compile/all.T
    ... ... @@ -233,5 +233,11 @@ test('T25182', [extra_files(['ReExportTuples.hs'])], multimod_compile, ['T25182'
    233 233
     test('T22581c', [extra_files(['T22581c_helper.hs'])], multimod_compile, ['T22581c', '-v0'])
    
    234 234
     test('T22581d', combined_output, ghci_script, ['T22581d.script'])
    
    235 235
     test('T25991a', [extra_files(['T25991a_helper.hs'])], multimod_compile, ['T25991a', '-v0'])
    
    236
    -test('T25983', normal, compile, [''])
    
    236
    +test('T25983a', normal, compile, [''])
    
    237
    +test('T25983b', normal, compile, [''])
    
    238
    +test('T25983c', normal, compile, [''])
    
    239
    +test('T25983d', normal, compile, [''])
    
    240
    +test('T25983e', normal, compile, [''])
    
    241
    +test('T25983f', normal, compile, [''])
    
    242
    +test('T25983g', normal, compile, [''])
    
    237 243
     test('T25984a', [extra_files(['T25984a_helper.hs'])], multimod_compile, ['T25984a', '-v0'])

  • testsuite/tests/rename/should_fail/T9006.stderr
    1 1
     T9006.hs:3:16: error: [GHC-10237]
    
    2 2
         In the import of ‘T9006a’:
    
    3 3
           a data type called ‘T’ is exported, but it does not export
    
    4
    -      any constructors or record fields called ‘T’.
    
    4
    +      any constructors called ‘T’.
    
    5 5