Repository navigation
Conversation
|
rustbot has assigned @hanna-kruppe. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Don't emit allow attributes in try/contract desugaring
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (8b7218a): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. @bors rollup=never rustc-perf Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -0.8%, secondary 5.2%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 1.3%, secondary 4.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary 0.1%, secondary 0.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 488.311s -> 490.216s (0.39%) |
ac3d7ab to
1b0cff3
Compare
There was a problem hiding this comment.
This makes sense to me in the abstract, but I'm not confident that I fully understand the ramifications. I tried experimenting a bit, but so far I haven't managed to find any test that even showcases why we need to allow unreachable code in parts of the try desugaring. That's a bit concerning, mostly for my ability to review this, but also for test coverage.
| // `ControlFlow::Break(residual) => | ||
| // #[allow(unreachable_code)] | ||
| // return Try::from_residual(residual),` | ||
| // `ControlFlow::Break(residual) => return Try::from_residual(residual),` |
There was a problem hiding this comment.
Nit: this comment doesn't reflect the variations:
breakinstead ofreturnwithin try blocksTry::into_residualvsTry::from_residualdepending on the kind of try block
That's a pre-existing problem, but maybe you want to fix it while we're here?
There was a problem hiding this comment.
I wonder if we should just delete this documentation, it feels like it's just going to become wrong again in the future.
There was a problem hiding this comment.
I do think it's helpful to have it spelled out in one place (maybe not in both places). Even as outdated as it was, it helped me pattern match what the code is doing and notice the gaps. Reverse engineering the whole desugaring from the code alone seems harder to me.
| /// // If there is an enclosing `try {...}`: | ||
| /// break 'catch_target Residual::into_try_type(residual), |
There was a problem hiding this comment.
Nit: this comment is outdated since #149489, which added the option break 'catch_target Residual::from_residual(residual), for heterogeneous try blocks -- also pre-existing but may be worth a drive-by fix.
| // Don't lint *within* the `?` operator | ||
| Some(DesugaringKind::QuestionMark) => return, | ||
|
|
||
| // Don't lint *within* contract attrs | ||
| Some(DesugaringKind::Contract) => return, |
There was a problem hiding this comment.
I think this applies to more HIR nodes than the previous #[allow(..)] did because all nodes produced by the lowering have the same span with the desugaring bit set. For try blocks that's the whole match including patterns, not just the expressions following the arms.
Is this right? If yes, is it observable? If not, why not?
| Some(DesugaringKind::Await) => return, | ||
|
|
||
| // Don't lint *within* the `?` operator | ||
| Some(DesugaringKind::QuestionMark) => return, |
There was a problem hiding this comment.
If I drop this line, all of tests/ui/ still passes. (The contracts counterpart is exercised by the test suite.) I think we need at least one test for this, ideally several because there's at minimum two expressions (possibly also unreachable patterns, see earlier comment).
The test is https://github.com/rust-lang/rust/blob/main/tests/ui/reachable/unreachable-try-pattern.rs It was added in #39127 In any case, I think the allow is now unnecessary because we desugar differently. Back then the second arm would desugar into a bunch of function calls, now it doesn't. For example, fn main(){
let x: Option<!> = None;
match x {
None => {},
Some(never) => { From::from(never) },
}
}emits warning: unreachable call
--> src/main.rs:5:26
|
5 | Some(never) => { From::from(never) },
| ^^^^^^^^^^ ----- any code following this expression is unreachable
| |
| unreachable call
|
= note: `#[warn(unreachable_code)]` (part of `#[warn(unused)]`) on by defaultbut this doesn't fn main(){
let x: Option<!> = None;
match x {
None => {},
Some(never) => { never },
}
}I'm not sure why the attribute is on the first arm. Maybe the unreachable code lint is implemented differently now. |
|
I saw that test, but since it doesn’t fail when removing the I assume you’re right that something has changed to make the allow/early-return unnecessary, but I don’t understand what/how. The try desugaring still produces a call in the |
|
Hm, this seems very relevant: rust/compiler/rustc_hir_typeck/src/expr.rs Lines 291 to 294 in 0617e57 Edit: oops, no, |
1b0cff3 to
8ede13b
Compare
No description provided.