Skip to content

Commit

Permalink
Merge pull request #2985 from onflow/sainati/restricted-type-argument…
Browse files Browse the repository at this point in the history
…-parsing

Report bespoke error for restricted types parsed as type arguments
  • Loading branch information
dsainati1 authored Dec 20, 2023
2 parents dc44c50 + 7c9209c commit 26fab85
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 15 deletions.
17 changes: 17 additions & 0 deletions runtime/parser/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,20 @@ func (e *CustomDestructorError) Error() string {
func (e *CustomDestructorError) SecondaryError() string {
return "remove the destructor definition"
}

// RestrictedTypeError

type RestrictedTypeError struct {
ast.Range
}

var _ ParseError = &CustomDestructorError{}
var _ errors.UserError = &CustomDestructorError{}

func (*RestrictedTypeError) isParseError() {}

func (*RestrictedTypeError) IsUserError() {}

func (e *RestrictedTypeError) Error() string {
return "restricted types have been removed; replace with the concrete type or an equivalent intersection type"
}
6 changes: 6 additions & 0 deletions runtime/parser/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,12 @@ func defineLessThanOrTypeArgumentsExpression() {

} else {

// if the error specifically occurred during parsing restricted types,
// this is still an invocation and we should report that error instead
if _, isRestrictedTypeErr := err.(*RestrictedTypeError); isRestrictedTypeErr {
return nil, err, true
}

// The previous attempt to parse an invocation failed,
// replay the buffered tokens.

Expand Down
18 changes: 18 additions & 0 deletions runtime/parser/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4474,6 +4474,24 @@ func TestParseLessThanOrTypeArguments(t *testing.T) {
result,
)
})

t.Run("restricted type argument", func(t *testing.T) {

t.Parallel()

_, errs := testParseExpression("foo<X{T}>")
utils.AssertEqualWithDiff(t,
[]error{
&RestrictedTypeError{
Range: ast.Range{
StartPos: ast.Position{Offset: 6, Line: 1, Column: 6},
EndPos: ast.Position{Offset: 6, Line: 1, Column: 6},
},
},
},
errs,
)
})
}

func TestParseBoolExpression(t *testing.T) {
Expand Down
12 changes: 7 additions & 5 deletions runtime/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ func TestParseBuffering(t *testing.T) {
fun isneg(x: SignedFixedPoint): Bool { /* I kinda forget what this is all about */
return x /* but we probably need to figure it out */
< /* ************/((TODO?{/*))************ *//
< /* ************/((TODO?/*))************ *//
-x /* maybe it says NaNs are not negative? */
}
`
Expand All @@ -515,7 +515,7 @@ func TestParseBuffering(t *testing.T) {
[]error{
&SyntaxError{
Message: "expected token identifier",
Pos: ast.Position{Offset: 399, Line: 9, Column: 95},
Pos: ast.Position{Offset: 398, Line: 9, Column: 94},
},
},
err.(Error).Errors,
Expand All @@ -538,9 +538,11 @@ func TestParseBuffering(t *testing.T) {

utils.AssertEqualWithDiff(t,
[]error{
&SyntaxError{
Message: "expected token identifier",
Pos: ast.Position{Offset: 146, Line: 4, Column: 63},
&RestrictedTypeError{
Range: ast.Range{
StartPos: ast.Position{Offset: 138, Line: 4, Column: 55},
EndPos: ast.Position{Offset: 139, Line: 4, Column: 56},
},
},
},
err.(Error).Errors,
Expand Down
2 changes: 1 addition & 1 deletion runtime/parser/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ func defineIntersectionOrDictionaryType() {
return left, nil, true
}

return nil, p.syntaxError("restricted types have been removed; replace with the concrete type or an equivalent intersection type"), true
return nil, &RestrictedTypeError{Range: p.current.Range}, true
},
)
}
Expand Down
24 changes: 15 additions & 9 deletions runtime/parser/type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,11 @@ func TestParseIntersectionType(t *testing.T) {

utils.AssertEqualWithDiff(t,
[]error{
&SyntaxError{
Message: "restricted types have been removed; replace with the concrete type or an equivalent intersection type",
Pos: ast.Position{Offset: 2, Line: 1, Column: 2},
&RestrictedTypeError{
Range: ast.Range{
StartPos: ast.Position{Offset: 2, Line: 1, Column: 2},
EndPos: ast.Position{Offset: 2, Line: 1, Column: 2},
},
},
},
errs,
Expand All @@ -571,9 +573,11 @@ func TestParseIntersectionType(t *testing.T) {
_, errs := testParseType("T{U}")
utils.AssertEqualWithDiff(t,
[]error{
&SyntaxError{
Message: "restricted types have been removed; replace with the concrete type or an equivalent intersection type",
Pos: ast.Position{Offset: 2, Line: 1, Column: 2},
&RestrictedTypeError{
Range: ast.Range{
StartPos: ast.Position{Offset: 2, Line: 1, Column: 2},
EndPos: ast.Position{Offset: 2, Line: 1, Column: 2},
},
},
},
errs,
Expand All @@ -587,9 +591,11 @@ func TestParseIntersectionType(t *testing.T) {
_, errs := testParseType("T{U , V }")
utils.AssertEqualWithDiff(t,
[]error{
&SyntaxError{
Message: "restricted types have been removed; replace with the concrete type or an equivalent intersection type",
Pos: ast.Position{Offset: 2, Line: 1, Column: 2},
&RestrictedTypeError{
Range: ast.Range{
StartPos: ast.Position{Offset: 2, Line: 1, Column: 2},
EndPos: ast.Position{Offset: 2, Line: 1, Column: 2},
},
},
},
errs,
Expand Down

0 comments on commit 26fab85

Please sign in to comment.