

rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission...
source link: https://github.com/rust-lang/rust/pull/93368
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

That is, DiagnosticBuilder
is now generic over the return type of .emit()
, so we'll now have:
DiagnosticBuilder<ErrorReported>
for error (incl. fatal/bug) diagnostics- can only be created via a
const L: Level
-generic constructor, that limits allowed variants via awhere
clause, so not evenrustc_errors
can accidentally bypass this limitation - asserts
diagnostic.is_error()
on emission, just in case the construction restriction was bypassed (e.g. by replacing the wholeDiagnostic
insideDiagnosticBuilder
) .emit()
returnsErrorReported
, as a "proof" token that.emit()
was called
(though note that this isn't a real guarantee until after completing the work on
#69426)
- can only be created via a
DiagnosticBuilder<()>
for everything else (warnings, notes, etc.)- can also be obtained from other
DiagnosticBuilder
s by calling.forget_guarantee()
- can also be obtained from other
This PR is a companion to other ongoing work, namely:
- #69426
and it's ongoing implementation:
#93222
the API changes in this PR are needed to get statically-checked "only errors produceErrorReported
from.emit()
", but doesn't itself provide any really strong guarantees without those otherErrorReported
changes - #93244
would make the choices of API changes (esp. naming) in this PR fit better overall
In order to be able to let .emit()
return anything trustable, several changes had to be made:
Diagnostic
'slevel
field is now private torustc_errors
, to disallow arbitrary "downgrade"s from "some kind of error" to "warning" (or anything else that doesn't cause compilation to fail)- it's still possible to replace the whole
Diagnostic
inside theDiagnosticBuilder
, sadly, that's harder to fix, but it's unlikely enough that we can paper over it with asserts on.emit()
- it's still possible to replace the whole
.cancel()
now consumesDiagnosticBuilder
, preventing.emit()
calls on a cancelled diagnostic- it's also now done internally, through
DiagnosticBuilder
-private state, instead of having aLevel::Cancelled
variant that can be read (or worse, written) by the user - this removes a hazard of calling
.cancel()
on an error then continuing to attach details to it, and even expect to be able to.emit()
it - warnings were switched to only
can_emit_warnings
on emission (instead of pre-cancelling early) struct_dummy
was removed (as it relied on a pre-Cancelled
Diagnostic
)
- it's also now done internally, through
- since
.emit()
doesn't consume theDiagnosticBuilder
(I tried and gave up, it's much more work than this PR),
we have to make.emit()
idempotent wrt the guarantees it returns- thankfully,
err.emit(); err.emit();
can returnErrorReported
both times, as the second.emit()
call has no side-effects only because the first one did do the appropriate emission
- thankfully,
&mut Diagnostic
is now used in a lot of function signatures, which used to take&mut DiagnosticBuilder
(in the interest of not having to make those functions generic)- the APIs were already mostly identical, allowing for low-effort porting to this new setup
- only some of the suggestion methods needed some rework, to have the extra
DiagnosticBuilder
functionality on theDiagnostic
methods themselves (that change is also present in #93259) .emit()
/.cancel()
aren't available, but IMO calling them from an "error decorator/annotator" function isn't a good practice, and can lead to strange behavior (from the caller's perspective).downgrade_to_delayed_bug()
was added, letting you convert any.is_error()
diagnostic into adelay_span_bug
one (which works because in both cases the guarantees available are the same)
This PR should ideally be reviewed commit-by-commit, since there is a lot of fallout in each.
Recommend
-
28
关于Emit的博客已经进入第四篇,在读本篇博文之前,我希望读者能先仔细回顾博主之前所编写的关于Emit的博文,从该篇博文开始,我们就可以真正的使用Emit,并把知识转化为实战,我也会把之前的博文链接放在下方,以方便读者阅读,大家也可...
-
10
0. 前言 首先立马解释一波为啥会有这样一篇伪标题的Demo随笔呢? 不是本人有知识误区,或者要误人子弟 因为大家都知道emit写出来的都是同步方法,不可能await,至少现在这么多年来没有提供对应的功能
-
16
Conversation Copy link Contributor ...
-
4
Copy link Member
-
13
“Why do some objects emit a ‘pitchless’ sound when hit, and others a 'tuned’ sound?”...
-
11
Google Pixel 3 in all colorways (Image credit: Android Central)...
-
6
Contributor rsc commented
-
12
Stressed Plants Emit Sounds That Can Be Detected More Than a Meter Away Follow Slashdot stories on Twitter...
-
10
Closed Bug 1753682...
-
4
Contributor ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK