diff --git a/compiler/deSugar/DsBinds.hs b/compiler/deSugar/DsBinds.hs
index b6693aa0d437cd3f9437738a8c28d4387f38b531..d65cc42cc3908589e2548331a44c28c127e8c8c0 100644
--- a/compiler/deSugar/DsBinds.hs
+++ b/compiler/deSugar/DsBinds.hs
@@ -37,7 +37,6 @@ import CoreUnfold
 import CoreFVs
 import UniqSupply
 import Digraph
-import Module
 import PrelNames
 import TysPrim ( mkProxyPrimTy )
 import TyCon      ( isTupleTyCon, tyConDataCons_maybe
@@ -47,11 +46,12 @@ import TcType
 import Type
 import Kind (returnsConstraintKind)
 import Coercion hiding (substCo)
-import TysWiredIn ( eqBoxDataCon, coercibleDataCon, tupleCon )
+import TysWiredIn ( eqBoxDataCon, coercibleDataCon, tupleCon, mkListTy
+                  , mkBoxedTupleTy, stringTy )
 import Id
 import MkId(proxyHashId)
 import Class
-import DataCon  ( dataConWorkId )
+import DataCon  ( dataConTyCon, dataConWorkId )
 import Name
 import IdInfo   ( IdDetails(..) )
 import Var
@@ -59,6 +59,7 @@ import VarSet
 import Rules
 import VarEnv
 import Outputable
+import Module
 import SrcLoc
 import Maybes
 import OrdList
@@ -914,6 +915,8 @@ dsEvTerm (EvLit l) =
 
 dsEvTerm (EvTypeable ev) = dsEvTypeable ev
 
+dsEvTerm (EvCallStack cs) = dsEvCallStack cs
+
 dsEvTypeable :: EvTypeable -> DsM CoreExpr
 dsEvTypeable ev =
   do tyCl      <- dsLookupTyCon typeableClassName
@@ -1032,6 +1035,59 @@ the proxy argument.  This is what went wrong in #3245 and #9203. So we
 help GHC by manually keeping the 'rep' *outside* the lambda.
 -}
 
+dsEvCallStack :: EvCallStack -> DsM CoreExpr
+-- See Note [Overview of implicit CallStacks] in TcEvidence.hs
+dsEvCallStack cs = do
+  df              <- getDynFlags
+  m               <- getModule
+  srcLocDataCon   <- dsLookupDataCon srcLocDataConName
+  let srcLocTyCon  = dataConTyCon srcLocDataCon
+  let srcLocTy     = mkTyConTy srcLocTyCon
+  let mkSrcLoc l =
+        liftM (mkCoreConApps srcLocDataCon)
+              (sequence [ mkStringExprFS (packageKeyFS $ modulePackageKey m)
+                        , mkStringExprFS (moduleNameFS $ moduleName m)
+                        , mkStringExprFS (srcSpanFile l)
+                        , return $ mkIntExprInt df (srcSpanStartLine l)
+                        , return $ mkIntExprInt df (srcSpanStartCol l)
+                        , return $ mkIntExprInt df (srcSpanEndLine l)
+                        , return $ mkIntExprInt df (srcSpanEndCol l)
+                        ])
+
+  let callSiteTy = mkBoxedTupleTy [stringTy, srcLocTy]
+
+  matchId         <- newSysLocalDs $ mkListTy callSiteTy
+
+  callStackDataCon <- dsLookupDataCon callStackDataConName
+  let callStackTyCon = dataConTyCon callStackDataCon
+  let callStackTy    = mkTyConTy callStackTyCon
+  let emptyCS        = mkCoreConApps callStackDataCon [mkNilExpr callSiteTy]
+  let pushCS name loc rest =
+        mkWildCase rest callStackTy callStackTy
+                   [( DataAlt callStackDataCon
+                    , [matchId]
+                    , mkCoreConApps callStackDataCon
+                       [mkConsExpr callSiteTy
+                                   (mkCoreTup [name, loc])
+                                   (Var matchId)]
+                    )]
+  let mkPush name loc tm = do
+        nameExpr <- mkStringExprFS name
+        locExpr <- mkSrcLoc loc
+        case tm of
+          EvCallStack EvCsEmpty -> return (pushCS nameExpr locExpr emptyCS)
+          _ -> do tmExpr  <- dsEvTerm tm
+                  -- at this point tmExpr :: IP sym CallStack
+                  -- but we need the actual CallStack to pass to pushCS,
+                  -- so we use unwrapIP to strip the dictionary wrapper
+                  -- See Note [Overview of implicit CallStacks]
+                  let ip_co = unwrapIP (exprType tmExpr)
+                  return (pushCS nameExpr locExpr (mkCast tmExpr ip_co))
+  case cs of
+    EvCsTop name loc tm -> mkPush name loc tm
+    EvCsPushCall name loc tm -> mkPush (occNameFS $ getOccName name) loc tm
+    EvCsEmpty -> panic "Cannot have an empty CallStack"
+
 ---------------------------------------
 dsTcCoercion :: TcCoercion -> (Coercion -> CoreExpr) -> DsM CoreExpr
 -- This is the crucial function that moves
