Get rid of `USIZE_MARKER` in formatting infrastructure
An alternative to #123780.
The `USIZE_MARKER` function used to differentiate between placeholder and count arguments is never called anyway, so we can just replace the function-pointer-comparison hack with an `enum` and an `unreachable_unchecked`, hopefully without causing a regression.
CC `@RalfJung`
Linker flavors next steps: linker features
This is my understanding of the first step towards `@petrochenkov's` vision for the future of linker flavors, described in https://github.com/rust-lang/rust/pull/119906#issuecomment-1895693162 and the discussion that followed.
To summarize: having `Cc` and `Lld` embedded in linker flavors creates tension about naming, and a combinatorial explosion of flavors for each new linker feature we'd want to use. Linker features are an extension mechanism that is complementary to principal flavors, with benefits described in #119906.
The most immediate use of this flag would be to turn self-contained linking on and off via features instead of flavors. For example, `-Clinker-features=+/-lld` would toggle using lld instead of selecting a precise flavor, and would be "generic" and work cross-platform (whereas linker flavors are currently more tied to targets). Under this scheme, MCP510 is expected to be `-Clink-self-contained=+linker -Zlinker-features=+lld -Zunstable-options` (though for the time being, the original flags using lld-cc flavors still work).
I purposefully didn't add or document CLI support for `+/-cc`, as it would be a noop right now. I only expect that we'd initially want to stabilize `+/-lld` to begin with.
r? `@petrochenkov`
You had requested that minimal churn would be done to the 230 target specs and this does none yet: the linker features are inferred from the flavor since they're currently isomorphic. We of course expect this to change sooner rather than later.
In the future, we can allow targets to define linker features independently from their flavor, and remove the cc and lld components from the flavors to use the features instead, this actually doesn't need to block stabilization, as we discussed.
(Best reviewed per commit)
Detect borrow checker errors where `.clone()` would be an appropriate user action
When a value is moved twice, suggest cloning the earlier move:
```
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
--> $DIR/union-move.rs:49:18
|
LL | move_out(x.f1_nocopy);
| ^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `x.f1_nocopy` has type `ManuallyDrop<RefCell<i32>>`, which does not implement the `Copy` trait
|
help: consider cloning the value if the performance cost is acceptable
|
LL | move_out(x.f1_nocopy.clone());
| ++++++++
```
When a value is borrowed by an `fn` call, consider if cloning the result of the call would be reasonable, and suggest cloning that, instead of the argument:
```
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:53:14
|
LL | let a = AffineU32(1);
| - binding `a` declared here
LL | let x = bat(&a);
| -- borrow of `a` occurs here
LL | drop(a);
| ^ move out of `a` occurs here
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
|
LL | let x = bat(&a).clone();
| ++++++++
```
otherwise, suggest cloning the argument:
```
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:59:14
|
LL | let a = ClonableAffineU32(1);
| - binding `a` declared here
LL | let x = foo(&a);
| -- borrow of `a` occurs here
LL | drop(a);
| ^ move out of `a` occurs here
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
|
LL - let x = foo(&a);
LL + let x = foo(a.clone());
|
```
This suggestion doesn't attempt to square out the types between what's cloned and what the `fn` expects, to allow the user to make a determination on whether to change the `fn` call or `fn` definition themselves.
Special case move errors caused by `FnOnce`:
```
error[E0382]: use of moved value: `blk`
--> $DIR/once-cant-call-twice-on-heap.rs:8:5
|
LL | fn foo<F:FnOnce()>(blk: F) {
| --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
LL | blk();
| ----- `blk` moved due to this call
LL | blk();
| ^^^ value used here after move
|
note: `FnOnce` closures can only be called once
--> $DIR/once-cant-call-twice-on-heap.rs:6:10
|
LL | fn foo<F:FnOnce()>(blk: F) {
| ^^^^^^^^ `F` is made to be an `FnOnce` closure here
LL | blk();
| ----- this value implements `FnOnce`, which causes it to be moved when called
```
Account for redundant `.clone()` calls in resulting suggestions:
```
error[E0507]: cannot move out of dereference of `S`
--> $DIR/needs-clone-through-deref.rs:15:18
|
LL | for _ in self.clone().into_iter() {}
| ^^^^^^^^^^^^ ----------- value moved due to this method call
| |
| move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait
|
note: `into_iter` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | for _ in <Vec<usize> as Clone>::clone(&self).into_iter() {}
| ++++++++++++++++++++++++++++++ ~
```
We use the presence of `&mut` values in a move error as a proxy for the user caring about side effects, so we don't emit a clone suggestion in that case:
```
error[E0505]: cannot move out of `s` because it is borrowed
--> $DIR/borrowck-overloaded-index-move-index.rs:53:7
|
LL | let mut s = "hello".to_string();
| ----- binding `s` declared here
LL | let rs = &mut s;
| ------ borrow of `s` occurs here
...
LL | f[s] = 10;
| ^ move out of `s` occurs here
...
LL | use_mut(rs);
| -- borrow later used here
```
We properly account for `foo += foo;` errors where we *don't* suggest `foo.clone() += foo;`, instead suggesting `foo += foo.clone();`.
---
Each commit can be reviewed in isolation. There are some "cleanup" commits, but kept them separate in order to show *why* specific changes were being made, and their effect on tests' output.
Fix#49693, CC #64167.
Avoid more NonNull-raw-NonNull roundtrips in Vec
r? the8472
The standard library in general has a lot of these round-trips from niched types to their raw innards and back. Such round-trips have overhead in debug builds since https://github.com/rust-lang/rust/pull/120594. I removed some such round-trips in that initial PR and I've been meaning to come back and hunt down more such examples (this is the last item on https://github.com/rust-lang/rust/issues/120848).
Add `/System/iOSSupport` to the library search path on Mac Catalyst
On macOS, `/System/iOSSupport` contains iOS frameworks like UIKit, which is the whole idea of Mac Catalyst.
To link to these, we need to explicitly tell the linker about the support library stubs provided in the macOS SDK under the same path.
Concretely, when building a binary for Mac Catalyst, Xcode passes the following flags to the linker:
```
-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/iOSSupport/System/Library/Frameworks
-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/iOSSupport/usr/lib
```
This is not something that can be disabled (it's enabled as soon as you enable `SUPPORTS_MACCATALYST`), so I think it's pretty safe to say that we don't need an option to turn these off.
I've chosen to slightly deviate from what Xcode does and use `-F` instead of `-iframework`, since we don't need to change the header search path, and this way the flags nicely match on all the linkers. From what I could tell by reading Clang sources, there shouldn't be a difference when just running the linker.
CC `@BlackHoleFox,` `@shepmaster` (I accidentally let rustbot choose the reviewer).
typeck: fix `?` suggestion span
Noticed in <https://github.com/rust-lang/rust/pull/112043#issuecomment-2043565292>, if the
```
use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
```
suggestion is applied to a macro that comes from a non-local crate (e.g. the stdlib), the suggestion span can become non-local, which will cause newer rustfix versions to fail.
This PR tries to remedy the problem by recursively probing ancestors of the expression span, trying to identify the most ancestor span that is (1) still local, and (2) still shares the same syntax context as the expression.
This is the same strategy used in https://github.com/rust-lang/rust/pull/112043.
The test unfortunately cannot `//@ run-rustfix` because there are two conflicting MaybeIncorrect suggestions that when collectively applied, cause the fixed source file to become non-compilable.
Also avoid running `//@ run-rustfix` for `tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.rs` because that also contains conflicting suggestions.
cc `@ehuss` who noticed this. This question mark span fix + not running rustfix on the tests containing conflicting MaybeIncorrect suggestions should hopefully unblock rustfix from updating.
The suggestion to use `let else` with an uninitialized refutable `let`
statement was erroneous: `let else` cannot be used with deferred
initialization.
Improve diagnostic by suggesting to remove visibility qualifier
Resolves#123529
This PR improve diagnostic by suggesting to remove visibility qualifier.
Fix invalid silencing of parsing error
Given
```rust
macro_rules! a {
( ) => {
impl<'b> c for d {
e::<f'g>
}
};
}
```
ensure an error is emitted.
Fix#123079.
Don't delay a bug if we suggest adding a semicolon to the RHS of an assign operator
It only makes sense to delay a bug based on the assumption that "[we] defer to the later error produced by `check_lhs_assignable`" *if* the expression we're erroring actually is an LHS; otherwise, we should still report the error since it's both useful and required.
Fixes#123722
Fix revisions syntax in cfg(ub_checks) test
`//@ revisions YES NO` doesn't do anything without the `:`. Thanks for pointing this out to me.
r? jieyouxu
Set the host library path in run-make v2
When the build is configured with `[rust] rpath = false`, we need to set
`LD_LIBRARY_PATH` (or equivalent) to what would have been the `RPATH`,
so the compiler can find its own libraries. The old `tools.mk` code has
this environment prefixed in the `$(BARE_RUSTC)` variable, so we just
need to wire up something similar for run-make v2.
This is now set while building each `rmake.rs` itself, as well as in the
`rust-make-support` helpers for `rustc` and `rustdoc` commands. This is
also available in a `set_host_rpath` function for manual commands, like
in the `compiler-builtins` test.
Rollup of 8 pull requests
Successful merges:
- #122882 (Avoid a panic in `set_output_capture` in the default panic handler)
- #123523 (Account for trait/impl difference when suggesting changing argument from ref to mut ref)
- #123744 (Silence `unused_imports` for redundant imports)
- #123784 (Replace `document.write` with `document.head.insertAdjacent`)
- #123798 (Avoid invalid socket address in length calculation)
- #123804 (Stop using `HirId` for fn-like parents since closures are not `OwnerNode`s)
- #123806 (Panic on overflow in `BorrowedCursor::advance`)
- #123820 (Add my former address to .mailmap)
r? `@ghost`
`@rustbot` modify labels: rollup
Stop using `HirId` for fn-like parents since closures are not `OwnerNode`s
This is a minimal fix for #123273.
I'm overall pretty disappointed w/ the state of this code; although it's "just diagnostics", it still should be maintainable and understandable and neither of those are true. I believe this code really needs some major overhauling before anything more should be added to it, because there are subtle invariants that are being exercised and subsequently broken all over the place, and I don't think we should just paper over them (e.g.) by delaying bugs or things like that. I wouldn't be surprised if fixing up this code would also yield better diagnostics.
Silence `unused_imports` for redundant imports
Quick fix for https://github.com/rust-lang/rust/issues/121708#issuecomment-2048105393
r? `@petrochenkov` cc `@joshtriplett`
I think this is right, would like confirmation. I also think it's weird that we're using `=` to assign to `is_redundant` but using `per_ns` for the actual spans. Seems like this could be weirdly order dependent, but that's unrelated to this change.
Account for trait/impl difference when suggesting changing argument from ref to mut ref
Do not ICE when encountering a lifetime error involving an argument with an immutable reference of a method that differs from the trait definition.
Fix#123414.
codegen tests: Tolerate `nuw` `nsw` on `trunc`
llvm/llvm-project#87910 infers `nuw` and `nsw` on some `trunc` instructions we're doing `FileCheck` on. Tolerate but don't require them to support both release and head LLVM.
`@rustbot` label: +llvm-main
cc `@durin42`
Correctly handle inlining of doc hidden foreign items
Fixes#123435.
In case a foreign item has doc(hidden) attribute, we simply merged its attributes with the re-export's, making it being removed once in the `strip_hidden` pass.
The solution was to use the same as for local reexported items: merge attributes, but not some of them (like `doc(hidden)`).
I originally checked if we could simply update `Item::is_doc_hidden` method to use `self.inline_stmt_id.is_some_and(|def_id| tcx.is_doc_hidden(def_id))` but unfortunately, it added (local) items that shouldn't be inlined. At least it unifies local and foreign items inlining, which I think is the best course of action here.
r? `@notriddle`
llvm/llvm-project#87910 infers `nuw` and `nsw` on some `trunc`
instructions we're doing `FileCheck` on. Tolerate but don't require them
to support both release and head LLVM.
We attempt to suggest an appropriate clone for move errors on expressions
like `S { ..s }` where a field isn't `Copy`. If we can't suggest, we still don't
emit the incorrect suggestion of `S { ..s }.clone()`.
```
error[E0509]: cannot move out of type `S<K>`, which implements the `Drop` trait
--> $DIR/borrowck-struct-update-with-dtor.rs:28:19
|
LL | let _s2 = S { a: 2, ..s0 };
| ^^^^^^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `s0.c` has type `K`, which does not implement the `Copy` trait
|
help: clone the value from the field instead of using the spread operator syntax
|
LL | let _s2 = S { a: 2, c: s0.c.clone(), ..s0 };
| +++++++++++++++++
```
```
error[E0509]: cannot move out of type `S<()>`, which implements the `Drop` trait
--> $DIR/borrowck-struct-update-with-dtor.rs:20:19
|
LL | let _s2 = S { a: 2, ..s0 };
| ^^^^^^^^^^^^^^^^
| |
| cannot move out of here
| move occurs because `s0.b` has type `B`, which does not implement the `Copy` trait
|
note: `B` doesn't implement `Copy` or `Clone`
--> $DIR/borrowck-struct-update-with-dtor.rs:4:1
|
LL | struct B;
| ^^^^^^^^
help: if `B` implemented `Clone`, you could clone the value from the field instead of using the spread operator syntax
|
LL | let _s2 = S { a: 2, b: s0.b.clone(), ..s0 };
| +++++++++++++++++
```
```
error[E0382]: use of moved value: `blk`
--> $DIR/once-cant-call-twice-on-heap.rs:8:5
|
LL | fn foo<F:FnOnce()>(blk: F) {
| --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
LL | blk();
| ----- `blk` moved due to this call
LL | blk();
| ^^^ value used here after move
|
note: `FnOnce` closures can only be called once
--> $DIR/once-cant-call-twice-on-heap.rs:6:10
|
LL | fn foo<F:FnOnce()>(blk: F) {
| ^^^^^^^^ `F` is made to be an `FnOnce` closure here
LL | blk();
| ----- this value implements `FnOnce`, which causes it to be moved when called
```
```
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:28:14
|
LL | let a = AffineU32(1);
| - binding `a` declared here
LL | let x = foo(&a);
| -- borrow of `a` occurs here
LL | drop(a);
| ^ move out of `a` occurs here
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
|
LL | let x = foo(&a).clone();
| ++++++++
```
```
error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure
--> $DIR/issue-87456-point-to-closure.rs:10:28
|
LL | let val = String::new();
| --- captured outer variable
LL |
LL | take_mut(|| {
| -- captured by this `FnMut` closure
LL |
LL | let _foo: String = val;
| ^^^ move occurs because `val` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
|
LL | let _foo: String = &val;
| +
help: consider cloning the value if the performance cost is acceptable
|
LL | let _foo: String = val.clone();
| ++++++++
```
```
error[E0507]: cannot move out of `*x` which is behind a shared reference
--> $DIR/borrowck-fn-in-const-a.rs:6:16
|
LL | return *x
| ^^ move occurs because `*x` has type `String`, which does not implement the `Copy` trait
|
help: consider cloning the value if the performance cost is acceptable
|
LL - return *x
LL + return x.clone()
|
```