Skip to content

Commit

Permalink
Merge commit 'refs/pull/2686/head' of https://github.com/onflow/cadence
Browse files Browse the repository at this point in the history
… into supun/stable-cadence
  • Loading branch information
SupunS committed Aug 15, 2023
2 parents 22bddeb + 88806df commit fc15617
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 172 deletions.
2 changes: 1 addition & 1 deletion runtime/ast/entitlement_declaration.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func NewEntitlementMappingDeclaration(
docString string,
declRange Range,
) *EntitlementMappingDeclaration {
common.UseMemory(gauge, common.EntitlementDeclarationMemoryUsage)
common.UseMemory(gauge, common.EntitlementMappingDeclarationMemoryUsage)

return &EntitlementMappingDeclaration{
Access: access,
Expand Down
1 change: 0 additions & 1 deletion runtime/common/memorykind.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ const (
MemoryKindDictionaryStaticType
MemoryKindOptionalStaticType
MemoryKindIntersectionStaticType
MemoryKindUnauthorizedStaticAccess
MemoryKindEntitlementSetStaticAccess
MemoryKindEntitlementMapStaticAccess
MemoryKindReferenceStaticType
Expand Down
323 changes: 161 additions & 162 deletions runtime/common/memorykind_string.go

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5350,18 +5350,20 @@ func (interpreter *Interpreter) checkReferencedResourceNotMovedOrDestroyed(
referencedValue Value,
locationRange LocationRange,
) {
resourceKindedValue, ok := referencedValue.(ReferenceTrackedResourceKindedValue)
if !ok {
return
}

if resourceKindedValue.IsDestroyed() {
// First check if the referencedValue is a resource.
// This is to handle optionals, since optionals does not
// belong to `ReferenceTrackedResourceKindedValue`

resourceKindedValue, ok := referencedValue.(ResourceKindedValue)
if ok && resourceKindedValue.IsDestroyed() {
panic(DestroyedResourceError{
LocationRange: locationRange,
})
}

if resourceKindedValue.IsStaleResource(interpreter) {
referenceTrackedResourceKindedValue, ok := referencedValue.(ReferenceTrackedResourceKindedValue)
if ok && referenceTrackedResourceKindedValue.IsStaleResource(interpreter) {
panic(InvalidatedResourceReferenceError{
LocationRange: locationRange,
})
Expand Down
4 changes: 2 additions & 2 deletions runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9037,7 +9037,7 @@ func TestRuntimeReturnDestroyedOptional(t *testing.T) {
Location: common.ScriptLocation{},
},
)
RequireError(t, err)

require.ErrorAs(t, err, &interpreter.InvalidatedResourceError{})
RequireError(t, err)
require.ErrorAs(t, err, &interpreter.DestroyedResourceError{})
}
10 changes: 10 additions & 0 deletions runtime/sema/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -4951,6 +4951,16 @@ func (t *InterfaceType) initializeMemberResolvers() {
t.memberResolversOnce.Do(func() {
members := MembersMapAsResolvers(t.Members)

// add any inherited members from up the inheritance chain
for _, conformance := range t.EffectiveInterfaceConformances() {
for name, member := range conformance.InterfaceType.GetMembers() { //nolint:maprange
if _, ok := members[name]; !ok {
members[name] = member
}
}

}

t.memberResolvers = withBuiltinMembers(t, members)
})
}
Expand Down
66 changes: 66 additions & 0 deletions runtime/tests/checker/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4095,6 +4095,72 @@ func TestCheckInterfaceTypeDefinitionInheritance(t *testing.T) {

}

func TestInheritedInterfaceMembers(t *testing.T) {
t.Parallel()

t.Run("inherited interface field", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
resource interface A {
let foo: String
}
resource interface B: A {}
resource C: B {
let foo: String
init() {
self.foo = ""
}
}
fun test() {
let c: @{B} <- create C()
c.foo
destroy c
}
`)

require.NoError(t, err)
})

t.Run("inherited interface function", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
resource interface A {
fun foo ()
}
resource interface B: A {}
fun test(c: @{B}) {
c.foo()
destroy c
}
`)

require.NoError(t, err)
})

t.Run("doubly inherited interface function", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
resource interface A {
fun foo ()
}
resource interface B: A {}
resource interface C: B {}
fun test(c: @{C}) {
c.foo()
destroy c
}
`)

require.NoError(t, err)
})
}

func TestCheckInterfaceEventsInheritance(t *testing.T) {

t.Parallel()
Expand Down
34 changes: 34 additions & 0 deletions runtime/tests/interpreter/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,40 @@ func TestInterpretInterfaceDefaultImplementation(t *testing.T) {
array.Get(inter, interpreter.EmptyLocationRange, 1),
)
})

t.Run("inherited interface function", func(t *testing.T) {

t.Parallel()

inter := parseCheckAndInterpret(t, `
struct interface I {
fun test(): Int {
return 3
}
}
struct interface J: I {}
struct S: J {}
fun foo(_ s: {J}): Int {
return s.test()
}
fun main(): Int {
return foo(S())
}
`)

value, err := inter.Invoke("main")
require.NoError(t, err)

assert.Equal(t,
interpreter.NewUnmeteredIntValueFromInt64(3),
value,
)
})
}

func TestInterpretInterfaceDefaultImplementationWhenOverriden(t *testing.T) {
Expand Down

0 comments on commit fc15617

Please sign in to comment.