Make closures and generators a must use types
Warn about unused expressions with closure or generator type. This follows
existing precedence of must use annotations present on `FnOnce`, `FnMut`, `Fn`
traits, which already indirectly apply to closures in some cases, e.g.,:
```rust
fn f() -> impl FnOnce() {
|| {}
}
fn main() {
// an existing warning: unused implementer of `std::ops::FnOnce` that must be used:
f();
// a new warning: unused closure that must be used:
|| {};
}
```
Closes#74691.
Remove links to rejected errata 4406 for RFC 4291
Fixes#74198.
For now I simply removed the links, the docs seems clear enough to me but I'm no expert in the domain so don't hesitate to correct me if more is needed.
cc @ghanan94.
@rustbot modify labels: T-doc, T-libs
This does not actually alter the previously specified important parts, but apparently `rustc` cares about more layout components than `cargo-xbuild` ever did. This extends the data layout to be fully specified layout, as given in the error from issue #74767
Refactor librustdoc html backend
This PR moves several types out of the librustdoc::html module so that they can be used by a future json backend. These changes are a re-implementation of [some work done 6 months ago](https://github.com/rust-lang/rust/compare/master...GuillaumeGomez:multiple-output-formats) by @GuillaumeGomez. I'm currently working on said json backend and will put up an RFC soon with the proposed implementation.
There are a couple of changes that are more substantial than relocating structs to a different module:
1. The `Cache` is no longer part of the `html::render::Context` type and therefor it needs to be explicitly passed to any functions that access it.
2. The driving function `html::render::run` has been rewritten to use the `FormatRenderer` trait which should allow different backends to re-use the driving code.
r? @GuillaumeGomez
cc @tmandry @betamos
Fixed coverage map issues; better aligned with LLVM APIs
Found some problems with the coverage map encoding when testing with more than one counter per function.
While debugging, I realized some better ways to structure the Rust implementation of the coverage mapping generator. I refactored somewhat, resulting in less code overall, expanded coverage of LLVM Coverage Map capabilities, and much closer alignment with LLVM data structures, APIs, and naming.
This should be easier to follow and easier to maintain.
r? @tmandry
Rust compiler MCP rust-lang/compiler-team#278
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
Fix#70767
This PR changes the format of MIR dump filenames to include the crate name rather than `rustc` at the start.
As a result, we can now place mir-opt tests in the same directory as the source files, like with UI tests. I had to make sure that `compiletest` added a bit_width suffix to the expected files when appropriate but otherwise the change is only moving the files to the correct location and ensuring that the `EMIT_MIR` lines are correct.
Fixes#70767
cc @oli-obk
Stabilize const_type_id feature
The tracking issue for `const_type_id` points to the ill-fated #41875. So I'm re-energizing `TypeId` shenanigans by opening this one up to see if there's anything blocking us from stabilizing the constification of type ids.
Will wait for CI before pinging teams/groups.
-----
This PR stabilizes the `const_type_id` feature, which allows `TypeId::of` (and the underlying unstable intrinsic) to be called in constant contexts.
There are some [sanity tests](https://github.com/rust-lang/rust/blob/master/src/test/ui/consts/const-typeid-of-rpass.rs) that demonstrate its usage, but I’ve included some more below.
As a simple example, you could create a constant item that contains some type ids:
```rust
use std::any::TypeId;
const TYPE_IDS: [TypeId; 2] = [
TypeId::of::<u32>(),
TypeId::of::<i32>(),
];
assert_eq!(TypeId::of::<u32>(), TYPE_IDS[0]);
```
Type ids can also now appear in associated constants. You could create a trait that associates each type with its constant type id:
```rust
trait Any where Self: 'static {
const TYPE_ID: TypeId = TypeId::of::<Self>();
}
impl<T: 'static> Any for T { }
assert_eq!(TypeId::of::<usize>(), usize::TYPE_ID);
```
`TypeId::of` is generic, which we saw above in the way the generic `Self` argument was used. This has some implications for const evaluation. It means we can make trait impls evaluate differently depending on information that wasn't directly passed through the trait system. This violates the _parametricity_ property, which requires all instances of a generic function to behave the same way with respect to its generic parameters. That's not unique to `TypeId::of`, other generic const functions based on compiler intrinsics like `mem::align_of` can also violate parametricity. In practice Rust doesn't really have type parametricity anyway since it monomorphizes generics into concrete functions, so violating it using type ids isn’t new.
As an example of how impls can behave differently, you could combine constant type ids with the `const_if_match` feature to dispatch calls based on the type id of the generic `Self`, rather than based on information about `Self` that was threaded through trait bounds. It's like a rough-and-ready form of specialization:
```rust
#![feature(const_if_match)]
trait Specialized where Self: 'static {
// An associated constant that determines the function to call
// at compile-time based on `TypeId::of::<Self>`.
const CALL: fn(&Self) = {
const USIZE: TypeId = TypeId::of::<usize>();
match TypeId::of::<Self>() {
// Use a closure for `usize` that transmutes the generic `Self` to
// a concrete `usize` and dispatches to `Self::usize`.
USIZE => |x| Self::usize(unsafe { &*(x as *const Self as *const usize) }),
// For other types, dispatch to the generic `Self::default`.
_ => Self::default,
}
};
fn call(&self) {
// Call the function we determined at compile-time
(Self::CALL)(self)
}
fn default(x: &Self);
fn usize(x: &usize);
}
// Implement our `Specialized` trait for any `Debug` type.
impl<T: fmt::Debug + 'static> Specialized for T {
fn default(x: &Self) {
println!("default: {:?}", x);
}
fn usize(x: &usize) {
println!("usize: {:?}", x);
}
}
// Will print "usize: 42"
Specialized::call(&42usize);
// Will print "default: ()"
Specialized::call(&());
```
Type ids have some edges that this stabilization exposes to more contexts. It's possible for type ids to collide (but this is a bug). Since they can change between compiler versions, it's never valid to cast a type id to its underlying value.
This fixes various cases where LD could not guess dllexport correctly and greatly improves compatibility with LLD which is not going to support linker scripts anytime soon
Fix opening docs for std crates with ./x.py doc --open library/*
The directories for core, alloc, std, proc_macro, and test crates now
correspond directly to the crate name, and stripping the "lib" prefix is
no longer necessary.
The directories for core, alloc, std, proc_macro, and test crates now
correspond directly to the crate name and stripping the "lib" prefix is
no longer necessary.
Cache non-exhaustive separately from attributes
This prevents cross-crate attribute loading from metadata just for non_exhaustive checking; cross-crate attribute loading implies disk reading and is relatively slow.
Fix RefUnwindSafe & UnwinsSafe impls for lazy::SyncLazy
I *think* we should implement those unconditionally with respect to `F`.
The user code can't observe the closure in any way, and we poison lazy if the closure itself panics.
But I've never fully wrapped my head around `UnwindSafe` traits, so 🤷♂️
Add str::[r]split_once
This is useful for quick&dirty parsing of key: value config pairs. Used a bunch in Cargo and rust-analyzer:
* https://github.com/rust-lang/cargo/search?q=splitn%282&unscoped_q=splitn%282
* https://github.com/rust-analyzer/rust-analyzer/search?q=split_delim&unscoped_q=split_delim
In theory, once const-generics are done, this functionality could be achieved without a dedicated method with
```rust
match s.splitn(delimier, 2).collect_array::<2>() {
Some([prefix, suffix]) => todo!(),
None => todo!(),
}
```
Even in that world, having a dedicated method seems clearer on the intention.
I am not sure about naming -- this is something I've just came up with yesterday, I don't know off the top of my head analogs in other languages.
If T-libs thinks this is a reasonable API to have, I'll open a tracking issue and add more thorough tests.
Add #[inline] to RawWaker::new
`RawWaker::new` is used when creating a new waker or cloning an existing one,
for example as in code below. The `RawWakerVTable::new` can be const evaluated,
but `RawWaker::new` itself cannot since waker pointer is not known at compile
time. Add `#[inline]` to avoid overhead of a function call.
```rust
unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
unsafe { Arc::incr_strong_count(waker as *const W) };
RawWaker::new(
waker as *const (),
&RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
)
}
```