Skip to content

Commit

Permalink
Fix static show for Base.Colon (JuliaLang#44726)
Browse files Browse the repository at this point in the history
As noted in 44635, we current static show `Base.Colon()` as
`Base.Any`, which is very confusing. Try to improve the situation
by only using the special function printing if the binding actually
matches the value we're trying to print.
  • Loading branch information
Keno authored Mar 30, 2022
1 parent 7c2edc5 commit 54be1ce
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
34 changes: 19 additions & 15 deletions src/rtutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,21 +628,27 @@ JL_DLLEXPORT jl_value_t *jl_argument_datatype(jl_value_t *argt JL_PROPAGATES_ROO
return (jl_value_t*)dt;
}

static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname_out)
static int is_globname_binding(jl_value_t *v, jl_datatype_t *dv)
{
jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL;
*globname_out = globname;
int globfunc = 0;
if (globname && !strchr(jl_symbol_name(globname), '#') &&
!strchr(jl_symbol_name(globname), '@') && dv->name->module &&
jl_binding_resolved_p(dv->name->module, globname)) {
if (globname && dv->name->module && jl_binding_resolved_p(dv->name->module, globname)) {
jl_binding_t *b = jl_get_module_binding(dv->name->module, globname);
// The `||` makes this function work for both function instances and function types.
if (b && b->value && (b->value == v || jl_typeof(b->value) == v)) {
globfunc = 1;
return 1;
}
}
return globfunc;
return 0;
}

static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname_out)
{
jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL;
*globname_out = globname;
if (globname && !strchr(jl_symbol_name(globname), '#') && !strchr(jl_symbol_name(globname), '@')) {
return 1;
}
return 0;
}

static size_t jl_static_show_x_sym_escaped(JL_STREAM *out, jl_sym_t *name) JL_NOTSAFEPOINT
Expand Down Expand Up @@ -773,7 +779,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
// `Base.Set{Int}`, and function types are printed as e.g. `typeof(Main.f)`
jl_datatype_t *dv = (jl_datatype_t*)v;
jl_sym_t *globname;
int globfunc = is_globfunction(v, dv, &globname);
int globfunc = is_globname_binding(v, dv) && is_globfunction(v, dv, &globname);
jl_sym_t *sym = globfunc ? globname : dv->name->name;
char *sn = jl_symbol_name(sym);
size_t quote = 0;
Expand Down Expand Up @@ -1065,20 +1071,18 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
n += jl_static_show_x(out, *(jl_value_t**)v, depth);
n += jl_printf(out, ")");
}
else if (jl_static_is_function_(vt)) {
else if (jl_static_is_function_(vt) && is_globname_binding(v, (jl_datatype_t*)vt)) {
// v is function instance (an instance of a Function type).
jl_datatype_t *dv = (jl_datatype_t*)vt;
jl_sym_t *sym = dv->name->mt->name;
char *sn = jl_symbol_name(sym);

jl_sym_t *globname;
int globfunc = is_globfunction(v, dv, &globname);
jl_sym_t *sym;
int globfunc = is_globfunction(v, dv, &sym);
int quote = 0;
if (jl_core_module && (dv->name->module != jl_core_module || !jl_module_exports_p(jl_core_module, sym))) {
n += jl_static_show_x(out, (jl_value_t*)dv->name->module, depth);
n += jl_printf(out, ".");

size_t i = 0;
char *sn = jl_symbol_name(sym);
if (globfunc && !jl_id_start_char(u8_nextchar(sn, &i))) {
n += jl_printf(out, ":(");
quote = 1;
Expand Down
3 changes: 3 additions & 0 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,9 @@ struct var"%X%" end # Invalid name without '#'
end
end

# Test that static show prints something reasonable for `<:Function` types
@test static_shown(:) == "Base.Colon()"

# Test @show
let fname = tempname()
try
Expand Down

0 comments on commit 54be1ce

Please sign in to comment.