X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcPat.lhs;h=4fe704a84abca4f32842bce3370be85f5cac1312;hb=90dc9026b091be5cca5da4c6cbd3713ecc493361;hp=a5d420930dd7adf7d8b1aa4816a2a849b0db18f3;hpb=3bcc65b82524d1b37e81492885a9eab7b48920ca;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcPat.lhs b/compiler/typecheck/TcPat.lhs index a5d4209..4fe704a 100644 --- a/compiler/typecheck/TcPat.lhs +++ b/compiler/typecheck/TcPat.lhs @@ -332,11 +332,26 @@ tc_pat pstate (BangPat pat) pat_ty thing_inside -- -- Nor should a lazy pattern bind any existential type variables -- because they won't be in scope when we do the desugaring +-- +-- Note [Hopping the LIE in lazy patterns] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In a lazy pattern, we must *not* discharge constraints from the RHS +-- from dictionaries bound in the pattern. E.g. +-- f ~(C x) = 3 +-- We can't discharge the Num constraint from dictionaries bound by +-- the pattern C! +-- +-- So we have to make the constraints from thing_inside "hop around" +-- the pattern. Hence the getLLE and extendLIEs later. + tc_pat pstate lpat@(LazyPat pat) pat_ty thing_inside - = do { (pat', pat_tvs, res) <- tc_lpat pat pat_ty pstate $ \ _ -> - thing_inside pstate - -- Ignore refined pstate', - -- revert to pstate + = do { (pat', pat_tvs, (res,lie)) + <- tc_lpat pat pat_ty pstate $ \ _ -> + getLIE (thing_inside pstate) + -- Ignore refined pstate', revert to pstate + ; extendLIEs lie + -- getLIE/extendLIEs: see Note [Hopping the LIE in lazy patterns] + -- Check no existentials ; if (null pat_tvs) then return () else lazyPatErr lpat pat_tvs @@ -540,7 +555,7 @@ tcConPat pstate con_span data_con tycon pat_ty arg_pats thing_inside ; ex_tvs' <- tcInstSkolTyVars skol_info ex_tvs -- Get location from monad, -- not from ex_tvs ; let tenv = zipTopTvSubst (univ_tvs ++ ex_tvs) - (ctxt_res_tys ++ mkTyVarTys ex_tvs') + (ctxt_res_tys ++ mkTyVarTys ex_tvs') eq_spec' = substEqSpec tenv eq_spec theta' = substTheta tenv theta arg_tys' = substTys tenv arg_tys @@ -798,6 +813,19 @@ tcOverloadedLit orig lit@(HsFractional r fr) res_ty = do { expr <- newLitInst orig lit res_ty ; return (HsFractional r expr) } +tcOverloadedLit orig lit@(HsIsString s fr) res_ty + | not (fr `isHsVar` fromStringName) -- c.f. HsIntegral case + = do { str_ty <- tcMetaTy stringTyConName + ; fr' <- tcSyntaxOp orig fr (mkFunTy str_ty res_ty) + ; return (HsIsString s (HsApp (noLoc fr') (nlHsLit (HsString s)))) } + + | Just expr <- shortCutStringLit s res_ty + = return (HsIsString s expr) + + | otherwise + = do { expr <- newLitInst orig lit res_ty + ; return (HsIsString s expr) } + newLitInst :: InstOrigin -> HsOverLit Name -> BoxyRhoType -> TcM (HsExpr TcId) newLitInst orig lit res_ty -- Make a LitInst = do { loc <- getInstLoc orig @@ -904,13 +932,12 @@ sigPatCtxt pats bound_tvs pat_tys body_ty tidy_env sep [ptext SLIT("When checking an existential match that binds"), nest 4 (vcat (zipWith ppr_id show_ids tidy_tys)), ptext SLIT("The pattern(s) have type(s):") <+> vcat (map ppr tidy_pat_tys), - ptext SLIT("The body has type:") <+> ppr tidy_body_ty, - ppr pats + ptext SLIT("The body has type:") <+> ppr tidy_body_ty ]) } where bound_ids = collectPatsBinders pats show_ids = filter is_interesting bound_ids - is_interesting id = any (`elemVarSet` idFreeTyVars id) bound_tvs + is_interesting id = any (`elemVarSet` varTypeTyVars id) bound_tvs ppr_id id ty = ppr id <+> dcolon <+> ppr ty -- Don't zonk the types so we get the separate, un-unified versions