Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macroexpansion exceptions are needlessly chained #852

Closed
chrisrink10 opened this issue Jan 31, 2024 · 0 comments · Fixed by #853
Closed

Macroexpansion exceptions are needlessly chained #852

chrisrink10 opened this issue Jan 31, 2024 · 0 comments · Fixed by #853
Assignees
Labels
component:compiler Issue pertaining to compiler issue-type:enhancement New feature or request

Comments

@chrisrink10
Copy link
Member

chrisrink10 commented Jan 31, 2024

Macroexpansion exceptions get chained at each level of macroexpansion which leads to excessively long exception chains that are are challenging to read. It would be trivially to continue raising the source exception during macroexpansion without adding another cause exception.

Take this example for instance:

(defn f [] (let [a :a] b))

There are 4 exceptions in the chain with only the last being the meaningful:

Traceback (most recent call last):
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2510, in _invoke_ast
    return __handle_macroexpanded_ast(form, expanded, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2455, in __handle_macroexpanded_ast
    expanded_ast = _analyze_form(expanded, ctx)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 712, in _analyze_form
    return cast(T_node, f(form, ctx).fix_missing_locations(form_loc))
                        ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3250, in _list_node
    return handle_special_form(form, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2587, in _let_ast
    stmts, ret = _body_ast(let_body, ctx)
                 ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 750, in _body_ast
    body_expr = _analyze_form(ret_form, ctx)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 712, in _analyze_form
    return cast(T_node, f(form, ctx).fix_missing_locations(form_loc))
                        ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3558, in _symbol_node
    return _resolve_sym(ctx, form)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3536, in _resolve_sym
    return __resolve_bare_symbol(ctx, form)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3509, in __resolve_bare_symbol
    raise ctx.AnalyzerException(
basilisp.lang.compiler.exception.CompilerException: unable to resolve symbol 'b' in this context {:col 24 :end-col 25 :file "<REPL Input>" :line 1 :end-line 1 :phase :analyzing :form b}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2510, in _invoke_ast
    return __handle_macroexpanded_ast(form, expanded, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2455, in __handle_macroexpanded_ast
    expanded_ast = _analyze_form(expanded, ctx)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 710, in _analyze_form
    return f(form, ctx)
           ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3250, in _list_node
    return handle_special_form(form, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 839, in with_meta
    descriptor = gen_node(form, ctx)
                 ^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2136, in _fn_ast
    __fn_method_ast(
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 1963, in __fn_method_ast
    stmts, ret = _body_ast(form.rest, ctx)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 750, in _body_ast
    body_expr = _analyze_form(ret_form, ctx)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 712, in _analyze_form
    return cast(T_node, f(form, ctx).fix_missing_locations(form_loc))
                        ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3256, in _list_node
    return _invoke_ast(form, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2512, in _invoke_ast
    raise CompilerException(
basilisp.lang.compiler.exception.CompilerException: error occurred during macroexpansion {:col 12 :end-col 26 :file "<REPL Input>" :line 1 :end-line 1 :phase :macroexpansion :form (let [a :a] b)}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2510, in _invoke_ast
    return __handle_macroexpanded_ast(form, expanded, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2455, in __handle_macroexpanded_ast
    expanded_ast = _analyze_form(expanded, ctx)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 712, in _analyze_form
    return cast(T_node, f(form, ctx).fix_missing_locations(form_loc))
                        ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3250, in _list_node
    return handle_special_form(form, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 1007, in _def_ast
    init = _analyze_form(runtime.nth(form, init_idx), ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 710, in _analyze_form
    return f(form, ctx)
           ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3256, in _list_node
    return _invoke_ast(form, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2512, in _invoke_ast
    raise CompilerException(
basilisp.lang.compiler.exception.CompilerException: error occurred during macroexpansion {:file "<REPL Input>" :phase :macroexpansion :form (basilisp.core/fn f [] (let [a :a] b))}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/christopher/Projects/basilisp/src/basilisp/cli.py", line 446, in repl
    result = eval_str(lsrc, ctx, ns, eof)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/cli.py", line 46, in eval_str
    last = compiler.compile_and_exec_form(form, ctx, ns)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/__init__.py", line 168, in compile_and_exec_form
    lisp_ast = analyze_form(ctx.analyzer_context, form)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3826, in analyze_form
    return _analyze_form(form, ctx).assoc(top_level=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/.pyenv/versions/3.12.1/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 712, in _analyze_form
    return cast(T_node, f(form, ctx).fix_missing_locations(form_loc))
                        ^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 3256, in _list_node
    return _invoke_ast(form, ctx)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/christopher/Projects/basilisp/src/basilisp/lang/compiler/analyzer.py", line 2512, in _invoke_ast
    raise CompilerException(
basilisp.lang.compiler.exception.CompilerException: error occurred during macroexpansion {:col 1 :end-col 27 :file "<REPL Input>" :line 1 :end-line 1 :phase :macroexpansion :form (defn f [] (let [a :a] b))}```
@chrisrink10 chrisrink10 added issue-type:enhancement New feature or request component:compiler Issue pertaining to compiler labels Jan 31, 2024
@chrisrink10 chrisrink10 added this to the Release v0.1.0 milestone Jan 31, 2024
@chrisrink10 chrisrink10 self-assigned this Jan 31, 2024
chrisrink10 added a commit that referenced this issue Jan 31, 2024
Fixes #852

---------

Co-authored-by: Christopher Rink <christopher@Christophers-MacBook-Pro.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component:compiler Issue pertaining to compiler issue-type:enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant