@@ -412,6 +412,46 @@ section of the Metaprogramming chapter of the manual for more details and exampl
412
412
"""
413
413
esc (@nospecialize (e)) = Expr (:escape , e)
414
414
415
+ """
416
+ @boundscheck(blk)
417
+
418
+ Annotates the expression `blk` as a bounds checking block, allowing it to be elided by [`@inbounds`](@ref).
419
+
420
+ Note that the function in which `@boundscheck` is written must be inlined into
421
+ its caller with [`@inline`](@ref) in order for `@inbounds` to have effect.
422
+
423
+ ```jldoctest
424
+ julia> @inline function g(A, i)
425
+ @boundscheck checkbounds(A, i)
426
+ return "accessing (\$ A)[\$ i]"
427
+ end
428
+ f1() = return g(1:2, -1)
429
+ f2() = @inbounds return g(1:2, -1)
430
+ f2 (generic function with 1 method)
431
+
432
+ julia> f1()
433
+ ERROR: BoundsError: attempt to access 2-element UnitRange{Int64} at index [-1]
434
+ Stacktrace:
435
+ [1] throw_boundserror(::UnitRange{Int64}, ::Tuple{Int64}) at ./abstractarray.jl:428
436
+ [2] checkbounds at ./abstractarray.jl:392 [inlined]
437
+ [3] g at ./REPL[20]:2 [inlined]
438
+ [4] f1() at ./REPL[20]:5
439
+
440
+ julia> f2()
441
+ "accessing (1:2)[-1]"
442
+ ```
443
+
444
+ !!! warning
445
+
446
+ The `@boundscheck` annotation allows you, as a library writer, to opt-in to
447
+ allowing *other code* to remove your bounds checks with [`@inbounds`](@ref).
448
+ As noted there, the caller must verify—using information they can access—that
449
+ their accesses are valid before using `@inbounds`. For indexing into your
450
+ [`AbstractArray`](@ref) subclasses, for example, this involves checking the
451
+ indices against its [`size`](@ref). Therefore, `@boundscheck` annotations
452
+ should only be added to a [`getindex`](@ref) or [`setindex!`](@ref)
453
+ implementation after you are certain its behavior is correct.
454
+ """
415
455
macro boundscheck (blk)
416
456
return Expr (:if , Expr (:boundscheck ), esc (blk))
417
457
end
438
478
439
479
Using `@inbounds` may return incorrect results/crashes/corruption
440
480
for out-of-bounds indices. The user is responsible for checking it manually.
481
+ Only use `@inbounds` when it is certain from the information locally available
482
+ that all accesses are in bounds.
441
483
"""
442
484
macro inbounds (blk)
443
485
return Expr (:block ,
0 commit comments