File tree Expand file tree Collapse file tree 4 files changed +45
-9
lines changed Expand file tree Collapse file tree 4 files changed +45
-9
lines changed Original file line number Diff line number Diff line change @@ -906,28 +906,38 @@ func (v *checker) checkArguments(
906
906
fnInOffset = 1
907
907
}
908
908
909
+ var err * file.Error
909
910
if fn .IsVariadic () {
910
911
if len (arguments ) < fnNumIn - 1 {
911
- return anyType , & file.Error {
912
+ err = & file.Error {
912
913
Location : node .Location (),
913
914
Message : fmt .Sprintf ("not enough arguments to call %v" , name ),
914
915
}
915
916
}
916
917
} else {
917
918
if len (arguments ) > fnNumIn {
918
- return anyType , & file.Error {
919
+ err = & file.Error {
919
920
Location : node .Location (),
920
921
Message : fmt .Sprintf ("too many arguments to call %v" , name ),
921
922
}
922
923
}
923
924
if len (arguments ) < fnNumIn {
924
- return anyType , & file.Error {
925
+ err = & file.Error {
925
926
Location : node .Location (),
926
927
Message : fmt .Sprintf ("not enough arguments to call %v" , name ),
927
928
}
928
929
}
929
930
}
930
931
932
+ if err != nil {
933
+ // If we have an error, we should still visit all arguments to
934
+ // type check them, as a patch can fix the error later.
935
+ for _ , arg := range arguments {
936
+ _ , _ = v .visit (arg )
937
+ }
938
+ return fn .Out (0 ), err
939
+ }
940
+
931
941
for i , arg := range arguments {
932
942
t , _ := v .visit (arg )
933
943
Original file line number Diff line number Diff line change @@ -170,9 +170,9 @@ type mock.Foo has no field bar (1:4)
170
170
| Foo['bar']
171
171
| ...^
172
172
173
- Foo.Method(Not )
173
+ Foo.Method(42 )
174
174
too many arguments to call Method (1:5)
175
- | Foo.Method(Not )
175
+ | Foo.Method(42 )
176
176
| ....^
177
177
178
178
Foo.Bar()
@@ -210,9 +210,9 @@ array elements can only be selected using an integer (got string) (1:12)
210
210
| ArrayOfFoo.Not
211
211
| ...........^
212
212
213
- FuncParam(Not )
213
+ FuncParam(true )
214
214
not enough arguments to call FuncParam (1:1)
215
- | FuncParam(Not )
215
+ | FuncParam(true )
216
216
| ^
217
217
218
218
MapOfFoo['str'].Not
Original file line number Diff line number Diff line change @@ -13,10 +13,12 @@ type WithContext struct {
13
13
14
14
// Visit adds WithContext.Name argument to all functions calls with a context.Context argument.
15
15
func (w WithContext ) Visit (node * ast.Node ) {
16
- switch (* node ).(type ) {
16
+ switch call := (* node ).(type ) {
17
17
case * ast.CallNode :
18
- call := (* node ).(* ast.CallNode )
19
18
fn := call .Callee .Type ()
19
+ if fn == nil {
20
+ return
21
+ }
20
22
if fn .Kind () != reflect .Func {
21
23
return
22
24
}
Original file line number Diff line number Diff line change @@ -104,3 +104,27 @@ func TestWithContext_with_env_method_chain(t *testing.T) {
104
104
require .NoError (t , err )
105
105
require .Equal (t , int64 (42 ), output )
106
106
}
107
+
108
+ func TestWithContext_issue529 (t * testing.T ) {
109
+ env := map [string ]any {
110
+ "ctx" : context .Background (),
111
+ "foo" : func (ctx context.Context , n int ) int {
112
+ if ctx == nil {
113
+ panic ("wanted a context" )
114
+ }
115
+ return n + 1
116
+ },
117
+ }
118
+ options := []expr.Option {
119
+ expr .Env (env ),
120
+ expr .WithContext ("ctx" ),
121
+ }
122
+
123
+ code := "foo(0) | foo()"
124
+ program , err := expr .Compile (code , options ... )
125
+ require .NoError (t , err )
126
+
127
+ out , err := expr .Run (program , env )
128
+ require .NoError (t , err )
129
+ require .Equal (t , 2 , out )
130
+ }
You can’t perform that action at this time.
0 commit comments