Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify the requirement for all interface types to have to occur in intersection types #3090

Merged
4 changes: 2 additions & 2 deletions runtime/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1656,7 +1656,7 @@ func TestRuntimeAuthAccountContracts(t *testing.T) {

transaction {
prepare(acc: &Account) {
let hello = acc.contracts.borrow<&HelloInterface>(name: "Hello")
let hello = acc.contracts.borrow<&{HelloInterface}>(name: "Hello")
assert(hello?.hello() == "Hello!")
}
}
Expand Down Expand Up @@ -1747,7 +1747,7 @@ func TestRuntimeAuthAccountContracts(t *testing.T) {

transaction {
prepare(acc: &Account) {
let hello = acc.contracts.borrow<&HelloInterface>(name: "Hello")
let hello = acc.contracts.borrow<&{HelloInterface}>(name: "Hello")
assert(hello == nil)
}
}
Expand Down
13 changes: 3 additions & 10 deletions runtime/sema/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -5906,16 +5906,9 @@ func (*InterfaceType) TypeAnnotationState() TypeAnnotationState {
}

func (t *InterfaceType) RewriteWithIntersectionTypes() (Type, bool) {
switch t.CompositeKind {
case common.CompositeKindResource, common.CompositeKindStructure:
return &IntersectionType{
Types: []*InterfaceType{t},
}, true

default:
return t, false
}

return &IntersectionType{
Types: []*InterfaceType{t},
}, true
}

func (*InterfaceType) Unify(
Expand Down
7 changes: 3 additions & 4 deletions runtime/tests/checker/access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/onflow/cadence/runtime/ast"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/sema"
. "github.com/onflow/cadence/runtime/tests/utils"
)

func expectSuccess(t *testing.T, err error) {
Expand Down Expand Up @@ -772,7 +771,7 @@ func TestCheckAccessInterfaceFunction(t *testing.T) {
if compositeKind == common.CompositeKindContract {
identifier = "TestImpl"
} else {
interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`let test: %[1]s%[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down Expand Up @@ -990,7 +989,7 @@ func TestCheckAccessInterfaceFieldRead(t *testing.T) {
if compositeKind == common.CompositeKindContract {
identifier = "TestImpl"
} else {
interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`let test: %[1]s%[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down Expand Up @@ -1237,7 +1236,7 @@ func TestCheckAccessInterfaceFieldWrite(t *testing.T) {
identifier = "TestImpl"
} else {

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`let test: %[1]s%[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down
22 changes: 6 additions & 16 deletions runtime/tests/checker/arrays_dictionaries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (

"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/sema"
. "github.com/onflow/cadence/runtime/tests/utils"
)

func TestCheckDictionary(t *testing.T) {
Expand Down Expand Up @@ -1464,24 +1463,18 @@ func TestCheckArraySubtyping(t *testing.T) {

t.Run(kind.Keyword(), func(t *testing.T) {

body := "{}"
if kind == common.CompositeKindEvent {
body = "()"
}

interfaceType := AsInterfaceType("I", kind)
interfaceType := "{I}"

_, err := ParseAndCheck(t,
fmt.Sprintf(
`
%[1]s interface I %[2]s
%[1]s S: I %[2]s
%[1]s interface I {}
%[1]s S: I {}

let xs: %[3]s[S] %[4]s []
let ys: %[3]s[%[5]s] %[4]s xs
let xs: %[2]s[S] %[3]s []
let ys: %[2]s[%[4]s] %[3]s xs
`,
kind.Keyword(),
body,
kind.Annotation(),
kind.TransferOperator(),
interfaceType,
Expand Down Expand Up @@ -1523,22 +1516,19 @@ func TestCheckDictionarySubtyping(t *testing.T) {
body = "()"
}

interfaceType := AsInterfaceType("I", kind)

_, err := ParseAndCheck(t,
fmt.Sprintf(
`
%[1]s interface I %[2]s
%[1]s S: I %[2]s

let xs: %[3]s{String: S} %[4]s {}
let ys: %[3]s{String: %[5]s} %[4]s xs
let ys: %[3]s{String: {I}} %[4]s xs
`,
kind.Keyword(),
body,
kind.Annotation(),
kind.TransferOperator(),
interfaceType,
),
)

Expand Down
2 changes: 1 addition & 1 deletion runtime/tests/checker/attachments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2583,7 +2583,7 @@ func TestCheckAttachmentAnyAttachmentTypes(t *testing.T) {
},
{
setupCode: "contract interface CI {}",
subType: "CI",
subType: "{CI}",
expectedSuccess: false,
},
}
Expand Down
5 changes: 2 additions & 3 deletions runtime/tests/checker/composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/onflow/cadence/runtime/errors"
"github.com/onflow/cadence/runtime/parser"
"github.com/onflow/cadence/runtime/sema"
. "github.com/onflow/cadence/runtime/tests/utils"
)

func TestCheckInvalidCompositeRedeclaringType(t *testing.T) {
Expand Down Expand Up @@ -1963,14 +1962,14 @@ func TestCheckMutualTypeUseTopLevel(t *testing.T) {
firstTypeAnnotation := "A"
if firstIsInterface {
firstInterfaceKeyword = "interface"
firstTypeAnnotation = AsInterfaceType("A", firstKind)
firstTypeAnnotation = "{A}"
}

secondInterfaceKeyword := ""
secondTypeAnnotation := "B"
if secondIsInterface {
secondInterfaceKeyword = "interface"
secondTypeAnnotation = AsInterfaceType("B", secondKind)
secondTypeAnnotation = "{B}"
}

testName := fmt.Sprintf(
Expand Down
20 changes: 10 additions & 10 deletions runtime/tests/checker/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func TestCheckInterfaceUse(t *testing.T) {
body = "()"
}

annotationType := AsInterfaceType("Test", kind)
annotationType := "{Test}"

t.Run(kind.Keyword(), func(t *testing.T) {

Expand Down Expand Up @@ -320,7 +320,7 @@ func TestCheckInterfaceConformanceNoRequirements(t *testing.T) {
body = "()"
}

annotationType := AsInterfaceType("Test", compositeKind)
annotationType := "{Test}"

var useCode string
if compositeKind != common.CompositeKindContract {
Expand Down Expand Up @@ -386,7 +386,7 @@ func TestCheckInvalidInterfaceConformanceIncompatibleCompositeKinds(t *testing.T
secondBody = "()"
}

firstKindInterfaceType := AsInterfaceType("Test", firstKind)
firstKindInterfaceType := "{Test}"

// NOTE: type mismatch is only tested when both kinds are not contracts
// (which can not be passed by value)
Expand Down Expand Up @@ -455,7 +455,7 @@ func TestCheckInvalidInterfaceConformanceUndeclared(t *testing.T) {
continue
}

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

var useCode string
if compositeKind != common.CompositeKindContract {
Expand Down Expand Up @@ -557,7 +557,7 @@ func TestCheckInterfaceFieldUse(t *testing.T) {

t.Run(compositeKind.Keyword(), func(t *testing.T) {

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

_, err := ParseAndCheck(t,
fmt.Sprintf(
Expand Down Expand Up @@ -602,7 +602,7 @@ func TestCheckInvalidInterfaceUndeclaredFieldUse(t *testing.T) {
continue
}

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

t.Run(compositeKind.Keyword(), func(t *testing.T) {

Expand Down Expand Up @@ -648,7 +648,7 @@ func TestCheckInterfaceFunctionUse(t *testing.T) {
if compositeKind != common.CompositeKindContract {
identifier = "test"

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`let test: %[1]s%[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down Expand Up @@ -704,7 +704,7 @@ func TestCheckInvalidInterfaceUndeclaredFunctionUse(t *testing.T) {

t.Run(compositeKind.Keyword(), func(t *testing.T) {

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

_, err := ParseAndCheck(t,
fmt.Sprintf(
Expand Down Expand Up @@ -3697,7 +3697,7 @@ func TestCheckInheritedInterfacesSubtyping(t *testing.T) {

contract S: B {}

fun foo(a: [S]): [A] {
fun foo(a: [S]): [{A}] {
return a // must be covariant
}
`)
Expand All @@ -3716,7 +3716,7 @@ func TestCheckInheritedInterfacesSubtyping(t *testing.T) {

contract S: B {}

fun foo(a: [B]): [A] {
fun foo(a: [{B}]): [{A}] {
return a // must be covariant
}
`)
Expand Down
2 changes: 1 addition & 1 deletion runtime/tests/checker/resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3097,7 +3097,7 @@ func testResourceNesting(

innerTypeAnnotation := "T"
if innerIsInterface {
innerTypeAnnotation = AsInterfaceType("T", innerCompositeKind)
innerTypeAnnotation = "{T}"
}

// Prepare the initializer, if needed.
Expand Down
4 changes: 2 additions & 2 deletions runtime/tests/interpreter/condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ func TestInterpretInterfaceFunctionUseWithPreCondition(t *testing.T) {
if compositeKind == common.CompositeKindContract {
identifier = "TestImpl"
} else {
interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`let test: %[1]s%[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down Expand Up @@ -839,7 +839,7 @@ func TestInterpretInitializerWithInterfacePreCondition(t *testing.T) {
}
`
} else {
interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

testFunction =
fmt.Sprintf(
Expand Down
6 changes: 3 additions & 3 deletions runtime/tests/interpreter/interpreter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3973,7 +3973,7 @@ func TestInterpretInterfaceConformanceNoRequirements(t *testing.T) {
continue
}

interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

t.Run(compositeKind.Keyword(), func(t *testing.T) {

Expand Down Expand Up @@ -4017,7 +4017,7 @@ func TestInterpretInterfaceFieldUse(t *testing.T) {
if compositeKind == common.CompositeKindContract {
identifier = "TestImpl"
} else {
interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`access(all) let test: %[1]s%[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down Expand Up @@ -4097,7 +4097,7 @@ func TestInterpretInterfaceFunctionUse(t *testing.T) {
if compositeKind == common.CompositeKindContract {
identifier = "TestImpl"
} else {
interfaceType := AsInterfaceType("Test", compositeKind)
interfaceType := "{Test}"

setupCode = fmt.Sprintf(
`access(all) let test: %[1]s %[2]s %[3]s %[4]s TestImpl%[5]s`,
Expand Down
10 changes: 0 additions & 10 deletions runtime/tests/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,6 @@ func AssertEqualWithDiff(t *testing.T, expected, actual any) {
s.String(),
)
}

}

func AsInterfaceType(name string, kind common.CompositeKind) string {
switch kind {
case common.CompositeKindResource, common.CompositeKindStructure:
return fmt.Sprintf("{%s}", name)
default:
return name
}
}

func DeploymentTransaction(name string, contract []byte) []byte {
Expand Down
Loading