@@ -18,7 +18,7 @@ forceArgs :: Name -> Type -> Idris ()
18forceArgs n t = do i <- getIState
18forceArgs n t = do i <- getIState
19 let fargs = force i 0 t
19 let fargs = force i 0 t
20 copt <- case lookupCtxt n (idris_optimisation i) of
20 copt <- case lookupCtxt n (idris_optimisation i) of
21− [] -> return $ Optimise False [] []
21+ [] -> return $ Optimise False False [] []
22 (op:_) -> return op
22 (op:_) -> return op
23 let opts = addDef n (copt { forceable = fargs }) (idris_optimisation i)
23 let opts = addDef n (copt { forceable = fargs }) (idris_optimisation i)
24 putIState (i { idris_optimisation = opts })
24 putIState (i { idris_optimisation = opts })
@@ -62,8 +62,22 @@ collapseCons ty cons =
62 let cons' = map (\ (n, t) -> (n, map snd (getArgTys t))) cons
62 let cons' = map (\ (n, t) -> (n, map snd (getArgTys t))) cons
63 allFR <- mapM (forceRec i) cons'
63 allFR <- mapM (forceRec i) cons'
64 if and allFR then detaggable (map getRetTy (map snd cons))
64 if and allFR then detaggable (map getRetTy (map snd cons))
65− else return () -- not collapsible as not detaggable
65+ else checkNewType cons'
67+ -- one constructor; if one remaining argument, treat as newtype
68+ checkNewType [(n, ts)] = do
70+ case lookupCtxt n (idris_optimisation i) of
71+ (oi:_) -> do let remaining = length ts - length (forceable oi)
72+ if remaining == 1 then
73+ do let oi' = oi { isnewtype = True }
74+ let opts = addDef n oi' (idris_optimisation i)
75+ putIState (i { idris_optimisation = opts })
79+ checkNewType _ = return ()
67 setCollapsible :: Name -> Idris ()
81 setCollapsible :: Name -> Idris ()
68 setCollapsible n
82 setCollapsible n
69 = do i <- getIState
83 = do i <- getIState
@@ -72,7 +86,7 @@ collapseCons ty cons =
72 (oi:_) -> do let oi' = oi { collapsible = True }
86 (oi:_) -> do let oi' = oi { collapsible = True }
73 let opts = addDef n oi' (idris_optimisation i)
87 let opts = addDef n oi' (idris_optimisation i)
74 putIState (i { idris_optimisation = opts })
88 putIState (i { idris_optimisation = opts })
75− [] -> do let oi = Optimise True [] []
89+ [] -> do let oi = Optimise True False [] []
76 let opts = addDef n oi (idris_optimisation i)
90 let opts = addDef n oi (idris_optimisation i)
77 putIState (i { idris_optimisation = opts })
91 putIState (i { idris_optimisation = opts })
78 addIBC (IBCOpt n)
92 addIBC (IBCOpt n)
@@ -256,7 +270,13 @@ applyDataOptRT oi n tag arity args
256 doOpts n args _ forced
270 doOpts n args _ forced
257 = let args' = filter keep (zip (map (\x -> x `elem` forced) [0..])
271 = let args' = filter keep (zip (map (\x -> x `elem` forced) [0..])
276+ _ -> error "Can't happen (not isnewtype)"
259− mkApp (P (DCon tag (arity - length forced)) n Erased) (map snd args')
278+ mkApp (P (DCon tag (arity - length forced)) n Erased)
261 keep (forced, _) = not forced
281 keep (forced, _) = not forced