diff --git a/compiler/prelude/PrelNames.hs b/compiler/prelude/PrelNames.hs
index eb36f62332ee51c69a7f0de2d2c1b44e0e57bb60..168578d8c1b21f2ae317396f8ee671ed9ff056da 100644
--- a/compiler/prelude/PrelNames.hs
+++ b/compiler/prelude/PrelNames.hs
@@ -331,6 +331,10 @@ basicKnownKeyNames
         -- Implicit parameters
         ipClassName,
 
+        -- Source locations
+        callStackDataConName, callStackTyConName,
+        srcLocDataConName,
+
         -- Annotation type checking
         toAnnotationWrapperName
 
@@ -463,6 +467,12 @@ gHC_IP          = mkBaseModule (fsLit "GHC.IP")
 gHC_PARR' :: Module
 gHC_PARR' = mkBaseModule (fsLit "GHC.PArr")
 
+gHC_SRCLOC :: Module
+gHC_SRCLOC = mkBaseModule (fsLit "GHC.SrcLoc")
+
+gHC_STACK :: Module
+gHC_STACK = mkBaseModule (fsLit "GHC.Stack")
+
 gHC_STATICPTR :: Module
 gHC_STATICPTR = mkBaseModule (fsLit "GHC.StaticPtr")
 
@@ -1187,6 +1197,15 @@ knownSymbolClassName  = clsQual gHC_TYPELITS (fsLit "KnownSymbol") knownSymbolCl
 ipClassName :: Name
 ipClassName         = clsQual gHC_IP (fsLit "IP")      ipClassNameKey
 
+-- Source Locations
+callStackDataConName, callStackTyConName, srcLocDataConName :: Name
+callStackDataConName
+  = conName gHC_STACK (fsLit "CallStack") callStackDataConKey
+callStackTyConName
+  = tcQual  gHC_STACK (fsLit "CallStack") callStackTyConKey
+srcLocDataConName
+  = conName gHC_SRCLOC (fsLit "SrcLoc")   srcLocDataConKey
+
 -- plugins
 pLUGINS :: Module
 pLUGINS = mkThisGhcModule (fsLit "Plugins")
@@ -1540,6 +1559,9 @@ staticPtrInfoTyConKey = mkPreludeTyConUnique 181
 typeRepTyConKey :: Unique
 typeRepTyConKey = mkPreludeTyConUnique 183
 
+callStackTyConKey :: Unique
+callStackTyConKey = mkPreludeTyConUnique 182
+
 ---------------- Template Haskell -------------------
 --      USES TyConUniques 200-299
 -----------------------------------------------------
@@ -1612,6 +1634,10 @@ staticPtrInfoDataConKey                 = mkPreludeDataConUnique 34
 fingerprintDataConKey :: Unique
 fingerprintDataConKey                   = mkPreludeDataConUnique 35
 
