Change:
let found = match sm.span_to_snippet(sp) { Ok(snippet) => snippet, Err(e) => { <del> warn!("Invalid span {:?}. Err={:?}", sp, e); </del> <ins> warn!(error = ?e, "Invalid span {:?}", sp); </ins> return false; } };

Discussion:
We don't use // a lot, but they come in handy for "debugging without a build" situations, e.g. we use to show the function being codegen'd (as it's low-overhead and really helpful for e.g. LLVM crashes). While makes sense for off-by-default debugging helpers like that, / seem closer to user-facing diagnostics, where the main difference is them being usable outside of code which has access to a (either due to running before the is created, or just in dependencies that have access to / but not any -specific diagnostics APIs). However, one surprising aspect is only is enabled by default, while is not, meaning that, with the current defaults, one is forced to choose between (which would output the word "error" which sounds more dire than "warning") or (which may never be seen by an user). <hr/My usecase for is in the upcoming support for using hardware performance counters (which needs to be implemented in the separate project), e.g. if they have an unrecognized (newer) CPU, but there's nothing preventing from working (if the newer CPUs aren't drastically different), so showing "error" seems quite inappropriate. Sadly, I don't think itself will change this behavior, so even if we change 's default, might still have to use the less-appropriate if it wants to account for being used in other projects. cc
This might not as big of a problem as I thought, suggested checking if is enabled (either by the user, or 's default if we change that) and emit if it's not (and say "warning" in the message). For convenience I could wrap this in a macro.
warn! then seems not significantly better than just an eprintln - am I missing something there?
Perhaps, but I would prefer using / macros for consistency of output, and more generally the ability for consumers of a library to choose where to direct the messages. This is even more important with , where there is a nesting structure, not just individual messages.
Since for tracing, and should all show up in regular builds.
This has gotten worse with , where even isn't enabled by default (see ).
I assume you mean this? This is just the old equivalent of disabling / unless you have a local built that opts into it. IIUC, "max" means the limit of what can access (i.e.

on nightly can't enable any because optimized those out). What we want is the default level, which doesn't seem to be anything nowadays, with not set.
Talking to we're in agreement this is very wrong: Bailing out means the whole output infrastructure isn't registered, so e.g. will do absolutely nothing.
This is not correct. means that info and below will not be statically disabled (compiled out). Because you are also using to filter the spans and events that are enabled, , , and will only be enabled if the is configured to enable them. What means is that anything below will be disabled at compile time, and cannot be enabled by the filter configuration.
The bail out was done on purpose out of perf concerns. We can certainly bench it and see, but I would prefer to keep it as is and use the appropriate error/warn diagnostics of rustc instead of tracing statements
Do you know more details? There aren't that many non-/ calls and they mainly exist in places that cannot easily get access to the rustc diagnostics infrastructure. So the perf impact should be minimal, while offering a valuable infrastructure for miscellanea that has no other way to interface with the user. For something like , we can probably alleviate it by having a fallback to , especially since it may be used without any logging infrastructure. Or maybe the warnings could be returned by value but that's an easy to misuse API, unlike for errors.
Hmm... maybe it was just a misunderstanding while we were fixing other perf regressions. I'll open a PR later today to test it out.