Don't declare variables in `ExprKind::Let` in invalid positions
Handle `let` expressions in invalid positions specially during resolve in order to avoid making destructuring-assignment expressions that reference (invalid) variables that have not yet been delcared yet.
See further explanation in test and comment in the source.
Fixesrust-lang/rust#141844
Async drop - type instead of async drop fn, fixes#140484Fixes: rust-lang/rust#140484Fixes: rust-lang/rust#140500
Fixes ICE, when type is provided in AsyncDrop trait instead of `async fn drop()`.
Fixes ICE, when async drop fn has wrong signature.
They're very little value, because they only measure the top-level
`main.rs` or `lib.rs` file. (Other `.rs` files don't get read and parsed
until expansion occurs.)
I saw an example recently where the pre-expansion AST was 3KB in size
and the post-expansion AST was 66MB.
I kept the "POST EXPANSION" in the output header, I think that's useful
information to avoid possible confusion about when the measurement
happens.
terminology: allocated object → allocation
Rust does not have "objects" in memory so "allocated object" is a somewhat odd name. I am not sure where the term comes from. "object" has been used to refer to allocations already [in 1.0 docs](https://doc.rust-lang.org/1.0.0/std/primitive.pointer.html#method.offset); this was apparently later changed to "allocated object".
"Allocation" is already the terminology used in Miri and in the [UCG](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#allocation). We should properly move to that terminology, and avoid any confusion about whether Rust has an object memory model. (It does not. Memory contains untyped bytes.)
Cc ``@rust-lang/opsem`` ``@rust-lang/lang``
Improve diagnostics for usage of qualified paths within tuple struct exprs/pats
For patterns the old diagnostic was just incorrect, but I also added machine applicable suggestions.
For context, this special cases errors for `<T as Trait>::Assoc(..)` patterns and expressions (latter is just a call). Tuple struct patterns and expressions both live in the value namespace, so they are not forwarded through associated *types*.
r? ``@jdonszelmann``
cc ``@petrochenkov`` in https://github.com/rust-lang/rust/pull/80080#issuecomment-800630582 you were wondering why it doesn't work for types, that's why — tuple patterns are resolved in the value namespace.
Fix "consider borrowing" for else-if
Fixesrust-lang/rust#141810
When trying to suggest a borrow on a `if` or `block` expression, instead we now recurse into the `if` or `block`.
The comments in the code should explain the goal of the new code.
r? ``@jdonszelmann``
`slice.get(i)` should use a slice projection in MIR, like `slice[i]` does
`slice[i]` is built-in magic, so ends up being quite different from `slice.get(i)` in MIR, even though they're both doing nearly identical operations -- checking the length of the slice then getting a ref/ptr to the element if it's in-bounds.
This PR adds a `slice_get_unchecked` intrinsic for `impl SliceIndex for usize` to use to fix that, so it no longer needs to do a bunch of lines of pointer math and instead just gets the obvious single statement. (This is *not* used for the range versions, since `slice[i..]` and `slice[..k]` can't use the mir Slice projection as they're using fenceposts, not indices.)
I originally tried to do this with some kind of GVN pattern, but realized that I'm pretty sure it's not legal to optimize `BinOp::Offset` to `PlaceElem::Index` without an extremely complicated condition. Basically, the problem is that the `Index` projection on a dereferenced slice pointer *cares about the metadata*, since it's UB to `PlaceElem::Index` outside the range described by the metadata. But then you cast the fat pointer to a thin pointer then offset it, that *ignores* the slice length metadata, so it's possible to write things that are legal with `Offset` but would be UB if translated in the obvious way to `Index`. Checking (or even determining) the necessary conditions for that would be complicated and error-prone, whereas this intrinsic-based approach is quite straight-forward.
Zero backend changes, because it just lowers to MIR, so it's already supported naturally by CTFE/Miri/cg_llvm/cg_clif.
Rollup of 8 pull requests
Successful merges:
- rust-lang/rust#140787 (Note expr being cast when encounter NonScalar cast error)
- rust-lang/rust#141112 (std: note that `std::str::from_utf8*` functions are aliases to `<str>::from_utf8*` methods)
- rust-lang/rust#141646 (Document what `distcheck` is intended to exercise)
- rust-lang/rust#141740 (Hir item kind field order)
- rust-lang/rust#141793 (`tests/ui`: A New Order [1/N])
- rust-lang/rust#141805 (Update `compiler-builtins` to 0.1.160)
- rust-lang/rust#141815 (Enable non-leaf Frame Pointers for mingw-w64 Arm64 Windows)
- rust-lang/rust#141819 (Fixes for building windows-gnullvm hosts)
r? `@ghost`
`@rustbot` modify labels: rollup
`tests/ui`: A New Order [1/N]
not sure if i should say something about changes here, just part of rust-lang/rust#133895
but this is my very first time doing something like this, id love to keep contributing in this area later on, so any feedback is appreciated
also should say that im going to squash it after agreement on changes
r? `@jieyouxu`
mind if i name this PR series like "`tests/ui`: A New Order [N/N]", im not sure if it fits the project tone, so id like your approval first — but i think it sounds really neat (Star Wars reference)
this could be a first part :)
Note expr being cast when encounter NonScalar cast error
Fixes#140491
I added note for `expr` so that it doesn't treat `&x as T` as `&(x as T)` but `(&x) as T`. But I'm not sure if I want to add note for all NonScalar, maybe for specific `expr_ty`?
r? compiler
Do not move thread-locals before dropping
Fixesrust-lang/rust#140816. I also (potentially) improved the speed of `get_or_init` a bit by having an explicit hot/cold path.
We still move the value before dropping in the event of a recursive initialization (leading to double-initialization with one value being silently dropped). This is the old behavior, but changing this to panic instead would involve changing tests and also the other OS-specific `thread_local/os.rs` implementation, which is more than I'd like in this PR.
Add fast path for maybe-initializedness in liveness
r? `@matthewjasper`
Correct me if I'm wrong Matthew, but my understanding is that
1. `MaybeInitializedPlaces` is currently eagerly computed, in `do_mir_borrowck`
2. but this data is only used in liveness
3. and `liveness::trace` actually only uses it for drop-liveness
This PR moves the computation to `liveness::trace` which looks to be its only use-site. We also add a fast path there, so that it's only computed by drop-liveness.
This is interesting because 1) liveness is only computed for relevant live locals, 2) drop-liveness is only computed for relevant live locals with >0 drop points; 0 is the common case from our benchmarks, as far as I can tell, so even just computing the entire data lazily helps.
It seems possible to also reduce the domain here, and speed up the analysis for the cases where it has to be computed -- so I've left a fixme for that, and may look into it soon.
(I've come upon this while doing implementation work for polonius, so don't be too enamored with possible wins: the goal is to reduce the eventual polonius overhead and make it more palatable 😓)
Add Range parameter to `BTreeMap::extract_if` and `BTreeSet::extract_if`
This new parameter was requested in the btree_extract_if tracking issue: https://github.com/rust-lang/rust/issues/70530#issuecomment-2486566328
I attempted to follow the style used by `Vec::extract_if`.
Before:
```rust
impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
#[unstable(feature = "btree_extract_if", issue = "70530")]
pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F, A>
where
K: Ord,
F: FnMut(&K, &mut V) -> bool;
}
```
After:
```rust
impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
#[unstable(feature = "btree_extract_if", issue = "70530")]
pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, K, V, R, F, A>
where
K: Ord,
R: RangeBounds<K>,
F: FnMut(&K, &mut V) -> bool;
}
```
Related: #70530
—
While I believe I have adjusted all of the necessary bits, as this is my first attempt to contribute to Rust, I may have overlooked something out of ignorance, but if you can point out any oversight, I shall attempt to remedy it.
Structurally normalize types as needed in `projection_ty_core`
Introduce a `structurally_normalize` callback to `projection_ty_core`, and then use it before we match on the ty kind in `projection_ty_core`.
Previously we were only structurally normalizing the return type of the `handle_field` struct, but if we were to (e.g.) apply a deref projection to that type, then the resulting type is not guaranteed to be structurally normalized and any subsequent projections applied would ICE.
Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/221
I'll leave a few comments inline to explain the changes.
r? lcnr
---
Also fixesrust-lang/rust#141708