fix calculation of unexported bindings

When a module defines <name-1> and doesn't export it, but when
the module imports <name-2> and re-exports that refers to another
module's definition of <name-1>, then <name-1> wasn't properly
registered as an unexported binding.

Most of the implementation change is just a clean-up of an
unnecessary traversal from before the addition of a `count`
field in each hash table.
This commit is contained in:
Matthew Flatt 2016-01-02 15:08:57 -07:00
parent 190925ee32
commit fdf56dfebf
2 changed files with 24 additions and 18 deletions

View File

@ -1705,4 +1705,20 @@ case of module-leve bindings; it doesn't cover local bindings.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module exports-x*-as-x racket/base
(define x* 5)
(provide (rename-out [x* x])))
(module exports-x**-as-x racket/base
(require 'exports-x*-as-x)
(define x* 5)
(define-syntax-rule (x**) x*)
(provide (rename-out [x x***])
(rename-out [x** x])))
(require 'exports-x**-as-x)
(test 5 'five (x))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -10396,39 +10396,28 @@ static Scheme_Object **compute_indirects(Scheme_Env *genv,
{
int i, count, j, start, end;
Scheme_Bucket **bs, *b;
Scheme_Object **exsns = pt->provide_src_names, **exis;
Scheme_Object **exsns = pt->provide_src_names, **exss = pt->provide_srcs, **exis;
int exicount;
Scheme_Bucket_Table *t;
if (vars) {
start = 0;
end = pt->num_provides; /* check both vars & syntax, in case of rename transformer */
t = genv->toplevel;
} else {
start = pt->num_var_provides;
end = pt->num_provides;
}
if (vars)
t = genv->toplevel;
else
t = genv->syntax;
if (!t)
count = 0;
else {
bs = t->buckets;
for (count = 0, i = t->size; i--; ) {
b = bs[i];
if (b && b->val)
count++;
}
}
count = (t ? t->count : 0);
if (!count) {
*_count = 0;
return NULL;
}
bs = t->buckets;
exis = MALLOC_N(Scheme_Object *, count);
@ -10441,7 +10430,8 @@ static Scheme_Object **compute_indirects(Scheme_Env *genv,
/* If the name is directly provided, no need for indirect... */
for (j = start; j < end; j++) {
if (SAME_OBJ(name, exsns[j]))
if (SAME_OBJ(name, exsns[j])
&& SCHEME_FALSEP(exss[j]))
break;
}