From ed2b579e3c353d92f11cfe8e7f724cad00a16758 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 May 2012 03:29:42 -0400 Subject: [PATCH] Fail early on a non-pair input to `list-ref'. There's no index that works with non-pairs, and the generic error message in such cases is confusing. Closes PR12740. --- collects/scribblings/reference/pairs.scrbl | 2 +- collects/scribblings/reference/unsafe.scrbl | 2 +- src/racket/src/list.c | 20 ++++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/collects/scribblings/reference/pairs.scrbl b/collects/scribblings/reference/pairs.scrbl index 60529e57bc..d660d3ae2e 100644 --- a/collects/scribblings/reference/pairs.scrbl +++ b/collects/scribblings/reference/pairs.scrbl @@ -206,7 +206,7 @@ Returns the number of elements in @racket[lst]. ]} -@defproc[(list-ref [lst any/c] [pos exact-nonnegative-integer?]) +@defproc[(list-ref [lst pair?] [pos exact-nonnegative-integer?]) any/c]{ Returns the element of @racket[lst] at position @racket[pos], where diff --git a/collects/scribblings/reference/unsafe.scrbl b/collects/scribblings/reference/unsafe.scrbl index 3ea2d5739d..85e0a36d4b 100644 --- a/collects/scribblings/reference/unsafe.scrbl +++ b/collects/scribblings/reference/unsafe.scrbl @@ -192,7 +192,7 @@ Unsafe variants of @racket[car], @racket[cdr], @racket[mcar], @deftogether[( -@defproc[(unsafe-list-ref [lst any/c] [pos (and/c exact-nonnegative-integer? fixnum?)]) any/c] +@defproc[(unsafe-list-ref [lst pair?] [pos (and/c exact-nonnegative-integer? fixnum?)]) any/c] @defproc[(unsafe-list-tail [lst any/c] [pos (and/c exact-nonnegative-integer? fixnum?)]) any/c] )]{ diff --git a/src/racket/src/list.c b/src/racket/src/list.c index 73cceb0249..957b340166 100644 --- a/src/racket/src/list.c +++ b/src/racket/src/list.c @@ -743,7 +743,7 @@ scheme_init_unsafe_list (Scheme_Env *env) | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); scheme_add_global_constant ("unsafe-cdr", p, env); - p = scheme_make_folding_prim(unsafe_list_ref, "unsafe-list-tail", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_list_ref, "unsafe-list-ref", 2, 2, 1); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); scheme_add_global_constant ("unsafe-list-ref", p, env); @@ -1291,20 +1291,24 @@ do_list_ref(char *name, int takecar, int argc, Scheme_Object *argv[]) intptr_t i, k; Scheme_Object *lst, *index, *bnindex; - if (SCHEME_BIGNUMP(argv[1])) { - bnindex = argv[1]; + lst = argv[0]; + index = argv[1]; + + if (!SCHEME_PAIRP(lst) && takecar) { + scheme_wrong_type(name, "pair", 0, argc, argv);; + } + + if (SCHEME_BIGNUMP(index)) { + bnindex = index; k = 0; - } else if (!SCHEME_INTP(argv[1])) { + } else if (!SCHEME_INTP(index)) { scheme_wrong_type(name, "non-negative exact integer", 1, argc, argv); return NULL; } else { bnindex = NULL; - k = SCHEME_INT_VAL(argv[1]); + k = SCHEME_INT_VAL(index); } - lst = argv[0]; - index = argv[1]; - if ((bnindex && !SCHEME_BIGPOS(bnindex)) || (!bnindex && (k < 0))) { scheme_wrong_type(name, "non-negative exact integer", 1, argc, argv);