@@ -822,6 +822,22 @@ JL_DLLEXPORT jl_module_t *jl_get_module_of_binding(jl_module_t *m, jl_sym_t *var
822822 return b ? b -> globalref -> mod : m ;
823823}
824824
825+ static NOINLINE void print_backdate_admonition (jl_binding_t * b ) JL_NOTSAFEPOINT
826+ {
827+ jl_safe_printf (
828+ "WARNING: Detected access to binding `%s.%s` in a world prior to its definition world.\n"
829+ " Julia 1.12 has introduced more strict world age semantics for global bindings.\n"
830+ " !!! This code will error in future versions of Julia.\n"
831+ "Hint: Add an appropriate `invokelatest` around the access to this binding.\n"
832+ "To make this warning an error, and hence obtain a stack trace, use `julia --depwarn=error`.\n" ,
833+ jl_symbol_name (b -> globalref -> mod -> name ), jl_symbol_name (b -> globalref -> name ));
834+ }
835+
836+ static inline void check_backdated_binding (jl_binding_t * b , enum jl_partition_kind kind ) JL_NOTSAFEPOINT
837+ {
838+ if (!(jl_atomic_fetch_or_relaxed (& b -> flags , BINDING_FLAG_DID_PRINT_INVOKELATEST_ADMONITION ) & BINDING_FLAG_DID_PRINT_INVOKELATEST_ADMONITION ))
839+ print_backdate_admonition (b );
840+ }
825841
826842JL_DLLEXPORT jl_value_t * jl_get_binding_value (jl_binding_t * b )
827843{
@@ -833,18 +849,20 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_in_world(jl_binding_t *b, size_t w
833849 jl_binding_partition_t * bpart = jl_get_binding_partition (b , world );
834850 jl_walk_binding_inplace (& b , & bpart , world );
835851 enum jl_partition_kind kind = jl_binding_kind (bpart );
836- if (kind == PARTITION_KIND_GUARD ) {
837- // Retry lookup in current world counter for guard partitions (unless in pure callback)
838- if (!jl_current_task -> ptls -> in_pure_callback ) {
852+ if (jl_bkind_is_some_guard ( kind ) ) {
853+ // Retry lookup in current world counter for guard partitions (unless in pure callback or with deprecations disabled )
854+ if (jl_options . depwarn != JL_OPTIONS_DEPWARN_ERROR && !jl_current_task -> ptls -> in_pure_callback ) {
839855 size_t current_world = jl_atomic_load_acquire (& jl_world_counter );
840- if (current_world != world ) {
841- return jl_get_binding_value_in_world (b , current_world );
856+ if (current_world != world ) { {
857+ jl_value_t * futurevalue = jl_get_binding_value_in_world (b , current_world );
858+ if (futurevalue )
859+ check_backdated_binding (b , kind );
860+ return futurevalue ;
861+ }
842862 }
843863 }
844864 return NULL ;
845865 }
846- if (jl_bkind_is_some_guard (kind ))
847- return NULL ;
848866 if (jl_bkind_is_some_constant (kind )) {
849867 return bpart -> restriction ;
850868 }
@@ -865,18 +883,19 @@ static jl_value_t *jl_get_binding_value_depwarn(jl_binding_t *b, size_t world)
865883 jl_walk_binding_inplace (& b , & bpart , world );
866884 }
867885 enum jl_partition_kind kind = jl_binding_kind (bpart );
868- if (kind == PARTITION_KIND_GUARD ) {
869- // Retry lookup in current world counter for guard partitions (unless in pure callback)
870- if (!jl_current_task -> ptls -> in_pure_callback ) {
886+ if (jl_bkind_is_some_guard ( kind ) ) {
887+ // Retry lookup in current world counter for guard partitions (unless in pure callback or with deprecations disabled )
888+ if (jl_options . depwarn != JL_OPTIONS_DEPWARN_ERROR && !jl_current_task -> ptls -> in_pure_callback ) {
871889 size_t current_world = jl_atomic_load_acquire (& jl_world_counter );
872890 if (current_world != world ) {
873- return jl_get_binding_value_depwarn (b , current_world );
891+ jl_value_t * futurevalue = jl_get_binding_value_depwarn (b , current_world );
892+ if (futurevalue )
893+ check_backdated_binding (b , kind );
894+ return futurevalue ;
874895 }
875896 }
876897 return NULL ;
877898 }
878- if (jl_bkind_is_some_guard (kind ))
879- return NULL ;
880899 if (jl_bkind_is_some_constant (kind )) {
881900 return bpart -> restriction ;
882901 }
@@ -890,18 +909,19 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_seqcst(jl_binding_t *b)
890909 jl_binding_partition_t * bpart = jl_get_binding_partition (b , world );
891910 jl_walk_binding_inplace (& b , & bpart , world );
892911 enum jl_partition_kind kind = jl_binding_kind (bpart );
893- if (kind == PARTITION_KIND_GUARD ) {
894- // Retry lookup in current world counter for guard partitions (unless in pure callback)
895- if (!jl_current_task -> ptls -> in_pure_callback ) {
912+ if (jl_bkind_is_some_guard ( kind ) ) {
913+ // Retry lookup in current world counter for guard partitions (unless in pure callback or with deprecations disabled )
914+ if (jl_options . depwarn != JL_OPTIONS_DEPWARN_ERROR && !jl_current_task -> ptls -> in_pure_callback ) {
896915 size_t current_world = jl_atomic_load_acquire (& jl_world_counter );
897916 if (current_world != world ) {
898- return jl_get_binding_value_in_world (b , current_world );
917+ jl_value_t * futurevalue = jl_get_binding_value_in_world (b , current_world );
918+ if (futurevalue )
919+ check_backdated_binding (b , kind );
920+ return futurevalue ;
899921 }
900922 }
901923 return NULL ;
902924 }
903- if (jl_bkind_is_some_guard (kind ))
904- return NULL ;
905925 if (jl_bkind_is_some_constant (kind )) {
906926 return bpart -> restriction ;
907927 }
@@ -1438,31 +1458,7 @@ JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var, int allow_import) // u
14381458 jl_walk_binding_inplace (& b , & bpart , jl_current_task -> world_age );
14391459 }
14401460 enum jl_partition_kind kind = jl_binding_kind (bpart );
1441- if (kind == PARTITION_KIND_GUARD ) {
1442- // Retry lookup in current world counter for guard partitions (unless in pure callback)
1443- if (!jl_current_task -> ptls -> in_pure_callback ) {
1444- size_t current_world = jl_atomic_load_acquire (& jl_world_counter );
1445- if (current_world != jl_current_task -> world_age ) {
1446- jl_binding_partition_t * current_bpart = jl_get_binding_partition (b , current_world );
1447- if (!current_bpart )
1448- return 0 ;
1449- if (!allow_import ) {
1450- if (!current_bpart || jl_bkind_is_some_import (jl_binding_kind (current_bpart )))
1451- return 0 ;
1452- } else {
1453- jl_walk_binding_inplace (& b , & current_bpart , current_world );
1454- }
1455- enum jl_partition_kind current_kind = jl_binding_kind (current_bpart );
1456- if (jl_bkind_is_some_guard (current_kind ))
1457- return 0 ;
1458- if (jl_bkind_is_defined_constant (current_kind )) {
1459- return 1 ;
1460- }
1461- return jl_atomic_load (& b -> value ) != NULL ;
1462- }
1463- }
1464- return 0 ;
1465- }
1461+ // isdefined queries only check in the current world, and do not retry with invokelatest
14661462 if (jl_bkind_is_some_guard (kind ))
14671463 return 0 ;
14681464 if (jl_bkind_is_defined_constant (kind )) {
0 commit comments