summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Gundry <adam@well-typed.com>2015-12-11 22:43:26 +0100
committerBen Gamari <ben@smart-cactus.org>2015-12-11 22:44:36 +0100
commit6e56ac58a6905197412d58e32792a04a63b94d7e (patch)
treea204c6ffc3b72c35ad4b44292acdd7a4994d77b0
parentceaf0f4683a3e0ba85ae420956cfc394824e9a38 (diff)
downloadhaskell-6e56ac58a6905197412d58e32792a04a63b94d7e.tar.gz
Fix infix record field fixity (#11167 and #11173).
This extends D1585 with proper support for infix duplicate record fields. In particular, it is now possible to declare record fields as infix in a module for which `DuplicateRecordFields` is enabled, fixity is looked up correctly and a readable (although unpleasant) error message is generated if multiple fields with different fixities are in scope. As a bonus, `DEPRECATED` and `WARNING` pragmas now work for duplicate record fields. The pragma applies to all fields with the given label. In addition, a couple of minor `DuplicateRecordFields` bugs, which were pinpointed by the `T11167_ambig` test case, are fixed by this patch: - Ambiguous infix fields can now be disambiguated by putting a type signature on the first argument - Polymorphic type constructor signatures (such as `ContT () IO a` in `T11167_ambig`) now work for disambiguation Parts of this patch are from D1585 authored by @KaneTW. Test Plan: New tests added. Reviewers: KaneTW, bgamari, austin Reviewed By: bgamari Subscribers: thomie, hvr Differential Revision: https://phabricator.haskell.org/D1600 GHC Trac Issues: #11167, #11173
-rw-r--r--compiler/hsSyn/HsExpr.hs1
-rw-r--r--compiler/hsSyn/HsTypes.hs4
-rw-r--r--compiler/main/HscTypes.hs12
-rw-r--r--compiler/rename/RnEnv.hs59
-rw-r--r--compiler/rename/RnExpr.hs7
-rw-r--r--compiler/rename/RnNames.hs11
-rw-r--r--compiler/rename/RnSource.hs4
-rw-r--r--compiler/typecheck/TcExpr.hs16
-rw-r--r--testsuite/tests/overloadedrecflds/should_compile/T11173.hs6
-rw-r--r--testsuite/tests/overloadedrecflds/should_compile/T11173a.hs10
-rw-r--r--testsuite/tests/overloadedrecflds/should_compile/all.T1
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/OverloadedRecFldsFail11_A.hs6
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.hs6
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.stderr16
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_A.hs5
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_B.hs3
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/all.T8
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.hs6
-rw-r--r--testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.stderr11
-rw-r--r--testsuite/tests/rename/should_compile/T11167.hs21
-rw-r--r--testsuite/tests/rename/should_compile/T11167_ambig.hs23
-rw-r--r--testsuite/tests/rename/should_compile/all.T2
22 files changed, 205 insertions, 33 deletions
diff --git a/compiler/hsSyn/HsExpr.hs b/compiler/hsSyn/HsExpr.hs
index b15e4304f4..c5afa7410f 100644
--- a/compiler/hsSyn/HsExpr.hs
+++ b/compiler/hsSyn/HsExpr.hs
@@ -650,6 +650,7 @@ ppr_expr (HsApp e1 e2)
ppr_expr (OpApp e1 op _ e2)
= case unLoc op of
HsVar (L _ v) -> pp_infixly v
+ HsRecFld f -> pp_infixly f
_ -> pp_prefixly
where
pp_e1 = pprDebugParendExpr e1 -- In debug mode, add parens
diff --git a/compiler/hsSyn/HsTypes.hs b/compiler/hsSyn/HsTypes.hs
index 5546a91843..8bcdc6aac1 100644
--- a/compiler/hsSyn/HsTypes.hs
+++ b/compiler/hsSyn/HsTypes.hs
@@ -723,6 +723,10 @@ deriving instance ( Data name
instance Outputable (AmbiguousFieldOcc name) where
ppr = ppr . rdrNameAmbiguousFieldOcc
+instance OutputableBndr (AmbiguousFieldOcc name) where
+ pprInfixOcc = pprInfixOcc . rdrNameAmbiguousFieldOcc
+ pprPrefixOcc = pprPrefixOcc . rdrNameAmbiguousFieldOcc
+
mkAmbiguousFieldOcc :: RdrName -> AmbiguousFieldOcc RdrName
mkAmbiguousFieldOcc rdr = Unambiguous rdr PlaceHolder
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index b5abdf4374..3ffffa1f3b 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -807,8 +807,10 @@ data ModIface
-- Cached environments for easy lookup
-- These are computed (lazily) from other fields
-- and are not put into the interface file
- mi_warn_fn :: Name -> Maybe WarningTxt, -- ^ Cached lookup for 'mi_warns'
- mi_fix_fn :: OccName -> Fixity, -- ^ Cached lookup for 'mi_fixities'
+ mi_warn_fn :: OccName -> Maybe WarningTxt,
+ -- ^ Cached lookup for 'mi_warns'
+ mi_fix_fn :: OccName -> Fixity,
+ -- ^ Cached lookup for 'mi_fixities'
mi_hash_fn :: OccName -> Maybe (OccName, Fingerprint),
-- ^ Cached lookup for 'mi_decls'.
-- The @Nothing@ in 'mi_hash_fn' means that the thing
@@ -2008,12 +2010,12 @@ instance Binary Warnings where
return (WarnSome aa)
-- | Constructs the cache for the 'mi_warn_fn' field of a 'ModIface'
-mkIfaceWarnCache :: Warnings -> Name -> Maybe WarningTxt
+mkIfaceWarnCache :: Warnings -> OccName -> Maybe WarningTxt
mkIfaceWarnCache NoWarnings = \_ -> Nothing
mkIfaceWarnCache (WarnAll t) = \_ -> Just t
-mkIfaceWarnCache (WarnSome pairs) = lookupOccEnv (mkOccEnv pairs) . nameOccName
+mkIfaceWarnCache (WarnSome pairs) = lookupOccEnv (mkOccEnv pairs)
-emptyIfaceWarnCache :: Name -> Maybe WarningTxt
+emptyIfaceWarnCache :: OccName -> Maybe WarningTxt
emptyIfaceWarnCache _ = Nothing
plusWarns :: Warnings -> Warnings -> Warnings
diff --git a/compiler/rename/RnEnv.hs b/compiler/rename/RnEnv.hs
index 42a159f3d4..7466381cd5 100644
--- a/compiler/rename/RnEnv.hs
+++ b/compiler/rename/RnEnv.hs
@@ -21,7 +21,7 @@ module RnEnv (
HsSigCtxt(..), lookupLocalTcNames, lookupSigOccRn,
lookupSigCtxtOccRn,
- lookupFixityRn, lookupTyFixityRn,
+ lookupFixityRn, lookupFieldFixityRn, lookupTyFixityRn,
lookupInstDeclBndr, lookupRecFieldOcc, lookupFamInstName,
lookupConstructorFields,
lookupSyntaxName, lookupSyntaxNames, lookupIfThenElse,
@@ -1043,10 +1043,10 @@ warnIfDeprecated gre@(GRE { gre_name = name, gre_imp = iss })
lookupImpDeprec :: ModIface -> GlobalRdrElt -> Maybe WarningTxt
lookupImpDeprec iface gre
- = mi_warn_fn iface (gre_name gre) `mplus` -- Bleat if the thing,
+ = mi_warn_fn iface (greOccName gre) `mplus` -- Bleat if the thing,
case gre_par gre of -- or its parent, is warn'd
- ParentIs p -> mi_warn_fn iface p
- FldParent { par_is = p } -> mi_warn_fn iface p
+ ParentIs p -> mi_warn_fn iface (nameOccName p)
+ FldParent { par_is = p } -> mi_warn_fn iface (nameOccName p)
NoParent -> Nothing
PatternSynonym -> Nothing
@@ -1259,7 +1259,7 @@ lookupBindGroupOcc ctxt what rdr_name
---------------
-lookupLocalTcNames :: HsSigCtxt -> SDoc -> RdrName -> RnM [Name]
+lookupLocalTcNames :: HsSigCtxt -> SDoc -> RdrName -> RnM [(RdrName, Name)]
-- GHC extension: look up both the tycon and data con or variable.
-- Used for top-level fixity signatures and deprecations.
-- Complain if neither is in scope.
@@ -1270,7 +1270,8 @@ lookupLocalTcNames ctxt what rdr_name
; when (null names) $ addErr (head errs) -- Bleat about one only
; return names }
where
- lookup = lookupBindGroupOcc ctxt what
+ lookup rdr = do { name <- lookupBindGroupOcc ctxt what rdr
+ ; return (fmap ((,) rdr) name) }
dataTcOccs :: RdrName -> [RdrName]
-- Return both the given name and the same name promoted to the TcClsName
@@ -1373,7 +1374,10 @@ lookupFixity is a bit strange.
-}
lookupFixityRn :: Name -> RnM Fixity
-lookupFixityRn name
+lookupFixityRn name = lookupFixityRn' name (nameOccName name)
+
+lookupFixityRn' :: Name -> OccName -> RnM Fixity
+lookupFixityRn' name occ
| isUnboundName name
= return (Fixity minPrecedence InfixL)
-- Minimise errors from ubound names; eg
@@ -1412,8 +1416,8 @@ lookupFixityRn name
-- and that's what we want.
= do { iface <- loadInterfaceForName doc name
; traceRn (text "lookupFixityRn: looking up name in iface cache and found:" <+>
- vcat [ppr name, ppr $ mi_fix_fn iface (nameOccName name)])
- ; return (mi_fix_fn iface (nameOccName name)) }
+ vcat [ppr name, ppr $ mi_fix_fn iface occ])
+ ; return (mi_fix_fn iface occ) }
doc = ptext (sLit "Checking fixity for") <+> ppr name
@@ -1421,6 +1425,43 @@ lookupFixityRn name
lookupTyFixityRn :: Located Name -> RnM Fixity
lookupTyFixityRn (L _ n) = lookupFixityRn n
+-- | Look up the fixity of a (possibly ambiguous) occurrence of a record field
+-- selector. We use 'lookupFixityRn'' so that we can specifiy the 'OccName' as
+-- the field label, which might be different to the 'OccName' of the selector
+-- 'Name' if @DuplicateRecordFields@ is in use (Trac #1173). If there are
+-- multiple possible selectors with different fixities, generate an error.
+lookupFieldFixityRn :: AmbiguousFieldOcc Name -> RnM Fixity
+lookupFieldFixityRn (Unambiguous rdr n) = lookupFixityRn' n (rdrNameOcc rdr)
+lookupFieldFixityRn (Ambiguous rdr _) = get_ambiguous_fixity rdr
+ where
+ get_ambiguous_fixity :: RdrName -> RnM Fixity
+ get_ambiguous_fixity rdr_name = do
+ traceRn $ text "get_ambiguous_fixity" <+> ppr rdr_name
+ rdr_env <- getGlobalRdrEnv
+ let elts = lookupGRE_RdrName rdr_name rdr_env
+
+ fixities <- groupBy ((==) `on` snd) . zip elts
+ <$> mapM lookup_gre_fixity elts
+
+ case fixities of
+ -- There should always be at least one fixity.
+ -- Something's very wrong if there are no fixity candidates, so panic
+ [] -> panic "get_ambiguous_fixity: no candidates for a given RdrName"
+ [ (_, fix):_ ] -> return fix
+ ambigs -> addErr (ambiguous_fixity_err rdr_name ambigs)
+ >> return (Fixity minPrecedence InfixL)
+
+ lookup_gre_fixity gre = lookupFixityRn' (gre_name gre) (greOccName gre)
+
+ ambiguous_fixity_err rn ambigs
+ = vcat [ text "Ambiguous fixity for record field" <+> quotes (ppr rn)
+ , hang (text "Conflicts: ") 2 . vcat .
+ map format_ambig $ concat ambigs ]
+
+ format_ambig (elt, fix) = hang (ppr fix)
+ 2 (pprNameProvenance elt)
+
+
{-
************************************************************************
* *
diff --git a/compiler/rename/RnExpr.hs b/compiler/rename/RnExpr.hs
index 5df96cf042..11d03f4d6a 100644
--- a/compiler/rename/RnExpr.hs
+++ b/compiler/rename/RnExpr.hs
@@ -150,9 +150,10 @@ rnExpr (OpApp e1 op _ e2)
-- more, so I've removed the test. Adding HsPars in TcGenDeriv
-- should prevent bad things happening.
; fixity <- case op' of
- L _ (HsVar (L _ n)) -> lookupFixityRn n
- _ -> return (Fixity minPrecedence InfixL)
- -- c.f. lookupFixity for unbound
+ L _ (HsVar (L _ n)) -> lookupFixityRn n
+ L _ (HsRecFld f) -> lookupFieldFixityRn f
+ _ -> return (Fixity minPrecedence InfixL)
+ -- c.f. lookupFixity for unbound
; final_e <- mkOpAppRn e1' op' fixity e2'
; return (final_e, fv_e1 `plusFV` fv_op `plusFV` fv_e2) }
diff --git a/compiler/rename/RnNames.hs b/compiler/rename/RnNames.hs
index 0024304b3a..cfe5fc5c27 100644
--- a/compiler/rename/RnNames.hs
+++ b/compiler/rename/RnNames.hs
@@ -477,7 +477,7 @@ extendGlobalRdrEnvRn avails new_fixities
; rdr_env2 <- foldlM add_gre rdr_env1 new_gres
- ; let fix_env' = foldl extend_fix_env fix_env new_names
+ ; let fix_env' = foldl extend_fix_env fix_env new_gres
gbl_env' = gbl_env { tcg_rdr_env = rdr_env2, tcg_fix_env = fix_env' }
; traceRn (text "extendGlobalRdrEnvRn 2" <+> (pprGlobalRdrEnv True rdr_env2))
@@ -487,13 +487,14 @@ extendGlobalRdrEnvRn avails new_fixities
new_occs = map nameOccName new_names
-- If there is a fixity decl for the gre, add it to the fixity env
- extend_fix_env fix_env name
+ extend_fix_env fix_env gre
| Just (L _ fi) <- lookupFsEnv new_fixities (occNameFS occ)
= extendNameEnv fix_env name (FixItem occ fi)
| otherwise
= fix_env
where
- occ = nameOccName name
+ name = gre_name gre
+ occ = greOccName gre
new_gres :: [GlobalRdrElt] -- New LocalDef GREs, derived from avails
new_gres = concatMap localGREsFromAvail avails
@@ -564,8 +565,8 @@ getLocalNonValBinders fixity_env
; val_avails <- mapM new_simple val_bndrs
; let avails = concat nti_availss ++ val_avails
- new_bndrs = availsToNameSet avails `unionNameSet`
- availsToNameSet tc_avails
+ new_bndrs = availsToNameSetWithSelectors avails `unionNameSet`
+ availsToNameSetWithSelectors tc_avails
flds = concat nti_fldss ++ concat tc_fldss
; traceRn (text "getLocalNonValBinders 2" <+> ppr avails)
; (tcg_env, tcl_env) <- extendGlobalRdrEnvRn avails fixity_env
diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs
index 1579400fc2..b284ec8d88 100644
--- a/compiler/rename/RnSource.hs
+++ b/compiler/rename/RnSource.hs
@@ -287,7 +287,7 @@ rnSrcFixityDecls bndr_set fix_decls
= setSrcSpan name_loc $
-- this lookup will fail if the definition isn't local
do names <- lookupLocalTcNames sig_ctxt what rdr_name
- return [ L name_loc name | name <- names ]
+ return [ L name_loc name | (_, name) <- names ]
what = ptext (sLit "fixity signature")
{-
@@ -325,7 +325,7 @@ rnSrcWarnDecls bndr_set decls'
-- ensures that the names are defined locally
= do { names <- concatMapM (lookupLocalTcNames sig_ctxt what . unLoc)
rdr_names
- ; return [(nameOccName name, txt) | name <- names] }
+ ; return [(rdrNameOcc rdr, txt) | (rdr, _) <- names] }
what = ptext (sLit "deprecation")
diff --git a/compiler/typecheck/TcExpr.hs b/compiler/typecheck/TcExpr.hs
index 26e920ead9..853ef54c8a 100644
--- a/compiler/typecheck/TcExpr.hs
+++ b/compiler/typecheck/TcExpr.hs
@@ -379,6 +379,15 @@ tcExpr (OpApp arg1 op fix arg2) res_ty
op' fix
(mkLHsWrapCo co_a arg2') }
+ | (L loc (HsRecFld (Ambiguous lbl _))) <- op
+ , Just sig_ty <- obviousSig (unLoc arg1)
+ -- See Note [Disambiguating record fields]
+ = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty
+ ; sel_name <- disambiguateSelector lbl sig_tc_ty
+ ; let op' = L loc (HsRecFld (Unambiguous lbl sel_name))
+ ; tcExpr (OpApp arg1 op' fix arg2) res_ty
+ }
+
| otherwise
= do { traceTc "Non Application rule" (ppr op)
; (op', op_ty) <- tcInferFun op
@@ -1739,11 +1748,14 @@ disambiguateRecordBinds record_expr record_tau rbnds res_ty
-- Extract the outermost TyCon of a type, if there is one; for
-- data families this is the representation tycon (because that's
--- where the fields live).
+-- where the fields live). Look inside sigma-types, so that
+-- tyConOf _ (forall a. Q => T a) = T
tyConOf :: FamInstEnvs -> Type -> Maybe TyCon
-tyConOf fam_inst_envs ty = case tcSplitTyConApp_maybe ty of
+tyConOf fam_inst_envs ty0 = case tcSplitTyConApp_maybe ty of
Just (tc, tys) -> Just (fstOf3 (tcLookupDataFamInst fam_inst_envs tc tys))
Nothing -> Nothing
+ where
+ (_, _, ty) = tcSplitSigmaTy ty0
-- For an ambiguous record field, find all the candidate record
-- selectors (as GlobalRdrElts) and their parents.
diff --git a/testsuite/tests/overloadedrecflds/should_compile/T11173.hs b/testsuite/tests/overloadedrecflds/should_compile/T11173.hs
new file mode 100644
index 0000000000..54b363869e
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_compile/T11173.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+module T11173 where
+import T11173a (A(..))
+
+-- Check that the fixity declaration applied to the field 'foo' is used
+x b = b `foo` b `foo` 0
diff --git a/testsuite/tests/overloadedrecflds/should_compile/T11173a.hs b/testsuite/tests/overloadedrecflds/should_compile/T11173a.hs
new file mode 100644
index 0000000000..ae8c37f763
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_compile/T11173a.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+module T11173a where
+
+data A = A { foo :: Int -> Int, bar :: Int -> Int }
+newtype B = B { foo :: Int -> Int }
+infixr 5 `foo`
+infixr 5 `bar`
+
+-- This is well-typed only if the fixity is correctly applied
+y b = b `bar` b `bar` 0
diff --git a/testsuite/tests/overloadedrecflds/should_compile/all.T b/testsuite/tests/overloadedrecflds/should_compile/all.T
new file mode 100644
index 0000000000..ea5baf899e
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_compile/all.T
@@ -0,0 +1 @@
+test('T11173', extra_clean(['T11173a.hi', 'T11173a.o']), multimod_compile, ['T11173', '-v0'])
diff --git a/testsuite/tests/overloadedrecflds/should_fail/OverloadedRecFldsFail11_A.hs b/testsuite/tests/overloadedrecflds/should_fail/OverloadedRecFldsFail11_A.hs
new file mode 100644
index 0000000000..9dbadc648c
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/OverloadedRecFldsFail11_A.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+module OverloadedRecFldsFail11_A where
+
+{-# WARNING foo "Warning on a record field" #-}
+data S = MkS { foo :: Bool }
+data T = MkT { foo :: Int }
diff --git a/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.hs b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.hs
new file mode 100644
index 0000000000..d4dd38edbb
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+module T11167_ambiguous_fixity where
+import T11167_ambiguous_fixity_A
+import T11167_ambiguous_fixity_B
+
+x a = (a :: A) `foo` 0
diff --git a/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.stderr b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.stderr
new file mode 100644
index 0000000000..26b8daa53d
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity.stderr
@@ -0,0 +1,16 @@
+[1 of 3] Compiling T11167_ambiguous_fixity_B ( T11167_ambiguous_fixity_B.hs, T11167_ambiguous_fixity_B.o )
+[2 of 3] Compiling T11167_ambiguous_fixity_A ( T11167_ambiguous_fixity_A.hs, T11167_ambiguous_fixity_A.o )
+[3 of 3] Compiling T11167_ambiguous_fixity ( T11167_ambiguous_fixity.hs, T11167_ambiguous_fixity.o )
+
+T11167_ambiguous_fixity.hs:6:7: error:
+ Ambiguous fixity for record field ‘foo’
+ Conflicts:
+ infixr 3
+ imported from ‘T11167_ambiguous_fixity_A’ at T11167_ambiguous_fixity.hs:3:1-32
+ (and originally defined at T11167_ambiguous_fixity_A.hs:4:16-18)
+ infixr 3
+ imported from ‘T11167_ambiguous_fixity_A’ at T11167_ambiguous_fixity.hs:3:1-32
+ (and originally defined at T11167_ambiguous_fixity_A.hs:3:16-18)
+ infixl 5
+ imported from ‘T11167_ambiguous_fixity_B’ at T11167_ambiguous_fixity.hs:4:1-32
+ (and originally defined at T11167_ambiguous_fixity_B.hs:2:16-18)
diff --git a/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_A.hs b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_A.hs
new file mode 100644
index 0000000000..cc5440de16
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_A.hs
@@ -0,0 +1,5 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+module T11167_ambiguous_fixity_A where
+data A = MkA { foo :: Int -> Int }
+data C = MkC { foo :: Int -> Int }
+infixr 3 `foo`
diff --git a/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_B.hs b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_B.hs
new file mode 100644
index 0000000000..927a336537
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/T11167_ambiguous_fixity_B.hs
@@ -0,0 +1,3 @@
+module T11167_ambiguous_fixity_B where
+data B = MkB { foo :: Int -> Int }
+infixl 5 `foo`
diff --git a/testsuite/tests/overloadedrecflds/should_fail/all.T b/testsuite/tests/overloadedrecflds/should_fail/all.T
index a9c7426c78..a1b8ccb4ad 100644
--- a/testsuite/tests/overloadedrecflds/should_fail/all.T
+++ b/testsuite/tests/overloadedrecflds/should_fail/all.T
@@ -16,10 +16,16 @@ test('overloadedrecfldsfail10',
, 'OverloadedRecFldsFail10_B.hi', 'OverloadedRecFldsFail10_B.o'
, 'OverloadedRecFldsFail10_C.hi', 'OverloadedRecFldsFail10_C.o']),
multimod_compile_fail, ['overloadedrecfldsfail10', ''])
-test('overloadedrecfldsfail11', normal, compile_fail, [''])
+test('overloadedrecfldsfail11',
+ extra_clean(['OverloadedRecFldsFail11_A.hi', 'OverloadedRecFldsFail11_A.o']),
+ multimod_compile_fail, ['overloadedrecfldsfail11', ''])
test('overloadedrecfldsfail12',
extra_clean(['OverloadedRecFldsFail12_A.hi', 'OverloadedRecFldsFail12_A.o']),
multimod_compile_fail, ['overloadedrecfldsfail12', ''])
test('overloadedrecfldsfail13', normal, compile_fail, [''])
test('overloadedrecfldsfail14', normal, compile_fail, [''])
test('overloadedlabelsfail01', normal, compile_fail, [''])
+test('T11167_ambiguous_fixity',
+ extra_clean([ 'T11167_ambiguous_fixity_A.hi', 'T11167_ambiguous_fixity_A.o'
+ , 'T11167_ambiguous_fixity_B.hi', 'T11167_ambiguous_fixity_B.o' ]),
+ multimod_compile_fail, ['T11167_ambiguous_fixity', ''])
diff --git a/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.hs b/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.hs
index 9c5c145c94..c1c309a48a 100644
--- a/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.hs
+++ b/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.hs
@@ -1,5 +1,5 @@
{-# LANGUAGE DuplicateRecordFields #-}
+{-# OPTIONS_GHC -Werror #-}
+import OverloadedRecFldsFail11_A
-{-# WARNING foo "No warnings for DRFs" #-}
-data S = MkS { foo :: Bool }
-data T = MkT { foo :: Int }
+main = print (foo (MkS True :: S))
diff --git a/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.stderr b/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.stderr
index 650456ccd0..771a46f10c 100644
--- a/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.stderr
+++ b/testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail11.stderr
@@ -1,4 +1,9 @@
+[1 of 2] Compiling OverloadedRecFldsFail11_A ( OverloadedRecFldsFail11_A.hs, OverloadedRecFldsFail11_A.o )
+[2 of 2] Compiling Main ( overloadedrecfldsfail11.hs, overloadedrecfldsfail11.o )
-overloadedrecfldsfail11.hs:3:13: error:
- The deprecation for ‘foo’ lacks an accompanying binding
- (The deprecation must be given where ‘foo’ is declared)
+overloadedrecfldsfail11.hs:5:15: warning:
+ In the use of ‘foo’ (imported from OverloadedRecFldsFail11_A):
+ "Warning on a record field"
+
+<no location info>: error:
+Failing due to -Werror.
diff --git a/testsuite/tests/rename/should_compile/T11167.hs b/testsuite/tests/rename/should_compile/T11167.hs
new file mode 100644
index 0000000000..644cc90bed
--- /dev/null
+++ b/testsuite/tests/rename/should_compile/T11167.hs
@@ -0,0 +1,21 @@
+module T11167 where
+
+data SomeException
+
+newtype ContT r m a = ContT {runContT :: (a -> m r) -> m r}
+
+runContT' :: ContT r m a -> (a -> m r) -> m r
+runContT' = runContT
+
+catch_ :: IO a -> (SomeException -> IO a) -> IO a
+catch_ = undefined
+
+foo :: IO ()
+foo = (undefined :: ContT () IO a)
+ `runContT` (undefined :: a -> IO ())
+ `catch_` (undefined :: SomeException -> IO ())
+
+foo' :: IO ()
+foo' = (undefined :: ContT () IO a)
+ `runContT'` (undefined :: a -> IO ())
+ `catch_` (undefined :: SomeException -> IO ())
diff --git a/testsuite/tests/rename/should_compile/T11167_ambig.hs b/testsuite/tests/rename/should_compile/T11167_ambig.hs
new file mode 100644
index 0000000000..74df05e5ee
--- /dev/null
+++ b/testsuite/tests/rename/should_compile/T11167_ambig.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+module T11167_ambig where
+
+data SomeException
+
+newtype ContT r m a = ContT {runContT :: (a -> m r) -> m r}
+newtype ContT' r m a = ContT' {runContT :: (a -> m r) -> m r}
+
+runContT' :: ContT r m a -> (a -> m r) -> m r
+runContT' = runContT
+
+catch_ :: IO a -> (SomeException -> IO a) -> IO a
+catch_ = undefined
+
+foo :: IO ()
+foo = (undefined :: ContT () IO a)
+ `runContT` (undefined :: a -> IO ())
+ `catch_` (undefined :: SomeException -> IO ())
+
+foo' :: IO ()
+foo' = (undefined :: ContT () IO a)
+ `runContT'` (undefined :: a -> IO ())
+ `catch_` (undefined :: SomeException -> IO ())
diff --git a/testsuite/tests/rename/should_compile/all.T b/testsuite/tests/rename/should_compile/all.T
index 05bc2507d0..8c120cd4c2 100644
--- a/testsuite/tests/rename/should_compile/all.T
+++ b/testsuite/tests/rename/should_compile/all.T
@@ -230,3 +230,5 @@ test('T11164',
extra_clean(['T11164a.hi', 'T11164a.o',
'T11164b.hi', 'T11164b.o']),
multimod_compile, ['T11164', '-v0'])
+test('T11167', normal, compile, [''])
+test('T11167_ambig', normal, compile, [''])