diff --git a/compiler/deSugar/Coverage.hs b/compiler/deSugar/Coverage.hs index d140829544c3a86da9f62d92c9e0bf89665208f4..d8fefe16601c733ac0c94e932421c88d52205f5a 100644 --- a/compiler/deSugar/Coverage.hs +++ b/compiler/deSugar/Coverage.hs @@ -768,16 +768,18 @@ addTickApplicativeArg addTickApplicativeArg isGuard (op, arg) = liftM2 (,) (addTickSyntaxExpr hpcSrcSpan op) (addTickArg arg) where - addTickArg (ApplicativeArgOne x pat expr isBody) = + addTickArg (ApplicativeArgOne x pat expr isBody fail) = (ApplicativeArgOne x) <$> addTickLPat pat <*> addTickLHsExpr expr <*> pure isBody - addTickArg (ApplicativeArgMany x stmts ret pat) = + <*> addTickSyntaxExpr hpcSrcSpan fail + addTickArg (ApplicativeArgMany x stmts ret pat fail) = (ApplicativeArgMany x) <$> addTickLStmts isGuard stmts <*> (unLoc <$> addTickLHsExpr (cL hpcSrcSpan ret)) <*> addTickLPat pat + <*> addTickSyntaxExpr hpcSrcSpan fail addTickArg (XApplicativeArg _) = panic "addTickApplicativeArg" addTickStmtAndBinders :: Maybe (Bool -> BoxLabel) -> ParStmtBlock GhcTc GhcTc diff --git a/compiler/deSugar/DsExpr.hs b/compiler/deSugar/DsExpr.hs index 89ca815ed53d7b4294152afc962e4113d2f82fe6..2a454fa3448337f19612bd9106d065b913bfc38a 100644 --- a/compiler/deSugar/DsExpr.hs +++ b/compiler/deSugar/DsExpr.hs @@ -37,7 +37,6 @@ import HsSyn import TcType import TcEvidence import TcRnMonad -import TcHsSyn import Type import CoreSyn import CoreUtils @@ -927,25 +926,39 @@ dsDo stmts let (pats, rhss) = unzip (map (do_arg . snd) args) - do_arg (ApplicativeArgOne _ pat expr _) = - (pat, dsLExpr expr) - do_arg (ApplicativeArgMany _ stmts ret pat) = - (pat, dsDo (stmts ++ [noLoc $ mkLastStmt (noLoc ret)])) + do_arg (ApplicativeArgOne _ pat expr _ fail_op) = + ((pat, fail_op), dsLExpr expr) + do_arg (ApplicativeArgMany _ stmts ret pat fail_op) = + ((pat, fail_op), dsDo (stmts ++ [noLoc $ mkLastStmt (noLoc ret)])) do_arg (XApplicativeArg _) = panic "dsDo" - arg_tys = map hsLPatType pats +-- arg_tys = map (hsLPatType . fst) pats +{- + ; dflags <- getDynFlags + + ; liftIO $ printSDoc PageMode dflags stdout (defaultDumpStyle dflags{dumpFlags = insert Opt_D_ppr_debug (dumpFlags dflags)}) + (vcat [text "Desugar ApplicativeStmt" + ,debugPprType body_ty + ,hsep (map debugPprType arg_tys) + ,ppr mb_join + ,text "" + ]) +-} ; rhss' <- sequence rhss - ; let body' = noLoc $ HsDo body_ty DoExpr (noLoc stmts) + ; body' <- dsLExpr $ noLoc $ HsDo body_ty DoExpr (noLoc stmts) - ; let fun = cL noSrcSpan $ HsLam noExt $ - MG { mg_alts = noLoc [mkSimpleMatch LambdaExpr pats - body'] - , mg_ext = MatchGroupTc arg_tys body_ty - , mg_origin = Generated } + ; let match_args (pat, fail_op) (vs,body) + = do { var <- selectSimpleMatchVarL pat + ; match <- matchSinglePatVar var (StmtCtxt DoExpr) pat + body_ty (cantFailMatchResult body) + ; match_code <- handle_failure pat match fail_op + ; return (var:vs, match_code) + } - ; fun' <- dsLExpr fun + ; (vars, body) <- foldrM match_args ([],body') pats + ; let fun' = mkLams vars body ; let mk_ap_call l (op,r) = dsSyntaxExpr op [l,r] ; expr <- foldlM mk_ap_call fun' (zip (map fst args) rhss') ; case mb_join of diff --git a/compiler/hieFile/HieAst.hs b/compiler/hieFile/HieAst.hs index 2ab2acbe3fa6bb355d0a0ea1f59ab92a6df69d2b..2dd3802aa5ab908cdf9a834c1cfc78081f42be24 100644 --- a/compiler/hieFile/HieAst.hs +++ b/compiler/hieFile/HieAst.hs @@ -1039,11 +1039,11 @@ instance ( a ~ GhcPass p , Data (StmtLR a a (Located (HsExpr a))) , Data (HsLocalBinds a) ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where - toHie (RS sc (ApplicativeArgOne _ pat expr _)) = concatM + toHie (RS sc (ApplicativeArgOne _ pat expr _ _)) = concatM [ toHie $ PS Nothing sc NoScope pat , toHie expr ] - toHie (RS sc (ApplicativeArgMany _ stmts _ pat)) = concatM + toHie (RS sc (ApplicativeArgMany _ stmts _ pat _)) = concatM [ toHie $ listScopes NoScope stmts , toHie $ PS Nothing sc NoScope pat ] diff --git a/compiler/hsSyn/HsExpr.hs b/compiler/hsSyn/HsExpr.hs index b86f4a147d78805769dd830cdb89a6e992b63689..3c5e7b2352e2930d912469cb992dc641ee65bc57 100644 --- a/compiler/hsSyn/HsExpr.hs +++ b/compiler/hsSyn/HsExpr.hs @@ -1989,12 +1989,18 @@ data ApplicativeArg idL Bool -- True <=> was a BodyStmt -- False <=> was a BindStmt -- See Note [Applicative BodyStmt] + (SyntaxExpr idL) -- The fail operator + -- The fail operator is noSyntaxExpr + -- if the pattern match can't fail | ApplicativeArgMany -- do { stmts; return vars } (XApplicativeArgMany idL) [ExprLStmt idL] -- stmts (HsExpr idL) -- return (v1,..,vn), or just (v1,..,vn) (LPat idL) -- (v1,...,vn) + (SyntaxExpr idL) -- The fail operator + -- The fail operator is noSyntaxExpr + -- if the pattern match can't fail | XApplicativeArg (XXApplicativeArg idL) type instance XApplicativeArgOne (GhcPass _) = NoExt @@ -2221,14 +2227,14 @@ pprStmt (ApplicativeStmt _ args mb_join) flattenStmt stmt = [ppr stmt] flattenArg :: forall a . (a, ApplicativeArg (GhcPass idL)) -> [SDoc] - flattenArg (_, ApplicativeArgOne _ pat expr isBody) + flattenArg (_, ApplicativeArgOne _ pat expr isBody _) | isBody = -- See Note [Applicative BodyStmt] [ppr (BodyStmt (panic "pprStmt") expr noSyntaxExpr noSyntaxExpr :: ExprStmt (GhcPass idL))] | otherwise = [ppr (BindStmt (panic "pprStmt") pat expr noSyntaxExpr noSyntaxExpr :: ExprStmt (GhcPass idL))] - flattenArg (_, ApplicativeArgMany _ stmts _ _) = + flattenArg (_, ApplicativeArgMany _ stmts _ _ _) = concatMap flattenStmt stmts flattenArg (_, XApplicativeArg _) = panic "flattenArg" @@ -2241,14 +2247,14 @@ pprStmt (ApplicativeStmt _ args mb_join) else text "join" <+> parens ap_expr pp_arg :: (a, ApplicativeArg (GhcPass idL)) -> SDoc - pp_arg (_, ApplicativeArgOne _ pat expr isBody) + pp_arg (_, ApplicativeArgOne _ pat expr isBody _) | isBody = -- See Note [Applicative BodyStmt] ppr (BodyStmt (panic "pprStmt") expr noSyntaxExpr noSyntaxExpr :: ExprStmt (GhcPass idL)) | otherwise = ppr (BindStmt (panic "pprStmt") pat expr noSyntaxExpr noSyntaxExpr :: ExprStmt (GhcPass idL)) - pp_arg (_, ApplicativeArgMany _ stmts return pat) = + pp_arg (_, ApplicativeArgMany _ stmts return pat _) = ppr pat <+> text "<-" <+> ppr (HsDo (panic "pprStmt") DoExpr (noLoc diff --git a/compiler/hsSyn/HsUtils.hs b/compiler/hsSyn/HsUtils.hs index 531ff46ee40a7e88c0bbed3b8141b3c47920fa6f..b1649dfefe8b89e5b1e8811d15792f5b8933be20 100644 --- a/compiler/hsSyn/HsUtils.hs +++ b/compiler/hsSyn/HsUtils.hs @@ -1051,8 +1051,8 @@ collectStmtBinders (TransStmt { trS_stmts = stmts }) = collectLStmtsBinders stmt collectStmtBinders (RecStmt { recS_stmts = ss }) = collectLStmtsBinders ss collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where - collectArgBinders (_, ApplicativeArgOne _ pat _ _) = collectPatBinders pat - collectArgBinders (_, ApplicativeArgMany _ _ _ pat) = collectPatBinders pat + collectArgBinders (_, ApplicativeArgOne _ pat _ _ _) = collectPatBinders pat + collectArgBinders (_, ApplicativeArgMany _ _ _ pat _) = collectPatBinders pat collectArgBinders _ = [] collectStmtBinders XStmtLR{} = panic "collectStmtBinders" @@ -1353,8 +1353,8 @@ lStmtsImplicits = hs_lstmts -> [(SrcSpan, [Name])] hs_stmt (BindStmt _ pat _ _ _) = lPatImplicits pat hs_stmt (ApplicativeStmt _ args _) = concatMap do_arg args - where do_arg (_, ApplicativeArgOne _ pat _ _) = lPatImplicits pat - do_arg (_, ApplicativeArgMany _ stmts _ _) = hs_lstmts stmts + where do_arg (_, ApplicativeArgOne _ pat _ _ _) = lPatImplicits pat + do_arg (_, ApplicativeArgMany _ stmts _ _ _) = hs_lstmts stmts do_arg (_, XApplicativeArg _) = panic "lStmtsImplicits" hs_stmt (LetStmt _ binds) = hs_local_binds (unLoc binds) hs_stmt (BodyStmt {}) = [] diff --git a/compiler/rename/RnExpr.hs b/compiler/rename/RnExpr.hs index dd38feb3672edc7f5b9075532cacf4e242ad9fae..c81453bf35bc0f7f2c9d6743f2f799eec0be2ee8 100644 --- a/compiler/rename/RnExpr.hs +++ b/compiler/rename/RnExpr.hs @@ -1519,6 +1519,16 @@ dsDo {(arg_1 | ... | arg_n); stmts} expr = -- 'pureName' due to @RebindableSyntax@. data MonadNames = MonadNames { return_name, pure_name :: Name } +instance Outputable MonadNames where + ppr (MonadNames {return_name=return_name,pure_name=pure_name}) = + hcat + [text "MonadNames { return_name = " + ,ppr return_name + ,text ", pure_name = " + ,ppr pure_name + ,text "}" + ] + -- | rearrange a list of statements using ApplicativeDoStmt. See -- Note [ApplicativeDo]. rearrangeForApplicativeDo @@ -1661,16 +1671,16 @@ stmtTreeToStmts -- In the spec, but we do it here rather than in the desugarer, -- because we need the typechecker to typecheck the <$> form rather than -- the bind form, which would give rise to a Monad constraint. -stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BindStmt _ pat rhs _ _), _)) +stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BindStmt _ pat rhs _ fail_op), _)) tail _tail_fvs | not (isStrictPattern pat), (False,tail') <- needJoin monad_names tail -- See Note [ApplicativeDo and strict patterns] - = mkApplicativeStmt ctxt [ApplicativeArgOne noExt pat rhs False] False tail' -stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BodyStmt _ rhs _ _),_)) + = mkApplicativeStmt ctxt [ApplicativeArgOne noExt pat rhs False fail_op] False tail' +stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BodyStmt _ rhs _ fail_op),_)) tail _tail_fvs | (False,tail') <- needJoin monad_names tail = mkApplicativeStmt ctxt - [ApplicativeArgOne noExt nlWildPatName rhs True] False tail' + [ApplicativeArgOne noExt nlWildPatName rhs True fail_op] False tail' stmtTreeToStmts _monad_names _ctxt (StmtTreeOne (s,_)) tail _tail_fvs = return (s : tail, emptyNameSet) @@ -1684,14 +1694,29 @@ stmtTreeToStmts monad_names ctxt (StmtTreeBind before after) tail tail_fvs = do stmtTreeToStmts monad_names ctxt (StmtTreeApplicative trees) tail tail_fvs = do pairs <- mapM (stmtTreeArg ctxt tail_fvs) trees let (stmts', fvss) = unzip pairs - let (need_join, tail') = needJoin monad_names tail + let (need_join, tail') = + if any hasStrictPattern trees + then (True, tail) + else needJoin monad_names tail +{- + dflags <- getDynFlags + + liftIO $ printSDoc PageMode dflags stdout (defaultDumpStyle dflags) + (vcat [text "Rn.StmtTreeApplicative" + ,ppr trees + ,ppr tail + ,ppr monad_names + ,text "" + ]) +-} + (stmts, fvs) <- mkApplicativeStmt ctxt stmts' need_join tail' return (stmts, unionNameSets (fvs:fvss)) where - stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BindStmt _ pat exp _ _), _)) - = return (ApplicativeArgOne noExt pat exp False, emptyFVs) - stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BodyStmt _ exp _ _), _)) = - return (ApplicativeArgOne noExt nlWildPatName exp True, emptyFVs) + stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BindStmt _ pat exp _ fail_op), _)) + = return (ApplicativeArgOne noExt pat exp False fail_op, emptyFVs) + stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BodyStmt _ exp _ fail_op), _)) = + return (ApplicativeArgOne noExt nlWildPatName exp True fail_op, emptyFVs) stmtTreeArg ctxt tail_fvs tree = do let stmts = flattenStmtTree tree pvarset = mkNameSet (concatMap (collectStmtBinders.unLoc.fst) stmts) @@ -1707,8 +1732,9 @@ stmtTreeToStmts monad_names ctxt (StmtTreeApplicative trees) tail tail_fvs = do | otherwise -> do (ret,fvs) <- lookupStmtNamePoly ctxt returnMName return (HsApp noExt (noLoc ret) tup, fvs) - return ( ApplicativeArgMany noExt stmts' mb_ret pat - , fvs1 `plusFV` fvs2) + (fail_op, fvs3) <- getMonadFailOp + return ( ApplicativeArgMany noExt stmts' mb_ret pat fail_op + , fvs1 `plusFV` fvs2 `plusFV` fvs3) -- | Divide a sequence of statements into segments, where no segment @@ -1811,6 +1837,13 @@ isStrictPattern lpat = SplicePat{} -> True _otherwise -> panic "isStrictPattern" +hasStrictPattern :: ExprStmtTree -> Bool +hasStrictPattern (StmtTreeOne (L _ (BindStmt _ pat _ _ _), _)) = isStrictPattern pat +hasStrictPattern (StmtTreeOne _) = False +hasStrictPattern (StmtTreeBind a b) = hasStrictPattern a || hasStrictPattern b +hasStrictPattern (StmtTreeApplicative trees) = any hasStrictPattern trees + + isLetStmt :: LStmt a b -> Bool isLetStmt (L _ LetStmt{}) = True isLetStmt _ = False diff --git a/compiler/typecheck/TcHsSyn.hs b/compiler/typecheck/TcHsSyn.hs index 52783e72102474f68183abe8ff2d33bf2a46118f..4acff6a28aa5e6ae7fb8035166f6495e206d7d63 100644 --- a/compiler/typecheck/TcHsSyn.hs +++ b/compiler/typecheck/TcHsSyn.hs @@ -1257,19 +1257,20 @@ zonkStmt env _zBody (ApplicativeStmt body_ty args mb_join) = do { (env1, new_mb_join) <- zonk_join env mb_join ; (env2, new_args) <- zonk_args env1 args ; new_body_ty <- zonkTcTypeToTypeX env2 body_ty - ; return (env2, ApplicativeStmt new_body_ty new_args new_mb_join) } + ; return ( env2 + , ApplicativeStmt new_body_ty new_args new_mb_join) } where zonk_join env Nothing = return (env, Nothing) zonk_join env (Just j) = second Just <$> zonkSyntaxExpr env j - get_pat (_, ApplicativeArgOne _ pat _ _) = pat - get_pat (_, ApplicativeArgMany _ _ _ pat) = pat + get_pat (_, ApplicativeArgOne _ pat _ _ _) = pat + get_pat (_, ApplicativeArgMany _ _ _ pat _) = pat get_pat (_, XApplicativeArg _) = panic "zonkStmt" - replace_pat pat (op, ApplicativeArgOne x _ a isBody) - = (op, ApplicativeArgOne x pat a isBody) - replace_pat pat (op, ApplicativeArgMany x a b _) - = (op, ApplicativeArgMany x a b pat) + replace_pat pat (op, ApplicativeArgOne x _ a isBody fail_op) + = (op, ApplicativeArgOne x pat a isBody fail_op) + replace_pat pat (op, ApplicativeArgMany x a b _ fail_op) + = (op, ApplicativeArgMany x a b pat fail_op) replace_pat _ (_, XApplicativeArg _) = panic "zonkStmt" zonk_args env args @@ -1287,13 +1288,15 @@ zonkStmt env _zBody (ApplicativeStmt body_ty args mb_join) ; return (env2, (new_op, new_arg) : new_args) } zonk_args_rev env [] = return (env, []) - zonk_arg env (ApplicativeArgOne x pat expr isBody) + zonk_arg env (ApplicativeArgOne x pat expr isBody fail_op) = do { new_expr <- zonkLExpr env expr - ; return (ApplicativeArgOne x pat new_expr isBody) } - zonk_arg env (ApplicativeArgMany x stmts ret pat) + ; (_, new_fail) <- zonkSyntaxExpr env fail_op + ; return (ApplicativeArgOne x pat new_expr isBody new_fail) } + zonk_arg env (ApplicativeArgMany x stmts ret pat fail_op) = do { (env1, new_stmts) <- zonkStmts env zonkLExpr stmts ; new_ret <- zonkExpr env1 ret - ; return (ApplicativeArgMany x new_stmts new_ret pat) } + ; (_, new_fail) <- zonkSyntaxExpr env1 fail_op + ; return (ApplicativeArgMany x new_stmts new_ret pat new_fail) } zonk_arg _ (XApplicativeArg _) = panic "zonkStmt.XApplicativeArg" zonkStmt _ _ (XStmtLR _) = panic "zonkStmt" diff --git a/compiler/typecheck/TcMatches.hs b/compiler/typecheck/TcMatches.hs index 6b727ed5aaa36eb7ba4460a26d489d39c0912f24..e749da7eacc62624a58b5999314c2eaf2dc70a74 100644 --- a/compiler/typecheck/TcMatches.hs +++ b/compiler/typecheck/TcMatches.hs @@ -992,7 +992,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside -- Typecheck each ApplicativeArg separately -- See Note [ApplicativeDo and constraints] - ; args' <- mapM goArg (zip3 args pat_tys exp_tys) + ; args' <- mapM (goArg body_ty) (zip3 args pat_tys exp_tys) -- Bring into scope all the things bound by the args, -- and typecheck the thing_inside @@ -1012,35 +1012,39 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside ; ops' <- goOps t_i ops ; return (op' : ops') } - goArg :: (ApplicativeArg GhcRn, Type, Type) + goArg :: Type -> (ApplicativeArg GhcRn, Type, Type) -> TcM (ApplicativeArg GhcTcId) - goArg (ApplicativeArgOne x pat rhs isBody, pat_ty, exp_ty) + goArg body_ty (ApplicativeArgOne x pat rhs isBody fail_op, pat_ty, exp_ty) = setSrcSpan (combineSrcSpans (getLoc pat) (getLoc rhs)) $ addErrCtxt (pprStmtInCtxt ctxt (mkBindStmt pat rhs)) $ do { rhs' <- tcMonoExprNC rhs (mkCheckExpType exp_ty) ; (pat', _) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ return () - ; return (ApplicativeArgOne x pat' rhs' isBody) } + ; fail_op' <- tcMonadFailOp (DoPatOrigin pat) pat' fail_op body_ty - goArg (ApplicativeArgMany x stmts ret pat, pat_ty, exp_ty) - = do { (stmts', (ret',pat')) <- + ; return (ApplicativeArgOne x pat' rhs' isBody fail_op') } + + goArg body_ty (ApplicativeArgMany x stmts ret pat fail_op, pat_ty, exp_ty) + = do { (stmts', (ret',pat', fail_op')) <- tcStmtsAndThen ctxt tcDoStmt stmts (mkCheckExpType exp_ty) $ \res_ty -> do { L _ ret' <- tcMonoExprNC (noLoc ret) res_ty ; (pat', _) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ return () - ; return (ret', pat') + ; monad_ty_var <- newFlexiTyVarTy (liftedTypeKind `mkVisFunTy` liftedTypeKind) + ; let monad_type = mkAppTy monad_ty_var body_ty + ; fail_op' <- tcMonadFailOp (DoPatOrigin pat) pat' fail_op monad_type + ; return (ret', pat', fail_op') } - ; return (ApplicativeArgMany x stmts' ret' pat') } + ; return (ApplicativeArgMany x stmts' ret' pat' fail_op') } - goArg (XApplicativeArg _, _, _) = panic "tcApplicativeStmts" + goArg _ (XApplicativeArg _, _, _) = panic "tcApplicativeStmts" get_arg_bndrs :: ApplicativeArg GhcTcId -> [Id] - get_arg_bndrs (ApplicativeArgOne _ pat _ _) = collectPatBinders pat - get_arg_bndrs (ApplicativeArgMany _ _ _ pat) = collectPatBinders pat - get_arg_bndrs (XApplicativeArg _) = panic "tcApplicativeStmts" - + get_arg_bndrs (ApplicativeArgOne _ pat _ _ _) = collectPatBinders pat + get_arg_bndrs (ApplicativeArgMany _ _ _ pat _) = collectPatBinders pat + get_arg_bndrs (XApplicativeArg _) = panic "tcApplicativeStmts" {- Note [ApplicativeDo and constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/testsuite/tests/ado/T15344.hs b/testsuite/tests/ado/T15344.hs new file mode 100644 index 0000000000000000000000000000000000000000..3956423ef6ea43288fa0dab83b5e68de9ba0ba0b --- /dev/null +++ b/testsuite/tests/ado/T15344.hs @@ -0,0 +1,10 @@ +{-# LANGUAGE ApplicativeDo #-} + +f :: Maybe (Maybe Int) -> Maybe Int -> Maybe Int +f mgs mid = do + _ <- mid + (Just moi) <- mgs + pure (moi + 42) + +main :: IO () +main = print (f (Just Nothing) (Just 2)) diff --git a/testsuite/tests/ado/T15344.stdout b/testsuite/tests/ado/T15344.stdout new file mode 100644 index 0000000000000000000000000000000000000000..4a584e4989262b5560db8504e40e2dcb591c6edf --- /dev/null +++ b/testsuite/tests/ado/T15344.stdout @@ -0,0 +1 @@ +Nothing diff --git a/testsuite/tests/ado/all.T b/testsuite/tests/ado/all.T index 866e414da8d361614e704e7e688e9051c18c6679..574367a6825e869470bd4e72f0396ce6b7adfca9 100644 --- a/testsuite/tests/ado/all.T +++ b/testsuite/tests/ado/all.T @@ -12,3 +12,4 @@ test('T13242', normal, compile, ['']) test('T13242a', normal, compile_fail, ['']) test('T13875', normal, compile_and_run, ['']) test('T14163', normal, compile_and_run, ['']) +test('T15344', normal, compile_and_run, [''])