@@ -699,12 +699,12 @@ JL_CALLABLE(jl_f_setfield)
699
699
return args [2 ];
700
700
}
701
701
702
- static jl_value_t * get_fieldtype (jl_value_t * t , jl_value_t * f )
702
+ static jl_value_t * get_fieldtype (jl_value_t * t , jl_value_t * f , int dothrow )
703
703
{
704
704
if (jl_is_unionall (t )) {
705
705
jl_value_t * u = t ;
706
706
JL_GC_PUSH1 (& u );
707
- u = get_fieldtype (((jl_unionall_t * )t )-> body , f );
707
+ u = get_fieldtype (((jl_unionall_t * )t )-> body , f , dothrow );
708
708
u = jl_type_unionall (((jl_unionall_t * )t )-> var , u );
709
709
JL_GC_POP ();
710
710
return u ;
@@ -713,8 +713,13 @@ static jl_value_t *get_fieldtype(jl_value_t *t, jl_value_t *f)
713
713
jl_value_t * * u ;
714
714
jl_value_t * r ;
715
715
JL_GC_PUSHARGS (u , 2 );
716
- u [0 ] = get_fieldtype (((jl_uniontype_t * )t )-> a , f );
717
- u [1 ] = get_fieldtype (((jl_uniontype_t * )t )-> b , f );
716
+ u [0 ] = get_fieldtype (((jl_uniontype_t * )t )-> a , f , 0 );
717
+ u [1 ] = get_fieldtype (((jl_uniontype_t * )t )-> b , f , 0 );
718
+ if (u [0 ] == jl_bottom_type && u [1 ] == jl_bottom_type && dothrow ) {
719
+ // error if all types in the union might have
720
+ get_fieldtype (((jl_uniontype_t * )t )-> a , f , 1 );
721
+ get_fieldtype (((jl_uniontype_t * )t )-> b , f , 1 );
722
+ }
718
723
r = jl_type_union (u , 2 );
719
724
JL_GC_POP ();
720
725
return r ;
@@ -729,28 +734,38 @@ static jl_value_t *get_fieldtype(jl_value_t *t, jl_value_t *f)
729
734
jl_value_t * nm = jl_tparam0 (st );
730
735
if (jl_is_tuple (nm )) {
731
736
int nf = jl_nfields (nm );
732
- if (field_index < 0 || field_index >= nf )
733
- jl_bounds_error (t , f );
737
+ if (field_index < 0 || field_index >= nf ) {
738
+ if (dothrow )
739
+ jl_bounds_error (t , f );
740
+ else
741
+ return jl_bottom_type ;
742
+ }
734
743
}
735
744
jl_value_t * tt = jl_tparam1 (st );
736
745
while (jl_is_typevar (tt ))
737
746
tt = ((jl_tvar_t * )tt )-> ub ;
738
747
if (tt == (jl_value_t * )jl_any_type )
739
748
return (jl_value_t * )jl_any_type ;
740
- return get_fieldtype (tt , f );
749
+ return get_fieldtype (tt , f , dothrow );
741
750
}
742
751
int nf = jl_field_count (st );
743
752
if (nf > 0 && field_index >= nf - 1 && st -> name == jl_tuple_typename ) {
744
753
jl_value_t * ft = jl_field_type (st , nf - 1 );
745
754
if (jl_is_vararg_type (ft ))
746
755
return jl_unwrap_vararg (ft );
747
756
}
748
- if (field_index < 0 || field_index >= nf )
749
- jl_bounds_error (t , f );
757
+ if (field_index < 0 || field_index >= nf ) {
758
+ if (dothrow )
759
+ jl_bounds_error (t , f );
760
+ else
761
+ return jl_bottom_type ;
762
+ }
750
763
}
751
764
else {
752
765
JL_TYPECHK (fieldtype , symbol , f );
753
- field_index = jl_field_index (st , (jl_sym_t * )f , 1 );
766
+ field_index = jl_field_index (st , (jl_sym_t * )f , dothrow );
767
+ if (field_index == -1 )
768
+ return jl_bottom_type ;
754
769
}
755
770
return jl_field_type (st , field_index );
756
771
}
@@ -765,7 +780,7 @@ JL_CALLABLE(jl_f_fieldtype)
765
780
jl_datatype_t * st = (jl_datatype_t * )args [0 ];
766
781
if (st == jl_module_type )
767
782
jl_error ("cannot assign variables in other modules" );
768
- return get_fieldtype (args [0 ], args [1 ]);
783
+ return get_fieldtype (args [0 ], args [1 ], 1 );
769
784
}
770
785
771
786
JL_CALLABLE (jl_f_nfields )
0 commit comments