Previously, this code treated enum fields' visibility as if they were
struct fields. However, that's not correct because the visibility of a
struct field with `ast::VisibilityKind::Inherited` is private to the
module it's defined in, whereas the visibility of an *enum* field with
`ast::VisibilityKind::Inherited` is the visibility of the enum it
belongs to.
If we try to capture the `Vec<u8>` in `Option<Vec<u8>>`, we'll
need to capture a `>` token which was 'unglued' from a `>>` token.
The processing of unglueing a token for parsing purposes bypasses the
usual capturing infrastructure, so we currently lose the trailing `>`.
As a result, we fall back to the reparsed `TokenStream`, causing us to
lose spans.
This commit makes token capturing keep track of a trailing 'unglued'
token. Note that we don't need to care about unglueing except at the end
of the captured tokens - if we capture both the first and second unglued
tokens, then we'll end up capturing the full 'glued' token, which
already works correctly.
Create `rustc_type_ir`
Decided to start small 😄
This PR creates a `rustc_type_ir` crate as part of the WG-Traits plan to create a shared type library.
~~There already exists a `rustc_ty` crate, so I named the new crate `rustc_ty_library`. However I think it would make sense to rename the current `rustc_ty` to something else (e.g. `rustc_ty_passes`) to free the name for this new crate.~~
r? `@jackh726`
Fixes: #79569Fixes: #79566Fixes: #79565
For the first issue (#79569), I got hit a `debug_assert!()` before
encountering the reported error message (because I have `debug = true`
enabled in my config.toml).
The assertion showed me that some `SwitchInt`s can have more than one
target pointing to the same `BasicBlock`.
I had thought that was invalid, but since it seems to be possible, I'm
allowing this now.
I added a new test for this.
----
In the last two cases above, both tests (intentionally) fail to compile,
but the `InstrumentCoverage` pass is invoked anyway.
The MIR starts with an `Unreachable` `BasicBlock`, which I hadn't
encountered before. (I had assumed the `InstrumentCoverage` pass
would only be invoked with MIRs from successful compilations.)
I don't have test infrastructure set up to test coverage on files that
fail to compile, so I didn't add a new test.
Capture precise paths in THIR and MIR
This PR allows THIR and MIR to use the result of the new capture analysis to actually capture precise paths
To achieve we:
- Writeback min capture results to TypeckResults
- Move handling upvars to PlaceBuilder in mir_build
- Lower precise paths in THIR build by reading min_captures
- Search for ancestors in min_capture when trying to build a MIR place which starts off of an upvar
Closes: https://github.com/rust-lang/project-rfc-2229/issues/10
Partly implements: rust-lang/project-rfc-2229#18
Work that remains (not in this PR):
- [ ] [Known bugs when feature gate is enabled](https://github.com/rust-lang/project-rfc-2229/projects/1?card_filter_query=label%3Abug)
- [ ] Use min_capure_map for
- [ ] Liveness analysis
- [ ] rustc_mir/interpret/validity.rs
- [ ] regionck
- [ ] rust-lang/project-rfc-2229#8
- [ ] remove closure_captures and upvar_capture_map
r? `@ghost`
CTFE: tweak abort-on-uninhabited message
Having an "aborted execution:" makes it more consistent with the `Abort` terminator saying "the program aborted execution". Right now, at least one of the two errors will look weird in Miri.
r? `@oli-obk`
Use `def_path_hash_to_def_id` when re-using a `RawDefId`
Fixes#79890
Previously, we just copied a `RawDefId` from the 'old' map to the 'new'
map. However, the `RawDefId` for a given `DefPathHash` may be different
in the current compilation session. Using `def_path_hash_to_def_id`
ensures that the `RawDefId` we use is valid in the current session.
Use Symbol for inline asm register class names
This takes care of one "FIXME":
// FIXME: use direct symbol comparison for register class names
Instead of using string literals, this uses Symbol for register
class names.
This is part of work I am doing to improve how Symbol interning works.
Clarify the 'default is only allowed on...' error
Code like
impl Foo {
default fn foo() {}
}
will trigger the error
error: `default` is only allowed on items in `impl` definitions
--> src/lib.rs:5:5
|
5 | default fn foo() {}
| -------^^^^^^^^^
| |
| `default` because of this
but that's very confusing! I *did* put it on an item in an impl!
So this commit changes the message to
error: `default` is only allowed on items in trait impls
--> src/lib.rs:5:5
|
5 | default fn foo() {}
| -------^^^^^^^^^
| |
| `default` because of this
Dogfood `str_split_once()`
Part of https://github.com/rust-lang/rust/issues/74773.
Beyond increased clarity, this fixes some instances of a common confusion with how `splitn(2)` behaves: the first element will always be `Some()`, regardless of the delimiter, and even if the value is empty.
Given this code:
```rust
fn main() {
let val = "...";
let mut iter = val.splitn(2, '=');
println!("Input: {:?}, first: {:?}, second: {:?}", val, iter.next(), iter.next());
}
```
We get:
```
Input: "no_delimiter", first: Some("no_delimiter"), second: None
Input: "k=v", first: Some("k"), second: Some("v")
Input: "=", first: Some(""), second: Some("")
```
Using `str_split_once()` makes more clear what happens when the delimiter is not found.
This takes care of one "FIXME":
// FIXME: use direct symbol comparison for register class names
Instead of using string literals, this uses Symbol for register
class names.
Fixes#79890
Previously, we just copied a `RawDefId` from the 'old' map to the 'new'
map. However, the `RawDefId` for a given `DefPathHash` may be different
in the current compilation session. Using `def_path_hash_to_def_id`
ensures that the `RawDefId` we use is valid in the current session.
rustc_codegen_ssa: use bitcasts instead of type punning for scalar transmutes.
This specifically helps with `f32` <-> `u32` (`from_bits`, `to_bits`) in Rust-GPU (`rustc_codegen_spirv`), where (AFAIK) we don't yet have enough infrastructure to turn type punning memory accesses into SSA bitcasts.
(There may be more instances, but the one I've seen myself is `f32::signum` from `num-traits` inspecting e.g. the sign bit)
Sadly I've had to make an exception for `transmute`s between pointers and non-pointers, as LLVM disallows using `bitcast` for them.
r? `@nagisa` cc `@khyperia`
Constier maybe uninit
I was playing around trying to make `[T; N]::zip()` in #79451 be `const fn`. One of the things I bumped into was `MaybeUninit::assume_init`. Is there any reason for the intrinsic `assert_inhabited<T>()` and therefore `MaybeUninit::assume_init` not being `const`?
---
I have as best as I could tried to follow the instruction in [library/core/src/intrinsics.rs](https://github.com/rust-lang/rust/blob/master/library/core/src/intrinsics.rs#L11). I have no idea what I am doing but it seems to compile after some slight changes after the copy paste. Is this anywhere near how this should be done?
Also any ideas for name of the feature gate? I guess `const_maybe_assume_init` is quite misleading since I have added some more methods. Should I add test? If so what should be tested?
- Closures now use closure_min_captures to figure out captured paths
- Build upvar_mutbls using closure_min_captures
- Change logic in limit_capture_mutability to differentiate b/w
capturing parent's local variable or capturing a variable that is
captured by the parent (in case of nested closure) using PlaceBase.
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
- Use closure_min_capture maps to capture precise paths
- PlaceBuilder now searches for ancestors in min_capture list
- Add API to `Ty` to allow access to the n-th element in a
tuple in O(1) time.
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
Rollup of 12 pull requests
Successful merges:
- #79732 (minor stylistic clippy cleanups)
- #79750 (Fix trimming of lint docs)
- #79777 (Remove `first_merge` from liveness debug logs)
- #79795 (Privatize some of libcore unicode_internals)
- #79803 (Update xsv to prevent random CI failures)
- #79810 (Account for gaps in def path table during decoding)
- #79818 (Fixes to Rust coverage)
- #79824 (Strip prefix instead of replacing it with empty string)
- #79826 (Simplify visit_{foreign,trait}_item)
- #79844 (Move RWUTable to a separate module)
- #79861 (Update LLVM submodule)
- #79862 (Remove tab-lock and replace it with ctrl+up/down arrows to switch between search result tabs)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Simplify visit_{foreign,trait}_item
Using an `if` seems like a better semantic fit and saves a few lines.
Noticed while looking at https://github.com/rust-lang/rust/pull/79752, but that's already merged.
r? `@lcnr,` cc `@cjgillot`
`@rustbot` modify labels +C-cleanup +T-compiler
Strip prefix instead of replacing it with empty string
r? `@lcnr,` since you reviewed my other PR in the area.
`@rustbot` modify labels +C-cleanup +T-compiler
Fixes to Rust coverage
Fixes: #79725
Some macros can create a situation where `fn_sig_span` and `body_span`
map to different files.
New documentation on coverage tests incorrectly assumed multiple test
binaries could just be listed at the end of the `llvm-cov` command,
but it turns out each binary needs a `--object` prefix.
This PR fixes the bug and updates the documentation to correct that
issue. It also fixes a few other minor issues in internal implementation
comments, and adds documentation on getting coverage results for doc
tests.
Account for gaps in def path table during decoding
When encoding a proc-macro crate, there may be gaps in the table (since
we only encode the crate root and proc-macro items). Account for this by
checking if the entry is present, rather than using `unwrap()`
minor stylistic clippy cleanups
simplify if let Some(_) = x to if x.is_some() (clippy::redundant_pattern_matching)
don't create owned values for comparison (clippy::cmp_owned)
use .contains() or .any() instead of find(x).is_some() (clippy::search_is_some)
don't wrap code block in Ok() (clipppy::unit_arg)
Properly re-use def path hash in incremental mode
Fixes#79661
In incremental compilation mode, we update a `DefPathHash -> DefId`
mapping every time we create a `DepNode` for a foreign `DefId`.
This mapping is written out to the on-disk incremental cache, and is
read by the next compilation session to allow us to lazily decode
`DefId`s.
When we decode a `DepNode` from the current incremental cache, we need
to ensure that any previously-recorded `DefPathHash -> DefId` mapping
gets recorded in the new mapping that we write out. However, PR #74967
didn't do this in all cases, leading to us being unable to decode a
`DefPathHash` in certain circumstances.
This PR refactors some of the code around `DepNode` deserialization to
prevent this kind of mistake from happening again.
Also generate `StorageDead` in constants
r? `@eddyb`
None of this special casing is actually necessary since we started promoting within constants and statics.
We may want to keep some of it around out of perf reasons, but it's not required for user visible behaviour
somewhat related: #68622
remove this weird special case from promotion
Promotion has a special case to ignore interior mutability under some specific circumstances. The purpose of this PR is to figure out what changes if we remove that. Since `Cell::new` and friends only get promoted inside `const`/`static` initializers these days, it actually is not easy to exploit this case: you need something like
```rust
const TEST_INTERIOR_MUT: () = {
// The "0." case is already ruled out by not permitting any interior mutability in `const`.
let _val: &'static _ = &(Cell::new(1), 2).1;
};
```
I assume something like `&Some(&(Cell::new(1), 2).1)` would hit the nested case inside `validate_rvalue`... though I am not sure why that would not just trigger nested promotion, first promoting the inner reference and then the outer one?
Fixes https://github.com/rust-lang/rust/issues/67534 (by simply rejecting that code^^)
r? `@oli-obk` (but for now this is not meant to be merged!)
Cc `@rust-lang/wg-const-eval`
Code like
impl Foo {
default fn foo() {}
}
will trigger the error
error: `default` is only allowed on items in `impl` definitions
--> src/lib.rs:5:5
|
5 | default fn foo() {}
| -------^^^^^^^^^
| |
| `default` because of this
but that's very confusing! I *did* put it on an item in an impl!
So this commit changes the message to
error: `default` is only allowed on items in trait impls
--> src/lib.rs:5:5
|
5 | default fn foo() {}
| -------^^^^^^^^^
| |
| `default` because of this
Compress RWU from at least 32 bits to 4 bits
The liveness uses a mixed representation of RWUs based on the
observation that most of them have invalid reader and invalid
writer. The packed variant uses 32 bits and unpacked 96 bits.
Unpacked data contains reader live node and writer live node.
Since live nodes are used only to determine their validity,
RWUs can always be stored in a packed form with four bits for
each: reader bit, writer bit, used bit, and one extra padding
bit to simplify packing and unpacking operations.
When encoding a proc-macro crate, there may be gaps in the table (since
we only encode the crate root and proc-macro items). Account for this by
checking if the entry is present, rather than using `unwrap()`
Replace simple `if let` constructs with Option::map
Replaces a few constructs of the form
```
if let Some(x) = var {
Some(...)
} else {
None
}
```
with calls to `Option::map`.
`@rustbot` modify labels +C-cleanup +T-compiler
Fixes: #79725
Some macros can create a situation where `fn_sig_span` and `body_span`
map to different files.
New documentation on coverage tests incorrectly assumed multiple test
binaries could just be listed at the end of the `llvm-cov` command,
but it turns out each binary needs a `--object` prefix.
This PR fixes the bug and updates the documentation to correct that
issue. It also fixes a few other minor issues in internal implementation
comments, and adds documentation on getting coverage results for doc
tests.
Validate naked functions definitions
Validate that naked functions are defined in terms of a single inline assembly
block that uses only `const` and `sym` operands and has `noreturn` option.
Implemented as future incompatibility lint with intention to migrate it into
hard error. When it becomes a hard error it will ensure that naked functions are
either unsafe or contain an unsafe block around the inline assembly. It will
guarantee that naked functions do not reference functions parameters (obsoleting
part of existing checks from #79411). It will limit the definitions of naked
functions to what can be reliably supported. It will also reject naked functions
implemented using legacy LLVM style assembly since it cannot satisfy those
conditions.
https://github.com/rust-lang/rfcs/pull/2774https://github.com/rust-lang/rfcs/pull/2972
Prior to this commit, debuginfo was always generated by mapping a name
to a Place. This has the side-effect that `SimplifyLocals` cannot remove
locals that are only used for debuginfo because their other uses have
been const-propagated.
To allow these locals to be removed, we now allow debuginfo to point to
a constant value. The `ConstProp` pass detects when debuginfo points to
a local with a known constant value and replaces it with the value. This
allows the later `SimplifyLocals` pass to remove the local.
- This allows us to delay figuring out the index of a capture
in the closure structure when all projections to atleast form
a capture have been applied to the builder
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
- Derive TypeFoldable on `hir::place::Place` and associated
structs, to them to be written into typeck results.
Co-authored-by: Jennifer Wills <wills.jenniferg@gmail.com>
Co-authored-by: Logan Mosier <logmosier@gmail.com>
extend `WithOptConstParam` docs, move rustdoc test
This should hopefully make things a bit clearer, feel free to comment on anything which can still be improved.
cc `@ecstatic-morse` `@nikomatsakis` `@RalfJung`
Const parameters can not be inferred with `_` help note
This should close: #79557
# Example output
```
error[E0747]: type provided when a constant was expected
--> inferred_const_note.rs:6:19
|
6 | let a = foo::<_, 2>([0, 1, 2]);
| ^
|
= help: Const parameters can not be inferred with `_`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0747`.
```
r? `@lcnr`