diff --git a/runtime/sema/check_interface_declaration.go b/runtime/sema/check_interface_declaration.go index 51d798896b..45934ed77a 100644 --- a/runtime/sema/check_interface_declaration.go +++ b/runtime/sema/check_interface_declaration.go @@ -529,6 +529,7 @@ func (checker *Checker) declareEntitlementMappingType(declaration *ast.Entitleme checker.report(&InvalidNonEntitlementTypeInMapError{ Pos: association.Input.Identifier.Pos, }) + continue } output := checker.convertNominalType(association.Output) @@ -538,6 +539,7 @@ func (checker *Checker) declareEntitlementMappingType(declaration *ast.Entitleme checker.report(&InvalidNonEntitlementTypeInMapError{ Pos: association.Output.Identifier.Pos, }) + continue } entitlementRelations = append( diff --git a/runtime/tests/checker/entitlements_test.go b/runtime/tests/checker/entitlements_test.go index c43a02c0fc..3a997c54d5 100644 --- a/runtime/tests/checker/entitlements_test.go +++ b/runtime/tests/checker/entitlements_test.go @@ -7224,6 +7224,9 @@ func TestCheckEntitlementErrorReporting(t *testing.T) { } func TestCheckEntitlementOptionalChaining(t *testing.T) { + + t.Parallel() + t.Run("optional chain function call", func(t *testing.T) { t.Parallel() _, err := ParseAndCheck(t, ` @@ -7312,3 +7315,57 @@ func TestCheckEntitlementOptionalChaining(t *testing.T) { require.NoError(t, err) }) } + +func TestCheckEntitlementMissingInMap(t *testing.T) { + + t.Parallel() + + t.Run("missing type", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + access(all) entitlement X + access(all) entitlement mapping M { + X -> X + NonExistingEntitlement -> X + } + access(all) struct S { + access(M) var foo: auth(M) &Int + init() { + self.foo = &3 as auth(X) &Int + var selfRef = &self as auth(X) &S + selfRef.foo + } + } + `) + + errors := RequireCheckerErrors(t, err, 2) + require.IsType(t, &sema.NotDeclaredError{}, errors[0]) + require.IsType(t, &sema.InvalidNonEntitlementTypeInMapError{}, errors[1]) + }) + + t.Run("non entitlement type", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheck(t, ` + access(all) entitlement X + access(all) entitlement mapping M { + X -> X + Int -> X + } + access(all) struct S { + access(M) var foo: auth(M) &Int + init() { + self.foo = &3 as auth(X) &Int + var selfRef = &self as auth(X) &S + selfRef.foo + } + } + `) + + errors := RequireCheckerErrors(t, err, 1) + require.IsType(t, &sema.InvalidNonEntitlementTypeInMapError{}, errors[0]) + }) +}