From 9eb0d2eaf7573d363f065ead33914b4a3060f4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 27 Aug 2024 10:55:43 -0700 Subject: [PATCH] add regression tests for nil-coalescing bug --- runtime/tests/checker/resources_test.go | 33 ++++++++++++++++ runtime/tests/interpreter/resources_test.go | 42 +++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/runtime/tests/checker/resources_test.go b/runtime/tests/checker/resources_test.go index 987d3f07b3..bb2ae5d927 100644 --- a/runtime/tests/checker/resources_test.go +++ b/runtime/tests/checker/resources_test.go @@ -10417,3 +10417,36 @@ func TestCheckInvalidOptionalResourceCoalescingRightSideNilLeftSide(t *testing.T assert.IsType(t, &sema.InvalidNilCoalescingRightResourceOperandError{}, errs[0]) } + +func TestInterpretInvalidNilCoalescingResourceDuplication(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + resource R { + + let answer: Int + + init() { + self.answer = 42 + } + } + + fun main(): Int { + let rs <- [<- create R(), nil] + rs[1] <-! (nil ?? rs[0]) + let r1 <- rs.remove(at:0)! + let r2 <- rs.remove(at:0)! + let answer1 = r1.answer + let answer2 = r2.answer + destroy r1 + destroy r2 + destroy rs + return answer1 + answer2 + } + `) + require.Error(t, err) + + errs := RequireCheckerErrors(t, err, 1) + assert.IsType(t, &sema.InvalidNilCoalescingRightResourceOperandError{}, errs[0]) +} diff --git a/runtime/tests/interpreter/resources_test.go b/runtime/tests/interpreter/resources_test.go index aa62f8914b..964855685f 100644 --- a/runtime/tests/interpreter/resources_test.go +++ b/runtime/tests/interpreter/resources_test.go @@ -3543,3 +3543,45 @@ func TestInterpretResourceReferenceInvalidation(t *testing.T) { require.ErrorAs(t, err, &interpreter.InvalidatedResourceReferenceError{}) }) } + +func TestInterpretInvalidNilCoalescingResourceDuplication(t *testing.T) { + + t.Parallel() + + inter, err := parseCheckAndInterpretWithOptions(t, + ` + access(all) resource R { + access(all) let answer: Int + init() { + self.answer = 42 + } + } + + access(all) fun main(): Int { + let rs <- [<- create R(), nil] + rs[1] <-! (nil ?? rs[0]) + let r1 <- rs.remove(at:0)! + let r2 <- rs.remove(at:0)! + let answer1 = r1.answer + let answer2 = r2.answer + destroy r1 + destroy r2 + destroy rs + return answer1 + answer2 + } + `, + ParseCheckAndInterpretOptions{ + HandleCheckerError: func(err error) { + errs := checker.RequireCheckerErrors(t, err, 1) + assert.IsType(t, &sema.InvalidNilCoalescingRightResourceOperandError{}, errs[0]) + }, + }, + ) + require.NoError(t, err) + + _, err = inter.Invoke("main") + require.Error(t, err) + + var destroyedResourceErr interpreter.DestroyedResourceError + require.ErrorAs(t, err, &destroyedResourceErr) +}