<p dir="auto">Plugins can fail in ways that aren't the fault of the code being compiled. This could be an internal error in the plugin (which is still different from an ICE in Rust itself), or something like failure to load an external configuration file.</p>
<p dir="auto">Ideally, plugins would call the usual methods like <code class="notranslate">bug</code>, <code class="notranslate">err</code>, <code class="notranslate">span_bug</code>, etc., and the resulting messages would include the name of the plugin crate.  Unfortunately we can't do this by setting session state about which plugin is running, because they can call back into <code class="notranslate">librustc</code> and errors there shouldn't be reported as plugin errors.  We could introduce <code class="notranslate">plugin_bug</code>, <code class="notranslate">plugin_err</code>, <code class="notranslate">plugin_span_bug</code>, etc, but this API duplication is ugly, and you have to remember to use different methods when writing plugins.</p>
<p dir="auto">The nicer (though harder-to-implement) solution is to have these functions walk the stack and then look at which shared object their caller was defined in.  In glibc this can be done with <code class="notranslate">backtrace()</code> and <code class="notranslate">dladdr()</code>, but I don't know how hard it is on other platforms.</p>
<p dir="auto">Whatever we do, we should also make these error methods accessible from the <code class="notranslate">Registry</code>, for use handling errors that occur during plugin initialization.</p>
<p dir="auto">The AST formatting functions have a lot of duplication. Abstract out patterns<br>
like fmt_sequence and fmt_bracketed.</p>