Skip to content

Commit e99ff2b

Browse files
authored
[ fix ] Fix the support for generated function type arguments
2 parents 0a2feb4 + c2fccd7 commit e99ff2b

49 files changed

Lines changed: 965 additions & 44 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Deriving/DepTyCheck/Gen/ForAllNeededTypes/Impl.idr

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ lookupLengthChecked intSig m = lookup intSig m >>= \(extSig, name) => (name,) <$
4545
Yes prf => Just $ Element extSig prf
4646
No _ => Nothing
4747

48+
considerNewType : Elaboration m => ClosuringContext m => TypeInfo -> m ()
49+
considerNewType ty = do
50+
_ : (NamesInfoInTypes, ConsRecs) <- get
51+
when .| not (isTypeKnown ty) .| updateNamesAndConsRecs ty >>= put
52+
4853
DeriveBodyForType => ClosuringContext m => Elaboration m => DerivationClosure m where
4954

5055
needWeightFun ty = when (not !(gets $ contains ty.name)) $ do
@@ -64,7 +69,7 @@ DeriveBodyForType => ClosuringContext m => Elaboration m => DerivationClosure m
6469
startLoop <- get <* put False
6570

6671
-- update names info in types and cons recs if the asked type is not there
67-
_ <- considerNewType sig.targetType
72+
considerNewType sig.targetType
6873

6974
-- get the expression of calling the internal gen, derive if necessary
7075
internalGenCall <- do
@@ -98,12 +103,6 @@ DeriveBodyForType => ClosuringContext m => Elaboration m => DerivationClosure m
98103

99104
where
100105

101-
considerNewType : TypeInfo -> m (NamesInfoInTypes, ConsRecs)
102-
considerNewType ty = do
103-
nc : (NamesInfoInTypes, ConsRecs) <- get
104-
let False = isTypeKnown ty | True => pure nc
105-
updateNamesAndConsRecs sig.targetType >>= \x => put x $> x
106-
107106
deriveOne : (GenSignature, Name) -> m ()
108107
deriveOne (sig, name) = do
109108

src/Deriving/DepTyCheck/Gen/ForOneTypeConRhs/Impl.idr

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,39 +48,40 @@ record TypeApp (0 con : Con) where
4848
argHeadType : TypeInfo
4949
{auto 0 argHeadTypeGood : AllTyArgsNamed argHeadType}
5050
argApps : Vect argHeadType.args.length .| Either (Fin con.args.length) TTImp
51-
determ : Determination con
5251

