Commit 2dcebe69 authored by Simon Peyton Jones's avatar Simon Peyton Jones

Fix unused-import warnings

This patch fixes a fairly long-standing bug (dating back to 2015) in
RdrName.bestImport, namely

   commit 9376249b
   Author: Simon Peyton Jones <simonpj@microsoft.com>
   Date:   Wed Oct 28 17:16:55 2015 +0000

   Fix unused-import stuff in a better way

In that patch got the sense of the comparison back to front, and
thereby failed to implement the unused-import rules described in
  Note [Choosing the best import declaration] in RdrName

This led to Trac #13064 and #15393

Fixing this bug revealed a bunch of unused imports in libraries;
the ones in the GHC repo are part of this commit.

The two important changes are

* Fix the bug in bestImport

* Modified the rules by adding (a) in
     Note [Choosing the best import declaration] in RdrName
  Reason: the previosu rules made Trac #5211 go bad again.  And
  the new rule (a) makes sense to me.

In unravalling this I also ended up doing a few other things

* Refactor RnNames.ImportDeclUsage to use a [GlobalRdrElt] for the
  things that are used, rather than [AvailInfo]. This is simpler
  and more direct.

* Rename greParentName to greParent_maybe, to follow GHC
  naming conventions

* Delete dead code RdrName.greUsedRdrName

* Slightly change the spec of the unused function
  HsImpExpr.ieLWrappedName, and use it in RnNames.findImportUsage