+callStackDataConKey, srcLocDataConKey :: Unique
+callStackDataConKey                     = mkPreludeDataConUnique 36
+srcLocDataConKey                        = mkPreludeDataConUnique 37
+
 {-
 ************************************************************************
 *                                                                      *
diff --git a/compiler/typecheck/TcBinds.hs b/compiler/typecheck/TcBinds.hs
index a13d93e6e50159e16d0ee228ff3d8ea86b2e8f3d..9d8c581137ba8211def920b3baab4546372e8085 100644
--- a/compiler/typecheck/TcBinds.hs
+++ b/compiler/typecheck/TcBinds.hs
@@ -54,7 +54,6 @@ import BasicTypes
 import Outputable
 import FastString
 import Type(mkStrLitTy)
-import Class(classTyCon)
 import PrelNames(ipClassName)
 import TcValidity (checkValidType)
 
@@ -251,10 +250,8 @@ tcLocalBinds (HsIPBinds (IPBinds ip_binds _)) thing_inside
 
     -- Coerces a `t` into a dictionry for `IP "x" t`.
     -- co : t -> IP "x" t
-    toDict ipClass x ty =
-      case unwrapNewTyCon_maybe (classTyCon ipClass) of
-        Just (_,_,ax) -> HsWrap $ mkWpCast $ mkTcSymCo $ mkTcUnbranchedAxInstCo Representational ax [x,ty]
-        Nothing       -> panic "The dictionary for `IP` is not a newtype?"
+    toDict ipClass x ty = HsWrap $ mkWpCast $ TcCoercion $
+                          wrapIP $ mkClassPred ipClass [x,ty]
 
 {-
 Note [Implicit parameter untouchables]
diff --git a/compiler/typecheck/TcEvidence.hs b/compiler/typecheck/TcEvidence.hs
index 9eef643c9e4e3bfcb30d73e85c78ea4c5547c3c6..70baef463738fbf89adad56bb9aeafcda44ef1ae 100644
--- a/compiler/typecheck/TcEvidence.hs
+++ b/compiler/typecheck/TcEvidence.hs
@@ -16,6 +16,7 @@ module TcEvidence (
   EvTerm(..), mkEvCast, evVarsOfTerm, mkEvTupleSelectors, mkEvScSelectors,
   EvLit(..), evTermCoercion,
   EvTypeable(..),
+  EvCallStack(..),
 
   -- TcCoercion
   TcCoercion(..), LeftOrRight(..), pickLR,
@@ -27,7 +28,8 @@ module TcEvidence (
   mkTcAxiomRuleCo, mkTcPhantomCo,
   tcCoercionKind, coVarsOfTcCo, isEqVar, mkTcCoVarCo,
   isTcReflCo, getTcCoVar_maybe,
-  tcCoercionRole, eqVarRole
+  tcCoercionRole, eqVarRole,
+  unwrapIP, wrapIP
   ) where
 #include "HsVersions.h"
 
@@ -55,6 +57,7 @@ import Data.Traversable (traverse, sequenceA)
 import qualified Data.Data as Data
 import Outputable
 import FastString
+import SrcLoc
 import Data.IORef( IORef )
 
 {-
@@ -708,6 +711,8 @@ data EvTerm
 
   | EvTypeable EvTypeable   -- Dictionary for `Typeable`
 
+  | EvCallStack EvCallStack -- Dictionary for CallStack implicit parameters
+
   deriving( Data.Data, Data.Typeable )
 
 -- | Instructions on how to make a 'Typeable' dictionary.
@@ -727,7 +732,19 @@ data EvTypeable
 data EvLit
   = EvNum Integer
   | EvStr FastString
-    deriving( Data.Data, Data.Typeable)
+    deriving( Data.Data, Data.Typeable )
+
+-- | Evidence for @CallStack@ implicit parameters.
+data EvCallStack
+  -- See Note [Overview of implicit CallStacks]
+  = EvCsEmpty
+  | EvCsPushCall Name RealSrcSpan EvTerm
+    -- ^ @EvCsPushCall name loc stk@ represents a call to @name@, occurring at
+    -- @loc@, in a calling context @stk@.
+  | EvCsTop FastString RealSrcSpan EvTerm
+    -- ^ @EvCsTop name loc stk@ represents a use of an implicit parameter
+    -- @?name@, occurring at @loc@, in a calling context @stk@.
+  deriving( Data.Data, Data.Typeable )
 
 {-
 Note [Coercion evidence terms]
@@ -818,6 +835,119 @@ The story for kind `Symbol` is analogous:
   * class KnownSymbol
   * newtype SSymbol
   * Evidence: EvLit (EvStr n)
+
+
+Note [Overview of implicit CallStacks]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(See https://ghc.haskell.org/trac/ghc/wiki/ExplicitCallStack/ImplicitLocations)
+
+The goal of CallStack evidence terms is to reify locations
+in the program source as runtime values, without any support
+from the RTS. We accomplish this by assigning a special meaning
+to implicit parameters of type GHC.Stack.CallStack. A use of
+a CallStack IP, e.g.
+
+  head []    = error (show (?loc :: CallStack))
+  head (x:_) = x
+
+will be solved with the source location that gave rise to the IP
+constraint (here, the use of ?loc). If there is already
+a CallStack IP in scope, e.g. passed-in as an argument
+
+  head :: (?loc :: CallStack) => [a] -> a
+  head []    = error (show (?loc :: CallStack))
+  head (x:_) = x
+
+we will push the new location onto the CallStack that was passed
+in. These two cases are reflected by the EvCallStack evidence
+type. In the first case, we will create an evidence term
+
+  EvCsTop "?loc" <?loc's location> EvCsEmpty
+
+and in the second we'll have a given constraint
+
+  [G] d :: IP "loc" CallStack
+
+in scope, and will create an evidence term
+
+  EvCsTop "?loc" <?loc's location> d
+
+When we call a function that uses a CallStack IP, e.g.
+
+  f = head xs
+
+we create an evidence term
+
+  EvCsPushCall "head" <head's location> EvCsEmpty
+
+again pushing onto a given evidence term if one exists.
+
+This provides a lightweight mechanism for building up call-stacks
+explicitly, but is notably limited by the fact that the stack will
+stop at the first function whose type does not include a CallStack IP.
+For example, using the above definition of head:
+
+  f :: [a] -> a
+  f = head
+
+  g = f []
+
+the resulting CallStack will include use of ?loc inside head and
+the call to head inside f, but NOT the call to f inside g, because f
+did not explicitly request a CallStack.
+
+Important Details:
+- GHC should NEVER report an insoluble CallStack constraint.
+
+- A CallStack (defined in GHC.Stack) is a [(String, SrcLoc)], where the String
+  is the name of the binder that is used at the SrcLoc. SrcLoc is defined in
+  GHC.SrcLoc and contains the package/module/file name, as well as the full
+  source-span. Both CallStack and SrcLoc are kept abstract so only GHC can
+  construct new values.
+
+- Consider the use of ?stk in:
+
+    head :: (?stk :: CallStack) => [a] -> a
+    head [] = error (show ?stk)
+
+  When solving the use of ?stk we'll have a given
+
+   [G] d :: IP "stk" CallStack
+
+  in scope. In the interaction phase, GHC would normally solve the use of ?stk
+  directly from the given, i.e. re-using the dicionary. But this is NOT what we
+  want! We want to generate a *new* CallStack with ?loc's SrcLoc pushed onto
+  the given CallStack. So we must take care in TcInteract.interactDict to
+  prioritize solving wanted CallStacks.
+
+- We will automatically solve any wanted CallStack regardless of the name of the
+  IP, i.e.
+
+    f = show (?stk :: CallStack)
+    g = show (?loc :: CallStack)
+
+  are both valid. However, we will only push new SrcLocs onto existing
+  CallStacks when the IP names match, e.g. in
+
+    head :: (?loc :: CallStack) => [a] -> a
+    head [] = error (show (?stk :: CallStack))
+
+  the printed CallStack will NOT include head's call-site. This reflects the
+  standard scoping rules of implicit-parameters. (See TcInteract.interactDict)
+
+- An EvCallStack term desugars to a CoreExpr of type `IP "some str" CallStack`.
+  The desugarer will need to unwrap the IP newtype before pushing a new
+  call-site onto a given stack (See DsBinds.dsEvCallStack)
+
+- We only want to intercept constraints that arose due to the use of an IP or a
+  function call. In particular, we do NOT want to intercept the
+
+    (?stk :: CallStack) => [a] -> a
+      ~
+    (?stk :: CallStack) => [a] -> a
+
+  constraint that arises from the ambiguity check on `head`s type signature.
+  (See TcEvidence.isCallStackIP)
 -}
 
 mkEvCast :: EvTerm -> TcCoercion -> EvTerm
@@ -864,6 +994,7 @@ evVarsOfTerm (EvTupleMk evs)      = evVarsOfTerms evs
 evVarsOfTerm (EvDelayedError _ _) = emptyVarSet
 evVarsOfTerm (EvLit _)            = emptyVarSet
 evVarsOfTerm (EvTypeable ev)      = evVarsOfTypeable ev
+evVarsOfTerm (EvCallStack cs)     = evVarsOfCallStack cs
 
 evVarsOfTerms :: [EvTerm] -> VarSet
 evVarsOfTerms = mapUnionVarSet evVarsOfTerm
@@ -875,6 +1006,12 @@ evVarsOfTypeable ev =
     EvTypeableTyApp e1 e2  -> evVarsOfTerms (map fst [e1,e2])
     EvTypeableTyLit _      -> emptyVarSet
 
+evVarsOfCallStack :: EvCallStack -> VarSet
+evVarsOfCallStack cs = case cs of
+  EvCsEmpty -> emptyVarSet
+  EvCsTop _ _ tm -> evVarsOfTerm tm
+  EvCsPushCall _ _ tm -> evVarsOfTerm tm
+
 {-
 ************************************************************************
 *                                                                      *
@@ -934,6 +1071,7 @@ instance Outputable EvTerm where
   ppr (EvSuperClass d n) = ptext (sLit "sc") <> parens (ppr (d,n))
   ppr (EvDFunApp df tys ts) = ppr df <+> sep [ char '@' <> ppr tys, ppr ts ]
   ppr (EvLit l)          = ppr l
+  ppr (EvCallStack cs)   = ppr cs
   ppr (EvDelayedError ty msg) =     ptext (sLit "error")
                                 <+> sep [ char '@' <> ppr ty, ppr msg ]
   ppr (EvTypeable ev)    = ppr ev
@@ -948,3 +1086,33 @@ instance Outputable EvTypeable where
       EvTypeableTyCon tc ks    -> parens (ppr tc <+> sep (map ppr ks))
       EvTypeableTyApp t1 t2    -> parens (ppr (fst t1) <+> ppr (fst t2))
       EvTypeableTyLit x        -> ppr x
+
+instance Outputable EvCallStack where
+  ppr EvCsEmpty
+    = ptext (sLit "[]")
+  ppr (EvCsTop name loc tm)
+    = angleBrackets (ppr (name,loc)) <+> ptext (sLit ":") <+> ppr tm
+  ppr (EvCsPushCall name loc tm)
+    = angleBrackets (ppr (name,loc)) <+> ptext (sLit ":") <+> ppr tm
+
+----------------------------------------------------------------------
+-- Helper functions for dealing with IP newtype-dictionaries
+----------------------------------------------------------------------
+
+-- | Create a 'Coercion' that unwraps an implicit-parameter dictionary
+-- to expose the underlying value. We expect the 'Type' to have the form
+-- `IP sym ty`, return a 'Coercion' `co :: IP sym ty ~ ty`.
+unwrapIP :: Type -> Coercion
+unwrapIP ty =
+  case unwrapNewTyCon_maybe tc of
+    Just (_,_,ax) -> mkUnbranchedAxInstCo Representational ax tys
+    Nothing       -> pprPanic "unwrapIP" $
+                       text "The dictionary for" <+> quotes (ppr tc)
+                         <+> text "is not a newtype!"
+  where
+  (tc, tys) = splitTyConApp ty
+
+-- | Create a 'Coercion' that wraps a value in an implicit-parameter
+-- dictionary. See 'unwrapIP'.
+wrapIP :: Type -> Coercion
+wrapIP ty = mkSymCo (unwrapIP ty)
diff --git a/compiler/typecheck/TcExpr.hs b/compiler/typecheck/TcExpr.hs
index 0adeea47e062564a3df6bff1a6dd30186fcd602c..96ab8a96c1be8987ef23a90f96d52481804ef777 100644
--- a/compiler/typecheck/TcExpr.hs
+++ b/compiler/typecheck/TcExpr.hs
@@ -196,10 +196,8 @@ tcExpr (HsIPVar x) res_ty
        ; tcWrapResult (fromDict ipClass ip_name ip_ty (HsVar ip_var)) ip_ty res_ty }
   where
   -- Coerces a dictionary for `IP "x" t` into `t`.
-  fromDict ipClass x ty =
-    case unwrapNewTyCon_maybe (classTyCon ipClass) of
-      Just (_,_,ax) -> HsWrap $ mkWpCast $ mkTcUnbranchedAxInstCo Representational ax [x,ty]
-      Nothing       -> panic "The dictionary for `IP` is not a newtype?"
+  fromDict ipClass x ty = HsWrap $ mkWpCast $ TcCoercion $
+                          unwrapIP $ mkClassPred ipClass [x,ty]
 
 tcExpr (HsLam match) res_ty
   = do  { (co_fn, match') <- tcMatchLambda match res_ty
diff --git a/compiler/typecheck/TcHsSyn.hs b/compiler/typecheck/TcHsSyn.hs
index 4dfd5e9953fdf71d0ba43d40c6e749cb59f93927..6e742f2442e0887bffa5158030400862e11cfc36 100644
--- a/compiler/typecheck/TcHsSyn.hs
+++ b/compiler/typecheck/TcHsSyn.hs
@@ -1260,6 +1260,14 @@ zonkEvTerm env (EvTypeable ev) =
                    t'  <- zonkTcTypeToType env t
                    return (ev',t')
 
+zonkEvTerm env (EvCallStack cs)
+  = case cs of
+      EvCsEmpty -> return (EvCallStack cs)
+      EvCsTop n l tm -> do { tm' <- zonkEvTerm env tm
+                           ; return (EvCallStack (EvCsTop n l tm')) }
+      EvCsPushCall n l tm -> do { tm' <- zonkEvTerm env tm
+                                ; return (EvCallStack (EvCsPushCall n l tm')) }
+
 zonkEvTerm env (EvSuperClass d n) = do { d' <- zonkEvTerm env d
                                        ; return (EvSuperClass d' n) }
 zonkEvTerm env (EvDFunApp df tys tms)
@@ -1460,7 +1468,7 @@ zonkCoToCo env co
                                    do { (env', tv') <- zonkTyBndrX env tv
                                       ; co' <- zonkCoToCo env' co
                                       ; return (mkForAllCo tv' co') }
-                                   
+
 zonkTvCollecting :: TcRef TyVarSet -> UnboundTyVarZonker
 -- This variant collects unbound type variables in a mutable variable
 -- Works on both types and kinds
diff --git a/compiler/typecheck/TcInteract.hs b/compiler/typecheck/TcInteract.hs
index 62e106c2def8ce6b2bc2bf1d5811cb97e447c252..3adfd793c43a06b2ce350f0e9023ce58400ff5fb 100644
--- a/compiler/typecheck/TcInteract.hs
+++ b/compiler/typecheck/TcInteract.hs
@@ -8,6 +8,8 @@ module TcInteract (
 #include "HsVersions.h"
 
 import BasicTypes ()
+import HsTypes ( hsIPNameFS )
+import FastString
 import TcCanonical
 import TcFlatten
 import VarSet
@@ -20,7 +22,7 @@ import CoAxiom(sfInteractTop, sfInteractInert)
 import Var
 import TcType
 import PrelNames ( knownNatClassName, knownSymbolClassName, ipClassNameKey
-                 , typeableClassName )
+                 , typeableClassName, callStackTyConKey )
 import Id( idType )
 import Class
 import TyCon
@@ -43,7 +45,6 @@ import VarEnv
 import Control.Monad
 import Pair (Pair(..))
 import Unique( hasKey )
-import FastString ( sLit )
 import DynFlags
 import Util
 
@@ -534,6 +535,26 @@ interactIrred _ wi = pprPanic "interactIrred" (ppr wi)
 
 interactDict :: InertCans -> Ct -> TcS (StopOrContinue Ct)
 interactDict inerts workItem@(CDictCan { cc_ev = ev_w, cc_class = cls, cc_tyargs = tys })
+  -- don't ever try to solve CallStack IPs directly from other dicts,
+  -- we always build new dicts instead.
+  -- See Note [Overview of implicit CallStacks]
+  | [_ip, ty] <- tys
+  , isWanted ev_w
+  , Just mkEvCs <- isCallStackIP (ctEvLoc ev_w) cls ty
+  = do let ev_cs =
+             case lookupInertDict inerts (ctEvLoc ev_w) cls tys of
+               Just ev | isGiven ev -> mkEvCs (ctEvTerm ev)
+               _ -> mkEvCs (EvCallStack EvCsEmpty)
+
+       -- now we have ev_cs :: CallStack, but the evidence term should
+       -- be a dictionary, so we have to coerce ev_cs to a
+       -- dictionary for `IP ip CallStack`
+       let ip_ty = mkClassPred cls tys
+       let ev_tm = mkEvCast (EvCallStack ev_cs) (TcCoercion $ wrapIP ip_ty)
+       addSolvedDict ev_w cls tys
+       setEvBind (ctEvId ev_w) ev_tm
+       stopWith ev_w "Wanted CallStack IP"
+
   | Just ctev_i <- lookupInertDict inerts (ctEvLoc ev_w) cls tys
   = do { (inert_effect, stop_now) <- solveOneFromTheOther ctev_i ev_w
        ; case inert_effect of
@@ -2206,3 +2227,23 @@ a TypeRep for them.  For qualified but not polymorphic types, like
     no other class works with impredicative types.
     For now we leave it off, until we have a better story for impredicativity.
 -}
+
+-- | Is the constraint for an implicit CallStack parameter?
+isCallStackIP :: CtLoc -> Class -> Type -> Maybe (EvTerm -> EvCallStack)
+isCallStackIP loc cls ty
+  | Just (tc, []) <- splitTyConApp_maybe ty
+  , cls `hasKey` ipClassNameKey && tc `hasKey` callStackTyConKey
+  = occOrigin (ctLocOrigin loc)
+  where
+  -- We only want to grab constraints that arose due to the use of an IP or a
+  -- function call. See Note [Overview of implicit CallStacks]
+  occOrigin (OccurrenceOf n)
+    = Just (EvCsPushCall n locSpan)
+  occOrigin (IPOccOrigin n)
+    = Just (EvCsTop ('?' `consFS` hsIPNameFS n) locSpan)
+  occOrigin _
+    = Nothing
+  locSpan
+    = ctLocSpan loc
+isCallStackIP _ _ _
+  = Nothing
diff --git a/docs/users_guide/7.10.1-notes.xml b/docs/users_guide/7.10.1-notes.xml
index 43b236615ec10239fc036dd5e40a0868b8cc9ddd..b7c8f4167dabcfeb2ae2994187dcab4ad86be791 100644
--- a/docs/users_guide/7.10.1-notes.xml
+++ b/docs/users_guide/7.10.1-notes.xml
@@ -122,6 +122,32 @@
     <sect3>
         <title>Language</title>
         <itemizedlist>
+            <listitem>
+                <para>
+                    Implicit parameters of the new base type
+                    <literal>GHC.Stack.CallStack</literal> are treated
+                    specially, and automatically solved for the current source
+                    location. For example
+                    <programlisting>
+                      f = print (?stk :: CallStack)
+                    </programlisting>
+                    will print the singleton stack containing the occurrence of
+                    <literal>?stk</literal>. If there is another
+                    <literal>CallStack</literal> implicit in-scope, the new location
+                    will be appended to the existing stack, e.g.
+                    <programlisting>
+                      f :: (?stk :: CallStack) => IO ()
+                      f = print (?stk :: CallStack)
+                    </programlisting>
+                    will print the occurrence of <literal>?stk</literal> and the
+                    call-site of <literal>f</literal>. The name of the implicit
+                    parameter does not matter.
+               </para>
+                <para>
+                    See the release notes for base for a description of the
+                    <literal>CallStack</literal> type.
+               </para>
+           </listitem>
             <listitem>
                 <para>
                     There is a new extension,
@@ -544,6 +570,23 @@ echo "[]" > package.conf
                 <para>
                     Version number 4.8.0.0 (was 4.7.0.0)
                </para>
+           </listitem>
+            <listitem>
+                <para>
+                    A new module <literal>GHC.SrcLoc</literal> was added,
+                    exporting a new type <literal>SrcLoc</literal>. A
+                    <literal>SrcLoc</literal> contains package, module,
+                    and file names, as well as start and end positions.
+               </para>
+           </listitem>
+            <listitem>
+                <para>
+                    A new type <literal>CallStack</literal> was added for use
+                    with the new implicit callstack parameters. A
+                    <literal>CallStack</literal> is a
+                    <literal>[(String, SrcLoc)]</literal>, sorted by most-recent
+                    call.
+               </para>
            </listitem>
             <listitem>
                 <para>
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 9029c7405bb21aec0ed13e9e82d8a978c7c8eb2e..adb152b38fa521f9093c8ddca88a4767398253f2 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -7680,6 +7680,56 @@ inner binding of <literal>?x</literal>, so <literal>(f 9)</literal> will return
 <literal>14</literal>.
 </para>
 </sect3>
+
+<sect3><title>Special implicit parameters</title>
+<para>
+GHC treats implicit parameters of type <literal>GHC.Stack.CallStack</literal>
+specially, by resolving them to the current location in the program. Consider:
+<programlisting>
+  f :: String
+  f = show (?loc :: CallStack)
+</programlisting>
+GHC will automatically resolve <literal>?loc</literal> to its source
+location. If another implicit parameter with type <literal>CallStack</literal> is
+in scope, GHC will append the two locations, creating an explicit call-stack. For example:
+<programlisting>
+  f :: (?stk :: CallStack) => String
+  f = show (?stk :: CallStack)
+</programlisting>
+will produce the location of <literal>?stk</literal>, followed by
+<literal>f</literal>'s call-site. Note that the name of the implicit parameter does not
+matter (we used <literal>?loc</literal> above), GHC will solve any implicit parameter
+with the right type. The name does, however, matter when pushing new locations onto
+existing stacks. Consider:
+<programlisting>
+  f :: (?stk :: CallStack) => String
+  f = show (?loc :: CallStack)
+</programlisting>
+When we call <literal>f</literal>, the stack will include the use of <literal>?loc</literal>,
+but not the call to <literal>f</literal>; in this case the names must match.
+</para>
+<para>
+<literal>CallStack</literal> is kept abstract, but
+GHC provides a function
+<programlisting>
+  getCallStack :: CallStack -> [(String, SrcLoc)]
+</programlisting>
+to access the individual call-sites in the stack. The <literal>String</literal>
+is the name of the function that was called, and the <literal>SrcLoc</literal>
+provides the package, module, and file name, as well as the line and column
+numbers. The stack will never be empty, as the first call-site
+will be the location at which the implicit parameter was used. GHC will also
+never infer <literal>?loc :: CallStack</literal> as a type constraint, which
+means that functions must explicitly ask to be told about their call-sites.
+</para>
+<para>
+A potential "gotcha" when using implicit <literal>CallStack</literal>s is that
+the <literal>:type</literal> command in GHCi will not report the
+<literal>?loc :: CallStack</literal> constraint, as the typechecker will
+immediately solve it. Use <literal>:info</literal> instead to print the
+unsolved type.
+</para>
+</sect3>
 </sect2>
 
 <sect2 id="kinding">
diff --git a/libraries/base/GHC/SrcLoc.hs b/libraries/base/GHC/SrcLoc.hs
new file mode 100644
index 0000000000000000000000000000000000000000..16ebbab74c6e0cc5e2661e6cb186f805ee6a51e6
--- /dev/null
+++ b/libraries/base/GHC/SrcLoc.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE RecordWildCards #-}
+module GHC.SrcLoc
+  ( SrcLoc
+  , srcLocPackage
+  , srcLocModule
+  , srcLocFile
+  , srcLocStartLine
+  , srcLocStartCol
+  , srcLocEndLine
+  , srcLocEndCol
+
+  -- * Pretty printing
+  , showSrcLoc
+  ) where
+
+-- | A single location in the source code.
+data SrcLoc = SrcLoc
+  { srcLocPackage   :: String
+  , srcLocModule    :: String
+  , srcLocFile      :: String
+  , srcLocStartLine :: Int
+  , srcLocStartCol  :: Int
+  , srcLocEndLine   :: Int
+  , srcLocEndCol    :: Int
+  } deriving (Show, Eq)
+
+showSrcLoc :: SrcLoc -> String
+showSrcLoc SrcLoc {..}
+  = concat [ srcLocFile, ":"
+           , show srcLocStartLine, ":"
+           , show srcLocStartCol, " in "
+           , srcLocPackage, ":", srcLocModule
+           ]
diff --git a/libraries/base/GHC/Stack.hsc b/libraries/base/GHC/Stack.hsc
index 0aa4d1768dd28904adab30179e41a00a25a7225c..8c9f0c1f414506b06687bf403f11430103168844 100644
--- a/libraries/base/GHC/Stack.hsc
+++ b/libraries/base/GHC/Stack.hsc
@@ -17,11 +17,17 @@
 
 {-# LANGUAGE UnboxedTuples, MagicHash, NoImplicitPrelude #-}
 module GHC.Stack (
-    -- * Call stack
+    -- * Call stacks
+    -- ** Simulated by the RTS
     currentCallStack,
     whoCreated,
     errorWithStackTrace,
 
+    -- ** Explicitly created via implicit-parameters
+    CallStack,
+    getCallStack,
+    showCallStack,
+
     -- * Internals
     CostCentreStack,
     CostCentre,
@@ -36,6 +42,8 @@ module GHC.Stack (
     renderStack
   ) where
 
+import Data.List ( unlines )
+
 import Foreign
 import Foreign.C
 
@@ -46,6 +54,8 @@ import GHC.Foreign as GHC
 import GHC.IO.Encoding
 import GHC.Exception
 import GHC.List ( concatMap, null, reverse )
+import GHC.Show
+import GHC.SrcLoc
 
 #define PROFILING
 #include "Rts.h"
@@ -128,3 +138,48 @@ errorWithStackTrace x = unsafeDupablePerformIO $ do
    if null stack
       then throwIO (ErrorCall x)
       else throwIO (ErrorCall (x ++ '\n' : renderStack stack))
+
+
+----------------------------------------------------------------------
+-- Explicit call-stacks built via ImplicitParams
+----------------------------------------------------------------------
+
+-- | @CallStack@s are an alternate method of obtaining the call stack at a given
+-- point in the program.
+--
+-- When an implicit-parameter of type @CallStack@ occurs in a program, GHC will
+-- solve it with the current location. If another @CallStack@ implicit-parameter
+-- is in-scope (e.g. as a function argument), the new location will be appended
+-- to the one in-scope, creating an explicit call-stack. For example,
+--
+-- @
+-- myerror :: (?loc :: CallStack) => String -> a
+-- myerror msg = error (msg ++ "\n" ++ showCallStack ?loc)
+-- @
+-- ghci> myerror "die"
+-- *** Exception: die
+-- ?loc, called at MyError.hs:7:51 in main:MyError
+--   myerror, called at <interactive>:2:1 in interactive:Ghci1
+--
+-- @CallStack@s do not interact with the RTS and do not require compilation with
+-- @-prof@. On the other hand, as they are built up explicitly using
+-- implicit-parameters, they will generally not contain as much information as
+-- the simulated call-stacks maintained by the RTS.
+--
+-- The @CallStack@ type is abstract, but it can be converted into a
+-- @[(String, SrcLoc)]@ via 'getCallStack'. The @String@ is the name of function
+-- that was called, the 'SrcLoc' is the call-site. The list is ordered with the
+-- most recently called function at the head.
+--
+-- @since 4.9.0.0
+data CallStack = CallStack { getCallStack :: [(String, SrcLoc)] }
+  -- See Note [Overview of implicit CallStacks]
+  deriving (Show, Eq)
+
+showCallStack :: CallStack -> String
+showCallStack (CallStack (root:rest))
+  = unlines (showCallSite root : map (indent . showCallSite) rest)
+  where
+  indent l = "  " ++ l
+  showCallSite (f, loc) = f ++ ", called at " ++ showSrcLoc loc
+showCallStack _ = error "CallStack cannot be empty!"
diff --git a/libraries/base/base.cabal b/libraries/base/base.cabal
index 9296b3ffa158b9bfef4008ecf5257d05291fc904..fd1c3d8c3f028e7a50b7789ab1e47c897d7bc092 100644
--- a/libraries/base/base.cabal
+++ b/libraries/base/base.cabal
@@ -259,6 +259,7 @@ Library
         GHC.StaticPtr
         GHC.STRef
         GHC.Show
+        GHC.SrcLoc
         GHC.Stable
         GHC.Stack
         GHC.Stats
diff --git a/testsuite/tests/typecheck/should_run/IPLocation.hs b/testsuite/tests/typecheck/should_run/IPLocation.hs
new file mode 100644
index 0000000000000000000000000000000000000000..ffc377b2c9a94d5a6e359da2a313fdfd4531db37
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/IPLocation.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE ImplicitParams, RankNTypes #-}
+{-# OPTIONS_GHC -dcore-lint #-}
+module Main where
+
+import GHC.Stack
+
+f0 = putStrLn $ showCallStack ?loc
+     -- should just show the location of ?loc
+
+f1 :: (?loc :: CallStack) => IO ()
+f1 = putStrLn $ showCallStack ?loc
+     -- should show the location of ?loc *and* f1's call-site
+
+f2 :: (?loc :: CallStack) => IO ()
+f2 = do putStrLn $ showCallStack ?loc
+        putStrLn $ showCallStack ?loc
+     -- each ?loc should refer to a different location, but they should
+     -- share f2's call-site
+
+f3 :: ((?loc :: CallStack) => () -> IO ()) -> IO ()
+f3 x = x ()
+       -- the call-site for the functional argument should be added to the
+       -- stack..
+
+f4 :: (?loc :: CallStack) => ((?loc :: CallStack) => () -> IO ()) -> IO ()
+f4 x = x ()
+       -- as should the call-site for f4 itself
+
+f5 :: (?loc1 :: CallStack) => ((?loc2 :: CallStack) => () -> IO ()) -> IO ()
+f5 x = x ()
+       -- we only push new call-sites onto CallStacks with the name IP name
+
+f6 :: (?loc :: CallStack) => Int -> IO ()
+f6 0 = putStrLn $ showCallStack ?loc
+f6 n = f6 (n-1)
+       -- recursive functions add a SrcLoc for each recursive call
+
+main = do f0
+          f1
+          f2
+          f3 (\ () -> putStrLn $ showCallStack ?loc)
+          f4 (\ () -> putStrLn $ showCallStack ?loc)
+          f5 (\ () -> putStrLn $ showCallStack ?loc3)
+          f6 5
diff --git a/testsuite/tests/typecheck/should_run/IPLocation.stdout b/testsuite/tests/typecheck/should_run/IPLocation.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..6dca7214d6aec8393c38a9238eb857482ca56a0b
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/IPLocation.stdout
@@ -0,0 +1,28 @@
+?loc, called at IPLocation.hs:7:31 in main:Main
+
+?loc, called at IPLocation.hs:11:31 in main:Main
+  f1, called at IPLocation.hs:39:11 in main:Main
+
+?loc, called at IPLocation.hs:15:34 in main:Main
+  f2, called at IPLocation.hs:40:11 in main:Main
+
+?loc, called at IPLocation.hs:16:34 in main:Main
+  f2, called at IPLocation.hs:40:11 in main:Main
+
+?loc, called at IPLocation.hs:41:48 in main:Main
+  x, called at IPLocation.hs:21:8 in main:Main
+
+?loc, called at IPLocation.hs:42:48 in main:Main
+  x, called at IPLocation.hs:26:8 in main:Main
+  f4, called at IPLocation.hs:42:11 in main:Main
+
+?loc3, called at IPLocation.hs:43:48 in main:Main
+
+?loc, called at IPLocation.hs:34:33 in main:Main
+  f6, called at IPLocation.hs:35:8 in main:Main
+  f6, called at IPLocation.hs:35:8 in main:Main
+  f6, called at IPLocation.hs:35:8 in main:Main
+  f6, called at IPLocation.hs:35:8 in main:Main
+  f6, called at IPLocation.hs:35:8 in main:Main
+  f6, called at IPLocation.hs:44:11 in main:Main
+
diff --git a/testsuite/tests/typecheck/should_run/all.T b/testsuite/tests/typecheck/should_run/all.T
index 55b88cf30f71dff5f07d8e6027d0eecc9299f884..9cf7a806d0d0db8a307f13713ffeba7e4d62aae1 100755
--- a/testsuite/tests/typecheck/should_run/all.T
+++ b/testsuite/tests/typecheck/should_run/all.T
@@ -85,6 +85,7 @@ test('church', normal, compile_and_run, [''])
 test('testeq2', normal, compile_and_run, [''])
 test('T1624', normal, compile_and_run, [''])
 test('IPRun', normal, compile_and_run, [''])
+test('IPLocation', normal, compile_and_run, [''])
 
 # Support files for T1735 are in directory T1735_Help/
 test('T1735', normal, multimod_compile_and_run, ['T1735',''])