This matches the behavior of Clang and allows us to remove several
hacks which were needed to ensure functions weren't optimized away
before reaching the instrumentation pass.
Refactor rustc_resolve::late::lifetimes to resolve per-item
There are some changes to tests that I'd like some feedback on; so this is still WIP.
The reason behind this change will (hopefully) allow us to (as part of #76814) be able to essentially use the lifetime resolve code to resolve *all* late bound vars (including those of super traits). Currently, it only resolves those that are *syntactically* in scope. In #76814, I'm essentially finding that I would essentially have to redo the passing of bound vars through scopes (i.e. when instantiating a poly trait ref), and that's what this code does anyways. However, to be able to do this (ask super traits what bound vars are in scope), we have to be able to resolve items separately.
The first commit is actually partially orthogonal. Essentially removing one use of late bound debruijn indices.
Not exactly sure who would be best to review here.
Let r? `@nikomatsakis`
GenericParam does not need to be a HIR owner.
The special case is not required.
Universal impl traits design to regular generic parameters, and their content is owned by the enclosing item.
Existential (and opaque) impl traits generate their own enclosing item, and are collected through it.
coverage bug fixes and optimization support
Adjusted LLVM codegen for code compiled with `-Zinstrument-coverage` to
address multiple, somewhat related issues.
Fixed a significant flaw in prior coverage solution: Every counter
generated a new counter variable, but there should have only been one
counter variable per function. This appears to have bloated .profraw
files significantly. (For a small program, it increased the size by
about 40%. I have not tested large programs, but there is anecdotal
evidence that profraw files were way too large. This is a good fix,
regardless, but hopefully it also addresses related issues.
Fixes: #82144
Invalid LLVM coverage data produced when compiled with -C opt-level=1
Existing tests now work up to at least `opt-level=3`. This required a
detailed analysis of the LLVM IR, comparisons with Clang C++ LLVM IR
when compiled with coverage, and a lot of trial and error with codegen
adjustments.
The biggest hurdle was figuring out how to continue to support coverage
results for unused functions and generics. Rust's coverage results have
three advantages over Clang's coverage results:
1. Rust's coverage map does not include any overlapping code regions,
making coverage counting unambiguous.
2. Rust generates coverage results (showing zero counts) for all unused
functions, including generics. (Clang does not generate coverage for
uninstantiated template functions.)
3. Rust's unused functions produce minimal stubbed functions in LLVM IR,
sufficient for including in the coverage results; while Clang must
generate the complete LLVM IR for each unused function, even though
it will never be called.
This PR removes the previous hack of attempting to inject coverage into
some other existing function instance, and generates dedicated instances
for each unused function. This change, and a few other adjustments
(similar to what is required for `-C link-dead-code`, but with lower
impact), makes it possible to support LLVM optimizations.
Fixes: #79651
Coverage report: "Unexecuted instantiation:..." for a generic function
from multiple crates
Fixed by removing the aforementioned hack. Some "Unexecuted
instantiation" notices are unavoidable, as explained in the
`used_crate.rs` test, but `-Zinstrument-coverage` has new options to
back off support for either unused generics, or all unused functions,
which avoids the notice, at the cost of less coverage of unused
functions.
Fixes: #82875
Invalid LLVM coverage data produced with crate brotli_decompressor
Fixed by disabling the LLVM function attribute that forces inlining, if
`-Z instrument-coverage` is enabled. This attribute is applied to
Rust functions with `#[inline(always)], and in some cases, the forced
inlining breaks coverage instrumentation and reports.
FYI: `@wesleywiser`
r? `@tmandry`
This currently creates a field which is always false on GenericParamDefKind for future use when
consts are permitted to have defaults
Update const_generics:default locations
Previously just ignored them, now actually do something about them.
Fix using type check instead of value
Add parsing
This adds all the necessary changes to lower const-generics defaults from parsing.
Change P<Expr> to AnonConst
This matches the arguments passed to instantiations of const generics, and makes it specific to
just anonymous constants.
Attempt to fix lowering bugs
This saves us both the Freeze/Unpin queries, and avoids placing
noalias attributes, which have a compile-time impact on LLVM
even in optnone builds (due to always_inline functions).
Such structures may contain self-references, in which case the
same location may be accessible through a pointer that is not
based-on the noalias pointer.
This is still grey area as far as language semantics are concerned,
but checking for !Unpin as an indicator for self-referential
sturctures seems like a good approach for the meantime.
The frontend shouldn't be deciding whether or not to use mutable
noalias attributes, as this is a pure LLVM concern. Only provide
the necessary information and do the actual decision in
codegen_llvm.
const_evaluatable_checked: Stop eagerly erroring in `is_const_evaluatable`
Fixes#82279
We don't want to be emitting errors inside of is_const_evaluatable because we may call this during selection where it should be able to fail silently
There were two errors being emitted in `is_const_evaluatable`. The one causing the compile error in #82279 was inside the match arm for `FailureKind::MentionsParam` but I moved the other error being emitted too since it made things cleaner imo
The `NotConstEvaluatable` enum \*should\* have a fourth variant for when we fail to evaluate a concrete const, e.g. `0 - 1` but that cant happen until #81339
cc `@oli-obk` `@lcnr`
r? `@nikomatsakis`
Adjusted LLVM codegen for code compiled with `-Zinstrument-coverage` to
address multiple, somewhat related issues.
Fixed a significant flaw in prior coverage solution: Every counter
generated a new counter variable, but there should have only been one
counter variable per function. This appears to have bloated .profraw
files significantly. (For a small program, it increased the size by
about 40%. I have not tested large programs, but there is anecdotal
evidence that profraw files were way too large. This is a good fix,
regardless, but hopefully it also addresses related issues.
Fixes: #82144
Invalid LLVM coverage data produced when compiled with -C opt-level=1
Existing tests now work up to at least `opt-level=3`. This required a
detailed analysis of the LLVM IR, comparisons with Clang C++ LLVM IR
when compiled with coverage, and a lot of trial and error with codegen
adjustments.
The biggest hurdle was figuring out how to continue to support coverage
results for unused functions and generics. Rust's coverage results have
three advantages over Clang's coverage results:
1. Rust's coverage map does not include any overlapping code regions,
making coverage counting unambiguous.
2. Rust generates coverage results (showing zero counts) for all unused
functions, including generics. (Clang does not generate coverage for
uninstantiated template functions.)
3. Rust's unused functions produce minimal stubbed functions in LLVM IR,
sufficient for including in the coverage results; while Clang must
generate the complete LLVM IR for each unused function, even though
it will never be called.
This PR removes the previous hack of attempting to inject coverage into
some other existing function instance, and generates dedicated instances
for each unused function. This change, and a few other adjustments
(similar to what is required for `-C link-dead-code`, but with lower
impact), makes it possible to support LLVM optimizations.
Fixes: #79651
Coverage report: "Unexecuted instantiation:..." for a generic function
from multiple crates
Fixed by removing the aforementioned hack. Some "Unexecuted
instantiation" notices are unavoidable, as explained in the
`used_crate.rs` test, but `-Zinstrument-coverage` has new options to
back off support for either unused generics, or all unused functions,
which avoids the notice, at the cost of less coverage of unused
functions.
Fixes: #82875
Invalid LLVM coverage data produced with crate brotli_decompressor
Fixed by disabling the LLVM function attribute that forces inlining, if
`-Z instrument-coverage` is enabled. This attribute is applied to
Rust functions with `#[inline(always)], and in some cases, the forced
inlining breaks coverage instrumentation and reports.
Replace closures_captures and upvar_capture with closure_min_captures
Removed all uses of closures_captures and upvar_capture and refactored code to work with closure_min_captures. This also involved removing functions that were no longer needed like the bridge.
Closes https://github.com/rust-lang/project-rfc-2229/issues/18
r? `@nikomatsakis`
make changes to liveness to use closure_min_captures
use different span
borrow check uses new structures
rename to CapturedPlace
stop using upvar_capture in regionck
remove the bridge
cleanup from rebase + remove the upvar_capture reference from mutability_errors.rs
remove line from livenes test
make our unused var checking more consistent
update tests
adding more warnings to the tests
move is_ancestor_or_same_capture to rustc_middle/ty
update names to reflect the closures
add FIXME
check that all captures are immutable borrows before returning
add surrounding if statement like the original
move var out of the loop and rename
Co-authored-by: Logan Mosier <logmosier@gmail.com>
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
Make source-based code coverage compatible with MIR inlining
When codegenning code coverage use the instance that coverage data was
originally generated for, to ensure basic level of compatibility with
MIR inlining.
Fixes#83061
ast/hir: Rename field-related structures
I always forget what `ast::Field` and `ast::StructField` mean despite working with AST for long time, so this PR changes the naming to less confusing and more consistent.
- `StructField` -> `FieldDef` ("field definition")
- `Field` -> `ExprField` ("expression field", not "field expression")
- `FieldPat` -> `PatField` ("pattern field", not "field pattern")
Various visiting and other methods working with the fields are renamed correspondingly too.
The second commit reduces the size of `ExprKind` by boxing fields of `ExprKind::Struct` in preparation for https://github.com/rust-lang/rust/pull/80080.
Do not insert impl_trait_in_bindings opaque definitions twice.
The reference to the item already appears inside the `OpaqueDef`. It does not need to be repeated as a statement.
Implement (but don't use) valtree and refactor in preparation of use
This PR does not cause any functional change. It refactors various things that are needed to make valtrees possible. This refactoring got big enough that I decided I'd want it reviewed as a PR instead of trying to make one huge PR with all the changes.
cc `@rust-lang/wg-const-eval` on the following commits:
* 2027184 implement valtree
* eeecea9 fallible Scalar -> ScalarInt
* 042f663 ScalarInt convenience methods
cc `@eddyb` on ef04a6d
cc `@rust-lang/wg-mir-opt` for cf1700c (`mir::Constant` can now represent either a `ConstValue` or a `ty::Const`, and it is totally possible to have two different representations for the same value)
2229: Handle patterns within closures correctly when `capture_disjoint_fields` is enabled
This PR fixes several issues related to handling patterns within closures when `capture_disjoint_fields` is enabled.
1. Matching is always considered a use of the place, even with `_` patterns
2. Compiler ICE when capturing fields in closures through `let` assignments
To do so, we
- Introduced new Fake Reads
- Delayed use of `Place` in favor of `PlaceBuilder`
- Ensured that `PlaceBuilder` can be resolved before attempting to extract `Place` in any of the pattern matching code
Closes rust-lang/project-rfc-2229/issues/27
Closes rust-lang/project-rfc-2229/issues/24
r? `@nikomatsakis`
StructField -> FieldDef ("field definition")
Field -> ExprField ("expression field", not "field expression")
FieldPat -> PatField ("pattern field", not "field pattern")
Also rename visiting and other methods working on them.
83054 introduced validation of scalar range attributes, but panicking
code that uses the attribute remained reachable. Use `delay_span_bug`
instead to avoid the ICE.