53-
getTypeApps : Elaboration m => NamesInfoInTypes => (con : Con) -> m $ Vect con.args.length $ TypeApp con
52+
getTypeApps : Elaboration m => NamesInfoInTypes => (con : Con) -> m $ Vect con.args.length (Either (FC, String) $ TypeApp con, Determination con)
5453
getTypeApps con = do
5554
let conArgIdxs = SortedMap.fromList $ mapI con.args $ \idx, arg => (argName' arg, idx)
5655

5756
-- Analyse that we can do subgeneration for each constructor argument
5857
-- Fails using `Elaboration` if the given expression is not an application to a type constructor
59-
let analyseTypeApp : TTImp -> m $ TypeApp con
58+
let analyseTypeApp : TTImp -> m (Either (FC, String) $ TypeApp con, Determination con)
6059
analyseTypeApp expr = do
6160
let (lhs, args) = unAppAny expr
61+
let as = args.asVect <&> \arg => case getExpr arg of
62+
expr@(IVar _ n) => mirror . maybeToEither expr $ lookup n conArgIdxs
63+
expr => Right expr
6264
ty <- case lhs of
6365
IVar _ lhsName => do let Nothing = lookupType lhsName -- TODO to support `lhsName` to be a type parameter of type `Type`
64-
| Just found => pure found
66+
| Just found => pure $ pure found
6567
-- we haven't found, failing, there are at least two reasons
66-
failAt (getFC lhs) $ if isNamespaced lhsName
67-
then "Data type `\{lhsName}` is unavailable at the site of derivation (forgotten import?)"
68-
else "Unsupported applications to a non-concrete type `\{lhsName}` in \{show con.name}"
69-
IPrimVal _ (PrT t) => pure $ typeInfoForPrimType t
70-
IType _ => pure typeInfoForTypeOfTypes
71-
lhs@(IPi {}) => failAt (getFC lhs) "Fields with function types are not supported in constructors, like in \{show con.name}"
72-
lhs => failAt (getFC lhs) "Unsupported type of a constructor's \{show con.name} field: \{show lhs}"
73-
let Yes lengthCorrect = decEq ty.args.length args.length
74-
| No _ => failAt (getFC lhs) "INTERNAL ERROR: wrong count of unapp when analysing type application"
75-
_ <- ensureTyArgsNamed ty
76-
let as = rewrite lengthCorrect in args.asVect <&> \arg => case getExpr arg of
77-
expr@(IVar _ n) => mirror . maybeToEither expr $ lookup n conArgIdxs
78-
expr => Right expr
68+
if isNamespaced lhsName
69+
then failAt (getFC lhs) "Data type `\{lhsName}` is unavailable at the site of derivation (forgotten import?)"
70+
else pure $ Left (getFC lhs, "Unsupported applications to a non-concrete type `\{lhsName}` in \{show con.name}")
71+
IPrimVal _ (PrT t) => pure $ pure $ typeInfoForPrimType t
72+
IType _ => pure $ pure typeInfoForTypeOfTypes
73+
lhs@(IPi {}) => pure $ Left (getFC lhs, "Fields with function types are not supported in constructors, like in \{show con.name}")
74+
lhs => pure $ Left (getFC lhs, "Unsupported type of a constructor's \{show con.name} field: \{show lhs}")
75+
ta <- Prelude.for ty $ \ty : TypeInfo => do
76+
let Yes lengthCorrect = decEq ty.args.length args.length
77+
| No _ => failAt (getFC lhs) "INTERNAL ERROR: wrong count of unapp when analysing type application"
78+
_ <- ensureTyArgsNamed ty
79+
pure $ MkTypeApp ty $ rewrite lengthCorrect in as
7980
let strongDetermination = rights as.asList <&> mapMaybe (lookup' conArgIdxs) . allVarNames
8081
let strongDeterminationWeight = concatMap @{Additive} (max 1 . length) strongDetermination -- we add 1 for constant givens
8182
let stronglyDeterminedBy = fromList $ join strongDetermination
8283
let argsDependsOn = fromList (lefts as.asList) `difference` stronglyDeterminedBy
83-
pure $ MkTypeApp ty as $ MkDetermination stronglyDeterminedBy argsDependsOn $ argsDependsOn.size + strongDeterminationWeight
84+
pure (ta, MkDetermination stronglyDeterminedBy argsDependsOn $ argsDependsOn.size + strongDeterminationWeight)
8485

8586
for con.args.asVect $ analyseTypeApp . type
8687

@@ -229,7 +230,7 @@ export
229230
-------------------------------------------------------------
230231

231232
-- Compute left-to-right need of generation when there are non-trivial types at the left
232-
argsTypeApps <- getTypeApps con
233+
(argsTypeApps, argsDeterms) <- unzip <$> getTypeApps con
233234

234235
-- Decide how constructor arguments would be named during generation
235236
let bindNames = argName' <$> fromList con.args
@@ -252,7 +253,8 @@ export
252253
genForOrder order = map (foldr apply callCons) $ evalStateT givs $ for order $ \genedArg => do
253254

254255
-- Get info for the `genedArg`
255-
let MkTypeApp typeOfGened argsOfTypeOfGened _ = index genedArg $ the (Vect _ $ TypeApp con) argsTypeApps
256+
let Right $ MkTypeApp typeOfGened argsOfTypeOfGened = index genedArg $ the (Vect _ $ Either _ $ TypeApp con) argsTypeApps
257+
| Left (fc, str) => failAt fc str
256258

257259
-- Acquire the set of arguments that are already present
258260
presentArguments <- get
@@ -308,7 +310,7 @@ export
308310
--------------------------------------------
309311
310312
-- Compute determination map without weak determination information
311-
let determ = insertFrom' empty $ mapI (\i, ta => (i, ta.determ)) argsTypeApps
313+
let determ = insertFrom' empty $ withIndex argsDeterms
312314

313315
logPoint Debug "deptycheck.derive.least-effort" [sig, con] "- determ: \{determ}"
314316
logPoint Debug "deptycheck.derive.least-effort" [sig, con] "- givs: \{givs}"
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
1/2: Building RunDerivedGen (RunDerivedGen.idr)
22
2/2: Building DerivedGen (DerivedGen.idr)
3-
Error: While processing right hand side of checkedGen. Error during reflection: Unsupported applications to a non-concrete type `a` in Builtin.Refl
3+
Error: While processing right hand side of checkedGen. Error during reflection: While processing right hand side of $resolved1,<Builtin.Equal>[0, 1, 2, 3]. While processing right hand side of $resolved1,<Builtin.Equal>[0, 1, 2, 3],<<Builtin.Refl>>. Can't find an implementation for DecEq Type.
44

5-
DerivedGen:1
6-
13 | Show (X b1 b2) where
7-
14 | show (MkX b1 b2 _) = "MkX \{show b1} \{show b2} Refl"
8-
15 |
9-
16 | checkedGen : Fuel -> (b1 : Bool) -> (b2 : Bool) -> Gen MaybeEmpty (X b1 b2)
10-
17 | checkedGen = deriveGen
11-
^^^^^^^^^
5+
Deriving.DepTyCheck.Gen.ForOneTypeCon.Impl:1
6+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
1/2: Building RunDerivedGen (RunDerivedGen.idr)
22
2/2: Building DerivedGen (DerivedGen.idr)
3-
Error: While processing right hand side of checkedGen. Error during reflection: Unsupported applications to a non-concrete type `a` in Builtin.Refl
3+
Error: While processing right hand side of checkedGen. Error during reflection: While processing right hand side of $resolved1,<Builtin.Equal>[0, 1, 2, 3]. While processing right hand side of $resolved1,<Builtin.Equal>[0, 1, 2, 3],<<Builtin.Refl>>. Can't find an implementation for DecEq Type.
44

5-
DerivedGen:1
6-
15 | show (X0 b1 b2 _) = "X0 \{show b1} \{show b2} Refl"
7-
16 | show X1 = "X1"
8-
17 |
9-
18 | checkedGen : Fuel -> (b1 : Bool) -> (b2 : Bool) -> Gen MaybeEmpty (X b1 b2)
10-
19 | checkedGen = deriveGen
11-
^^^^^^^^^
5+
Deriving.DepTyCheck.Gen.ForOneTypeCon.Impl:1
6+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module DerivedGen
2+
3+
import Deriving.DepTyCheck.Gen
4+
5+
%default total
6+
7+
%language ElabReflection
8+
9+
data X : Type -> Type where
10+
MkX : Nat -> List a -> X a
11+
12+
%runElab deriveGenPrinter @{MainCoreDerivator @{LeastEffort}} $ Fuel -> (Fuel -> Gen MaybeEmpty (t ** List t)) => Gen MaybeEmpty (t ** X t)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../_common/derive.ipkg

0 commit comments

Comments
 (0)