Introduce `~const`
- [x] Removed `?const` and change uses of `?const`
- [x] Added `~const` to the AST. It is gated behind const_trait_impl.
- [x] Validate `~const` in ast_validation.
- [x] Update UI Tests
- [x] Add enum `BoundConstness` (With variants `NotConst` and
`ConstIfConst` allowing future extensions)
- [x] Adjust trait selection and pre-existing code to use `BoundConstness`.
- [ ] Optional steps for this PR
- [x] Fix#88155
- [x] ~~Do something with constness bounds in chalk~~ Must be done to rust-lang/chalk (just tried to refactor, there are a lot of errors to resolve :( )
- [ ] Adjust Error messages for `~const` bounds that can't be satisfied.
r? `@oli-obk`
`#[inline]` non-generic `pub fn`s in `rustc_target::abi` and `ty::layout`.
Mostly doing this as a perf curiosity, having spotted that `#[inline]` usage is a bit spotty.
- [x] Removed `?const` and change uses of `?const`
- [x] Added `~const` to the AST. It is gated behind const_trait_impl.
- [x] Validate `~const` in ast_validation.
- [ ] Add enum `BoundConstness` to the HIR. (With variants `NotConst` and
`ConstIfConst` allowing future extensions)
- [ ] Adjust trait selection and pre-existing code to use `BoundConstness`.
- [ ] Optional steps (*for this PR, obviously*)
- [ ] Fix#88155
- [ ] Do something with constness bounds in chalk
lazily "compute" anon const default substs
Continuing the work of #83086, this implements the discussed solution for the [unused substs problem](https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs). As of now, anonymous constants inherit all of their parents generics, even if they do not use them, e.g. in `fn foo<T, const N: usize>() -> [T; N + 1]`, the array length has `T` as a generic parameter even though it doesn't use it. These *unused substs* cause some backwards incompatible, and imo incorrect behavior, e.g. #78369.
---
We do not actually filter any generic parameters here and the `default_anon_const_substs` query still a dummy which only checks that
- we now prevent the previously existing query cycles and are able to call `predicates_of(parent)` when computing the substs of anonymous constants
- the default anon consts substs only include the typeflags we assume it does.
Implementing that filtering will be left as future work.
---
The idea of this PR is to delay the creation of the anon const substs until after we've computed `predicates_of` for the parent of the anon const. As the predicates of the parent can however contain the anon const we still have to create a `ty::Const` for it.
We do this by changing the substs field of `ty::Unevaluated` to an option and modifying accesses to instead call the method `unevaluated.substs(tcx)` which returns the substs as before. If the substs - now `substs_` - of `ty::Unevaluated` are `None`, it means that the anon const currently has its default substs, i.e. the substs it has when first constructed, which are the generic parameters it has available. To be able to call `unevaluated.substs(tcx)` in a `TypeVisitor`, we add the non-defaulted method `fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>>`. In case `tcx_for_anon_const_substs` returns `None`, unknown anon const default substs are skipped entirely.
Even when `substs_` is `None` we still have to treat the constant as if it has its default substs. To do this, `TypeFlags` are modified so that it is clear whether they can still change when *exposing* any anon const default substs. A new flag, `HAS_UNKNOWN_DEFAULT_CONST_SUBSTS`, is added in case some default flags are missing.
The rest of this PR are some smaller changes to either not cause cycles by trying to access the default anon const substs too early or to be able to access the `tcx` in previously unused locations.
cc `@rust-lang/project-const-generics`
r? `@nikomatsakis`
Morph `layout_raw` query into `layout_of`.
Before this PR, `LayoutCx::layout_of` wrapped the `layout_raw` query, to:
* normalize the type, before attempting to compute the layout
* pass the layout to `record_layout_for_printing`, for `-Zprint-type-sizes`
Moving those two responsibilities into the query may reduce overhead (due to cached calls skipping those steps), but I want to do a perf run to know.
One of the changes I had to make was changing the return type of the query, to be able to both get out the type produced by normalizing inside the query *and* to match the signature of the old `TyCtxt::layout_of`. This change may be worse, perf-wise, so that's another reason I want to check.
r? `@nagisa` cc `@oli-obk`
Use undef for uninitialized bytes in constants
Fixes#83657
This generates good code when the const is fully uninit, e.g.
```rust
#[no_mangle]
pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> {
const M: MaybeUninit<[u8; 10]> = MaybeUninit::uninit();
M
}
```
generates
```asm
fully_uninit:
ret
```
as you would expect.
There is no improvement, however, when it's partially uninit, e.g.
```rust
pub struct PartiallyUninit {
x: u64,
y: MaybeUninit<[u8; 10]>
}
#[no_mangle]
pub const fn partially_uninit() -> PartiallyUninit {
const X: PartiallyUninit = PartiallyUninit { x: 0xdeadbeefcafe, y: MaybeUninit::uninit() };
X
}
```
generates
```asm
partially_uninit:
mov rax, rdi
mov rcx, qword ptr [rip + .L__unnamed_1+16]
mov qword ptr [rdi + 16], rcx
movups xmm0, xmmword ptr [rip + .L__unnamed_1]
movups xmmword ptr [rdi], xmm0
ret
.L__unnamed_1:
.asciz "\376\312\357\276\255\336\000"
.zero 16
.size .L__unnamed_1, 24
```
which copies a bunch of zeros in place of the undef bytes, the same as before this change.
Edit: generating partially-undef constants isn't viable at the moment anyways due to #84565, so it's disabled
Use if-let guards in the codebase and various other pattern cleanups
Dogfooding if-let guards as experimentation for the feature.
Tracking issue #51114. Conflicts with #87937.
Normalize projections under binders
Fixes#70243Fixes#70120Fixes#62529Fixes#87219
Issues to followup on after (probably fixed, but no test added here):
#76956#56556#79207#85636
r? `@nikomatsakis`
Use custom wrap-around type instead of RangeInclusive
Two reasons:
1. More memory is allocated than necessary for `valid_range` in `Scalar`. The range is not used as an iterator and `exhausted` is never used.
2. `contains`, `count` etc. methods in `RangeInclusive` are doing very unhelpful(and dangerous!) things when used as a wrap-around range. - In general this PR wants to limit potentially confusing methods, that have a low probability of working.
Doing a local perf run, every metric shows improvement except for instructions.
Max-rss seem to have a very consistent improvement.
Sorry - newbie here, probably doing something wrong.
Remove `Session.used_attrs` and move logic to `CheckAttrVisitor`
Instead of updating global state to mark attributes as used,
we now explicitly emit a warning when an attribute is used in
an unsupported position. As a side effect, we are to emit more
detailed warning messages (instead of just a generic "unused" message).
`Session.check_name` is removed, since its only purpose was to mark
the attribute as used. All of the callers are modified to use
`Attribute.has_name`
Additionally, `AttributeType::AssumedUsed` is removed - an 'assumed
used' attribute is implemented by simply not performing any checks
in `CheckAttrVisitor` for a particular attribute.
We no longer emit unused attribute warnings for the `#[rustc_dummy]`
attribute - it's an internal attribute used for tests, so it doesn't
mark sense to treat it as 'unused'.
With this commit, a large source of global untracked state is removed.
Trait upcasting coercion (part 3)
By using separate candidates for each possible choice, this fixes type-checking issues in previous commits.
r? `@nikomatsakis`
Instead of updating global state to mark attributes as used,
we now explicitly emit a warning when an attribute is used in
an unsupported position. As a side effect, we are to emit more
detailed warning messages (instead of just a generic "unused" message).
`Session.check_name` is removed, since its only purpose was to mark
the attribute as used. All of the callers are modified to use
`Attribute.has_name`
Additionally, `AttributeType::AssumedUsed` is removed - an 'assumed
used' attribute is implemented by simply not performing any checks
in `CheckAttrVisitor` for a particular attribute.
We no longer emit unused attribute warnings for the `#[rustc_dummy]`
attribute - it's an internal attribute used for tests, so it doesn't
mark sense to treat it as 'unused'.
With this commit, a large source of global untracked state is removed.
Refactor fallback code to prepare for never type
This PR contains cherry-picks of some of `@nikomatsakis's` work from #79366, and shouldn't (AFAICT) represent any change in behavior. However, the refactoring is good regardless of the never type work being landed, and will reduce the size of those eventual PR(s) (and rebase pain).
I am not personally an expert on this code, and the commits are essentially 100% `@nikomatsakis's,` but they do seem reasonable to me by my understanding. Happy to edit with review, of course. Commits are best reviewed in sequence rather than all together.
r? `@jackh726` perhaps?
Remove box syntax from compiler and tools
Removes box syntax from the compiler and tools. In #49733, the future of box syntax is uncertain and the use in the compiler was listed as one of the reasons to keep it. Removal of box syntax [might affect the code generated](https://github.com/rust-lang/rust/pull/49646#issuecomment-379219615) and slow down the compiler so I'd recommend doing a perf run on this.
Update `polonius-engine` to 0.13.0
This PR updates the use of `polonius-engine` to the recently released 0.13.0:
- this version renamed a lot of relations to match the current terminology
- "illegal subset relationships errors" (AKA "subset errors" or "universal region errors" in rustc parlance) have been implemented in all variants, and therefore the `Hybrid` variant can be the rustc default once again
- some of the blessed expectations were updated: new tests have been added since the last time I updated the tests, diagnostics have changed, etc.
In particular:
- a few tests had trivial expectations changes such as basic diagnostics changes for the migrate-mode and full NLLs
- others were recursion and lengths limits which emits a file, and under the polonius compare-mode, the folder has a different name
- a few tests were ignored in the NLL compare-mode for reasons that obviously also apply to Polonius
- some diagnostics were unified so that older expectations no longer made sense: the NLL and Polonius outputs were identical.
- in a few cases Polonius gets a chance to emit more errors than NLLs
A few tests in the compare-mode still are super slow and trigger the 60s warning, or OOM rustc during fact generation, and I've detailed these [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/186049-t-compiler.2Fwg-polonius/topic/Challenges.20for.20move.2Finit.2C.20liveness.2C.20and.20.60Location.3A.3AAll.60):
- `src/test/ui/numbers-arithmetic/saturating-float-casts.rs` -> OOM during rustc fact generation
- `src/test/ui/numbers-arithmetic/num-wrapping.rs`
- `src/test/ui/issues/issue-72933-match-stack-overflow.rs`
- `src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs`
- `src/test/ui/repr/repr-no-niche.rs`
In addition, 2 tests don't currently pass and I didn't want to bless them now: they deal with HRTBs and miss errors that NLLs emit. We're currently trying to see if we need chalk to deal with HRTB errors (as we thought we would have to) but during the recent sprint, we discovered that we may be able to detect some of these errors in a way that resembles subset errors:
- `ui/hrtb/hrtb-just-for-static.rs` -> 3 errors in NLL, 2 in polonius: a missing error about HRTB + needing to outlive 'static
- `ui/issues/issue-26217.rs` -> missing HRTB that makes the test compile instead of emitting an error
We'll keep talking about this at the next sprint as well.
cc `@rust-lang/wg-polonius` r? `@nikomatsakis`
Try filtering out non-const impls when we expect const impls
**TL;DR**: Associated types on const impls are now bounded; we now disallow calling a const function with bounds when the specified type param only has a non-const impl.
r? `@oli-obk`
Name the captured upvars for closures/generators in debuginfo
Previously, debuggers print closures as something like
```
y::main::closure-0 (0x7fffffffdd34)
```
The pointer actually references to an upvar. It is not very obvious, especially for beginners.
It's because upvars don't have names before, as they are packed into a tuple. This PR names the upvars, so we can expect to see something like
```
y::main::closure-0 {_captured_ref__b: 0x[...]}
```
r? `@tmandry`
Discussed at https://github.com/rust-lang/rust/pull/84752#issuecomment-831639489 .
Add c_enum_min_bits target spec field, use for arm-none and thumb-none targets
Fixes https://github.com/rust-lang/rust/issues/87917
<s>Haven't tested this yet, still playing around.</s>
This seems to fix the issue.
Hide allocator details from TryReserveError
I think there's [no need for TryReserveError to carry detailed information](https://github.com/rust-lang/rust/issues/48043#issuecomment-825139280), but I wouldn't want that issue to delay stabilization of the `try_reserve` feature.
So I'm proposing to stabilize `try_reserve` with a `TryReserveError` as an opaque structure, and if needed, expose error details later.
This PR moves the `enum` to an unstable inner `TryReserveErrorKind` that lives under a separate feature flag. `TryReserveErrorKind` could possibly be left as an implementation detail forever, and the `TryReserveError` get methods such as `allocation_size() -> Option<usize>` or `layout() -> Option<Layout>` instead, or the details could be dropped completely to make try-reserve errors just a unit struct, and thus smaller and cheaper.
rustc: Fill out remaining parts of C-unwind ABI
This commit intends to fill out some of the remaining pieces of the
C-unwind ABI. This has a number of other changes with it though to move
this design space forward a bit. Notably contained within here is:
* On `panic=unwind`, the `extern "C"` ABI is now considered as "may
unwind". This fixes a longstanding soundness issue where if you
`panic!()` in an `extern "C"` function defined in Rust that's actually
UB because the LLVM representation for the function has the `nounwind`
attribute, but then you unwind.
* Whether or not a function unwinds now mainly considers the ABI of the
function instead of first checking the panic strategy. This fixes a
miscompile of `extern "C-unwind"` with `panic=abort` because that ABI
can still unwind.
* The aborting stub for non-unwinding ABIs with `panic=unwind` has been
reimplemented. Previously this was done as a small tweak during MIR
generation, but this has been moved to a separate and dedicated MIR
pass. This new pass will, for appropriate functions and function
calls, insert a `cleanup` landing pad for any function call that may
unwind within a function that is itself not allowed to unwind. Note
that this subtly changes some behavior from before where previously on
an unwind which was caught-to-abort it would run active destructors in
the function, and now it simply immediately aborts the process.
* The `#[unwind]` attribute has been removed and all users in tests and
such are now using `C-unwind` and `#![feature(c_unwind)]`.
I think this is largely the last piece of the RFC to implement.
Unfortunately I believe this is still not stabilizable as-is because
activating the feature gate changes the behavior of the existing `extern
"C"` ABI in a way that has no replacement. My thinking for how to enable
this is that we add support for the `C-unwind` ABI on stable Rust first,
and then after it hits stable we change the behavior of the `C` ABI.
That way anyone straddling stable/beta/nightly can switch to `C-unwind`
safely.
rustc: Replace `HirId`s with `LocalDefId`s in `AccessLevels` tables
and passes using those tables - primarily privacy checking, stability checking and dead code checking.
All these passes work with definitions rather than with arbitrary HIR nodes.
r? `@cjgillot`
cc `@lambinoo` (#87487)
Trait upcasting coercion (part2)
This is the second part of trait upcasting coercion implementation.
Currently this is blocked on #86264 .
The third part might be implemented using unsafety checking
r? `@bjorn3`
This commit intends to fill out some of the remaining pieces of the
C-unwind ABI. This has a number of other changes with it though to move
this design space forward a bit. Notably contained within here is:
* On `panic=unwind`, the `extern "C"` ABI is now considered as "may
unwind". This fixes a longstanding soundness issue where if you
`panic!()` in an `extern "C"` function defined in Rust that's actually
UB because the LLVM representation for the function has the `nounwind`
attribute, but then you unwind.
* Whether or not a function unwinds now mainly considers the ABI of the
function instead of first checking the panic strategy. This fixes a
miscompile of `extern "C-unwind"` with `panic=abort` because that ABI
can still unwind.
* The aborting stub for non-unwinding ABIs with `panic=unwind` has been
reimplemented. Previously this was done as a small tweak during MIR
generation, but this has been moved to a separate and dedicated MIR
pass. This new pass will, for appropriate functions and function
calls, insert a `cleanup` landing pad for any function call that may
unwind within a function that is itself not allowed to unwind. Note
that this subtly changes some behavior from before where previously on
an unwind which was caught-to-abort it would run active destructors in
the function, and now it simply immediately aborts the process.
* The `#[unwind]` attribute has been removed and all users in tests and
such are now using `C-unwind` and `#![feature(c_unwind)]`.
I think this is largely the last piece of the RFC to implement.
Unfortunately I believe this is still not stabilizable as-is because
activating the feature gate changes the behavior of the existing `extern
"C"` ABI in a way that has no replacement. My thinking for how to enable
this is that we add support for the `C-unwind` ABI on stable Rust first,
and then after it hits stable we change the behavior of the `C` ABI.
That way anyone straddling stable/beta/nightly can switch to `C-unwind`
safely.
CTFE: throw unsupported error when partially overwriting a pointer
Currently, during CTFE, when a write to memory would overwrite parts of a pointer, we make the remaining parts of that pointer "uninitialized". This is probably not what users expect, so if this ever happens they will be quite confused about why some of the data just vanishes for seemingly no good reason.
So I propose we change this to abort CTFE when that happens, to at last avoid silently doing the wrong thing.
Cc https://github.com/rust-lang/rust/issues/87184
Our CTFE test suite still seems to pass. However, we should probably crater this, and I want to do some tests with Miri as well.
rfc3052 followup: Remove authors field from Cargo manifests
Since RFC 3052 soft deprecated the authors field, hiding it from
crates.io, docs.rs, and making Cargo not add it by default, and it is
not generally up to date/useful information for contributors, we may as well
remove it from crates in this repo.
Bail on any found recursion when expanding opaque types
Fixes#87450. More of a bandaid because it does not fix the exponential complexity of the type folding used for opaque type expansion.