parent a08b285f
Pipeline #72 canceled with stages
......@@ -53,14 +53,14 @@ module RdrName (
-- * GlobalRdrElts
gresFromAvails, gresFromAvail, localGREsFromAvail, availFromGRE,
greUsedRdrName, greRdrNames, greSrcSpan, greQualModName,
greRdrNames, greSrcSpan, greQualModName,
gresToAvailInfo,
-- ** Global 'RdrName' mapping elements: 'GlobalRdrElt', 'Provenance', 'ImportSpec'
GlobalRdrElt(..), isLocalGRE, isRecFldGRE, greLabel,
unQualOK, qualSpecOK, unQualSpecOK,
pprNameProvenance,
Parent(..),
Parent(..), greParent_maybe,
ImportSpec(..), ImpDeclSpec(..), ImpItemSpec(..),
importSpecLoc, importSpecModule, isExplicitItem, bestImport,
......@@ -657,18 +657,6 @@ greQualModName gre@(GRE { gre_name = name, gre_lcl = lcl, gre_imp = iss })
| (is:_) <- iss = is_as (is_decl is)
| otherwise = pprPanic "greQualModName" (ppr gre)
greUsedRdrName :: GlobalRdrElt -> RdrName
-- For imported things, return a RdrName to add to the used-RdrName
-- set, which is used to generate unused-import-decl warnings.
-- Return a Qual RdrName if poss, so that identifies the most
-- specific ImportSpec. See Trac #10890 for some good examples.
greUsedRdrName gre@GRE{ gre_name = name, gre_lcl = lcl, gre_imp = iss }
| lcl, Just mod <- nameModule_maybe name = Qual (moduleName mod) occ
| not (null iss), is <- bestImport iss = Qual (is_as (is_decl is)) occ
| otherwise = pprTrace "greUsedRdrName" (ppr gre) (Unqual occ)
where
occ = greOccName gre
greRdrNames :: GlobalRdrElt -> [RdrName]
greRdrNames gre@GRE{ gre_lcl = lcl, gre_imp = iss }
= (if lcl then [unqual] else []) ++ concatMap do_spec (map is_decl iss)
......@@ -696,11 +684,11 @@ mkParent _ (Avail _) = NoParent
mkParent n (AvailTC m _ _) | n == m = NoParent
| otherwise = ParentIs m
greParentName :: GlobalRdrElt -> Maybe Name
greParentName gre = case gre_par gre of
NoParent -> Nothing
ParentIs n -> Just n
FldParent n _ -> Just n
greParent_maybe :: GlobalRdrElt -> Maybe Name
greParent_maybe gre = case gre_par gre of
NoParent -> Nothing
ParentIs n -> Just n
FldParent n _ -> Just n
-- | Takes a list of distinct GREs and folds them
-- into AvailInfos. This is more efficient than mapping each individual
......@@ -716,7 +704,7 @@ gresToAvailInfo gres
add :: NameEnv AvailInfo -> GlobalRdrElt -> NameEnv AvailInfo
add env gre = extendNameEnv_Acc comb availFromGRE env
(fromMaybe (gre_name gre)
(greParentName gre)) gre
(greParent_maybe gre)) gre
where
-- We want to insert the child `k` into a list of children but
......@@ -1192,10 +1180,7 @@ instance Ord ImpItemSpec where
bestImport :: [ImportSpec] -> ImportSpec
-- Given a non-empty bunch of ImportSpecs, return the one that
-- imported the item most specifically (e.g. by name), using
-- textually-first as a tie breaker. This is used when reporting
-- redundant imports
-- See Note [Choosing the best import declaration]
bestImport iss
= case sortBy best iss of
(is:_) -> is
......@@ -1203,17 +1188,76 @@ bestImport iss
where
best :: ImportSpec -> ImportSpec -> Ordering
-- Less means better
-- Unqualified always wins over qualified; then
-- import-all wins over import-some; then
-- earlier declaration wins over later
best (ImpSpec { is_item = item1, is_decl = d1 })
(ImpSpec { is_item = item2, is_decl = d2 })
= best_item item1 item2 `thenCmp` (is_dloc d1 `compare` is_dloc d2)
= (is_qual d1 `compare` is_qual d2) `thenCmp`
(best_item item1 item2) `thenCmp`
(is_dloc d1 `compare` is_dloc d2)
best_item :: ImpItemSpec -> ImpItemSpec -> Ordering
best_item ImpAll ImpAll = EQ
best_item ImpAll (ImpSome {}) = GT
best_item (ImpSome {}) ImpAll = LT
best_item ImpAll (ImpSome {}) = LT
best_item (ImpSome {}) ImpAll = GT
best_item (ImpSome { is_explicit = e1 })
(ImpSome { is_explicit = e2 }) = e2 `compare` e1
-- False < True, so if e1 is explicit and e2 is not, we get LT
(ImpSome { is_explicit = e2 }) = e1 `compare` e2
-- False < True, so if e1 is explicit and e2 is not, we get GT
{- Note [Choosing the best import declaration]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When reporting unused import declarations we use the following rules.
(see [wiki:Commentary/Compiler/UnusedImports])
Say that an import-item is either
* an entire import-all decl (eg import Foo), or
* a particular item in an import list (eg import Foo( ..., x, ...)).
The general idea is that for each /occurrence/ of an imported name, we will
attribute that use to one import-item. Once we have processed all the
occurrences, any import items with no uses attributed to them are unused, and are
warned about. More precisely:
1. For every RdrName in the program text, find its GlobalRdrElt.
2. Then, from the [ImportSpec] (gre_imp) of that GRE, choose one
the "chosen import-item", and mark it "used". This is done
by 'bestImport'
3. After processing all the RdrNames, bleat about any
import-items that are unused.
This is done in RnNames.warnUnusedImportDecls.
The function 'bestImport' returns the dominant import among the
ImportSpecs it is given, implementing Step 2. We say import-item A
dominates import-item B if we choose A over B. In general, we try to
choose the import that is most likely to render other imports
unnecessary. Here is the dominance relationship we choose:
a) import Foo dominates import qualified Foo.
b) import Foo dominates import Foo(x).
c) Otherwise choose the textually first one.
Rationale for (a). Consider
import qualified M -- Import #1
import M( x ) -- Import #2
foo = M.x + x
The unqualified 'x' can only come from import #2. The qualified 'M.x'
could come from either, but bestImport picks import #2, because it is
more likely to be useful in other imports, as indeed it is in this
case (see Trac #5211 for a concrete example).
But the rules are not perfect; consider
import qualified M -- Import #1
import M( x ) -- Import #2
foo = M.x + M.y
The M.x will use import #2, but M.y can only use import #1.
-}
unQualSpecOK :: ImportSpec -> Bool
-- ^ Is in scope unqualified?
......
......@@ -22,7 +22,6 @@ import UniqFM
import PprCmm ()
import qualified Data.IntSet as IntSet
import Data.List (partition)
import qualified Data.Set as Set
import Data.List
import Data.Maybe
......
......@@ -35,7 +35,6 @@ import Cmm
import CmmUtils
import CLabel
import qualified Module
import CostCentre
import DynFlags
import FastString
......
......@@ -41,7 +41,6 @@ import Util
-- Standard libraries
import Data.Array.Unboxed
import Foreign.Ptr
import GHC.IO ( IO(..) )
import GHC.Exts
{-
......
......@@ -59,7 +59,6 @@ import Outputable as Ppr
import GHC.Char
import GHC.Exts
import GHC.Exts.Heap
import GHC.IO ( IO(..) )
import SMRep ( roundUpTo )
import Control.Monad
......
......@@ -23,7 +23,6 @@ import RdrName
import qualified Name
import Module
import RdrHsSyn
import qualified OccName
import OccName
import SrcLoc
import Type
......
......@@ -44,7 +44,6 @@ import DynFlags
import Data.Data hiding ( Fixity )
import Data.List hiding ( foldr )
import Data.Ord
import Data.Foldable ( Foldable(..) )
{-
************************************************************************
......
......@@ -281,8 +281,8 @@ ieWrappedName (IEName (L _ n)) = n
ieWrappedName (IEPattern (L _ n)) = n
ieWrappedName (IEType (L _ n)) = n
ieLWrappedName :: LIEWrappedName name -> Located name
ieLWrappedName (L l n) = L l (ieWrappedName n)
ieLWrappedName :: LIEWrappedName name -> name
ieLWrappedName (L l n) = ieWrappedName n
replaceWrappedName :: IEWrappedName name1 -> name2 -> IEWrappedName name2
replaceWrappedName (IEName (L l _)) n = IEName (L l n)
......
......@@ -38,7 +38,6 @@ import Util
import Control.Monad.Trans.Class
import Control.Monad.Trans.Writer
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
import Data.List ( nub )
import Data.Maybe ( catMaybes )
......
......@@ -34,7 +34,6 @@ module Ar
import GhcPrelude
import Data.Semigroup (Semigroup)
import Data.List (mapAccumL, isPrefixOf)
import Data.Monoid ((<>))
import Data.Binary.Get
......
......@@ -244,7 +244,9 @@ import qualified EnumSet
import GHC.Foreign (withCString, peekCString)
import qualified GHC.LanguageExtensions as LangExt
#if defined(GHCI)
import Foreign (Ptr) -- needed for 2nd stage
#endif
-- Note [Updating flag description in the User's Guide]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -25,7 +25,6 @@ module DynamicLoading (
) where
import GhcPrelude
import HscTypes ( HscEnv )
import DynFlags
#if defined(GHCI)
......@@ -63,6 +62,7 @@ import GHC.Exts ( unsafeCoerce# )
#else
import HscTypes ( HscEnv )
import Module ( ModuleName, moduleNameString )
import Panic
......@@ -76,12 +76,13 @@ import Control.Monad ( unless )
-- actual compilation starts. Idempotent operation. Should be re-called if
-- pluginModNames or pluginModNameOpts changes.
initializePlugins :: HscEnv -> DynFlags -> IO DynFlags
initializePlugins hsc_env df
#if !defined(GHCI)
initializePlugins _ df
= do let pluginMods = pluginModNames df
unless (null pluginMods) (pluginError pluginMods)
return df
#else
initializePlugins hsc_env df
| map lpModuleName (plugins df) == pluginModNames df -- plugins not changed
&& all (\p -> lpArguments p == argumentsForPlugin p (pluginModNameOpts df))
(plugins df) -- arguments not changed
......
......@@ -291,7 +291,6 @@ import GhcPrelude hiding (init)
import ByteCodeTypes
import InteractiveEval
import InteractiveEvalTypes
import TcRnDriver ( runTcInteractive )
import GHCi
import GHCi.RemoteTypes
......@@ -358,7 +357,6 @@ import Data.Set (Set)
import qualified Data.Sequence as Seq
import System.Directory ( doesFileExist )
import Data.Maybe
import Data.List ( find )
import Data.Time
import Data.Typeable ( Typeable )
import Data.Word ( Word8 )
......
......@@ -85,7 +85,6 @@ module HscMain
import GhcPrelude
import Data.Data hiding (Fixity, TyCon)
import DynFlags (addPluginModuleName)
import Id
import GHCi ( addSptEntry )
import GHCi.RemoteTypes ( ForeignHValue )
......
......@@ -95,7 +95,6 @@ import Data.List as List
import Data.Map (Map)
import Data.Set (Set)
import Data.Monoid (First(..))
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
import qualified Data.Map as Map
import qualified Data.Map.Strict as MapStrict
......
......@@ -104,7 +104,6 @@ import FastString
import Maybes
import Util
import ApiAnnotation
import HsExtension ( noExt )
import Data.List
import qualified GHC.LanguageExtensions as LangExt
import DynFlags ( WarningFlag(..) )
......
......@@ -77,7 +77,6 @@ import ListSetOps ( minusList )
import qualified GHC.LanguageExtensions as LangExt
import RnUnbound
import RnUtils
import Data.Maybe (isJust)
import qualified Data.Semigroup as Semi
import Data.Either ( partitionEithers )
import Data.List (find)
......@@ -638,21 +637,21 @@ lookupSubBndrOcc_helper must_have_parent warn_if_deprec parent rdr_name
NoParent -> Nothing
picked_gres :: [GlobalRdrElt] -> DisambigInfo
-- For Unqual, find GREs that are in scope qualified or unqualified
-- For Qual, find GREs that are in scope with that qualification
picked_gres gres
| isUnqual rdr_name
= mconcat (map right_parent gres)
= mconcat (map right_parent gres)
| otherwise
= mconcat (map right_parent (pickGREs rdr_name gres))
= mconcat (map right_parent (pickGREs rdr_name gres))
right_parent :: GlobalRdrElt -> DisambigInfo
right_parent p
| Just cur_parent <- getParent p
= if parent == cur_parent
then DisambiguatedOccurrence p
else NoOccurrence
| otherwise
= UniqueOccurrence p
= case getParent p of
Just cur_parent
| parent == cur_parent -> DisambiguatedOccurrence p
| otherwise -> NoOccurrence
Nothing -> UniqueOccurrence p
-- This domain specific datatype is used to record why we decided it was
......
......@@ -5,7 +5,6 @@ import NameSet ( FreeVars )
import TcRnTypes
import SrcLoc ( Located )
import Outputable ( Outputable )
import HsExtension ( GhcPs, GhcRn )
rnLExpr :: LHsExpr GhcPs
-> RnM (LHsExpr GhcRn, FreeVars)
......
This diff is collapsed.
......@@ -27,7 +27,6 @@ import Rules
import CoreOpt ( collectBindersPushingCo )
import CoreUtils ( exprIsTrivial, applyTypeToArgs, mkCast )
import CoreFVs
import FV ( InterestingVarFun )
import CoreArity ( etaExpandToJoinPointRule )
import UniqSupply
import Name
......
......@@ -29,9 +29,7 @@ import Id
import Type
import MkCore ( mkStringExprFS, mkNaturalExpr )
import Unique ( hasKey )
import Name ( Name )
import Var ( DFunId )
import DataCon
import TyCon
import Class
......
......@@ -26,7 +26,7 @@ import TcValidity( allDistinctTyVars )
import TcClassDcl( instDeclCtxt3, tcATDefault, tcMkDeclCtxt )
import TcEnv
import TcGenDeriv -- Deriv stuff
import TcValidity
import TcValidity( checkValidInstHead )
import InstEnv
import Inst
import FamInstEnv
......
......@@ -64,7 +64,7 @@ import qualified Data.Set as Set
import {-# SOURCE #-} TcHoleErrors ( findValidHoleFits )
import Data.Semigroup ( Semigroup )
-- import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
......
......@@ -56,7 +56,6 @@ import TcEvidence
import TysPrim
import TyCon
import TysWiredIn
import TyCoRep( CoercionHole(..) )
import Type
import Coercion
import ConLike
......
......@@ -9,7 +9,6 @@ import HsSyn
import TcRnTypes
import TcEnv( InstInfo )
import TcDeriv
import HsExtension ( GhcRn )
-- We need this because of the mutual recursion
-- between TcTyClsDecls and TcInstDcls
......
......@@ -27,7 +27,7 @@ import Class
import TyCon
import FunDeps
import FamInst
import ClsInst( ClsInstResult(..), InstanceWhat(..), safeOverlap )
import ClsInst( InstanceWhat(..), safeOverlap )
import FamInstEnv
import Unify ( tcUnifyTyWithTFs, ruleMatchTyKiX )
......
......@@ -17,10 +17,9 @@ import GhcPrelude
import HsSyn
import TcPat
import Type( mkEmptyTCvSubst, tidyTyVarBinders, tidyTypes, tidyType )
import Type( tidyTyVarBinders, tidyTypes, tidyType )
import TcRnMonad
import TcSigs( emptyPragEnv, completeSigFromId )
import TcType( mkMinimalBySCs )
import TcEnv
import TcMType
import TcHsSyn( zonkTyVarBindersX, zonkTcTypeToTypes
......
......@@ -155,7 +155,7 @@ import TcEvidence
import Type
import Class ( Class )
import TyCon ( TyCon, TyConFlavour, tyConKind )
import TyCoRep ( CoercionHole(..), coHoleCoVar )
import TyCoRep ( coHoleCoVar )
import Coercion ( Coercion, mkHoleCo )
import ConLike ( ConLike(..) )
import DataCon ( DataCon, dataConUserType, dataConOrigArgTys )
......@@ -556,6 +556,7 @@ data TcGblEnv
tcg_dus :: DefUses, -- ^ What is defined in this module and what is used.
tcg_used_gres :: TcRef [GlobalRdrElt], -- ^ Records occurrences of imported entities
-- One entry for each occurrence; but may have different GREs for the same Name
-- See Note [Tracking unused binding and imports]
tcg_keep :: TcRef NameSet,
......
......@@ -143,7 +143,6 @@ import Kind
import TcType
import DynFlags
import Type
import TyCoRep( coHoleCoVar )
import Coercion
import Unify
......
......@@ -31,7 +31,6 @@ import Type
import Kind ( isTYPEApp )
import TyCon
import DataCon
import Name ( getOccName )
import Module
import HsSyn
import DynFlags
......
......@@ -135,7 +135,7 @@ import {-# SOURCE #-} TysWiredIn ( runtimeRepTyCon, constraintKind
, vecCountTyCon, vecElemTyCon, liftedTypeKind
, mkFunKind, mkForAllKind )
import {-# SOURCE #-} DataCon ( DataCon, dataConExTyVars, dataConFieldLabels
, dataConTyCon, dataConFullSig )
, dataConTyCon, dataConFullSig, isUnboxedSumCon )
import Binary
import Var
......@@ -156,7 +156,6 @@ import Util
import Unique( tyConRepNameUnique, dataConTyRepNameUnique )
import UniqSet
import Module
import {-# SOURCE #-} DataCon
import qualified Data.Data as Data
......
......@@ -19,7 +19,6 @@ import GhcPrelude
import Outputable
import Data.Semigroup ( Semigroup )
import qualified Data.Semigroup as Semigroup
infixl 5 `appOL`
......
......@@ -108,7 +108,6 @@ import Panic
import GHC.Serialized
import GHC.LanguageExtensions (Extension)
import Control.Exception (finally)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Char
......
......@@ -7,7 +7,7 @@ module GHCi.Leak
import Control.Monad
import Data.Bits
import DynFlags (settings, sTargetPlatform)
import DynFlags ( sTargetPlatform )
import Foreign.Ptr (ptrToIntPtr, intPtrToPtr)
import GHC
import GHC.Exts (anyToAddr#)
......
......@@ -69,7 +69,6 @@ import Control.Applicative (Alternative((<|>)), Const(Const))
import Data.Functor.Identity (Identity(Identity))
import Data.Proxy (Proxy(Proxy))
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid (mappend)
import Data.Ord (Down(Down))
import GHC.Read (expectP, list, paren)
......
......@@ -27,8 +27,6 @@ import Data.Functor.Classes
import Control.Applicative
import Data.Coerce (coerce)
import Data.Data (Data)
import Data.Foldable (Foldable(foldMap))
import Data.Traversable (Traversable(traverse))
import GHC.Generics (Generic, Generic1)
import Text.Read (Read(..), readListDefault, readListPrecDefault)
......
......@@ -54,7 +54,6 @@ import Data.Functor.Sum
import Data.Functor.Compose
import Data.Monoid (Alt(..))
import Data.Semigroup (Semigroup(..))
import Data.Proxy
import GHC.Generics
......
......@@ -26,10 +26,7 @@ import Control.Monad (MonadPlus(..))
import Control.Monad.Fix (MonadFix(..))
import Control.Monad.Zip (MonadZip(mzipWith))
import Data.Data (Data)
import Data.Foldable (Foldable(foldMap))
import Data.Functor.Classes
import Data.Monoid (mappend)
import Data.Traversable (Traversable(traverse))
import GHC.Generics (Generic, Generic1)
import Text.Read (Read(..), readListDefault, readListPrecDefault)
......
......@@ -23,9 +23,7 @@ module Data.Functor.Sum (
import Control.Applicative ((<|>))
import Data.Data (Data)
import Data.Foldable (Foldable(foldMap))
import Data.Functor.Classes
import Data.Traversable (Traversable(traverse))
import GHC.Generics (Generic, Generic1)
import Text.Read (Read(..), readListDefault, readListPrecDefault)
......
......@@ -117,9 +117,6 @@ import Data.Bifunctor
import Data.Bitraversable
import Data.Coerce
import Data.Data
import Data.Monoid (All (..), Any (..), Dual (..), Endo (..),
Product (..), Sum (..))
-- import qualified Data.Monoid as Monoid
import GHC.Generics
-- | A generalization of 'Data.List.cycle' to an arbitrary 'Semigroup'.
......
......@@ -49,7 +49,6 @@ import GHC.Event.Unique
import GHC.Word (Word64)
import GHC.Num (Num(..))
import GHC.Real (fromIntegral)
import GHC.Types (Int)
#include "MachDeps.h"
......
......@@ -749,7 +749,7 @@ import GHC.Show ( Show(..), showString )
-- Needed for metadata
import Data.Proxy ( Proxy(..) )
import GHC.TypeLits ( Nat, Symbol, KnownSymbol, KnownNat, symbolVal, natVal )
import GHC.TypeLits ( KnownSymbol, KnownNat, symbolVal, natVal )
--------------------------------------------------------------------------------
-- Representation types
......
......@@ -53,7 +53,6 @@ import GHC.Base
import GHC.List ((!!), foldr1, break)
import GHC.Num
import GHC.Stack.Types
import GHC.Types (TypeLitSort (..))
-- | The @shows@ functions return a function that prepends the
......
......@@ -50,7 +50,6 @@ module GHC.StaticPtr
import Foreign.C.Types (CInt(..))
import Foreign.Marshal (allocaArray, peekArray, withArray)
import Foreign.Ptr (castPtr)
import GHC.Exts (addrToAny#)
import GHC.Ptr (Ptr(..), nullPtr)
import GHC.Fingerprint (Fingerprint(..))
import GHC.Prim
......
......@@ -32,7 +32,7 @@ module GHC.Magic ( inline, noinline, lazy, oneShot, runRW# ) where
import GHC.Prim
import GHC.CString ()
import GHC.Types (RuntimeRep, TYPE)
import GHC.Types ( RuntimeRep )
-- | The call @inline f@ arranges that 'f' is inlined, regardless of
-- its size. More precisely, the call @inline f@ rewrites to the
......
mod177.hs:5:1: warning: [-Wunused-imports (in -Wextra)]
mod177.hs:4:1: warning: [-Wunused-imports (in -Wextra)]
The import of ‘Data.Maybe’ is redundant
except perhaps to import instances from ‘Data.Maybe’
To import instances alone, use: import Data.Maybe()
......@@ -6,21 +6,21 @@ data T a = MkT {Ghci2.foo :: Bool, ...}
<interactive>:1:1: error:
Ambiguous occurrence ‘foo’
It could refer to either the field ‘foo’,
defined at <interactive>:3:16
or the field ‘foo’, defined at <interactive>:4:18
It could refer to
either the field ‘foo’, defined at <interactive>:3:16
or the field ‘foo’, defined at <interactive>:4:18
<interactive>:9:1: error:
Ambiguous occurrence ‘foo’
It could refer to either the field ‘foo’,
defined at <interactive>:3:16
or the field ‘foo’, defined at <interactive>:4:18
It could refer to
either the field ‘foo’, defined at <interactive>:3:16
or the field ‘foo’, defined at <interactive>:4:18
True
<interactive>:1:1: error:
Ambiguous occurrence ‘foo’
It could refer to either the field ‘foo’,
defined at <interactive>:3:16
or the field ‘foo’, defined at <interactive>:4:18
It could refer to
either the field ‘foo’, defined at <interactive>:3:16
or the field ‘foo’, defined at <interactive>:4:18
foo :: U -> Int
42
{-# OPTIONS_GHC -Wunused-imports #-}
module T13064 where
import Control.Applicative
import Prelude (IO, pure) -- Import of 'pure' is redundant
foo :: IO ()
foo = () <$ pure ()
T13064.hs:5:1: warning: [-Wunused-imports (in -Wextra)]
The import of ‘pure’ from module ‘Prelude’ is redundant
import T4239A ( (·), type (:+++)((:---), X, (:+++)) )
import T4239A ( (·), type (:+++)((:---), (:+++), X) )
......@@ -157,3 +157,4 @@ test('T14881', [], multimod_compile, ['T14881', '-W'])
test('T14487', [], multimod_compile, ['T14487', '-v0'])
test('T14747', [], multimod_compile, ['T14747', '-v0'])
test('T15149', [], multimod_compile, ['T15149', '-v0'])
test('T13064', normal, compile, [''])