-lookupInstDeclBndr cls_name rdr_name
- | isUnqual rdr_name -- Find all the things the rdr-name maps to
- = do { -- and pick the one with the right parent name
- let { is_op gre = cls_name == nameParent (gre_name gre)
- ; occ = rdrNameOcc rdr_name
- ; lookup_fn env = filter is_op (lookupGlobalRdrEnv env occ) }
- ; mb_gre <- lookupGreRn_help rdr_name lookup_fn
- ; case mb_gre of
- Just gre -> return (gre_name gre)
- Nothing -> do { addErr (unknownInstBndrErr cls_name rdr_name)
- ; return (mkUnboundName rdr_name) } }
+-- This is called on the method name on the left-hand side of an
+-- instance declaration binding. eg. instance Functor T where
+-- fmap = ...
+-- ^^^^ called on this
+-- Regardless of how many unqualified fmaps are in scope, we want
+-- the one that comes from the Functor class.
+--
+-- Furthermore, note that we take no account of whether the
+-- name is only in scope qualified. I.e. even if method op is
+-- in scope as M.op, we still allow plain 'op' on the LHS of
+-- an instance decl
+lookupInstDeclBndr cls rdr
+ = do { when (isQual rdr)
+ (addErr (badQualBndrErr rdr))
+ -- In an instance decl you aren't allowed
+ -- to use a qualified name for the method
+ -- (Although it'd make perfect sense.)
+ ; lookupSubBndr (ParentIs cls) doc rdr }
+ where
+ doc = ptext (sLit "method of class") <+> quotes (ppr cls)
+
+-----------------------------------------------
+lookupConstructorFields :: Name -> RnM [Name]
+-- Look up the fields of a given constructor
+-- * For constructors from this module, use the record field env,
+-- which is itself gathered from the (as yet un-typechecked)
+-- data type decls
+--
+-- * For constructors from imported modules, use the *type* environment
+-- since imported modles are already compiled, the info is conveniently
+-- right there
+
+lookupConstructorFields con_name
+ = do { this_mod <- getModule
+ ; if nameIsLocalOrFrom this_mod con_name then
+ do { RecFields field_env _ <- getRecFieldEnv
+ ; return (lookupNameEnv field_env con_name `orElse` []) }
+ else
+ do { con <- tcLookupDataCon con_name
+ ; return (dataConFieldLabels con) } }
+
+-----------------------------------------------
+-- Used for record construction and pattern matching
+-- When the -XDisambiguateRecordFields flag is on, take account of the
+-- constructor name to disambiguate which field to use; it's just the
+-- same as for instance decls
+--
+-- NB: Consider this:
+-- module Foo where { data R = R { fld :: Int } }
+-- module Odd where { import Foo; fld x = x { fld = 3 } }
+-- Arguably this should work, because the reference to 'fld' is
+-- unambiguous because there is only one field id 'fld' in scope.
+-- But currently it's rejected.
+
+lookupSubBndr :: Parent -- NoParent => just look it up as usual
+ -- ParentIs p => use p to disambiguate
+ -> SDoc -> RdrName
+ -> RnM Name
+lookupSubBndr parent doc rdr_name
+ | Just n <- isExact_maybe rdr_name -- This happens in derived code
+ = return n
+
+ | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
+ = lookupOrig rdr_mod rdr_occ