Skip to content

Commit

Permalink
Remove precondition field from TemplateImplements (#11763)
Browse files Browse the repository at this point in the history
* Remove precondition field from TemplateImplements

fixes #11635

changelog_begin
changelog_end

* Update daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala

Co-authored-by: Remy <remy.haemmerle@daml.com>

Co-authored-by: Remy <remy.haemmerle@daml.com>
  • Loading branch information
cocreature and remyhaemmerle-da authored Nov 18, 2021
1 parent 2e789dd commit 3b5f8a7
Show file tree
Hide file tree
Showing 18 changed files with 46 additions and 45 deletions.
1 change: 0 additions & 1 deletion compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,6 @@ data TemplateImplements = TemplateImplements
, tpiMethods :: !(NM.NameMap TemplateImplementsMethod)
, tpiInheritedChoiceNames :: !(S.Set ChoiceName)
-- ^ Set of inherited fixed choice names.
, tpiPrecond :: !Expr
}
deriving (Eq, Data, Generic, NFData, Show)

Expand Down
3 changes: 1 addition & 2 deletions compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Optics.hs
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,10 @@ templateExpr f (Template loc tpl param precond signatories observers agreement c
<*> (NM.traverse . templateImplementsExpr) f implements

templateImplementsExpr :: Traversal' TemplateImplements Expr
templateImplementsExpr f (TemplateImplements iface methods inheritedChoiceNames precond) =
templateImplementsExpr f (TemplateImplements iface methods inheritedChoiceNames) =
TemplateImplements iface
<$> (NM.traverse . templateImplementsMethodExpr) f methods
<*> pure inheritedChoiceNames
<*> f precond

templateImplementsMethodExpr :: Traversal' TemplateImplementsMethod Expr
templateImplementsMethodExpr f (TemplateImplementsMethod name body) =
Expand Down
3 changes: 1 addition & 2 deletions compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Pretty.hs
Original file line number Diff line number Diff line change
Expand Up @@ -635,11 +635,10 @@ pPrintTemplate lvl modName (Template mbLoc tpl param precond signatories observe
implementsDoc = map (pPrintTemplateImplements lvl) (NM.toList implements)

pPrintTemplateImplements :: PrettyLevel -> TemplateImplements -> Doc ann
pPrintTemplateImplements lvl (TemplateImplements name methods inheritedChoices precond)
pPrintTemplateImplements lvl (TemplateImplements name methods inheritedChoices)
| NM.null methods = keyword_ "implements" <-> pPrintPrec lvl 0 name
| otherwise = vcat $
[ keyword_ "implements" <-> pPrintPrec lvl 0 name <-> keyword_ "where"
, nest 2 (keyword_ "ensure" <-> pPrintPrec lvl 0 precond)
, nest 2 (keyword_ "inherits" <-> pPrintPrec lvl 0 (S.toList inheritedChoices))
] ++ map (nest 2 . pPrintTemplateImplementsMethod lvl) (NM.toList methods)

Expand Down
1 change: 0 additions & 1 deletion compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/DecodeV1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ decodeDefTemplateImplements LF1.DefTemplate_Implements{..} = TemplateImplements
<$> mayDecode "defTemplate_ImplementsInterface" defTemplate_ImplementsInterface decodeTypeConName
<*> decodeNM DuplicateMethod decodeDefTemplateImplementsMethod defTemplate_ImplementsMethods
<*> decodeSet DuplicateChoice (decodeNameId ChoiceName) defTemplate_ImplementsInheritedChoiceInternedNames
<*> mayDecode "defTemplate_ImplementsPrecondition" defTemplate_ImplementsPrecond decodeExpr

decodeDefTemplateImplementsMethod :: LF1.DefTemplate_ImplementsMethod -> Decode TemplateImplementsMethod
decodeDefTemplateImplementsMethod LF1.DefTemplate_ImplementsMethod{..} = TemplateImplementsMethod
Expand Down
1 change: 0 additions & 1 deletion compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/EncodeV1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,6 @@ encodeTemplateImplements TemplateImplements{..} = do
defTemplate_ImplementsInterface <- encodeQualTypeConName tpiInterface
defTemplate_ImplementsMethods <- encodeNameMap encodeTemplateImplementsMethod tpiMethods
defTemplate_ImplementsInheritedChoiceInternedNames <- encodeSet (encodeNameId unChoiceName) tpiInheritedChoiceNames
defTemplate_ImplementsPrecond <- encodeExpr tpiPrecond
pure P.DefTemplate_Implements {..}

encodeTemplateImplementsMethod :: TemplateImplementsMethod -> Encode P.DefTemplate_ImplementsMethod
Expand Down
5 changes: 2 additions & 3 deletions compiler/daml-lf-tools/src/DA/Daml/LF/Completer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,5 @@ completeTemplateImplements :: LF.World -> LF.TemplateImplements -> LF.TemplateIm
completeTemplateImplements world tpi@TemplateImplements{..} =
case lookupInterface tpiInterface world of
Left _ -> error ("Could not find interface " <> T.unpack (T.intercalate "." (unTypeConName (qualObject tpiInterface))))
Right DefInterface { intFixedChoices, intPrecondition } ->
tpi { tpiInheritedChoiceNames = S.fromList (NM.names intFixedChoices)
, tpiPrecond = intPrecondition}
Right DefInterface { intFixedChoices } ->
tpi { tpiInheritedChoiceNames = S.fromList (NM.names intFixedChoices) }
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,7 @@ convertImplements env tplTypeCon = NM.fromList <$>
, Just methodName <- [T.stripPrefix "m_" fieldName]
]
let inheritedChoiceNames = S.empty -- This is filled during LF post-processing (in the LF completer).
let precond = ETrue -- This is filled during LF post-processing (in the LF completer).
pure (TemplateImplements con methods inheritedChoiceNames precond)
pure (TemplateImplements con methods inheritedChoiceNames)

convertChoices :: Env -> LF.TypeConName -> TemplateBinds -> ConvertM (NM.NameMap TemplateChoice)
convertChoices env tplTypeCon tbinds =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ template Asset
where
signatory issuer, owner

ensure (amount >= 5 && amount <= 6)
ensure (amount >= 5 && amount <= 8)

implements Token1 where
let getOwner1 = owner
Expand Down Expand Up @@ -95,13 +95,13 @@ main = scenario do
create Asset with
issuer = p
owner = p
amount = 7 -- violates ensure of Asset
amount = 8 -- violates ensure of Asset & Token2

p `submitMustFail` do
create Asset with
issuer = p
owner = p
amount = 8 -- violates ensure of Asset & Token2
amount = 8 -- violates ensure of Token1

p `submit` do
create Asset with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,6 @@ message DefTemplate {
repeated ImplementsMethod methods = 2;
repeated int32 inherited_choice_interned_names = 3;
// ^ inherited fixed choice names as interned strings
Expr precond = 4;
}

// The type constructor for the template, acting as both
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,6 @@ private[archive] class DecodeV1(minor: LV.Minor) {
inheritedChoices = lfImpl.getInheritedChoiceInternedNamesList.asScala
.map(getInternedName(_, "TemplateImplements.inheritedChoices"))
.toSet,
precond = decodeExpr(lfImpl.getPrecond, "TemplateImplements.precond"),
)

private[this] def decodeTemplateImplementsMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ private[lf] final class Compiler(
val identifier = Identifier(pkgId, QualifiedName(module.name, ifaceName))
addDef(compileCreateInterface(identifier))
addDef(compileFetchInterface(identifier))
addDef(compileInterfacePrecond(identifier, iface.param, iface.precond))
iface.fixedChoices.values.foreach(
builder += compileFixedChoice(identifier, iface.param, _)
)
Expand Down Expand Up @@ -1232,6 +1233,15 @@ private[lf] final class Compiler(
}
}

private[this] def compileInterfacePrecond(
iface: Identifier,
param: ExprVarName,
expr: Expr,
) =
topLevelFunction1(t.InterfacePrecondDefRef(iface))((argPos, env) =>
compile(env.bindExprVar(param, argPos), expr)
)

private[this] def compileKey(
tmplId: Identifier,
tmpl: Template,
Expand Down Expand Up @@ -1284,23 +1294,29 @@ private[lf] final class Compiler(
tmplArgPos: Position,
env: Env,
) = {
val precondsArray =
(Iterator(tmpl.precond) ++ (tmpl.implements.iterator.map(impl => impl._2.precond)))
.to(ImmArray)
val preconds = ECons(TBuiltin(BTBool), precondsArray, ENil(TBuiltin(BTBool)))
val env2 = env.bindExprVar(tmpl.param, tmplArgPos)
val implementsPrecondsIterator = tmpl.implements.iterator.map[s.SExpr](impl =>
// This relies on interfaces having the same representation as the underlying template
t.InterfacePrecondDefRef(impl._1)(env2.toSEVar(tmplArgPos))
)
// TODO Clean this up as part of changing how we evaluate these
// https://github.com/digital-asset/daml/issues/11762
val precondsArray: ImmArray[s.SExpr] =
(Iterator(compile(env2, tmpl.precond)) ++ implementsPrecondsIterator ++ Iterator(
s.SEValue.EmptyList
)).to(ImmArray)
val preconds = s.SEApp(s.SEBuiltin(SBConsMany(precondsArray.length - 1)), precondsArray.toArray)
// We check precondition in a separated builtin to prevent
// further evaluation of agreement, signatories, observers and key
// in case of failed precondition.
let(env2, SBCheckPrecond(tmplId)(env2.toSEVar(tmplArgPos), compile(env2, preconds))) {
(_, env) =>
SBUCreate(tmplId, byInterface)(
env.toSEVar(tmplArgPos),
compile(env, tmpl.agreementText),
compile(env, tmpl.signatories),
compile(env, tmpl.observers),
compileKeyWithMaintainers(env, tmpl.key),
)
let(env2, SBCheckPrecond(tmplId)(env2.toSEVar(tmplArgPos), preconds)) { (_, env) =>
SBUCreate(tmplId, byInterface)(
env.toSEVar(tmplArgPos),
compile(env, tmpl.agreementText),
compile(env, tmpl.signatories),
compile(env, tmpl.observers),
compileKeyWithMaintainers(env, tmpl.key),
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ object Profile {
implicit val lookupByKeyDefRef: Allowed[LookupByKeyDefRef] = allowAll
implicit val createAndExerciseLabel: Allowed[CreateAndExerciseLabel] = allowAll
implicit val exceptionMessageDefRef: Allowed[ExceptionMessageDefRef] = allowAll
implicit val interfacePrecondDefRef: Allowed[InterfacePrecondDefRef] = allowAll
implicit val scenarioLabel: Allowed[ScenarioLabel] = allowAll
implicit val exprVarName: Allowed[Ast.ExprVarName] = allowAll

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ object SExpr {
final case class KeyDefRef(ref: DefinitionRef) extends SDefinitionRef
final case class SignatoriesDefRef(ref: DefinitionRef) extends SDefinitionRef
final case class ObserversDefRef(ref: DefinitionRef) extends SDefinitionRef
final case class InterfacePrecondDefRef(ref: DefinitionRef) extends SDefinitionRef

/** ImplementsDefRef(ref=templateId, ifaceId) points to a function that converts a
* template value to an interface value. (This is currently an identity function.)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,36 +848,33 @@ object Ast {
interface: TypeConName,
methods: Map[MethodName, GenTemplateImplementsMethod[E]],
inheritedChoices: Set[ChoiceName],
precond: E,
)

final class GenTemplateImplementsCompanion[E] private[Ast] {
def apply(
interface: TypeConName,
methods: Iterable[(MethodName, GenTemplateImplementsMethod[E])],
inheritedChoices: Iterable[ChoiceName],
precond: E,
): GenTemplateImplements[E] = {
val methodMap = toMapWithoutDuplicate(
methods,
(methodName: MethodName) =>
throw PackageError(s"repeated method implementation $methodName"),
)
new GenTemplateImplements[E](interface, methodMap, inheritedChoices.toSet, precond)
new GenTemplateImplements[E](interface, methodMap, inheritedChoices.toSet)
}

def apply(
interface: TypeConName,
methods: Map[MethodName, GenTemplateImplementsMethod[E]],
inheritedChoices: Set[ChoiceName],
precond: E,
): GenTemplateImplements[E] =
GenTemplateImplements[E](interface, methods, inheritedChoices, precond)
GenTemplateImplements[E](interface, methods, inheritedChoices)

def unapply(
arg: GenTemplateImplements[E]
): Some[(TypeConName, Map[MethodName, GenTemplateImplementsMethod[E]], Set[ChoiceName], E)] =
Some((arg.interface, arg.methods, arg.inheritedChoices, arg.precond))
): Some[(TypeConName, Map[MethodName, GenTemplateImplementsMethod[E]], Set[ChoiceName])] =
Some((arg.interface, arg.methods, arg.inheritedChoices))
}

type TemplateImplements = GenTemplateImplements[Expr]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,11 @@ object Util {

private[this] def toSignature(implements: TemplateImplements): TemplateImplementsSignature =
implements match {
case TemplateImplements(name, methods, inheritedChoices, _) =>
case TemplateImplements(name, methods, inheritedChoices) =>
TemplateImplementsSignature(
name,
methods.transform((_, v) => toSignature(v)),
inheritedChoices,
(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,11 @@ private[daml] class AstRewriter(
interface,
methods,
inheritedChoices,
precond,
) =>
TemplateImplements(
interface,
methods.transform((_, x) => apply(x)),
inheritedChoices,
apply(precond),
)
}
def apply(x: TemplateImplementsMethod): TemplateImplementsMethod =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,8 @@ private[validation] object ExprIterable {
interface @ _,
methods,
inheritedChoices @ _,
precond,
) =>
Iterator(precond) ++ methods.values.iterator.flatMap(iterator(_))
methods.values.iterator.flatMap(iterator(_))
}

private[iterable] def iterator(x: TemplateImplementsMethod): Iterator[Expr] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,8 @@ private[validation] object TypeIterable {

private[validation] def iterator(impl: TemplateImplements): Iterator[Type] =
impl match {
case TemplateImplements(interface, methods, inheritedChoices @ _, precond) =>
case TemplateImplements(interface, methods, inheritedChoices @ _) =>
Iterator(TTyCon(interface)) ++
iterator(precond) ++
methods.values.flatMap(iterator(_))
}

Expand Down

0 comments on commit 3b5f8a7

Please sign in to comment.