about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/build
AgeCommit message (Collapse)AuthorLines
2024-05-15Fix more new for_loops_over_fallibles hits in compiler.Zachary S-1/+1
2024-05-13Remove `extern crate rustc_middle` from `rustc_mir_build`.Nicholas Nethercote-0/+11
2024-05-10Use fewer origins when creating type variables.Nicholas Nethercote-4/+1
`InferCtxt::next_{ty,const}_var*` all take an origin, but the `param_def_id` is almost always `None`. This commit changes them to just take a `Span` and build the origin within the method, and adds new methods for the rare cases where `param_def_id` might not be `None`. This avoids a lot of tedious origin building. Specifically: - next_ty_var{,_id_in_universe,_in_universe}: now take `Span` instead of `TypeVariableOrigin` - next_ty_var_with_origin: added - next_const_var{,_in_universe}: takes Span instead of ConstVariableOrigin - next_const_var_with_origin: added - next_region_var, next_region_var_in_universe: these are unchanged, still take RegionVariableOrigin The API inconsistency (ty/const vs region) seems worth it for the large conciseness improvements.
2024-05-07Auto merge of #124223 - Zalathar:conditional-let, r=compiler-errorsbors-3/+30
coverage: Branch coverage support for let-else and if-let This PR adds branch coverage instrumentation for let-else and if-let, including let-chains. This lifts two of the limitations listed at #124118.
2024-05-04Lower never patterns to Unreachable in mirNadrieril-1/+65
2024-05-04Auto merge of #124401 - oli-obk:some_hir_cleanups, r=cjgillotbors-1/+2
Some hir cleanups It seemed odd to not put `AnonConst` in the arena, compared with the other types that we did put into an arena. This way we can also give it a `Span` without growing a lot of other HIR data structures because of the extra field. r? compiler
2024-05-02Inline & delete `Ty::new_unit`, since it's just a field accessWaffle Lapkin-1/+1
2024-04-30coverage: Add branch coverage support for if-let and let-chainsZalathar-1/+4
2024-04-30coverage: Add branch coverage support for let-elseZalathar-3/+27
2024-04-30coverage. Split mcdc builder to a sub module of coverageinfozhuyunxing-269/+279
2024-04-30coverage. Add MCDCInfoBuilder to isolate all mcdc stuff from BranchInfoBuilderzhuyunxing-86/+110
2024-04-30coverage. Add BlockMarkerGen to avoid ownership gymnasticszhuyunxing-29/+35
2024-04-29Rollup merge of #124508 - Zalathar:op, r=jieyouxu许杰友 Jieyou Xu (Joe)-4/+4
coverage: Avoid hard-coded values when visiting logical ops This is a tiny little thing that I noticed during the final review of #123409, and I didn't want to hold up the whole PR just for this. Instead of separately hard-coding the operation being visited, we can get it from the match arm pattern by using an as-pattern. `@rustbot` label +A-code-coverage
2024-04-29Auto merge of #124255 - RenjiSann:renji/mcdc-nested-expressions, r=Zalatharbors-15/+66
MCDC coverage: support nested decision coverage #123409 provided the initial MCDC coverage implementation. As referenced in #124144, it does not currently support "nested" decisions, like the following example : ```rust fn nested_if_in_condition(a: bool, b: bool, c: bool) { if a && if b || c { true } else { false } { say("yes"); } else { say("no"); } } ``` Note that there is an if-expression (`if b || c ...`) embedded inside a boolean expression in the decision of an outer if-expression. This PR proposes a workaround for this cases, by introducing a Decision context stack, and by handing several `temporary condition bitmaps` instead of just one. When instrumenting boolean expressions, if the current node is a leaf condition (i.e. not a `||`/`&&` logical operator nor a `!` not operator), we insert a new decision context, such that if there are more boolean expressions inside the condition, they are handled as separate expressions. On the codegen LLVM side, we allocate as many `temp_cond_bitmap`s as necessary to handle the maximum encountered decision depth.
2024-04-29Avoid some `def_span` query callsOli Scherer-1/+2
2024-04-29mcdc-coverage: Get decision_depth from THIR loweringDorian Péron-17/+66
Use decision context stack to handle nested decisions: - Introduce MCDCDecisionCtx - Use a stack of MCDCDecisionCtx to handle nested decisions
2024-04-29mcdc-coverage: Add decision_depth field in structsDorian Péron-0/+2
Add decision_depth field to TVBitmapUpdate/CondBitmapUpdate statements Add decision_depth field to BcbMappingKinds MCDCBranch and MCDCDecision Add decision_depth field to MCDCBranchSpan and MCDCDecisionSpan
2024-04-29coverage: Avoid hard-coded values when visiting logical opsZalathar-4/+4
Instead of separately hard-coding the operation being visited, we can get it from the match arm pattern by using an as-pattern.
2024-04-23Rollup merge of #122598 - Nadrieril:full-derefpats, r=matthewjasperLeón Orell Valerian Liehr-147/+246
deref patterns: lower deref patterns to MIR This lowers deref patterns to MIR. This is a bit tricky because this is the first kind of pattern that requires storing a value in a temporary. Thanks to https://github.com/rust-lang/rust/pull/123324 false edges are no longer a problem. The thing I'm not confident about is the handling of fake borrows. This PR ignores any fake borrows inside a deref pattern. We are guaranteed to at least fake borrow the place of the first pointer value, which could be enough, but I'm not certain.
2024-04-22coverage: Move some helper code into `BranchInfoBuilder`Zalathar-26/+40
2024-04-22coverage: Detach MC/DC branch spans from regular branch spansZalathar-27/+20
MC/DC's reliance on the existing branch coverage types is making it much harder to improve branch coverage.
2024-04-20Use deep fake borrows for deref patternsNadrieril-28/+30
2024-04-20Add a non-shallow fake borrowNadrieril-2/+3
2024-04-20Rework fake borrow calculationNadrieril-117/+139
2024-04-20Allow mutable bindings inside deref patternsNadrieril-15/+33
2024-04-20Track mutability of deref patternsNadrieril-2/+2
2024-04-20Don't fake borrow inside a deref patternNadrieril-2/+12
2024-04-20Lower deref patterns to MIRNadrieril-32/+78
This handles using deref patterns to choose the correct match arm. This does not handle bindings or guards. Co-authored-by: Deadbeef <ent3rm4n@gmail.com>
2024-04-20Rollup merge of #123409 - ZhuUx:master, r=oli-obkMatthias Krüger-10/+247
Implement Modified Condition/Decision Coverage This is an implementation based on llvm backend support (>= 18) by `@evodius96` and branch coverage support by `@Zalathar.` ### Major changes: * Add -Zcoverage-options=mcdc as switch. Now coverage options accept either `no-branch`, `branch`, or `mcdc`. `mcdc` also enables `branch` because it is essential to work. * Add coverage mapping for MCDCBranch and MCDCDecision. Note that MCDCParameter evolves from llvm 18 to llvm 19. The mapping in rust side mainly references to 19 and is casted to 18 types in llvm wrapper. * Add wrapper for mcdc instrinc functions from llvm. And inject associated statements to mir. * Add BcbMappingKind::Decision, I'm not sure is it proper but can't find a better way temporarily. * Let coverage-dump support parsing MCDCBranch and MCDCDecision from llvm ir. * Add simple tests to check whether mcdc works. * Same as clang, currently rustc does not generate instrument for decision with more than 6 condtions or only 1 condition due to considerations of resource. ### Implementation Details 1. To get information about conditions and decisions, `MCDCState` in `BranchInfoBuilder` is used during hir lowering to mir. For expressions with logical op we call `Builder::visit_coverage_branch_operation` to record its sub conditions, generate condition ids for them and save their spans (to construct the span of whole decision). This process mainly references to the implementation in clang and is described in comments over `MCDCState::record_conditions`. Also true marks and false marks introduced by branch coverage are used to detect where the decision evaluation ends: the next id of the condition == 0. 2. Once the `MCDCState::decision_stack` popped all recorded conditions, we can ensure that the decision is checked over and push it into `decision_spans`. We do not manually insert decision span to avoid complexity from then_else_break in nested if scopes. 3. When constructing CoverageSpans, add condition info to BcbMappingKind::Branch and decision info to BcbMappingKind::Decision. If the branch mapping has non-zero condition id it will be transformed to MCDCBranch mapping and insert `CondBitmapUpdate` statements to its evaluated blocks. While decision bcb mapping will insert `TestVectorBitmapUpdate` in all its end blocks. ### Usage ```bash echo "[build]\nprofiler=true" >> config.toml ./x build --stage 1 ./x test tests/coverage/mcdc_if.rs ``` to build the compiler and run tests. ```shell export PATH=path/to/llvm-build:$PATH rustup toolchain link mcdc build/host/stage1 cargo +mcdc rustc --bin foo -- -Cinstrument-coverage -Zcoverage-options=mcdc cd target/debug LLVM_PROFILE_FILE="foo.profraw" ./foo llvm-profdata merge -sparse foo.profraw -o foo.profdata llvm-cov show ./foo -instr-profile=foo.profdata --show-mcdc ``` to check "foo" code. ### Problems to solve For now decision mapping will insert statements to its all end blocks, which may be optimized by inserting a final block of the decision. To do this we must also trace the evaluated value at each end of the decision and join them separately. This implementation is not heavily tested so there should be some unrevealed issues. We are going to check our rust products in the next. Please let me know if you had any suggestions or comments.
2024-04-19coverage. Generate Mappings of decisions and conditions for MC/DCzhuyunxing-10/+247
2024-04-18Rollup merge of #124110 - beetrees:neg-f16-f128, r=compiler-errorsJubilee-2/+14
Fix negating `f16` and `f128` constants Make `f16` and `f128` constants respect `neg` in `parse_float_into_scalar`. Tracking issue: #116909 ```@rustbot``` label +F-f16_and_f128
2024-04-18Rollup merge of #124064 - Zalathar:otherwise-block, r=NadrierilMatthias Krüger-3/+3
Move confusing comment about otherwise blocks in `lower_match_tree` This comment was historically inside a block guarded by `if let Some(otherwise_block) = otherwise`. When #120978 made the “otherwise block” non-optional, it also flattened that region of code. Doing so left this comment awkwardly stranded above an unrelated line of code, without its original context. We can restore that context by moving it above the declaration of `otherwise`. r? ``@Nadrieril``
2024-04-18Fix negating `f16` and `f128` constantsbeetrees-2/+14
2024-04-17Rename `BindingAnnotation` to `BindingMode`Jules Bertholet-14/+9
2024-04-17Move confusing comment about otherwise blocks in `lower_match_tree`Zalathar-3/+3
This comment was historically inside a block guarded by `if let Some(otherwise_block) = otherwise`. When #120978 made the otherwise block non-optional, it also flattened that region of code. Doing so left this comment awkwardly stranded above an unrelated line of code, without its original context. We can restore that context by moving it above the declaration of `otherwise`.
2024-04-16Avoid lots of `hir::HirId{,Map,Set}` qualifiers.Nicholas Nethercote-5/+5
Because they're a bit redundant.
2024-04-15Remove TypeVariableOriginKindMichael Goulet-5/+4
2024-04-04Rollup merge of #123324 - Nadrieril:false-edges2, r=matthewjasperMatthias Krüger-12/+94
match lowering: make false edges more precise When lowering match expressions, we add false edges to hide details of the lowering from borrowck. Morally we pretend we're testing the patterns (and guards) one after the other in order. See the tests for examples. Problem is, the way we implement this today is too coarse for deref patterns. In deref patterns, a pattern like `deref [1, x]` matches on a `Vec` by creating a temporary to store the output of the call to `deref()` and then uses that to continue matching. Here the pattern has a binding, which we set up after the pre-binding block. Problem is, currently the false edges tell borrowck that the pre-binding block can be reached from a previous arm as well, so the `deref()` temporary may not be initialized. This triggers an error when we try to use the binding `x`. We could call `deref()` a second time, but this opens the door to soundness issues if the deref impl is weird. Instead in this PR I rework false edges a little bit. What we need from false edges is a (fake) path from each candidate to the next, specifically from candidate C's pre-binding block to next candidate D's pre-binding block. Today, we link the pre-binding blocks directly. In this PR, I link them indirectly by choosing an earlier node on D's success path. Specifically, I choose the earliest block on D's success path that doesn't make a loop (if I chose e.g. the start block of the whole match (which is on the success path of all candidates), that would make a loop). This turns out to be rather straightforward to implement. r? `@matthewjasper` if you have the bandwidth, otherwise let me know
2024-04-03More precise false edgesNadrieril-10/+50
2024-04-03Explain false edges in more detailNadrieril-3/+45
2024-04-03rustc_index: Add a `ZERO` constant to index typesVadim Petrochenkov-3/+3
It is commonly used.
2024-04-03Remove MIR unsafe checkMatthew Jasper-114/+25
This also remove safety information from MIR.
2024-04-01Auto merge of #122046 - Nadrieril:integrate-or-pats2, r=matthewjasperbors-65/+38
match lowering: handle or-patterns one layer at a time `create_or_subcandidates` and `merge_trivial_subcandidates` both call themselves recursively to handle nested or-patterns, which is hard to follow. In this PR I avoid the need for that; we now process a single "layer" of or-patterns at a time. By calling back into `match_candidates`, we only need to expand one layer at a time. Conversely, since we always try to simplify a layer that we just expanded (thanks to https://github.com/rust-lang/rust/pull/123067), we only have to merge one layer at a time. r? `@matthewjasper`
2024-03-30Sort `Eq` candidates in the failure case tooNadrieril-6/+8
2024-03-29Rollup merge of #123188 - klensy:clippy-me2, r=NilstriebMatthias Krüger-4/+1
compiler: fix few unused_peekable and needless_pass_by_ref_mut clippy lints This fixes few instances of `unused_peekable` and `needless_pass_by_ref_mut`. While i expected to fix more warnings, `needless_pass_by_ref_mut` produced too much for one PR, so i stopped here. Better reviewed commit by commit, as fixes splitted by chunks.
2024-03-28and moreklensy-4/+1
warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_mir_transform\src\coroutine.rs:1229:11 | 1229 | body: &mut Body<'tcx>, | ^^^^^^^^^^^^^^^ help: consider changing to: `&Body<'tcx>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_mir_transform\src\nrvo.rs:123:11 | 123 | body: &mut mir::Body<'_>, | ^^^^^^^^^^^^^^^^^^ help: consider changing to: `&mir::Body<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_mir_transform\src\nrvo.rs:87:34 | 87 | fn local_eligible_for_nrvo(body: &mut mir::Body<'_>) -> Option<Local> { | ^^^^^^^^^^^^^^^^^^ help: consider changing to: `&mir::Body<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
2024-03-27Use `create_or_subcandidates` for all or-pattern expansionsNadrieril-46/+37
2024-03-27Avoid recursion in creating and merging or-patternsNadrieril-21/+3
By calling back into `match_candidates`, we only need to expand one layer at a time. Conversely, since we always try to simplify a layer that we just expanded, we only have to merge one layer at a time.
2024-03-27Implement `mut ref`/`mut ref mut`Jules Bertholet-58/+47
2024-03-27Rollup merge of #122439 - Nadrieril:store-built-place, r=compiler-errorsMatthias Krüger-36/+42
match lowering: build the `Place` instead of keeping a `PlaceBuilder` around Outside of `MatchPair::new` we don't construct new places, so we don't need to keep a `PlaceBuilder` around. A bit annoyingly we have to store an `Option<Place>` even though it's never `None` after simplification, but the alternative would be to re-entangle `MatchPair` construction and simplification and I'd rather not do that.