Skip to content

Commit

Permalink
Clarify error messages when passing owned asset references to shared …
Browse files Browse the repository at this point in the history
…inputs.
  • Loading branch information
mcoblenz committed Sep 1, 2019
1 parent 31bc252 commit 7f083d5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
9 changes: 7 additions & 2 deletions src/main/scala/edu/cmu/cs/obsidian/typecheck/Checker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ class Checker(globalTable: SymbolTable, verbose: Boolean = false) {
if (passedType.isOwned && initialType.permission == Shared() && !finalType.isOwned &&
passedType.isAssetReference(context.contractTable) != No()) {
// Special case: passing an owned reference to a Shared >> Unowned arg will make the arg Unowned but also lose ownership!
logError(arg, UnusedExpressionArgumentOwnershipError(arg))
logError(arg, LostOwnershipErrorDueToSharing(arg))
}

if (context.get(referenceIdentifier).isDefined) {
Expand Down Expand Up @@ -1288,7 +1288,12 @@ class Checker(globalTable: SymbolTable, verbose: Boolean = false) {
if (argType.isOwned && argType.isAssetReference(context.contractTable) != No() &&
(declaredFinalType.isOwned || !declaredInitialType.isOwned))
{
logError(arg, UnusedExpressionArgumentOwnershipError(arg))
if (declaredInitialType.permission == Shared()) {
logError(arg, LostOwnershipErrorDueToSharing(arg))
}
else {
logError(arg, UnusedExpressionArgumentOwnershipError(arg))
}
}
None
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/edu/cmu/cs/obsidian/typecheck/Error.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ case class UnusedExpressionArgumentOwnershipError(e: Expression) extends Error {
val msg: String = s"Expression '$e' holds ownership, but is passed as an argument to a transaction that did not consume ownership."
}

case class LostOwnershipErrorDueToSharing(e: Expression) extends Error {
val msg: String = s"Expression '$e' holds ownership, but is passed as an argument to a transaction that causes it to become Shared, losing ownership."
}

case class PotentiallyUnusedOwnershipError(name: String) extends Error {
val msg: String = s"Variable '$name' holds ownership, but may be unused at the end of its scope."
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ class TypeCheckerTests extends JUnitSuite {
ContractReferenceType(ContractType("PermissionPassing", Nil), Unowned(), false),
ContractReferenceType(ContractType("PermissionPassing", Nil), Owned(), false)), 47) ::
(UnusedExpressionArgumentOwnershipError(LocalInvocation("returnOwnedAsset", Nil, Nil, Nil)), 58) ::
(UnusedExpressionArgumentOwnershipError(LocalInvocation("returnOwnedAsset", Nil, Nil, Nil)), 65) ::
(LostOwnershipErrorDueToSharing(LocalInvocation("returnOwnedAsset", Nil, Nil, Nil)), 65) ::
Nil)
}

Expand All @@ -898,8 +898,8 @@ class TypeCheckerTests extends JUnitSuite {
ContractReferenceType(ContractType("AllPermissions", Nil), Owned(), false), false), 25) ::
(SubtypingError(ContractReferenceType(ContractType("AllPermissions", Nil), Unowned(), false),
ContractReferenceType(ContractType("AllPermissions", Nil), Shared(), false), false), 29) ::
(UnusedExpressionArgumentOwnershipError(ReferenceIdentifier("x2")), 41) ::
(UnusedExpressionArgumentOwnershipError(ReferenceIdentifier("x7")), 63) ::
(LostOwnershipErrorDueToSharing(ReferenceIdentifier("x2")), 41) ::
(LostOwnershipErrorDueToSharing(ReferenceIdentifier("x7")), 63) ::
(ReceiverTypeIncompatibleError("t1",
ContractReferenceType(ContractType("AllPermissions", Nil), Shared(), false),
ContractReferenceType(ContractType("AllPermissions", Nil), Owned(), false)), 81) ::
Expand Down

0 comments on commit 7f083d5

Please sign in to comment.