@@ -208,8 +208,8 @@ func checkSame(at, bt Type, msg string) error {
208
208
return nil
209
209
}
210
210
211
- func assertAssignableTo (xt , dt Type , autoNative bool ) {
212
- err := checkAssignableTo (xt , dt , autoNative )
211
+ func assertAssignableTo (n Node , xt , dt Type , autoNative bool ) {
212
+ err := checkAssignableTo (n , xt , dt , autoNative )
213
213
if err != nil {
214
214
panic (err .Error ())
215
215
}
@@ -282,7 +282,7 @@ func checkValDefineMismatch(n Node) {
282
282
// Assert that xt can be assigned as dt (dest type).
283
283
// If autoNative is true, a broad range of xt can match against
284
284
// a target native dt type, if and only if dt is a native type.
285
- func checkAssignableTo (xt , dt Type , autoNative bool ) error {
285
+ func checkAssignableTo (n Node , xt , dt Type , autoNative bool ) error {
286
286
if debug {
287
287
debug .Printf ("checkAssignableTo, xt: %v dt: %v \n " , xt , dt )
288
288
}
@@ -292,7 +292,20 @@ func checkAssignableTo(xt, dt Type, autoNative bool) error {
292
292
return nil
293
293
}
294
294
if ! maybeNil (dt ) {
295
- panic (fmt .Sprintf ("invalid operation, nil can not be compared to %v" , dt ))
295
+ switch n := n .(type ) {
296
+ case * ValueDecl :
297
+ panic (fmt .Sprintf ("cannot use nil as %v value in variable declaration" , dt ))
298
+ case * AssignStmt :
299
+ panic (fmt .Sprintf ("cannot use nil as %v value in assignment" , dt ))
300
+ case * CompositeLitExpr :
301
+ panic (fmt .Sprintf ("cannot use nil as %v value in array, slice literal or map literal" , dt ))
302
+ case * CallExpr :
303
+ panic (fmt .Sprintf ("cannot use nil as %v value in argument to %v" , dt , n .Func ))
304
+ case * BinaryExpr :
305
+ panic (fmt .Sprintf ("invalid operation: %v (mismatched types %v and untyped nil)" , n , dt ))
306
+ default :
307
+ panic (fmt .Sprintf ("cannot use nil as %v value" , dt ))
308
+ }
296
309
}
297
310
return nil
298
311
} else if dt == nil { // _ = xxx, assign8.gno, 0f31. else cases?
@@ -504,7 +517,7 @@ func checkAssignableTo(xt, dt Type, autoNative bool) error {
504
517
}
505
518
case * PointerType : // case 4 from here on
506
519
if pt , ok := xt .(* PointerType ); ok {
507
- return checkAssignableTo (pt .Elt , cdt .Elt , false )
520
+ return checkAssignableTo (n , pt .Elt , cdt .Elt , false )
508
521
}
509
522
case * ArrayType :
510
523
if at , ok := xt .(* ArrayType ); ok {
@@ -526,7 +539,7 @@ func checkAssignableTo(xt, dt Type, autoNative bool) error {
526
539
case * SliceType :
527
540
if st , ok := xt .(* SliceType ); ok {
528
541
if cdt .Vrd {
529
- return checkAssignableTo (st .Elt , cdt .Elt , false )
542
+ return checkAssignableTo (n , st .Elt , cdt .Elt , false )
530
543
} else {
531
544
err := checkSame (st .Elt , cdt .Elt , "" )
532
545
if err != nil {
@@ -634,7 +647,7 @@ func (x *BinaryExpr) assertShiftExprCompatible1(store Store, last BlockNode, lt,
634
647
if lt == UntypedBigdecType {
635
648
// 1.0 << 1
636
649
if lic && ric {
637
- convertConst (store , last , lcx , UntypedBigintType )
650
+ convertConst (store , last , x , lcx , UntypedBigintType )
638
651
return
639
652
}
640
653
}
@@ -697,11 +710,11 @@ func (x *BinaryExpr) AssertCompatible(lt, rt Type) {
697
710
case EQL , NEQ :
698
711
assertComparable (xt , dt )
699
712
if ! isUntyped (xt ) && ! isUntyped (dt ) {
700
- assertAssignableTo (xt , dt , false )
713
+ assertAssignableTo (x , xt , dt , false )
701
714
}
702
715
case LSS , LEQ , GTR , GEQ :
703
716
if checker , ok := binaryChecker [x .Op ]; ok {
704
- x .checkCompatibility (xt , dt , checker , x .Op .TokenString ())
717
+ x .checkCompatibility (x , xt , dt , checker , x .Op .TokenString ())
705
718
} else {
706
719
panic (fmt .Sprintf ("checker for %s does not exist" , x .Op ))
707
720
}
@@ -710,7 +723,7 @@ func (x *BinaryExpr) AssertCompatible(lt, rt Type) {
710
723
}
711
724
} else {
712
725
if checker , ok := binaryChecker [x .Op ]; ok {
713
- x .checkCompatibility (xt , dt , checker , x .Op .TokenString ())
726
+ x .checkCompatibility (x , xt , dt , checker , x .Op .TokenString ())
714
727
} else {
715
728
panic (fmt .Sprintf ("checker for %s does not exist" , x .Op ))
716
729
}
@@ -738,14 +751,14 @@ func (x *BinaryExpr) AssertCompatible(lt, rt Type) {
738
751
// The function checkOrConvertType will be invoked after this check.
739
752
// NOTE: dt is established based on a specificity check between xt and dt,
740
753
// confirming dt as the appropriate destination type for this context.
741
- func (x * BinaryExpr ) checkCompatibility (xt , dt Type , checker func (t Type ) bool , OpStr string ) {
754
+ func (x * BinaryExpr ) checkCompatibility (n Node , xt , dt Type , checker func (t Type ) bool , OpStr string ) {
742
755
if ! checker (dt ) {
743
756
panic (fmt .Sprintf ("operator %s not defined on: %v" , OpStr , kindString (dt )))
744
757
}
745
758
746
759
// if both typed
747
760
if ! isUntyped (xt ) && ! isUntyped (dt ) {
748
- err := checkAssignableTo (xt , dt , false )
761
+ err := checkAssignableTo (n , xt , dt , false )
749
762
if err != nil {
750
763
panic (fmt .Sprintf ("invalid operation: mismatched types %v and %v" , xt , dt ))
751
764
}
@@ -810,19 +823,19 @@ func (x *RangeStmt) AssertCompatible(store Store, last BlockNode) {
810
823
xt := evalStaticTypeOf (store , last , x .X )
811
824
switch cxt := xt .(type ) {
812
825
case * MapType :
813
- assertAssignableTo (cxt .Key , kt , false )
826
+ assertAssignableTo (x , cxt .Key , kt , false )
814
827
if vt != nil {
815
- assertAssignableTo (cxt .Value , vt , false )
828
+ assertAssignableTo (x , cxt .Value , vt , false )
816
829
}
817
830
case * SliceType :
818
831
assertIndexTypeIsInt (kt )
819
832
if vt != nil {
820
- assertAssignableTo (cxt .Elt , vt , false )
833
+ assertAssignableTo (x , cxt .Elt , vt , false )
821
834
}
822
835
case * ArrayType :
823
836
assertIndexTypeIsInt (kt )
824
837
if vt != nil {
825
- assertAssignableTo (cxt .Elt , vt , false )
838
+ assertAssignableTo (x , cxt .Elt , vt , false )
826
839
}
827
840
case PrimitiveType :
828
841
if cxt .Kind () == StringKind {
@@ -862,7 +875,7 @@ func (x *AssignStmt) AssertCompatible(store Store, last BlockNode) {
862
875
assertValidAssignLhs (store , last , lx )
863
876
if ! isBlankIdentifier (lx ) {
864
877
lxt := evalStaticTypeOf (store , last , lx )
865
- assertAssignableTo (cft .Results [i ].Type , lxt , false )
878
+ assertAssignableTo (x , cft .Results [i ].Type , lxt , false )
866
879
}
867
880
}
868
881
}
@@ -877,7 +890,7 @@ func (x *AssignStmt) AssertCompatible(store Store, last BlockNode) {
877
890
if ! isBlankIdentifier (x .Lhs [0 ]) { // see composite3.gno
878
891
dt := evalStaticTypeOf (store , last , x .Lhs [0 ])
879
892
ift := evalStaticTypeOf (store , last , cx )
880
- assertAssignableTo (ift , dt , false )
893
+ assertAssignableTo (x , ift , dt , false )
881
894
}
882
895
// check second value
883
896
assertValidAssignLhs (store , last , x .Lhs [1 ])
@@ -900,12 +913,12 @@ func (x *AssignStmt) AssertCompatible(store Store, last BlockNode) {
900
913
if _ , ok := cx .X .(* NameExpr ); ok {
901
914
rt := evalStaticTypeOf (store , last , cx .X )
902
915
if mt , ok := rt .(* MapType ); ok {
903
- assertAssignableTo (mt .Value , lt , false )
916
+ assertAssignableTo (x , mt .Value , lt , false )
904
917
}
905
918
} else if _ , ok := cx .X .(* CompositeLitExpr ); ok {
906
919
cpt := evalStaticTypeOf (store , last , cx .X )
907
920
if mt , ok := cpt .(* MapType ); ok {
908
- assertAssignableTo (mt .Value , lt , false )
921
+ assertAssignableTo (x , mt .Value , lt , false )
909
922
} else {
910
923
panic ("should not happen" )
911
924
}
0 commit comments