-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: error if impure callable is passed to pure parameter (#792)
Closes #730 ### Summary of Changes Show an error if an impure callable is passed to a pure parameter.
- Loading branch information
1 parent
741113e
commit 5536a4a
Showing
6 changed files
with
297 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
packages/safe-ds-lang/tests/resources/generation/statements/assignment/input.sdstest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ges/safe-ds-lang/tests/resources/generation/statements/expression statement/input.sdstest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
...ts/resources/validation/purity/impure callable passed to pure parameter/arguments.sdstest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package tests.validation.purity.impureCallablePassedToPureParameter.arguments | ||
|
||
@Pure | ||
fun pureFunction() | ||
|
||
@Impure([ImpurityReason.Other]) | ||
fun impureFunction() | ||
|
||
annotation MyAnnotation( | ||
f: () -> (), | ||
other: Int = 1, | ||
) | ||
|
||
class MyClass( | ||
f: () -> (), | ||
other: Int = 1, | ||
) | ||
|
||
enum MyEnum { | ||
MyEnumVariant( | ||
f: () -> (), | ||
other: Int = 1, | ||
) | ||
} | ||
|
||
@Impure([ | ||
ImpurityReason.PotentiallyImpureParameterCall("g"), | ||
]) | ||
fun myFunction( | ||
f: () -> (), | ||
g: () -> (), | ||
other: Int = 1, | ||
) | ||
|
||
segment mySegment1( | ||
f: () -> (), | ||
other: Int = 1, | ||
) {} | ||
|
||
segment mySegment2( | ||
myCallableType: ( | ||
f: () -> (), | ||
other: Int, | ||
) -> () | ||
) { | ||
val myBlockLambda = ( | ||
f: () -> (), | ||
other: Int = 1, | ||
) {}; | ||
|
||
val myExpressionLambda = ( | ||
f: () -> (), | ||
other: Int = 1, | ||
) -> 1; | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyAnnotation(»pureFunction«, »pureFunction«); | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyAnnotation(»impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyClass(»pureFunction«, »pureFunction«); | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyClass(»impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyEnum.MyEnumVariant(»pureFunction«, »pureFunction«); | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyEnum.MyEnumVariant(»impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myFunction(»pureFunction«, »pureFunction«, »pureFunction«); | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myFunction(»impureFunction«, »impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
mySegment1(»pureFunction«, »pureFunction«); | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
mySegment1(»impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myCallableType(»pureFunction«, »pureFunction«); | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myCallableType(»impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myBlockLambda(»pureFunction«, »pureFunction«); | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myBlockLambda(»impureFunction«, »impureFunction«); | ||
|
||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myExpressionLambda(»pureFunction«, »pureFunction«); | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
myExpressionLambda(»impureFunction«, »impureFunction«); | ||
} | ||
|
||
// Argument does not have callable type | ||
pipeline myPipeline { | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
MyClass(»1«, »1«); | ||
} |
109 changes: 109 additions & 0 deletions
109
...sources/validation/purity/impure callable passed to pure parameter/default values.sdstest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package tests.validation.purity.impureCallablePassedToPureParameter.defaultValues | ||
|
||
@Pure | ||
fun pureFunction() | ||
|
||
@Impure([ImpurityReason.Other]) | ||
fun impureFunction() | ||
|
||
annotation MyAnnotation( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) | ||
|
||
class MyClass1( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) | ||
|
||
enum MyEnum { | ||
MyEnumVariant( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) | ||
} | ||
|
||
@Pure | ||
fun myFunction1( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) | ||
|
||
@Impure([ | ||
ImpurityReason.PotentiallyImpureParameterCall("f1"), | ||
ImpurityReason.PotentiallyImpureParameterCall("g1"), | ||
]) | ||
fun myFunction2( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f1: () -> () = »pureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
g1: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f2: () -> () = »pureFunction«, | ||
// $TEST$ error "Cannot pass an impure callable to a pure parameter." | ||
g2: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) | ||
|
||
segment mySegment1( | ||
myCallableType: ( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) -> () | ||
) {} | ||
|
||
segment mySegment2( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) {} | ||
|
||
pipeline myPipeline { | ||
( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) {}; | ||
|
||
( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »pureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
g: () -> () = »impureFunction«, | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
other: Int = »impureFunction«, | ||
) -> 1; | ||
} | ||
|
||
// Default value does not have callable type | ||
class MyClass2( | ||
// $TEST$ no error "Cannot pass an impure callable to a pure parameter." | ||
f: () -> () = »1«, | ||
) |