diff --git a/src/datatype.c b/src/datatype.c index b3ff1997ca8eb..9cf1ec58e09e9 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -19,6 +19,11 @@ extern "C" { // allocating TypeNames ----------------------------------------------------------- +static int is10digit(char c) JL_NOTSAFEPOINT +{ + return (c >= '0' && c <= '9'); +} + jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT { char *n = jl_symbol_name(s); @@ -30,6 +35,8 @@ jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT len = strlen(n) - 1; else len = (end-n) - 1; // extract `f` from `#f#...` + if (is10digit(n[1])) + return jl_symbol_n(n, len+1); return jl_symbol_n(&n[1], len); } @@ -448,6 +455,14 @@ void jl_compute_field_offsets(jl_datatype_t *st) jl_errorf("type %s has field offset %d that exceeds the page size", jl_symbol_name(st->name->name), descsz); } +static int is_anonfn_typename(char *name) +{ + if (name[0] != '#') + return 0; + char *other = strrchr(name, '#'); + return (name[1] != '#' && other > &name[1] && is10digit(other[1])); +} + JL_DLLEXPORT jl_datatype_t *jl_new_datatype( jl_sym_t *name, jl_module_t *module, @@ -487,7 +502,7 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype( } else { tn = jl_new_typename_in((jl_sym_t*)name, module); - if (super == jl_function_type || super == jl_builtin_type || jl_symbol_name(name)[0] == '#') { + if (super == jl_function_type || super == jl_builtin_type || is_anonfn_typename(jl_symbol_name(name))) { // Callable objects (including compiler-generated closures) get independent method tables // as an optimization tn->mt = jl_new_method_table(name, module); diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 46d7054389e21..ac477a9966ac3 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -435,8 +435,12 @@ sparams))) (let ((kw (gensy)) (rkw (if (null? restkw) (make-ssavalue) (symbol (string (car restkw) "...")))) - (mangled (symbol (string (if name (undot-name name) '_) "#" - (current-julia-module-counter))))) + (mangled (let ((und (and name (undot-name name)))) + (symbol (string (if (and name (= (string.char (string name) 0) #\#)) + "" + "#") + (or und '_) "#" + (string (current-julia-module-counter))))))) ;; this is a hack: nest these statements inside a call so they get closure ;; converted together, allowing all needed types to be defined before any methods. `(call (core ifelse) false false (block @@ -3265,7 +3269,10 @@ f(x) = yt(x) (let* ((exists (get defined name #f)) (type-name (or (get namemap name #f) (and name - (symbol (string "#" name "#" (current-julia-module-counter)))))) + (symbol (string (if (= (string.char (string name) 0) #\#) + "" + "#") + name "#" (current-julia-module-counter)))))) (alldefs (expr-find-all (lambda (ex) (and (length> ex 2) (eq? (car ex) 'method) (not (eq? ex e)) diff --git a/test/core.jl b/test/core.jl index 0d6b99c73ee6e..ec5de14031b7d 100644 --- a/test/core.jl +++ b/test/core.jl @@ -2404,6 +2404,20 @@ for f in (:(Core.arrayref), :((::typeof(Core.arrayref))), :((::Core.IntrinsicFun @test_throws ErrorException("cannot add methods to a builtin function") @eval $f() = 1 end +# issue #33370 +abstract type B33370 end + +let n = gensym(), c(x) = B33370[x][1]() + @eval begin + struct $n <: B33370 + end + + function (::$n)() + end + end + @test c(eval(n)()) === nothing +end + # issue #8798 let npy_typestrs = Dict("b1"=>Bool,