diff --git a/base/boot.jl b/base/boot.jl index 00a2064735897..3227e3e2c7f4c 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -83,7 +83,6 @@ #end #immutable LineNumberNode -# file::Symbol # line::Int #end @@ -280,7 +279,7 @@ _new(:TopNode, :Symbol) _new(:NewvarNode, :Slot) _new(:QuoteNode, :ANY) _new(:GenSym, :Int) -eval(:((::Type{LineNumberNode})(f::Symbol, l::Int) = $(Expr(:new, :LineNumberNode, :f, :l)))) +eval(:((::Type{LineNumberNode})(l::Int) = $(Expr(:new, :LineNumberNode, :l)))) eval(:((::Type{GlobalRef})(m::Module, s::Symbol) = $(Expr(:new, :GlobalRef, :m, :s)))) eval(:((::Type{Slot})(n::Int) = $(Expr(:new, :Slot, :n, Any)))) eval(:((::Type{Slot})(n::Int, t::ANY) = $(Expr(:new, :Slot, :n, :t)))) diff --git a/base/show.jl b/base/show.jl index 236caeeb875ce..8f69b325aa309 100644 --- a/base/show.jl +++ b/base/show.jl @@ -489,7 +489,7 @@ end ## AST printing ## show_unquoted(io::IO, sym::Symbol, ::Int, ::Int) = print(io, sym) -show_unquoted(io::IO, ex::LineNumberNode, ::Int, ::Int) = show_linenumber(io, ex.line, ex.file) +show_unquoted(io::IO, ex::LineNumberNode, ::Int, ::Int) = show_linenumber(io, ex.line) show_unquoted(io::IO, ex::LabelNode, ::Int, ::Int) = print(io, ex.label, ": ") show_unquoted(io::IO, ex::GotoNode, ::Int, ::Int) = print(io, "goto ", ex.label) show_unquoted(io::IO, ex::TopNode, ::Int, ::Int) = print(io,"top(",ex.name,')') @@ -539,7 +539,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int) head, args, nargs = ex.head, ex.args, length(ex.args) emphstate = typeemphasize(io) show_type = true - if (ex.head == :(=) || + if (ex.head == :(=) || ex.head == :line || ex.head == :boundscheck || ex.head == :gotoifnot || ex.head == :return) diff --git a/src/alloc.c b/src/alloc.c index 71a49cea8d820..eb98adefece53 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -293,12 +293,11 @@ JL_DLLEXPORT void jl_lambda_info_set_ast(jl_lambda_info_t *li, jl_value_t *ast) li->pure = 1; jl_value_t *body1 = skip_meta(body); if (jl_is_linenode(body1)) { - li->file = jl_linenode_file(body1); li->line = jl_linenode_line(body1); } else if (jl_is_expr(body1) && ((jl_expr_t*)body1)->head == line_sym) { - li->file = (jl_sym_t*)jl_exprarg(body1, 1); li->line = jl_unbox_long(jl_exprarg(body1, 0)); + li->file = (jl_sym_t*)jl_exprarg(body1, 1); } jl_array_t *vis = jl_lam_vinfo((jl_expr_t*)ast); jl_array_t *args = jl_lam_args((jl_expr_t*)ast); diff --git a/src/ast.c b/src/ast.c index dbafa41d894a8..aaf07887a4496 100644 --- a/src/ast.c +++ b/src/ast.c @@ -496,16 +496,10 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, int eo) else n++; if (!eo) { - if (sym == line_sym && n==2) { - // NOTE: n==3 case exists: '(line, linenum, filename, funcname) passes - // the original name through to keyword-arg specializations. - // See 'line handling in julia-syntax.scm:keywords-method-def-expr - jl_value_t *filename = NULL, *linenum = NULL; - JL_GC_PUSH2(&filename, &linenum); - filename = scm_to_julia_(fl_ctx, car_(cdr_(e)), 0); - linenum = scm_to_julia_(fl_ctx, car_(e), 0); - jl_value_t *temp = jl_new_struct(jl_linenumbernode_type, - filename, linenum); + if (sym == line_sym && n==1) { + jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), 0); + JL_GC_PUSH1(&linenum); + jl_value_t *temp = jl_new_struct(jl_linenumbernode_type, linenum); JL_GC_POP(); return temp; } @@ -659,21 +653,13 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) fl_free_gc_handles(fl_ctx, 1); return scmv; } - if (jl_typeis(v, jl_linenumbernode_type)) { - // GC Note: jl_fieldref(v, 1) allocates but neither jl_fieldref(v, 0) - // or julia_to_list2 should allocate here - value_t args = julia_to_list2(fl_ctx, jl_fieldref(v,1), jl_fieldref(v,0)); - fl_gc_handle(fl_ctx, &args); - value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)line_sym); - value_t scmv = fl_cons(fl_ctx, hd, args); - fl_free_gc_handles(fl_ctx, 1); - return scmv; - } // GC Note: jl_fieldref(v, 0) allocate for LabelNode, GotoNode // but we don't need a GC root here because julia_to_list2 // shouldn't allocate in this case. if (jl_typeis(v, jl_slot_type)) return julia_to_list2(fl_ctx, (jl_value_t*)slot_sym, jl_fieldref(v,0)); + if (jl_typeis(v, jl_linenumbernode_type)) + return julia_to_list2(fl_ctx, (jl_value_t*)line_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_labelnode_type)) return julia_to_list2(fl_ctx, (jl_value_t*)label_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_gotonode_type)) diff --git a/src/builtins.c b/src/builtins.c index e12cd4a1fbe1e..46362e722b54c 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1379,8 +1379,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, n += jl_printf(out, ")"); } else if (vt == jl_linenumbernode_type) { - n += jl_printf(out, "# line %" PRIuPTR " %s", - jl_linenode_line(v), jl_symbol_name(jl_linenode_file(v))); + n += jl_printf(out, "# line %" PRIuPTR, jl_linenode_line(v)); } else if (vt == jl_expr_type) { jl_expr_t *e = (jl_expr_t*)v; diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 071adbb3243fc..c9d39e40b2f4b 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -315,6 +315,8 @@ JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed) return PointerType::get(lt, 0); } if (jl_is_bitstype(jt)) { + if (jt == (jl_value_t*)jl_long_type) + return T_size; int nb = jl_datatype_size(jt); if (jl_is_floattype(jt)) { #ifndef DISABLE_FLOAT16 diff --git a/src/codegen.cpp b/src/codegen.cpp index 719036df563d8..d4d9878dd9116 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4129,13 +4129,12 @@ static std::unique_ptr emit_function(jl_lambda_info_t *lam, jl_llvm_func bool do_coverage = jl_options.code_coverage == JL_LOG_ALL || (jl_options.code_coverage == JL_LOG_USER && in_user_code); bool do_malloc_log = jl_options.malloc_log == JL_LOG_ALL || (jl_options.malloc_log == JL_LOG_USER && in_user_code); jl_value_t *stmt = skip_meta(stmts); - StringRef filename = ""; + StringRef filename = jl_symbol_name(lam->file); StringRef dbgFuncName = jl_symbol_name(lam->name); int lno = -1; // look for initial (line num filename [funcname]) node, [funcname] for kwarg methods. if (jl_is_linenode(stmt)) { lno = jl_linenode_line(stmt); - filename = jl_symbol_name(jl_linenode_file(stmt)); } else if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == line_sym && jl_array_dim0(((jl_expr_t*)stmt)->args) > 0) { @@ -4626,10 +4625,9 @@ static std::unique_ptr emit_function(jl_lambda_info_t *lam, jl_llvm_func if (jl_is_linenode(stmt) || (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == line_sym)) { - jl_sym_t *file = NULL; + jl_sym_t *file=NULL; if (jl_is_linenode(stmt)) { lno = jl_linenode_line(stmt); - file = jl_linenode_file(stmt); } else if (jl_is_expr(stmt)) { lno = jl_unbox_long(jl_exprarg(stmt,0)); @@ -4640,7 +4638,6 @@ static std::unique_ptr emit_function(jl_lambda_info_t *lam, jl_llvm_func } } } - assert(jl_symbol_name(file)); # ifdef LLVM37 DIFile *dfil = NULL; @@ -4649,7 +4646,7 @@ static std::unique_ptr emit_function(jl_lambda_info_t *lam, jl_llvm_func # endif // If the string is not empty - if (*jl_symbol_name(file) != '\0') { + if (file && *jl_symbol_name(file) != '\0') { # ifdef LLVM37 std::map::iterator it = filescopes.find(file); # else diff --git a/src/gf.c b/src/gf.c index ad29e0ed625ad..65db4b374cb27 100644 --- a/src/gf.c +++ b/src/gf.c @@ -916,7 +916,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_instantiate_staged(jl_lambda_info_t *generator jl_cellset(((jl_expr_t*)jl_exprarg(ex,1))->args, 0, body); linenum = jl_box_long(generator->line); - jl_value_t *linenode = jl_new_struct(jl_linenumbernode_type, generator->file, linenum); + jl_value_t *linenode = jl_new_struct(jl_linenumbernode_type, linenum); jl_cellset(body->args, 0, linenode); // invoke code generator @@ -939,6 +939,7 @@ JL_DLLEXPORT jl_lambda_info_t *jl_instantiate_staged(jl_lambda_info_t *generator func->name = generator->name; if (generator->isva) func->isva = 1; + func->file = generator->file; JL_GC_POP(); return func; } diff --git a/src/jltypes.c b/src/jltypes.c index d974caab9aadd..e1c23f610c884 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3449,8 +3449,8 @@ void jl_init_types(void) jl_linenumbernode_type = jl_new_datatype(jl_symbol("LineNumberNode"), jl_any_type, jl_emptysvec, - jl_svec(2, jl_symbol("file"), jl_symbol("line")), - jl_svec(2, jl_symbol_type, jl_long_type), 0, 0, 2); + jl_svec(1, jl_symbol("line")), + jl_svec(1, jl_long_type), 0, 0, 1); jl_labelnode_type = jl_new_datatype(jl_symbol("LabelNode"), jl_any_type, jl_emptysvec, diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 984ebfd451240..15c0f2e609e85 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -596,7 +596,9 @@ (if (invalid-initial-token? t) (error (string "unexpected \"" t "\""))) (if (closer? t) - (list head) ; empty block + (if add-linenums ;; empty block + (list head (line-number-node s)) + (list head)) (let loop ((ex ;; in allow-empty mode skip leading runs of operator (if (and allow-empty (memv t ops)) @@ -1133,7 +1135,10 @@ (error "let variables should end in \";\" or newline")) (let ((ex (parse-block s))) (expect-end s word) - `(let ,ex ,@binds)))) + ;; don't need line info in an empty let block + (if (and (length= ex 2) (pair? (cadr ex)) (eq? (caadr ex) 'line)) + `(let (block) ,@binds) + `(let ,ex ,@binds))))) ((global local) (let* ((lno (input-port-line (ts:port s))) (const (and (eq? (peek-token s) 'const) @@ -1165,13 +1170,8 @@ (eq? (car sig) 'tuple)))) (error (string "expected \"(\" in " word " definition")) sig))) - (loc (begin (if (not (eq? (peek-token s) 'end)) - ;; if ends on same line, don't skip the following newline - (skip-ws-and-comments (ts:port s))) - (line-number-node s))) (body (parse-block s))) (expect-end s word) - (add-filename-to-block! body loc) (list word def body))))) ((abstract) (list 'abstract (parse-subtype-spec s))) @@ -1179,10 +1179,9 @@ (let ((immu? (eq? word 'immutable))) (if (reserved-word? (peek-token s)) (error (string "invalid type name \"" (take-token s) "\""))) - (let ((sig (parse-subtype-spec s)) - (loc (line-number-node s))) + (let ((sig (parse-subtype-spec s))) (begin0 (list 'type (if (eq? word 'type) #t #f) - sig (add-filename-to-block! (parse-block s) loc)) + sig (parse-block s)) (expect-end s word))))) ((bitstype) (list 'bitstype (with-space-sensitive (parse-cond s)) @@ -1218,15 +1217,13 @@ '(block) #f finalb) - (let* ((var (if nl (parse-eq s) (parse-eq* s))) + (let* ((var (if nl #f (parse-eq* s))) (var? (and (not nl) (or (symbol? var) (and (length= var 2) (eq? (car var) '$))))) (catch-block (if (eq? (require-token s) 'finally) '(block) (parse-block s)))) (loop (require-token s) - (if var? - catch-block - `(block ,var ,@(cdr catch-block))) + catch-block (and var? var) finalb))))) ((and (eq? nxt 'finally) @@ -1305,23 +1302,15 @@ (error "invalid \"do\" syntax")) (else (error "unhandled reserved word"))))))) -(define (add-filename-to-block! body loc) - (if (and (length> body 1) - (pair? (cadr body)) - (eq? (caadr body) 'line)) - (set-car! (cdr body) loc)) - body) - (define (parse-do s) (with-bindings ((expect-end-current-line (input-port-line (ts:port s)))) (without-whitespace-newline - (let* ((doargs (if (memv (peek-token s) '(#\newline #\;)) - '() - (parse-comma-separated s parse-range))) - (loc (line-number-node s))) + (let ((doargs (if (memv (peek-token s) '(#\newline #\;)) + '() + (parse-comma-separated s parse-range)))) `(-> (tuple ,@doargs) - ,(begin0 (add-filename-to-block! (parse-block s) loc) + ,(begin0 (parse-block s) (expect-end s 'do))))))) (define (macrocall-to-atsym e) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 1362ca0a76ce1..898a333e162bc 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -387,9 +387,7 @@ ,(method-def-expr- name positional-sparams (append pargl vararg) `(block - ,(if (null? lno) - `(line 0 || ||) - (append (car lno) '(||))) + ,@lno ,@(if (not ordered-defaults) '() (map make-assignment keynames vals)) @@ -417,9 +415,7 @@ (car not-optional)) ,@(cdr not-optional) ,@vararg) `(block - ,@(if (null? lno) '() - ;; TODO jb/functions get a better `name` for functions specified by type - (list (append (car lno) (list (undot-name name))))) + ,@lno ,@stmts) isstaged) ;; call with unsorted keyword args. this sorts and re-dispatches. @@ -434,7 +430,6 @@ ,(if (any kwarg? pargl) (gensy) UNUSED) (call (|.| Core 'kwftype) ,ftype)) (:: ,kw (top Array)) ,@pargl ,@vararg) `(block - (line 0 || ||) ;; initialize keyword args to their defaults, or set a flag telling ;; whether this keyword needs to be set. ,@(map (lambda (name dflt flag) @@ -1457,15 +1452,6 @@ (if ,g ,g ,(loop (cdr tail))))))))))) -(define (expand-forms e) - (if (or (atom? e) (memq (car e) '(quote inert top line module toplevel jlgensym null meta))) - e - (let ((ex (get expand-table (car e) #f))) - (if ex - (ex e) - (cons (car e) - (map expand-forms (cdr e))))))) - (define (expand-for while lhs X body) ;; (for (= lhs X) body) (let ((coll (make-jlgensym)) @@ -1488,6 +1474,15 @@ (define (syntactic-op-to-call e) `(call ,(car e) ,(expand-forms (cadr e)) ,(expand-forms (caddr e)))) +(define (expand-forms e) + (if (or (atom? e) (memq (car e) '(quote inert top line module toplevel jlgensym null meta))) + e + (let ((ex (get expand-table (car e) #f))) + (if ex + (ex e) + (cons (car e) + (map expand-forms (cdr e))))))) + ;; table mapping expression head to a function expanding that form (define expand-table (table @@ -1508,17 +1503,15 @@ 'block (lambda (e) - (let ((e (flatten-blocks e))) - (cond ((null? (cdr e)) '(null)) - ((null? (cddr e)) (expand-forms (cadr e))) - (else - `(block - ,.(map (lambda (x) - (if (decl? x) - `(decl ,@(map expand-forms (cdr x))) - (expand-forms x))) - (butlast (cdr e))) - ,(expand-forms (last e))))))) + (if (null? (cdr e)) + '(null) + `(block + ,.(map (lambda (x) + (if (decl? x) + `(decl ,@(map expand-forms (cdr x))) + (expand-forms x))) + (butlast (cdr e))) + ,(expand-forms (last (cdr e)))))) '|.| (lambda (e) @@ -2557,6 +2550,15 @@ f(x) = yt(x) (cons (last e2) (append tl (butlast (cdr e2)))) (cons e2 tl))))) +(define (first-non-meta blk) + (let loop ((xs (cdr blk))) + (if (null? xs) + #f + (let ((elt (car xs))) + (if (and (pair? elt) (eq? (car elt) 'meta)) + (loop (cdr xs)) + elt))))) + ;; return `body` with `stmts` inserted after any meta nodes (define (insert-after-meta body stmts) (let ((meta (take-while (lambda (x) (and (pair? x) @@ -2581,6 +2583,22 @@ f(x) = yt(x) '()))) args))))) +(define (take-statements-while pred body) + (let ((acc '())) + (define (take expr) + ;; returns #t as long as exprs match and we should continue + (cond ((and (pair? expr) (memq (car expr) '(block body))) + (let loop ((xs (cdr expr))) + (cond ((null? xs) #t) + ((take (car xs)) (loop (cdr xs))) + (else #f)))) + ((pred expr) + (set! acc (cons expr acc)) + #t) + (else #f))) + (take body) + (reverse! acc))) + ;; clear capture bit for vars assigned once at the top, to avoid allocating ;; some unnecessary Boxes. (define (lambda-optimize-vars! lam) @@ -2597,12 +2615,13 @@ f(x) = yt(x) (let* ((leading (filter (lambda (x) (and (pair? x) (or (eq? (car x) 'method) (eq? (car x) '=)))) - (take-while (lambda (e) - (or (atom? e) - (memq (car e) '(quote top line inert local - implicit-global global - const newvar = null method)))) - (lam:body lam)))) + (take-statements-while + (lambda (e) + (or (atom? e) + (memq (car e) '(quote top line inert local meta + implicit-global global + const newvar = null method)))) + (lam:body lam)))) (unused (map cadr leading)) (def (table))) ;; TODO: reorder leading statements to put assignments where the RHS is @@ -2831,8 +2850,6 @@ f(x) = yt(x) '(null) (convert-assignment name mk-closure fname lam interp))))))) ((lambda) ;; should only happen inside (thunk ...) - ;; flattening blocks helps lambda-optimize-vars! work - (set-car! (cdddr e) (flatten-blocks (lam:body e))) `(lambda ,(cadr e) (,(clear-capture-bits (car (lam:vinfo e))) () ,@(cddr (lam:vinfo e))) @@ -2882,6 +2899,8 @@ f(x) = yt(x) ;; only possible returned values. (define (compile-body e vi lam) (let ((code '()) + (filename #f) + (first-line #t) (label-counter 0) ;; counter for generating label addresses (label-map (table)) ;; maps label names to generated addresses (label-level (table)) ;; exception handler level of each label @@ -2989,11 +3008,25 @@ f(x) = yt(x) rr) (emit `(= ,(cadr e) ,rhs))))) ((block body) - (let loop ((xs (cdr e))) - (if (null? (cdr xs)) - (compile (car xs) break-labels value tail) - (begin (compile (car xs) break-labels #f #f) - (loop (cdr xs)))))) + (let* ((last-fname filename) + (fnm (first-non-meta e)) + (fname (if (and (length> e 1) (pair? fnm) (eq? (car fnm) 'line) + (length> fnm 2)) + (caddr fnm) + filename))) + (if (not (eq? fname last-fname)) + (begin (set! filename fname) + ;; don't need a filename node for start of function + (if (not (eq? e (lam:body lam))) (emit `(meta push_loc ,fname))))) + (begin0 + (let loop ((xs (cdr e))) + (if (null? (cdr xs)) + (compile (car xs) break-labels value tail) + (begin (compile (car xs) break-labels #f #f) + (loop (cdr xs))))) + (if (not (eq? fname last-fname)) + (begin (if (not tail) (emit `(meta pop_loc))) + (set! filename last-fname)))))) ((return) (compile (cadr e) break-labels #t #t) '(null)) @@ -3136,7 +3169,17 @@ f(x) = yt(x) ((const) (emit e)) ;; metadata - ((line meta boundscheck simdloop) (emit e)) + ((line meta boundscheck simdloop) + (if (eq? (car e) 'line) + (if first-line + (begin (set! first-line #f) + (emit e)) + ;; strip filenames out of non-initial line nodes + (emit `(line ,(cadr e)))) + (emit e)) + (if tail + (emit-return '(null)) + '(null))) ((inbounds) ;; TODO: this should not be here but sometimes ends up in tail position, e.g. ;; `f(x) = @inbounds return x` diff --git a/src/julia.h b/src/julia.h index a590d5b0677d7..ba959e0458a9d 100644 --- a/src/julia.h +++ b/src/julia.h @@ -669,8 +669,7 @@ STATIC_INLINE void jl_array_uint8_set(void *a, size_t i, uint8_t x) #define jl_nfields(v) jl_datatype_nfields(jl_typeof(v)) // Not using jl_fieldref to avoid allocations -#define jl_linenode_file(x) (*(jl_sym_t**)x) -#define jl_linenode_line(x) (((intptr_t*)x)[1]) +#define jl_linenode_line(x) (((intptr_t*)x)[0]) #define jl_labelnode_label(x) (((intptr_t*)x)[0]) #define jl_slot_number(x) (((intptr_t*)x)[0]) #define jl_slot_get_type(x) (((jl_value_t**)x)[1]) diff --git a/test/backtrace.jl b/test/backtrace.jl index 3dec42bf6b39f..3a20293ee330d 100644 --- a/test/backtrace.jl +++ b/test/backtrace.jl @@ -27,16 +27,16 @@ end # same-file inline eval(Expr(:function, Expr(:call, :test_inline_1), - Expr(:block, LineNumberNode(symbol("backtrace.jl"), 42), - LineNumberNode(symbol("backtrace.jl"), 37), + Expr(:block, LineNumberNode(42), + LineNumberNode(37), Expr(:call, :throw, "foo")))) # different-file inline const absfilepath = OS_NAME == :Windows ? "C:\\foo\\bar\\baz.jl" : "/foo/bar/baz.jl" eval(Expr(:function, Expr(:call, :test_inline_2), - Expr(:block, LineNumberNode(symbol("backtrace.jl"), 99), - LineNumberNode(symbol("foobar.jl"), 666), - LineNumberNode(symbol(absfilepath), 111), + Expr(:block, LineNumberNode(99), + LineNumberNode(666), + LineNumberNode(111), Expr(:call, :throw, "foo")))) try diff --git a/test/parse.jl b/test/parse.jl index bbd497af83631..9b0bc49d80001 100644 --- a/test/parse.jl +++ b/test/parse.jl @@ -148,7 +148,7 @@ macro test999_str(args...); args; end @test parseall(""" macro f(args...) end; @f "" """) == Expr(:toplevel, - Expr(:macro, Expr(:call, :f, Expr(:..., :args)), Expr(:block,)), + Expr(:macro, Expr(:call, :f, Expr(:..., :args)), Expr(:block, Expr(:line, 1, :none))), Expr(:macrocall, symbol("@f"), "")) # blocks vs. tuples diff --git a/test/reflection.jl b/test/reflection.jl index cbc5fecf54564..1c6ab402fff56 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -249,3 +249,7 @@ end end end @test functionloc(f15447)[2] > 0 + +# issue #15280 +function f15280(x) end +@test functionloc(f15280)[2] > 0 diff --git a/test/show.jl b/test/show.jl index bec0133c965e9..17fe4fd9e8905 100644 --- a/test/show.jl +++ b/test/show.jl @@ -11,8 +11,8 @@ immutable T5589 end @test replstr(T5589(Array(UTF8String,100))) == "T5589(UTF8String[#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef … #undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef])" -@test replstr(parse("type X end")) == ":(type X\n end)" -@test replstr(parse("immutable X end")) == ":(immutable X\n end)" +@test replstr(parse("type X end")) == ":(type X # none, line 1:\n end)" +@test replstr(parse("immutable X end")) == ":(immutable X # none, line 1:\n end)" s = "ccall(:f,Int,(Ptr{Void},),&x)" @test replstr(parse(s)) == ":($s)" @@ -362,15 +362,15 @@ end # issue #15309 -l1, l2, l2n = Expr(:line,42), Expr(:line,42,:myfile), LineNumberNode(:myfile,42) -@test string(l2n) == " # myfile, line 42:" -@test string(l2) == string(l2n) -@test string(l1) == replace(string(l2n),"myfile, ","",1) +l1, l2, l2n = Expr(:line,42), Expr(:line,42,:myfile), LineNumberNode(42) +@test string(l2n) == " # line 42:" +@test string(l2) == " # myfile, line 42:" +@test string(l1) == string(l2n) ex = Expr(:block, l1, :x, l2, :y, l2n, :z) @test replace(string(ex)," ","") == replace(""" begin # line 42: x # myfile, line 42: - y # myfile, line 42: + y # line 42: z end""", " ", "") # Test the printing of whatever form of line number representation diff --git a/test/stacktraces.jl b/test/stacktraces.jl index c0ba1faaa3c18..b9218709c3ba8 100644 --- a/test/stacktraces.jl +++ b/test/stacktraces.jl @@ -59,7 +59,6 @@ let ct = current_task() try bad_function() catch - i_need_a_line_number_julia_bug = true # julia lowering doesn't emit a proper line number for catch return stacktrace() end end @@ -70,7 +69,7 @@ let ct = current_task() return catch_stacktrace() end end - line_numbers = @__LINE__ .- [16, 10, 5] + line_numbers = @__LINE__ .- [15, 10, 5] # Test try...catch with stacktrace @test try_stacktrace()[1] == StackFrame(:try_stacktrace, @__FILE__, line_numbers[2])